Skip to content

Commit 6d859c1

Browse files
authored
[SandboxIR] Implement GlobalValue (#108317)
This patch implements sandboxir::GlobalValue mirroring llvm::GlobalValue. Please note that the implementation is incomplete as it's missing several member functions.
1 parent 6292ea6 commit 6d859c1

File tree

5 files changed

+199
-2
lines changed

5 files changed

+199
-2
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ class ConstantPointerNull;
125125
class PoisonValue;
126126
class BlockAddress;
127127
class ConstantTokenNone;
128+
class GlobalValue;
128129
class Context;
129130
class Function;
130131
class Instruction;
@@ -326,6 +327,7 @@ class Value {
326327
friend class UndefValue; // For `Val`.
327328
friend class PoisonValue; // For `Val`.
328329
friend class BlockAddress; // For `Val`.
330+
friend class GlobalValue; // For `Val`.
329331

330332
/// All values point to the context.
331333
Context &Ctx;
@@ -1115,6 +1117,80 @@ class PoisonValue final : public UndefValue {
11151117
#endif
11161118
};
11171119

1120+
class GlobalValue : public Constant {
1121+
protected:
1122+
GlobalValue(ClassID ID, llvm::GlobalValue *C, Context &Ctx)
1123+
: Constant(ID, C, Ctx) {}
1124+
friend class Context; // For constructor.
1125+
Use getOperandUseInternal(unsigned OpIdx, bool Verify) const override {
1126+
return getOperandUseDefault(OpIdx, Verify);
1127+
}
1128+
1129+
public:
1130+
unsigned getUseOperandNo(const Use &Use) const override {
1131+
return getUseOperandNoDefault(Use);
1132+
}
1133+
/// For isa/dyn_cast.
1134+
static bool classof(const sandboxir::Value *From) {
1135+
switch (From->getSubclassID()) {
1136+
case ClassID::Function:
1137+
case ClassID::GlobalVariable:
1138+
case ClassID::GlobalAlias:
1139+
case ClassID::GlobalIFunc:
1140+
return true;
1141+
default:
1142+
return false;
1143+
}
1144+
}
1145+
1146+
unsigned getAddressSpace() const {
1147+
return cast<llvm::GlobalValue>(Val)->getAddressSpace();
1148+
}
1149+
bool hasGlobalUnnamedAddr() const {
1150+
return cast<llvm::GlobalValue>(Val)->hasGlobalUnnamedAddr();
1151+
}
1152+
1153+
/// Returns true if this value's address is not significant in this module.
1154+
/// This attribute is intended to be used only by the code generator and LTO
1155+
/// to allow the linker to decide whether the global needs to be in the symbol
1156+
/// table. It should probably not be used in optimizations, as the value may
1157+
/// have uses outside the module; use hasGlobalUnnamedAddr() instead.
1158+
bool hasAtLeastLocalUnnamedAddr() const {
1159+
return cast<llvm::GlobalValue>(Val)->hasAtLeastLocalUnnamedAddr();
1160+
}
1161+
1162+
using UnnamedAddr = llvm::GlobalValue::UnnamedAddr;
1163+
1164+
UnnamedAddr getUnnamedAddr() const {
1165+
return cast<llvm::GlobalValue>(Val)->getUnnamedAddr();
1166+
}
1167+
void setUnnamedAddr(UnnamedAddr V);
1168+
1169+
static UnnamedAddr getMinUnnamedAddr(UnnamedAddr A, UnnamedAddr B) {
1170+
return llvm::GlobalValue::getMinUnnamedAddr(A, B);
1171+
}
1172+
1173+
bool hasComdat() const { return cast<llvm::GlobalValue>(Val)->hasComdat(); }
1174+
1175+
// TODO: We need a SandboxIR Comdat if we want to implement getComdat().
1176+
using VisibilityTypes = llvm::GlobalValue::VisibilityTypes;
1177+
VisibilityTypes getVisibility() const {
1178+
return cast<llvm::GlobalValue>(Val)->getVisibility();
1179+
}
1180+
bool hasDefaultVisibility() const {
1181+
return cast<llvm::GlobalValue>(Val)->hasDefaultVisibility();
1182+
}
1183+
bool hasHiddenVisibility() const {
1184+
return cast<llvm::GlobalValue>(Val)->hasHiddenVisibility();
1185+
}
1186+
bool hasProtectedVisibility() const {
1187+
return cast<llvm::GlobalValue>(Val)->hasProtectedVisibility();
1188+
}
1189+
void setVisibility(VisibilityTypes V);
1190+
1191+
// TODO: Add missing functions.
1192+
};
1193+
11181194
class BlockAddress final : public Constant {
11191195
BlockAddress(llvm::BlockAddress *C, Context &Ctx)
11201196
: Constant(ClassID::BlockAddress, C, Ctx) {}
@@ -3845,8 +3921,9 @@ class Context {
38453921
friend class PointerType; // For LLVMCtx.
38463922
friend class CmpInst; // For LLVMCtx. TODO: cleanup when sandboxir::VectorType
38473923
// is complete
3848-
friend class IntegerType; // For LLVMCtx.
3849-
friend class StructType; // For LLVMCtx.
3924+
friend class IntegerType; // For LLVMCtx.
3925+
friend class StructType; // For LLVMCtx.
3926+
friend class TargetExtType; // For LLVMCtx.
38503927
Tracker IRTracker;
38513928

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

llvm/include/llvm/SandboxIR/SandboxIRValues.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ DEF_CONST(ConstantAggregateZero, ConstantAggregateZero)
3434
DEF_CONST(ConstantPointerNull, ConstantPointerNull)
3535
DEF_CONST(UndefValue, UndefValue)
3636
DEF_CONST(PoisonValue, PoisonValue)
37+
DEF_CONST(GlobalVariable, GlobalVariable)
38+
DEF_CONST(GlobalIFunc, GlobalIFunc)
39+
DEF_CONST(GlobalAlias, GlobalAlias)
3740
DEF_CONST(BlockAddress, BlockAddress)
3841
DEF_CONST(ConstantTokenNone, ConstantTokenNone)
3942

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2495,6 +2495,20 @@ PoisonValue *PoisonValue::getElementValue(unsigned Idx) const {
24952495
cast<llvm::PoisonValue>(Val)->getElementValue(Idx)));
24962496
}
24972497

2498+
void GlobalValue::setUnnamedAddr(UnnamedAddr V) {
2499+
Ctx.getTracker()
2500+
.emplaceIfTracking<GenericSetter<&GlobalValue::getUnnamedAddr,
2501+
&GlobalValue::setUnnamedAddr>>(this);
2502+
cast<llvm::GlobalValue>(Val)->setUnnamedAddr(V);
2503+
}
2504+
2505+
void GlobalValue::setVisibility(VisibilityTypes V) {
2506+
Ctx.getTracker()
2507+
.emplaceIfTracking<GenericSetter<&GlobalValue::getVisibility,
2508+
&GlobalValue::setVisibility>>(this);
2509+
cast<llvm::GlobalValue>(Val)->setVisibility(V);
2510+
}
2511+
24982512
BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) {
24992513
auto *LLVMC = llvm::BlockAddress::get(cast<llvm::Function>(F->Val),
25002514
cast<llvm::BasicBlock>(BB->Val));

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,72 @@ define void @foo() {
729729
EXPECT_EQ(UndefStruct->getNumElements(), 2u);
730730
}
731731

732+
TEST_F(SandboxIRTest, GlobalValue) {
733+
parseIR(C, R"IR(
734+
declare external void @bar()
735+
define void @foo() {
736+
call void @bar()
737+
ret void
738+
}
739+
)IR");
740+
Function &LLVMF = *M->getFunction("foo");
741+
auto *LLVMBB = &*LLVMF.begin();
742+
auto LLVMIt = LLVMBB->begin();
743+
auto *LLVMCall = cast<llvm::CallInst>(&*LLVMIt++);
744+
auto *LLVMGV = cast<llvm::GlobalValue>(LLVMCall->getCalledOperand());
745+
sandboxir::Context Ctx(C);
746+
747+
auto &F = *Ctx.createFunction(&LLVMF);
748+
auto *BB = &*F.begin();
749+
auto It = BB->begin();
750+
auto *Call = cast<sandboxir::CallInst>(&*It++);
751+
[[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
752+
753+
// Check classof(), creation, getFunction(), getBasicBlock().
754+
auto *GV = cast<sandboxir::GlobalValue>(Call->getCalledOperand());
755+
// Check getAddressSpace().
756+
EXPECT_EQ(GV->getAddressSpace(), LLVMGV->getAddressSpace());
757+
// Check hasGlobalUnnamedAddr().
758+
EXPECT_EQ(GV->hasGlobalUnnamedAddr(), LLVMGV->hasGlobalUnnamedAddr());
759+
// Check hasAtLeastLocalUnnamedAddr().
760+
EXPECT_EQ(GV->hasAtLeastLocalUnnamedAddr(),
761+
LLVMGV->hasAtLeastLocalUnnamedAddr());
762+
// Check getUnnamedAddr().
763+
EXPECT_EQ(GV->getUnnamedAddr(), LLVMGV->getUnnamedAddr());
764+
// Check setUnnamedAddr().
765+
auto OrigUnnamedAddr = GV->getUnnamedAddr();
766+
auto NewUnnamedAddr = sandboxir::GlobalValue::UnnamedAddr::Global;
767+
EXPECT_NE(NewUnnamedAddr, OrigUnnamedAddr);
768+
GV->setUnnamedAddr(NewUnnamedAddr);
769+
EXPECT_EQ(GV->getUnnamedAddr(), NewUnnamedAddr);
770+
GV->setUnnamedAddr(OrigUnnamedAddr);
771+
EXPECT_EQ(GV->getUnnamedAddr(), OrigUnnamedAddr);
772+
// Check getMinUnnamedAddr().
773+
EXPECT_EQ(
774+
sandboxir::GlobalValue::getMinUnnamedAddr(OrigUnnamedAddr,
775+
NewUnnamedAddr),
776+
llvm::GlobalValue::getMinUnnamedAddr(OrigUnnamedAddr, NewUnnamedAddr));
777+
// Check hasComdat().
778+
EXPECT_EQ(GV->hasComdat(), LLVMGV->hasComdat());
779+
// Check getVisibility().
780+
EXPECT_EQ(GV->getVisibility(), LLVMGV->getVisibility());
781+
// Check hasDefaultVisibility().
782+
EXPECT_EQ(GV->hasDefaultVisibility(), LLVMGV->hasDefaultVisibility());
783+
// Check hasHiddenVisibility().
784+
EXPECT_EQ(GV->hasHiddenVisibility(), LLVMGV->hasHiddenVisibility());
785+
// Check hasProtectedVisibility().
786+
EXPECT_EQ(GV->hasProtectedVisibility(), LLVMGV->hasProtectedVisibility());
787+
// Check setVisibility().
788+
auto OrigVisibility = GV->getVisibility();
789+
auto NewVisibility =
790+
sandboxir::GlobalValue::VisibilityTypes::ProtectedVisibility;
791+
EXPECT_NE(NewVisibility, OrigVisibility);
792+
GV->setVisibility(NewVisibility);
793+
EXPECT_EQ(GV->getVisibility(), NewVisibility);
794+
GV->setVisibility(OrigVisibility);
795+
EXPECT_EQ(GV->getVisibility(), OrigVisibility);
796+
}
797+
732798
TEST_F(SandboxIRTest, BlockAddress) {
733799
parseIR(C, R"IR(
734800
define void @foo(ptr %ptr) {

llvm/unittests/SandboxIR/TrackerTest.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,6 +1521,43 @@ define void @foo(i64 %i0, i64 %i1, float %f0, float %f1) {
15211521
checkCmpInst(Ctx, ICmp);
15221522
}
15231523

1524+
TEST_F(TrackerTest, GlobalValueSetters) {
1525+
parseIR(C, R"IR(
1526+
define void @foo() {
1527+
call void @foo()
1528+
ret void
1529+
}
1530+
)IR");
1531+
Function &LLVMF = *M->getFunction("foo");
1532+
sandboxir::Context Ctx(C);
1533+
1534+
auto &F = *Ctx.createFunction(&LLVMF);
1535+
auto *BB = &*F.begin();
1536+
auto *Call = cast<sandboxir::CallInst>(&*BB->begin());
1537+
1538+
auto *GV = cast<sandboxir::GlobalValue>(Call->getCalledOperand());
1539+
// Check setUnnamedAddr().
1540+
auto OrigUnnamedAddr = GV->getUnnamedAddr();
1541+
auto NewUnnamedAddr = sandboxir::GlobalValue::UnnamedAddr::Global;
1542+
EXPECT_NE(NewUnnamedAddr, OrigUnnamedAddr);
1543+
Ctx.save();
1544+
GV->setUnnamedAddr(NewUnnamedAddr);
1545+
EXPECT_EQ(GV->getUnnamedAddr(), NewUnnamedAddr);
1546+
Ctx.revert();
1547+
EXPECT_EQ(GV->getUnnamedAddr(), OrigUnnamedAddr);
1548+
1549+
// Check setVisibility().
1550+
auto OrigVisibility = GV->getVisibility();
1551+
auto NewVisibility =
1552+
sandboxir::GlobalValue::VisibilityTypes::ProtectedVisibility;
1553+
EXPECT_NE(NewVisibility, OrigVisibility);
1554+
Ctx.save();
1555+
GV->setVisibility(NewVisibility);
1556+
EXPECT_EQ(GV->getVisibility(), NewVisibility);
1557+
Ctx.revert();
1558+
EXPECT_EQ(GV->getVisibility(), OrigVisibility);
1559+
}
1560+
15241561
TEST_F(TrackerTest, SetVolatile) {
15251562
parseIR(C, R"IR(
15261563
define void @foo(ptr %arg0, i8 %val) {

0 commit comments

Comments
 (0)