Skip to content

Commit b91b1f0

Browse files
authored
[SandboxIR] Implement remaining ConstantInt functions (#106775)
This patch adds the remaining ConstantInt:: functions and it also implements the IntegerType class.
1 parent 26a4edf commit b91b1f0

File tree

6 files changed

+421
-6
lines changed

6 files changed

+421
-6
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 157 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,9 @@ class Constant : public sandboxir::User {
564564
#endif
565565
};
566566

567+
// TODO: This should inherit from ConstantData.
567568
class ConstantInt : public Constant {
568-
ConstantInt(llvm::ConstantInt *C, sandboxir::Context &Ctx)
569+
ConstantInt(llvm::ConstantInt *C, Context &Ctx)
569570
: Constant(ClassID::ConstantInt, C, Ctx) {}
570571
friend class Context; // For constructor.
571572

@@ -574,11 +575,164 @@ class ConstantInt : public Constant {
574575
}
575576

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

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

583737
/// For isa/dyn_cast.
584738
static bool classof(const sandboxir::Value *From) {
@@ -3198,6 +3352,7 @@ class Context {
31983352
LLVMContext &LLVMCtx;
31993353
friend class Type; // For LLVMCtx.
32003354
friend class PointerType; // For LLVMCtx.
3355+
friend class IntegerType; // For LLVMCtx.
32013356
Tracker IRTracker;
32023357

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

llvm/include/llvm/SandboxIR/Type.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class Context;
2525
// Forward declare friend classes for MSVC.
2626
class PointerType;
2727
class VectorType;
28+
class IntegerType;
2829
class FunctionType;
2930
#define DEF_INSTR(ID, OPCODE, CLASS) class CLASS;
3031
#define DEF_CONST(ID, CLASS) class CLASS;
@@ -38,6 +39,7 @@ class Type {
3839
friend class VectorType; // For LLVMTy.
3940
friend class PointerType; // For LLVMTy.
4041
friend class FunctionType; // For LLVMTy.
42+
friend class IntegerType; // For LLVMTy.
4143
friend class Function; // For LLVMTy.
4244
friend class CallBase; // For LLVMTy.
4345
friend class ConstantInt; // For LLVMTy.
@@ -295,6 +297,22 @@ class FunctionType : public Type {
295297
}
296298
};
297299

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

300318
#endif // LLVM_SANDBOXIR_TYPE_H

llvm/lib/SandboxIR/SandboxIR.cpp

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

2253+
ConstantInt *ConstantInt::getTrue(Context &Ctx) {
2254+
auto *LLVMC = llvm::ConstantInt::getTrue(Ctx.LLVMCtx);
2255+
return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
2256+
}
2257+
ConstantInt *ConstantInt::getFalse(Context &Ctx) {
2258+
auto *LLVMC = llvm::ConstantInt::getFalse(Ctx.LLVMCtx);
2259+
return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
2260+
}
2261+
ConstantInt *ConstantInt::getBool(Context &Ctx, bool V) {
2262+
auto *LLVMC = llvm::ConstantInt::getBool(Ctx.LLVMCtx, V);
2263+
return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
2264+
}
2265+
Constant *ConstantInt::getTrue(Type *Ty) {
2266+
auto *LLVMC = llvm::ConstantInt::getTrue(Ty->LLVMTy);
2267+
return Ty->getContext().getOrCreateConstant(LLVMC);
2268+
}
2269+
Constant *ConstantInt::getFalse(Type *Ty) {
2270+
auto *LLVMC = llvm::ConstantInt::getFalse(Ty->LLVMTy);
2271+
return Ty->getContext().getOrCreateConstant(LLVMC);
2272+
}
2273+
Constant *ConstantInt::getBool(Type *Ty, bool V) {
2274+
auto *LLVMC = llvm::ConstantInt::getBool(Ty->LLVMTy, V);
2275+
return Ty->getContext().getOrCreateConstant(LLVMC);
2276+
}
22532277
ConstantInt *ConstantInt::get(Type *Ty, uint64_t V, bool IsSigned) {
22542278
auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned);
22552279
return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
22562280
}
2281+
ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool IsSigned) {
2282+
auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned);
2283+
return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
2284+
}
2285+
ConstantInt *ConstantInt::getSigned(IntegerType *Ty, int64_t V) {
2286+
auto *LLVMC =
2287+
llvm::ConstantInt::getSigned(cast<llvm::IntegerType>(Ty->LLVMTy), V);
2288+
return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
2289+
}
2290+
Constant *ConstantInt::getSigned(Type *Ty, int64_t V) {
2291+
auto *LLVMC = llvm::ConstantInt::getSigned(Ty->LLVMTy, V);
2292+
return Ty->getContext().getOrCreateConstant(LLVMC);
2293+
}
2294+
ConstantInt *ConstantInt::get(Context &Ctx, const APInt &V) {
2295+
auto *LLVMC = llvm::ConstantInt::get(Ctx.LLVMCtx, V);
2296+
return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
2297+
}
2298+
ConstantInt *ConstantInt::get(IntegerType *Ty, StringRef Str, uint8_t Radix) {
2299+
auto *LLVMC =
2300+
llvm::ConstantInt::get(cast<llvm::IntegerType>(Ty->LLVMTy), Str, Radix);
2301+
return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
2302+
}
2303+
Constant *ConstantInt::get(Type *Ty, const APInt &V) {
2304+
auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V);
2305+
return Ty->getContext().getOrCreateConstant(LLVMC);
2306+
}
2307+
IntegerType *ConstantInt::getIntegerType() const {
2308+
auto *LLVMTy = cast<llvm::ConstantInt>(Val)->getIntegerType();
2309+
return cast<IntegerType>(Ctx.getType(LLVMTy));
2310+
}
2311+
2312+
bool ConstantInt::isValueValidForType(Type *Ty, uint64_t V) {
2313+
return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V);
2314+
}
2315+
bool ConstantInt::isValueValidForType(Type *Ty, int64_t V) {
2316+
return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V);
2317+
}
22572318

22582319
Constant *ConstantFP::get(Type *Ty, double V) {
22592320
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)