1#ifndef PROTEUS_FRONTEND_VAR_H
2#define PROTEUS_FRONTEND_VAR_H
16template <
typename T,
typename =
void>
struct Var;
21struct Var<T,
std::enable_if_t<is_scalar_arithmetic_v<T>>> {
26 unsigned AddrSpace = 0;
32 : CB(CBIn), Slot(A.Slot), ValueTy(A.ValueTy), AllocTy(A.AllocTy),
33 AddrSpace(A.AddrSpace) {}
37 typename = std::enable_if_t<std::is_convertible_v<U, T> &&
38 (!std::is_same_v<U, T>)>>
49 Var &operator=(
const Var &V);
60 template <
typename U>
auto convert()
const;
64 if constexpr (std::is_reference_v<T>)
70 if constexpr (std::is_reference_v<T>)
101 template <
typename U>
104 template <
typename U>
108 template <
typename U>
111 template <
typename U>
141 template <
typename U>
142 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
143 operator>(
const Var<U> &Other)
const;
145 template <
typename U>
146 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
147 operator>=(
const Var<U> &Other)
const;
149 template <
typename U>
150 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
151 operator<(
const Var<U> &Other)
const;
153 template <
typename U>
154 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
155 operator<=(
const Var<U> &Other)
const;
157 template <
typename U>
158 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
159 operator==(
const Var<U> &Other)
const;
161 template <
typename U>
162 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
163 operator!=(
const Var<U> &Other)
const;
165 template <
typename U>
166 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
167 operator>(
const U &ConstValue)
const;
169 template <
typename U>
170 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
171 operator>=(
const U &ConstValue)
const;
173 template <
typename U>
174 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
175 operator<(
const U &ConstValue)
const;
177 template <
typename U>
178 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
179 operator<=(
const U &ConstValue)
const;
181 template <
typename U>
182 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
183 operator==(
const U &ConstValue)
const;
185 template <
typename U>
186 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
187 operator!=(
const U &ConstValue)
const;
191template <
typename T>
struct Var<T,
std::enable_if_t<std::is_array_v<T>>> {
196 unsigned AddrSpace = 0;
202 : CB(CBIn), Slot(A.Slot), ValueTy(A.ValueTy), AllocTy(A.AllocTy),
203 AddrSpace(A.AddrSpace) {}
220 template <
typename IdxT>
221 std::enable_if_t<std::is_integral_v<IdxT>,
229template <
typename T>
struct Var<T,
std::enable_if_t<is_pointer_unref_v<T>>> {
234 unsigned AddrSpace = 0;
237 using ElemType = std::remove_pointer_t<std::remove_reference_t<T>>;
240 : CB(CBIn), Slot(A.Slot), ValueTy(A.ValueTy), AllocTy(A.AllocTy),
241 AddrSpace(A.AddrSpace) {}
259 template <
typename IdxT>
260 std::enable_if_t<std::is_arithmetic_v<IdxT>,
268 template <
typename OffsetT>
269 std::enable_if_t<std::is_arithmetic_v<OffsetT>,
273 template <
typename OffsetT>
274 std::enable_if_t<std::is_arithmetic_v<OffsetT>,
278 template <
typename OffsetT>
279 friend std::enable_if_t<std::is_arithmetic_v<OffsetT>,
287template <
typename T,
typename U>
288std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
289 Var<std::common_type_t<T, U>>>
290operator+(
const T &ConstValue,
const Var<U> &Var);
292template <
typename T,
typename U>
293std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
294 Var<std::common_type_t<T, U>>>
295operator-(
const T &ConstValue,
const Var<U> &V);
297template <
typename T,
typename U>
298std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
299 Var<std::common_type_t<T, U>>>
300operator*(
const T &ConstValue,
const Var<U> &V);
302template <
typename T,
typename U>
303std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
304 Var<std::common_type_t<T, U>>>
305operator/(
const T &ConstValue,
const Var<U> &V);
307template <
typename T,
typename U>
308std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
309 Var<std::common_type_t<T, U>>>
310operator%(
const T &ConstValue,
const Var<U> &V);
319template <
typename FromT,
typename ToT>
323 static_assert(std::is_arithmetic_v<From>,
"From type must be arithmetic");
324 static_assert(std::is_arithmetic_v<To>,
"To type must be arithmetic");
326 if constexpr (std::is_same_v<From, To>)
335 static_assert(!std::is_array_v<T>,
"Expected non-array type");
336 static_assert(!std::is_reference_v<T>,
337 "declVar does not support reference types");
339 if constexpr (std::is_pointer_v<T>) {
351 using RawT = std::remove_const_t<T>;
361template <
typename T,
typename U>
362Var<std::common_type_t<remove_cvref_t<T>, remove_cvref_t<U>>>
370 IRValue *LHS = detail::convert<T, CommonT>(CB, L.loadValue());
371 IRValue *RHS = detail::convert<U, CommonT>(CB, R.loadValue());
375 auto ResultVar = declVar<CommonT>(CB,
"res.");
376 ResultVar.storeValue(Result);
381template <
typename T,
typename U>
382Var<T, std::enable_if_t<is_scalar_arithmetic_v<T>>> &
384 const U &ConstValue,
ArithOp Op) {
386 "U must be convertible to T");
391 if constexpr (std::is_integral_v<remove_cvref_t<U>>) {
392 RHS = LHS.CB.getConstantInt(RHSType, ConstValue);
394 RHS = LHS.CB.getConstantFP(RHSType, ConstValue);
397 IRValue *LHSVal = LHS.loadValue();
399 RHS = detail::convert<U, T>(LHS.CB, RHS);
403 LHS.storeValue(Result);
407template <
typename T,
typename U>
414 IRValue *RHS = detail::convert<U, T>(CB, R.loadValue());
419 auto ResultVar = declVar<bool>(CB,
"res.");
420 ResultVar.storeValue(Result);
432 using ResultT = std::remove_reference_t<U>;
433 Var<ResultT> Res = declVar<ResultT>(this->CB,
"convert.");
434 IRValue *Converted = detail::convert<T, U>(this->CB, this->loadValue());
435 Res.storeValue(Converted);
440template <
typename U,
typename>
444 auto Converted = detail::convert<U, T>(CB, V.loadValue());
445 storeValue(Converted);
451 static_assert(is_mutable_v<T>,
"Cannot assign to Var<const T>");
452 storeValue(V.loadValue());
459 static_assert(is_mutable_v<T>,
"Cannot assign to Var<const T>");
460 storeValue(V.loadValue());
467 if constexpr (std::is_reference_v<T>) {
470 IRValue *PtrVal = CB.loadAddress(Slot, AllocTy);
471 auto A = CB.allocPointer(
"addr.ref.tmp", ValueTy, AddrSpace);
472 CB.storeAddress(A.Slot, PtrVal);
476 auto A = CB.allocPointer(
"addr.tmp", AllocTy, AddrSpace);
477 CB.storeAddress(A.Slot, Slot);
486 static_assert(is_mutable_v<T>,
"Cannot assign to Var<const T>");
487 auto Converted = detail::convert<U, T>(CB, V.loadValue());
488 storeValue(Converted);
496 const U &ConstValue) {
497 static_assert(is_mutable_v<T>,
"Cannot assign to Var<const T>");
498 static_assert(std::is_arithmetic_v<U>,
499 "Can only assign arithmetic types to Var");
501 IRType LHSType = getValueType();
504 storeValue(CB.getConstantInt(LHSType, ConstValue));
506 storeValue(CB.getConstantFP(LHSType, ConstValue));
518 const Var<U> &Other)
const {
526 const Var<U> &Other)
const {
534 const Var<U> &Other)
const {
542 const Var<U> &Other)
const {
550 const Var<U> &Other)
const {
559 const U &ConstValue)
const {
560 static_assert(std::is_arithmetic_v<U>,
561 "Can only add arithmetic types to Var");
562 Var<U> Tmp = defVar<U>(CB, ConstValue,
"tmp.");
563 return (*
this) + Tmp;
570 const U &ConstValue)
const {
571 static_assert(std::is_arithmetic_v<U>,
572 "Can only subtract arithmetic types from Var");
573 Var<U> Tmp = defVar<U>(CB, ConstValue,
"tmp.");
574 return (*
this) - Tmp;
581 const U &ConstValue)
const {
582 static_assert(std::is_arithmetic_v<U>,
583 "Can only multiply Var by arithmetic types");
584 Var<U> Tmp = defVar<U>(CB, ConstValue,
"tmp.");
585 return (*
this) * Tmp;
592 const U &ConstValue)
const {
593 static_assert(std::is_arithmetic_v<U>,
594 "Can only divide Var by arithmetic types");
595 Var<U> Tmp = defVar<U>(CB, ConstValue,
"tmp.");
596 return (*
this) / Tmp;
603 const U &ConstValue)
const {
604 static_assert(std::is_arithmetic_v<U>,
605 "Can only modulo Var by arithmetic types");
606 Var<U> Tmp = defVar<U>(CB, ConstValue,
"tmp.");
607 return (*
this) % Tmp;
616 static_assert(is_mutable_v<T>,
"Cannot use += on Var<const T>");
617 auto Result = (*this) + Other;
626 const U &ConstValue) {
627 static_assert(is_mutable_v<T>,
"Cannot use += on Var<const T>");
628 static_assert(std::is_arithmetic_v<U>,
629 "Can only add arithmetic types to Var");
638 static_assert(is_mutable_v<T>,
"Cannot use -= on Var<const T>");
639 auto Result = (*this) - Other;
648 const U &ConstValue) {
649 static_assert(is_mutable_v<T>,
"Cannot use -= on Var<const T>");
650 static_assert(std::is_arithmetic_v<U>,
651 "Can only subtract arithmetic types from Var");
660 static_assert(is_mutable_v<T>,
"Cannot use *= on Var<const T>");
661 auto Result = (*this) * Other;
670 const U &ConstValue) {
671 static_assert(is_mutable_v<T>,
"Cannot use *= on Var<const T>");
672 static_assert(std::is_arithmetic_v<U>,
673 "Can only multiply Var by arithmetic types");
682 static_assert(is_mutable_v<T>,
"Cannot use /= on Var<const T>");
683 auto Result = (*this) / Other;
692 const U &ConstValue) {
693 static_assert(is_mutable_v<T>,
"Cannot use /= on Var<const T>");
694 static_assert(std::is_arithmetic_v<U>,
695 "Can only divide Var by arithmetic types");
704 static_assert(is_mutable_v<T>,
"Cannot use %= on Var<const T>");
705 auto Result = (*this) % Other;
714 const U &ConstValue) {
715 static_assert(is_mutable_v<T>,
"Cannot use %= on Var<const T>");
716 static_assert(std::is_arithmetic_v<U>,
717 "Can only modulo Var by arithmetic types");
724 auto MinusOne = defVar<remove_cvref_t<T>>(
726 return MinusOne * (*this);
734 if constexpr (std::is_same_v<remove_cvref_t<T>,
bool>) {
735 ResV = CB.createNot(V);
736 }
else if constexpr (std::is_integral_v<remove_cvref_t<T>>) {
737 IRValue *Zero = CB.getConstantInt(getValueType(), 0);
738 ResV = CB.createCmp(
CmpOp::EQ, V, Zero, getValueType());
740 IRValue *Zero = CB.getConstantFP(getValueType(), 0.0);
741 ResV = CB.createCmp(
CmpOp::EQ, V, Zero, getValueType());
743 auto Ret = declVar<bool>(CB,
"not.");
744 Ret.storeValue(ResV);
751 auto A = CB.getElementPtr(Slot, AllocTy, Index, ValueTy);
756template <
typename IdxT>
757std::enable_if_t<std::is_integral_v<IdxT>,
761 auto A = CB.getElementPtr(Slot, AllocTy, Index.loadValue(), ValueTy);
766Var<std::add_lvalue_reference_t<
767 std::remove_pointer_t<std::remove_reference_t<T>>>>
769 using ElemT = std::remove_pointer_t<std::remove_reference_t<T>>;
771 IRValue *Ptr = CB.loadAddress(Slot, AllocTy);
772 auto A = CB.getElementPtr(Ptr, AllocTy, Index, ElemIRTy);
773 return Var<std::add_lvalue_reference_t<
774 std::remove_pointer_t<std::remove_reference_t<T>>>>(A, CB);
778template <
typename IdxT>
779std::enable_if_t<std::is_arithmetic_v<IdxT>,
780 Var<std::add_lvalue_reference_t<
781 std::remove_pointer_t<std::remove_reference_t<T>>>>>
784 using ElemT = std::remove_pointer_t<std::remove_reference_t<T>>;
786 IRValue *Ptr = CB.loadAddress(Slot, AllocTy);
787 auto A = CB.getElementPtr(Ptr, AllocTy, Index.loadValue(), ElemIRTy);
788 return Var<std::add_lvalue_reference_t<
789 std::remove_pointer_t<std::remove_reference_t<T>>>>(A, CB);
793Var<std::add_lvalue_reference_t<
794 std::remove_pointer_t<std::remove_reference_t<T>>>>
802 IRValue *PtrVal = CB.loadAddress(Slot, AllocTy);
805 auto A = CB.allocPointer(
"addr.ptr.tmp", PointeePtrIRTy, 0);
806 CB.storeAddress(A.Slot, PtrVal);
811template <
typename OffsetT>
812std::enable_if_t<std::is_arithmetic_v<OffsetT>,
816 IRValue *IdxVal = detail::convert<OffsetT, int64_t>(CB,
Offset.loadValue());
817 IRValue *BasePtr = CB.loadAddress(Slot, AllocTy);
818 auto A = CB.getElementPtr(BasePtr, AllocTy, IdxVal, ValueTy);
823template <
typename OffsetT>
824std::enable_if_t<std::is_arithmetic_v<OffsetT>,
829 static_cast<uint64_t
>(
Offset));
830 IRValue *BasePtr = CB.loadAddress(Slot, AllocTy);
831 auto A = CB.getElementPtr(BasePtr, AllocTy, IdxVal, ValueTy);
838std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
840 const Var<U> &Other)
const {
846std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
848 const Var<U> &Other)
const {
854std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
856 const Var<U> &Other)
const {
862std::enable_if_t<is_arithmetic_unref_v<U>, Var<bool>>
863Var<T, std::enable_if_t<is_scalar_arithmetic_v<T>>>::operator<=(
864 const Var<U> &Other)
const {
870std::enable_if_t<is_arithmetic_unref_v<U>, Var<bool>>
872 const Var<U> &Other)
const {
878std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
880 const Var<U> &Other)
const {
886std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
888 const U &ConstValue)
const {
889 Var<U> Tmp = defVar<U>(CB, ConstValue,
"cmp.");
890 return (*
this) > Tmp;
895std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
897 const U &ConstValue)
const {
898 Var<U> Tmp = defVar<U>(CB, ConstValue,
"cmp.");
899 return (*
this) >= Tmp;
904std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
906 const U &ConstValue)
const {
907 Var<U> Tmp = defVar<U>(CB, ConstValue,
"cmp.");
908 return (*
this) < Tmp;
913std::enable_if_t<is_arithmetic_unref_v<U>, Var<bool>>
914Var<T, std::enable_if_t<is_scalar_arithmetic_v<T>>>::operator<=(
915 const U &ConstValue)
const {
916 auto Tmp = defVar<U>(CB, ConstValue,
"cmp.");
917 return (*
this) <= Tmp;
922std::enable_if_t<is_arithmetic_unref_v<U>, Var<bool>>
924 const U &ConstValue)
const {
925 Var<U> Tmp = defVar<U>(CB, ConstValue,
"cmp.");
926 return (*
this) == Tmp;
931std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
933 const U &ConstValue)
const {
934 auto Tmp = defVar<U>(CB, ConstValue,
"cmp.");
935 return (*
this) != Tmp;
939template <
typename T,
typename U>
940std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
943 Var<T> Tmp = defVar<T>(V.CB, ConstValue,
"tmp.");
947template <
typename T,
typename U>
948std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
949 Var<std::common_type_t<T, U>>>
951 using CommonType = std::common_type_t<T, U>;
956template <
typename T,
typename U>
957std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
958 Var<std::common_type_t<T, U>>>
960 Var<T> Tmp = defVar<T>(V.CB, ConstValue,
"tmp.");
964template <
typename T,
typename U>
965std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
966 Var<std::common_type_t<T, U>>>
968 Var<T> Tmp = defVar<T>(V.CB, ConstValue,
"tmp.");
972template <
typename T,
typename U>
973std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
974 Var<std::common_type_t<T, U>>>
976 Var<T> Tmp = defVar<T>(V.CB, ConstValue,
"tmp.");
989 return detail::convert<U, T>(
CB, Operand.loadValue());
993template <
typename T,
typename... Operands>
994static Var<T> emitIntrinsic(
const std::string &IntrinsicName,
995 const Operands &...Ops) {
996 static_assert(
sizeof...(Ops) > 0,
"Intrinsic requires at least one operand");
998 CodeBuilder &CB = std::get<0>(std::tie(Ops...)).CB;
999 auto CheckFn = [&CB](
const auto &Operand) {
1000 if (&Operand.CB != &CB)
1003 (CheckFn(Ops), ...);
1005 IntrinsicOperandConverter<T> ConvertOperand{CB};
1007 IRType ResultIRTy = TypeMap<T>::get();
1008 std::vector<IRType> ArgTys(
sizeof...(Ops), ResultIRTy);
1009 IRValue *Call = CB.createCall(IntrinsicName, ResultIRTy, ArgTys,
1010 {ConvertOperand(Ops)...});
1012 auto ResultVar = declVar<T>(CB,
"res.");
1013 ResultVar.storeValue(Call);
1022 static_assert(std::is_convertible_v<T, float>,
1023 "powf requires floating-point type");
1025 auto RFloat = R.template convert<float>();
1026 std::string IntrinsicName =
"llvm.pow.f32";
1027#if PROTEUS_ENABLE_CUDA
1029 IntrinsicName =
"__nv_powf";
1032 return emitIntrinsic<float>(IntrinsicName, L, RFloat);
1036 static_assert(std::is_convertible_v<T, float>,
1037 "sqrtf requires floating-point type");
1039 auto RFloat = R.template convert<float>();
1040 std::string IntrinsicName =
"llvm.sqrt.f32";
1041#if PROTEUS_ENABLE_CUDA
1043 IntrinsicName =
"__nv_sqrtf";
1046 return emitIntrinsic<float>(IntrinsicName, RFloat);
1050 static_assert(std::is_convertible_v<T, float>,
1051 "expf requires floating-point type");
1053 auto RFloat = R.template convert<float>();
1054 std::string IntrinsicName =
"llvm.exp.f32";
1055#if PROTEUS_ENABLE_CUDA
1057 IntrinsicName =
"__nv_expf";
1060 return emitIntrinsic<float>(IntrinsicName, RFloat);
1064 static_assert(std::is_convertible_v<T, float>,
1065 "sinf requires floating-point type");
1067 auto RFloat = R.template convert<float>();
1068 std::string IntrinsicName =
"llvm.sin.f32";
1069#if PROTEUS_ENABLE_CUDA
1071 IntrinsicName =
"__nv_sinf";
1074 return emitIntrinsic<float>(IntrinsicName, RFloat);
1078 static_assert(std::is_convertible_v<T, float>,
1079 "cosf requires floating-point type");
1081 auto RFloat = R.template convert<float>();
1082 std::string IntrinsicName =
"llvm.cos.f32";
1083#if PROTEUS_ENABLE_CUDA
1085 IntrinsicName =
"__nv_cosf";
1088 return emitIntrinsic<float>(IntrinsicName, RFloat);
1092 static_assert(std::is_convertible_v<T, float>,
1093 "fabs requires floating-point type");
1095 auto RFloat = R.template convert<float>();
1096 std::string IntrinsicName =
"llvm.fabs.f32";
1097#if PROTEUS_ENABLE_CUDA
1099 IntrinsicName =
"__nv_fabsf";
1102 return emitIntrinsic<float>(IntrinsicName, RFloat);
1106 static_assert(std::is_convertible_v<T, float>,
1107 "truncf requires floating-point type");
1109 auto RFloat = R.template convert<float>();
1110 std::string IntrinsicName =
"llvm.trunc.f32";
1111#if PROTEUS_ENABLE_CUDA
1113 IntrinsicName =
"__nv_truncf";
1116 return emitIntrinsic<float>(IntrinsicName, RFloat);
1120 static_assert(std::is_convertible_v<T, float>,
1121 "logf requires floating-point type");
1123 auto RFloat = R.template convert<float>();
1124 std::string IntrinsicName =
"llvm.log.f32";
1125#if PROTEUS_ENABLE_CUDA
1127 IntrinsicName =
"__nv_logf";
1130 return emitIntrinsic<float>(IntrinsicName, RFloat);
1134 static_assert(std::is_convertible_v<T, float>,
1135 "absf requires floating-point type");
1137 auto RFloat = R.template convert<float>();
1138 std::string IntrinsicName =
"llvm.fabs.f32";
1139#if PROTEUS_ENABLE_CUDA
1141 IntrinsicName =
"__nv_fabsf";
1144 return emitIntrinsic<float>(IntrinsicName, RFloat);
1147template <
typename T>
1148std::enable_if_t<is_arithmetic_unref_v<T>, Var<remove_cvref_t<T>>>
1154 auto ResultVar = declVar<remove_cvref_t<T>>(CB,
"min_res");
1156 auto CondVar = L < R;
1157 CB.
beginIf(CondVar.loadValue(), __builtin_FILE(), __builtin_LINE());
1163template <
typename T>
1164std::enable_if_t<is_arithmetic_unref_v<T>, Var<remove_cvref_t<T>>>
1170 auto ResultVar = declVar<remove_cvref_t<T>>(CB,
"max_res");
1172 auto CondVar = L > R;
1173 CB.
beginIf(CondVar.loadValue(), __builtin_FILE(), __builtin_LINE());
Definition CodeBuilder.h:66
virtual VarAlloc allocPointer(const std::string &Name, IRType ElemTy, unsigned AddrSpace=0)=0
virtual IRValue * loadFromPointee(IRValue *Slot, IRType AllocTy, IRType ValueTy)=0
Dereference the pointer stored in Slot, then load the pointee.
virtual IRValue * createArith(ArithOp Op, IRValue *LHS, IRValue *RHS, IRType Ty)=0
virtual void storeAddress(IRValue *Slot, IRValue *Addr)=0
Store Addr into Slot (pointer alloca).
virtual VarAlloc allocScalar(const std::string &Name, IRType ValueTy)=0
virtual void beginIf(IRValue *Cond, const char *File, int Line)=0
virtual void storeScalar(IRValue *Slot, IRValue *Val)=0
Store Val directly into Slot (scalar alloca).
virtual IRValue * createCmp(CmpOp Op, IRValue *LHS, IRValue *RHS, IRType Ty)=0
virtual IRValue * loadAddress(IRValue *Slot, IRType AllocTy)=0
Load the pointer stored in Slot (pointer alloca).
virtual IRValue * loadScalar(IRValue *Slot, IRType ValueTy)=0
Load the value stored directly in Slot (scalar alloca).
virtual IRValue * createCast(IRValue *V, IRType FromTy, IRType ToTy)=0
virtual void storeToPointee(IRValue *Slot, IRType AllocTy, IRValue *Val)=0
Dereference the pointer stored in Slot, then store Val to it.
IRValue * convert(CodeBuilder &CB, IRValue *V)
Definition Var.h:320
Definition MemoryCache.h:26
std::remove_cv_t< std::remove_reference_t< T > > remove_cvref_t
Definition TypeTraits.h:11
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 Var.h:950
std::enable_if_t< is_arithmetic_unref_v< T >, Var< remove_cvref_t< T > > > min(const Var< T > &L, const Var< T > &R)
Definition Var.h:1149
Var< T, std::enable_if_t< is_scalar_arithmetic_v< T > > > & compoundAssignConst(Var< T, std::enable_if_t< is_scalar_arithmetic_v< T > > > &LHS, const U &ConstValue, ArithOp Op)
Definition Var.h:383
Var< float > sqrtf(const Var< T > &R)
Definition Var.h:1035
ArithOp
Semantic arithmetic operation selector.
Definition CodeBuilder.h:43
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 > &Var)
Definition Var.h:942
Var< float > fabs(const Var< T > &R)
Definition Var.h:1091
bool isFloatingPointKind(const IRType &T)
Returns true when T is a floating-point kind (Float or Double).
Definition IRType.h:57
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 Var.h:959
Var< bool > cmpOp(const Var< T > &L, const Var< U > &R, CmpOp Op)
Definition Var.h:408
Var< std::common_type_t< remove_cvref_t< T >, remove_cvref_t< U > > > binOp(const Var< T > &L, const Var< U > &R, ArithOp Op)
Definition Var.h:363
CmpOp
Semantic comparison operation selector.
Definition CodeBuilder.h:46
Var< float > sinf(const Var< T > &R)
Definition Var.h:1063
Var< T > declVar(CodeBuilder &CB, const std::string &Name="var")
Definition Var.h:334
Var< float > logf(const Var< T > &R)
Definition Var.h:1119
void reportFatalError(const llvm::Twine &Reason, const char *FILE, unsigned Line)
Definition Error.cpp:14
static int int Offset
Definition JitInterface.h:102
Var< float > cosf(const Var< T > &R)
Definition Var.h:1077
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 Var.h:967
Var< float > expf(const Var< T > &R)
Definition Var.h:1049
Var< float > powf(const Var< float > &L, const Var< T > &R)
Definition Var.h:1021
Var< float > truncf(const Var< T > &R)
Definition Var.h:1105
Var< T > defVar(CodeBuilder &CB, const T &Val, const std::string &Name="var")
Definition Var.h:350
Var< float > absf(const Var< T > &R)
Definition Var.h:1133
std::enable_if_t< is_arithmetic_unref_v< T >, Var< remove_cvref_t< T > > > max(const Var< T > &L, const Var< T > &R)
Definition Var.h:1165
bool isIntegerKind(const IRType &T)
Returns true when T is an integer kind (Int1, Int16, Int32, or Int64).
Definition IRType.h:51
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 Var.h:975
bool Signed
Signedness of the type (meaningful for integer kinds and pointer-to-int).
Definition IRType.h:38
CodeBuilder & CB
Definition Var.h:986
IRValue * operator()(const Var< U > &Operand) const
Definition Var.h:988
Definition CodeBuilder.h:29
IRType ValueTy
Pointee (element) type.
Definition Var.h:232
T ValueType
Definition Var.h:236
void storeAddress(IRValue *Ptr)
Definition Var.h:249
IRValue * getSlot() const
Definition Var.h:243
Var(VarAlloc A, CodeBuilder &CBIn)
Definition Var.h:239
CodeBuilder & CB
Definition Var.h:230
IRType getValueType() const
Definition Var.h:244
friend std::enable_if_t< std::is_arithmetic_v< OffsetT >, Var< T, std::enable_if_t< is_pointer_unref_v< T > > > > operator+(OffsetT Offset, const Var &Ptr)
Definition Var.h:281
std::remove_pointer_t< std::remove_reference_t< T > > ElemType
Definition Var.h:237
IRValue * loadValue() const
Definition Var.h:252
IRValue * Slot
Definition Var.h:231
std::enable_if_t< std::is_arithmetic_v< IdxT >, Var< std::add_lvalue_reference_t< ElemType > > > operator[](const Var< IdxT > &Index)
IRType AllocTy
Type of the pointer alloca.
Definition Var.h:233
IRType getAllocatedType() const
Definition Var.h:245
void storeValue(IRValue *Val)
Definition Var.h:255
IRValue * loadAddress() const
Definition Var.h:248
Var & operator*=(const U &ConstValue)
IRType ValueTy
Definition Var.h:24
Var & operator-=(const Var< U > &Other)
Var & operator/=(const U &ConstValue)
Var & operator%=(const U &ConstValue)
Var & operator=(const Var< U > &V)
IRValue * getSlot() const
Definition Var.h:75
void storeValue(IRValue *Val)
Definition Var.h:69
Var & operator*=(const Var< U > &Other)
Var & operator+=(const U &ConstValue)
Var(VarAlloc A, CodeBuilder &CBIn)
Definition Var.h:31
Var & operator+=(const Var< U > &Other)
CodeBuilder & CB
Definition Var.h:22
IRValue * Slot
Definition Var.h:23
IRType getAllocatedType() const
Definition Var.h:77
Var(const Var &V)=default
Var & operator%=(const Var< U > &Other)
Var & operator/=(const Var< U > &Other)
T ElemType
Definition Var.h:29
IRType getValueType() const
Definition Var.h:76
IRType AllocTy
Definition Var.h:25
Var & operator-=(const U &ConstValue)
IRValue * loadValue() const
Definition Var.h:63
Var & operator=(const U &ConstValue)
T ValueType
Definition Var.h:28
Var(VarAlloc A, CodeBuilder &CBIn)
Definition Var.h:201
IRType AllocTy
Array type.
Definition Var.h:195
T ValueType
Definition Var.h:198
CodeBuilder & CB
Definition Var.h:192
Var< std::add_pointer_t< ValueType > > getAddress() const =delete
std::enable_if_t< std::is_integral_v< IdxT >, Var< std::add_lvalue_reference_t< ElemType > > > operator[](const Var< IdxT > &Index)
IRValue * getSlot() const
Definition Var.h:205
std::remove_extent_t< T > ElemType
Definition Var.h:199
IRType getAllocatedType() const
Definition Var.h:207
IRType getValueType() const
Definition Var.h:206
IRType ValueTy
Element type.
Definition Var.h:194
IRValue * loadValue() const
Definition Var.h:210
void storeValue(IRValue *)
Definition Var.h:214
IRValue * Slot
Definition Var.h:193