mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-24 06:25:18 +00:00
Reformat the implementation of mem2reg with clang-format so that my
subsequent changes don't introduce inconsistencies. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186775 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -101,16 +101,17 @@ bool llvm::isAllocaPromotable(const AllocaInst *AI) {
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct AllocaInfo;
|
||||
|
||||
// Data package used by RenamePass()
|
||||
class RenamePassData {
|
||||
public:
|
||||
struct AllocaInfo;
|
||||
|
||||
// Data package used by RenamePass()
|
||||
class RenamePassData {
|
||||
public:
|
||||
typedef std::vector<Value *> ValVector;
|
||||
|
||||
RenamePassData() : BB(NULL), Pred(NULL), Values() {}
|
||||
RenamePassData(BasicBlock *B, BasicBlock *P,
|
||||
const ValVector &V) : BB(B), Pred(P), Values(V) {}
|
||||
RenamePassData(BasicBlock *B, BasicBlock *P, const ValVector &V)
|
||||
: BB(B), Pred(P), Values(V) {}
|
||||
BasicBlock *BB;
|
||||
BasicBlock *Pred;
|
||||
ValVector Values;
|
||||
@@ -120,21 +121,22 @@ namespace {
|
||||
std::swap(Pred, RHS.Pred);
|
||||
Values.swap(RHS.Values);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/// \brief This assigns and keeps a per-bb relative ordering of load/store
|
||||
/// instructions in the block that directly load or store an alloca.
|
||||
///
|
||||
/// This functionality is important because it avoids scanning large basic
|
||||
/// blocks multiple times when promoting many allocas in the same block.
|
||||
class LargeBlockInfo {
|
||||
/// \brief This assigns and keeps a per-bb relative ordering of load/store
|
||||
/// instructions in the block that directly load or store an alloca.
|
||||
///
|
||||
/// This functionality is important because it avoids scanning large basic
|
||||
/// blocks multiple times when promoting many allocas in the same block.
|
||||
class LargeBlockInfo {
|
||||
/// \brief For each instruction that we track, keep the index of the
|
||||
/// instruction.
|
||||
///
|
||||
/// The index starts out as the number of the instruction from the start of
|
||||
/// the block.
|
||||
DenseMap<const Instruction *, unsigned> InstNumbers;
|
||||
public:
|
||||
|
||||
public:
|
||||
|
||||
/// This code only looks at accesses to allocas.
|
||||
static bool isInterestingInstruction(const Instruction *I) {
|
||||
@@ -149,15 +151,16 @@ namespace {
|
||||
|
||||
// If we already have this instruction number, return it.
|
||||
DenseMap<const Instruction *, unsigned>::iterator It = InstNumbers.find(I);
|
||||
if (It != InstNumbers.end()) return It->second;
|
||||
if (It != InstNumbers.end())
|
||||
return It->second;
|
||||
|
||||
// Scan the whole block to get the instruction. This accumulates
|
||||
// information for every interesting instruction in the block, in order to
|
||||
// avoid gratuitus rescans.
|
||||
const BasicBlock *BB = I->getParent();
|
||||
unsigned InstNo = 0;
|
||||
for (BasicBlock::const_iterator BBI = BB->begin(), E = BB->end();
|
||||
BBI != E; ++BBI)
|
||||
for (BasicBlock::const_iterator BBI = BB->begin(), E = BB->end(); BBI != E;
|
||||
++BBI)
|
||||
if (isInterestingInstruction(BBI))
|
||||
InstNumbers[BBI] = InstNo++;
|
||||
It = InstNumbers.find(I);
|
||||
@@ -166,18 +169,14 @@ namespace {
|
||||
return It->second;
|
||||
}
|
||||
|
||||
void deleteValue(const Instruction *I) {
|
||||
InstNumbers.erase(I);
|
||||
}
|
||||
void deleteValue(const Instruction *I) { InstNumbers.erase(I); }
|
||||
|
||||
void clear() {
|
||||
InstNumbers.clear();
|
||||
}
|
||||
};
|
||||
void clear() { InstNumbers.clear(); }
|
||||
};
|
||||
|
||||
struct PromoteMem2Reg {
|
||||
struct PromoteMem2Reg {
|
||||
/// The alloca instructions being promoted.
|
||||
std::vector<AllocaInst*> Allocas;
|
||||
std::vector<AllocaInst *> Allocas;
|
||||
DominatorTree &DT;
|
||||
DIBuilder *DIB;
|
||||
|
||||
@@ -185,7 +184,7 @@ namespace {
|
||||
AliasSetTracker *AST;
|
||||
|
||||
/// Reverse mapping of Allocas.
|
||||
DenseMap<AllocaInst*, unsigned> AllocaLookup;
|
||||
DenseMap<AllocaInst *, unsigned> AllocaLookup;
|
||||
|
||||
/// \brief The PhiNodes we're adding.
|
||||
///
|
||||
@@ -193,42 +192,41 @@ namespace {
|
||||
/// it should have deterministic iterators. We could use a MapVector, but
|
||||
/// since we already maintain a map from BasicBlock* to a stable numbering
|
||||
/// (BBNumbers), the DenseMap is more efficient (also supports removal).
|
||||
DenseMap<std::pair<unsigned, unsigned>, PHINode*> NewPhiNodes;
|
||||
DenseMap<std::pair<unsigned, unsigned>, PHINode *> NewPhiNodes;
|
||||
|
||||
/// For each PHI node, keep track of which entry in Allocas it corresponds
|
||||
/// to.
|
||||
DenseMap<PHINode*, unsigned> PhiToAllocaMap;
|
||||
DenseMap<PHINode *, unsigned> PhiToAllocaMap;
|
||||
|
||||
/// If we are updating an AliasSetTracker, then for each alloca that is of
|
||||
/// pointer type, we keep track of what to copyValue to the inserted PHI
|
||||
/// nodes here.
|
||||
std::vector<Value*> PointerAllocaValues;
|
||||
std::vector<Value *> PointerAllocaValues;
|
||||
|
||||
/// For each alloca, we keep track of the dbg.declare intrinsic that
|
||||
/// describes it, if any, so that we can convert it to a dbg.value
|
||||
/// intrinsic if the alloca gets promoted.
|
||||
SmallVector<DbgDeclareInst*, 8> AllocaDbgDeclares;
|
||||
SmallVector<DbgDeclareInst *, 8> AllocaDbgDeclares;
|
||||
|
||||
/// The set of basic blocks the renamer has already visited.
|
||||
///
|
||||
SmallPtrSet<BasicBlock*, 16> Visited;
|
||||
SmallPtrSet<BasicBlock *, 16> Visited;
|
||||
|
||||
/// Contains a stable numbering of basic blocks to avoid non-determinstic
|
||||
/// behavior.
|
||||
DenseMap<BasicBlock*, unsigned> BBNumbers;
|
||||
DenseMap<BasicBlock *, unsigned> BBNumbers;
|
||||
|
||||
/// Maps DomTreeNodes to their level in the dominator tree.
|
||||
DenseMap<DomTreeNode*, unsigned> DomLevels;
|
||||
DenseMap<DomTreeNode *, unsigned> DomLevels;
|
||||
|
||||
/// Lazily compute the number of predecessors a block has.
|
||||
DenseMap<const BasicBlock*, unsigned> BBNumPreds;
|
||||
public:
|
||||
PromoteMem2Reg(const std::vector<AllocaInst*> &A, DominatorTree &dt,
|
||||
DenseMap<const BasicBlock *, unsigned> BBNumPreds;
|
||||
|
||||
public:
|
||||
PromoteMem2Reg(const std::vector<AllocaInst *> &A, DominatorTree &dt,
|
||||
AliasSetTracker *ast)
|
||||
: Allocas(A), DT(dt), DIB(0), AST(ast) {}
|
||||
~PromoteMem2Reg() {
|
||||
delete DIB;
|
||||
}
|
||||
~PromoteMem2Reg() { delete DIB; }
|
||||
|
||||
void run();
|
||||
|
||||
@@ -237,7 +235,7 @@ namespace {
|
||||
return DT.dominates(BB1, BB2);
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
void RemoveFromAllocasList(unsigned &AllocaIdx) {
|
||||
Allocas[AllocaIdx] = Allocas.back();
|
||||
Allocas.pop_back();
|
||||
@@ -247,15 +245,15 @@ namespace {
|
||||
unsigned getNumPreds(const BasicBlock *BB) {
|
||||
unsigned &NP = BBNumPreds[BB];
|
||||
if (NP == 0)
|
||||
NP = std::distance(pred_begin(BB), pred_end(BB))+1;
|
||||
return NP-1;
|
||||
NP = std::distance(pred_begin(BB), pred_end(BB)) + 1;
|
||||
return NP - 1;
|
||||
}
|
||||
|
||||
void DetermineInsertionPoint(AllocaInst *AI, unsigned AllocaNum,
|
||||
AllocaInfo &Info);
|
||||
void ComputeLiveInBlocks(AllocaInst *AI, AllocaInfo &Info,
|
||||
const SmallPtrSet<BasicBlock*, 32> &DefBlocks,
|
||||
SmallPtrSet<BasicBlock*, 32> &LiveInBlocks);
|
||||
const SmallPtrSet<BasicBlock *, 32> &DefBlocks,
|
||||
SmallPtrSet<BasicBlock *, 32> &LiveInBlocks);
|
||||
|
||||
void RewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info,
|
||||
LargeBlockInfo &LBI);
|
||||
@@ -266,11 +264,11 @@ namespace {
|
||||
RenamePassData::ValVector &IncVals,
|
||||
std::vector<RenamePassData> &Worklist);
|
||||
bool QueuePhiNode(BasicBlock *BB, unsigned AllocaIdx, unsigned &Version);
|
||||
};
|
||||
};
|
||||
|
||||
struct AllocaInfo {
|
||||
SmallVector<BasicBlock*, 32> DefiningBlocks;
|
||||
SmallVector<BasicBlock*, 32> UsingBlocks;
|
||||
struct AllocaInfo {
|
||||
SmallVector<BasicBlock *, 32> DefiningBlocks;
|
||||
SmallVector<BasicBlock *, 32> UsingBlocks;
|
||||
|
||||
StoreInst *OnlyStore;
|
||||
BasicBlock *OnlyBlock;
|
||||
@@ -324,15 +322,16 @@ namespace {
|
||||
|
||||
DbgDeclare = FindAllocaDbgDeclare(AI);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
typedef std::pair<DomTreeNode*, unsigned> DomTreeNodePair;
|
||||
typedef std::pair<DomTreeNode *, unsigned> DomTreeNodePair;
|
||||
|
||||
struct DomTreeNodeCompare {
|
||||
struct DomTreeNodeCompare {
|
||||
bool operator()(const DomTreeNodePair &LHS, const DomTreeNodePair &RHS) {
|
||||
return LHS.second < RHS.second;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
||||
static void removeLifetimeIntrinsicUsers(AllocaInst *AI) {
|
||||
@@ -364,7 +363,8 @@ static void removeLifetimeIntrinsicUsers(AllocaInst *AI) {
|
||||
void PromoteMem2Reg::run() {
|
||||
Function &F = *DT.getRoot()->getParent();
|
||||
|
||||
if (AST) PointerAllocaValues.resize(Allocas.size());
|
||||
if (AST)
|
||||
PointerAllocaValues.resize(Allocas.size());
|
||||
AllocaDbgDeclares.resize(Allocas.size());
|
||||
|
||||
AllocaInfo Info;
|
||||
@@ -373,8 +373,7 @@ void PromoteMem2Reg::run() {
|
||||
for (unsigned AllocaNum = 0; AllocaNum != Allocas.size(); ++AllocaNum) {
|
||||
AllocaInst *AI = Allocas[AllocaNum];
|
||||
|
||||
assert(isAllocaPromotable(AI) &&
|
||||
"Cannot promote non-promotable alloca!");
|
||||
assert(isAllocaPromotable(AI) && "Cannot promote non-promotable alloca!");
|
||||
assert(AI->getParent()->getParent() == &F &&
|
||||
"All allocas should be in the same function, which is same as DF!");
|
||||
|
||||
@@ -382,7 +381,8 @@ void PromoteMem2Reg::run() {
|
||||
|
||||
if (AI->use_empty()) {
|
||||
// If there are no uses of the alloca, just delete it now.
|
||||
if (AST) AST->deleteValue(AI);
|
||||
if (AST)
|
||||
AST->deleteValue(AI);
|
||||
AI->eraseFromParent();
|
||||
|
||||
// Remove the alloca from the Allocas list, since it has been processed
|
||||
@@ -414,7 +414,8 @@ void PromoteMem2Reg::run() {
|
||||
Info.OnlyStore->eraseFromParent();
|
||||
LBI.deleteValue(Info.OnlyStore);
|
||||
|
||||
if (AST) AST->deleteValue(AI);
|
||||
if (AST)
|
||||
AST->deleteValue(AI);
|
||||
AI->eraseFromParent();
|
||||
LBI.deleteValue(AI);
|
||||
|
||||
@@ -448,7 +449,8 @@ void PromoteMem2Reg::run() {
|
||||
LBI.deleteValue(SI);
|
||||
}
|
||||
|
||||
if (AST) AST->deleteValue(AI);
|
||||
if (AST)
|
||||
AST->deleteValue(AI);
|
||||
AI->eraseFromParent();
|
||||
LBI.deleteValue(AI);
|
||||
|
||||
@@ -466,7 +468,7 @@ void PromoteMem2Reg::run() {
|
||||
|
||||
// If we haven't computed dominator tree levels, do so now.
|
||||
if (DomLevels.empty()) {
|
||||
SmallVector<DomTreeNode*, 32> Worklist;
|
||||
SmallVector<DomTreeNode *, 32> Worklist;
|
||||
|
||||
DomTreeNode *Root = DT.getRootNode();
|
||||
DomLevels[Root] = 0;
|
||||
@@ -497,7 +499,8 @@ void PromoteMem2Reg::run() {
|
||||
PointerAllocaValues[AllocaNum] = Info.AllocaPointerVal;
|
||||
|
||||
// Remember the dbg.declare intrinsic describing this alloca, if any.
|
||||
if (Info.DbgDeclare) AllocaDbgDeclares[AllocaNum] = Info.DbgDeclare;
|
||||
if (Info.DbgDeclare)
|
||||
AllocaDbgDeclares[AllocaNum] = Info.DbgDeclare;
|
||||
|
||||
// Keep the reverse mapping of the 'Allocas' array for the rename pass.
|
||||
AllocaLookup[Allocas[AllocaNum]] = AllocaNum;
|
||||
@@ -514,7 +517,6 @@ void PromoteMem2Reg::run() {
|
||||
|
||||
LBI.clear();
|
||||
|
||||
|
||||
// Set the incoming values for the basic block to be null values for all of
|
||||
// the alloca's. We do this in case there is a load of a value that has not
|
||||
// been stored yet. In this case, it will get this null value.
|
||||
@@ -548,7 +550,8 @@ void PromoteMem2Reg::run() {
|
||||
// tree. Just delete the users now.
|
||||
if (!A->use_empty())
|
||||
A->replaceAllUsesWith(UndefValue::get(A->getType()));
|
||||
if (AST) AST->deleteValue(A);
|
||||
if (AST)
|
||||
AST->deleteValue(A);
|
||||
A->eraseFromParent();
|
||||
}
|
||||
|
||||
@@ -569,8 +572,10 @@ void PromoteMem2Reg::run() {
|
||||
// simplify and RAUW them as we go. If it was not, we could add uses to
|
||||
// the values we replace with in a non deterministic order, thus creating
|
||||
// non deterministic def->use chains.
|
||||
for (DenseMap<std::pair<unsigned, unsigned>, PHINode*>::iterator I =
|
||||
NewPhiNodes.begin(), E = NewPhiNodes.end(); I != E;) {
|
||||
for (DenseMap<std::pair<unsigned, unsigned>, PHINode *>::iterator
|
||||
I = NewPhiNodes.begin(),
|
||||
E = NewPhiNodes.end();
|
||||
I != E;) {
|
||||
PHINode *PN = I->second;
|
||||
|
||||
// If this PHI node merges one value and/or undefs, get the value.
|
||||
@@ -593,8 +598,10 @@ void PromoteMem2Reg::run() {
|
||||
// have incoming values for all predecessors. Loop over all PHI nodes we have
|
||||
// created, inserting undef values if they are missing any incoming values.
|
||||
//
|
||||
for (DenseMap<std::pair<unsigned, unsigned>, PHINode*>::iterator I =
|
||||
NewPhiNodes.begin(), E = NewPhiNodes.end(); I != E; ++I) {
|
||||
for (DenseMap<std::pair<unsigned, unsigned>, PHINode *>::iterator
|
||||
I = NewPhiNodes.begin(),
|
||||
E = NewPhiNodes.end();
|
||||
I != E; ++I) {
|
||||
// We want to do this once per basic block. As such, only process a block
|
||||
// when we find the PHI that is the first entry in the block.
|
||||
PHINode *SomePHI = I->second;
|
||||
@@ -609,7 +616,7 @@ void PromoteMem2Reg::run() {
|
||||
continue;
|
||||
|
||||
// Get the preds for BB.
|
||||
SmallVector<BasicBlock*, 16> Preds(pred_begin(BB), pred_end(BB));
|
||||
SmallVector<BasicBlock *, 16> Preds(pred_begin(BB), pred_end(BB));
|
||||
|
||||
// Ok, now we know that all of the PHI nodes are missing entries for some
|
||||
// basic blocks. Start by sorting the incoming predecessors for efficient
|
||||
@@ -620,10 +627,9 @@ void PromoteMem2Reg::run() {
|
||||
// them from the Preds list.
|
||||
for (unsigned i = 0, e = SomePHI->getNumIncomingValues(); i != e; ++i) {
|
||||
// Do a log(n) search of the Preds list for the entry we want.
|
||||
SmallVectorImpl<BasicBlock *>::iterator EntIt =
|
||||
std::lower_bound(Preds.begin(), Preds.end(),
|
||||
SomePHI->getIncomingBlock(i));
|
||||
assert(EntIt != Preds.end() && *EntIt == SomePHI->getIncomingBlock(i)&&
|
||||
SmallVectorImpl<BasicBlock *>::iterator EntIt = std::lower_bound(
|
||||
Preds.begin(), Preds.end(), SomePHI->getIncomingBlock(i));
|
||||
assert(EntIt != Preds.end() && *EntIt == SomePHI->getIncomingBlock(i) &&
|
||||
"PHI node has entry for a block which is not a predecessor!");
|
||||
|
||||
// Remove the entry
|
||||
@@ -647,21 +653,20 @@ void PromoteMem2Reg::run() {
|
||||
NewPhiNodes.clear();
|
||||
}
|
||||
|
||||
|
||||
/// \brief Determine which blocks the value is live in.
|
||||
///
|
||||
/// These are blocks which lead to uses. Knowing this allows us to avoid
|
||||
/// inserting PHI nodes into blocks which don't lead to uses (thus, the
|
||||
/// inserted phi nodes would be dead).
|
||||
void PromoteMem2Reg::
|
||||
ComputeLiveInBlocks(AllocaInst *AI, AllocaInfo &Info,
|
||||
const SmallPtrSet<BasicBlock*, 32> &DefBlocks,
|
||||
SmallPtrSet<BasicBlock*, 32> &LiveInBlocks) {
|
||||
void PromoteMem2Reg::ComputeLiveInBlocks(
|
||||
AllocaInst *AI, AllocaInfo &Info,
|
||||
const SmallPtrSet<BasicBlock *, 32> &DefBlocks,
|
||||
SmallPtrSet<BasicBlock *, 32> &LiveInBlocks) {
|
||||
|
||||
// To determine liveness, we must iterate through the predecessors of blocks
|
||||
// where the def is live. Blocks are added to the worklist if we need to
|
||||
// check their predecessors. Start with all the using blocks.
|
||||
SmallVector<BasicBlock*, 64> LiveInBlockWorklist(Info.UsingBlocks.begin(),
|
||||
SmallVector<BasicBlock *, 64> LiveInBlockWorklist(Info.UsingBlocks.begin(),
|
||||
Info.UsingBlocks.end());
|
||||
|
||||
// If any of the using blocks is also a definition block, check to see if the
|
||||
@@ -669,13 +674,15 @@ ComputeLiveInBlocks(AllocaInst *AI, AllocaInfo &Info,
|
||||
// the value isn't really live-in.
|
||||
for (unsigned i = 0, e = LiveInBlockWorklist.size(); i != e; ++i) {
|
||||
BasicBlock *BB = LiveInBlockWorklist[i];
|
||||
if (!DefBlocks.count(BB)) continue;
|
||||
if (!DefBlocks.count(BB))
|
||||
continue;
|
||||
|
||||
// Okay, this is a block that both uses and defines the value. If the first
|
||||
// reference to the alloca is a def (store), then we know it isn't live-in.
|
||||
for (BasicBlock::iterator I = BB->begin(); ; ++I) {
|
||||
for (BasicBlock::iterator I = BB->begin();; ++I) {
|
||||
if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
|
||||
if (SI->getOperand(1) != AI) continue;
|
||||
if (SI->getOperand(1) != AI)
|
||||
continue;
|
||||
|
||||
// We found a store to the alloca before a load. The alloca is not
|
||||
// actually live-in here.
|
||||
@@ -686,7 +693,8 @@ ComputeLiveInBlocks(AllocaInst *AI, AllocaInfo &Info,
|
||||
}
|
||||
|
||||
if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
|
||||
if (LI->getOperand(0) != AI) continue;
|
||||
if (LI->getOperand(0) != AI)
|
||||
continue;
|
||||
|
||||
// Okay, we found a load before a store to the alloca. It is actually
|
||||
// live into this block.
|
||||
@@ -728,29 +736,31 @@ ComputeLiveInBlocks(AllocaInst *AI, AllocaInfo &Info,
|
||||
void PromoteMem2Reg::DetermineInsertionPoint(AllocaInst *AI, unsigned AllocaNum,
|
||||
AllocaInfo &Info) {
|
||||
// Unique the set of defining blocks for efficient lookup.
|
||||
SmallPtrSet<BasicBlock*, 32> DefBlocks;
|
||||
SmallPtrSet<BasicBlock *, 32> DefBlocks;
|
||||
DefBlocks.insert(Info.DefiningBlocks.begin(), Info.DefiningBlocks.end());
|
||||
|
||||
// Determine which blocks the value is live in. These are blocks which lead
|
||||
// to uses.
|
||||
SmallPtrSet<BasicBlock*, 32> LiveInBlocks;
|
||||
SmallPtrSet<BasicBlock *, 32> LiveInBlocks;
|
||||
ComputeLiveInBlocks(AI, Info, DefBlocks, LiveInBlocks);
|
||||
|
||||
// Use a priority queue keyed on dominator tree level so that inserted nodes
|
||||
// are handled from the bottom of the dominator tree upwards.
|
||||
typedef std::priority_queue<DomTreeNodePair, SmallVector<DomTreeNodePair, 32>,
|
||||
typedef std::priority_queue<DomTreeNodePair,
|
||||
SmallVector<DomTreeNodePair, 32>,
|
||||
DomTreeNodeCompare> IDFPriorityQueue;
|
||||
IDFPriorityQueue PQ;
|
||||
|
||||
for (SmallPtrSet<BasicBlock*, 32>::const_iterator I = DefBlocks.begin(),
|
||||
E = DefBlocks.end(); I != E; ++I) {
|
||||
for (SmallPtrSet<BasicBlock *, 32>::const_iterator I = DefBlocks.begin(),
|
||||
E = DefBlocks.end();
|
||||
I != E; ++I) {
|
||||
if (DomTreeNode *Node = DT.getNode(*I))
|
||||
PQ.push(std::make_pair(Node, DomLevels[Node]));
|
||||
}
|
||||
|
||||
SmallVector<std::pair<unsigned, BasicBlock*>, 32> DFBlocks;
|
||||
SmallPtrSet<DomTreeNode*, 32> Visited;
|
||||
SmallVector<DomTreeNode*, 32> Worklist;
|
||||
SmallVector<std::pair<unsigned, BasicBlock *>, 32> DFBlocks;
|
||||
SmallPtrSet<DomTreeNode *, 32> Visited;
|
||||
SmallVector<DomTreeNode *, 32> Worklist;
|
||||
while (!PQ.empty()) {
|
||||
DomTreeNodePair RootPair = PQ.top();
|
||||
PQ.pop();
|
||||
@@ -812,8 +822,7 @@ void PromoteMem2Reg::DetermineInsertionPoint(AllocaInst *AI, unsigned AllocaNum,
|
||||
|
||||
/// If there is only a single store to this value, replace any loads of it that
|
||||
/// are directly dominated by the definition with the value stored.
|
||||
void PromoteMem2Reg::RewriteSingleStoreAlloca(AllocaInst *AI,
|
||||
AllocaInfo &Info,
|
||||
void PromoteMem2Reg::RewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info,
|
||||
LargeBlockInfo &LBI) {
|
||||
StoreInst *OnlyStore = Info.OnlyStore;
|
||||
bool StoringGlobalVal = !isa<Instruction>(OnlyStore->getOperand(0));
|
||||
@@ -823,7 +832,7 @@ void PromoteMem2Reg::RewriteSingleStoreAlloca(AllocaInst *AI,
|
||||
// Clear out UsingBlocks. We will reconstruct it here if needed.
|
||||
Info.UsingBlocks.clear();
|
||||
|
||||
for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); UI != E; ) {
|
||||
for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); UI != E;) {
|
||||
Instruction *UserInst = cast<Instruction>(*UI++);
|
||||
if (!isa<LoadInst>(UserInst)) {
|
||||
assert(UserInst == OnlyStore && "Should only have load/stores");
|
||||
@@ -874,15 +883,13 @@ void PromoteMem2Reg::RewriteSingleStoreAlloca(AllocaInst *AI,
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// This is a helper predicate used to search by the first element of a pair.
|
||||
struct StoreIndexSearchPredicate {
|
||||
bool operator()(const std::pair<unsigned, StoreInst*> &LHS,
|
||||
const std::pair<unsigned, StoreInst*> &RHS) {
|
||||
bool operator()(const std::pair<unsigned, StoreInst *> &LHS,
|
||||
const std::pair<unsigned, StoreInst *> &RHS) {
|
||||
return LHS.first < RHS.first;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/// Many allocas are only used within a single basic block. If this is the
|
||||
@@ -909,11 +916,11 @@ void PromoteMem2Reg::PromoteSingleBlockAlloca(AllocaInst *AI, AllocaInfo &Info,
|
||||
Info.UsingBlocks.clear();
|
||||
|
||||
// Walk the use-def list of the alloca, getting the locations of all stores.
|
||||
typedef SmallVector<std::pair<unsigned, StoreInst*>, 64> StoresByIndexTy;
|
||||
typedef SmallVector<std::pair<unsigned, StoreInst *>, 64> StoresByIndexTy;
|
||||
StoresByIndexTy StoresByIndex;
|
||||
|
||||
for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end();
|
||||
UI != E; ++UI)
|
||||
for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); UI != E;
|
||||
++UI)
|
||||
if (StoreInst *SI = dyn_cast<StoreInst>(*UI))
|
||||
StoresByIndex.push_back(std::make_pair(LBI.getInstructionIndex(SI), SI));
|
||||
|
||||
@@ -938,14 +945,15 @@ void PromoteMem2Reg::PromoteSingleBlockAlloca(AllocaInst *AI, AllocaInfo &Info,
|
||||
// store above them, if any.
|
||||
for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); UI != E;) {
|
||||
LoadInst *LI = dyn_cast<LoadInst>(*UI++);
|
||||
if (!LI) continue;
|
||||
if (!LI)
|
||||
continue;
|
||||
|
||||
unsigned LoadIdx = LBI.getInstructionIndex(LI);
|
||||
|
||||
// Find the nearest store that has a lower than this load.
|
||||
StoresByIndexTy::iterator I =
|
||||
std::lower_bound(StoresByIndex.begin(), StoresByIndex.end(),
|
||||
std::pair<unsigned, StoreInst*>(LoadIdx, static_cast<StoreInst*>(0)),
|
||||
StoresByIndexTy::iterator I = std::lower_bound(
|
||||
StoresByIndex.begin(), StoresByIndex.end(),
|
||||
std::pair<unsigned, StoreInst *>(LoadIdx, static_cast<StoreInst *>(0)),
|
||||
StoreIndexSearchPredicate());
|
||||
|
||||
// If there is no store before this load, then we can't promote this load.
|
||||
@@ -974,7 +982,8 @@ bool PromoteMem2Reg::QueuePhiNode(BasicBlock *BB, unsigned AllocaNo,
|
||||
PHINode *&PN = NewPhiNodes[std::make_pair(BBNumbers[BB], AllocaNo)];
|
||||
|
||||
// If the BB already has a phi node added for the i'th alloca then we're done!
|
||||
if (PN) return false;
|
||||
if (PN)
|
||||
return false;
|
||||
|
||||
// Create a PhiNode using the dereferenced type... and add the phi-node to the
|
||||
// BasicBlock.
|
||||
@@ -1034,7 +1043,8 @@ NextIteration:
|
||||
// Get the next phi node.
|
||||
++PNI;
|
||||
APN = dyn_cast<PHINode>(PNI);
|
||||
if (APN == 0) break;
|
||||
if (APN == 0)
|
||||
break;
|
||||
|
||||
// Verify that it is missing entries. If not, it is not being inserted
|
||||
// by this mem2reg invocation so we want to ignore it.
|
||||
@@ -1043,17 +1053,20 @@ NextIteration:
|
||||
}
|
||||
|
||||
// Don't revisit blocks.
|
||||
if (!Visited.insert(BB)) return;
|
||||
if (!Visited.insert(BB))
|
||||
return;
|
||||
|
||||
for (BasicBlock::iterator II = BB->begin(); !isa<TerminatorInst>(II); ) {
|
||||
for (BasicBlock::iterator II = BB->begin(); !isa<TerminatorInst>(II);) {
|
||||
Instruction *I = II++; // get the instruction, increment iterator
|
||||
|
||||
if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
|
||||
AllocaInst *Src = dyn_cast<AllocaInst>(LI->getPointerOperand());
|
||||
if (!Src) continue;
|
||||
if (!Src)
|
||||
continue;
|
||||
|
||||
DenseMap<AllocaInst*, unsigned>::iterator AI = AllocaLookup.find(Src);
|
||||
if (AI == AllocaLookup.end()) continue;
|
||||
DenseMap<AllocaInst *, unsigned>::iterator AI = AllocaLookup.find(Src);
|
||||
if (AI == AllocaLookup.end())
|
||||
continue;
|
||||
|
||||
Value *V = IncomingVals[AI->second];
|
||||
|
||||
@@ -1066,7 +1079,8 @@ NextIteration:
|
||||
// Delete this instruction and mark the name as the current holder of the
|
||||
// value
|
||||
AllocaInst *Dest = dyn_cast<AllocaInst>(SI->getPointerOperand());
|
||||
if (!Dest) continue;
|
||||
if (!Dest)
|
||||
continue;
|
||||
|
||||
DenseMap<AllocaInst *, unsigned>::iterator ai = AllocaLookup.find(Dest);
|
||||
if (ai == AllocaLookup.end())
|
||||
@@ -1086,10 +1100,11 @@ NextIteration:
|
||||
|
||||
// 'Recurse' to our successors.
|
||||
succ_iterator I = succ_begin(BB), E = succ_end(BB);
|
||||
if (I == E) return;
|
||||
if (I == E)
|
||||
return;
|
||||
|
||||
// Keep track of the successors so we don't visit the same successor twice
|
||||
SmallPtrSet<BasicBlock*, 8> VisitedSuccs;
|
||||
SmallPtrSet<BasicBlock *, 8> VisitedSuccs;
|
||||
|
||||
// Handle the first successor without using the worklist.
|
||||
VisitedSuccs.insert(*I);
|
||||
@@ -1104,10 +1119,11 @@ NextIteration:
|
||||
goto NextIteration;
|
||||
}
|
||||
|
||||
void llvm::PromoteMemToReg(const std::vector<AllocaInst*> &Allocas,
|
||||
void llvm::PromoteMemToReg(const std::vector<AllocaInst *> &Allocas,
|
||||
DominatorTree &DT, AliasSetTracker *AST) {
|
||||
// If there is nothing to do, bail out...
|
||||
if (Allocas.empty()) return;
|
||||
if (Allocas.empty())
|
||||
return;
|
||||
|
||||
PromoteMem2Reg(Allocas, DT, AST).run();
|
||||
}
|
||||
|
Reference in New Issue
Block a user