1
0
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:
Philip Reames 2021-03-17 12:12:00 -07:00
parent be8cccd26d
commit 2b6a185756
3 changed files with 53 additions and 22 deletions

View File

@ -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...

View File

@ -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) {

View File

@ -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: