From 2480737211fcb466f4f8d2c6c5a7303fd832984b Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Fri, 26 May 2006 21:11:53 +0000 Subject: [PATCH] Clean up and refactor LCSSA a bunch. It should also run faster now, though there's still a lot of work to be done on it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28506 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/LCSSA.cpp | 118 ++++++++++++++------------------- 1 file changed, 51 insertions(+), 67 deletions(-) diff --git a/lib/Transforms/Utils/LCSSA.cpp b/lib/Transforms/Utils/LCSSA.cpp index 5382ec6d6a5..bb4c57e9542 100644 --- a/lib/Transforms/Utils/LCSSA.cpp +++ b/lib/Transforms/Utils/LCSSA.cpp @@ -1,4 +1,4 @@ -//===-- LCSSA.cpp - Convert loops into loop-closed SSA form ------===// +//===-- LCSSA.cpp - Convert loops into loop-closed SSA form ---------------===// // // The LLVM Compiler Infrastructure // @@ -27,14 +27,14 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Transforms/Scalar.h" #include "llvm/Pass.h" #include "llvm/Function.h" #include "llvm/Instructions.h" +#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Support/CFG.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include +#include #include #include @@ -44,26 +44,28 @@ namespace { class LCSSA : public FunctionPass { public: LoopInfo *LI; // Loop information - - // LoopProcessWorklist - List of loops we need to process. - std::vector LoopProcessWorklist; + DominatorTree *DT; // Dominator Tree for the current Loop... + DominanceFrontier *DF; // Current Dominance Frontier virtual bool runOnFunction(Function &F); - - bool visitLoop(Loop *L, Value *V); + bool LCSSA::visitSubloop(Loop* L); /// This transformation requires natural loop information & requires that /// loop preheaders be inserted into the CFG... /// virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); AU.addRequiredID(LoopSimplifyID); AU.addPreservedID(LoopSimplifyID); AU.addRequired(); AU.addPreserved(); + AU.addRequired(); // Not sure if this one will actually + // be needed. + AU.addRequired(); } private: - void addSubloopsToWorklist(Loop* L); - std::set loopValuesUsedOutsideLoop(Loop *L); + std::set getLoopValuesUsedOutsideLoop(Loop *L, + std::vector LoopBlocks); }; RegisterOpt X("lcssa", "Loop-Closed SSA Form Pass"); @@ -74,86 +76,68 @@ FunctionPass *llvm::createLCSSAPass() { return new LCSSA(); } bool LCSSA::runOnFunction(Function &F) { bool changed = false; LI = &getAnalysis(); + DF = &getAnalysis(); + DT = &getAnalysis(); for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I) { - addSubloopsToWorklist(*I); - LoopProcessWorklist.push_back(*I); - } - - for (std::vector::iterator I = LoopProcessWorklist.begin(), - E = LoopProcessWorklist.end(); I != E; ++I) { - std::set AffectedValues = loopValuesUsedOutsideLoop(*I); - if (!AffectedValues.empty()) { - for (std::set::iterator VI = AffectedValues.begin(), - VE = AffectedValues.end(); VI != VE; ++VI) - changed |= visitLoop(*I, *VI); - } + changed |= visitSubloop(*I); } return changed; } -bool LCSSA::visitLoop(Loop *L, Value* V) { - // We will be doing lots of "loop contains block" queries. Loop::contains is - // linear time, use a set to speed this up. - std::set LoopBlocks; - - for (Loop::block_iterator BB = L->block_begin(), E = L->block_end(); - BB != E; ++BB) - LoopBlocks.insert(*BB); +bool LCSSA::visitSubloop(Loop* L) { + for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I) + visitSubloop(*I); + + // Speed up queries by creating a sorted list of blocks + std::vector LoopBlocks(L->block_begin(), L->block_end()); + std::sort(LoopBlocks.begin(), LoopBlocks.end()); + + std::set AffectedValues = getLoopValuesUsedOutsideLoop(L, + LoopBlocks); std::vector exitBlocks; L->getExitBlocks(exitBlocks); - for (std::vector::iterator BBI = exitBlocks.begin(), - BBE = exitBlocks.end(); BBI != BBE; ++BBI) { - PHINode *phi = new PHINode(V->getType(), "lcssa"); - (*BBI)->getInstList().insert((*BBI)->front(), phi); + for (std::set::iterator I = AffectedValues.begin(), + E = AffectedValues.end(); I != E; ++I) { + for (std::vector::iterator BBI = exitBlocks.begin(), + BBE = exitBlocks.end(); BBI != BBE; ++BBI) { + PHINode *phi = new PHINode((*I)->getType(), "lcssa"); + (*BBI)->getInstList().insert((*BBI)->front(), phi); - for (pred_iterator PI = pred_begin(*BBI), PE = pred_end(*BBI); PI != PE; - ++PI) - phi->addIncoming(V, *PI); + for (pred_iterator PI = pred_begin(*BBI), PE = pred_end(*BBI); PI != PE; + ++PI) + phi->addIncoming(*I, *PI); + } + + for (Value::use_iterator UI = (*I)->use_begin(), UE = (*I)->use_end(); + UI != UE; ++UI) { + BasicBlock *UserBB = cast(*UI)->getParent(); + if (!std::binary_search(LoopBlocks.begin(), LoopBlocks.end(), UserBB)) + ; // FIXME: This should update the SSA form. + } } - for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); UI != UE; - ++UI) { - BasicBlock *UserBB = cast(*UI)->getParent(); - if (!LoopBlocks.count(UserBB)) - ; // FIXME: This should update the SSA form through the rest of the graph. - } - - return false; + return true; // FIXME: Should be more intelligent in our return value. } -void LCSSA::addSubloopsToWorklist(Loop* L) { - for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I) { - addSubloopsToWorklist(*I); - LoopProcessWorklist.push_back(*I); - } -} +/// getLoopValuesUsedOutsideLoop - Return any values defined in the loop that +/// are used by instructions outside of it. +std::set LCSSA::getLoopValuesUsedOutsideLoop(Loop *L, + std::vector LoopBlocks) { -/// loopValuesUsedOutsideLoop - Return true if there are any values defined in -/// the loop that are used by instructions outside of it. -std::set LCSSA::loopValuesUsedOutsideLoop(Loop *L) { - std::set AffectedValues; - - // We will be doing lots of "loop contains block" queries. Loop::contains is - // linear time, use a set to speed this up. - std::set LoopBlocks; - - for (Loop::block_iterator BB = L->block_begin(), E = L->block_end(); - BB != E; ++BB) - LoopBlocks.insert(*BB); - + std::set AffectedValues; for (Loop::block_iterator BB = L->block_begin(), E = L->block_end(); BB != E; ++BB) { for (BasicBlock::iterator I = (*BB)->begin(), E = (*BB)->end(); I != E; ++I) for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) { BasicBlock *UserBB = cast(*UI)->getParent(); - if (!LoopBlocks.count(UserBB)) + if (!std::binary_search(LoopBlocks.begin(), LoopBlocks.end(), UserBB)) AffectedValues.insert(I); } } return AffectedValues; -} \ No newline at end of file +}