Skip to content

Commit 2d8b282

Browse files
authored
[SandboxIR] Update visibility of IR constructors. (llvm#98107)
All SandboxIR objects are owned by sandboxir::Context and should be created using sandboxir::Context's builder functions. This patch protects the constructors to prohibit their use by the user.
1 parent d283627 commit 2d8b282

File tree

3 files changed

+55
-40
lines changed

3 files changed

+55
-40
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,9 @@ class Value {
117117
void clearValue() { Val = nullptr; }
118118
template <typename ItTy, typename SBTy> friend class LLVMOpUserItToSBTy;
119119

120-
public:
121120
Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx);
121+
122+
public:
122123
virtual ~Value() = default;
123124
ClassID getSubclassID() const { return SubclassID; }
124125

@@ -146,9 +147,11 @@ class Value {
146147

147148
/// Argument of a sandboxir::Function.
148149
class Argument : public sandboxir::Value {
149-
public:
150150
Argument(llvm::Argument *Arg, sandboxir::Context &Ctx)
151151
: sandboxir::Value(ClassID::Argument, Arg, Ctx) {}
152+
friend class Context; // For constructor.
153+
154+
public:
152155
static bool classof(const sandboxir::Value *From) {
153156
return From->getSubclassID() == ClassID::Argument;
154157
}
@@ -168,8 +171,10 @@ class Argument : public sandboxir::Value {
168171
};
169172

170173
class User : public Value {
171-
public:
174+
protected:
172175
User(ClassID ID, llvm::Value *V, Context &Ctx) : Value(ID, V, Ctx) {}
176+
177+
public:
173178
/// For isa/dyn_cast.
174179
static bool classof(const Value *From);
175180
#ifndef NDEBUG
@@ -187,9 +192,11 @@ class User : public Value {
187192
};
188193

189194
class Constant : public sandboxir::User {
190-
public:
191195
Constant(llvm::Constant *C, sandboxir::Context &SBCtx)
192196
: sandboxir::User(ClassID::Constant, C, SBCtx) {}
197+
friend class Context; // For constructor.
198+
199+
public:
193200
/// For isa/dyn_cast.
194201
static bool classof(const sandboxir::Value *From) {
195202
return From->getSubclassID() == ClassID::Constant ||
@@ -263,11 +270,11 @@ class Instruction : public sandboxir::User {
263270
#include "llvm/SandboxIR/SandboxIRValues.def"
264271
};
265272

273+
protected:
266274
Instruction(ClassID ID, Opcode Opc, llvm::Instruction *I,
267275
sandboxir::Context &SBCtx)
268276
: sandboxir::User(ID, I, SBCtx), Opc(Opc) {}
269277

270-
protected:
271278
Opcode Opc;
272279

273280
public:
@@ -297,11 +304,13 @@ class Instruction : public sandboxir::User {
297304
/// An LLLVM Instruction that has no SandboxIR equivalent class gets mapped to
298305
/// an OpaqueInstr.
299306
class OpaqueInst : public sandboxir::Instruction {
300-
public:
301307
OpaqueInst(llvm::Instruction *I, sandboxir::Context &Ctx)
302308
: sandboxir::Instruction(ClassID::Opaque, Opcode::Opaque, I, Ctx) {}
303309
OpaqueInst(ClassID SubclassID, llvm::Instruction *I, sandboxir::Context &Ctx)
304310
: sandboxir::Instruction(SubclassID, Opcode::Opaque, I, Ctx) {}
311+
friend class Context; // For constructor.
312+
313+
public:
305314
static bool classof(const sandboxir::Value *From) {
306315
return From->getSubclassID() == ClassID::Opaque;
307316
}
@@ -326,11 +335,12 @@ class BasicBlock : public Value {
326335
void buildBasicBlockFromLLVMIR(llvm::BasicBlock *LLVMBB);
327336
friend class Context; // For `buildBasicBlockFromIR`
328337

329-
public:
330338
BasicBlock(llvm::BasicBlock *BB, Context &SBCtx)
331339
: Value(ClassID::Block, BB, SBCtx) {
332340
buildBasicBlockFromLLVMIR(BB);
333341
}
342+
343+
public:
334344
~BasicBlock() = default;
335345
/// For isa/dyn_cast.
336346
static bool classof(const Value *From) {
@@ -385,7 +395,7 @@ class Context {
385395
auto Pair = LLVMValueToValueMap.insert({LLVMArg, nullptr});
386396
auto It = Pair.first;
387397
if (Pair.second) {
388-
It->second = std::make_unique<Argument>(LLVMArg, *this);
398+
It->second = std::unique_ptr<Argument>(new Argument(LLVMArg, *this));
389399
return cast<Argument>(It->second.get());
390400
}
391401
return cast<Argument>(It->second.get());
@@ -422,10 +432,12 @@ class Function : public sandboxir::Value {
422432
return *cast<BasicBlock>(Ctx.getValue(&LLVMBB));
423433
}
424434
};
425-
426-
public:
435+
/// Use Context::createFunction() instead.
427436
Function(llvm::Function *F, sandboxir::Context &Ctx)
428437
: sandboxir::Value(ClassID::Function, F, Ctx) {}
438+
friend class Context; // For constructor.
439+
440+
public:
429441
/// For isa/dyn_cast.
430442
static bool classof(const sandboxir::Value *From) {
431443
return From->getSubclassID() == ClassID::Function;

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -233,11 +233,11 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
233233
if (auto *C = dyn_cast<llvm::Constant>(LLVMV)) {
234234
for (llvm::Value *COp : C->operands())
235235
getOrCreateValueInternal(COp, C);
236-
It->second = std::make_unique<Constant>(C, *this);
236+
It->second = std::unique_ptr<Constant>(new Constant(C, *this));
237237
return It->second.get();
238238
}
239239
if (auto *Arg = dyn_cast<llvm::Argument>(LLVMV)) {
240-
It->second = std::make_unique<Argument>(Arg, *this);
240+
It->second = std::unique_ptr<Argument>(new Argument(Arg, *this));
241241
return It->second.get();
242242
}
243243
if (auto *BB = dyn_cast<llvm::BasicBlock>(LLVMV)) {
@@ -248,14 +248,14 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
248248
return nullptr;
249249
}
250250
assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction");
251-
It->second =
252-
std::make_unique<OpaqueInst>(cast<llvm::Instruction>(LLVMV), *this);
251+
It->second = std::unique_ptr<OpaqueInst>(
252+
new OpaqueInst(cast<llvm::Instruction>(LLVMV), *this));
253253
return It->second.get();
254254
}
255255

256256
BasicBlock *Context::createBasicBlock(llvm::BasicBlock *LLVMBB) {
257257
assert(getValue(LLVMBB) == nullptr && "Already exists!");
258-
auto NewBBPtr = std::make_unique<BasicBlock>(LLVMBB, *this);
258+
auto NewBBPtr = std::unique_ptr<BasicBlock>(new BasicBlock(LLVMBB, *this));
259259
auto *BB = cast<BasicBlock>(registerValue(std::move(NewBBPtr)));
260260
// Create SandboxIR for BB's body.
261261
BB->buildBasicBlockFromLLVMIR(LLVMBB);
@@ -271,7 +271,7 @@ Value *Context::getValue(llvm::Value *V) const {
271271

272272
Function *Context::createFunction(llvm::Function *F) {
273273
assert(getValue(F) == nullptr && "Already exists!");
274-
auto NewFPtr = std::make_unique<Function>(F, *this);
274+
auto NewFPtr = std::unique_ptr<Function>(new Function(F, *this));
275275
// Create arguments.
276276
for (auto &Arg : F->args())
277277
getOrCreateArgument(&Arg);

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,7 @@ struct SandboxIRTest : public testing::Test {
3535
}
3636
};
3737

38-
TEST_F(SandboxIRTest, UserInstantiation) {
39-
parseIR(C, R"IR(
40-
define void @foo(i32 %v1) {
41-
ret void
42-
}
43-
)IR");
44-
Function &F = *M->getFunction("foo");
45-
auto *Ret = F.begin()->getTerminator();
46-
sandboxir::Context Ctx(C);
47-
[[maybe_unused]] sandboxir::User U(sandboxir::Value::ClassID::User, Ret, Ctx);
48-
}
49-
50-
TEST_F(SandboxIRTest, FunctionArgumentConstantAndOpaqueInstInstantiation) {
38+
TEST_F(SandboxIRTest, ClassID) {
5139
parseIR(C, R"IR(
5240
define void @foo(i32 %v1) {
5341
%add = add i32 %v1, 42
@@ -58,51 +46,66 @@ define void @foo(i32 %v1) {
5846
llvm::BasicBlock *LLVMBB = &*LLVMF->begin();
5947
llvm::Instruction *LLVMAdd = &*LLVMBB->begin();
6048
auto *LLVMC = cast<llvm::Constant>(LLVMAdd->getOperand(1));
61-
auto *LLVMArg0 = LLVMF->getArg(0);
6249

6350
sandboxir::Context Ctx(C);
64-
sandboxir::Function F(LLVMF, Ctx);
65-
sandboxir::Argument Arg0(LLVMArg0, Ctx);
66-
sandboxir::Constant Const0(LLVMC, Ctx);
67-
sandboxir::OpaqueInst OpaqueI(LLVMAdd, Ctx);
51+
sandboxir::Function *F = Ctx.createFunction(LLVMF);
52+
sandboxir::Argument *Arg0 = F->getArg(0);
53+
sandboxir::BasicBlock *BB = &*F->begin();
54+
sandboxir::Instruction *AddI = &*BB->begin();
55+
sandboxir::OpaqueInst *OpaqueI = cast<sandboxir::OpaqueInst>(AddI);
56+
sandboxir::Constant *Const0 = cast<sandboxir::Constant>(Ctx.getValue(LLVMC));
6857

6958
EXPECT_TRUE(isa<sandboxir::Function>(F));
7059
EXPECT_FALSE(isa<sandboxir::Function>(Arg0));
60+
EXPECT_FALSE(isa<sandboxir::Function>(BB));
61+
EXPECT_FALSE(isa<sandboxir::Function>(AddI));
7162
EXPECT_FALSE(isa<sandboxir::Function>(Const0));
7263
EXPECT_FALSE(isa<sandboxir::Function>(OpaqueI));
7364

7465
EXPECT_FALSE(isa<sandboxir::Argument>(F));
7566
EXPECT_TRUE(isa<sandboxir::Argument>(Arg0));
67+
EXPECT_FALSE(isa<sandboxir::Argument>(BB));
68+
EXPECT_FALSE(isa<sandboxir::Argument>(AddI));
7669
EXPECT_FALSE(isa<sandboxir::Argument>(Const0));
7770
EXPECT_FALSE(isa<sandboxir::Argument>(OpaqueI));
7871

7972
EXPECT_TRUE(isa<sandboxir::Constant>(F));
8073
EXPECT_FALSE(isa<sandboxir::Constant>(Arg0));
74+
EXPECT_FALSE(isa<sandboxir::Constant>(BB));
75+
EXPECT_FALSE(isa<sandboxir::Constant>(AddI));
8176
EXPECT_TRUE(isa<sandboxir::Constant>(Const0));
8277
EXPECT_FALSE(isa<sandboxir::Constant>(OpaqueI));
8378

8479
EXPECT_FALSE(isa<sandboxir::OpaqueInst>(F));
8580
EXPECT_FALSE(isa<sandboxir::OpaqueInst>(Arg0));
81+
EXPECT_FALSE(isa<sandboxir::OpaqueInst>(BB));
82+
EXPECT_TRUE(isa<sandboxir::OpaqueInst>(AddI));
8683
EXPECT_FALSE(isa<sandboxir::OpaqueInst>(Const0));
8784
EXPECT_TRUE(isa<sandboxir::OpaqueInst>(OpaqueI));
8885

8986
EXPECT_FALSE(isa<sandboxir::Instruction>(F));
9087
EXPECT_FALSE(isa<sandboxir::Instruction>(Arg0));
88+
EXPECT_FALSE(isa<sandboxir::Instruction>(BB));
89+
EXPECT_TRUE(isa<sandboxir::Instruction>(AddI));
9190
EXPECT_FALSE(isa<sandboxir::Instruction>(Const0));
9291
EXPECT_TRUE(isa<sandboxir::Instruction>(OpaqueI));
9392

9493
EXPECT_FALSE(isa<sandboxir::User>(F));
9594
EXPECT_FALSE(isa<sandboxir::User>(Arg0));
95+
EXPECT_FALSE(isa<sandboxir::User>(BB));
96+
EXPECT_TRUE(isa<sandboxir::User>(AddI));
9697
EXPECT_TRUE(isa<sandboxir::User>(Const0));
9798
EXPECT_TRUE(isa<sandboxir::User>(OpaqueI));
9899

99100
#ifndef NDEBUG
100-
// The dump() functions should be very forgiving and should not crash even if
101-
// sandboxir has not been built properly.
102-
F.dump();
103-
Arg0.dump();
104-
Const0.dump();
105-
OpaqueI.dump();
101+
std::string Buff;
102+
raw_string_ostream BS(Buff);
103+
F->dump(BS);
104+
Arg0->dump(BS);
105+
BB->dump(BS);
106+
AddI->dump(BS);
107+
Const0->dump(BS);
108+
OpaqueI->dump(BS);
106109
#endif
107110
}
108111

0 commit comments

Comments
 (0)