Proteus
Programmable JIT compilation and optimization for C/C++ using LLVM
Loading...
Searching...
No Matches
Func.h
Go to the documentation of this file.
1#ifndef PROTEUS_FRONTEND_FUNC_H
2#define PROTEUS_FRONTEND_FUNC_H
3
10
11#include <functional>
12#include <optional>
13#include <vector>
14
15namespace proteus {
16
17class JitModule;
18template <typename T> class LoopBoundInfo;
19template <typename T, typename... ForLoopBuilders> class LoopNestBuilder;
20template <typename T, typename BodyLambda> class ForLoopBuilder;
21
22// Helper struct to represent the signature of a function.
23// Useful to partially-specialize function templates.
24template <typename... ArgTs> struct ArgTypeList {};
25template <typename T> struct FnSig;
26template <typename RetT_, typename... ArgT> struct FnSig<RetT_(ArgT...)> {
27 using ArgsTList = ArgTypeList<ArgT...>;
28 using RetT = RetT_;
29};
30
32 void operator()() const {}
33};
34
35enum class EmissionPolicy { Eager, Lazy };
36
37// Returned by forLoop<Eager> so that buildLoopNest's static_assert fires with
38// a clear message instead of a generic "cannot form a reference to void" error.
40
41template <typename T> struct IsForLoopBuilder : std::false_type {};
42template <typename T, typename BodyLambda>
43struct IsForLoopBuilder<ForLoopBuilder<T, BodyLambda>> : std::true_type {};
44
45class FuncBase {
46public:
47 JitModule &getJitModule() { return J; }
48
51
52protected:
54
55 std::string Name;
58 // Kernel-ness must be known at creation time so backends can create the
59 // correct IR container (gpu.func vs func.func) without duplication.
61
62public:
63 FuncBase(JitModule &J, CodeBuilder &CB, const std::string &Name, IRType RetTy,
64 const std::vector<IRType> &ArgTys, bool IsKernel = false);
66
68 IRValue *getArg(size_t Idx);
69
70 bool isKernel() const { return IsKernel; }
71
72#if PROTEUS_ENABLE_CUDA || PROTEUS_ENABLE_HIP
73 void setLaunchBoundsForKernel(int MaxThreadsPerBlock, int MinBlocksPerSM);
74#endif
75
76 template <typename T> Var<T> declVar(const std::string &Name = "var") {
77 static_assert(!std::is_array_v<T>, "Expected non-array type");
78 static_assert(!std::is_reference_v<T>,
79 "declVar does not support reference types");
80
81 if constexpr (std::is_pointer_v<T>) {
83 return Var<T>{CB->allocPointer(Name, ElemIRTy), *CB};
84 } else {
85 IRType AllocaIRTy = TypeMap<T>::get();
86 return Var<T>{CB->allocScalar(Name, AllocaIRTy), *CB};
87 }
88 }
89
90 template <typename T>
92 const std::string &Name = "array_var") {
93 static_assert(std::is_array_v<T>, "Expected array type");
94
95 IRType ArrIRTy = TypeMap<T>::get(NElem);
96 IRType ElemIRTy{ArrIRTy.ElemKind, ArrIRTy.Signed};
97 return Var<T>{CB->allocArray(Name, AS, ElemIRTy, ArrIRTy.NElem), *CB};
98 }
99
100 template <typename... Ts> auto declVars() {
101 return std::make_tuple(declVar<Ts>()...);
102 }
103
104 template <typename... Ts, typename... NameTs>
105 auto declVars(NameTs &&...Names) {
106 static_assert(sizeof...(Ts) == sizeof...(NameTs),
107 "Number of types must match number of names");
108 return std::make_tuple(declVar<Ts>(std::forward<NameTs>(Names))...);
109 }
110
111 template <typename T>
112 Var<T> defVar(const T &Val, const std::string &Name = "var") {
113 using RawT = std::remove_const_t<T>;
114 Var<RawT> V = declVar<RawT>(Name);
115 V = Val;
116 return Var<T>(V);
117 }
118
119 template <typename T, typename U>
120 Var<T> defVar(const Var<U> &Val, const std::string &Name = "var") {
121 using RawT = std::remove_const_t<T>;
122 Var<RawT> Res = declVar<RawT>(Name);
123 Res = Val;
124 return Var<T>(Res);
125 }
126
127 template <typename U>
128 Var<U> defVar(const Var<U> &Val, const std::string &Name = "var") {
129 Var<U> Res = declVar<U>(Name);
130 Res = Val;
131 return Res;
132 }
133
134 template <
135 typename T, typename NameT,
136 typename = std::enable_if_t<std::is_convertible_v<NameT, std::string>>>
137 auto defVar(std::pair<T, NameT> P) {
138 return defVar(P.first, std::string(P.second));
139 }
140
141 template <typename... ArgT> auto defVars(ArgT &&...Args) {
142 return std::make_tuple(defVar(std::forward<ArgT>(Args))...);
143 }
144
145 template <typename T>
147 const std::string &Name = "run.const.var") {
148 return Var<const T>(defVar<T>(Val, Name));
149 }
150
151 template <
152 typename T, typename NameT,
153 typename = std::enable_if_t<std::is_convertible_v<NameT, std::string>>>
154 Var<const T> defRuntimeConst(std::pair<T, NameT> P) {
155 return defRuntimeConst(P.first, std::string(P.second));
156 }
157
158 template <typename... ArgT> auto defRuntimeConsts(ArgT &&...Args) {
159 return std::make_tuple(defRuntimeConst(std::forward<ArgT>(Args))...);
160 }
161
162 void beginFunction(const char *File = __builtin_FILE(),
163 int Line = __builtin_LINE());
164 void endFunction();
165
166 template <typename BodyLambda>
167 void function(BodyLambda &&Body, const char *File = __builtin_FILE(),
168 int Line = __builtin_LINE()) {
169 beginFunction(File, Line);
170 std::forward<BodyLambda>(Body)();
171 endFunction();
172 }
173
174 void beginIf(const Var<bool> &CondVar, const char *File = __builtin_FILE(),
175 int Line = __builtin_LINE());
176 void endIf();
177
178 template <typename BodyLambda>
179 void ifThen(const Var<bool> &CondVar, BodyLambda &&Body,
180 const char *File = __builtin_FILE(),
181 int Line = __builtin_LINE()) {
182 beginIf(CondVar, File, Line);
183 std::forward<BodyLambda>(Body)();
184 endIf();
185 }
186
187 template <typename IterT, typename InitT, typename UpperT, typename IncT>
188 void beginFor(Var<IterT> &IterVar, const Var<InitT> &InitVar,
189 const Var<UpperT> &UpperBound, const Var<IncT> &IncVar,
190 const char *File = __builtin_FILE(),
191 int Line = __builtin_LINE(), LoopHints Hints = {});
192 void endFor();
193
194 template <typename CondLambda>
195 void beginWhile(CondLambda &&Cond, const char *File = __builtin_FILE(),
196 int Line = __builtin_LINE());
197 void endWhile();
198
199 template <typename CondLambda, typename BodyLambda>
200 void whileLoop(CondLambda &&Cond, BodyLambda &&Body,
201 const char *File = __builtin_FILE(),
202 int Line = __builtin_LINE()) {
203 beginWhile(std::forward<CondLambda>(Cond), File, Line);
204 std::forward<BodyLambda>(Body)();
205 endWhile();
206 }
207
208 template <typename Sig>
209 std::enable_if_t<!std::is_void_v<typename FnSig<Sig>::RetT>,
211 call(const std::string &Name);
212
213 template <typename Sig>
214 std::enable_if_t<std::is_void_v<typename FnSig<Sig>::RetT>, void>
215 call(const std::string &Name);
216
217 template <typename Sig, typename... ArgVars>
218 std::enable_if_t<!std::is_void_v<typename FnSig<Sig>::RetT>,
220 call(const std::string &Name, ArgVars &&...ArgsVars);
221
222 template <typename Sig, typename... ArgVars>
223 std::enable_if_t<std::is_void_v<typename FnSig<Sig>::RetT>, void>
224 call(const std::string &Name, ArgVars &&...ArgsVars);
225
226 template <typename BuiltinFuncT>
227 decltype(auto) callBuiltin(BuiltinFuncT &&BuiltinFunc) {
228 using RetT = std::invoke_result_t<BuiltinFuncT &, FuncBase &>;
229 if constexpr (std::is_void_v<RetT>) {
230 std::invoke(std::forward<BuiltinFuncT>(BuiltinFunc), *this);
231 } else {
232 return std::invoke(std::forward<BuiltinFuncT>(BuiltinFunc), *this);
233 }
234 }
235
236 template <typename T>
237 std::enable_if_t<is_arithmetic_unref_v<T>, Var<T>>
238 atomicAdd(const Var<T *> &Addr, const Var<T> &Val);
239 template <typename T>
240 std::enable_if_t<is_arithmetic_unref_v<T>, Var<T>>
241 atomicSub(const Var<T *> &Addr, const Var<T> &Val);
242 template <typename T>
243 std::enable_if_t<is_arithmetic_unref_v<T>, Var<T>>
244 atomicMax(const Var<T *> &Addr, const Var<T> &Val);
245 template <typename T>
246 std::enable_if_t<is_arithmetic_unref_v<T>, Var<T>>
247 atomicMin(const Var<T *> &Addr, const Var<T> &Val);
248
249 template <EmissionPolicy Policy = EmissionPolicy::Eager, typename IterT,
250 typename InitT, typename UpperT, typename IncT,
251 typename BodyLambda = EmptyLambda>
252 auto forLoop(Var<IterT> &Iter, const Var<InitT> &Init,
253 const Var<UpperT> &Upper, const Var<IncT> &Inc,
254 BodyLambda &&Body = {}) {
255 static_assert(is_mutable_v<IterT>, "Loop iterator must be mutable");
256 if constexpr (Policy == EmissionPolicy::Eager) {
257 beginFor(Iter, Init, Upper, Inc);
258 std::forward<BodyLambda>(Body)();
259 endFor();
260 return EmittedLoopTag{};
261 } else {
262 LoopBoundInfo<IterT> BoundsInfo{Iter, Init, Upper, Inc};
263 return ForLoopBuilder<IterT, BodyLambda>(BoundsInfo, *this,
264 std::forward<BodyLambda>(Body));
265 }
266 }
267
268 template <typename... LoopBuilders>
269 auto buildLoopNest(LoopBuilders &&...Loops) {
270 using FirstBuilder = std::remove_reference_t<
271 std::tuple_element_t<0, std::tuple<LoopBuilders...>>>;
272 using T = typename FirstBuilder::LoopIndexType;
274 *this, std::forward<LoopBuilders>(Loops)...);
275 }
276
277 template <typename T> void ret(const Var<T> &RetVal);
278
279 void ret();
280
281 const std::string &getName() const { return Name; }
282
283 void setName(const std::string &NewName);
284
285 // Update only the frontend-visible function name without touching backend IR.
286 void setFrontendName(const std::string &NewName) { Name = NewName; }
287
288 // Convert the given Var's value to type U and return a new Var holding
289 // the converted value. Preserves cv-qualifiers but drops references.
290 // Note: prefer calling var.convert<U>() directly on the Var.
291 template <typename U, typename T> auto convert(const Var<T> &V) {
292 return V.template convert<U>();
293 }
294};
295
296template <typename RetT, typename... ArgT> class Func final : public FuncBase {
297private:
298 Dispatcher &Dispatch;
299 RetT (*CompiledFunc)(ArgT...) = nullptr;
300 // Optional because Var<ArgT> is not default constructible.
301 std::tuple<std::optional<Var<ArgT>>...> ArgumentsT;
302
303private:
304 template <typename T, std::size_t ArgIdx> Var<T> createArg() {
305 auto Var = declVar<T>("arg." + std::to_string(ArgIdx));
306 if constexpr (std::is_pointer_v<T>) {
307 Var.storeAddress(FuncBase::getArg(ArgIdx));
308 } else {
309 Var.storeValue(FuncBase::getArg(ArgIdx));
310 }
311 return Var;
312 }
313
314 template <std::size_t... Is> void declArgsImpl(std::index_sequence<Is...>) {
316
317 (std::get<Is>(ArgumentsT).emplace(createArg<ArgT, Is>()), ...);
318
320 }
321
322 template <std::size_t... Is> auto getArgsImpl(std::index_sequence<Is...>) {
323 return std::tie(*std::get<Is>(ArgumentsT)...);
324 }
325
326public:
327 Func(JitModule &J, CodeBuilder &CB, const std::string &Name,
328 Dispatcher &Dispatch, bool IsKernel = false)
329 : FuncBase(J, CB, Name, TypeMap<RetT>::get(), {TypeMap<ArgT>::get()...},
330 IsKernel),
331 Dispatch(Dispatch) {}
332
333 RetT operator()(ArgT... Args);
334
335 void declArgs() { declArgsImpl(std::index_sequence_for<ArgT...>{}); }
336
337 auto getArgs() { return getArgsImpl(std::index_sequence_for<ArgT...>{}); }
338
339 template <std::size_t Idx> auto &getArg() {
340 return *std::get<Idx>(ArgumentsT);
341 }
342
343 auto getCompiledFunc() const { return CompiledFunc; }
344
345 void setCompiledFunc(RetT (*CompiledFuncIn)(ArgT...)) {
346 CompiledFunc = CompiledFuncIn;
347 }
348};
349
350// beginFor implementation
351template <typename IterT, typename InitT, typename UpperT, typename IncT>
352void FuncBase::beginFor(Var<IterT> &IterVar, const Var<InitT> &Init,
353 const Var<UpperT> &UpperBound, const Var<IncT> &Inc,
354 const char *File, int Line, LoopHints Hints) {
355 static_assert(std::is_integral_v<std::remove_const_t<IterT>>,
356 "Loop iterator must be an integral type");
357 static_assert(is_mutable_v<IterT>, "Loop iterator must be mutable");
358
359 CB->beginFor(IterVar.getSlot(), IterVar.getValueType(), Init.loadValue(),
360 UpperBound.loadValue(), Inc.loadValue(),
361 std::is_signed_v<std::remove_const_t<IterT>>, File, Line, Hints);
362}
363
364template <typename CondLambda>
365void FuncBase::beginWhile(CondLambda &&Cond, const char *File, int Line) {
366 CB->beginWhile([Cond = std::forward<CondLambda>(
367 Cond)]() -> IRValue * { return Cond().loadValue(); },
368 File, Line);
369}
370
371template <typename Sig, typename... ArgVars>
372std::enable_if_t<std::is_void_v<typename FnSig<Sig>::RetT>, void>
373FuncBase::call(const std::string &Name, ArgVars &&...ArgsVars) {
374 using RetT = typename FnSig<Sig>::RetT;
375 using ArgT = typename FnSig<Sig>::ArgsTList;
376
377 auto GetArgVal = [](auto &&Arg) {
378 using ArgVarT = std::decay_t<decltype(Arg)>;
379 if constexpr (std::is_pointer_v<typename ArgVarT::ValueType>)
380 return Arg.loadAddress();
381 else
382 return Arg.loadValue();
383 };
384
385 std::vector<IRType> ArgTys = unpackArgTypes(ArgT{});
387 {GetArgVal(ArgsVars)...});
388}
389
390template <typename Sig>
391std::enable_if_t<!std::is_void_v<typename FnSig<Sig>::RetT>,
393FuncBase::call(const std::string &Name) {
394 using RetT = typename FnSig<Sig>::RetT;
395
397 Var<RetT> Ret = declVar<RetT>("ret");
398 Ret.storeValue(Call);
399 return Ret;
400}
401
402template <typename Sig>
403std::enable_if_t<std::is_void_v<typename FnSig<Sig>::RetT>, void>
404FuncBase::call(const std::string &Name) {
405 using RetT = typename FnSig<Sig>::RetT;
407}
408
409template <typename... Ts>
410std::vector<IRType> unpackArgTypes(ArgTypeList<Ts...>) {
411 return {TypeMap<Ts>::get()...};
412}
413
414template <typename Sig, typename... ArgVars>
415std::enable_if_t<!std::is_void_v<typename FnSig<Sig>::RetT>,
416 Var<typename FnSig<Sig>::RetT>>
417FuncBase::call(const std::string &Name, ArgVars &&...ArgsVars) {
418 using RetT = typename FnSig<Sig>::RetT;
419 using ArgT = typename FnSig<Sig>::ArgsTList;
420
421 auto GetArgVal = [](auto &&Arg) {
422 using ArgVarT = std::decay_t<decltype(Arg)>;
423 if constexpr (std::is_pointer_v<typename ArgVarT::ValueType>)
424 return Arg.loadAddress();
425 else
426 return Arg.loadValue();
427 };
428
429 std::vector<IRType> ArgTys = unpackArgTypes(ArgT{});
430 std::vector<IRValue *> ArgVals = {GetArgVal(ArgsVars)...};
431
432 auto Call =
433 getCodeBuilder().createCall(Name, TypeMap<RetT>::get(), ArgTys, ArgVals);
434
435 Var<RetT> Ret = declVar<RetT>("ret");
436 Ret.storeValue(Call);
437 return Ret;
438}
439
440template <typename T>
441std::enable_if_t<is_arithmetic_unref_v<T>, Var<T>>
442FuncBase::atomicAdd(const Var<T *> &Addr, const Var<T> &Val) {
443 static_assert(std::is_arithmetic_v<T>, "atomicAdd requires arithmetic type");
444
445 IRValue *Result = CB->createAtomicAdd(Addr.loadAddress(), Val.loadValue());
446 auto Ret = declVar<T>("atomic.add.res.");
447 Ret.storeValue(Result);
448 return Ret;
449}
450
451template <typename T>
452std::enable_if_t<is_arithmetic_unref_v<T>, Var<T>>
453FuncBase::atomicSub(const Var<T *> &Addr, const Var<T> &Val) {
454 static_assert(std::is_arithmetic_v<T>, "atomicSub requires arithmetic type");
455
456 IRValue *Result = CB->createAtomicSub(Addr.loadAddress(), Val.loadValue());
457 auto Ret = declVar<T>("atomic.sub.res.");
458 Ret.storeValue(Result);
459 return Ret;
460}
461
462template <typename T>
463std::enable_if_t<is_arithmetic_unref_v<T>, Var<T>>
464FuncBase::atomicMax(const Var<T *> &Addr, const Var<T> &Val) {
465 static_assert(std::is_arithmetic_v<T>, "atomicMax requires arithmetic type");
466
467 IRValue *Result = CB->createAtomicMax(Addr.loadAddress(), Val.loadValue());
468 auto Ret = declVar<T>("atomic.max.res.");
469 Ret.storeValue(Result);
470 return Ret;
471}
472
473template <typename T>
474std::enable_if_t<is_arithmetic_unref_v<T>, Var<T>>
475FuncBase::atomicMin(const Var<T *> &Addr, const Var<T> &Val) {
476 static_assert(std::is_arithmetic_v<T>, "atomicMin requires arithmetic type");
477
478 IRValue *Result = CB->createAtomicMin(Addr.loadAddress(), Val.loadValue());
479 auto Ret = declVar<T>("atomic.min.res.");
480 Ret.storeValue(Result);
481 return Ret;
482}
483
484inline void FuncBase::ret() { CB->createRetVoid(); }
485
486template <typename T> void FuncBase::ret(const Var<T> &RetVal) {
487 IRValue *RetValue = RetVal.loadValue();
488 CB->createRet(RetValue);
489}
490} // namespace proteus
491
492#endif // PROTEUS_FRONTEND_FUNC_H
char int void ** Args
Definition CompilerInterfaceHost.cpp:23
Definition CodeBuilder.h:70
virtual VarAlloc allocPointer(const std::string &Name, IRType ElemTy, unsigned AddrSpace=0)=0
virtual void clearInsertPoint()=0
virtual IRValue * createCall(const std::string &FName, IRType RetTy, const std::vector< IRType > &ArgTys, const std::vector< IRValue * > &Args)=0
virtual void setInsertPointAtEntry()=0
virtual IRValue * createAtomicAdd(IRValue *Addr, IRValue *Val)=0
virtual void beginFor(IRValue *IterSlot, IRType IterTy, IRValue *InitVal, IRValue *UpperBoundVal, IRValue *IncVal, bool IsSigned, const char *File, int Line, LoopHints Hints={})=0
virtual VarAlloc allocScalar(const std::string &Name, IRType ValueTy)=0
virtual IRValue * createAtomicMax(IRValue *Addr, IRValue *Val)=0
virtual void beginWhile(std::function< IRValue *()> CondFn, const char *File, int Line)=0
virtual IRValue * createAtomicSub(IRValue *Addr, IRValue *Val)=0
virtual IRValue * createAtomicMin(IRValue *Addr, IRValue *Val)=0
virtual VarAlloc allocArray(const std::string &Name, AddressSpace AS, IRType ElemTy, size_t NElem)=0
virtual void createRetVoid()=0
virtual void createRet(IRValue *V)=0
Definition Dispatcher.h:75
Definition LoopNest.h:24
Definition Func.h:45
Var< T > declVar(size_t NElem, AddressSpace AS=AddressSpace::DEFAULT, const std::string &Name="array_var")
Definition Func.h:91
std::enable_if_t< is_arithmetic_unref_v< T >, Var< T > > atomicSub(const Var< T * > &Addr, const Var< T > &Val)
Definition Func.h:453
const std::string & getName() const
Definition Func.h:281
bool IsKernel
Definition Func.h:60
decltype(auto) callBuiltin(BuiltinFuncT &&BuiltinFunc)
Definition Func.h:227
void ifThen(const Var< bool > &CondVar, BodyLambda &&Body, const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.h:179
Var< T > defVar(const T &Val, const std::string &Name="var")
Definition Func.h:112
void beginIf(const Var< bool > &CondVar, const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.cpp:40
Var< T > defVar(const Var< U > &Val, const std::string &Name="var")
Definition Func.h:120
auto defVar(std::pair< T, NameT > P)
Definition Func.h:137
auto defRuntimeConsts(ArgT &&...Args)
Definition Func.h:158
bool isKernel() const
Definition Func.h:70
Var< U > defVar(const Var< U > &Val, const std::string &Name="var")
Definition Func.h:128
CodeBuilder & getCodeBuilder()
Get the underlying CodeBuilder for direct IR generation.
Definition Func.cpp:30
auto declVars(NameTs &&...Names)
Definition Func.h:105
auto defVars(ArgT &&...Args)
Definition Func.h:141
void endFunction()
Definition Func.cpp:36
void beginWhile(CondLambda &&Cond, const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.h:365
void beginFunction(const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.cpp:32
IRFunction * Func
Definition Func.h:57
IRFunction * getFunction()
Definition Func.cpp:38
void whileLoop(CondLambda &&Cond, BodyLambda &&Body, const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.h:200
void endIf()
Definition Func.cpp:45
CodeBuilder * CB
Definition Func.h:56
auto forLoop(Var< IterT > &Iter, const Var< InitT > &Init, const Var< UpperT > &Upper, const Var< IncT > &Inc, BodyLambda &&Body={})
Definition Func.h:252
std::string Name
Definition Func.h:55
auto buildLoopNest(LoopBuilders &&...Loops)
Definition Func.h:269
void ret()
Definition Func.h:484
JitModule & J
Definition Func.h:53
void endWhile()
Definition Func.cpp:49
JitModule & getJitModule()
Definition Func.h:47
Var< const T > defRuntimeConst(std::pair< T, NameT > P)
Definition Func.h:154
auto declVars()
Definition Func.h:100
IRValue * getArg(size_t Idx)
Definition Func.cpp:20
void beginFor(Var< IterT > &IterVar, const Var< InitT > &InitVar, const Var< UpperT > &UpperBound, const Var< IncT > &IncVar, const char *File=__builtin_FILE(), int Line=__builtin_LINE(), LoopHints Hints={})
Definition Func.h:352
Var< const T > defRuntimeConst(const T &Val, const std::string &Name="run.const.var")
Definition Func.h:146
void function(BodyLambda &&Body, const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.h:167
void setFrontendName(const std::string &NewName)
Definition Func.h:286
void endFor()
Definition Func.cpp:47
auto convert(const Var< T > &V)
Definition Func.h:291
std::enable_if_t<!std::is_void_v< typename FnSig< Sig >::RetT >, Var< typename FnSig< Sig >::RetT > > call(const std::string &Name)
Definition Func.h:393
Var< T > declVar(const std::string &Name="var")
Definition Func.h:76
std::enable_if_t< is_arithmetic_unref_v< T >, Var< T > > atomicAdd(const Var< T * > &Addr, const Var< T > &Val)
Definition Func.h:442
std::enable_if_t< is_arithmetic_unref_v< T >, Var< T > > atomicMax(const Var< T * > &Addr, const Var< T > &Val)
Definition Func.h:464
std::enable_if_t< is_arithmetic_unref_v< T >, Var< T > > atomicMin(const Var< T * > &Addr, const Var< T > &Val)
Definition Func.h:475
void setName(const std::string &NewName)
Definition Func.cpp:15
Definition Func.h:296
auto & getArg()
Definition Func.h:339
auto getCompiledFunc() const
Definition Func.h:343
Func(JitModule &J, CodeBuilder &CB, const std::string &Name, Dispatcher &Dispatch, bool IsKernel=false)
Definition Func.h:327
auto getArgs()
Definition Func.h:337
void setCompiledFunc(RetT(*CompiledFuncIn)(ArgT...))
Definition Func.h:345
RetT operator()(ArgT... Args)
Definition JitFrontend.h:178
void declArgs()
Definition Func.h:335
Definition IRFunction.h:9
Definition IRValue.h:15
Definition JitFrontend.h:19
Definition LoopNest.h:76
Definition MemoryCache.h:27
AddressSpace
Definition AddressSpace.h:6
std::vector< IRType > unpackArgTypes(ArgTypeList< Ts... >)
Definition Func.h:410
void setLaunchBoundsForKernel(Function &F, int MaxThreadsPerSM, int MinBlocksPerSM=0)
Definition CoreLLVMCUDA.h:87
EmissionPolicy
Definition Func.h:35
Definition Func.h:24
Definition Func.h:39
Definition Func.h:31
void operator()() const
Definition Func.h:32
RetT_ RetT
Definition Func.h:28
Definition Func.h:25
Definition IRType.h:34
bool Signed
Signedness of the type (meaningful for integer kinds and pointer-to-int).
Definition IRType.h:38
std::size_t NElem
Number of array elements; only meaningful when Kind == Array.
Definition IRType.h:41
IRTypeKind ElemKind
Element type kind; meaningful when Kind == Pointer or Kind == Array.
Definition IRType.h:44
Definition Func.h:41
Definition CodeBuilder.h:21
Definition TypeMap.h:15
Definition Var.h:15