aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/GVNPRE.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/Scalar/GVNPRE.cpp')
-rw-r--r--lib/Transforms/Scalar/GVNPRE.cpp24
1 files changed, 16 insertions, 8 deletions
diff --git a/lib/Transforms/Scalar/GVNPRE.cpp b/lib/Transforms/Scalar/GVNPRE.cpp
index bedfb5d270..0661c94dbd 100644
--- a/lib/Transforms/Scalar/GVNPRE.cpp
+++ b/lib/Transforms/Scalar/GVNPRE.cpp
@@ -564,6 +564,7 @@ namespace {
std::map<BasicBlock*, SmallPtrSet<Value*, 16> > availableOut;
std::map<BasicBlock*, SmallPtrSet<Value*, 16> > anticipatedIn;
+ std::map<BasicBlock*, SmallPtrSet<Value*, 16> > generatedPhis;
// This transformation requires dominator postdominator info
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
@@ -594,7 +595,7 @@ namespace {
bool dependsOnInvoke(Value* V);
void buildsets_availout(BasicBlock::iterator I,
SmallPtrSet<Value*, 16>& currAvail,
- SmallPtrSet<PHINode*, 16>& currPhis,
+ SmallPtrSet<Value*, 16>& currPhis,
SmallPtrSet<Value*, 16>& currExps,
SmallPtrSet<Value*, 16>& currTemps,
BitVector& availNumbers,
@@ -1168,7 +1169,7 @@ void GVNPRE::cleanup() {
/// by inserting it into the appropriate sets
void GVNPRE::buildsets_availout(BasicBlock::iterator I,
SmallPtrSet<Value*, 16>& currAvail,
- SmallPtrSet<PHINode*, 16>& currPhis,
+ SmallPtrSet<Value*, 16>& currPhis,
SmallPtrSet<Value*, 16>& currExps,
SmallPtrSet<Value*, 16>& currTemps,
BitVector& availNumbers,
@@ -1401,7 +1402,6 @@ unsigned GVNPRE::buildsets_anticin(BasicBlock* BB,
/// and the ANTIC_IN sets.
void GVNPRE::buildsets(Function& F) {
std::map<BasicBlock*, SmallPtrSet<Value*, 16> > generatedExpressions;
- std::map<BasicBlock*, SmallPtrSet<PHINode*, 16> > generatedPhis;
std::map<BasicBlock*, SmallPtrSet<Value*, 16> > generatedTemporaries;
DominatorTree &DT = getAnalysis<DominatorTree>();
@@ -1414,7 +1414,7 @@ void GVNPRE::buildsets(Function& F) {
// Get the sets to update for this block
SmallPtrSet<Value*, 16>& currExps = generatedExpressions[DI->getBlock()];
- SmallPtrSet<PHINode*, 16>& currPhis = generatedPhis[DI->getBlock()];
+ SmallPtrSet<Value*, 16>& currPhis = generatedPhis[DI->getBlock()];
SmallPtrSet<Value*, 16>& currTemps = generatedTemporaries[DI->getBlock()];
SmallPtrSet<Value*, 16>& currAvail = availableOut[DI->getBlock()];
@@ -1628,6 +1628,7 @@ void GVNPRE::insertion_pre(Value* e, BasicBlock* BB,
VN.add(p, VN.lookup(e));
val_replace(availableOut[BB], p);
+ generatedPhis[BB].insert(p);
new_sets[BB].insert(p);
++NumInsertedPhis;
@@ -1655,7 +1656,8 @@ unsigned GVNPRE::insertion_mergepoint(std::vector<Value*>& workList,
std::map<BasicBlock*, Value*> avail;
bool by_some = false;
- int num_avail = 0;
+ bool all_same = true;
+ Value * first_s = 0;
for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE;
++PI) {
@@ -1667,6 +1669,7 @@ unsigned GVNPRE::insertion_mergepoint(std::vector<Value*>& workList,
if (av != avail.end())
avail.erase(av);
avail.insert(std::make_pair(*PI, e2));
+ all_same = false;
} else {
std::map<BasicBlock*, Value*>::iterator av = avail.find(*PI);
if (av != avail.end())
@@ -1674,11 +1677,15 @@ unsigned GVNPRE::insertion_mergepoint(std::vector<Value*>& workList,
avail.insert(std::make_pair(*PI, e3));
by_some = true;
- num_avail++;
+ if (first_s == 0)
+ first_s = e3;
+ else if (first_s != e3)
+ all_same = false;
}
}
- if (by_some && num_avail < std::distance(pred_begin(BB), pred_end(BB))) {
+ if (by_some && !all_same &&
+ !find_leader(generatedPhis[BB], VN.lookup(e))) {
insertion_pre(e, BB, avail, new_sets);
changed_function = true;
@@ -1755,7 +1762,8 @@ bool GVNPRE::runOnFunction(Function &F) {
createdExpressions.clear();
availableOut.clear();
anticipatedIn.clear();
-
+ generatedPhis.clear();
+
bool changed_function = false;
// Phase 1: BuildSets