forked from OSchip/llvm-project
[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
2426b1fa66
commit
31764ea295
|
@ -1199,6 +1199,14 @@ public:
|
||||||
|
|
||||||
return true;
|
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...
|
// 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;
|
AnalysisKey LoopAnalysis::Key;
|
||||||
|
|
||||||
LoopInfo LoopAnalysis::run(Function &F, FunctionAnalysisManager &AM) {
|
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
|
// LCSSA. That will eliminate creating PHI nodes just to nuke them when
|
||||||
// sinking bottom-up.
|
// sinking bottom-up.
|
||||||
for (Use &Op : New->operands())
|
for (Use &Op : New->operands())
|
||||||
if (Instruction *OInst = dyn_cast<Instruction>(Op))
|
if (LI->wouldBeOutOfLoopUseRequiringLCSSA(Op.get(), PN.getParent())) {
|
||||||
if (Loop *OLoop = LI->getLoopFor(OInst->getParent()))
|
auto *OInst = cast<Instruction>(Op.get());
|
||||||
if (!OLoop->contains(&PN) && !Op->getType()->isTokenTy()) {
|
PHINode *OpPN =
|
||||||
PHINode *OpPN =
|
PHINode::Create(OInst->getType(), PN.getNumIncomingValues(),
|
||||||
PHINode::Create(OInst->getType(), PN.getNumIncomingValues(),
|
OInst->getName() + ".lcssa", &ExitBlock.front());
|
||||||
OInst->getName() + ".lcssa", &ExitBlock.front());
|
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
|
||||||
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
|
OpPN->addIncoming(OInst, PN.getIncomingBlock(i));
|
||||||
OpPN->addIncoming(OInst, PN.getIncomingBlock(i));
|
Op = OpPN;
|
||||||
Op = OpPN;
|
}
|
||||||
}
|
|
||||||
return New;
|
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
|
// (if legal) if doing so would add an out-of-loop use to an instruction
|
||||||
// defined in-loop.
|
// defined in-loop.
|
||||||
Value *maybeInsertLCSSAPHI(Value *V, BasicBlock *BB) const {
|
Value *maybeInsertLCSSAPHI(Value *V, BasicBlock *BB) const {
|
||||||
if (Instruction *I = dyn_cast<Instruction>(V))
|
if (!LI.wouldBeOutOfLoopUseRequiringLCSSA(V, BB))
|
||||||
if (Loop *L = LI.getLoopFor(I->getParent()))
|
return V;
|
||||||
if (!L->contains(BB) && !I->getType()->isTokenTy()) {
|
|
||||||
// We need to create an LCSSA PHI node for the incoming value and
|
Instruction *I = cast<Instruction>(V);
|
||||||
// store that.
|
// We need to create an LCSSA PHI node for the incoming value and
|
||||||
PHINode *PN = PHINode::Create(I->getType(), PredCache.size(BB),
|
// store that.
|
||||||
I->getName() + ".lcssa", &BB->front());
|
PHINode *PN = PHINode::Create(I->getType(), PredCache.size(BB),
|
||||||
for (BasicBlock *Pred : PredCache.get(BB))
|
I->getName() + ".lcssa", &BB->front());
|
||||||
PN->addIncoming(I, Pred);
|
for (BasicBlock *Pred : PredCache.get(BB))
|
||||||
return PN;
|
PN->addIncoming(I, Pred);
|
||||||
}
|
return PN;
|
||||||
return V;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in New Issue