1#ifndef PROTEUS_FRONTEND_VAR_H
2#define PROTEUS_FRONTEND_VAR_H
15template <
typename T,
typename =
void>
struct Var;
20struct Var<T,
std::enable_if_t<is_scalar_arithmetic_v<T>>> {
25 unsigned AddrSpace = 0;
31 : CB(CBIn), Slot(A.Slot), ValueTy(A.ValueTy), AllocTy(A.AllocTy),
32 AddrSpace(A.AddrSpace) {}
36 typename = std::enable_if_t<std::is_convertible_v<U, T> &&
37 (!std::is_same_v<U, T>)>>
48 Var &operator=(
const Var &V);
59 template <
typename U>
auto convert()
const;
63 if constexpr (std::is_reference_v<T>)
69 if constexpr (std::is_reference_v<T>)
100 template <
typename U>
103 template <
typename U>
107 template <
typename U>
110 template <
typename U>
140 template <
typename U>
141 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
142 operator>(
const Var<U> &Other)
const;
144 template <
typename U>
145 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
146 operator>=(
const Var<U> &Other)
const;
148 template <
typename U>
149 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
150 operator<(
const Var<U> &Other)
const;
152 template <
typename U>
153 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
154 operator<=(
const Var<U> &Other)
const;
156 template <
typename U>
157 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
158 operator==(
const Var<U> &Other)
const;
160 template <
typename U>
161 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
162 operator!=(
const Var<U> &Other)
const;
164 template <
typename U>
165 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
166 operator>(
const U &ConstValue)
const;
168 template <
typename U>
169 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
170 operator>=(
const U &ConstValue)
const;
172 template <
typename U>
173 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
174 operator<(
const U &ConstValue)
const;
176 template <
typename U>
177 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
178 operator<=(
const U &ConstValue)
const;
180 template <
typename U>
181 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
182 operator==(
const U &ConstValue)
const;
184 template <
typename U>
185 std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
186 operator!=(
const U &ConstValue)
const;
190template <
typename T>
struct Var<T,
std::enable_if_t<std::is_array_v<T>>> {
195 unsigned AddrSpace = 0;
201 : CB(CBIn), Slot(A.Slot), ValueTy(A.ValueTy), AllocTy(A.AllocTy),
202 AddrSpace(A.AddrSpace) {}
219 template <
typename IdxT>
220 std::enable_if_t<std::is_integral_v<IdxT>,
228template <
typename T>
struct Var<T,
std::enable_if_t<is_pointer_unref_v<T>>> {
233 unsigned AddrSpace = 0;
236 using ElemType = std::remove_pointer_t<std::remove_reference_t<T>>;
239 : CB(CBIn), Slot(A.Slot), ValueTy(A.ValueTy), AllocTy(A.AllocTy),
240 AddrSpace(A.AddrSpace) {}
258 template <
typename IdxT>
259 std::enable_if_t<std::is_arithmetic_v<IdxT>,
267 template <
typename OffsetT>
268 std::enable_if_t<std::is_arithmetic_v<OffsetT>,
272 template <
typename OffsetT>
273 std::enable_if_t<std::is_arithmetic_v<OffsetT>,
277 template <
typename OffsetT>
278 friend std::enable_if_t<std::is_arithmetic_v<OffsetT>,
286template <
typename T,
typename U>
287std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
288 Var<std::common_type_t<T, U>>>
289operator+(
const T &ConstValue,
const Var<U> &Var);
291template <
typename T,
typename U>
292std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
293 Var<std::common_type_t<T, U>>>
294operator-(
const T &ConstValue,
const Var<U> &V);
296template <
typename T,
typename U>
297std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
298 Var<std::common_type_t<T, U>>>
299operator*(
const T &ConstValue,
const Var<U> &V);
301template <
typename T,
typename U>
302std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
303 Var<std::common_type_t<T, U>>>
304operator/(
const T &ConstValue,
const Var<U> &V);
306template <
typename T,
typename U>
307std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
308 Var<std::common_type_t<T, U>>>
309operator%(
const T &ConstValue,
const Var<U> &V);
318template <
typename FromT,
typename ToT>
322 static_assert(std::is_arithmetic_v<From>,
"From type must be arithmetic");
323 static_assert(std::is_arithmetic_v<To>,
"To type must be arithmetic");
325 if constexpr (std::is_same_v<From, To>)
334 static_assert(!std::is_array_v<T>,
"Expected non-array type");
335 static_assert(!std::is_reference_v<T>,
336 "declVar does not support reference types");
338 if constexpr (std::is_pointer_v<T>) {
350 using RawT = std::remove_const_t<T>;
360template <
typename T,
typename U>
361Var<std::common_type_t<remove_cvref_t<T>, remove_cvref_t<U>>>
369 IRValue *LHS = detail::convert<T, CommonT>(CB, L.loadValue());
370 IRValue *RHS = detail::convert<U, CommonT>(CB, R.loadValue());
374 auto ResultVar = declVar<CommonT>(CB,
"res.");
375 ResultVar.storeValue(Result);
380template <
typename T,
typename U>
381Var<T, std::enable_if_t<is_scalar_arithmetic_v<T>>> &
383 const U &ConstValue,
ArithOp Op) {
385 "U must be convertible to T");
390 if constexpr (std::is_integral_v<remove_cvref_t<U>>) {
391 RHS = LHS.CB.getConstantInt(RHSType, ConstValue);
393 RHS = LHS.CB.getConstantFP(RHSType, ConstValue);
396 IRValue *LHSVal = LHS.loadValue();
398 RHS = detail::convert<U, T>(LHS.CB, RHS);
402 LHS.storeValue(Result);
406template <
typename T,
typename U>
413 IRValue *RHS = detail::convert<U, T>(CB, R.loadValue());
418 auto ResultVar = declVar<bool>(CB,
"res.");
419 ResultVar.storeValue(Result);
431 using ResultT = std::remove_reference_t<U>;
432 Var<ResultT> Res = declVar<ResultT>(this->CB,
"convert.");
433 IRValue *Converted = detail::convert<T, U>(this->CB, this->loadValue());
434 Res.storeValue(Converted);
439template <
typename U,
typename>
443 auto Converted = detail::convert<U, T>(CB, V.loadValue());
444 storeValue(Converted);
450 static_assert(is_mutable_v<T>,
"Cannot assign to Var<const T>");
451 storeValue(V.loadValue());
458 static_assert(is_mutable_v<T>,
"Cannot assign to Var<const T>");
459 storeValue(V.loadValue());
466 if constexpr (std::is_reference_v<T>) {
469 IRValue *PtrVal = CB.loadAddress(Slot, AllocTy);
470 auto A = CB.allocPointer(
"addr.ref.tmp", ValueTy, AddrSpace);
471 CB.storeAddress(A.Slot, PtrVal);
475 auto A = CB.allocPointer(
"addr.tmp", AllocTy, AddrSpace);
476 CB.storeAddress(A.Slot, Slot);
485 static_assert(is_mutable_v<T>,
"Cannot assign to Var<const T>");
486 auto Converted = detail::convert<U, T>(CB, V.loadValue());
487 storeValue(Converted);
495 const U &ConstValue) {
496 static_assert(is_mutable_v<T>,
"Cannot assign to Var<const T>");
497 static_assert(std::is_arithmetic_v<U>,
498 "Can only assign arithmetic types to Var");
500 IRType LHSType = getValueType();
503 storeValue(CB.getConstantInt(LHSType, ConstValue));
505 storeValue(CB.getConstantFP(LHSType, ConstValue));
517 const Var<U> &Other)
const {
525 const Var<U> &Other)
const {
533 const Var<U> &Other)
const {
541 const Var<U> &Other)
const {
549 const Var<U> &Other)
const {
558 const U &ConstValue)
const {
559 static_assert(std::is_arithmetic_v<U>,
560 "Can only add arithmetic types to Var");
561 Var<U> Tmp = defVar<U>(CB, ConstValue,
"tmp.");
562 return (*
this) + Tmp;
569 const U &ConstValue)
const {
570 static_assert(std::is_arithmetic_v<U>,
571 "Can only subtract arithmetic types from Var");
572 Var<U> Tmp = defVar<U>(CB, ConstValue,
"tmp.");
573 return (*
this) - Tmp;
580 const U &ConstValue)
const {
581 static_assert(std::is_arithmetic_v<U>,
582 "Can only multiply Var by arithmetic types");
583 Var<U> Tmp = defVar<U>(CB, ConstValue,
"tmp.");
584 return (*
this) * Tmp;
591 const U &ConstValue)
const {
592 static_assert(std::is_arithmetic_v<U>,
593 "Can only divide Var by arithmetic types");
594 Var<U> Tmp = defVar<U>(CB, ConstValue,
"tmp.");
595 return (*
this) / Tmp;
602 const U &ConstValue)
const {
603 static_assert(std::is_arithmetic_v<U>,
604 "Can only modulo Var by arithmetic types");
605 Var<U> Tmp = defVar<U>(CB, ConstValue,
"tmp.");
606 return (*
this) % Tmp;
615 static_assert(is_mutable_v<T>,
"Cannot use += on Var<const T>");
616 auto Result = (*this) + Other;
625 const U &ConstValue) {
626 static_assert(is_mutable_v<T>,
"Cannot use += on Var<const T>");
627 static_assert(std::is_arithmetic_v<U>,
628 "Can only add arithmetic types to Var");
637 static_assert(is_mutable_v<T>,
"Cannot use -= on Var<const T>");
638 auto Result = (*this) - Other;
647 const U &ConstValue) {
648 static_assert(is_mutable_v<T>,
"Cannot use -= on Var<const T>");
649 static_assert(std::is_arithmetic_v<U>,
650 "Can only subtract arithmetic types from Var");
659 static_assert(is_mutable_v<T>,
"Cannot use *= on Var<const T>");
660 auto Result = (*this) * Other;
669 const U &ConstValue) {
670 static_assert(is_mutable_v<T>,
"Cannot use *= on Var<const T>");
671 static_assert(std::is_arithmetic_v<U>,
672 "Can only multiply Var by arithmetic types");
681 static_assert(is_mutable_v<T>,
"Cannot use /= on Var<const T>");
682 auto Result = (*this) / Other;
691 const U &ConstValue) {
692 static_assert(is_mutable_v<T>,
"Cannot use /= on Var<const T>");
693 static_assert(std::is_arithmetic_v<U>,
694 "Can only divide Var by arithmetic types");
703 static_assert(is_mutable_v<T>,
"Cannot use %= on Var<const T>");
704 auto Result = (*this) % Other;
713 const U &ConstValue) {
714 static_assert(is_mutable_v<T>,
"Cannot use %= on Var<const T>");
715 static_assert(std::is_arithmetic_v<U>,
716 "Can only modulo Var by arithmetic types");
723 auto MinusOne = defVar<remove_cvref_t<T>>(
725 return MinusOne * (*this);
733 if constexpr (std::is_same_v<remove_cvref_t<T>,
bool>) {
734 ResV = CB.createNot(V);
735 }
else if constexpr (std::is_integral_v<remove_cvref_t<T>>) {
736 IRValue *Zero = CB.getConstantInt(getValueType(), 0);
737 ResV = CB.createCmp(
CmpOp::EQ, V, Zero, getValueType());
739 IRValue *Zero = CB.getConstantFP(getValueType(), 0.0);
740 ResV = CB.createCmp(
CmpOp::EQ, V, Zero, getValueType());
742 auto Ret = declVar<bool>(CB,
"not.");
743 Ret.storeValue(ResV);
750 auto A = CB.getElementPtr(Slot, AllocTy, Index, ValueTy);
755template <
typename IdxT>
756std::enable_if_t<std::is_integral_v<IdxT>,
760 auto A = CB.getElementPtr(Slot, AllocTy, Index.loadValue(), ValueTy);
765Var<std::add_lvalue_reference_t<
766 std::remove_pointer_t<std::remove_reference_t<T>>>>
768 using ElemT = std::remove_pointer_t<std::remove_reference_t<T>>;
770 IRValue *Ptr = CB.loadAddress(Slot, AllocTy);
771 auto A = CB.getElementPtr(Ptr, AllocTy, Index, ElemIRTy);
772 return Var<std::add_lvalue_reference_t<
773 std::remove_pointer_t<std::remove_reference_t<T>>>>(A, CB);
777template <
typename IdxT>
778std::enable_if_t<std::is_arithmetic_v<IdxT>,
779 Var<std::add_lvalue_reference_t<
780 std::remove_pointer_t<std::remove_reference_t<T>>>>>
783 using ElemT = std::remove_pointer_t<std::remove_reference_t<T>>;
785 IRValue *Ptr = CB.loadAddress(Slot, AllocTy);
786 auto A = CB.getElementPtr(Ptr, AllocTy, Index.loadValue(), ElemIRTy);
787 return Var<std::add_lvalue_reference_t<
788 std::remove_pointer_t<std::remove_reference_t<T>>>>(A, CB);
792Var<std::add_lvalue_reference_t<
793 std::remove_pointer_t<std::remove_reference_t<T>>>>
801 IRValue *PtrVal = CB.loadAddress(Slot, AllocTy);
804 auto A = CB.allocPointer(
"addr.ptr.tmp", PointeePtrIRTy, 0);
805 CB.storeAddress(A.Slot, PtrVal);
810template <
typename OffsetT>
811std::enable_if_t<std::is_arithmetic_v<OffsetT>,
815 IRValue *IdxVal = detail::convert<OffsetT, int64_t>(CB,
Offset.loadValue());
816 IRValue *BasePtr = CB.loadAddress(Slot, AllocTy);
817 auto A = CB.getElementPtr(BasePtr, AllocTy, IdxVal, ValueTy);
822template <
typename OffsetT>
823std::enable_if_t<std::is_arithmetic_v<OffsetT>,
828 static_cast<uint64_t
>(
Offset));
829 IRValue *BasePtr = CB.loadAddress(Slot, AllocTy);
830 auto A = CB.getElementPtr(BasePtr, AllocTy, IdxVal, ValueTy);
837std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
839 const Var<U> &Other)
const {
845std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
847 const Var<U> &Other)
const {
853std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
855 const Var<U> &Other)
const {
861std::enable_if_t<is_arithmetic_unref_v<U>, Var<bool>>
862Var<T, std::enable_if_t<is_scalar_arithmetic_v<T>>>::operator<=(
863 const Var<U> &Other)
const {
869std::enable_if_t<is_arithmetic_unref_v<U>, Var<bool>>
871 const Var<U> &Other)
const {
877std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
879 const Var<U> &Other)
const {
885std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
887 const U &ConstValue)
const {
888 Var<U> Tmp = defVar<U>(CB, ConstValue,
"cmp.");
889 return (*
this) > Tmp;
894std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
896 const U &ConstValue)
const {
897 Var<U> Tmp = defVar<U>(CB, ConstValue,
"cmp.");
898 return (*
this) >= Tmp;
903std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
905 const U &ConstValue)
const {
906 Var<U> Tmp = defVar<U>(CB, ConstValue,
"cmp.");
907 return (*
this) < Tmp;
912std::enable_if_t<is_arithmetic_unref_v<U>, Var<bool>>
913Var<T, std::enable_if_t<is_scalar_arithmetic_v<T>>>::operator<=(
914 const U &ConstValue)
const {
915 auto Tmp = defVar<U>(CB, ConstValue,
"cmp.");
916 return (*
this) <= Tmp;
921std::enable_if_t<is_arithmetic_unref_v<U>, Var<bool>>
923 const U &ConstValue)
const {
924 Var<U> Tmp = defVar<U>(CB, ConstValue,
"cmp.");
925 return (*
this) == Tmp;
930std::enable_if_t<is_arithmetic_unref_v<U>,
Var<bool>>
932 const U &ConstValue)
const {
933 auto Tmp = defVar<U>(CB, ConstValue,
"cmp.");
934 return (*
this) != Tmp;
938template <
typename T,
typename U>
939std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
942 Var<T> Tmp = defVar<T>(V.CB, ConstValue,
"tmp.");
946template <
typename T,
typename U>
947std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
948 Var<std::common_type_t<T, U>>>
950 using CommonType = std::common_type_t<T, U>;
955template <
typename T,
typename U>
956std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
957 Var<std::common_type_t<T, U>>>
959 Var<T> Tmp = defVar<T>(V.CB, ConstValue,
"tmp.");
963template <
typename T,
typename U>
964std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
965 Var<std::common_type_t<T, U>>>
967 Var<T> Tmp = defVar<T>(V.CB, ConstValue,
"tmp.");
971template <
typename T,
typename U>
972std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>,
973 Var<std::common_type_t<T, U>>>
975 Var<T> Tmp = defVar<T>(V.CB, ConstValue,
"tmp.");
988 return detail::convert<U, T>(
CB, Operand.loadValue());
992template <
typename T,
typename... Operands>
993static Var<T> emitIntrinsic(
const std::string &IntrinsicName,
994 const Operands &...Ops) {
995 static_assert(
sizeof...(Ops) > 0,
"Intrinsic requires at least one operand");
997 CodeBuilder &CB = std::get<0>(std::tie(Ops...)).CB;
998 auto CheckFn = [&CB](
const auto &Operand) {
999 if (&Operand.CB != &CB)
1002 (CheckFn(Ops), ...);
1004 IntrinsicOperandConverter<T> ConvertOperand{CB};
1006 IRType ResultIRTy = TypeMap<T>::get();
1008 CB.emitIntrinsic(IntrinsicName, ResultIRTy, {ConvertOperand(Ops)...});
1010 auto ResultVar = declVar<T>(CB,
"res.");
1011 ResultVar.storeValue(Call);
1020 static_assert(std::is_convertible_v<T, float>,
1021 "powf requires floating-point type");
1023 auto RFloat = R.template convert<float>();
1025 return emitIntrinsic<float>(
"powf", L, RFloat);
1029 static_assert(std::is_convertible_v<T, float>,
1030 "sqrtf requires floating-point type");
1032 auto RFloat = R.template convert<float>();
1033 return emitIntrinsic<float>(
"sqrtf", RFloat);
1037 static_assert(std::is_convertible_v<T, float>,
1038 "expf requires floating-point type");
1040 auto RFloat = R.template convert<float>();
1041 return emitIntrinsic<float>(
"expf", RFloat);
1045 static_assert(std::is_convertible_v<T, float>,
1046 "sinf requires floating-point type");
1048 auto RFloat = R.template convert<float>();
1049 return emitIntrinsic<float>(
"sinf", RFloat);
1053 static_assert(std::is_convertible_v<T, float>,
1054 "cosf requires floating-point type");
1056 auto RFloat = R.template convert<float>();
1057 return emitIntrinsic<float>(
"cosf", RFloat);
1061 static_assert(std::is_convertible_v<T, float>,
1062 "fabs requires floating-point type");
1064 auto RFloat = R.template convert<float>();
1065 return emitIntrinsic<float>(
"fabsf", RFloat);
1069 static_assert(std::is_convertible_v<T, float>,
1070 "truncf requires floating-point type");
1072 auto RFloat = R.template convert<float>();
1073 return emitIntrinsic<float>(
"truncf", RFloat);
1077 static_assert(std::is_convertible_v<T, float>,
1078 "logf requires floating-point type");
1080 auto RFloat = R.template convert<float>();
1081 return emitIntrinsic<float>(
"logf", RFloat);
1085 static_assert(std::is_convertible_v<T, float>,
1086 "absf requires floating-point type");
1088 auto RFloat = R.template convert<float>();
1089 return emitIntrinsic<float>(
"absf", RFloat);
1092template <
typename T>
1093std::enable_if_t<is_arithmetic_unref_v<T>, Var<remove_cvref_t<T>>>
1099 auto ResultVar = declVar<remove_cvref_t<T>>(CB,
"min_res");
1101 auto CondVar = L < R;
1102 CB.
beginIf(CondVar.loadValue(), __builtin_FILE(), __builtin_LINE());
1110template <
typename T>
1111std::enable_if_t<is_arithmetic_unref_v<T>, Var<remove_cvref_t<T>>>
1117 auto ResultVar = declVar<remove_cvref_t<T>>(CB,
"max_res");
1119 auto CondVar = L > R;
1120 CB.
beginIf(CondVar.loadValue(), __builtin_FILE(), __builtin_LINE());
Definition CodeBuilder.h:70
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:319
Definition MemoryCache.h:27
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:949
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:1094
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:382
Var< float > sqrtf(const Var< T > &R)
Definition Var.h:1028
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:941
Var< float > fabs(const Var< T > &R)
Definition Var.h:1060
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:958
Var< bool > cmpOp(const Var< T > &L, const Var< U > &R, CmpOp Op)
Definition Var.h:407
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:362
CmpOp
Semantic comparison operation selector.
Definition CodeBuilder.h:46
Var< float > sinf(const Var< T > &R)
Definition Var.h:1044
Var< T > declVar(CodeBuilder &CB, const std::string &Name="var")
Definition Var.h:333
Var< float > logf(const Var< T > &R)
Definition Var.h:1076
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:1052
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:966
Var< float > expf(const Var< T > &R)
Definition Var.h:1036
Var< float > powf(const Var< float > &L, const Var< T > &R)
Definition Var.h:1019
Var< float > truncf(const Var< T > &R)
Definition Var.h:1068
Var< T > defVar(CodeBuilder &CB, const T &Val, const std::string &Name="var")
Definition Var.h:349
Var< float > absf(const Var< T > &R)
Definition Var.h:1084
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:1112
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:974
bool Signed
Signedness of the type (meaningful for integer kinds and pointer-to-int).
Definition IRType.h:38
CodeBuilder & CB
Definition Var.h:985
IRValue * operator()(const Var< U > &Operand) const
Definition Var.h:987
Definition CodeBuilder.h:29
IRType ValueTy
Pointee (element) type.
Definition Var.h:231
T ValueType
Definition Var.h:235
void storeAddress(IRValue *Ptr)
Definition Var.h:248
IRValue * getSlot() const
Definition Var.h:242
Var(VarAlloc A, CodeBuilder &CBIn)
Definition Var.h:238
CodeBuilder & CB
Definition Var.h:229
IRType getValueType() const
Definition Var.h:243
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:280
std::remove_pointer_t< std::remove_reference_t< T > > ElemType
Definition Var.h:236
IRValue * loadValue() const
Definition Var.h:251
IRValue * Slot
Definition Var.h:230
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:232
IRType getAllocatedType() const
Definition Var.h:244
void storeValue(IRValue *Val)
Definition Var.h:254
IRValue * loadAddress() const
Definition Var.h:247
Var & operator*=(const U &ConstValue)
IRType ValueTy
Definition Var.h:23
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:74
void storeValue(IRValue *Val)
Definition Var.h:68
Var & operator*=(const Var< U > &Other)
Var & operator+=(const U &ConstValue)
Var(VarAlloc A, CodeBuilder &CBIn)
Definition Var.h:30
Var & operator+=(const Var< U > &Other)
CodeBuilder & CB
Definition Var.h:21
IRValue * Slot
Definition Var.h:22
IRType getAllocatedType() const
Definition Var.h:76
Var(const Var &V)=default
Var & operator%=(const Var< U > &Other)
Var & operator/=(const Var< U > &Other)
T ElemType
Definition Var.h:28
IRType getValueType() const
Definition Var.h:75
IRType AllocTy
Definition Var.h:24
Var & operator-=(const U &ConstValue)
IRValue * loadValue() const
Definition Var.h:62
Var & operator=(const U &ConstValue)
T ValueType
Definition Var.h:27
Var(VarAlloc A, CodeBuilder &CBIn)
Definition Var.h:200
IRType AllocTy
Array type.
Definition Var.h:194
T ValueType
Definition Var.h:197
CodeBuilder & CB
Definition Var.h:191
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:204
std::remove_extent_t< T > ElemType
Definition Var.h:198
IRType getAllocatedType() const
Definition Var.h:206
IRType getValueType() const
Definition Var.h:205
IRType ValueTy
Element type.
Definition Var.h:193
IRValue * loadValue() const
Definition Var.h:209
void storeValue(IRValue *)
Definition Var.h:213
IRValue * Slot
Definition Var.h:192