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
59public:
60 FuncBase(JitModule &J, CodeBuilder &CB, const std::string &Name, IRType RetTy,
61 const std::vector<IRType> &ArgTys);
63
65 IRValue *getArg(size_t Idx);
66
67#if PROTEUS_ENABLE_CUDA || PROTEUS_ENABLE_HIP
68 // Kernel management.
69 void setKernel();
70 void setLaunchBoundsForKernel(int MaxThreadsPerBlock, int MinBlocksPerSM);
71#endif
72
73 template <typename T> Var<T> declVar(const std::string &Name = "var") {
74 static_assert(!std::is_array_v<T>, "Expected non-array type");
75 static_assert(!std::is_reference_v<T>,
76 "declVar does not support reference types");
77
78 if constexpr (std::is_pointer_v<T>) {
80 return Var<T>{CB->allocPointer(Name, ElemIRTy), *CB};
81 } else {
82 IRType AllocaIRTy = TypeMap<T>::get();
83 return Var<T>{CB->allocScalar(Name, AllocaIRTy), *CB};
84 }
85 }
86
87 template <typename T>
89 const std::string &Name = "array_var") {
90 static_assert(std::is_array_v<T>, "Expected array type");
91
92 IRType ArrIRTy = TypeMap<T>::get(NElem);
93 IRType ElemIRTy{ArrIRTy.ElemKind, ArrIRTy.Signed};
94 return Var<T>{CB->allocArray(Name, AS, ElemIRTy, ArrIRTy.NElem), *CB};
95 }
96
97 template <typename... Ts> auto declVars() {
98 return std::make_tuple(declVar<Ts>()...);
99 }
100
101 template <typename... Ts, typename... NameTs>
102 auto declVars(NameTs &&...Names) {
103 static_assert(sizeof...(Ts) == sizeof...(NameTs),
104 "Number of types must match number of names");
105 return std::make_tuple(declVar<Ts>(std::forward<NameTs>(Names))...);
106 }
107
108 template <typename T>
109 Var<T> defVar(const T &Val, const std::string &Name = "var") {
110 using RawT = std::remove_const_t<T>;
111 Var<RawT> V = declVar<RawT>(Name);
112 V = Val;
113 return Var<T>(V);
114 }
115
116 template <typename T, typename U>
117 Var<T> defVar(const Var<U> &Val, const std::string &Name = "var") {
118 using RawT = std::remove_const_t<T>;
119 Var<RawT> Res = declVar<RawT>(Name);
120 Res = Val;
121 return Var<T>(Res);
122 }
123
124 template <typename U>
125 Var<U> defVar(const Var<U> &Val, const std::string &Name = "var") {
126 Var<U> Res = declVar<U>(Name);
127 Res = Val;
128 return Res;
129 }
130
131 template <
132 typename T, typename NameT,
133 typename = std::enable_if_t<std::is_convertible_v<NameT, std::string>>>
134 auto defVar(std::pair<T, NameT> P) {
135 return defVar(P.first, std::string(P.second));
136 }
137
138 template <typename... ArgT> auto defVars(ArgT &&...Args) {
139 return std::make_tuple(defVar(std::forward<ArgT>(Args))...);
140 }
141
142 template <typename T>
144 const std::string &Name = "run.const.var") {
145 return Var<const T>(defVar<T>(Val, Name));
146 }
147
148 template <
149 typename T, typename NameT,
150 typename = std::enable_if_t<std::is_convertible_v<NameT, std::string>>>
151 Var<const T> defRuntimeConst(std::pair<T, NameT> P) {
152 return defRuntimeConst(P.first, std::string(P.second));
153 }
154
155 template <typename... ArgT> auto defRuntimeConsts(ArgT &&...Args) {
156 return std::make_tuple(defRuntimeConst(std::forward<ArgT>(Args))...);
157 }
158
159 void beginFunction(const char *File = __builtin_FILE(),
160 int Line = __builtin_LINE());
161 void endFunction();
162
163 template <typename BodyLambda>
164 void function(BodyLambda &&Body, const char *File = __builtin_FILE(),
165 int Line = __builtin_LINE()) {
166 beginFunction(File, Line);
167 std::forward<BodyLambda>(Body)();
168 endFunction();
169 }
170
171 void beginIf(const Var<bool> &CondVar, const char *File = __builtin_FILE(),
172 int Line = __builtin_LINE());
173 void endIf();
174
175 template <typename BodyLambda>
176 void ifThen(const Var<bool> &CondVar, BodyLambda &&Body,
177 const char *File = __builtin_FILE(),
178 int Line = __builtin_LINE()) {
179 beginIf(CondVar, File, Line);
180 std::forward<BodyLambda>(Body)();
181 endIf();
182 }
183
184 template <typename IterT, typename InitT, typename UpperT, typename IncT>
185 void beginFor(Var<IterT> &IterVar, const Var<InitT> &InitVar,
186 const Var<UpperT> &UpperBound, const Var<IncT> &IncVar,
187 const char *File = __builtin_FILE(),
188 int Line = __builtin_LINE(), LoopHints Hints = {});
189 void endFor();
190
191 template <typename CondLambda>
192 void beginWhile(CondLambda &&Cond, const char *File = __builtin_FILE(),
193 int Line = __builtin_LINE());
194 void endWhile();
195
196 template <typename CondLambda, typename BodyLambda>
197 void whileLoop(CondLambda &&Cond, BodyLambda &&Body,
198 const char *File = __builtin_FILE(),
199 int Line = __builtin_LINE()) {
200 beginWhile(std::forward<CondLambda>(Cond), File, Line);
201 std::forward<BodyLambda>(Body)();
202 endWhile();
203 }
204
205 template <typename Sig>
206 std::enable_if_t<!std::is_void_v<typename FnSig<Sig>::RetT>,
208 call(const std::string &Name);
209
210 template <typename Sig>
211 std::enable_if_t<std::is_void_v<typename FnSig<Sig>::RetT>, void>
212 call(const std::string &Name);
213
214 template <typename Sig, typename... ArgVars>
215 std::enable_if_t<!std::is_void_v<typename FnSig<Sig>::RetT>,
217 call(const std::string &Name, ArgVars &&...ArgsVars);
218
219 template <typename Sig, typename... ArgVars>
220 std::enable_if_t<std::is_void_v<typename FnSig<Sig>::RetT>, void>
221 call(const std::string &Name, ArgVars &&...ArgsVars);
222
223 template <typename BuiltinFuncT>
224 decltype(auto) callBuiltin(BuiltinFuncT &&BuiltinFunc) {
225 using RetT = std::invoke_result_t<BuiltinFuncT &, FuncBase &>;
226 if constexpr (std::is_void_v<RetT>) {
227 std::invoke(std::forward<BuiltinFuncT>(BuiltinFunc), *this);
228 } else {
229 return std::invoke(std::forward<BuiltinFuncT>(BuiltinFunc), *this);
230 }
231 }
232
233 template <typename T>
234 std::enable_if_t<is_arithmetic_unref_v<T>, Var<T>>
235 atomicAdd(const Var<T *> &Addr, const Var<T> &Val);
236 template <typename T>
237 std::enable_if_t<is_arithmetic_unref_v<T>, Var<T>>
238 atomicSub(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 atomicMax(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 atomicMin(const Var<T *> &Addr, const Var<T> &Val);
245
246 template <EmissionPolicy Policy = EmissionPolicy::Eager, typename IterT,
247 typename InitT, typename UpperT, typename IncT,
248 typename BodyLambda = EmptyLambda>
249 auto forLoop(Var<IterT> &Iter, const Var<InitT> &Init,
250 const Var<UpperT> &Upper, const Var<IncT> &Inc,
251 BodyLambda &&Body = {}) {
252 static_assert(is_mutable_v<IterT>, "Loop iterator must be mutable");
253 if constexpr (Policy == EmissionPolicy::Eager) {
254 beginFor(Iter, Init, Upper, Inc);
255 std::forward<BodyLambda>(Body)();
256 endFor();
257 return EmittedLoopTag{};
258 } else {
259 LoopBoundInfo<IterT> BoundsInfo{Iter, Init, Upper, Inc};
260 return ForLoopBuilder<IterT, BodyLambda>(BoundsInfo, *this,
261 std::forward<BodyLambda>(Body));
262 }
263 }
264
265 template <typename... LoopBuilders>
266 auto buildLoopNest(LoopBuilders &&...Loops) {
267 using FirstBuilder = std::remove_reference_t<
268 std::tuple_element_t<0, std::tuple<LoopBuilders...>>>;
269 using T = typename FirstBuilder::LoopIndexType;
271 *this, std::forward<LoopBuilders>(Loops)...);
272 }
273
274 template <typename T> void ret(const Var<T> &RetVal);
275
276 void ret();
277
278 const std::string &getName() const { return Name; }
279
280 void setName(const std::string &NewName);
281
282 // Convert the given Var's value to type U and return a new Var holding
283 // the converted value. Preserves cv-qualifiers but drops references.
284 // Note: prefer calling var.convert<U>() directly on the Var.
285 template <typename U, typename T> auto convert(const Var<T> &V) {
286 return V.template convert<U>();
287 }
288};
289
290template <typename RetT, typename... ArgT> class Func final : public FuncBase {
291private:
292 Dispatcher &Dispatch;
293 RetT (*CompiledFunc)(ArgT...) = nullptr;
294 // Optional because Var<ArgT> is not default constructible.
295 std::tuple<std::optional<Var<ArgT>>...> ArgumentsT;
296
297private:
298 template <typename T, std::size_t ArgIdx> Var<T> createArg() {
299 auto Var = declVar<T>("arg." + std::to_string(ArgIdx));
300 if constexpr (std::is_pointer_v<T>) {
301 Var.storeAddress(FuncBase::getArg(ArgIdx));
302 } else {
303 Var.storeValue(FuncBase::getArg(ArgIdx));
304 }
305 return Var;
306 }
307
308 template <std::size_t... Is> void declArgsImpl(std::index_sequence<Is...>) {
310
311 (std::get<Is>(ArgumentsT).emplace(createArg<ArgT, Is>()), ...);
312
314 }
315
316 template <std::size_t... Is> auto getArgsImpl(std::index_sequence<Is...>) {
317 return std::tie(*std::get<Is>(ArgumentsT)...);
318 }
319
320public:
321 Func(JitModule &J, CodeBuilder &CB, const std::string &Name,
322 Dispatcher &Dispatch)
323 : FuncBase(J, CB, Name, TypeMap<RetT>::get(), {TypeMap<ArgT>::get()...}),
324 Dispatch(Dispatch) {}
325
326 RetT operator()(ArgT... Args);
327
328 void declArgs() { declArgsImpl(std::index_sequence_for<ArgT...>{}); }
329
330 auto getArgs() { return getArgsImpl(std::index_sequence_for<ArgT...>{}); }
331
332 template <std::size_t Idx> auto &getArg() {
333 return *std::get<Idx>(ArgumentsT);
334 }
335
336 auto getCompiledFunc() const { return CompiledFunc; }
337
338 void setCompiledFunc(RetT (*CompiledFuncIn)(ArgT...)) {
339 CompiledFunc = CompiledFuncIn;
340 }
341};
342
343// beginFor implementation
344template <typename IterT, typename InitT, typename UpperT, typename IncT>
345void FuncBase::beginFor(Var<IterT> &IterVar, const Var<InitT> &Init,
346 const Var<UpperT> &UpperBound, const Var<IncT> &Inc,
347 const char *File, int Line, LoopHints Hints) {
348 static_assert(std::is_integral_v<std::remove_const_t<IterT>>,
349 "Loop iterator must be an integral type");
350 static_assert(is_mutable_v<IterT>, "Loop iterator must be mutable");
351
352 CB->beginFor(IterVar.getSlot(), IterVar.getValueType(), Init.loadValue(),
353 UpperBound.loadValue(), Inc.loadValue(),
354 std::is_signed_v<std::remove_const_t<IterT>>, File, Line, Hints);
355}
356
357template <typename CondLambda>
358void FuncBase::beginWhile(CondLambda &&Cond, const char *File, int Line) {
359 CB->beginWhile([Cond = std::forward<CondLambda>(
360 Cond)]() -> IRValue * { return Cond().loadValue(); },
361 File, Line);
362}
363
364template <typename Sig, typename... ArgVars>
365std::enable_if_t<std::is_void_v<typename FnSig<Sig>::RetT>, void>
366FuncBase::call(const std::string &Name, ArgVars &&...ArgsVars) {
367 using RetT = typename FnSig<Sig>::RetT;
368 using ArgT = typename FnSig<Sig>::ArgsTList;
369
370 auto GetArgVal = [](auto &&Arg) {
371 using ArgVarT = std::decay_t<decltype(Arg)>;
372 if constexpr (std::is_pointer_v<typename ArgVarT::ValueType>)
373 return Arg.loadAddress();
374 else
375 return Arg.loadValue();
376 };
377
378 std::vector<IRType> ArgTys = unpackArgTypes(ArgT{});
380 {GetArgVal(ArgsVars)...});
381}
382
383template <typename Sig>
384std::enable_if_t<!std::is_void_v<typename FnSig<Sig>::RetT>,
386FuncBase::call(const std::string &Name) {
387 using RetT = typename FnSig<Sig>::RetT;
388
390 Var<RetT> Ret = declVar<RetT>("ret");
391 Ret.storeValue(Call);
392 return Ret;
393}
394
395template <typename Sig>
396std::enable_if_t<std::is_void_v<typename FnSig<Sig>::RetT>, void>
397FuncBase::call(const std::string &Name) {
398 using RetT = typename FnSig<Sig>::RetT;
400}
401
402template <typename... Ts>
403std::vector<IRType> unpackArgTypes(ArgTypeList<Ts...>) {
404 return {TypeMap<Ts>::get()...};
405}
406
407template <typename Sig, typename... ArgVars>
408std::enable_if_t<!std::is_void_v<typename FnSig<Sig>::RetT>,
409 Var<typename FnSig<Sig>::RetT>>
410FuncBase::call(const std::string &Name, ArgVars &&...ArgsVars) {
411 using RetT = typename FnSig<Sig>::RetT;
412 using ArgT = typename FnSig<Sig>::ArgsTList;
413
414 auto GetArgVal = [](auto &&Arg) {
415 using ArgVarT = std::decay_t<decltype(Arg)>;
416 if constexpr (std::is_pointer_v<typename ArgVarT::ValueType>)
417 return Arg.loadAddress();
418 else
419 return Arg.loadValue();
420 };
421
422 std::vector<IRType> ArgTys = unpackArgTypes(ArgT{});
423 std::vector<IRValue *> ArgVals = {GetArgVal(ArgsVars)...};
424
425 auto Call =
426 getCodeBuilder().createCall(Name, TypeMap<RetT>::get(), ArgTys, ArgVals);
427
428 Var<RetT> Ret = declVar<RetT>("ret");
429 Ret.storeValue(Call);
430 return Ret;
431}
432
433template <typename T>
434std::enable_if_t<is_arithmetic_unref_v<T>, Var<T>>
435FuncBase::atomicAdd(const Var<T *> &Addr, const Var<T> &Val) {
436 static_assert(std::is_arithmetic_v<T>, "atomicAdd requires arithmetic type");
437
438 IRValue *Result = CB->createAtomicAdd(Addr.loadAddress(), Val.loadValue());
439 auto Ret = declVar<T>("atomic.add.res.");
440 Ret.storeValue(Result);
441 return Ret;
442}
443
444template <typename T>
445std::enable_if_t<is_arithmetic_unref_v<T>, Var<T>>
446FuncBase::atomicSub(const Var<T *> &Addr, const Var<T> &Val) {
447 static_assert(std::is_arithmetic_v<T>, "atomicSub requires arithmetic type");
448
449 IRValue *Result = CB->createAtomicSub(Addr.loadAddress(), Val.loadValue());
450 auto Ret = declVar<T>("atomic.sub.res.");
451 Ret.storeValue(Result);
452 return Ret;
453}
454
455template <typename T>
456std::enable_if_t<is_arithmetic_unref_v<T>, Var<T>>
457FuncBase::atomicMax(const Var<T *> &Addr, const Var<T> &Val) {
458 static_assert(std::is_arithmetic_v<T>, "atomicMax requires arithmetic type");
459
460 IRValue *Result = CB->createAtomicMax(Addr.loadAddress(), Val.loadValue());
461 auto Ret = declVar<T>("atomic.max.res.");
462 Ret.storeValue(Result);
463 return Ret;
464}
465
466template <typename T>
467std::enable_if_t<is_arithmetic_unref_v<T>, Var<T>>
468FuncBase::atomicMin(const Var<T *> &Addr, const Var<T> &Val) {
469 static_assert(std::is_arithmetic_v<T>, "atomicMin requires arithmetic type");
470
471 IRValue *Result = CB->createAtomicMin(Addr.loadAddress(), Val.loadValue());
472 auto Ret = declVar<T>("atomic.min.res.");
473 Ret.storeValue(Result);
474 return Ret;
475}
476
477inline void FuncBase::ret() { CB->createRetVoid(); }
478
479template <typename T> void FuncBase::ret(const Var<T> &RetVal) {
480 IRValue *RetValue = RetVal.loadValue();
481 CB->createRet(RetValue);
482}
483} // namespace proteus
484
485#endif // PROTEUS_FRONTEND_FUNC_H
char int void ** Args
Definition CompilerInterfaceHost.cpp:22
Definition CodeBuilder.h:66
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:74
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:88
std::enable_if_t< is_arithmetic_unref_v< T >, Var< T > > atomicSub(const Var< T * > &Addr, const Var< T > &Val)
Definition Func.h:446
const std::string & getName() const
Definition Func.h:278
decltype(auto) callBuiltin(BuiltinFuncT &&BuiltinFunc)
Definition Func.h:224
void ifThen(const Var< bool > &CondVar, BodyLambda &&Body, const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.h:176
Var< T > defVar(const T &Val, const std::string &Name="var")
Definition Func.h:109
void beginIf(const Var< bool > &CondVar, const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.cpp:41
Var< T > defVar(const Var< U > &Val, const std::string &Name="var")
Definition Func.h:117
auto defVar(std::pair< T, NameT > P)
Definition Func.h:134
auto defRuntimeConsts(ArgT &&...Args)
Definition Func.h:155
Var< U > defVar(const Var< U > &Val, const std::string &Name="var")
Definition Func.h:125
CodeBuilder & getCodeBuilder()
Get the underlying CodeBuilder for direct IR generation.
Definition Func.cpp:31
auto declVars(NameTs &&...Names)
Definition Func.h:102
auto defVars(ArgT &&...Args)
Definition Func.h:138
void endFunction()
Definition Func.cpp:37
void beginWhile(CondLambda &&Cond, const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.h:358
void beginFunction(const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.cpp:33
IRFunction * Func
Definition Func.h:57
IRFunction * getFunction()
Definition Func.cpp:39
void whileLoop(CondLambda &&Cond, BodyLambda &&Body, const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.h:197
void endIf()
Definition Func.cpp:46
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:249
std::string Name
Definition Func.h:55
auto buildLoopNest(LoopBuilders &&...Loops)
Definition Func.h:266
void ret()
Definition Func.h:477
JitModule & J
Definition Func.h:53
void endWhile()
Definition Func.cpp:50
JitModule & getJitModule()
Definition Func.h:47
Var< const T > defRuntimeConst(std::pair< T, NameT > P)
Definition Func.h:151
auto declVars()
Definition Func.h:97
IRValue * getArg(size_t Idx)
Definition Func.cpp:19
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:345
Var< const T > defRuntimeConst(const T &Val, const std::string &Name="run.const.var")
Definition Func.h:143
void function(BodyLambda &&Body, const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.h:164
void endFor()
Definition Func.cpp:48
auto convert(const Var< T > &V)
Definition Func.h:285
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:386
Var< T > declVar(const std::string &Name="var")
Definition Func.h:73
std::enable_if_t< is_arithmetic_unref_v< T >, Var< T > > atomicAdd(const Var< T * > &Addr, const Var< T > &Val)
Definition Func.h:435
std::enable_if_t< is_arithmetic_unref_v< T >, Var< T > > atomicMax(const Var< T * > &Addr, const Var< T > &Val)
Definition Func.h:457
std::enable_if_t< is_arithmetic_unref_v< T >, Var< T > > atomicMin(const Var< T * > &Addr, const Var< T > &Val)
Definition Func.h:468
void setName(const std::string &NewName)
Definition Func.cpp:14
Definition Func.h:290
auto & getArg()
Definition Func.h:332
auto getCompiledFunc() const
Definition Func.h:336
auto getArgs()
Definition Func.h:330
void setCompiledFunc(RetT(*CompiledFuncIn)(ArgT...))
Definition Func.h:338
RetT operator()(ArgT... Args)
Definition JitFrontend.h:178
Func(JitModule &J, CodeBuilder &CB, const std::string &Name, Dispatcher &Dispatch)
Definition Func.h:321
void declArgs()
Definition Func.h:328
Definition IRFunction.h:9
Definition IRValue.h:15
Definition JitFrontend.h:18
Definition LoopNest.h:76
Definition MemoryCache.h:26
AddressSpace
Definition AddressSpace.h:6
std::vector< IRType > unpackArgTypes(ArgTypeList< Ts... >)
Definition Func.h:403
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:16