forked from OSchip/llvm-project
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
This commit is contained in:
parent
467a9e84c4
commit
6443769b34
|
@ -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<LoopInfo>();
|
||||
AU.addRequired<DominatorTree>();
|
||||
AU.addRequired<AliasAnalysis>();
|
||||
}
|
||||
|
||||
|
@ -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<BasicBlock*>::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<DominatorTree>()[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<DominatorTree::Node*> &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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue