#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/LLVMContext.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/ADT/DenseMap.h"
#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> > {
return false; // Don't allow a store OF the AI, only INTO the AI.
if (SI->isVolatile())
return false;
+ } else if (const BitCastInst *BC = dyn_cast<BitCastInst>(*UI)) {
+ // 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; // Not a load or store.
+ return false;
}
return true;
struct AllocaInfo;
// Data package used by RenamePass()
- class VISIBILITY_HIDDEN RenamePassData {
+ class RenamePassData {
public:
typedef std::vector<Value *> ValVector;
///
/// 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;
+
+ LLVMContext &Context;
/// AllocaLookup - Reverse mapping of Allocas.
///
DenseMap<const BasicBlock*, unsigned> BBNumPreds;
public:
PromoteMem2Reg(const std::vector<AllocaInst*> &A, DominatorTree &dt,
- DominanceFrontier &df, AliasSetTracker *ast)
- : Allocas(A), DT(dt), DF(df), AST(ast) {}
+ DominanceFrontier &df, AliasSetTracker *ast,
+ LLVMContext &C)
+ : Allocas(A), DT(dt), DF(df), AST(ast), Context(C) {}
void run();
/// ivars.
void AnalyzeAlloca(AllocaInst *AI) {
clear();
-
+
// 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; ++U) {
- Instruction *User = cast<Instruction>(*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!");
+ DbgInfoIntrinsic *DI = cast<DbgInfoIntrinsic>(*BC->use_begin());
+ DI->eraseFromParent();
+ BC->eraseFromParent();
+ continue;
+ }
+
if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
// Remember the basic blocks which define new values for the alloca
DefiningBlocks.push_back(SI->getParent());
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.
}
}
+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;
}
///
void llvm::PromoteMemToReg(const std::vector<AllocaInst*> &Allocas,
DominatorTree &DT, DominanceFrontier &DF,
- AliasSetTracker *AST) {
+ LLVMContext &Context, AliasSetTracker *AST) {
// If there is nothing to do, bail out...
if (Allocas.empty()) return;
- PromoteMem2Reg(Allocas, DT, DF, AST).run();
+ PromoteMem2Reg(Allocas, DT, DF, AST, Context).run();
}