Skip to content

Commit a0b2a95

Browse files
authored
[SandboxIR] Implement ConstantDataArray functions (#134729)
Mirrors LLVM IR.
1 parent 889dad7 commit a0b2a95

File tree

5 files changed

+120
-3
lines changed

5 files changed

+120
-3
lines changed

llvm/include/llvm/SandboxIR/Constant.h

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,72 @@ class ConstantDataArray final : public ConstantDataSequential {
591591
friend class Context;
592592

593593
public:
594-
// TODO: Add missing functions.
594+
static bool classof(const Value *From) {
595+
return From->getSubclassID() == ClassID::ConstantDataArray;
596+
}
597+
/// get() constructor - Return a constant with array type with an element
598+
/// count and element type matching the ArrayRef passed in. Note that this
599+
/// can return a ConstantAggregateZero object.
600+
template <typename ElementTy>
601+
static Constant *get(Context &Ctx, ArrayRef<ElementTy> Elts) {
602+
auto *NewLLVMC = llvm::ConstantDataArray::get(Ctx.LLVMCtx, Elts);
603+
return Ctx.getOrCreateConstant(NewLLVMC);
604+
}
605+
606+
/// get() constructor - ArrayTy needs to be compatible with
607+
/// ArrayRef<ElementTy>.
608+
template <typename ArrayTy>
609+
static Constant *get(Context &Ctx, ArrayTy &Elts) {
610+
return ConstantDataArray::get(Ctx, ArrayRef(Elts));
611+
}
612+
613+
/// getRaw() constructor - Return a constant with array type with an element
614+
/// count and element type matching the NumElements and ElementTy parameters
615+
/// passed in. Note that this can return a ConstantAggregateZero object.
616+
/// ElementTy must be one of i8/i16/i32/i64/half/bfloat/float/double. Data is
617+
/// the buffer containing the elements. Be careful to make sure Data uses the
618+
/// right endianness, the buffer will be used as-is.
619+
static Constant *getRaw(StringRef Data, uint64_t NumElements,
620+
Type *ElementTy) {
621+
auto *LLVMC =
622+
llvm::ConstantDataArray::getRaw(Data, NumElements, ElementTy->LLVMTy);
623+
return ElementTy->getContext().getOrCreateConstant(LLVMC);
624+
}
625+
/// getFP() constructors - Return a constant of array type with a float
626+
/// element type taken from argument `ElementType', and count taken from
627+
/// argument `Elts'. The amount of bits of the contained type must match the
628+
/// number of bits of the type contained in the passed in ArrayRef.
629+
/// (i.e. half or bfloat for 16bits, float for 32bits, double for 64bits) Note
630+
/// that this can return a ConstantAggregateZero object.
631+
static Constant *getFP(Type *ElementType, ArrayRef<uint16_t> Elts) {
632+
auto *LLVMC = llvm::ConstantDataArray::getFP(ElementType->LLVMTy, Elts);
633+
return ElementType->getContext().getOrCreateConstant(LLVMC);
634+
}
635+
static Constant *getFP(Type *ElementType, ArrayRef<uint32_t> Elts) {
636+
auto *LLVMC = llvm::ConstantDataArray::getFP(ElementType->LLVMTy, Elts);
637+
return ElementType->getContext().getOrCreateConstant(LLVMC);
638+
}
639+
static Constant *getFP(Type *ElementType, ArrayRef<uint64_t> Elts) {
640+
auto *LLVMC = llvm::ConstantDataArray::getFP(ElementType->LLVMTy, Elts);
641+
return ElementType->getContext().getOrCreateConstant(LLVMC);
642+
}
643+
/// This method constructs a CDS and initializes it with a text string.
644+
/// The default behavior (AddNull==true) causes a null terminator to
645+
/// be placed at the end of the array (increasing the length of the string by
646+
/// one more than the StringRef would normally indicate. Pass AddNull=false
647+
/// to disable this behavior.
648+
static Constant *getString(Context &Ctx, StringRef Initializer,
649+
bool AddNull = true) {
650+
auto *LLVMC =
651+
llvm::ConstantDataArray::getString(Ctx.LLVMCtx, Initializer, AddNull);
652+
return Ctx.getOrCreateConstant(LLVMC);
653+
}
654+
655+
/// Specialize the getType() method to always return an ArrayType,
656+
/// which reduces the amount of casting needed in parts of the compiler.
657+
inline ArrayType *getType() const {
658+
return cast<ArrayType>(Value::getType());
659+
}
595660
};
596661

597662
/// A vector constant whose element type is a simple 1/2/4/8-byte integer or

llvm/include/llvm/SandboxIR/Type.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ class Type {
275275
static Type *getInt1Ty(Context &Ctx);
276276
static Type *getDoubleTy(Context &Ctx);
277277
static Type *getFloatTy(Context &Ctx);
278+
static Type *getHalfTy(Context &Ctx);
278279
// TODO: missing get*
279280

280281
/// Get the address space of this pointer or pointer vector type.

llvm/include/llvm/SandboxIR/Value.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ class Value {
170170
// expose metadata in sandboxir.
171171
friend class Region;
172172
friend class ScoreBoard; // Needs access to `Val` for the instruction cost.
173+
friend class ConstantDataArray; // For `Val`
173174

174175
/// All values point to the context.
175176
Context &Ctx;

llvm/lib/SandboxIR/Type.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ Type *Type::getDoubleTy(Context &Ctx) {
3636
Type *Type::getFloatTy(Context &Ctx) {
3737
return Ctx.getType(llvm::Type::getFloatTy(Ctx.LLVMCtx));
3838
}
39+
Type *Type::getHalfTy(Context &Ctx) {
40+
return Ctx.getType(llvm::Type::getHalfTy(Ctx.LLVMCtx));
41+
}
3942

4043
#ifndef NDEBUG
4144
void Type::dumpOS(raw_ostream &OS) { LLVMTy->print(OS); }

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,10 @@ define void @foo(i32 %v0) {
298298

299299
TEST_F(SandboxIRTest, ConstantFP) {
300300
parseIR(C, R"IR(
301-
define void @foo(float %v0, double %v1) {
301+
define void @foo(float %v0, double %v1, half %v2) {
302302
%fadd0 = fadd float %v0, 42.0
303303
%fadd1 = fadd double %v1, 43.0
304+
%fadd2 = fadd half %v2, 44.0
304305
ret void
305306
}
306307
)IR");
@@ -312,12 +313,16 @@ define void @foo(float %v0, double %v1) {
312313
auto It = BB.begin();
313314
auto *FAdd0 = cast<sandboxir::BinaryOperator>(&*It++);
314315
auto *FAdd1 = cast<sandboxir::BinaryOperator>(&*It++);
316+
auto *FAdd2 = cast<sandboxir::BinaryOperator>(&*It++);
315317
auto *FortyTwo = cast<sandboxir::ConstantFP>(FAdd0->getOperand(1));
316318
[[maybe_unused]] auto *FortyThree =
317319
cast<sandboxir::ConstantFP>(FAdd1->getOperand(1));
318320

319321
auto *FloatTy = sandboxir::Type::getFloatTy(Ctx);
320322
auto *DoubleTy = sandboxir::Type::getDoubleTy(Ctx);
323+
auto *HalfTy = sandboxir::Type::getHalfTy(Ctx);
324+
EXPECT_EQ(HalfTy, Ctx.getType(llvm::Type::getHalfTy(C)));
325+
EXPECT_EQ(FAdd2->getType(), HalfTy);
321326
auto *LLVMFloatTy = Type::getFloatTy(C);
322327
auto *LLVMDoubleTy = Type::getDoubleTy(C);
323328
// Check that creating an identical constant gives us the same object.
@@ -616,6 +621,7 @@ define void @foo() {
616621
%farray = extractvalue [2 x float] [float 0.0, float 1.0], 0
617622
%fvector = extractelement <2 x double> <double 0.0, double 1.0>, i32 0
618623
%string = extractvalue [6 x i8] [i8 72, i8 69, i8 76, i8 76, i8 79, i8 0], 0
624+
%stringNoNull = extractvalue [5 x i8] [i8 72, i8 69, i8 76, i8 76, i8 79], 0
619625
ret void
620626
}
621627
)IR");
@@ -630,16 +636,19 @@ define void @foo() {
630636
auto *I2 = &*It++;
631637
auto *I3 = &*It++;
632638
auto *I4 = &*It++;
639+
auto *I5 = &*It++;
633640
auto *Array = cast<sandboxir::ConstantDataArray>(I0->getOperand(0));
634641
EXPECT_TRUE(isa<sandboxir::ConstantDataSequential>(Array));
635642
auto *Vector = cast<sandboxir::ConstantDataVector>(I1->getOperand(0));
636643
EXPECT_TRUE(isa<sandboxir::ConstantDataVector>(Vector));
637644
auto *FArray = cast<sandboxir::ConstantDataArray>(I2->getOperand(0));
638645
EXPECT_TRUE(isa<sandboxir::ConstantDataSequential>(FArray));
639-
auto *FVector = cast<sandboxir::ConstantDataArray>(I3->getOperand(0));
646+
auto *FVector = cast<sandboxir::ConstantDataVector>(I3->getOperand(0));
640647
EXPECT_TRUE(isa<sandboxir::ConstantDataVector>(FVector));
641648
auto *String = cast<sandboxir::ConstantDataArray>(I4->getOperand(0));
642649
EXPECT_TRUE(isa<sandboxir::ConstantDataArray>(String));
650+
auto *StringNoNull = cast<sandboxir::ConstantDataArray>(I5->getOperand(0));
651+
EXPECT_TRUE(isa<sandboxir::ConstantDataArray>(StringNoNull));
643652

644653
auto *Zero8 = sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 0);
645654
auto *One8 = sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 1);
@@ -706,6 +715,44 @@ define void @foo() {
706715
EXPECT_EQ(String->getAsCString(), "HELLO");
707716
// Check getRawDataValues().
708717
EXPECT_EQ(String->getRawDataValues(), HelloWithNull);
718+
719+
// Check ConstantDataArray member functions
720+
// ----------------------------------------
721+
// Check get<ElementTy>().
722+
EXPECT_EQ(sandboxir::ConstantDataArray::get<char>(Ctx, {0, 1}), Array);
723+
// Check get<ArrayTy>().
724+
SmallVector<char> Elmts({0, 1});
725+
EXPECT_EQ(sandboxir::ConstantDataArray::get<SmallVector<char>>(Ctx, Elmts),
726+
Array);
727+
// Check getRaw().
728+
EXPECT_EQ(sandboxir::ConstantDataArray::getRaw(StringRef("HELLO"), 5,
729+
Zero8->getType()),
730+
StringNoNull);
731+
// Check getFP().
732+
SmallVector<uint16_t> Elts16({42, 43});
733+
SmallVector<uint32_t> Elts32({42, 43});
734+
SmallVector<uint64_t> Elts64({42, 43});
735+
auto *F16Ty = sandboxir::Type::getHalfTy(Ctx);
736+
auto *F32Ty = sandboxir::Type::getFloatTy(Ctx);
737+
auto *F64Ty = sandboxir::Type::getDoubleTy(Ctx);
738+
739+
auto *CDA16 = sandboxir::ConstantDataArray::getFP(F16Ty, Elts16);
740+
EXPECT_EQ(CDA16, cast<sandboxir::ConstantDataArray>(
741+
Ctx.getValue(llvm::ConstantDataArray::getFP(
742+
llvm::Type::getHalfTy(C), Elts16))));
743+
auto *CDA32 = sandboxir::ConstantDataArray::getFP(F32Ty, Elts32);
744+
EXPECT_EQ(CDA32, cast<sandboxir::ConstantDataArray>(
745+
Ctx.getValue(llvm::ConstantDataArray::getFP(
746+
llvm::Type::getFloatTy(C), Elts32))));
747+
auto *CDA64 = sandboxir::ConstantDataArray::getFP(F64Ty, Elts64);
748+
EXPECT_EQ(CDA64, cast<sandboxir::ConstantDataArray>(
749+
Ctx.getValue(llvm::ConstantDataArray::getFP(
750+
llvm::Type::getDoubleTy(C), Elts64))));
751+
// Check getString().
752+
EXPECT_EQ(sandboxir::ConstantDataArray::getString(Ctx, "HELLO"), String);
753+
EXPECT_EQ(sandboxir::ConstantDataArray::getString(Ctx, "HELLO",
754+
/*AddNull=*/false),
755+
StringNoNull);
709756
}
710757

711758
TEST_F(SandboxIRTest, ConstantPointerNull) {

0 commit comments

Comments
 (0)