Skip to content

Commit f458822

Browse files
committed
[SandboxIR] Implement remaining ConstantInt functions
1 parent 2c7e1b8 commit f458822

File tree

6 files changed

+419
-6
lines changed

6 files changed

+419
-6
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 156 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ class Constant : public sandboxir::User {
565565
};
566566

567567
class ConstantInt : public Constant {
568-
ConstantInt(llvm::ConstantInt *C, sandboxir::Context &Ctx)
568+
ConstantInt(llvm::ConstantInt *C, Context &Ctx)
569569
: Constant(ClassID::ConstantInt, C, Ctx) {}
570570
friend class Context; // For constructor.
571571

@@ -574,11 +574,164 @@ class ConstantInt : public Constant {
574574
}
575575

576576
public:
577+
static ConstantInt *getTrue(Context &Ctx);
578+
static ConstantInt *getFalse(Context &Ctx);
579+
static ConstantInt *getBool(Context &Ctx, bool V);
580+
static Constant *getTrue(Type *Ty);
581+
static Constant *getFalse(Type *Ty);
582+
static Constant *getBool(Type *Ty, bool V);
583+
577584
/// If Ty is a vector type, return a Constant with a splat of the given
578585
/// value. Otherwise return a ConstantInt for the given value.
579586
static ConstantInt *get(Type *Ty, uint64_t V, bool IsSigned = false);
580587

581-
// TODO: Implement missing functions.
588+
/// Return a ConstantInt with the specified integer value for the specified
589+
/// type. If the type is wider than 64 bits, the value will be zero-extended
590+
/// to fit the type, unless IsSigned is true, in which case the value will
591+
/// be interpreted as a 64-bit signed integer and sign-extended to fit
592+
/// the type.
593+
/// Get a ConstantInt for a specific value.
594+
static ConstantInt *get(IntegerType *Ty, uint64_t V, bool IsSigned = false);
595+
596+
/// Return a ConstantInt with the specified value for the specified type. The
597+
/// value V will be canonicalized to a an unsigned APInt. Accessing it with
598+
/// either getSExtValue() or getZExtValue() will yield a correctly sized and
599+
/// signed value for the type Ty.
600+
/// Get a ConstantInt for a specific signed value.
601+
static ConstantInt *getSigned(IntegerType *Ty, int64_t V);
602+
static Constant *getSigned(Type *Ty, int64_t V);
603+
604+
/// Return a ConstantInt with the specified value and an implied Type. The
605+
/// type is the integer type that corresponds to the bit width of the value.
606+
static ConstantInt *get(Context &Ctx, const APInt &V);
607+
608+
/// Return a ConstantInt constructed from the string strStart with the given
609+
/// radix.
610+
static ConstantInt *get(IntegerType *Ty, StringRef Str, uint8_t Radix);
611+
612+
/// If Ty is a vector type, return a Constant with a splat of the given
613+
/// value. Otherwise return a ConstantInt for the given value.
614+
static Constant *get(Type *Ty, const APInt &V);
615+
616+
/// Return the constant as an APInt value reference. This allows clients to
617+
/// obtain a full-precision copy of the value.
618+
/// Return the constant's value.
619+
inline const APInt &getValue() const {
620+
return cast<llvm::ConstantInt>(Val)->getValue();
621+
}
622+
623+
/// getBitWidth - Return the scalar bitwidth of this constant.
624+
unsigned getBitWidth() const {
625+
return cast<llvm::ConstantInt>(Val)->getBitWidth();
626+
}
627+
/// Return the constant as a 64-bit unsigned integer value after it
628+
/// has been zero extended as appropriate for the type of this constant. Note
629+
/// that this method can assert if the value does not fit in 64 bits.
630+
/// Return the zero extended value.
631+
inline uint64_t getZExtValue() const {
632+
return cast<llvm::ConstantInt>(Val)->getZExtValue();
633+
}
634+
635+
/// Return the constant as a 64-bit integer value after it has been sign
636+
/// extended as appropriate for the type of this constant. Note that
637+
/// this method can assert if the value does not fit in 64 bits.
638+
/// Return the sign extended value.
639+
inline int64_t getSExtValue() const {
640+
return cast<llvm::ConstantInt>(Val)->getSExtValue();
641+
}
642+
643+
/// Return the constant as an llvm::MaybeAlign.
644+
/// Note that this method can assert if the value does not fit in 64 bits or
645+
/// is not a power of two.
646+
inline MaybeAlign getMaybeAlignValue() const {
647+
return cast<llvm::ConstantInt>(Val)->getMaybeAlignValue();
648+
}
649+
650+
/// Return the constant as an llvm::Align, interpreting `0` as `Align(1)`.
651+
/// Note that this method can assert if the value does not fit in 64 bits or
652+
/// is not a power of two.
653+
inline Align getAlignValue() const {
654+
return cast<llvm::ConstantInt>(Val)->getAlignValue();
655+
}
656+
657+
/// A helper method that can be used to determine if the constant contained
658+
/// within is equal to a constant. This only works for very small values,
659+
/// because this is all that can be represented with all types.
660+
/// Determine if this constant's value is same as an unsigned char.
661+
bool equalsInt(uint64_t V) const {
662+
return cast<llvm::ConstantInt>(Val)->equalsInt(V);
663+
}
664+
665+
/// Variant of the getType() method to always return an IntegerType, which
666+
/// reduces the amount of casting needed in parts of the compiler.
667+
IntegerType *getIntegerType() const;
668+
669+
/// This static method returns true if the type Ty is big enough to
670+
/// represent the value V. This can be used to avoid having the get method
671+
/// assert when V is larger than Ty can represent. Note that there are two
672+
/// versions of this method, one for unsigned and one for signed integers.
673+
/// Although ConstantInt canonicalizes everything to an unsigned integer,
674+
/// the signed version avoids callers having to convert a signed quantity
675+
/// to the appropriate unsigned type before calling the method.
676+
/// @returns true if V is a valid value for type Ty
677+
/// Determine if the value is in range for the given type.
678+
static bool isValueValidForType(Type *Ty, uint64_t V);
679+
static bool isValueValidForType(Type *Ty, int64_t V);
680+
681+
bool isNegative() const { return cast<llvm::ConstantInt>(Val)->isNegative(); }
682+
683+
/// This is just a convenience method to make client code smaller for a
684+
/// common code. It also correctly performs the comparison without the
685+
/// potential for an assertion from getZExtValue().
686+
bool isZero() const { return cast<llvm::ConstantInt>(Val)->isZero(); }
687+
688+
/// This is just a convenience method to make client code smaller for a
689+
/// common case. It also correctly performs the comparison without the
690+
/// potential for an assertion from getZExtValue().
691+
/// Determine if the value is one.
692+
bool isOne() const { return cast<llvm::ConstantInt>(Val)->isOne(); }
693+
694+
/// This function will return true iff every bit in this constant is set
695+
/// to true.
696+
/// @returns true iff this constant's bits are all set to true.
697+
/// Determine if the value is all ones.
698+
bool isMinusOne() const { return cast<llvm::ConstantInt>(Val)->isMinusOne(); }
699+
700+
/// This function will return true iff this constant represents the largest
701+
/// value that may be represented by the constant's type.
702+
/// @returns true iff this is the largest value that may be represented
703+
/// by this type.
704+
/// Determine if the value is maximal.
705+
bool isMaxValue(bool IsSigned) const {
706+
return cast<llvm::ConstantInt>(Val)->isMaxValue(IsSigned);
707+
}
708+
709+
/// This function will return true iff this constant represents the smallest
710+
/// value that may be represented by this constant's type.
711+
/// @returns true if this is the smallest value that may be represented by
712+
/// this type.
713+
/// Determine if the value is minimal.
714+
bool isMinValue(bool IsSigned) const {
715+
return cast<llvm::ConstantInt>(Val)->isMinValue(IsSigned);
716+
}
717+
718+
/// This function will return true iff this constant represents a value with
719+
/// active bits bigger than 64 bits or a value greater than the given uint64_t
720+
/// value.
721+
/// @returns true iff this constant is greater or equal to the given number.
722+
/// Determine if the value is greater or equal to the given number.
723+
bool uge(uint64_t Num) const {
724+
return cast<llvm::ConstantInt>(Val)->uge(Num);
725+
}
726+
727+
/// getLimitedValue - If the value is smaller than the specified limit,
728+
/// return it, otherwise return the limit value. This causes the value
729+
/// to saturate to the limit.
730+
/// @returns the min of the value of the constant and the specified value
731+
/// Get the constant's value with a saturation limit
732+
uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
733+
return cast<llvm::ConstantInt>(Val)->getLimitedValue(Limit);
734+
}
582735

