Skip to content

[SandboxIR] Implement DSOLocalEquivalent #108473

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions llvm/include/llvm/SandboxIR/SandboxIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ class ConstantAggregateZero;
class ConstantPointerNull;
class PoisonValue;
class BlockAddress;
class DSOLocalEquivalent;
class ConstantTokenNone;
class GlobalValue;
class Context;
Expand Down Expand Up @@ -328,6 +329,7 @@ class Value {
friend class PoisonValue; // For `Val`.
friend class BlockAddress; // For `Val`.
friend class GlobalValue; // For `Val`.
friend class DSOLocalEquivalent; // For `Val`.

/// All values point to the context.
Context &Ctx;
Expand Down Expand Up @@ -1218,6 +1220,38 @@ class BlockAddress final : public Constant {
}
};

class DSOLocalEquivalent final : public Constant {
DSOLocalEquivalent(llvm::DSOLocalEquivalent *C, Context &Ctx)
: Constant(ClassID::DSOLocalEquivalent, C, Ctx) {}
friend class Context; // For constructor.

public:
/// Return a DSOLocalEquivalent for the specified global value.
static DSOLocalEquivalent *get(GlobalValue *GV);

GlobalValue *getGlobalValue() const;

/// For isa/dyn_cast.
static bool classof(const sandboxir::Value *From) {
return From->getSubclassID() == ClassID::DSOLocalEquivalent;
}

unsigned getUseOperandNo(const Use &Use) const final {
llvm_unreachable("DSOLocalEquivalent has no operands!");
}

#ifndef NDEBUG
void verify() const override {
assert(isa<llvm::DSOLocalEquivalent>(Val) &&
"Expected a DSOLocalEquivalent!");
}
void dumpOS(raw_ostream &OS) const override {
dumpCommonPrefix(OS);
dumpCommonSuffix(OS);
}
#endif
};

// TODO: This should inherit from ConstantData.
class ConstantTokenNone final : public Constant {
ConstantTokenNone(llvm::ConstantTokenNone *C, Context &Ctx)
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/SandboxIR/SandboxIRValues.def
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ DEF_CONST(GlobalVariable, GlobalVariable)
DEF_CONST(GlobalIFunc, GlobalIFunc)
DEF_CONST(GlobalAlias, GlobalAlias)
DEF_CONST(BlockAddress, BlockAddress)
DEF_CONST(DSOLocalEquivalent, DSOLocalEquivalent)
DEF_CONST(ConstantTokenNone, ConstantTokenNone)

#ifndef DEF_INSTR
Expand Down
18 changes: 18 additions & 0 deletions llvm/lib/SandboxIR/SandboxIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2535,6 +2535,16 @@ BasicBlock *BlockAddress::getBasicBlock() const {
Ctx.getValue(cast<llvm::BlockAddress>(Val)->getBasicBlock()));
}

DSOLocalEquivalent *DSOLocalEquivalent::get(GlobalValue *GV) {
auto *LLVMC = llvm::DSOLocalEquivalent::get(cast<llvm::GlobalValue>(GV->Val));
return cast<DSOLocalEquivalent>(GV->getContext().getValue(LLVMC));
}

GlobalValue *DSOLocalEquivalent::getGlobalValue() const {
return cast<GlobalValue>(
Ctx.getValue(cast<llvm::DSOLocalEquivalent>(Val)->getGlobalValue()));
}

ConstantTokenNone *ConstantTokenNone::get(Context &Ctx) {
auto *LLVMC = llvm::ConstantTokenNone::get(Ctx.LLVMCtx);
return cast<ConstantTokenNone>(Ctx.getOrCreateConstant(LLVMC));
Expand Down Expand Up @@ -2669,6 +2679,14 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
It->second = std::unique_ptr<UndefValue>(
new UndefValue(cast<llvm::UndefValue>(C), *this));
return It->second.get();
case llvm::Value::DSOLocalEquivalentVal: {
auto *DSOLE = cast<llvm::DSOLocalEquivalent>(C);
It->second = std::unique_ptr<DSOLocalEquivalent>(
new DSOLocalEquivalent(DSOLE, *this));
auto *Ret = It->second.get();
getOrCreateValueInternal(DSOLE->getGlobalValue(), DSOLE);
return Ret;
}
case llvm::Value::ConstantArrayVal:
It->second = std::unique_ptr<ConstantArray>(
new ConstantArray(cast<llvm::ConstantArray>(C), *this));
Expand Down
24 changes: 24 additions & 0 deletions llvm/unittests/SandboxIR/SandboxIRTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,30 @@ define void @foo(ptr %ptr) {
EXPECT_EQ(LookupBB2Addr, nullptr);
}

TEST_F(SandboxIRTest, DSOLocalEquivalent) {
parseIR(C, R"IR(
declare void @bar()
define void @foo() {
call void dso_local_equivalent @bar()
ret void
}
)IR");
Function &LLVMF = *M->getFunction("foo");
sandboxir::Context Ctx(C);

auto &F = *Ctx.createFunction(&LLVMF);
auto *BB = &*F.begin();
auto It = BB->begin();
auto *CI = cast<sandboxir::CallInst>(&*It++);
// Check classof().
auto *DSOLE = cast<sandboxir::DSOLocalEquivalent>(CI->getCalledOperand());
// Check getGlobalValue().
auto *GV = DSOLE->getGlobalValue();
// Check get().
auto *NewDSOLE = sandboxir::DSOLocalEquivalent::get(GV);
EXPECT_EQ(NewDSOLE, DSOLE);
}

TEST_F(SandboxIRTest, ConstantTokenNone) {
parseIR(C, R"IR(
define void @foo(ptr %ptr) {
Expand Down
Loading