From 6443769b340fce03b48ff920382f337ec795cddf Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 29 Sep 2002 21:46:09 +0000 Subject: [PATCH] Hoist the contents of Loops in depth first order in the dominator tree, rather than in random order. This causes LICM to be DRAMATICALLY more effective. For example, on bzip2.c, it is able to hoist 302 loads and 2380 total instructions, as opposed to 44/338 before. This obviously makes other transformations much more powerful as well! llvm-svn: 3978 --- llvm/lib/Transforms/Scalar/LICM.cpp | 42 ++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp index 9a30fbf9d1f5..88abccda00b8 100644 --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -8,6 +8,7 @@ #include "llvm/Transforms/Utils/Local.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/Dominators.h" #include "llvm/iOperators.h" #include "llvm/iMemory.h" #include "llvm/Support/InstVisitor.h" @@ -30,6 +31,7 @@ namespace { AU.preservesCFG(); AU.addRequiredID(LoopPreheadersID); AU.addRequired(); + AU.addRequired(); AU.addRequired(); } @@ -43,6 +45,14 @@ namespace { /// void visitLoop(Loop *L); + /// HoistRegion - Walk the specified region of the CFG (defined by all + /// blocks dominated by the specified block, and that are in the current + /// loop) in depth first order w.r.t the DominatorTree. This allows us to + /// visit defintions before uses, allowing us to hoist a loop body in one + /// pass without iteration. + /// + void HoistRegion(DominatorTree::Node *N); + /// inCurrentLoop - Little predicate that returns false if the specified /// basic block is in a subloop of the current one, not the current one /// itself. @@ -139,22 +149,42 @@ void LICM::visitLoop(Loop *L) { // their loop, into this loop, so there is no need to process the BODIES of // the subloops). // - for (std::vector::const_iterator - I = L->getBlocks().begin(), E = L->getBlocks().end(); I != E; ++I) - if (inCurrentLoop(*I)) - visit(**I); + // Traverse the body of the loop in depth first order on the dominator tree so + // that we are guaranteed to see definitions before we see uses. This allows + // us to perform the LICM transformation in one pass, without iteration. + // + HoistRegion(getAnalysis()[L->getHeader()]); // Clear out loops state information for the next iteration CurLoop = 0; Preheader = 0; } +/// HoistRegion - Walk the specified region of the CFG (defined by all blocks +/// dominated by the specified block, and that are in the current loop) in depth +/// first order w.r.t the DominatorTree. This allows us to visit defintions +/// before uses, allowing us to hoist a loop body in one pass without iteration. +/// +void LICM::HoistRegion(DominatorTree::Node *N) { + assert(N != 0 && "Null dominator tree node?"); + + // This subregion is not in the loop, it has already been already been hoisted + if (!inCurrentLoop(N->getNode())) + return; + + visit(*N->getNode()); + + const std::vector &Children = N->getChildren(); + for (unsigned i = 0, e = Children.size(); i != e; ++i) + HoistRegion(Children[i]); +} + + /// hoist - When an instruction is found to only use loop invariant operands /// that is safe to hoist, this instruction is called to do the dirty work. /// void LICM::hoist(Instruction &Inst) { - if (Inst.use_empty()) return; // Don't (re) hoist dead instructions! - //cerr << "Hoisting " << Inst; + DEBUG(std::cerr << "LICM hoisting: " << Inst); BasicBlock *Header = CurLoop->getHeader();