583736
/// For isa/dyn_cast.
584737
static bool classof(const sandboxir::Value *From) {
@@ -3198,6 +3351,7 @@ class Context {
31983351
LLVMContext &LLVMCtx;
31993352
friend class Type; // For LLVMCtx.
32003353
friend class PointerType; // For LLVMCtx.
3354+
friend class IntegerType; // For LLVMCtx.
32013355
Tracker IRTracker;
32023356

32033357
/// Maps LLVM Value to the corresponding sandboxir::Value. Owns all

llvm/include/llvm/SandboxIR/Type.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class Type {
3838
friend class VectorType; // For LLVMTy.
3939
friend class PointerType; // For LLVMTy.
4040
friend class FunctionType; // For LLVMTy.
41+
friend class IntegerType; // For LLVMTy.
4142
friend class Function; // For LLVMTy.
4243
friend class CallBase; // For LLVMTy.
4344
friend class ConstantInt; // For LLVMTy.
@@ -295,6 +296,22 @@ class FunctionType : public Type {
295296
}
296297
};
297298

299+
/// Class to represent integer types. Note that this class is also used to
300+
/// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and
301+
/// Int64Ty.
302+
/// Integer representation type
303+
class IntegerType : public Type {
304+
public:
305+
static IntegerType *get(Context &C, unsigned NumBits);
306+
// TODO: add missing functions
307+
static bool classof(const Type *From) {
308+
return isa<llvm::IntegerType>(From->LLVMTy);
309+
}
310+
operator llvm::IntegerType &() const {
311+
return *cast<llvm::IntegerType>(LLVMTy);
312+
}
313+
};
314+
298315
} // namespace llvm::sandboxir
299316

300317
#endif // LLVM_SANDBOXIR_TYPE_H

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2243,10 +2243,71 @@ void Constant::dumpOS(raw_ostream &OS) const {
22432243
}
22442244
#endif // NDEBUG
22452245

2246+
ConstantInt *ConstantInt::getTrue(Context &Ctx) {
2247+
auto *LLVMC = llvm::ConstantInt::getTrue(Ctx.LLVMCtx);
2248+
return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
2249+
}
2250+
ConstantInt *ConstantInt::getFalse(Context &Ctx) {
2251+
auto *LLVMC = llvm::ConstantInt::getFalse(Ctx.LLVMCtx);
2252+
return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
2253+
}
2254+
ConstantInt *ConstantInt::getBool(Context &Ctx, bool V) {
2255+
auto *LLVMC = llvm::ConstantInt::getBool(Ctx.LLVMCtx, V);
2256+
return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
2257+
}
2258+
Constant *ConstantInt::getTrue(Type *Ty) {
2259+
auto *LLVMC = llvm::ConstantInt::getTrue(Ty->LLVMTy);
2260+
return Ty->getContext().getOrCreateConstant(LLVMC);
2261+
}
2262+
Constant *ConstantInt::getFalse(Type *Ty) {
2263+
auto *LLVMC = llvm::ConstantInt::getFalse(Ty->LLVMTy);
2264+
return Ty->getContext().getOrCreateConstant(LLVMC);
2265+
}
2266+
Constant *ConstantInt::getBool(Type *Ty, bool V) {
2267+
auto *LLVMC = llvm::ConstantInt::getBool(Ty->LLVMTy, V);
2268+
return Ty->getContext().getOrCreateConstant(LLVMC);
2269+
}
22462270
ConstantInt *ConstantInt::get(Type *Ty, uint64_t V, bool IsSigned) {
22472271
auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned);
22482272
return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
22492273
}
2274+
ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool IsSigned) {
2275+
auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned);
2276+
return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
2277+
}
2278+
ConstantInt *ConstantInt::getSigned(IntegerType *Ty, int64_t V) {
2279+
auto *LLVMC =
2280+
llvm::ConstantInt::getSigned(cast<llvm::IntegerType>(Ty->LLVMTy), V);
2281+
return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
2282+
}
2283+
Constant *ConstantInt::getSigned(Type *Ty, int64_t V) {
2284+
auto *LLVMC = llvm::ConstantInt::getSigned(Ty->LLVMTy, V);
2285+
return Ty->getContext().getOrCreateConstant(LLVMC);
2286+
}
2287+
ConstantInt *ConstantInt::get(Context &Ctx, const APInt &V) {
2288+
auto *LLVMC = llvm::ConstantInt::get(Ctx.LLVMCtx, V);
2289+
return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
2290+
}
2291+
ConstantInt *ConstantInt::get(IntegerType *Ty, StringRef Str, uint8_t Radix) {
2292+
auto *LLVMC =
2293+
llvm::ConstantInt::get(cast<llvm::IntegerType>(Ty->LLVMTy), Str, Radix);
2294+
return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
2295+
}
2296+
Constant *ConstantInt::get(Type *Ty, const APInt &V) {
2297+
auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V);
2298+
return Ty->getContext().getOrCreateConstant(LLVMC);
2299+
}
2300+
IntegerType *ConstantInt::getIntegerType() const {
2301+
auto *LLVMTy = cast<llvm::ConstantInt>(Val)->getIntegerType();
2302+
return cast<IntegerType>(Ctx.getType(LLVMTy));
2303+
}
2304+
2305+
bool ConstantInt::isValueValidForType(Type *Ty, uint64_t V) {
2306+
return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V);
2307+
}
2308+
bool ConstantInt::isValueValidForType(Type *Ty, int64_t V) {
2309+
return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V);
2310+
}
22502311

22512312
Constant *ConstantFP::get(Type *Ty, double V) {
22522313
auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, V);

llvm/lib/SandboxIR/Type.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,8 @@ PointerType *PointerType::get(Context &Ctx, unsigned AddressSpace) {
4646
return cast<PointerType>(
4747
Ctx.getType(llvm::PointerType::get(Ctx.LLVMCtx, AddressSpace)));
4848
}
49+
50+
IntegerType *IntegerType::get(Context &Ctx, unsigned NumBits) {
51+
return cast<IntegerType>(
52+
Ctx.getType(llvm::IntegerType::get(Ctx.LLVMCtx, NumBits)));
53+
}

0 commit comments

Comments
 (0)