STATISTIC(NumGVNPRE, "Number of instructions PRE'd");
static cl::opt<bool> EnablePRE("enable-pre",
- cl::init(false), cl::Hidden);
+ cl::init(false), cl::Hidden);
//===----------------------------------------------------------------------===//
// ValueTable Class
void setAliasAnalysis(AliasAnalysis* A) { AA = A; }
void setMemDep(MemoryDependenceAnalysis* M) { MD = M; }
void setDomTree(DominatorTree* D) { DT = D; }
+ uint32_t getNextUnusedValueNumber() { return nextValueNumber; }
};
}
// This transformation requires dominator postdominator info
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesCFG();
AU.addRequired<DominatorTree>();
AU.addRequired<MemoryDependenceAnalysis>();
AU.addRequired<AliasAnalysis>();
+
+ AU.addPreserved<DominatorTree>();
AU.addPreserved<AliasAnalysis>();
AU.addPreserved<MemoryDependenceAnalysis>();
}
DenseMap<BasicBlock*, Value*>::iterator V = Phis.find(BB);
if (V != Phis.end() && !top_level) return V->second;
+ // If the block is unreachable, just return undef, since this path
+ // can't actually occur at runtime.
+ if (!getAnalysis<DominatorTree>().isReachableFromEntry(BB))
+ return Phis[BB] = UndefValue::get(orig->getType());
+
BasicBlock* singlePred = BB->getSinglePredecessor();
if (singlePred) {
Value *ret = GetValueForBlock(singlePred, orig, Phis);
}
Value* GVN::lookupNumber(BasicBlock* BB, uint32_t num) {
- ValueNumberScope* locals = localAvail[BB];
+ DenseMap<BasicBlock*, ValueNumberScope*>::iterator I = localAvail.find(BB);
+ if (I == localAvail.end())
+ return 0;
+
+ ValueNumberScope* locals = I->second;
while (locals) {
DenseMap<uint32_t, Value*>::iterator I = locals->table.find(num);
return changed;
}
+ uint32_t nextNum = VN.getNextUnusedValueNumber();
unsigned num = VN.lookup_or_add(I);
// Allocations are always uniquely numbered, so we can save time and memory
// by fast failing them.
- if (isa<AllocationInst>(I)) {
+ if (isa<AllocationInst>(I) || isa<TerminatorInst>(I)) {
localAvail[I->getParent()]->table.insert(std::make_pair(num, I));
return false;
}
} else {
localAvail[I->getParent()]->table.insert(std::make_pair(num, I));
}
+
+ // If the number we were assigned was a brand new VN, then we don't
+ // need to do a lookup to see if the number already exists
+ // somewhere in the domtree: it can't!
+ } else if (num == nextNum) {
+ localAvail[I->getParent()]->table.insert(std::make_pair(num, I));
+
// Perform value-number based elimination
} else if (Value* repl = lookupNumber(I->getParent(), num)) {
// Remove it!
I->replaceAllUsesWith(repl);
toErase.push_back(I);
return true;
- } else if (!I->isTerminator()) {
+ } else {
localAvail[I->getParent()]->table.insert(std::make_pair(num, I));
}
for (BasicBlock::iterator BI = CurrentBlock->begin(),
BE = CurrentBlock->end(); BI != BE; ) {
- if (isa<AllocaInst>(BI) || isa<TerminatorInst>(BI) ||
- isa<LoadInst>(BI) || isa<StoreInst>(BI) ||
- isa<CallInst>(BI) || isa<PHINode>(BI)) {
+ if (isa<AllocationInst>(BI) || isa<TerminatorInst>(BI) ||
+ isa<PHINode>(BI) || BI->mayReadFromMemory() ||
+ BI->mayWriteToMemory()) {
BI++;
continue;
}
Phi->addIncoming(predMap[*PI], *PI);
VN.add(Phi, valno);
-
- // The newly created PHI completely replaces the old instruction,
- // so we need to update the maps to reflect this.
- DomTreeNode* DTN = getAnalysis<DominatorTree>()[CurrentBlock];
- for (DomTreeNode::iterator UI = DTN->begin(), UE = DTN->end();
- UI != UE; ++UI)
- localAvail[(*UI)->getBlock()]->table[valno] = Phi;
localAvail[CurrentBlock]->table[valno] = Phi;
BI->replaceAllUsesWith(Phi);
DE = df_end(DT.getRootNode()); DI != DE; ++DI)
changed |= processBlock(*DI);
- if (!EnablePRE)
+ if (EnablePRE)
changed |= performPRE(F);
return changed;