forked from OSchip/llvm-project
Fix a bunch of issues found in a testcase from 400.perlbench.
llvm-svn: 37929
This commit is contained in:
parent
da784693c3
commit
02e9698293
|
@ -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<UnifyFunctionExitNodes>();
|
||||
AU.addRequired<DominatorTree>();
|
||||
}
|
||||
|
||||
|
@ -608,10 +610,10 @@ namespace {
|
|||
|
||||
void insertion_pre(Value* e, BasicBlock* BB,
|
||||
std::map<BasicBlock*, Value*>& avail,
|
||||
SmallPtrSet<Value*, 16>& new_set);
|
||||
std::map<BasicBlock*, SmallPtrSet<Value*, 16> >& new_set);
|
||||
unsigned insertion_mergepoint(std::vector<Value*>& workList,
|
||||
df_iterator<DomTreeNode*>& D,
|
||||
SmallPtrSet<Value*, 16>& new_set);
|
||||
std::map<BasicBlock*, SmallPtrSet<Value*, 16> >& new_set);
|
||||
bool insertion(Function& F);
|
||||
|
||||
};
|
||||
|
@ -1331,7 +1333,7 @@ bool GVNPRE::buildsets_anticout(BasicBlock* BB,
|
|||
|
||||
for (SmallPtrSet<Value*, 16>::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<Value*>::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<BasicBlock*, Value*>& avail,
|
||||
SmallPtrSet<Value*, 16>& new_set) {
|
||||
std::map<BasicBlock*, SmallPtrSet<Value*, 16> >& 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<User>(e2);
|
||||
|
@ -1602,6 +1605,7 @@ void GVNPRE::insertion_pre(Value* e, BasicBlock* BB,
|
|||
|
||||
SmallPtrSet<Value*, 16>& predAvail = availableOut[*PI];
|
||||
val_replace(predAvail, newVal);
|
||||
val_replace(new_sets[*PI], newVal);
|
||||
|
||||
std::map<BasicBlock*, Value*>::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<Value*>& workList,
|
||||
df_iterator<DomTreeNode*>& D,
|
||||
SmallPtrSet<Value*, 16>& new_set) {
|
||||
std::map<BasicBlock*, SmallPtrSet<Value*, 16> >& new_sets) {
|
||||
bool changed_function = false;
|
||||
bool new_stuff = false;
|
||||
|
||||
|
@ -1655,6 +1659,11 @@ unsigned GVNPRE::insertion_mergepoint(std::vector<Value*>& 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<Value*>& 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<Value*, 16>& new_set = new_sets[BB];
|
||||
SmallPtrSet<Value*, 16>& availOut = availableOut[BB];
|
||||
SmallPtrSet<Value*, 16>& anticIn = anticipatedIn[BB];
|
||||
|
||||
new_set.clear();
|
||||
|
||||
// Replace leaders with leaders inherited from dominator
|
||||
if (DI->getIDom() != 0) {
|
||||
SmallPtrSet<Value*, 16>& dom_set = new_sets[DI->getIDom()->getBlock()];
|
||||
for (SmallPtrSet<Value*, 16>::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";
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue