Skip to content

Commit 32b6e9a

Browse files
committed
[DomTree] Accept Value as Def (NFC)
Non-instruction defs like arguments, constants or global values always dominate all instructions/uses inside the function. This case currently needs to be treated separately by the caller, see https://reviews.llvm.org/D89623#inline-832818 for an example. This patch makes the dominator tree APIs accept a Value instead of an Instruction and always returns true for the non-Instruction case. A complication here is that BasicBlocks are also Values. For that reason we can't support the dominates(Value *, BasicBlock *) variant, as it would conflict with dominates(BasicBlock *, BasicBlock *), which has different semantics. For the other two APIs we assert that the passed value is not a BasicBlock. Differential Revision: https://reviews.llvm.org/D89632
1 parent d842b88 commit 32b6e9a

File tree

3 files changed

+57
-7
lines changed

3 files changed

+57
-7
lines changed

llvm/include/llvm/IR/Dominators.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,21 @@ class DominatorTree : public DominatorTreeBase<BasicBlock, false> {
165165
// Ensure base-class overloads are visible.
166166
using Base::dominates;
167167

168-
/// Return true if Def dominates a use in User.
168+
/// Return true if value Def dominates use U, in the sense that Def is
169+
/// available at U, and could be substituted as the used value without
170+
/// violating the SSA dominance requirement.
169171
///
170-
/// This performs the special checks necessary if Def and User are in the same
171-
/// basic block. Note that Def doesn't dominate a use in Def itself!
172-
bool dominates(const Instruction *Def, const Use &U) const;
173-
bool dominates(const Instruction *Def, const Instruction *User) const;
172+
/// In particular, it is worth noting that:
173+
/// * Non-instruction Defs dominate everything.
174+
/// * Def does not dominate a use in Def itself (outside of degenerate cases
175+
/// like unreachable code or trivial phi cycles).
176+
/// * Invoke/callbr Defs only dominate uses in their default destination.
177+
bool dominates(const Value *Def, const Use &U) const;
178+
/// Return true if value Def dominates all possible uses inside instruction
179+
/// User. Same comments as for the Use-based API apply.
180+
bool dominates(const Value *Def, const Instruction *User) const;
181+
// Does not accept Value to avoid ambiguity with dominance checks between
182+
// two basic blocks.
174183
bool dominates(const Instruction *Def, const BasicBlock *BB) const;
175184

176185
/// Return true if an edge dominates a use.

llvm/lib/IR/Dominators.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,14 @@ bool DominatorTree::invalidate(Function &F, const PreservedAnalyses &PA,
115115
// dominates - Return true if Def dominates a use in User. This performs
116116
// the special checks necessary if Def and User are in the same basic block.
117117
// Note that Def doesn't dominate a use in Def itself!
118-
bool DominatorTree::dominates(const Instruction *Def,
118+
bool DominatorTree::dominates(const Value *DefV,
119119
const Instruction *User) const {
120+
const Instruction *Def = dyn_cast<Instruction>(DefV);
121+
if (!Def) {
122+
assert(!isa<BasicBlock>(DefV) && "Should not be called with basic blocks");
123+
return true; // Arguments, constants, globals dominate everything.
124+
}
125+
120126
const BasicBlock *UseBB = User->getParent();
121127
const BasicBlock *DefBB = Def->getParent();
122128

@@ -250,7 +256,13 @@ bool DominatorTree::dominates(const BasicBlockEdge &BBE, const Use &U) const {
250256
return dominates(BBE, UseBB);
251257
}
252258

253-
bool DominatorTree::dominates(const Instruction *Def, const Use &U) const {
259+
bool DominatorTree::dominates(const Value *DefV, const Use &U) const {
260+
const Instruction *Def = dyn_cast<Instruction>(DefV);
261+
if (!Def) {
262+
assert(!isa<BasicBlock>(DefV) && "Should not be called with basic blocks");
263+
return true; // Arguments, constants, globals dominate everything.
264+
}
265+
254266
Instruction *UserInst = cast<Instruction>(U.getUser());
255267
const BasicBlock *DefBB = Def->getParent();
256268

llvm/unittests/IR/DominatorTreeTest.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,3 +1071,32 @@ TEST(DominatorTree, EdgeDomination) {
10711071
EXPECT_TRUE(DT->dominates(E23, E23));
10721072
});
10731073
}
1074+
1075+
TEST(DominatorTree, ValueDomination) {
1076+
StringRef ModuleString = R"(
1077+
@foo = global i8 0
1078+
define i8 @f(i8 %arg) {
1079+
ret i8 %arg
1080+
}
1081+
)";
1082+
1083+
LLVMContext Context;
1084+
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
1085+
1086+
runWithDomTree(*M, "f",
1087+
[&](Function &F, DominatorTree *DT, PostDominatorTree *PDT) {
1088+
Argument *A = F.getArg(0);
1089+
GlobalValue *G = M->getNamedValue("foo");
1090+
Constant *C = ConstantInt::getNullValue(Type::getInt8Ty(Context));
1091+
1092+
Instruction *I = F.getEntryBlock().getTerminator();
1093+
EXPECT_TRUE(DT->dominates(A, I));
1094+
EXPECT_TRUE(DT->dominates(G, I));
1095+
EXPECT_TRUE(DT->dominates(C, I));
1096+
1097+
const Use &U = I->getOperandUse(0);
1098+
EXPECT_TRUE(DT->dominates(A, U));
1099+
EXPECT_TRUE(DT->dominates(G, U));
1100+
EXPECT_TRUE(DT->dominates(C, U));
1101+
});
1102+
}

0 commit comments

Comments
 (0)