From: Owen Anderson Date: Wed, 28 Oct 2009 06:18:42 +0000 (+0000) Subject: Add trivial support for the invariance intrinsics to memdep. This logic is X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=4bc737c5ef120e27834b92a86939331f370ba49c Add trivial support for the invariance intrinsics to memdep. This logic is purely local for now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85378 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index a071205a125..edead091ed4 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -171,13 +171,42 @@ getCallSiteDependencyFrom(CallSite CS, bool isReadOnlyCall, /// location depends. If isLoad is true, this routine ignore may-aliases with /// read-only operations. MemDepResult MemoryDependenceAnalysis:: -getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad, +getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad, BasicBlock::iterator ScanIt, BasicBlock *BB) { + Value* invariantTag = 0; + // Walk backwards through the basic block, looking for dependencies. while (ScanIt != BB->begin()) { Instruction *Inst = --ScanIt; + // If we're in an invariant region, no dependencies can be found before + // we pass an invariant-begin marker. + if (invariantTag == Inst) { + invariantTag = 0; + continue; + + // If we pass an invariant-end marker, then we've just entered an invariant + // region and can start ignoring dependencies. + } else if (IntrinsicInst* II = dyn_cast(Inst)) { + if (II->getIntrinsicID() == Intrinsic::invariant_end) { + uint64_t invariantSize = ~0ULL; + if (ConstantInt* CI = dyn_cast(II->getOperand(2))) + invariantSize = CI->getZExtValue(); + + AliasAnalysis::AliasResult R = + AA->alias(II->getOperand(3), invariantSize, MemPtr, MemSize); + if (R == AliasAnalysis::MustAlias) { + invariantTag = II->getOperand(1); + continue; + } + } + } + + // If we're querying on a load and we're in an invariant region, we're done + // at this point. Nothing a load depends on can live in an invariant region. + if (isLoad && invariantTag) continue; + // Debug intrinsics don't cause dependences. if (isa(Inst)) continue; @@ -201,6 +230,11 @@ getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad, return MemDepResult::getDef(Inst); } + // If we're querying on a store and we're in an invariant region, we're done + // at this point. The only things that stores depend on that could exist in + // an invariant region are loads, which we've already checked. + if (invariantTag) continue; + if (StoreInst *SI = dyn_cast(Inst)) { // If alias analysis can tell that this store is guaranteed to not modify // the query pointer, ignore it. Use getModRefInfo to handle cases where diff --git a/test/Transforms/GVN/invariant-simple.ll b/test/Transforms/GVN/invariant-simple.ll new file mode 100644 index 00000000000..c3ff353833b --- /dev/null +++ b/test/Transforms/GVN/invariant-simple.ll @@ -0,0 +1,21 @@ +; RUN: opt < %s -gvn -S | FileCheck %s + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin7" + +define i8 @test(i8* %P) nounwind { +; CHECK: @test +; CHECK-NOT: load +; CHECK: ret i8 +entry: + store i8 1, i8* %P + %0 = call {}* @llvm.invariant.start(i64 32, i8* %P) + %1 = tail call i32 @foo(i8* %P) + call void @llvm.invariant.end({}* %0, i64 32, i8* %P) + %2 = load i8* %P + ret i8 %2 +} + +declare i32 @foo(i8*) nounwind +declare {}* @llvm.invariant.start(i64 %S, i8* nocapture %P) readonly +declare void @llvm.invariant.end({}* %S, i64 %SS, i8* nocapture %P) \ No newline at end of file