mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
Add forms of dominates and isReachableFromEntry that accept a Use
directly instead of a user Instruction. This allows them to test whether a def dominates a particular operand if the user instruction is a PHI. llvm-svn: 154631
This commit is contained in:
parent
5118ccf4c7
commit
c0a906405e
@ -775,6 +775,7 @@ public:
|
|||||||
// dominates - Return true if Def dominates a use in User. This performs
|
// dominates - Return true if Def dominates a use in User. This performs
|
||||||
// the special checks necessary if Def and User are in the same basic block.
|
// the special checks necessary if Def and User are in the same basic block.
|
||||||
// Note that Def doesn't dominate a use in Def itself!
|
// Note that Def doesn't dominate a use in Def itself!
|
||||||
|
bool dominates(const Instruction *Def, const Use &U) const;
|
||||||
bool dominates(const Instruction *Def, const Instruction *User) const;
|
bool dominates(const Instruction *Def, const Instruction *User) const;
|
||||||
bool dominates(const Instruction *Def, const BasicBlock *BB) const;
|
bool dominates(const Instruction *Def, const BasicBlock *BB) const;
|
||||||
|
|
||||||
@ -843,6 +844,8 @@ public:
|
|||||||
return DT->isReachableFromEntry(A);
|
return DT->isReachableFromEntry(A);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isReachableFromEntry(const Use &U) const;
|
||||||
|
|
||||||
|
|
||||||
virtual void releaseMemory() {
|
virtual void releaseMemory() {
|
||||||
DT->releaseMemory();
|
DT->releaseMemory();
|
||||||
|
@ -184,3 +184,84 @@ bool DominatorTree::dominates(const Instruction *Def,
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DominatorTree::dominates(const Instruction *Def,
|
||||||
|
const Use &U) const {
|
||||||
|
Instruction *UserInst = dyn_cast<Instruction>(U.getUser());
|
||||||
|
|
||||||
|
// All non-instructions conceptually dominate everything. Instructions do
|
||||||
|
// not dominate non-instructions.
|
||||||
|
if (!UserInst)
|
||||||
|
return !isa<Instruction>(Def);
|
||||||
|
|
||||||
|
const BasicBlock *DefBB = Def->getParent();
|
||||||
|
|
||||||
|
// Determine the block in which the use happens. PHI nodes use
|
||||||
|
// their operands on edges; simulate this by thinking of the use
|
||||||
|
// happening at the end of the predecessor block.
|
||||||
|
const BasicBlock *UseBB;
|
||||||
|
if (PHINode *PN = dyn_cast<PHINode>(UserInst))
|
||||||
|
UseBB = PN->getIncomingBlock(U);
|
||||||
|
else
|
||||||
|
UseBB = UserInst->getParent();
|
||||||
|
|
||||||
|
// Any unreachable use is dominated, even if Def == User.
|
||||||
|
if (!isReachableFromEntry(UseBB))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Unreachable definitions don't dominate anything.
|
||||||
|
if (!isReachableFromEntry(DefBB))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Invoke instructions define their return values on the edges
|
||||||
|
// to their normal successors, so we have to handle them specially.
|
||||||
|
// Among other things, this means they don't dominate anything in
|
||||||
|
// their own block, except possibly a phi, so we don't need to
|
||||||
|
// walk the block in any case.
|
||||||
|
if (const InvokeInst *II = dyn_cast<InvokeInst>(Def)) {
|
||||||
|
// A PHI in the normal successor using the invoke's return value is
|
||||||
|
// dominated by the invoke's return value.
|
||||||
|
if (isa<PHINode>(UserInst) &&
|
||||||
|
UserInst->getParent() == II->getNormalDest() &&
|
||||||
|
cast<PHINode>(UserInst)->getIncomingBlock(U) == DefBB)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Otherwise use the instruction-dominates-block query, which
|
||||||
|
// handles the crazy case of an invoke with a critical edge
|
||||||
|
// properly.
|
||||||
|
return dominates(Def, UseBB);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the def and use are in different blocks, do a simple CFG dominator
|
||||||
|
// tree query.
|
||||||
|
if (DefBB != UseBB)
|
||||||
|
return dominates(DefBB, UseBB);
|
||||||
|
|
||||||
|
// Ok, def and use are in the same block. If the def is an invoke, it
|
||||||
|
// doesn't dominate anything in the block. If it's a PHI, it dominates
|
||||||
|
// everything in the block.
|
||||||
|
if (isa<PHINode>(UserInst))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Otherwise, just loop through the basic block until we find Def or User.
|
||||||
|
BasicBlock::const_iterator I = DefBB->begin();
|
||||||
|
for (; &*I != Def && &*I != UserInst; ++I)
|
||||||
|
/*empty*/;
|
||||||
|
|
||||||
|
return &*I != UserInst;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DominatorTree::isReachableFromEntry(const Use &U) const {
|
||||||
|
Instruction *I = dyn_cast<Instruction>(U.getUser());
|
||||||
|
|
||||||
|
// ConstantExprs aren't really reachable from the entry block, but they
|
||||||
|
// don't need to be treated like unreachable code either.
|
||||||
|
if (!I) return true;
|
||||||
|
|
||||||
|
// PHI nodes use their operands on their incoming edges.
|
||||||
|
if (PHINode *PN = dyn_cast<PHINode>(I))
|
||||||
|
return isReachableFromEntry(PN->getIncomingBlock(U));
|
||||||
|
|
||||||
|
// Everything else uses their operands in their own block.
|
||||||
|
return isReachableFromEntry(I->getParent());
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user