1#ifndef PROTEUS_FRONTEND_FUNC_HPP
2#define PROTEUS_FRONTEND_FUNC_HPP
4#include <initializer_list>
7#include <llvm/IR/IRBuilder.h>
8#include <llvm/IR/Module.h>
21template <
typename T>
class LoopBoundInfo;
23template <
typename T,
typename BodyLambda>
class ForLoopBuilder;
28template <
typename T>
struct FnSig;
45 IRBuilderBase::InsertPoint
IP;
57 IRBuilderBase::InsertPoint
ContIP)
74 std::to_string(
static_cast<int>(Kind)));
97 static_assert(!std::is_array_v<T>,
"Expected non-array type");
100 auto &Ctx = F->getContext();
104 if constexpr (std::is_pointer_v<T>) {
113 template <
typename T>
116 static_assert(std::is_array_v<T>,
"Expected array type");
123 return Var<T>(std::make_unique<ArrayStorage>(BasePointer,
IRB,
ArrTy),
133 template <
typename T,
typename U>
140 template <
typename T>
157 template <
typename T>
164 template <
typename CondLambda>
169 template <
typename Sig>
170 std::enable_if_t<!std::is_void_v<typename FnSig<Sig>::RetT>,
174 template <
typename Sig>
175 std::enable_if_t<std::is_void_v<typename FnSig<Sig>::RetT>,
void>
179 std::enable_if_t<!std::is_void_v<typename FnSig<Sig>::RetT>,
184 std::enable_if_t<std::is_void_v<typename FnSig<Sig>::RetT>,
void>
187 template <
typename BuiltinFuncT>
189 using RetT = std::invoke_result_t<BuiltinFuncT &, FuncBase &>;
190 if constexpr (std::is_void_v<RetT>) {
191 std::invoke(std::forward<BuiltinFuncT>(
BuiltinFunc), *
this);
193 return std::invoke(std::forward<BuiltinFuncT>(
BuiltinFunc), *
this);
197 template <
typename T>
198 std::enable_if_t<std::is_arithmetic_v<T>,
Var<T>>
200 template <
typename T>
201 std::enable_if_t<std::is_arithmetic_v<T>,
Var<T>>
203 template <
typename T>
204 std::enable_if_t<std::is_arithmetic_v<T>,
Var<T>>
206 template <
typename T>
207 std::enable_if_t<std::is_arithmetic_v<T>,
Var<T>>
210 template <
typename T,
typename BodyLambda = EmptyLambda>
212 auto It = Bounds.begin();
215 std::forward<BodyLambda>(Body));
222 using T =
typename FirstBuilder::LoopIndexType;
224 *
this, std::forward<LoopBuilders>(Loops)...);
241 template <
typename U,
typename T>
242 std::enable_if_t<std::is_convertible_v<T, U>,
Var<U>>
255 RetT (*CompiledFunc)(
ArgT...) =
nullptr;
257 std::tuple<std::optional<Var<ArgT>>...> ArgumentsT;
260 template <
typename T, std::
size_t ArgIdx>
Var<T> createArg() {
263 if constexpr (std::is_pointer_v<T>) {
271 template <std::size_t...
Is>
void declArgsImpl(std::index_sequence<Is...>) {
273 auto &
EntryBB = F->getEntryBlock();
279 IRB.ClearInsertionPoint();
282 template <std::size_t...
Is>
auto getArgsImpl(std::index_sequence<Is...>) {
283 return std::tie(*std::get<Is>(ArgumentsT)...);
292 void declArgs() { declArgsImpl(std::index_sequence_for<ArgT...>{}); }
294 auto getArgs() {
return getArgsImpl(std::index_sequence_for<ArgT...>{}); }
296 template <std::
size_t Idx>
auto &
getArg() {
297 return *std::get<Idx>(ArgumentsT);
311 const char *File,
int Line) {
312 static_assert(std::is_integral_v<T>,
313 "Loop iterator must be an integral type");
326 BasicBlock::Create(F->getContext(),
"loop.header", F,
NextBlock);
328 BasicBlock::Create(F->getContext(),
"loop.cond", F,
NextBlock);
330 BasicBlock::Create(F->getContext(),
"loop.body", F,
NextBlock);
332 BasicBlock::Create(F->getContext(),
"loop.inc", F,
NextBlock);
334 BasicBlock::Create(F->getContext(),
"loop.end", F,
NextBlock);
337 CurBlock->getTerminator()->eraseFromParent();
349 auto CondVar = IterVar < UpperBound;
350 Value *
Cond = CondVar.loadValue();
354 IRB.SetInsertPoint(Body);
359 IterVar = IterVar + Inc;
366 IP = IRBuilderBase::InsertPoint(Body, Body->begin());
370template <
typename CondLambda>
383 BasicBlock::Create(F->getContext(),
"while.cond", F,
NextBlock);
385 BasicBlock::Create(F->getContext(),
"while.body", F,
NextBlock);
387 BasicBlock::Create(F->getContext(),
"while.end", F,
NextBlock);
389 CurBlock->getTerminator()->eraseFromParent();
395 auto CondVar =
Cond();
396 Value *
CondV = CondVar.loadValue();
400 IRB.SetInsertPoint(Body);
406 IP = IRBuilderBase::InsertPoint(Body, Body->begin());
414template <
typename T,
typename U,
typename IntOp,
typename FPOp>
423 Value *
LHS =
L.loadValue();
424 Value *
RHS =
R.loadValue();
426 using CommonT = std::common_type_t<T, U>;
431 if constexpr (std::is_integral_v<CommonT>) {
444template <
typename T,
typename U,
typename IntOp,
typename FPOp>
448 static_assert(std::is_convertible_v<U, T>,
"U must be convertible to T");
451 using CleanU = std::remove_cv_t<std::remove_reference_t<U>>;
457 Value *
RHS =
nullptr;
458 if constexpr (std::is_integral_v<CleanU>) {
469 if constexpr (std::is_integral_v<T>) {
472 static_assert(std::is_floating_point_v<T>,
"Unsupported type");
481template <
typename T,
typename U,
typename IntOp,
typename FPOp>
489 Value *
LHS =
L.loadValue();
490 Value *
RHS =
R.loadValue();
495 if constexpr (std::is_integral_v<T>) {
498 static_assert(std::is_floating_point_v<T>,
"Unsupported type");
515 Storage = std::make_unique<ScalarStorage>(
Alloca, Fn.getIRBuilder());
522 storeValue(
V.loadValue());
529 if (this->Storage ==
nullptr) {
531 Storage =
V.Storage->clone();
534 storeValue(
V.loadValue());
542 auto &IRB = Fn.getIRBuilder();
544 Value *Slot = getSlot();
546 Type *
ElemTy = getAllocatedType();
548 unsigned AddrSpace =
SlotPtrTy->getAddressSpace();
549 Type *PtrTy = PointerType::get(
ElemTy, AddrSpace);
550 Value *PtrVal = Slot;
551 if (PtrVal->getType() != PtrTy)
552 PtrVal = IRB.CreateBitCast(Slot, PtrTy);
554 auto *PtrSlot = Fn.emitAlloca(PtrTy,
"addr.tmp");
555 IRB.CreateStore(PtrVal, PtrSlot);
558 std::make_unique<PointerStorage>(PtrSlot, IRB,
ElemTy);
567 auto &IRB = Fn.getIRBuilder();
578 static_assert(std::is_arithmetic_v<U>,
579 "Can only assign arithmetic types to Var");
581 Type *
LHSType = getValueType();
585 }
else if (
LHSType->isFloatingPointTy()) {
655 static_assert(std::is_arithmetic_v<U>,
656 "Can only add arithmetic types to Var");
658 return (*
this) +
Tmp;
666 static_assert(std::is_arithmetic_v<U>,
667 "Can only subtract arithmetic types from Var");
669 return (*
this) -
Tmp;
677 static_assert(std::is_arithmetic_v<U>,
678 "Can only multiply Var by arithmetic types");
680 return (*
this) *
Tmp;
688 static_assert(std::is_arithmetic_v<U>,
689 "Can only divide Var by arithmetic types");
691 return (*
this) /
Tmp;
699 static_assert(std::is_arithmetic_v<U>,
700 "Can only modulo Var by arithmetic types");
702 return (*
this) %
Tmp;
721 static_assert(std::is_arithmetic_v<U>,
722 "Can only add arithmetic types to Var");
744 static_assert(std::is_arithmetic_v<U>,
745 "Can only subtract arithmetic types from Var");
767 static_assert(std::is_arithmetic_v<U>,
768 "Can only multiply Var by arithmetic types");
790 static_assert(std::is_arithmetic_v<U>,
791 "Can only divide Var by arithmetic types");
813 static_assert(std::is_arithmetic_v<U>,
814 "Can only modulo Var by arithmetic types");
824 auto MinusOne = Fn.defVar<
T>(
static_cast<T>(-1),
"minus_one.");
830 auto &IRB = Fn.getIRBuilder();
831 Value *
V = loadValue();
832 Value *
ResV =
nullptr;
833 if constexpr (std::is_same_v<T, bool>) {
834 ResV = IRB.CreateNot(
V);
835 }
else if constexpr (std::is_integral_v<T>) {
836 Value *
Zero = ConstantInt::get(
V->getType(), 0);
839 static_assert(std::is_floating_point_v<T>,
840 "Unsupported type for operator!");
841 Value *
Zero = ConstantFP::get(
V->getType(), 0.0);
844 auto Ret = Fn.declVar<
bool>(
"not.");
845 Ret.storeValue(
ResV);
852 auto &IRB = Fn.getIRBuilder();
854 auto *BasePointer = getSlot();
857 auto *
GEP = IRB.CreateConstInBoundsGEP2_64(ArrayTy, BasePointer, 0,
Index);
858 Type *
ElemTy = getValueType();
860 unsigned AddrSpace =
BasePtrTy->getAddressSpace();
863 auto *PtrSlot = Fn.emitAlloca(
ElemPtrTy,
"elem.ptr");
864 IRB.CreateStore(
GEP, PtrSlot);
867 std::make_unique<PointerStorage>(PtrSlot, IRB,
ElemTy);
872template <
typename IdxT>
876 auto &IRB = Fn.getIRBuilder();
878 auto *BasePointer = getSlot();
881 Value *
Zero = llvm::ConstantInt::get(
IdxVal->getType(), 0);
882 auto *
GEP = IRB.CreateInBoundsGEP(ArrayTy, BasePointer, {
Zero,
IdxVal});
883 Type *
ElemTy = getValueType();
885 unsigned AddrSpace =
BasePtrTy->getAddressSpace();
888 auto *PtrSlot = Fn.emitAlloca(
ElemPtrTy,
"elem.ptr");
889 IRB.CreateStore(
GEP, PtrSlot);
892 std::make_unique<PointerStorage>(PtrSlot, IRB,
ElemTy);
899 auto &IRB = Fn.getIRBuilder();
901 auto *PointerElemTy =
903 auto *
Ptr = loadPointer();
904 auto *
GEP = IRB.CreateConstInBoundsGEP1_64(PointerElemTy,
Ptr,
Index);
906 Type *
ElemPtrTy = PointerType::get(PointerElemTy, AddrSpace);
910 auto *PtrSlot = Fn.emitAlloca(
ElemPtrTy,
"elem.ptr");
911 IRB.CreateStore(
GEP, PtrSlot);
913 std::make_unique<PointerStorage>(PtrSlot, IRB, PointerElemTy);
919template <
typename IdxT>
923 auto &IRB = Fn.getIRBuilder();
927 auto *
Ptr = loadPointer();
935 auto *PtrSlot = Fn.emitAlloca(
ElemPtrTy,
"elem.ptr");
936 IRB.CreateStore(
GEP, PtrSlot);
938 std::make_unique<PointerStorage>(PtrSlot, IRB,
PointeeType);
953 auto &IRB = Fn.getIRBuilder();
955 Value *PtrVal = loadPointer();
957 Type *
ElemTy = getValueType();
959 unsigned AddrSpace = PtrTy->getAddressSpace();
967 auto *PtrSlot = Fn.emitAlloca(
TargetPtrTy,
"addr.ptr.tmp");
968 IRB.CreateStore(PtrVal, PtrSlot);
971 std::make_unique<PointerStorage>(PtrSlot, IRB,
PointeePtrTy);
977template <
typename OffsetT>
978std::enable_if_t<std::is_arithmetic_v<OffsetT>,
982 auto &IRB = Fn.getIRBuilder();
988 auto *
ElemTy = getValueType();
994 auto *PtrSlot = Fn.emitAlloca(
ElemPtrTy,
"ptr.add.tmp");
995 IRB.CreateStore(
GEP, PtrSlot);
997 std::make_unique<PointerStorage>(PtrSlot, IRB,
ElemTy);
1002template <
typename T>
1003template <
typename OffsetT>
1004std::enable_if_t<std::is_arithmetic_v<OffsetT>,
1008 auto &IRB = Fn.getIRBuilder();
1009 auto *
IntTy = IRB.getInt64Ty();
1012 auto *
BasePtr = loadPointer();
1013 auto *
ElemTy = getValueType();
1019 auto *PtrSlot = Fn.emitAlloca(
ElemPtrTy,
"ptr.add.tmp");
1020 IRB.CreateStore(
GEP, PtrSlot);
1022 std::make_unique<PointerStorage>(PtrSlot, IRB,
ElemTy);
1028template <
typename T>
1029template <
typename U>
1030std::enable_if_t<std::is_arithmetic_v<U>,
Var<bool>>
1036 return B.CreateICmpSGT(
L,
R);
1039 return B.CreateFCmpOGT(
L,
R);
1043template <
typename T>
1044template <
typename U>
1045std::enable_if_t<std::is_arithmetic_v<U>,
Var<bool>>
1051 return B.CreateICmpSGE(
L,
R);
1054 return B.CreateFCmpOGE(
L,
R);
1058template <
typename T>
1059template <
typename U>
1060std::enable_if_t<std::is_arithmetic_v<U>,
Var<bool>>
1066 return B.CreateICmpSLT(
L,
R);
1069 return B.CreateFCmpOLT(
L,
R);
1073template <
typename T>
1074template <
typename U>
1075std::enable_if_t<std::is_arithmetic_v<U>,
Var<bool>>
1081 return B.CreateICmpSLE(
L,
R);
1084 return B.CreateFCmpOLE(
L,
R);
1088template <
typename T>
1089template <
typename U>
1090std::enable_if_t<std::is_arithmetic_v<U>,
Var<bool>>
1097 return B.CreateFCmpOEQ(
L,
R);
1101template <
typename T>
1102template <
typename U>
1103std::enable_if_t<std::is_arithmetic_v<U>,
Var<bool>>
1110 return B.CreateFCmpONE(
L,
R);
1114template <
typename T>
1115template <
typename U>
1116std::enable_if_t<std::is_arithmetic_v<U>,
Var<bool>>
1120 return (*
this) >
Tmp;
1123template <
typename T>
1124template <
typename U>
1125std::enable_if_t<std::is_arithmetic_v<U>,
Var<bool>>
1129 return (*
this) >=
Tmp;
1132template <
typename T>
1133template <
typename U>
1134std::enable_if_t<std::is_arithmetic_v<U>,
Var<bool>>
1138 return (*
this) <
Tmp;
1141template <
typename T>
1142template <
typename U>
1143std::enable_if_t<std::is_arithmetic_v<U>,
Var<bool>>
1147 return (*
this) <=
Tmp;
1150template <
typename T>
1151template <
typename U>
1152std::enable_if_t<std::is_arithmetic_v<U>,
Var<bool>>
1156 return (*
this) ==
Tmp;
1159template <
typename T>
1160template <
typename U>
1161std::enable_if_t<std::is_arithmetic_v<U>,
Var<bool>>
1165 return (*
this) !=
Tmp;
1169template <
typename T,
typename U>
1170std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
1177template <
typename T,
typename U>
1178std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
1186template <
typename T,
typename U>
1187std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
1194template <
typename T,
typename U>
1195std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
1202template <
typename T,
typename U>
1203std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
1211template <
typename T>
1214 static_assert(std::is_arithmetic_v<T>,
"Atomic ops require arithmetic type");
1219 AtomicOrdering::SequentiallyConsistent, SyncScope::SingleThread);
1226template <
typename T>
1227std::enable_if_t<std::is_arithmetic_v<T>,
Var<T>>
1229 static_assert(std::is_arithmetic_v<T>,
"atomicAdd requires arithmetic type");
1233 ValueType->isFloatingPointTy() ? AtomicRMWInst::FAdd : AtomicRMWInst::Add;
1237template <
typename T>
1238std::enable_if_t<std::is_arithmetic_v<T>,
Var<T>>
1240 static_assert(std::is_arithmetic_v<T>,
"atomicSub requires arithmetic type");
1244 ValueType->isFloatingPointTy() ? AtomicRMWInst::FSub : AtomicRMWInst::Sub;
1248template <
typename T>
1249std::enable_if_t<std::is_arithmetic_v<T>,
Var<T>>
1251 static_assert(std::is_arithmetic_v<T>,
"atomicMax requires arithmetic type");
1255 ValueType->isFloatingPointTy() ? AtomicRMWInst::FMax : AtomicRMWInst::Max;
1259template <
typename T>
1260std::enable_if_t<std::is_arithmetic_v<T>,
Var<T>>
1262 static_assert(std::is_arithmetic_v<T>,
"atomicMin requires arithmetic type");
1266 ValueType->isFloatingPointTy() ? AtomicRMWInst::FMin : AtomicRMWInst::Min;
1272 if (!
CurBB->getSingleSuccessor())
1277 IRB.CreateRetVoid();
1279 TermI->eraseFromParent();
1284 if (!
CurBB->getSingleSuccessor())
1292 TermI->eraseFromParent();
1307template <
typename T,
typename...
Operands>
1310 static_assert(
sizeof...(Ops) > 0,
"Intrinsic requires at least one operand");
1312 auto &Fn = std::get<0>(std::tie(
Ops...)).Fn;
1319 auto &IRB = Fn.getIRBuilder();
1320 auto &M = *Fn.getFunction()->getParent();
1335 static_assert(std::is_convertible_v<T, float>,
1336 "powf requires floating-point type");
1337 auto &IRB =
L.Fn.getIRBuilder();
1341#if PROTEUS_ENABLE_CUDA
1350 static_assert(std::is_convertible_v<T, float>,
1351 "sqrtf requires floating-point type");
1353 auto &IRB =
R.Fn.getIRBuilder();
1357#if PROTEUS_ENABLE_CUDA
1366 static_assert(std::is_convertible_v<T, float>,
1367 "expf requires floating-point type");
1369 auto &IRB =
R.Fn.getIRBuilder();
1373#if PROTEUS_ENABLE_CUDA
1382 static_assert(std::is_convertible_v<T, float>,
1383 "sinf requires floating-point type");
1385 auto &IRB =
R.Fn.getIRBuilder();
1389#if PROTEUS_ENABLE_CUDA
1398 static_assert(std::is_convertible_v<T, float>,
1399 "cosf requires floating-point type");
1401 auto &IRB =
R.Fn.getIRBuilder();
1405#if PROTEUS_ENABLE_CUDA
1414 static_assert(std::is_convertible_v<T, float>,
1415 "fabs requires floating-point type");
1417 auto &IRB =
R.Fn.getIRBuilder();
1421#if PROTEUS_ENABLE_CUDA
1430 static_assert(std::is_convertible_v<T, float>,
1431 "truncf requires floating-point type");
1433 auto &IRB =
R.Fn.getIRBuilder();
1437#if PROTEUS_ENABLE_CUDA
1446 static_assert(std::is_convertible_v<T, float>,
1447 "logf requires floating-point type");
1449 auto &IRB =
R.Fn.getIRBuilder();
1453#if PROTEUS_ENABLE_CUDA
1462 static_assert(std::is_convertible_v<T, float>,
1463 "absf requires floating-point type");
1465 auto &IRB =
R.Fn.getIRBuilder();
1469#if PROTEUS_ENABLE_CUDA
1477template <
typename T>
1480 static_assert(std::is_arithmetic_v<T>,
"min requires arithmetic type");
1494template <
typename T>
1497 static_assert(std::is_arithmetic_v<T>,
"max requires arithmetic type");
char int void ** Args
Definition CompilerInterfaceHost.cpp:20
#define PROTEUS_FATAL_ERROR(x)
Definition Error.h:7
Definition Dispatcher.hpp:54
Var< T > emitAtomic(AtomicRMWInst::BinOp Op, const Var< T * > &Addr, const Var< T > &Val)
Definition Func.hpp:1212
std::vector< Scope > Scopes
Definition Func.hpp:60
void setName(StringRef NewName)
Definition Func.hpp:233
Var< T > declVar(StringRef Name="var")
Definition Func.hpp:96
auto forLoop(std::initializer_list< Var< T > > Bounds, BodyLambda &&Body={})
Definition Func.hpp:211
Var< T > defVar(const T &Val, StringRef Name="var")
Definition Func.hpp:127
decltype(auto) callBuiltin(BuiltinFuncT &&BuiltinFunc)
Definition Func.hpp:188
void beginIf(const Var< bool > &CondVar, const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.cpp:115
auto defRuntimeConsts(ArgT &&...Args)
Definition Func.hpp:145
std::enable_if_t< std::is_convertible_v< T, U >, Var< U > > convert(const Var< T > &V)
Definition Func.hpp:243
std::enable_if_t< std::is_arithmetic_v< T >, Var< T > > atomicMin(const Var< T * > &Addr, const Var< T > &Val)
Definition Func.hpp:1261
void endFunction()
Definition Func.cpp:53
void beginWhile(CondLambda &&Cond, const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.hpp:371
void beginFunction(const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.cpp:30
Var< T > declVar(size_t NElem, AddressSpace AS=AddressSpace::DEFAULT, StringRef Name="array_var")
Definition Func.hpp:114
IRBuilder IRB
Definition Func.hpp:44
std::enable_if_t< std::is_arithmetic_v< T >, Var< T > > atomicMax(const Var< T * > &Addr, const Var< T > &Val)
Definition Func.hpp:1250
Function * getFunction()
Definition Func.cpp:66
ScopeKind
Definition Func.hpp:49
void endIf()
Definition Func.cpp:148
std::string Name
Definition Func.hpp:47
FunctionCallee FC
Definition Func.hpp:43
auto buildLoopNest(LoopBuilders &&...Loops)
Definition Func.hpp:219
void ret()
Definition Func.hpp:1270
IRBuilderBase::InsertPoint IP
Definition Func.hpp:45
JitModule & J
Definition Func.hpp:42
void endWhile()
Definition Func.cpp:181
std::enable_if_t< std::is_arithmetic_v< T >, Var< T > > atomicAdd(const Var< T * > &Addr, const Var< T > &Val)
Definition Func.hpp:1228
Value * emitArrayCreate(Type *Ty, AddressSpace AT, StringRef Name)
Definition Func.cpp:85
StringRef getName() const
Definition Func.hpp:231
std::enable_if_t<!std::is_void_v< typename FnSig< Sig >::RetT >, Var< typename FnSig< Sig >::RetT > > call(StringRef Name)
Definition JitFrontend.hpp:272
Var< T > defRuntimeConst(const T &Val, StringRef Name="run.const.var")
Definition Func.hpp:141
void endFor()
Definition Func.cpp:164
std::enable_if_t< std::is_arithmetic_v< T >, Var< T > > atomicSub(const Var< T * > &Addr, const Var< T > &Val)
Definition Func.hpp:1239
TargetModelType getTargetModel() const
Definition Func.cpp:22
std::string toString(ScopeKind Kind)
Definition Func.hpp:62
IRBuilderBase & getIRBuilder()
Definition Func.cpp:24
void beginFor(Var< T > &IterVar, const Var< T > &InitVar, const Var< T > &UpperBound, const Var< T > &IncVar, const char *File=__builtin_FILE(), int Line=__builtin_LINE())
Definition Func.hpp:309
AllocaInst * emitAlloca(Type *Ty, StringRef Name, AddressSpace AS=AddressSpace::DEFAULT)
Definition Func.cpp:73
Var< T > defVar(const Var< U > &Var, StringRef Name="var")
Definition Func.hpp:134
Func(JitModule &J, FunctionCallee FC, Dispatcher &Dispatch)
Definition Func.hpp:287
auto & getArg()
Definition Func.hpp:296
auto getCompiledFunc() const
Definition Func.hpp:300
auto getArgs()
Definition Func.hpp:294
void setCompiledFunc(RetT(*CompiledFuncIn)(ArgT...))
Definition Func.hpp:302
RetT operator()(ArgT... Args)
Definition JitFrontend.hpp:334
void declArgs()
Definition Func.hpp:292
Definition JitFrontend.hpp:29
Definition LoopNest.hpp:12
Definition LoopNest.hpp:47
Definition VarStorage.hpp:10
Definition StorageCache.cpp:24
std::enable_if_t< std::is_arithmetic_v< T > &&std::is_arithmetic_v< U >, Var< std::common_type_t< T, U > > > operator-(const T &ConstValue, const Var< U > &V)
Definition Func.hpp:1180
AddressSpace
Definition AddressSpace.hpp:6
TargetModelType
Definition TargetModel.hpp:14
Var< float > sqrtf(const Var< T > &R)
Definition Func.hpp:1349
std::enable_if_t< std::is_arithmetic_v< T >, Var< T > > max(const Var< T > &L, const Var< T > &R)
Definition Func.hpp:1495
Var< float > fabs(const Var< T > &R)
Definition Func.hpp:1413
std::enable_if_t< std::is_arithmetic_v< T > &&std::is_arithmetic_v< U >, Var< std::common_type_t< T, U > > > operator*(const T &ConstValue, const Var< U > &V)
Definition Func.hpp:1189
Var< float > sinf(const Var< T > &R)
Definition Func.hpp:1381
Var< float > logf(const Var< T > &R)
Definition Func.hpp:1445
T getRuntimeConstantValue(void *Arg)
Definition CompilerInterfaceRuntimeConstantInfo.h:114
std::enable_if_t< std::is_arithmetic_v< T > &&std::is_arithmetic_v< U >, Var< std::common_type_t< T, U > > > operator+(const T &ConstValue, const Var< U > &V)
Definition Func.hpp:1172
Var< float > cosf(const Var< T > &R)
Definition Func.hpp:1397
Var< T, std::enable_if_t< std::is_arithmetic_v< T > > > & compoundAssignConst(Var< T, std::enable_if_t< std::is_arithmetic_v< T > > > &LHS, const U &ConstValue, IntOp IOp, FPOp FOp)
Definition Func.hpp:446
std::enable_if_t< std::is_arithmetic_v< T > &&std::is_arithmetic_v< U >, Var< std::common_type_t< T, U > > > operator/(const T &ConstValue, const Var< U > &V)
Definition Func.hpp:1197
Var< float > expf(const Var< T > &R)
Definition Func.hpp:1365
Var< float > powf(const Var< float > &L, const Var< T > &R)
Definition Func.hpp:1334
Var< float > truncf(const Var< T > &R)
Definition Func.hpp:1429
std::enable_if_t< std::is_arithmetic_v< T >, Var< T > > min(const Var< T > &L, const Var< T > &R)
Definition Func.hpp:1478
Var< float > absf(const Var< T > &R)
Definition Func.hpp:1461
Var< std::common_type_t< T, U > > binOp(const Var< T > &L, const Var< U > &R, IntOp IOp, FPOp FOp)
Definition Func.hpp:415
std::enable_if_t< std::is_arithmetic_v< T > &&std::is_arithmetic_v< U >, Var< std::common_type_t< T, U > > > operator%(const T &ConstValue, const Var< U > &V)
Definition Func.hpp:1205
Var< bool > cmpOp(const Var< T > &L, const Var< U > &R, IntOp IOp, FPOp FOp)
Definition Func.hpp:482
void operator()() const
Definition Func.hpp:37
RetT_ RetT
Definition Func.hpp:31
Scope(const char *File, int Line, ScopeKind Kind, IRBuilderBase::InsertPoint ContIP)
Definition Func.hpp:56
int Line
Definition Func.hpp:52
ScopeKind Kind
Definition Func.hpp:53
std::string File
Definition Func.hpp:51
IRBuilderBase::InsertPoint ContIP
Definition Func.hpp:54
Value * operator()(const Var< U > &Operand) const
Definition Func.hpp:1301
IRBuilderBase & IRB
Definition Func.hpp:1299
Definition TypeMap.hpp:13
FuncBase & Fn
Definition Var.hpp:75