mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[LCSSA] Extract a utility for deciding if a new use requires a new lcssa phi [NFC]
(Triggered by a review comment on D98728, but otherwise unrelated.)
This commit is contained in:
parent
be8cccd26d
commit
2b6a185756
@ -1199,6 +1199,14 @@ public:
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return true if a new use of V added in ExitBB would require an LCSSA PHI
|
||||
// to be inserted at the begining of the block. Note that V is assumed to
|
||||
// dominate ExitBB, and ExitBB must be the exit block of some loop. The
|
||||
// IR is assumed to be in LCSSA form before the planned insertion.
|
||||
bool wouldBeOutOfLoopUseRequiringLCSSA(const Value *V,
|
||||
const BasicBlock *ExitBB) const;
|
||||
|
||||
};
|
||||
|
||||
// Allow clients to walk the list of nested loops...
|
||||
|
@ -924,6 +924,31 @@ void LoopInfo::erase(Loop *Unloop) {
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
LoopInfo::wouldBeOutOfLoopUseRequiringLCSSA(const Value *V,
|
||||
const BasicBlock *ExitBB) const {
|
||||
if (V->getType()->isTokenTy())
|
||||
// We can't form PHIs of token type, so the definition of LCSSA excludes
|
||||
// values of that type.
|
||||
return false;
|
||||
|
||||
const Instruction *I = dyn_cast<Instruction>(V);
|
||||
if (!I)
|
||||
return false;
|
||||
const Loop *L = getLoopFor(I->getParent());
|
||||
if (!L)
|
||||
return false;
|
||||
if (L->contains(ExitBB))
|
||||
// Could be an exit bb of a subloop and contained in defining loop
|
||||
return false;
|
||||
|
||||
// We found a (new) out-of-loop use location, for a value defined in-loop.
|
||||
// (Note that because of LCSSA, we don't have to account for values defined
|
||||
// in sibling loops. Such values will have LCSSA phis of their own in the
|
||||
// common parent loop.)
|
||||
return true;
|
||||
}
|
||||
|
||||
AnalysisKey LoopAnalysis::Key;
|
||||
|
||||
LoopInfo LoopAnalysis::run(Function &F, FunctionAnalysisManager &AM) {
|
||||
|
@ -1510,16 +1510,15 @@ static Instruction *cloneInstructionInExitBlock(
|
||||
// LCSSA. That will eliminate creating PHI nodes just to nuke them when
|
||||
// sinking bottom-up.
|
||||
for (Use &Op : New->operands())
|
||||
if (Instruction *OInst = dyn_cast<Instruction>(Op))
|
||||
if (Loop *OLoop = LI->getLoopFor(OInst->getParent()))
|
||||
if (!OLoop->contains(&PN) && !Op->getType()->isTokenTy()) {
|
||||
PHINode *OpPN =
|
||||
PHINode::Create(OInst->getType(), PN.getNumIncomingValues(),
|
||||
OInst->getName() + ".lcssa", &ExitBlock.front());
|
||||
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
|
||||
OpPN->addIncoming(OInst, PN.getIncomingBlock(i));
|
||||
Op = OpPN;
|
||||
}
|
||||
if (LI->wouldBeOutOfLoopUseRequiringLCSSA(Op.get(), PN.getParent())) {
|
||||
auto *OInst = cast<Instruction>(Op.get());
|
||||
PHINode *OpPN =
|
||||
PHINode::Create(OInst->getType(), PN.getNumIncomingValues(),
|
||||
OInst->getName() + ".lcssa", &ExitBlock.front());
|
||||
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
|
||||
OpPN->addIncoming(OInst, PN.getIncomingBlock(i));
|
||||
Op = OpPN;
|
||||
}
|
||||
return New;
|
||||
}
|
||||
|
||||
@ -1860,18 +1859,17 @@ class LoopPromoter : public LoadAndStorePromoter {
|
||||
// (if legal) if doing so would add an out-of-loop use to an instruction
|
||||
// defined in-loop.
|
||||
Value *maybeInsertLCSSAPHI(Value *V, BasicBlock *BB) const {
|
||||
if (Instruction *I = dyn_cast<Instruction>(V))
|
||||
if (Loop *L = LI.getLoopFor(I->getParent()))
|
||||
if (!L->contains(BB) && !I->getType()->isTokenTy()) {
|
||||
// We need to create an LCSSA PHI node for the incoming value and
|
||||
// store that.
|
||||
PHINode *PN = PHINode::Create(I->getType(), PredCache.size(BB),
|
||||
I->getName() + ".lcssa", &BB->front());
|
||||
for (BasicBlock *Pred : PredCache.get(BB))
|
||||
PN->addIncoming(I, Pred);
|
||||
return PN;
|
||||
}
|
||||
return V;
|
||||
if (!LI.wouldBeOutOfLoopUseRequiringLCSSA(V, BB))
|
||||
return V;
|
||||
|
||||
Instruction *I = cast<Instruction>(V);
|
||||
// We need to create an LCSSA PHI node for the incoming value and
|
||||
// store that.
|
||||
PHINode *PN = PHINode::Create(I->getType(), PredCache.size(BB),
|
||||
I->getName() + ".lcssa", &BB->front());
|
||||
for (BasicBlock *Pred : PredCache.get(BB))
|
||||
PN->addIncoming(I, Pred);
|
||||
return PN;
|
||||
}
|
||||
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user