From: Owen Anderson Date: Thu, 5 Jul 2007 23:11:26 +0000 (+0000) Subject: Fix a bunch of issues found in a testcase from 400.perlbench. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=2a5c9d8aac76e8b9585edf1012005432a496179c;p=oota-llvm.git Fix a bunch of issues found in a testcase from 400.perlbench. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37929 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/GVNPRE.cpp b/lib/Transforms/Scalar/GVNPRE.cpp index e5e3710643b..dde7e466afb 100644 --- a/lib/Transforms/Scalar/GVNPRE.cpp +++ b/lib/Transforms/Scalar/GVNPRE.cpp @@ -31,6 +31,7 @@ #include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" #include "llvm/Support/CFG.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" @@ -567,6 +568,7 @@ namespace { // This transformation requires dominator postdominator info virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); + AU.addRequired(); AU.addRequired(); } @@ -608,10 +610,10 @@ namespace { void insertion_pre(Value* e, BasicBlock* BB, std::map& avail, - SmallPtrSet& new_set); + std::map >& new_set); unsigned insertion_mergepoint(std::vector& workList, df_iterator& D, - SmallPtrSet& new_set); + std::map >& new_set); bool insertion(Function& F); }; @@ -1331,7 +1333,7 @@ bool GVNPRE::buildsets_anticout(BasicBlock* BB, for (SmallPtrSet::iterator I = anticOut.begin(), E = anticOut.end(); I != E; ++I) - if (succAnticIn.count(*I) == 0) + if (find_leader(succAnticIn, VN.lookup(*I)) == 0) temp.push_back(*I); for (std::vector::iterator I = temp.begin(), E = temp.end(); @@ -1488,8 +1490,9 @@ void GVNPRE::buildsets(Function& F) { /// the main block void GVNPRE::insertion_pre(Value* e, BasicBlock* BB, std::map& avail, - SmallPtrSet& new_set) { + std::map >& new_sets) { for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) { + DOUT << "PRED: " << (*PI)->getName() << "\n"; Value* e2 = avail[*PI]; if (!find_leader(availableOut[*PI], VN.lookup(e2))) { User* U = cast(e2); @@ -1602,6 +1605,7 @@ void GVNPRE::insertion_pre(Value* e, BasicBlock* BB, SmallPtrSet& predAvail = availableOut[*PI]; val_replace(predAvail, newVal); + val_replace(new_sets[*PI], newVal); std::map::iterator av = avail.find(*PI); if (av != avail.end()) @@ -1617,13 +1621,13 @@ void GVNPRE::insertion_pre(Value* e, BasicBlock* BB, for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) { if (p == 0) p = new PHINode(avail[*PI]->getType(), "gvnpre-join", BB->begin()); - + p->addIncoming(avail[*PI], *PI); } VN.add(p, VN.lookup(e)); val_replace(availableOut[BB], p); - new_set.insert(p); + new_sets[BB].insert(p); ++NumInsertedPhis; } @@ -1632,7 +1636,7 @@ void GVNPRE::insertion_pre(Value* e, BasicBlock* BB, /// block for the possibility of a partial redundancy. If present, eliminate it unsigned GVNPRE::insertion_mergepoint(std::vector& workList, df_iterator& D, - SmallPtrSet& new_set) { + std::map >& new_sets) { bool changed_function = false; bool new_stuff = false; @@ -1655,6 +1659,11 @@ unsigned GVNPRE::insertion_mergepoint(std::vector& workList, for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) { Value *e2 = phi_translate(e, *PI, BB); + if (find_leader(anticipatedIn[*PI], VN.lookup(e2)) == 0) { + by_some = false; + break; + } + Value *e3 = find_leader(availableOut[*PI], VN.lookup(e2)); if (e3 == 0) { @@ -1674,7 +1683,7 @@ unsigned GVNPRE::insertion_mergepoint(std::vector& workList, } if (by_some && num_avail < std::distance(pred_begin(BB), pred_end(BB))) { - insertion_pre(e, BB, avail, new_set); + insertion_pre(e, BB, avail, new_sets); changed_function = true; new_stuff = true; @@ -1710,18 +1719,15 @@ bool GVNPRE::insertion(Function& F) { if (BB == 0) continue; - SmallPtrSet& new_set = new_sets[BB]; SmallPtrSet& availOut = availableOut[BB]; SmallPtrSet& anticIn = anticipatedIn[BB]; - new_set.clear(); - // Replace leaders with leaders inherited from dominator if (DI->getIDom() != 0) { SmallPtrSet& dom_set = new_sets[DI->getIDom()->getBlock()]; for (SmallPtrSet::iterator I = dom_set.begin(), E = dom_set.end(); I != E; ++I) { - new_set.insert(*I); + val_replace(new_sets[BB], *I); val_replace(availOut, *I); } } @@ -1732,7 +1738,7 @@ bool GVNPRE::insertion(Function& F) { workList.reserve(anticIn.size()); topo_sort(anticIn, workList); - unsigned result = insertion_mergepoint(workList, DI, new_set); + unsigned result = insertion_mergepoint(workList, DI, new_sets); if (result & 1) changed_function = true; if (result & 2) @@ -1761,9 +1767,6 @@ bool GVNPRE::runOnFunction(Function &F) { buildsets(F); for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) { - DOUT << "AVAIL_OUT: " << FI->getName() << "\n"; - dump(availableOut[FI]); - DOUT << "\n"; DOUT << "ANTIC_IN: " << FI->getName() << "\n"; dump(anticipatedIn[FI]); DOUT << "\n\n"; diff --git a/test/Transforms/GVNPRE/2007-07-05-AvailabilityUpdating.ll b/test/Transforms/GVNPRE/2007-07-05-AvailabilityUpdating.ll new file mode 100644 index 00000000000..5510935ebbc --- /dev/null +++ b/test/Transforms/GVNPRE/2007-07-05-AvailabilityUpdating.ll @@ -0,0 +1,54 @@ +; RUN: llvm-as < %s | opt -gvnpre | llvm-dis | grep tmp114115.gvnpre + + %struct.AV = type { %struct.XPVAV*, i32, i32 } + %struct.CLONE_PARAMS = type { %struct.AV*, i32, %struct.PerlInterpreter* } + %struct.HE = type { %struct.HE*, %struct.HEK*, %struct.SV* } + %struct.HEK = type { i32, i32, [1 x i8] } + %struct.HV = type { %struct.XPVHV*, i32, i32 } + %struct.MAGIC = type { %struct.MAGIC*, %struct.MGVTBL*, i16, i8, i8, %struct.SV*, i8*, i32 } + %struct.MGVTBL = type { i32 (%struct.SV*, %struct.MAGIC*)*, i32 (%struct.SV*, %struct.MAGIC*)*, i32 (%struct.SV*, %struct.MAGIC*)*, i32 (%struct.SV*, %struct.MAGIC*)*, i32 (%struct.SV*, %struct.MAGIC*)*, i32 (%struct.SV*, %struct.MAGIC*, %struct.SV*, i8*, i32)*, i32 (%struct.MAGIC*, %struct.CLONE_PARAMS*)* } + %struct.OP = type { %struct.OP*, %struct.OP*, %struct.OP* ()*, i32, i16, i16, i8, i8 } + %struct.PMOP = type { %struct.OP*, %struct.OP*, %struct.OP* ()*, i32, i16, i16, i8, i8, %struct.OP*, %struct.OP*, %struct.OP*, %struct.OP*, %struct.PMOP*, %struct.REGEXP*, i32, i32, i8, %struct.HV* } + %struct.PerlInterpreter = type { i8 } + %struct.REGEXP = type { i32*, i32*, %struct.regnode*, %struct.reg_substr_data*, i8*, %struct.reg_data*, i8*, i32*, i32, i32, i32, i32, i32, i32, i32, i32, [1 x %struct.regnode] } + %struct.SV = type { i8*, i32, i32 } + %struct.XPVAV = type { i8*, i32, i32, i32, double, %struct.MAGIC*, %struct.HV*, %struct.SV**, %struct.SV*, i8 } + %struct.XPVHV = type { i8*, i32, i32, i32, double, %struct.MAGIC*, %struct.HV*, i32, %struct.HE*, %struct.PMOP*, i8* } + %struct.reg_data = type { i32, i8*, [1 x i8*] } + %struct.reg_substr_data = type { [3 x %struct.reg_substr_datum] } + %struct.reg_substr_datum = type { i32, i32, %struct.SV*, %struct.SV* } + %struct.regnode = type { i8, i8, i16 } + +define void @Perl_op_clear(%struct.OP* %o) { +entry: + switch i32 0, label %bb106 [ + i32 13, label %bb106 + i32 31, label %clear_pmop + i32 32, label %clear_pmop + i32 33, label %bb101 + ] + +bb101: ; preds = %entry + %tmp102103 = bitcast %struct.OP* %o to %struct.PMOP* ; <%struct.PMOP*> [#uses=1] + %tmp104 = getelementptr %struct.PMOP* %tmp102103, i32 0, i32 10 ; <%struct.OP**> [#uses=0] + br i1 false, label %cond_next174, label %cond_true122 + +bb106: ; preds = %entry, %entry + %tmp107108 = bitcast %struct.OP* %o to %struct.PMOP* ; <%struct.PMOP*> [#uses=0] + br label %clear_pmop + +clear_pmop: ; preds = %bb106, %entry, %entry + %tmp114115 = bitcast %struct.OP* %o to %struct.PMOP* ; <%struct.PMOP*> [#uses=0] + br label %cond_true122 + +cond_true122: ; preds = %clear_pmop, %bb101 + br i1 false, label %cond_next174, label %cond_true129 + +cond_true129: ; preds = %cond_true122 + ret void + +cond_next174: ; preds = %cond_true122, %bb101 + %tmp175176 = bitcast %struct.OP* %o to %struct.PMOP* ; <%struct.PMOP*> [#uses=1] + %tmp177 = getelementptr %struct.PMOP* %tmp175176, i32 0, i32 10 ; <%struct.OP**> [#uses=0] + ret void +}