clean up and simplify some code. Don't use setvector when things will be

inserted only once, just use vector.  Don't compute ExitBlocks unless we
need it, change std::sort to array_pod_sort.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83747 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2009-10-11 01:07:15 +00:00
parent a09fbf0af0
commit 39b0c3d613

View File

@ -34,15 +34,14 @@
#include "llvm/Function.h" #include "llvm/Function.h"
#include "llvm/Instructions.h" #include "llvm/Instructions.h"
#include "llvm/LLVMContext.h" #include "llvm/LLVMContext.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Support/CFG.h" #include "llvm/Support/CFG.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include "llvm/Support/PredIteratorCache.h" #include "llvm/Support/PredIteratorCache.h"
#include <algorithm>
#include <map> #include <map>
using namespace llvm; using namespace llvm;
@ -62,9 +61,6 @@ namespace {
virtual bool runOnLoop(Loop *L, LPPassManager &LPM); virtual bool runOnLoop(Loop *L, LPPassManager &LPM);
void ProcessInstruction(Instruction* Instr,
const SmallVector<BasicBlock*, 8>& exitBlocks);
/// This transformation requires natural loop information & requires that /// This transformation requires natural loop information & requires that
/// loop preheaders be inserted into the CFG. It maintains both of these, /// loop preheaders be inserted into the CFG. It maintains both of these,
/// as well as the CFG. It also requires dominator information. /// as well as the CFG. It also requires dominator information.
@ -87,7 +83,9 @@ namespace {
AU.addPreserved<DominanceFrontier>(); AU.addPreserved<DominanceFrontier>();
} }
private: private:
void ProcessInstruction(Instruction* Instr,
const SmallVector<BasicBlock*, 8>& exitBlocks);
/// verifyAnalysis() - Verify loop nest. /// verifyAnalysis() - Verify loop nest.
virtual void verifyAnalysis() const { virtual void verifyAnalysis() const {
// Check the special guarantees that LCSSA makes. // Check the special guarantees that LCSSA makes.
@ -95,14 +93,13 @@ namespace {
} }
void getLoopValuesUsedOutsideLoop(Loop *L, void getLoopValuesUsedOutsideLoop(Loop *L,
SetVector<Instruction*> &AffectedValues, SmallVectorImpl<Instruction*> &AffectedValues);
const SmallVector<BasicBlock*, 8>& exitBlocks);
Value *GetValueForBlock(DomTreeNode *BB, Instruction *OrigInst, Value *GetValueForBlock(DomTreeNode *BB, Instruction *OrigInst,
DenseMap<DomTreeNode*, Value*> &Phis); DenseMap<DomTreeNode*, Value*> &Phis);
/// inLoop - returns true if the given block is within the current loop /// inLoop - returns true if the given block is within the current loop
bool inLoop(BasicBlock* B) { bool inLoop(BasicBlock *B) const {
return std::binary_search(LoopBlocks.begin(), LoopBlocks.end(), B); return std::binary_search(LoopBlocks.begin(), LoopBlocks.end(), B);
} }
}; };
@ -122,28 +119,27 @@ bool LCSSA::runOnLoop(Loop *l, LPPassManager &LPM) {
LI = &LPM.getAnalysis<LoopInfo>(); LI = &LPM.getAnalysis<LoopInfo>();
DT = &getAnalysis<DominatorTree>(); DT = &getAnalysis<DominatorTree>();
// Speed up queries by creating a sorted list of blocks // Speed up queries by creating a sorted vector of blocks.
LoopBlocks.clear(); LoopBlocks.clear();
LoopBlocks.insert(LoopBlocks.end(), L->block_begin(), L->block_end()); LoopBlocks.insert(LoopBlocks.end(), L->block_begin(), L->block_end());
std::sort(LoopBlocks.begin(), LoopBlocks.end()); array_pod_sort(LoopBlocks.begin(), LoopBlocks.end());
SmallVector<BasicBlock*, 8> exitBlocks; SmallVector<Instruction*, 16> AffectedValues;
L->getExitBlocks(exitBlocks); getLoopValuesUsedOutsideLoop(L, AffectedValues);
SetVector<Instruction*> AffectedValues;
getLoopValuesUsedOutsideLoop(L, AffectedValues, exitBlocks);
// If no values are affected, we can save a lot of work, since we know that // If no values are affected, we can save a lot of work, since we know that
// nothing will be changed. // nothing will be changed.
if (AffectedValues.empty()) if (AffectedValues.empty())
return false; return false;
SmallVector<BasicBlock*, 8> ExitBlocks;
L->getExitBlocks(ExitBlocks);
// Iterate over all affected values for this loop and insert Phi nodes // Iterate over all affected values for this loop and insert Phi nodes
// for them in the appropriate exit blocks // for them in the appropriate exit blocks.
for (SmallVectorImpl<Instruction*>::iterator I = AffectedValues.begin(),
for (SetVector<Instruction*>::iterator I = AffectedValues.begin(),
E = AffectedValues.end(); I != E; ++I) E = AffectedValues.end(); I != E; ++I)
ProcessInstruction(*I, exitBlocks); ProcessInstruction(*I, ExitBlocks);
assert(L->isLCSSAForm()); assert(L->isLCSSAForm());
@ -153,7 +149,7 @@ bool LCSSA::runOnLoop(Loop *l, LPPassManager &LPM) {
/// processInstruction - Given a live-out instruction, insert LCSSA Phi nodes, /// processInstruction - Given a live-out instruction, insert LCSSA Phi nodes,
/// eliminate all out-of-loop uses. /// eliminate all out-of-loop uses.
void LCSSA::ProcessInstruction(Instruction *Instr, void LCSSA::ProcessInstruction(Instruction *Instr,
const SmallVector<BasicBlock*, 8>& exitBlocks) { const SmallVector<BasicBlock*, 8> &ExitBlocks) {
++NumLCSSA; // We are applying the transformation ++NumLCSSA; // We are applying the transformation
// Keep track of the blocks that have the value available already. // Keep track of the blocks that have the value available already.
@ -172,8 +168,8 @@ void LCSSA::ProcessInstruction(Instruction *Instr,
// Insert the LCSSA phi's into the exit blocks (dominated by the value), and // Insert the LCSSA phi's into the exit blocks (dominated by the value), and
// add them to the Phi's map. // add them to the Phi's map.
for (SmallVector<BasicBlock*, 8>::const_iterator BBI = exitBlocks.begin(), for (SmallVector<BasicBlock*, 8>::const_iterator BBI = ExitBlocks.begin(),
BBE = exitBlocks.end(); BBI != BBE; ++BBI) { BBE = ExitBlocks.end(); BBI != BBE; ++BBI) {
BasicBlock *BB = *BBI; BasicBlock *BB = *BBI;
DomTreeNode *ExitBBNode = DT->getNode(BB); DomTreeNode *ExitBBNode = DT->getNode(BB);
Value *&Phi = Phis[ExitBBNode]; Value *&Phi = Phis[ExitBBNode];
@ -221,8 +217,7 @@ void LCSSA::ProcessInstruction(Instruction *Instr,
/// getLoopValuesUsedOutsideLoop - Return any values defined in the loop that /// getLoopValuesUsedOutsideLoop - Return any values defined in the loop that
/// are used by instructions outside of it. /// are used by instructions outside of it.
void LCSSA::getLoopValuesUsedOutsideLoop(Loop *L, void LCSSA::getLoopValuesUsedOutsideLoop(Loop *L,
SetVector<Instruction*> &AffectedValues, SmallVectorImpl<Instruction*> &AffectedValues) {
const SmallVector<BasicBlock*, 8>& exitBlocks) {
// FIXME: For large loops, we may be able to avoid a lot of use-scanning // FIXME: For large loops, we may be able to avoid a lot of use-scanning
// by using dominance information. In particular, if a block does not // 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 // dominate any of the loop exits, then none of the values defined in the
@ -233,11 +228,11 @@ void LCSSA::getLoopValuesUsedOutsideLoop(Loop *L,
for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
UI != UE; ++UI) { UI != UE; ++UI) {
BasicBlock *UserBB = cast<Instruction>(*UI)->getParent(); BasicBlock *UserBB = cast<Instruction>(*UI)->getParent();
if (PHINode *p = dyn_cast<PHINode>(*UI)) if (PHINode *PN = dyn_cast<PHINode>(*UI))
UserBB = p->getIncomingBlock(UI); UserBB = PN->getIncomingBlock(UI);
if (*BB != UserBB && !inLoop(UserBB)) { if (*BB != UserBB && !inLoop(UserBB)) {
AffectedValues.insert(I); AffectedValues.push_back(I);
break; break;
} }
} }