Go to the documentation of this file.
16 #ifndef LLVM_SUPPORT_THREAD_H
17 #define LLVM_SUPPORT_THREAD_H
20 #include "llvm/Config/llvm-config.h"
23 typedef unsigned long DWORD;
28 #if LLVM_ENABLE_THREADS
34 #if LLVM_ON_UNIX || _WIN32
39 template <
typename FPtr,
typename...
Args,
size_t... Indices>
40 static void Apply(std::tuple<FPtr, Args...> &
Callee,
41 std::index_sequence<Indices...>) {
45 template <
typename CalleeTuple>
static void GenericThreadProxy(
void *Ptr) {
46 std::unique_ptr<CalleeTuple>
Callee(
static_cast<CalleeTuple *
>(Ptr));
49 std::make_index_sequence<std::tuple_size<CalleeTuple>() - 1> Indices{};
50 Apply(*
Callee.get(), Indices);
59 template <
typename CalleeTuple>
static void *
ThreadProxy(
void *Ptr) {
60 GenericThreadProxy<CalleeTuple>(Ptr);
68 template <
typename CalleeTuple>
70 GenericThreadProxy<CalleeTuple>(Ptr);
129 template <
class Function,
class...
Args>
135 std::unique_ptr<CalleeTuple>
Callee(
136 new CalleeTuple(std::forward<Function>(
f), std::forward<Args>(args)...));
158 namespace this_thread {
162 #else // !LLVM_ON_UNIX && !_WIN32
169 using id = std::thread::id;
173 : Thread(std::exchange(
Other.Thread, std::thread())) {}
181 explicit thread(Function &&
f,
Args &&...args) : Thread(
f, args...) {}
188 Thread = std::exchange(
Other.Thread, std::thread());
194 id get_id()
const noexcept {
return Thread.get_id(); }
202 inline void join() { Thread.join(); }
203 inline void detach() { Thread.detach(); }
211 namespace this_thread {
215 #endif // LLVM_ON_UNIX || _WIN32
219 #else // !LLVM_ENABLE_THREADS
231 f(std::forward<Args>(args)...);
235 f(std::forward<Args>(args)...);
241 "threading support");
249 #endif // LLVM_ENABLE_THREADS
251 #endif // LLVM_SUPPORT_THREAD_H
thread::id llvm_thread_get_id_impl(thread::native_handle_type Thread)
thread & operator=(thread &&Other) noexcept
ThreadPoolStrategy hardware_concurrency(unsigned ThreadCount=0)
Returns a default thread strategy where all available hardware resources are to be used,...
This is an optimization pass for GlobalISel generic memory operations.
static unsigned hardware_concurrency()
static void * ThreadProxy(void *Ptr)
thread::id llvm_thread_get_current_id_impl()
thread(Function &&f, Args &&...args)
void llvm_thread_join_impl(thread::native_handle_type Thread)
void llvm_thread_detach_impl(thread::native_handle_type Thread)
thread::native_handle_type llvm_execute_on_thread_impl(thread::start_routine_type ThreadFunc, void *Arg, llvm::Optional< unsigned > StackSizeInBytes)
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Itanium Name Demangler i e convert the string _Z1fv into f()". You can also use the CRTP base ManglingParser to perform some simple analysis on the mangled name
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
id get_id() const noexcept
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx rax ret instead of xmm1 cvttss2siq rcx movaps xmm2 subss xmm2 cvttss2siq rax rdx xorq rax ucomiss xmm0 cmovb rax ret Seems like the jb branch has high likelihood of being taken It would have saved a few instructions It s not possible to reference and DH registers in an instruction requiring REX prefix divb and mulb both produce results in AH If isel emits a CopyFromReg which gets turned into a movb and that can be allocated a r8b r15b To get around isel emits a CopyFromReg from AX and then right shift it down by and truncate it It s not pretty but it works We need some register allocation magic to make the hack go which would often require a callee saved register Callees usually need to keep this value live for most of their body so it doesn t add a significant burden on them We currently implement this in however this is suboptimal because it means that it would be quite awkward to implement the optimization for callers A better implementation would be to relax the LLVM IR rules for sret arguments to allow a function with an sret argument to have a non void return type
LLVM thread following std::thread interface with added constructor to specify stack size.
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
native_handle_type native_handle() const noexcept
amdgpu Simplify well known AMD library false FunctionCallee Callee
static const llvm::Optional< unsigned > DefaultStackSize
bool joinable() const noexcept
pthread_t native_handle_type
thread(thread &&Other) noexcept
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
void swap(llvm::thread &Other) noexcept
void *(*)(void *) start_routine_type
Optional< std::vector< StOtherPiece > > Other