From: Owen Anderson Date: Thu, 17 Apr 2008 05:36:50 +0000 (+0000) Subject: Make GVN able to remove unnecessary calls to read-only functions again. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=241f65321efc6ad84ed875cd9494df8ca1cff309;p=oota-llvm.git Make GVN able to remove unnecessary calls to read-only functions again. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49842 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index 314d6e4b3a7..161c2fed1c7 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -134,8 +134,7 @@ Instruction* MemoryDependenceAnalysis::getCallSiteDependency(CallSite C, } else if (isa(QI)) { AliasAnalysis::ModRefBehavior result = AA.getModRefBehavior(CallSite::get(QI)); - if (result != AliasAnalysis::DoesNotAccessMemory && - result != AliasAnalysis::OnlyReadsMemory) { + if (result != AliasAnalysis::DoesNotAccessMemory) { if (!start && !block) { cachedResult.first = QI; cachedResult.second = true; diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index b33d3af31fc..bd360520a70 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -135,6 +135,7 @@ namespace { DenseMap valueNumbering; DenseMap expressionNumbering; AliasAnalysis* AA; + MemoryDependenceAnalysis* MD; uint32_t nextValueNumber; @@ -159,6 +160,7 @@ namespace { void erase(Value* v); unsigned size(); void setAliasAnalysis(AliasAnalysis* A) { AA = A; } + void setMemDep(MemoryDependenceAnalysis* M) { MD = M; } }; } @@ -432,6 +434,33 @@ uint32_t ValueTable::lookup_or_add(Value* V) { return nextValueNumber++; } + } else if (AA->onlyReadsMemory(C)) { + Expression e = create_expression(C); + + Instruction* dep = MD->getDependency(C); + + if (dep == MemoryDependenceAnalysis::NonLocal || + !isa(dep)) { + expressionNumbering.insert(std::make_pair(e, nextValueNumber)); + valueNumbering.insert(std::make_pair(V, nextValueNumber)); + + return nextValueNumber++; + } + + CallInst* cdep = cast(dep); + Expression d_exp = create_expression(cdep); + + if (e != d_exp) { + expressionNumbering.insert(std::make_pair(e, nextValueNumber)); + valueNumbering.insert(std::make_pair(V, nextValueNumber)); + + return nextValueNumber++; + } else { + uint32_t v = expressionNumbering[d_exp]; + valueNumbering.insert(std::make_pair(V, v)); + return v; + } + } else { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; @@ -993,22 +1022,6 @@ bool GVN::processInstruction(Instruction *I, ValueNumberedSet &currAvail, } else if (currAvail.test(num)) { Value* repl = find_leader(currAvail, num); - if (CallInst* CI = dyn_cast(I)) { - AliasAnalysis& AA = getAnalysis(); - if (!AA.doesNotAccessMemory(CI)) { - MemoryDependenceAnalysis& MD = getAnalysis(); - if (cast(repl)->getParent() != CI->getParent() || - MD.getDependency(CI) != MD.getDependency(cast(repl))) { - // There must be an intervening may-alias store, so nothing from - // this point on will be able to be replaced with the preceding call - currAvail.erase(repl); - currAvail.insert(I); - - return false; - } - } - } - // Remove it! MemoryDependenceAnalysis& MD = getAnalysis(); MD.removeInstruction(I); @@ -1030,6 +1043,7 @@ bool GVN::processInstruction(Instruction *I, ValueNumberedSet &currAvail, // bool GVN::runOnFunction(Function& F) { VN.setAliasAnalysis(&getAnalysis()); + VN.setMemDep(&getAnalysis()); bool changed = false; bool shouldContinue = true; diff --git a/test/Analysis/BasicAA/const-dce.ll b/test/Analysis/BasicAA/const-dce.ll deleted file mode 100644 index dcde91434ff..00000000000 --- a/test/Analysis/BasicAA/const-dce.ll +++ /dev/null @@ -1,33 +0,0 @@ -; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestConst | count 2 -; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestPure | count 4 -; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestNone | count 4 -@g = global i32 0 ; [#uses=1] - -define i32 @test() { -entry: - %tmp0 = call i32 @TestConst( i32 5 ) readnone ; [#uses=1] - %tmp1 = call i32 @TestPure( i32 6 ) readonly ; [#uses=1] - %tmp2 = call i32 @TestNone( i32 7 ) ; [#uses=1] - store i32 1, i32* @g - %tmp3 = call i32 @TestConst( i32 5 ) readnone ; [#uses=1] - %tmp4 = call i32 @TestConst( i32 5 ) readnone ; [#uses=1] - %tmp5 = call i32 @TestPure( i32 6 ) readonly ; [#uses=1] - %tmp6 = call i32 @TestPure( i32 6 ) readonly ; [#uses=1] - %tmp7 = call i32 @TestNone( i32 7 ) ; [#uses=1] - %tmp8 = call i32 @TestNone( i32 7 ) ; [#uses=1] - %sum0 = add i32 %tmp0, %tmp1 ; [#uses=1] - %sum1 = add i32 %sum0, %tmp2 ; [#uses=1] - %sum2 = add i32 %sum1, %tmp3 ; [#uses=1] - %sum3 = add i32 %sum2, %tmp4 ; [#uses=1] - %sum4 = add i32 %sum3, %tmp5 ; [#uses=1] - %sum5 = add i32 %sum4, %tmp6 ; [#uses=1] - %sum6 = add i32 %sum5, %tmp7 ; [#uses=1] - %sum7 = add i32 %sum6, %tmp8 ; [#uses=1] - ret i32 %sum7 -} - -declare i32 @TestConst(i32) readnone - -declare i32 @TestPure(i32) readonly - -declare i32 @TestNone(i32) diff --git a/test/Analysis/BasicAA/pure-const-dce.ll b/test/Analysis/BasicAA/pure-const-dce.ll new file mode 100644 index 00000000000..b01b5c5cb81 --- /dev/null +++ b/test/Analysis/BasicAA/pure-const-dce.ll @@ -0,0 +1,33 @@ +; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestConst | count 2 +; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestPure | count 3 +; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestNone | count 4 +@g = global i32 0 ; [#uses=1] + +define i32 @test() { +entry: + %tmp0 = call i32 @TestConst( i32 5 ) readnone ; [#uses=1] + %tmp1 = call i32 @TestPure( i32 6 ) readonly ; [#uses=1] + %tmp2 = call i32 @TestNone( i32 7 ) ; [#uses=1] + store i32 1, i32* @g + %tmp3 = call i32 @TestConst( i32 5 ) readnone ; [#uses=1] + %tmp4 = call i32 @TestConst( i32 5 ) readnone ; [#uses=1] + %tmp5 = call i32 @TestPure( i32 6 ) readonly ; [#uses=1] + %tmp6 = call i32 @TestPure( i32 6 ) readonly ; [#uses=1] + %tmp7 = call i32 @TestNone( i32 7 ) ; [#uses=1] + %tmp8 = call i32 @TestNone( i32 7 ) ; [#uses=1] + %sum0 = add i32 %tmp0, %tmp1 ; [#uses=1] + %sum1 = add i32 %sum0, %tmp2 ; [#uses=1] + %sum2 = add i32 %sum1, %tmp3 ; [#uses=1] + %sum3 = add i32 %sum2, %tmp4 ; [#uses=1] + %sum4 = add i32 %sum3, %tmp5 ; [#uses=1] + %sum5 = add i32 %sum4, %tmp6 ; [#uses=1] + %sum6 = add i32 %sum5, %tmp7 ; [#uses=1] + %sum7 = add i32 %sum6, %tmp8 ; [#uses=1] + ret i32 %sum7 +} + +declare i32 @TestConst(i32) readnone + +declare i32 @TestPure(i32) readonly + +declare i32 @TestNone(i32)