Array accesses are independent if the underlying arrays differ.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74499 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/LoopDependenceAnalysis.cpp b/lib/Analysis/LoopDependenceAnalysis.cpp
index 020a8c7..c1168ec 100644
--- a/lib/Analysis/LoopDependenceAnalysis.cpp
+++ b/lib/Analysis/LoopDependenceAnalysis.cpp
@@ -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;
 }