[llvm] r200067 - [LPM] Make LCSSA a utility with a FunctionPass that applies it to all
Bruno Cardoso Lopes
bruno.cardoso at gmail.com
Thu Dec 11 12:07:23 PST 2014
Hi Chandler,
Sorry for the commit necromancy,
On Sat, Jan 25, 2014 at 2:07 AM, Chandler Carruth <chandlerc at gmail.com> wrote:
> Author: chandlerc
> Date: Fri Jan 24 22:07:24 2014
> New Revision: 200067
>
> URL: http://llvm.org/viewvc/llvm-project?rev=200067&view=rev
> Log:
> [LPM] Make LCSSA a utility with a FunctionPass that applies it to all
> the loops in a function, and teach LICM to work in the presance of
> LCSSA.
>
> Previously, LCSSA was a loop pass. That made passes requiring it also be
> loop passes and unable to depend on function analysis passes easily. It
> also caused outer loops to have a different "canonical" form from inner
> loops during analysis. Instead, we go into LCSSA form and preserve it
> through the loop pass manager run.
>
> Note that this has the same problem as LoopSimplify that prevents
> enabling its verification -- loop passes which run at the end of the loop
> pass manager and don't preserve these are valid, but the subsequent loop
> pass runs of outer loops that do preserve this pass trigger too much
> verification and fail because the inner loop no longer verifies.
>
> The other problem this exposed is that LICM was completely unable to
> handle LCSSA form. It didn't preserve it and it actually would give up
> on moving instructions in many cases when they were used by an LCSSA phi
> node. I've taught LICM to support detecting LCSSA-form PHI nodes and to
> hoist and sink around them. This may actually let LICM fire
> significantly more because we put everything into LCSSA form to rotate
> the loop before running LICM. =/ Now LICM should handle that fine and
> preserve it correctly. The down side is that LICM has to require LCSSA
> in order to preserve it. This is just a fact of life for LCSSA. It's
> entirely possible we should completely remove LCSSA from the optimizer.
>
> The test updates are essentially accomodating LCSSA phi nodes in the
> output of LICM, and the fact that we now completely sink every
> instruction in ashr-crash below the loop bodies prior to unrolling.
>
> With this change, LCSSA is computed only three times in the pass
> pipeline. One of them could be removed (and potentially a SCEV run and
> a separate LoopPassManager entirely!) if we had a LoopPass variant of
> InstCombine that ran InstCombine on the loop body but refused to combine
> away LCSSA PHI nodes. Currently, this also prevents loop unrolling from
> being in the same loop pass manager is rotate, LICM, and unswitch.
>
> There is one thing that I *really* don't like -- preserving LCSSA in
> LICM is quite expensive. We end up having to re-run LCSSA twice for some
> loops after LICM runs because LICM can undo LCSSA both in the current
> loop and the parent loop. I don't really see good solutions to this
> other than to completely move away from LCSSA and using tools like
> SSAUpdater instead.
>
> Modified:
> llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h
> llvm/trunk/lib/Transforms/Scalar/LICM.cpp
> llvm/trunk/lib/Transforms/Utils/LCSSA.cpp
> llvm/trunk/test/Transforms/LICM/scalar_promote.ll
> llvm/trunk/test/Transforms/LICM/sinking.ll
> llvm/trunk/test/Transforms/LoopSimplify/ashr-crash.ll
>
> Modified: llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h?rev=200067&r1=200066&r2=200067&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h (original)
> +++ llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h Fri Jan 24 22:07:24 2014
> @@ -34,6 +34,19 @@ BasicBlock *InsertPreheaderForLoop(Loop
> bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, Pass *PP,
> AliasAnalysis *AA = 0, ScalarEvolution *SE = 0);
>
> +/// \brief Put loop into LCSSA form.
> +///
> +/// Looks at all instructions in the loop which have uses outside of the
> +/// current loop. For each, an LCSSA PHI node is inserted and the uses outside
> +/// the loop are rewritten to use this node.
> +///
> +/// LoopInfo and DominatorTree are required and preserved.
> +///
> +/// If ScalarEvolution is passed in, it will be preserved.
> +///
> +/// Returns true if any modifications are made to the loop.
> +bool formLCSSA(Loop &L, DominatorTree &DT, ScalarEvolution *SE = 0);
> +
> }
>
> #endif
>
> Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=200067&r1=200066&r2=200067&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Fri Jan 24 22:07:24 2014
> @@ -54,6 +54,7 @@
> #include "llvm/Support/raw_ostream.h"
> #include "llvm/Target/TargetLibraryInfo.h"
> #include "llvm/Transforms/Utils/Local.h"
> +#include "llvm/Transforms/Utils/LoopUtils.h"
> #include "llvm/Transforms/Utils/SSAUpdater.h"
> #include <algorithm>
> using namespace llvm;
> @@ -85,10 +86,12 @@ namespace {
> AU.addRequired<DominatorTreeWrapperPass>();
> AU.addRequired<LoopInfo>();
> AU.addRequiredID(LoopSimplifyID);
> + AU.addPreservedID(LoopSimplifyID);
> + AU.addRequiredID(LCSSAID);
> + AU.addPreservedID(LCSSAID);
> AU.addRequired<AliasAnalysis>();
> AU.addPreserved<AliasAnalysis>();
> AU.addPreserved<ScalarEvolution>();
> - AU.addPreservedID(LoopSimplifyID);
> AU.addRequired<TargetLibraryInfo>();
> }
>
> @@ -193,6 +196,8 @@ INITIALIZE_PASS_BEGIN(LICM, "licm", "Loo
> INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
> INITIALIZE_PASS_DEPENDENCY(LoopInfo)
> INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
> +INITIALIZE_PASS_DEPENDENCY(LCSSA)
> +INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
> INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)
> INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
> INITIALIZE_PASS_END(LICM, "licm", "Loop Invariant Code Motion", false, false)
> @@ -283,6 +288,14 @@ bool LICM::runOnLoop(Loop *L, LPPassMana
> PromoteAliasSet(*I, ExitBlocks, InsertPts);
> }
>
> + // If we have successfully changed the loop, re-form LCSSA and also re-form
> + // LCSSA in the parent loop as hoisting or sinking may have broken it.
> + if (Changed) {
> + formLCSSA(*L, *DT, getAnalysisIfAvailable<ScalarEvolution>());
> + if (Loop *ParentL = L->getParentLoop())
> + formLCSSA(*ParentL, *DT, getAnalysisIfAvailable<ScalarEvolution>());
> + }
> +
> // Clear out loops state information for the next iteration
> CurLoop = 0;
> Preheader = 0;
> @@ -451,6 +464,19 @@ bool LICM::canSinkOrHoistInst(Instructio
> return isSafeToExecuteUnconditionally(I);
> }
>
> +/// \brief Returns true if a PHINode is a trivially replaceable with an
> +/// Instruction.
> +///
> +/// This is true when all incoming values are that instruction. This pattern
> +/// occurs most often with LCSSA PHI nodes.
> +static bool isTriviallyReplacablePHI(PHINode &PN, Instruction &I) {
> + for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
> + if (PN.getIncomingValue(i) != &I)
> + return false;
> +
> + return true;
> +}
> +
> /// isNotUsedInLoop - Return true if the only users of this instruction are
> /// outside of the loop. If this is true, we can sink the instruction to the
> /// exit blocks of the loop.
> @@ -459,18 +485,48 @@ bool LICM::isNotUsedInLoop(Instruction &
> for (Value::use_iterator UI = I.use_begin(), E = I.use_end(); UI != E; ++UI) {
> Instruction *User = cast<Instruction>(*UI);
> if (PHINode *PN = dyn_cast<PHINode>(User)) {
> - // PHI node uses occur in predecessor blocks!
> + // A PHI node where all of the incoming values are this instruction are
> + // special -- they can just be RAUW'ed with the instruction and thus
> + // don't require a use in the predecessor. This is a particular important
> + // special case because it is the pattern found in LCSSA form.
> + if (isTriviallyReplacablePHI(*PN, I)) {
> + if (CurLoop->contains(PN))
> + return false;
> + else
> + continue;
> + }
> +
> + // Otherwise, PHI node uses occur in predecessor blocks if the incoming
> + // values. Check for such a use being inside the loop.
> for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
> if (PN->getIncomingValue(i) == &I)
> if (CurLoop->contains(PN->getIncomingBlock(i)))
> return false;
> - } else if (CurLoop->contains(User)) {
> - return false;
> +
> + continue;
> }
> +
> + if (CurLoop->contains(User))
> + return false;
> }
> return true;
> }
>
> +static BasicBlock::iterator
> +replaceTrivialPHIsAndGetInsertionPt(BasicBlock &BB, Instruction &I) {
> + BasicBlock::iterator II = BB.begin();
> + while (PHINode *PN = dyn_cast<PHINode>(II)) {
> + ++II;
> + if (isTriviallyReplacablePHI(*PN, I)) {
> + PN->replaceAllUsesWith(&I);
> + PN->eraseFromParent();
> + }
> + }
> + if (isa<LandingPadInst>(II))
> + ++II;
> +
> + return II;
> +}
>
> /// sink - When an instruction is found to only be used outside of the loop,
> /// this function moves it to the exit blocks and patches up SSA form as needed.
> @@ -502,9 +558,14 @@ void LICM::sink(Instruction &I) {
> I.replaceAllUsesWith(UndefValue::get(I.getType()));
> I.eraseFromParent();
> } else {
> + // Look for any LCSSA PHI nodes for this instruction in the exit blocks
> + // and replace them.
> + BasicBlock::iterator II =
> + replaceTrivialPHIsAndGetInsertionPt(*ExitBlocks[0], I);
> +
> // Move the instruction to the start of the exit block, after any PHI
> // nodes in it.
> - I.moveBefore(ExitBlocks[0]->getFirstInsertionPt());
> + I.moveBefore(II);
>
> // This instruction is no longer in the AST for the current loop, because
> // we just sunk it out of the loop. If we just sunk it into an outer
> @@ -546,8 +607,10 @@ void LICM::sink(Instruction &I) {
> if (!DT->dominates(InstOrigBB, ExitBlock))
> continue;
>
> - // Insert the code after the last PHI node.
> - BasicBlock::iterator InsertPt = ExitBlock->getFirstInsertionPt();
> + // Look for any LCSSA PHI nodes for this instruction in the exit blocks
> + // and replace them. Then get the insertion point after the last PHI.
> + BasicBlock::iterator InsertPt =
> + replaceTrivialPHIsAndGetInsertionPt(*ExitBlock, I);
>
> // If this is the first exit block processed, just move the original
> // instruction, otherwise clone the original instruction and insert
>
> Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LCSSA.cpp?rev=200067&r1=200066&r2=200067&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Utils/LCSSA.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Fri Jan 24 22:07:24 2014
> @@ -39,208 +39,95 @@
> #include "llvm/IR/Instructions.h"
> #include "llvm/Pass.h"
> #include "llvm/Support/PredIteratorCache.h"
> +#include "llvm/Transforms/Utils/LoopUtils.h"
> #include "llvm/Transforms/Utils/SSAUpdater.h"
> using namespace llvm;
>
> STATISTIC(NumLCSSA, "Number of live out of a loop variables");
>
> -namespace {
> - struct LCSSA : public LoopPass {
> - static char ID; // Pass identification, replacement for typeid
> - LCSSA() : LoopPass(ID) {
> - initializeLCSSAPass(*PassRegistry::getPassRegistry());
> - }
> -
> - // Cached analysis information for the current function.
> - DominatorTree *DT;
> - LoopInfo *LI;
> - ScalarEvolution *SE;
> - PredIteratorCache PredCache;
> - Loop *L;
> -
> - virtual bool runOnLoop(Loop *L, LPPassManager &LPM);
> -
> - /// This transformation requires natural loop information & requires that
> - /// loop preheaders be inserted into the CFG. It maintains both of these,
> - /// as well as the CFG. It also requires dominator information.
> - ///
> - virtual void getAnalysisUsage(AnalysisUsage &AU) const {
> - AU.setPreservesCFG();
> -
> - AU.addRequired<DominatorTreeWrapperPass>();
> - AU.addRequired<LoopInfo>();
> - AU.addPreservedID(LoopSimplifyID);
> - AU.addPreserved<ScalarEvolution>();
> - }
> - private:
> - bool ProcessInstruction(Instruction *Inst,
> - const SmallVectorImpl<BasicBlock*> &ExitBlocks);
> -
> - /// verifyAnalysis() - Verify loop nest.
> - virtual void verifyAnalysis() const {
> - // Check the special guarantees that LCSSA makes.
> - assert(L->isLCSSAForm(*DT) && "LCSSA form not preserved!");
> - }
> - };
> -}
> -
> -char LCSSA::ID = 0;
> -INITIALIZE_PASS_BEGIN(LCSSA, "lcssa", "Loop-Closed SSA Form Pass", false, false)
> -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
> -INITIALIZE_PASS_DEPENDENCY(LoopInfo)
> -INITIALIZE_PASS_END(LCSSA, "lcssa", "Loop-Closed SSA Form Pass", false, false)
> -
> -Pass *llvm::createLCSSAPass() { return new LCSSA(); }
> -char &llvm::LCSSAID = LCSSA::ID;
> -
> -
> -/// BlockDominatesAnExit - Return true if the specified block dominates at least
> -/// one of the blocks in the specified list.
> -static bool BlockDominatesAnExit(BasicBlock *BB,
> - const SmallVectorImpl<BasicBlock*> &ExitBlocks,
> - DominatorTree *DT) {
> - DomTreeNode *DomNode = DT->getNode(BB);
> - for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i)
> - if (DT->dominates(DomNode, DT->getNode(ExitBlocks[i])))
> - return true;
> -
> - return false;
> -}
> -
> -
> -/// runOnFunction - Process all loops in the function, inner-most out.
> -bool LCSSA::runOnLoop(Loop *TheLoop, LPPassManager &LPM) {
> - L = TheLoop;
> -
> - DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
> - LI = &getAnalysis<LoopInfo>();
> - SE = getAnalysisIfAvailable<ScalarEvolution>();
> -
> - // Get the set of exiting blocks.
> - SmallVector<BasicBlock*, 8> ExitBlocks;
> - L->getExitBlocks(ExitBlocks);
> -
> - if (ExitBlocks.empty())
> - return false;
> -
> - // Look at all the instructions in the loop, checking to see if they have uses
> - // outside the loop. If so, rewrite those uses.
> - bool MadeChange = false;
> -
> - for (Loop::block_iterator BBI = L->block_begin(), E = L->block_end();
> - BBI != E; ++BBI) {
> - BasicBlock *BB = *BBI;
> -
> - // For large loops, avoid use-scanning by using dominance information: In
> - // particular, if a block does not dominate any of the loop exits, then none
> - // of the values defined in the block could be used outside the loop.
> - if (!BlockDominatesAnExit(BB, ExitBlocks, DT))
> - continue;
> -
> - for (BasicBlock::iterator I = BB->begin(), E = BB->end();
> - I != E; ++I) {
> - // Reject two common cases fast: instructions with no uses (like stores)
> - // and instructions with one use that is in the same block as this.
> - if (I->use_empty() ||
> - (I->hasOneUse() && I->use_back()->getParent() == BB &&
> - !isa<PHINode>(I->use_back())))
> - continue;
> -
> - MadeChange |= ProcessInstruction(I, ExitBlocks);
> - }
> - }
> -
> - // If we modified the code, remove any caches about the loop from SCEV to
> - // avoid dangling entries.
> - // FIXME: This is a big hammer, can we clear the cache more selectively?
> - if (SE && MadeChange)
> - SE->forgetLoop(L);
> -
> - assert(L->isLCSSAForm(*DT));
> - PredCache.clear();
> -
> - return MadeChange;
> -}
> -
> -/// isExitBlock - Return true if the specified block is in the list.
> +/// Return true if the specified block is in the list.
> static bool isExitBlock(BasicBlock *BB,
> - const SmallVectorImpl<BasicBlock*> &ExitBlocks) {
> + const SmallVectorImpl<BasicBlock *> &ExitBlocks) {
> for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i)
> if (ExitBlocks[i] == BB)
> return true;
> return false;
> }
>
> -/// ProcessInstruction - Given an instruction in the loop, check to see if it
> -/// has any uses that are outside the current loop. If so, insert LCSSA PHI
> -/// nodes and rewrite the uses.
> -bool LCSSA::ProcessInstruction(Instruction *Inst,
> - const SmallVectorImpl<BasicBlock*> &ExitBlocks) {
> - SmallVector<Use*, 16> UsesToRewrite;
> -
> - BasicBlock *InstBB = Inst->getParent();
> -
> - for (Value::use_iterator UI = Inst->use_begin(), E = Inst->use_end();
> - UI != E; ++UI) {
> +/// Given an instruction in the loop, check to see if it has any uses that are
> +/// outside the current loop. If so, insert LCSSA PHI nodes and rewrite the
> +/// uses.
> +static bool processInstruction(Loop &L, Instruction &Inst, DominatorTree &DT,
> + const SmallVectorImpl<BasicBlock *> &ExitBlocks,
> + PredIteratorCache &PredCache) {
> + SmallVector<Use *, 16> UsesToRewrite;
> +
> + BasicBlock *InstBB = Inst.getParent();
> +
> + for (Value::use_iterator UI = Inst.use_begin(), E = Inst.use_end(); UI != E;
> + ++UI) {
> User *U = *UI;
> BasicBlock *UserBB = cast<Instruction>(U)->getParent();
> if (PHINode *PN = dyn_cast<PHINode>(U))
> UserBB = PN->getIncomingBlock(UI);
> -
> - if (InstBB != UserBB && !L->contains(UserBB))
> +
> + if (InstBB != UserBB && !L.contains(UserBB))
> UsesToRewrite.push_back(&UI.getUse());
> }
>
> // If there are no uses outside the loop, exit with no change.
> - if (UsesToRewrite.empty()) return false;
> -
> + if (UsesToRewrite.empty())
> + return false;
> +
> ++NumLCSSA; // We are applying the transformation
>
> // Invoke instructions are special in that their result value is not available
> - // along their unwind edge. The code below tests to see whether DomBB dominates
> + // along their unwind edge. The code below tests to see whether DomBB
> + // dominates
> // the value, so adjust DomBB to the normal destination block, which is
> // effectively where the value is first usable.
> - BasicBlock *DomBB = Inst->getParent();
> - if (InvokeInst *Inv = dyn_cast<InvokeInst>(Inst))
> + BasicBlock *DomBB = Inst.getParent();
> + if (InvokeInst *Inv = dyn_cast<InvokeInst>(&Inst))
> DomBB = Inv->getNormalDest();
>
> - DomTreeNode *DomNode = DT->getNode(DomBB);
> + DomTreeNode *DomNode = DT.getNode(DomBB);
>
> - SmallVector<PHINode*, 16> AddedPHIs;
> + SmallVector<PHINode *, 16> AddedPHIs;
>
> SSAUpdater SSAUpdate;
> - SSAUpdate.Initialize(Inst->getType(), Inst->getName());
> -
> + SSAUpdate.Initialize(Inst.getType(), Inst.getName());
> +
> // Insert the LCSSA phi's into all of the exit blocks dominated by the
> // value, and add them to the Phi's map.
> - for (SmallVectorImpl<BasicBlock*>::const_iterator BBI = ExitBlocks.begin(),
> - BBE = ExitBlocks.end(); BBI != BBE; ++BBI) {
> + for (SmallVectorImpl<BasicBlock *>::const_iterator BBI = ExitBlocks.begin(),
> + BBE = ExitBlocks.end();
> + BBI != BBE; ++BBI) {
> BasicBlock *ExitBB = *BBI;
> - if (!DT->dominates(DomNode, DT->getNode(ExitBB))) continue;
> -
> + if (!DT.dominates(DomNode, DT.getNode(ExitBB)))
> + continue;
> +
> // If we already inserted something for this BB, don't reprocess it.
> - if (SSAUpdate.HasValueForBlock(ExitBB)) continue;
> -
> - PHINode *PN = PHINode::Create(Inst->getType(),
> - PredCache.GetNumPreds(ExitBB),
> - Inst->getName()+".lcssa",
> - ExitBB->begin());
> + if (SSAUpdate.HasValueForBlock(ExitBB))
> + continue;
> +
> + PHINode *PN = PHINode::Create(Inst.getType(), PredCache.GetNumPreds(ExitBB),
> + Inst.getName() + ".lcssa", ExitBB->begin());
>
> // Add inputs from inside the loop for this PHI.
> for (BasicBlock **PI = PredCache.GetPreds(ExitBB); *PI; ++PI) {
> - PN->addIncoming(Inst, *PI);
> + PN->addIncoming(&Inst, *PI);
>
> // If the exit block has a predecessor not within the loop, arrange for
> // the incoming value use corresponding to that predecessor to be
> // rewritten in terms of a different LCSSA PHI.
> - if (!L->contains(*PI))
> + if (!L.contains(*PI))
> UsesToRewrite.push_back(
> - &PN->getOperandUse(
> - PN->getOperandNumForIncomingValue(PN->getNumIncomingValues()-1)));
> + &PN->getOperandUse(PN->getOperandNumForIncomingValue(
> + PN->getNumIncomingValues() - 1)));
> }
>
> AddedPHIs.push_back(PN);
> -
> +
> // Remember that this phi makes the value alive in this block.
> SSAUpdate.AddAvailableValue(ExitBB, PN);
> }
> @@ -257,15 +144,14 @@ bool LCSSA::ProcessInstruction(Instructi
> if (PHINode *PN = dyn_cast<PHINode>(User))
> UserBB = PN->getIncomingBlock(*UsesToRewrite[i]);
>
> - if (isa<PHINode>(UserBB->begin()) &&
> - isExitBlock(UserBB, ExitBlocks)) {
> + if (isa<PHINode>(UserBB->begin()) && isExitBlock(UserBB, ExitBlocks)) {
> // Tell the VHs that the uses changed. This updates SCEV's caches.
> if (UsesToRewrite[i]->get()->hasValueHandle())
> ValueHandleBase::ValueIsRAUWd(*UsesToRewrite[i], UserBB->begin());
> UsesToRewrite[i]->set(UserBB->begin());
> continue;
> }
> -
> +
> // Otherwise, do full PHI insertion.
> SSAUpdate.RewriteUse(*UsesToRewrite[i]);
> }
> @@ -275,7 +161,152 @@ bool LCSSA::ProcessInstruction(Instructi
> if (AddedPHIs[i]->use_empty())
> AddedPHIs[i]->eraseFromParent();
> }
> -
> +
> return true;
> }
>
> +/// Return true if the specified block dominates at least
> +/// one of the blocks in the specified list.
> +static bool
> +blockDominatesAnExit(BasicBlock *BB,
> + DominatorTree &DT,
> + const SmallVectorImpl<BasicBlock *> &ExitBlocks) {
> + DomTreeNode *DomNode = DT.getNode(BB);
> + for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i)
> + if (DT.dominates(DomNode, DT.getNode(ExitBlocks[i])))
> + return true;
> +
> + return false;
> +}
> +
> +bool llvm::formLCSSA(Loop &L, DominatorTree &DT, ScalarEvolution *SE) {
> + bool Changed = false;
> +
> + // Get the set of exiting blocks.
> + SmallVector<BasicBlock *, 8> ExitBlocks;
> + L.getExitBlocks(ExitBlocks);
> +
> + if (ExitBlocks.empty())
> + return false;
> +
> + PredIteratorCache PredCache;
> +
> + // Look at all the instructions in the loop, checking to see if they have uses
> + // outside the loop. If so, rewrite those uses.
> + for (Loop::block_iterator BBI = L.block_begin(), BBE = L.block_end();
> + BBI != BBE; ++BBI) {
> + BasicBlock *BB = *BBI;
> +
> + // For large loops, avoid use-scanning by using dominance information: In
> + // particular, if a block does not dominate any of the loop exits, then none
> + // of the values defined in the block could be used outside the loop.
> + if (!blockDominatesAnExit(BB, DT, ExitBlocks))
> + continue;
> +
> + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
> + // Reject two common cases fast: instructions with no uses (like stores)
> + // and instructions with one use that is in the same block as this.
> + if (I->use_empty() ||
> + (I->hasOneUse() && I->use_back()->getParent() == BB &&
> + !isa<PHINode>(I->use_back())))
> + continue;
> +
> + Changed |= processInstruction(L, *I, DT, ExitBlocks, PredCache);
> + }
> + }
> +
> + // If we modified the code, remove any caches about the loop from SCEV to
> + // avoid dangling entries.
> + // FIXME: This is a big hammer, can we clear the cache more selectively?
> + if (SE && Changed)
> + SE->forgetLoop(&L);
> +
> + assert(L.isLCSSAForm(DT));
> +
> + return Changed;
> +}
> +
> +namespace {
> +struct LCSSA : public FunctionPass {
> + static char ID; // Pass identification, replacement for typeid
> + LCSSA() : FunctionPass(ID) {
> + initializeLCSSAPass(*PassRegistry::getPassRegistry());
> + }
> +
> + // Cached analysis information for the current function.
> + DominatorTree *DT;
> + LoopInfo *LI;
> + ScalarEvolution *SE;
> +
> + virtual bool runOnFunction(Function &F);
> +
> + /// This transformation requires natural loop information & requires that
> + /// loop preheaders be inserted into the CFG. It maintains both of these,
> + /// as well as the CFG. It also requires dominator information.
> + virtual void getAnalysisUsage(AnalysisUsage &AU) const {
> + AU.setPreservesCFG();
> +
> + AU.addRequired<DominatorTreeWrapperPass>();
> + AU.addRequired<LoopInfo>();
> + AU.addPreservedID(LoopSimplifyID);
> + AU.addPreserved<ScalarEvolution>();
> + }
> +
> +private:
> + bool processLoop(Loop &L);
> +
> + virtual void verifyAnalysis() const;
> +};
> +}
> +
> +char LCSSA::ID = 0;
> +INITIALIZE_PASS_BEGIN(LCSSA, "lcssa", "Loop-Closed SSA Form Pass", false, false)
> +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
> +INITIALIZE_PASS_DEPENDENCY(LoopInfo)
> +INITIALIZE_PASS_END(LCSSA, "lcssa", "Loop-Closed SSA Form Pass", false, false)
> +
> +Pass *llvm::createLCSSAPass() { return new LCSSA(); }
> +char &llvm::LCSSAID = LCSSA::ID;
> +
> +
> +/// Process all loops in the function, inner-most out.
> +bool LCSSA::runOnFunction(Function &F) {
> + bool Changed = false;
> + LI = &getAnalysis<LoopInfo>();
> + DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
> + SE = getAnalysisIfAvailable<ScalarEvolution>();
> +
> + // Simplify each loop nest in the function.
> + for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I)
> + Changed |= processLoop(**I);
> +
> + return Changed;
> +}
> +
> +/// Process a loop nest depth first.
> +bool LCSSA::processLoop(Loop &L) {
> + bool Changed = false;
> +
> + // Recurse depth-first through inner loops.
> + for (Loop::iterator LI = L.begin(), LE = L.end(); LI != LE; ++LI)
> + Changed |= processLoop(**LI);
> +
> + Changed |= formLCSSA(L, *DT, SE);
> + return Changed;
> +}
> +
> +static void verifyLoop(Loop &L, DominatorTree &DT) {
> + // Recurse depth-first through inner loops.
> + for (Loop::iterator LI = L.begin(), LE = L.end(); LI != LE; ++LI)
> + verifyLoop(**LI, DT);
> +
> + // Check the special guarantees that LCSSA makes.
> + //assert(L.isLCSSAForm(DT) && "LCSSA form not preserved!");
> +}
Do you recall any specific reason for commenting out this assertion?
Compile time performance?
I just sent out a patch to fix a issue in LCSSA and having this on
would have catch that before, I was wondering about turning it on
again.
Thanks,
--
Bruno Cardoso Lopes
http://www.brunocardoso.cc
More information about the llvm-commits
mailing list