Skip to content

Commit 9f738c8

Browse files
authored
[SandboxIR] Implement GlobalObject (#108604)
This patch implements sandboxir::GlobalObject mirroring llvm::GlobalObject.
1 parent d588e49 commit 9f738c8

File tree

3 files changed

+188
-8
lines changed

3 files changed

+188
-8
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

+100-8
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ class BlockAddress;
127127
class DSOLocalEquivalent;
128128
class ConstantTokenNone;
129129
class GlobalValue;
130+
class GlobalObject;
130131
class Context;
131132
class Function;
132133
class Instruction;
@@ -330,6 +331,7 @@ class Value {
330331
friend class BlockAddress; // For `Val`.
331332
friend class GlobalValue; // For `Val`.
332333
friend class DSOLocalEquivalent; // For `Val`.
334+
friend class GlobalObject; // For `Val`.
333335

334336
/// All values point to the context.
335337
Context &Ctx;
@@ -1124,14 +1126,8 @@ class GlobalValue : public Constant {
11241126
GlobalValue(ClassID ID, llvm::GlobalValue *C, Context &Ctx)
11251127
: Constant(ID, C, Ctx) {}
11261128
friend class Context; // For constructor.
1127-
Use getOperandUseInternal(unsigned OpIdx, bool Verify) const override {
1128-
return getOperandUseDefault(OpIdx, Verify);
1129-
}
11301129

11311130
public:
1132-
unsigned getUseOperandNo(const Use &Use) const override {
1133-
return getUseOperandNoDefault(Use);
1134-
}
11351131
/// For isa/dyn_cast.
11361132
static bool classof(const sandboxir::Value *From) {
11371133
switch (From->getSubclassID()) {
@@ -1193,6 +1189,102 @@ class GlobalValue : public Constant {
11931189
// TODO: Add missing functions.
11941190
};
11951191

1192+
class GlobalObject : public GlobalValue {
1193+
protected:
1194+
GlobalObject(ClassID ID, llvm::GlobalObject *C, Context &Ctx)
1195+
: GlobalValue(ID, C, Ctx) {}
1196+
friend class Context; // For constructor.
1197+
Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
1198+
return getOperandUseDefault(OpIdx, Verify);
1199+
}
1200+
1201+
public:
1202+
unsigned getUseOperandNo(const Use &Use) const final {
1203+
return getUseOperandNoDefault(Use);
1204+
}
1205+
/// For isa/dyn_cast.
1206+
static bool classof(const sandboxir::Value *From) {
1207+
switch (From->getSubclassID()) {
1208+
case ClassID::Function:
1209+
case ClassID::GlobalVariable:
1210+
case ClassID::GlobalIFunc:
1211+
return true;
1212+
default:
1213+
return false;
1214+
}
1215+
}
1216+
1217+
/// FIXME: Remove this function once transition to Align is over.
1218+
uint64_t getAlignment() const {
1219+
return cast<llvm::GlobalObject>(Val)->getAlignment();
1220+
}
1221+
1222+
/// Returns the alignment of the given variable or function.
1223+
///
1224+
/// Note that for functions this is the alignment of the code, not the
1225+
/// alignment of a function pointer.
1226+
MaybeAlign getAlign() const {
1227+
return cast<llvm::GlobalObject>(Val)->getAlign();
1228+
}
1229+
1230+
// TODO: Add missing: setAlignment(Align)
1231+
1232+
/// Sets the alignment attribute of the GlobalObject.
1233+
/// This method will be deprecated as the alignment property should always be
1234+
/// defined.
1235+
void setAlignment(MaybeAlign Align);
1236+
1237+
unsigned getGlobalObjectSubClassData() const {
1238+
return cast<llvm::GlobalObject>(Val)->getGlobalObjectSubClassData();
1239+
}
1240+
1241+
void setGlobalObjectSubClassData(unsigned V);
1242+
1243+
/// Check if this global has a custom object file section.
1244+
///
1245+
/// This is more efficient than calling getSection() and checking for an empty
1246+
/// string.
1247+
bool hasSection() const {
1248+
return cast<llvm::GlobalObject>(Val)->hasSection();
1249+
}
1250+
1251+
/// Get the custom section of this global if it has one.
1252+
///
1253+
/// If this global does not have a custom section, this will be empty and the
1254+
/// default object file section (.text, .data, etc) will be used.
1255+
StringRef getSection() const {
1256+
return cast<llvm::GlobalObject>(Val)->getSection();
1257+
}
1258+
1259+
/// Change the section for this global.
1260+
///
1261+
/// Setting the section to the empty string tells LLVM to choose an
1262+
/// appropriate default object file section.
1263+
void setSection(StringRef S);
1264+
1265+
bool hasComdat() const { return cast<llvm::GlobalObject>(Val)->hasComdat(); }
1266+
1267+
// TODO: implement get/setComdat(), etc. once we have a sandboxir::Comdat.
1268+
1269+
// TODO: We currently don't support Metadata in sandboxir so all
1270+
// Metadata-related functions are missing.
1271+
1272+
using VCallVisibility = llvm::GlobalObject::VCallVisibility;
1273+
1274+
VCallVisibility getVCallVisibility() const {
1275+
return cast<llvm::GlobalObject>(Val)->getVCallVisibility();
1276+
}
1277+
1278+
/// Returns true if the alignment of the value can be unilaterally
1279+
/// increased.
1280+
///
1281+
/// Note that for functions this is the alignment of the code, not the
1282+
/// alignment of a function pointer.
1283+
bool canIncreaseAlignment() const {
1284+
return cast<llvm::GlobalObject>(Val)->canIncreaseAlignment();
1285+
}
1286+
};
1287+
11961288
class BlockAddress final : public Constant {
11971289
BlockAddress(llvm::BlockAddress *C, Context &Ctx)
11981290
: Constant(ClassID::BlockAddress, C, Ctx) {}
@@ -4127,7 +4219,7 @@ class Context {
41274219
size_t getNumValues() const { return LLVMValueToValueMap.size(); }
41284220
};
41294221

4130-
class Function : public Constant {
4222+
class Function : public GlobalObject {
41314223
/// Helper for mapped_iterator.
41324224
struct LLVMBBToBB {
41334225
Context &Ctx;
@@ -4138,7 +4230,7 @@ class Function : public Constant {
41384230
};
41394231
/// Use Context::createFunction() instead.
41404232
Function(llvm::Function *F, sandboxir::Context &Ctx)
4141-
: Constant(ClassID::Function, F, Ctx) {}
4233+
: GlobalObject(ClassID::Function, F, Ctx) {}
41424234
friend class Context; // For constructor.
41434235

41444236
public:

llvm/lib/SandboxIR/SandboxIR.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -2495,6 +2495,30 @@ PoisonValue *PoisonValue::getElementValue(unsigned Idx) const {
24952495
cast<llvm::PoisonValue>(Val)->getElementValue(Idx)));
24962496
}
24972497

2498+
void GlobalObject::setAlignment(MaybeAlign Align) {
2499+
Ctx.getTracker()
2500+
.emplaceIfTracking<
2501+
GenericSetter<&GlobalObject::getAlign, &GlobalObject::setAlignment>>(
2502+
this);
2503+
cast<llvm::GlobalObject>(Val)->setAlignment(Align);
2504+
}
2505+
2506+
void GlobalObject::setGlobalObjectSubClassData(unsigned V) {
2507+
Ctx.getTracker()
2508+
.emplaceIfTracking<
2509+
GenericSetter<&GlobalObject::getGlobalObjectSubClassData,
2510+
&GlobalObject::setGlobalObjectSubClassData>>(this);
2511+
cast<llvm::GlobalObject>(Val)->setGlobalObjectSubClassData(V);
2512+
}
2513+
2514+
void GlobalObject::setSection(StringRef S) {
2515+
Ctx.getTracker()
2516+
.emplaceIfTracking<
2517+
GenericSetter<&GlobalObject::getSection, &GlobalObject::setSection>>(
2518+
this);
2519+
cast<llvm::GlobalObject>(Val)->setSection(S);
2520+
}
2521+
24982522
void GlobalValue::setUnnamedAddr(UnnamedAddr V) {
24992523
Ctx.getTracker()
25002524
.emplaceIfTracking<GenericSetter<&GlobalValue::getUnnamedAddr,

llvm/unittests/SandboxIR/SandboxIRTest.cpp

+64
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,70 @@ define void @foo() {
795795
EXPECT_EQ(GV->getVisibility(), OrigVisibility);
796796
}
797797

798+
TEST_F(SandboxIRTest, GlobalObject) {
799+
parseIR(C, R"IR(
800+
declare external void @bar()
801+
define void @foo() {
802+
call void @bar()
803+
ret void
804+
}
805+
)IR");
806+
Function &LLVMF = *M->getFunction("foo");
807+
auto *LLVMBB = &*LLVMF.begin();
808+
auto LLVMIt = LLVMBB->begin();
809+
auto *LLVMCall = cast<llvm::CallInst>(&*LLVMIt++);
810+
auto *LLVMGO = cast<llvm::GlobalObject>(LLVMCall->getCalledOperand());
811+
sandboxir::Context Ctx(C);
812+
813+
auto &F = *Ctx.createFunction(&LLVMF);
814+
auto *BB = &*F.begin();
815+
auto It = BB->begin();
816+
auto *Call = cast<sandboxir::CallInst>(&*It++);
817+
// Check classof(), creation.
818+
auto *GO = cast<sandboxir::GlobalObject>(Call->getCalledOperand());
819+
// Check getAlignment().
820+
EXPECT_EQ(GO->getAlignment(), LLVMGO->getAlignment());
821+
// Check getAlign().
822+
EXPECT_EQ(GO->getAlign(), LLVMGO->getAlign());
823+
// Check setAlignment().
824+
auto OrigMaybeAlign = GO->getAlign();
825+
auto NewMaybeAlign = MaybeAlign(128);
826+
EXPECT_NE(NewMaybeAlign, OrigMaybeAlign);
827+
GO->setAlignment(NewMaybeAlign);
828+
EXPECT_EQ(GO->getAlign(), NewMaybeAlign);
829+
GO->setAlignment(OrigMaybeAlign);
830+
EXPECT_EQ(GO->getAlign(), OrigMaybeAlign);
831+
// Check getGlobalObjectSubClassData().
832+
EXPECT_EQ(GO->getGlobalObjectSubClassData(),
833+
LLVMGO->getGlobalObjectSubClassData());
834+
// Check setGlobalObjectSubClassData().
835+
auto OrigGOSCD = GO->getGlobalObjectSubClassData();
836+
auto NewGOSCD = 1u;
837+
EXPECT_NE(NewGOSCD, OrigGOSCD);
838+
GO->setGlobalObjectSubClassData(NewGOSCD);
839+
EXPECT_EQ(GO->getGlobalObjectSubClassData(), NewGOSCD);
840+
GO->setGlobalObjectSubClassData(OrigGOSCD);
841+
EXPECT_EQ(GO->getGlobalObjectSubClassData(), OrigGOSCD);
842+
// Check hasSection().
843+
EXPECT_EQ(GO->hasSection(), LLVMGO->hasSection());
844+
// Check getSection().
845+
EXPECT_EQ(GO->getSection(), LLVMGO->getSection());
846+
// Check setSection().
847+
auto OrigSection = GO->getSection();
848+
auto NewSection = ".some_section";
849+
EXPECT_NE(NewSection, OrigSection);
850+
GO->setSection(NewSection);
851+
EXPECT_EQ(GO->getSection(), NewSection);
852+
GO->setSection(OrigSection);
853+
EXPECT_EQ(GO->getSection(), OrigSection);
854+
// Check hasComdat().
855+
EXPECT_EQ(GO->hasComdat(), LLVMGO->hasComdat());
856+
// Check getVCallVisibility().
857+
EXPECT_EQ(GO->getVCallVisibility(), LLVMGO->getVCallVisibility());
858+
// Check canIncreaseAlignment().
859+
EXPECT_EQ(GO->canIncreaseAlignment(), LLVMGO->canIncreaseAlignment());
860+
}
861+
798862
TEST_F(SandboxIRTest, BlockAddress) {
799863
parseIR(C, R"IR(
800864
define void @foo(ptr %ptr) {

0 commit comments

Comments
 (0)