[llvm-commits] [llvm] r74499 - in /llvm/trunk: lib/Analysis/LoopDependenceAnalysis.cpp test/Analysis/LoopDependenceAnalysis/local-array.ll test/Analysis/LoopDependenceAnalysis/no-array.ll test/Analysis/LoopDependenceAnalysis/siv-strong1.ll test/Analysis/LoopDependenceAnalysis/siv-strong2.ll
Chris Lattner
clattner at apple.com
Mon Jun 29 22:24:12 PDT 2009
On Jun 29, 2009, at 7:12 PM, Andreas Bolka wrote:
> Author: abolka
> Date: Mon Jun 29 21:12:10 2009
> New Revision: 74499
>
> URL: http://llvm.org/viewvc/llvm-project?rev=74499&view=rev
> Log:
> Array accesses are independent if the underlying arrays differ.
Andreas, you should really use AliasAnalysis queries for this. If you
have P[i] and Q[j] then the accesses are known not to depend on each
other if P/Q are known to noalias. Please don't reinvent alias
analysis in your pass :)
-Chris
>
> Added:
> llvm/trunk/test/Analysis/LoopDependenceAnalysis/local-array.ll
> llvm/trunk/test/Analysis/LoopDependenceAnalysis/no-array.ll
> Modified:
> llvm/trunk/lib/Analysis/LoopDependenceAnalysis.cpp
> llvm/trunk/test/Analysis/LoopDependenceAnalysis/siv-strong1.ll
> llvm/trunk/test/Analysis/LoopDependenceAnalysis/siv-strong2.ll
>
> Modified: llvm/trunk/lib/Analysis/LoopDependenceAnalysis.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopDependenceAnalysis.cpp?rev=74499&r1=74498&r2=74499&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/Analysis/LoopDependenceAnalysis.cpp (original)
> +++ llvm/trunk/lib/Analysis/LoopDependenceAnalysis.cpp Mon Jun 29
> 21:12:10 2009
> @@ -22,6 +22,7 @@
> #include "llvm/Analysis/LoopPass.h"
> #include "llvm/Analysis/ScalarEvolution.h"
> #include "llvm/Instructions.h"
> +#include "llvm/Support/Debug.h"
> using namespace llvm;
>
> LoopPass *llvm::createLoopDependenceAnalysisPass() {
> @@ -51,6 +52,20 @@
> memrefs.push_back(i);
> }
>
> +static bool IsLoadOrStoreInst(Value *I) {
> + return isa<LoadInst>(I) || isa<StoreInst>(I);
> +}
> +
> +static Value *GetPointerOperand(Value *I) {
> + if (LoadInst *i = dyn_cast<LoadInst>(I))
> + return i->getPointerOperand();
> + if (StoreInst *i = dyn_cast<StoreInst>(I))
> + return i->getPointerOperand();
> + assert(0 && "Value is no load or store instruction!");
> + // Never reached.
> + return 0;
> +}
> +
> //
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
> // Dependence Testing
> //
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
> @@ -65,6 +80,38 @@
>
> bool LoopDependenceAnalysis::depends(Value *src, Value *dst) {
> assert(isDependencePair(src, dst) && "Values form no dependence
> pair!");
> + DOUT << "== LDA test ==\n" << *src << *dst;
> +
> + // We only analyse loads and stores; for possible memory accesses
> by e.g.
> + // free, call, or invoke instructions we conservatively assume
> dependence.
> + if (!IsLoadOrStoreInst(src) || !IsLoadOrStoreInst(dst))
> + return true;
> +
> + Value *srcPtr = GetPointerOperand(src);
> + Value *dstPtr = GetPointerOperand(dst);
> + const Value *srcObj = srcPtr->getUnderlyingObject();
> + const Value *dstObj = dstPtr->getUnderlyingObject();
> + const Type *srcTy = srcObj->getType();
> + const Type *dstTy = dstObj->getType();
> +
> + // For now, we only work on (pointers to) global or stack-
> allocated array
> + // values, as we know that their underlying memory areas will not
> overlap.
> + // MAYBE: relax this and test for aliasing?
> + if (!((isa<GlobalVariable>(srcObj) || isa<AllocaInst>(srcObj)) &&
> + (isa<GlobalVariable>(dstObj) || isa<AllocaInst>(dstObj)) &&
> + isa<PointerType>(srcTy) &&
> + isa<PointerType>(dstTy) &&
> + isa<ArrayType>(cast<PointerType>(srcTy)->getElementType()) &&
> + isa<ArrayType>(cast<PointerType>(dstTy)->getElementType())))
> + return true;
> +
> + // If the arrays are different, the underlying memory areas do
> not overlap
> + // and the memory accesses are therefore independent.
> + if (srcObj != dstObj)
> + return false;
> +
> + // We couldn't establish a more precise result, so we have to
> conservatively
> + // assume full dependence.
> return true;
> }
>
>
> Added: llvm/trunk/test/Analysis/LoopDependenceAnalysis/local-array.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/LoopDependenceAnalysis/local-array.ll?rev=74499&view=auto
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/test/Analysis/LoopDependenceAnalysis/local-array.ll
> (added)
> +++ llvm/trunk/test/Analysis/LoopDependenceAnalysis/local-array.ll
> Mon Jun 29 21:12:10 2009
> @@ -0,0 +1,24 @@
> +; RUN: llvm-as < %s | opt -disable-output -analyze -lda > %t
> +; RUN: grep {instructions: 2} %t | count 1
> +; RUN: grep {0,1: dependent} %t | count 1
> +
> +; x[5] = x[6] // with x being an array on the stack
> +
> +define void @foo(...) nounwind {
> +entry:
> + %xptr = alloca [256 x i32], align 4
> + %x.ld.addr = getelementptr [256 x i32]* %xptr, i64 0, i64 6
> + %x.st.addr = getelementptr [256 x i32]* %xptr, i64 0, i64 5
> + br label %for.body
> +
> +for.body:
> + %i = phi i64 [ 0, %entry ], [ %i.next, %for.body ]
> + %x = load i32* %x.ld.addr
> + store i32 %x, i32* %x.st.addr
> + %i.next = add i64 %i, 1
> + %exitcond = icmp eq i64 %i.next, 256
> + br i1 %exitcond, label %for.end, label %for.body
> +
> +for.end:
> + ret void
> +}
>
> Added: llvm/trunk/test/Analysis/LoopDependenceAnalysis/no-array.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/LoopDependenceAnalysis/no-array.ll?rev=74499&view=auto
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/test/Analysis/LoopDependenceAnalysis/no-array.ll
> (added)
> +++ llvm/trunk/test/Analysis/LoopDependenceAnalysis/no-array.ll Mon
> Jun 29 21:12:10 2009
> @@ -0,0 +1,23 @@
> +; RUN: llvm-as < %s | opt -disable-output -analyze -lda > %t
> +; RUN: grep {instructions: 2} %t | count 1
> +; RUN: grep {0,1: dependent} %t | count 1
> +
> +; x[5] = x[6] // with x being a pointer passed as argument
> +
> +define void @foo(i32* nocapture %xptr) nounwind {
> +entry:
> + %x.ld.addr = getelementptr i32* %xptr, i64 6
> + %x.st.addr = getelementptr i32* %xptr, i64 5
> + br label %for.body
> +
> +for.body:
> + %i = phi i64 [ 0, %entry ], [ %i.next, %for.body ]
> + %x = load i32* %x.ld.addr
> + store i32 %x, i32* %x.st.addr
> + %i.next = add i64 %i, 1
> + %exitcond = icmp eq i64 %i.next, 256
> + br i1 %exitcond, label %for.end, label %for.body
> +
> +for.end:
> + ret void
> +}
>
> Modified: llvm/trunk/test/Analysis/LoopDependenceAnalysis/siv-
> strong1.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/LoopDependenceAnalysis/siv-strong1.ll?rev=74499&r1=74498&r2=74499&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/test/Analysis/LoopDependenceAnalysis/siv-strong1.ll
> (original)
> +++ llvm/trunk/test/Analysis/LoopDependenceAnalysis/siv-strong1.ll
> Mon Jun 29 21:12:10 2009
> @@ -1,7 +1,7 @@
> ; RUN: llvm-as < %s | opt -disable-output -analyze -lda > %t
> ; RUN: grep {instructions: 3} %t | count 1
> ; RUN: grep {0,2: dependent} %t | count 1
> -; RUN: grep {1,2: dependent} %t | count 1
> +; RUN: grep {1,2: independent} %t | count 1
>
> ; for (i = 0; i < 256; i++)
> ; x[i] = x[i] + y[i]
>
> Modified: llvm/trunk/test/Analysis/LoopDependenceAnalysis/siv-
> strong2.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/LoopDependenceAnalysis/siv-strong2.ll?rev=74499&r1=74498&r2=74499&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/test/Analysis/LoopDependenceAnalysis/siv-strong2.ll
> (original)
> +++ llvm/trunk/test/Analysis/LoopDependenceAnalysis/siv-strong2.ll
> Mon Jun 29 21:12:10 2009
> @@ -1,7 +1,7 @@
> ; RUN: llvm-as < %s | opt -disable-output -analyze -lda > %t
> ; RUN: grep {instructions: 3} %t | count 1
> ; RUN: grep {0,2: dependent} %t | count 1
> -; RUN: grep {1,2: dependent} %t | count 1
> +; RUN: grep {1,2: independent} %t | count 1
>
> ; for (i = 0; i < 256; i++)
> ; x[i+1] = x[i] + y[i]
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list