mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-24 12:50:42 +00:00
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:
parent
a09fbf0af0
commit
39b0c3d613
@ -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,6 +83,8 @@ 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 {
|
||||||
@ -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;
|
||||||
|
|
||||||
// Iterate over all affected values for this loop and insert Phi nodes
|
SmallVector<BasicBlock*, 8> ExitBlocks;
|
||||||
// for them in the appropriate exit blocks
|
L->getExitBlocks(ExitBlocks);
|
||||||
|
|
||||||
for (SetVector<Instruction*>::iterator I = AffectedValues.begin(),
|
// Iterate over all affected values for this loop and insert Phi nodes
|
||||||
|
// for them in the appropriate exit blocks.
|
||||||
|
for (SmallVectorImpl<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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user