#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/CFG.h"
-#include "llvm/Support/Compiler.h"
#include <algorithm>
using namespace llvm;
STATISTIC(NumDeadAlloca, "Number of dead alloca's removed");
STATISTIC(NumPHIInsert, "Number of PHI nodes inserted");
-// Provide DenseMapInfo for all pointers.
namespace llvm {
template<>
struct DenseMapInfo<std::pair<BasicBlock*, unsigned> > {
static bool isEqual(const EltTy &LHS, const EltTy &RHS) {
return LHS == RHS;
}
- static bool isPod() { return true; }
};
}
if (SI->isVolatile())
return false;
} else if (const BitCastInst *BC = dyn_cast<BitCastInst>(*UI)) {
- // Uses by dbg info shouldn't inhibit promotion.
+ // A bitcast that does not feed into debug info inhibits promotion.
if (!BC->hasOneUse() || !isa<DbgInfoIntrinsic>(*BC->use_begin()))
return false;
+ // If the only use is by debug info, this alloca will not exist in
+ // non-debug code, so don't try to promote; this ensures the same
+ // codegen with debug info. Otherwise, debug info should not
+ // inhibit promotion (but we must examine other uses).
+ if (AI->hasOneUse())
+ return false;
} else {
return false;
}
struct AllocaInfo;
// Data package used by RenamePass()
- class VISIBILITY_HIDDEN RenamePassData {
+ class RenamePassData {
public:
typedef std::vector<Value *> ValVector;
- RenamePassData() {}
+ RenamePassData() : BB(NULL), Pred(NULL), Values() {}
RenamePassData(BasicBlock *B, BasicBlock *P,
const ValVector &V) : BB(B), Pred(P), Values(V) {}
BasicBlock *BB;
///
/// This functionality is important because it avoids scanning large basic
/// blocks multiple times when promoting many allocas in the same block.
- class VISIBILITY_HIDDEN LargeBlockInfo {
+ class LargeBlockInfo {
/// InstNumbers - 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.
}
};
- struct VISIBILITY_HIDDEN PromoteMem2Reg {
+ struct PromoteMem2Reg {
/// Allocas - The alloca instructions being promoted.
///
std::vector<AllocaInst*> Allocas;
/// AST - An AliasSetTracker object to update. If null, don't update it.
///
AliasSetTracker *AST;
-
+
/// AllocaLookup - Reverse mapping of Allocas.
///
std::map<AllocaInst*, unsigned> AllocaLookup;
// As we scan the uses of the alloca instruction, keep track of stores,
// and decide whether all of the loads and stores to the alloca are within
// the same basic block.
- for (Value::use_iterator U = AI->use_begin(), E = AI->use_end();
- U != E;) {
- Instruction *User = cast<Instruction>(*U);
- ++U;
+ for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end();
+ UI != E;) {
+ Instruction *User = cast<Instruction>(*UI++);
if (BitCastInst *BC = dyn_cast<BitCastInst>(User)) {
// Remove any uses of this alloca in DbgInfoInstrinsics.
assert(BC->hasOneUse() && "Unexpected alloca uses!");
BC->eraseFromParent();
continue;
}
- else if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
+
+ if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
// Remember the basic blocks which define new values for the alloca
DefiningBlocks.push_back(SI->getParent());
AllocaPointerVal = SI->getOperand(0);
PHINode *PN = I->second;
// If this PHI node merges one value and/or undefs, get the value.
- if (Value *V = PN->hasConstantValue(true)) {
- if (!isa<Instruction>(V) ||
- properlyDominates(cast<Instruction>(V), PN)) {
- if (AST && isa<PointerType>(PN->getType()))
- AST->deleteValue(PN);
- PN->replaceAllUsesWith(V);
- PN->eraseFromParent();
- NewPhiNodes.erase(I++);
- EliminatedAPHI = true;
- continue;
- }
+ if (Value *V = PN->hasConstantValue(&DT)) {
+ if (AST && isa<PointerType>(PN->getType()))
+ AST->deleteValue(PN);
+ PN->replaceAllUsesWith(V);
+ PN->eraseFromParent();
+ NewPhiNodes.erase(I++);
+ EliminatedAPHI = true;
+ continue;
}
++I;
}
LiveInBlockWorklist.pop_back();
--i, --e;
break;
- } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
+ }
+
+ if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
if (LI->getOperand(0) != AI) continue;
// Okay, we found a load before a store to the alloca. It is actually
// Now that we have a set of blocks where the phi is live-in, recursively add
// their predecessors until we find the full region the value is live.
while (!LiveInBlockWorklist.empty()) {
- BasicBlock *BB = LiveInBlockWorklist.back();
- LiveInBlockWorklist.pop_back();
+ BasicBlock *BB = LiveInBlockWorklist.pop_back_val();
// The block really is live in here, insert it into the set. If already in
// the set, then it has already been processed.
}
// Otherwise, we *can* safely rewrite this load.
- LI->replaceAllUsesWith(OnlyStore->getOperand(0));
+ Value *ReplVal = OnlyStore->getOperand(0);
+ // If the replacement value is the load, this must occur in unreachable
+ // code.
+ if (ReplVal == LI)
+ ReplVal = UndefValue::get(LI->getType());
+ LI->replaceAllUsesWith(ReplVal);
if (AST && isa<PointerType>(LI->getType()))
AST->deleteValue(LI);
LI->eraseFromParent();
}
}
+namespace {
/// StoreIndexSearchPredicate - This is a helper predicate used to search by the
/// first element of a pair.
}
};
+}
+
/// PromoteSingleBlockAlloca - Many allocas are only used within a single basic
/// block. If this is the case, avoid traversing the CFG and inserting a lot of
/// potentially useless PHI nodes by just performing a single linear pass over
// Create a PhiNode using the dereferenced type... and add the phi-node to the
// BasicBlock.
PN = PHINode::Create(Allocas[AllocaNo]->getAllocatedType(),
- Allocas[AllocaNo]->getName() + "." +
- utostr(Version++), BB->begin());
+ Allocas[AllocaNo]->getName() + "." + Twine(Version++),
+ BB->begin());
++NumPHIInsert;
PhiToAllocaMap[PN] = AllocaNo;
PN->reserveOperandSpace(getNumPreds(BB));
// If we are inserting any phi nodes into this BB, they will already be in the
// block.
if (PHINode *APN = dyn_cast<PHINode>(BB->begin())) {
- // Pred may have multiple edges to BB. If so, we want to add N incoming
- // values to each PHI we are inserting on the first time we see the edge.
- // Check to see if APN already has incoming values from Pred. This also
- // prevents us from modifying PHI nodes that are not currently being
- // inserted.
- bool HasPredEntries = false;
- for (unsigned i = 0, e = APN->getNumIncomingValues(); i != e; ++i) {
- if (APN->getIncomingBlock(i) == Pred) {
- HasPredEntries = true;
- break;
- }
- }
-
// If we have PHI nodes to update, compute the number of edges from Pred to
// BB.
- if (!HasPredEntries) {
+ if (PhiToAllocaMap.count(APN)) {
// We want to be able to distinguish between PHI nodes being inserted by
// this invocation of mem2reg from those phi nodes that already existed in
// the IR before mem2reg was run. We determine that APN is being inserted
succ_iterator I = succ_begin(BB), E = succ_end(BB);
if (I == E) return;
- // Handle the last successor without using the worklist. This allows us to
- // handle unconditional branches directly, for example.
- --E;
- for (; I != E; ++I)
- Worklist.push_back(RenamePassData(*I, BB, IncomingVals));
+ // Keep track of the successors so we don't visit the same successor twice
+ SmallPtrSet<BasicBlock*, 8> VisitedSuccs;
+ // Handle the first successor without using the worklist.
+ VisitedSuccs.insert(*I);
Pred = BB;
BB = *I;
+ ++I;
+
+ for (; I != E; ++I)
+ if (VisitedSuccs.insert(*I))
+ Worklist.push_back(RenamePassData(*I, Pred, IncomingVals));
+
goto NextIteration;
}