Extend the getDependence query with support for PHI translation.
authorDan Gohman <gohman@apple.com>
Thu, 9 Sep 2010 18:37:31 +0000 (18:37 +0000)
committerDan Gohman <gohman@apple.com>
Thu, 9 Sep 2010 18:37:31 +0000 (18:37 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113521 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/AliasAnalysis.h
lib/Analysis/AliasAnalysis.cpp
lib/Analysis/BasicAliasAnalysis.cpp

index c74f9e11431a8de7e2c9cc510b002109f45aa6fb..a03e0c88068ddaa561049575f0e8704bbfa8a789 100644 (file)
@@ -340,17 +340,20 @@ public:
   /// WARNING: This is an experimental interface.
   DependenceResult getDependence(const Instruction *First,
                                  const Instruction *Second) {
-    return getDependence(First, Default, Second, Default);
+    return getDependence(First, 0, Default, Second, 0, Default);
   }
 
   /// getDependence - Determine the dependence relationship between the
   /// instructions. This does not include "register" dependencies; it just
   /// considers memory references and other side effects.  This overload
-  /// accepts additional flags to refine the query.
+  /// has additional parameters to allow phi-translated addresses to be
+  /// specified, and additional flags to refine the query.
   /// WARNING: This is an experimental interface.
   virtual DependenceResult getDependence(const Instruction *First,
+                                         const Value *FirstPHITranslatedAddr,
                                          DependenceQueryFlags FirstFlags,
                                          const Instruction *Second,
+                                         const Value *SecondPHITranslatedAddr,
                                          DependenceQueryFlags SecondFlags);
 
   //===--------------------------------------------------------------------===//
@@ -403,8 +406,10 @@ protected:
   /// getDependenceViaModRefInfo - Helper function for implementing getDependence
   /// in implementations which already have getModRefInfo implementations.
   DependenceResult getDependenceViaModRefInfo(const Instruction *First,
+                                              const Value *FirstPHITranslatedAddr,
                                               DependenceQueryFlags FirstFlags,
                                               const Instruction *Second,
+                                              const Value *SecondPHITranslatedAddr,
                                               DependenceQueryFlags SecondFlags);
 
 };
