[llvm] 9f738c8 - [SandboxIR] Implement GlobalObject (#108604)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 13 11:18:44 PDT 2024
Author: vporpo
Date: 2024-09-13T11:18:42-07:00
New Revision: 9f738c84f05ff965b81e0be5cc725af3fa13cbf0
URL: https://github.com/llvm/llvm-project/commit/9f738c84f05ff965b81e0be5cc725af3fa13cbf0
DIFF: https://github.com/llvm/llvm-project/commit/9f738c84f05ff965b81e0be5cc725af3fa13cbf0.diff
LOG: [SandboxIR] Implement GlobalObject (#108604)
This patch implements sandboxir::GlobalObject mirroring
llvm::GlobalObject.
Added:
Modified:
llvm/include/llvm/SandboxIR/SandboxIR.h
llvm/lib/SandboxIR/SandboxIR.cpp
llvm/unittests/SandboxIR/SandboxIRTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index d21b8a85161e4b..24c34466b4415e 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -127,6 +127,7 @@ class BlockAddress;
class DSOLocalEquivalent;
class ConstantTokenNone;
class GlobalValue;
+class GlobalObject;
class Context;
class Function;
class Instruction;
@@ -330,6 +331,7 @@ class Value {
friend class BlockAddress; // For `Val`.
friend class GlobalValue; // For `Val`.
friend class DSOLocalEquivalent; // For `Val`.
+ friend class GlobalObject; // For `Val`.
/// All values point to the context.
Context &Ctx;
@@ -1124,14 +1126,8 @@ class GlobalValue : public Constant {
GlobalValue(ClassID ID, llvm::GlobalValue *C, Context &Ctx)
: Constant(ID, C, Ctx) {}
friend class Context; // For constructor.
- Use getOperandUseInternal(unsigned OpIdx, bool Verify) const override {
- return getOperandUseDefault(OpIdx, Verify);
- }
public:
- unsigned getUseOperandNo(const Use &Use) const override {
- return getUseOperandNoDefault(Use);
- }
/// For isa/dyn_cast.
static bool classof(const sandboxir::Value *From) {
switch (From->getSubclassID()) {
@@ -1193,6 +1189,102 @@ class GlobalValue : public Constant {
// TODO: Add missing functions.
};
+class GlobalObject : public GlobalValue {
+protected:
+ GlobalObject(ClassID ID, llvm::GlobalObject *C, Context &Ctx)
+ : GlobalValue(ID, C, Ctx) {}
+ friend class Context; // For constructor.
+ Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
+ return getOperandUseDefault(OpIdx, Verify);
+ }
+
+public:
+ unsigned getUseOperandNo(const Use &Use) const final {
+ return getUseOperandNoDefault(Use);
+ }
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ switch (From->getSubclassID()) {
+ case ClassID::Function:
+ case ClassID::GlobalVariable:
+ case ClassID::GlobalIFunc:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /// FIXME: Remove this function once transition to Align is over.
+ uint64_t getAlignment() const {
+ return cast<llvm::GlobalObject>(Val)->getAlignment();
+ }
+
+ /// Returns the alignment of the given variable or function.
+ ///
+ /// Note that for functions this is the alignment of the code, not the
+ /// alignment of a function pointer.
+ MaybeAlign getAlign() const {
+ return cast<llvm::GlobalObject>(Val)->getAlign();
+ }
+
+ // TODO: Add missing: setAlignment(Align)
+
+ /// Sets the alignment attribute of the GlobalObject.
+ /// This method will be deprecated as the alignment property should always be
+ /// defined.
+ void setAlignment(MaybeAlign Align);
+
+ unsigned getGlobalObjectSubClassData() const {
+ return cast<llvm::GlobalObject>(Val)->getGlobalObjectSubClassData();
+ }
+
+ void setGlobalObjectSubClassData(unsigned V);
+
+ /// Check if this global has a custom object file section.
+ ///
+ /// This is more efficient than calling getSection() and checking for an empty
+ /// string.
+ bool hasSection() const {
+ return cast<llvm::GlobalObject>(Val)->hasSection();
+ }
+
+ /// Get the custom section of this global if it has one.
+ ///
+ /// If this global does not have a custom section, this will be empty and the
+ /// default object file section (.text, .data, etc) will be used.
+ StringRef getSection() const {
+ return cast<llvm::GlobalObject>(Val)->getSection();
+ }
+
+ /// Change the section for this global.
+ ///
+ /// Setting the section to the empty string tells LLVM to choose an
+ /// appropriate default object file section.
+ void setSection(StringRef S);
+
+ bool hasComdat() const { return cast<llvm::GlobalObject>(Val)->hasComdat(); }
+
+ // TODO: implement get/setComdat(), etc. once we have a sandboxir::Comdat.
+
+ // TODO: We currently don't support Metadata in sandboxir so all
+ // Metadata-related functions are missing.
+
+ using VCallVisibility = llvm::GlobalObject::VCallVisibility;
+
+ VCallVisibility getVCallVisibility() const {
+ return cast<llvm::GlobalObject>(Val)->getVCallVisibility();
+ }
+
+ /// Returns true if the alignment of the value can be unilaterally
+ /// increased.
+ ///
+ /// Note that for functions this is the alignment of the code, not the
+ /// alignment of a function pointer.
+ bool canIncreaseAlignment() const {
+ return cast<llvm::GlobalObject>(Val)->canIncreaseAlignment();
+ }
+};
+
class BlockAddress final : public Constant {
BlockAddress(llvm::BlockAddress *C, Context &Ctx)
: Constant(ClassID::BlockAddress, C, Ctx) {}
@@ -4127,7 +4219,7 @@ class Context {
size_t getNumValues() const { return LLVMValueToValueMap.size(); }
};
-class Function : public Constant {
+class Function : public GlobalObject {
/// Helper for mapped_iterator.
struct LLVMBBToBB {
Context &Ctx;
@@ -4138,7 +4230,7 @@ class Function : public Constant {
};
/// Use Context::createFunction() instead.
Function(llvm::Function *F, sandboxir::Context &Ctx)
- : Constant(ClassID::Function, F, Ctx) {}
+ : GlobalObject(ClassID::Function, F, Ctx) {}
friend class Context; // For constructor.
public:
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index 04243564809dbf..2f20fd3ff1dcc9 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -2495,6 +2495,30 @@ PoisonValue *PoisonValue::getElementValue(unsigned Idx) const {
cast<llvm::PoisonValue>(Val)->getElementValue(Idx)));
}
+void GlobalObject::setAlignment(MaybeAlign Align) {
+ Ctx.getTracker()
+ .emplaceIfTracking<
+ GenericSetter<&GlobalObject::getAlign, &GlobalObject::setAlignment>>(
+ this);
+ cast<llvm::GlobalObject>(Val)->setAlignment(Align);
+}
+
+void GlobalObject::setGlobalObjectSubClassData(unsigned V) {
+ Ctx.getTracker()
+ .emplaceIfTracking<
+ GenericSetter<&GlobalObject::getGlobalObjectSubClassData,
+ &GlobalObject::setGlobalObjectSubClassData>>(this);
+ cast<llvm::GlobalObject>(Val)->setGlobalObjectSubClassData(V);
+}
+
+void GlobalObject::setSection(StringRef S) {
+ Ctx.getTracker()
+ .emplaceIfTracking<
+ GenericSetter<&GlobalObject::getSection, &GlobalObject::setSection>>(
+ this);
+ cast<llvm::GlobalObject>(Val)->setSection(S);
+}
+
void GlobalValue::setUnnamedAddr(UnnamedAddr V) {
Ctx.getTracker()
.emplaceIfTracking<GenericSetter<&GlobalValue::getUnnamedAddr,
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index d883c185f82962..b1f3a6c0cf550a 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -795,6 +795,70 @@ define void @foo() {
EXPECT_EQ(GV->getVisibility(), OrigVisibility);
}
+TEST_F(SandboxIRTest, GlobalObject) {
+ parseIR(C, R"IR(
+declare external void @bar()
+define void @foo() {
+ call void @bar()
+ ret void
+}
+)IR");
+ Function &LLVMF = *M->getFunction("foo");
+ auto *LLVMBB = &*LLVMF.begin();
+ auto LLVMIt = LLVMBB->begin();
+ auto *LLVMCall = cast<llvm::CallInst>(&*LLVMIt++);
+ auto *LLVMGO = cast<llvm::GlobalObject>(LLVMCall->getCalledOperand());
+ sandboxir::Context Ctx(C);
+
+ auto &F = *Ctx.createFunction(&LLVMF);
+ auto *BB = &*F.begin();
+ auto It = BB->begin();
+ auto *Call = cast<sandboxir::CallInst>(&*It++);
+ // Check classof(), creation.
+ auto *GO = cast<sandboxir::GlobalObject>(Call->getCalledOperand());
+ // Check getAlignment().
+ EXPECT_EQ(GO->getAlignment(), LLVMGO->getAlignment());
+ // Check getAlign().
+ EXPECT_EQ(GO->getAlign(), LLVMGO->getAlign());
+ // Check setAlignment().
+ auto OrigMaybeAlign = GO->getAlign();
+ auto NewMaybeAlign = MaybeAlign(128);
+ EXPECT_NE(NewMaybeAlign, OrigMaybeAlign);
+ GO->setAlignment(NewMaybeAlign);
+ EXPECT_EQ(GO->getAlign(), NewMaybeAlign);
+ GO->setAlignment(OrigMaybeAlign);
+ EXPECT_EQ(GO->getAlign(), OrigMaybeAlign);
+ // Check getGlobalObjectSubClassData().
+ EXPECT_EQ(GO->getGlobalObjectSubClassData(),
+ LLVMGO->getGlobalObjectSubClassData());
+ // Check setGlobalObjectSubClassData().
+ auto OrigGOSCD = GO->getGlobalObjectSubClassData();
+ auto NewGOSCD = 1u;
+ EXPECT_NE(NewGOSCD, OrigGOSCD);
+ GO->setGlobalObjectSubClassData(NewGOSCD);
+ EXPECT_EQ(GO->getGlobalObjectSubClassData(), NewGOSCD);
+ GO->setGlobalObjectSubClassData(OrigGOSCD);
+ EXPECT_EQ(GO->getGlobalObjectSubClassData(), OrigGOSCD);
+ // Check hasSection().
+ EXPECT_EQ(GO->hasSection(), LLVMGO->hasSection());
+ // Check getSection().
+ EXPECT_EQ(GO->getSection(), LLVMGO->getSection());
+ // Check setSection().
+ auto OrigSection = GO->getSection();
+ auto NewSection = ".some_section";
+ EXPECT_NE(NewSection, OrigSection);
+ GO->setSection(NewSection);
+ EXPECT_EQ(GO->getSection(), NewSection);
+ GO->setSection(OrigSection);
+ EXPECT_EQ(GO->getSection(), OrigSection);
+ // Check hasComdat().
+ EXPECT_EQ(GO->hasComdat(), LLVMGO->hasComdat());
+ // Check getVCallVisibility().
+ EXPECT_EQ(GO->getVCallVisibility(), LLVMGO->getVCallVisibility());
+ // Check canIncreaseAlignment().
+ EXPECT_EQ(GO->canIncreaseAlignment(), LLVMGO->canIncreaseAlignment());
+}
+
TEST_F(SandboxIRTest, BlockAddress) {
parseIR(C, R"IR(
define void @foo(ptr %ptr) {
More information about the llvm-commits
mailing list