index 536b75986eb39bba76d7757b141b3eacad4709f6..93597cab226ae7259d78a6f4172f3109a5dd56c5 100644 (file)
@@ -190,11 +190,14 @@ AliasAnalysis::getModRefBehavior(const Function *F) {
 
 AliasAnalysis::DependenceResult
 AliasAnalysis::getDependence(const Instruction *First,
+                             const Value *FirstPHITranslatedAddr,
                              DependenceQueryFlags FirstFlags,
                              const Instruction *Second,
+                             const Value *SecondPHITranslatedAddr,
                              DependenceQueryFlags SecondFlags) {
   assert(AA && "AA didn't call InitializeAliasAnalyais in its run method!");
-  return AA->getDependence(First, FirstFlags, Second, SecondFlags);
+  return AA->getDependence(First, FirstPHITranslatedAddr, FirstFlags,
+                           Second, SecondPHITranslatedAddr, SecondFlags);
 }
 
 //===----------------------------------------------------------------------===//
@@ -255,17 +258,23 @@ AliasAnalysis::getModRefInfo(const VAArgInst *V, const Value *P, unsigned Size)
 
 AliasAnalysis::DependenceResult
 AliasAnalysis::getDependenceViaModRefInfo(const Instruction *First,
+                                          const Value *FirstPHITranslatedAddr,
                                           DependenceQueryFlags FirstFlags,
                                           const Instruction *Second,
+                                          const Value *SecondPHITranslatedAddr,
                                           DependenceQueryFlags SecondFlags) {
   if (const LoadInst *L = dyn_cast<LoadInst>(First)) {
     // Be over-conservative with volatile for now.
     if (L->isVolatile())
       return Unknown;
 
+    // If we don't have a phi-translated address, use the actual one.
+    if (!FirstPHITranslatedAddr)
+      FirstPHITranslatedAddr = L->getPointerOperand();
+
     // Forward this query to getModRefInfo.
     switch (getModRefInfo(Second,
-                          L->getPointerOperand(),
+                          FirstPHITranslatedAddr,
                           getTypeStoreSize(L->getType()))) {
     case NoModRef:
       // Second doesn't reference First's memory, so they're independent.
@@ -280,10 +289,14 @@ AliasAnalysis::getDependenceViaModRefInfo(const Instruction *First,
       // If it's loading the same size from the same address, we can
       // give a more precise result.
       if (const LoadInst *SecondL = dyn_cast<LoadInst>(Second)) {
+        // If we don't have a phi-translated address, use the actual one.
+        if (!SecondPHITranslatedAddr)
+          SecondPHITranslatedAddr = SecondL->getPointerOperand();
+
         unsigned LSize = getTypeStoreSize(L->getType());
         unsigned SecondLSize = getTypeStoreSize(SecondL->getType());
-        if (alias(L->getPointerOperand(), LSize,
-                  SecondL->getPointerOperand(), SecondLSize) ==
+        if (alias(FirstPHITranslatedAddr, LSize,
+                  SecondPHITranslatedAddr, SecondLSize) ==
             MustAlias) {
           // If the loads are the same size, it's ReadThenRead.
           if (LSize == SecondLSize)
@@ -307,10 +320,14 @@ AliasAnalysis::getDependenceViaModRefInfo(const Instruction *First,
       // If it's storing the same size to the same address, we can
       // give a more precise result.
       if (const StoreInst *SecondS = dyn_cast<StoreInst>(Second)) {
+        // If we don't have a phi-translated address, use the actual one.
+        if (!SecondPHITranslatedAddr)
+          SecondPHITranslatedAddr = SecondS->getPointerOperand();
+
         unsigned LSize = getTypeStoreSize(L->getType());
         unsigned SecondSSize = getTypeStoreSize(SecondS->getType());
-        if (alias(L->getPointerOperand(), LSize,
-                  SecondS->getPointerOperand(), SecondSSize) ==
+        if (alias(FirstPHITranslatedAddr, LSize,
+                  SecondPHITranslatedAddr, SecondSSize) ==
             MustAlias) {
           // If the load and the store are the same size, it's ReadThenWrite.
           if (LSize == SecondSSize)
@@ -332,9 +349,13 @@ AliasAnalysis::getDependenceViaModRefInfo(const Instruction *First,
     if (S->isVolatile())
       return Unknown;
 
+    // If we don't have a phi-translated address, use the actual one.
+    if (!FirstPHITranslatedAddr)
+      FirstPHITranslatedAddr = S->getPointerOperand();
+
     // Forward this query to getModRefInfo.
     switch (getModRefInfo(Second,
-                          S->getPointerOperand(),
+                          FirstPHITranslatedAddr,
                           getTypeStoreSize(S->getValueOperand()->getType()))) {
     case NoModRef:
       // Second doesn't reference First's memory, so they're independent.
@@ -349,10 +370,14 @@ AliasAnalysis::getDependenceViaModRefInfo(const Instruction *First,
       // If it's loading the same size from the same address, we can
       // give a more precise result.
       if (const LoadInst *SecondL = dyn_cast<LoadInst>(Second)) {
+        // If we don't have a phi-translated address, use the actual one.
+        if (!SecondPHITranslatedAddr)
+          SecondPHITranslatedAddr = SecondL->getPointerOperand();
+
         unsigned SSize = getTypeStoreSize(S->getValueOperand()->getType());
         unsigned SecondLSize = getTypeStoreSize(SecondL->getType());
-        if (alias(S->getPointerOperand(), SSize,
-                  SecondL->getPointerOperand(), SecondLSize) ==
+        if (alias(FirstPHITranslatedAddr, SSize,
+                  SecondPHITranslatedAddr, SecondLSize) ==
             MustAlias) {
           // If the store and the load are the same size, it's WriteThenRead.
           if (SSize == SecondLSize)
@@ -376,10 +401,14 @@ AliasAnalysis::getDependenceViaModRefInfo(const Instruction *First,
       // If it's storing the same size to the same address, we can
       // give a more precise result.
       if (const StoreInst *SecondS = dyn_cast<StoreInst>(Second)) {
+        // If we don't have a phi-translated address, use the actual one.
+        if (!SecondPHITranslatedAddr)
+          SecondPHITranslatedAddr = SecondS->getPointerOperand();
+
         unsigned SSize = getTypeStoreSize(S->getValueOperand()->getType());
         unsigned SecondSSize = getTypeStoreSize(SecondS->getType());
-        if (alias(S->getPointerOperand(), SSize,
-                  SecondS->getPointerOperand(), SecondSSize) ==
+        if (alias(FirstPHITranslatedAddr, SSize,
+                  SecondPHITranslatedAddr, SecondSSize) ==
             MustAlias) {
           // If the stores are the same size, it's WriteThenWrite.
           if (SSize == SecondSSize)
@@ -401,12 +430,20 @@ AliasAnalysis::getDependenceViaModRefInfo(const Instruction *First,
     }
 
   } else if (const VAArgInst *V = dyn_cast<VAArgInst>(First)) {
+    // If we don't have a phi-translated address, use the actual one.
+    if (!FirstPHITranslatedAddr)
+      FirstPHITranslatedAddr = V->getPointerOperand();
+
     // Forward this query to getModRefInfo.
-    if (getModRefInfo(Second, V->getOperand(0), UnknownSize) == NoModRef)
+    if (getModRefInfo(Second, FirstPHITranslatedAddr, UnknownSize) == NoModRef)
       // Second doesn't reference First's memory, so they're independent.
       return Independent;
 
   } else if (ImmutableCallSite FirstCS = cast<Value>(First)) {
+    assert(!FirstPHITranslatedAddr &&
+           !SecondPHITranslatedAddr &&
+           "PHI translation with calls not supported yet!");
+
     // If both instructions are calls/invokes we can use the two-callsite
     // form of getModRefInfo.
     if (ImmutableCallSite SecondCS = cast<Value>(Second))
index 597e34b55eb30422820c6b6d21b912a2277ca9e6..354e66df0c03a9693877b662e0522eb59c09fb3c 100644 (file)
@@ -172,8 +172,10 @@ namespace {
     }
 
     virtual DependenceResult getDependence(const Instruction *First,
+                                           const Value *FirstPHITranslatedAddr,
                                            DependenceQueryFlags FirstFlags,
                                            const Instruction *Second,
+                                           const Value *SecondPHITranslatedAddr,
                                            DependenceQueryFlags SecondFlags) {
       return Unknown;
     }
@@ -531,8 +533,10 @@ namespace {
     virtual ModRefBehavior getModRefBehavior(const Function *F);
 
     virtual DependenceResult getDependence(const Instruction *First,
+                                           const Value *FirstPHITranslatedAddr,
                                            DependenceQueryFlags FirstFlags,
                                            const Instruction *Second,
+                                           const Value *SecondPHITranslatedAddr,
                                            DependenceQueryFlags SecondFlags);
 
     /// getAdjustedAnalysisPointer - This method is used when a pass implements
@@ -748,11 +752,14 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
 
 AliasAnalysis::DependenceResult
 BasicAliasAnalysis::getDependence(const Instruction *First,
+                                  const Value *FirstPHITranslatedAddr,
                                   DependenceQueryFlags FirstFlags,
                                   const Instruction *Second,
+                                  const Value *SecondPHITranslatedAddr,
                                   DependenceQueryFlags SecondFlags) {
   // We don't have anything special to say yet.
-  return getDependenceViaModRefInfo(First, FirstFlags, Second, SecondFlags);
+  return getDependenceViaModRefInfo(First, FirstPHITranslatedAddr, FirstFlags,
+                                    Second, SecondPHITranslatedAddr, SecondFlags);
 }
 
 /// aliasGEP - Provide a bunch of ad-hoc rules to disambiguate a GEP instruction