[llvm-commits] CVS: llvm/lib/Transforms/IPO/ArgumentPromotion.cpp

Owen Anderson resistor at mac.com
Thu Sep 14 22:23:05 PDT 2006



Changes in directory llvm/lib/Transforms/IPO:

ArgumentPromotion.cpp updated: 1.23 -> 1.24
---
Log message:

Revert my previous work on ArgumentPromotion.  Further investigation has revealed these
changes to be incorrect.  They just weren't showing up in any of our current testcases.


---
Diffs of the changes:  (+46 -34)

 ArgumentPromotion.cpp |   80 ++++++++++++++++++++++++++++----------------------
 1 files changed, 46 insertions(+), 34 deletions(-)


Index: llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
diff -u llvm/lib/Transforms/IPO/ArgumentPromotion.cpp:1.23 llvm/lib/Transforms/IPO/ArgumentPromotion.cpp:1.24
--- llvm/lib/Transforms/IPO/ArgumentPromotion.cpp:1.23	Sat Sep  2 16:19:44 2006
+++ llvm/lib/Transforms/IPO/ArgumentPromotion.cpp	Fri Sep 15 00:22:51 2006
@@ -179,6 +179,40 @@
   return true;
 }
 
+/// AccessOccursOnPath - Returns true if and only if a load or GEP instruction
+/// on Pointer occurs in Path, or in every control-flow path that succeeds it.
+bool AccessOccursOnPath(Argument* Arg) {
+  std::vector<BasicBlock*> Worklist;
+  Worklist.push_back(Arg->getParent()->begin());
+  
+  std::set<BasicBlock*> Visited;
+  
+  while (!Worklist.empty()) {
+    BasicBlock* BB = Worklist.back();
+    Worklist.pop_back();
+    Visited.insert(BB);
+    
+    bool ContainsAccess = false;
+    for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
+      if (isa<LoadInst>(I) || isa<GetElementPtrInst>(I)) {
+        ContainsAccess = true;
+        break;
+      }
+    
+    if (ContainsAccess) continue;
+    
+    TerminatorInst* TI = BB->getTerminator();
+    if (isa<BranchInst>(TI) || isa<SwitchInst>(TI)) {
+      for (unsigned i = 0; i < TI->getNumSuccessors(); ++i)
+        if (!Visited.count(TI->getSuccessor(i)))
+          Worklist.push_back(TI->getSuccessor(i));
+    } else {
+      return false;
+    }
+  }
+  
+  return true;
+}
 
 /// isSafeToPromoteArgument - As you might guess from the name of this method,
 /// it checks to see if it is both safe and useful to promote the argument.
@@ -186,8 +220,6 @@
 /// elements of the aggregate in order to avoid exploding the number of
 /// arguments passed in.
 bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg) const {
-  AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
-
   // We can only promote this argument if all of the uses are loads, or are GEP
   // instructions (with constant indices) that are subsequently loaded.
   bool HasLoadInEntryBlock = false;
@@ -242,25 +274,6 @@
         }
         GEPIndices.push_back(Operands);
       }
-    } else if (CallInst* CI = dyn_cast<CallInst>(*UI)) {
-      // Is this a recursive call?
-      if (CI->getCalledFunction() != Arg->getParent())
-        return false;
-      
-      // Find out what position argument we're dealing with.
-      unsigned Position = 0;
-      Function::arg_iterator ArgPos = Arg->getParent()->arg_begin();
-      while (Arg != ArgPos) {
-        assert(ArgPos != Arg->getParent()->arg_end() &&
-               "Arg not in parent's arg list?");
-        Position++;
-        ArgPos++;
-      }
-      
-      // We only know that the call is safe if it's passing the argument in
-      // the same position that it came in at.
-      if (UI.getOperandNo() != Position+1)
-        return false;
     } else {
       return false;  // Not a load or a GEP.
     }
@@ -273,7 +286,7 @@
   // of the pointer in the entry block of the function) or if we can prove that
   // all pointers passed in are always to legal locations (for example, no null
   // pointers are passed in, no pointers to free'd memory, etc).
-  if (!HasLoadInEntryBlock && !AllCalleesPassInValidPointerForArgument(Arg))
+  if (!AccessOccursOnPath(Arg) && !AllCalleesPassInValidPointerForArgument(Arg))
     return false;   // Cannot prove that this is safe!!
 
   // Okay, now we know that the argument is only used by load instructions and
@@ -285,7 +298,8 @@
   // Because there could be several/many load instructions, remember which
   // blocks we know to be transparent to the load.
   std::set<BasicBlock*> TranspBlocks;
-  
+
+  AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
   TargetData &TD = getAnalysis<TargetData>();
 
   for (unsigned i = 0, e = Loads.size(); i != e; ++i) {
@@ -380,17 +394,15 @@
       for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E;
            ++UI) {
         Instruction *User = cast<Instruction>(*UI);
-        if (!isa<CallInst>(User)) {
-          assert(isa<LoadInst>(User) || isa<GetElementPtrInst>(User));
-          std::vector<Value*> Indices(User->op_begin()+1, User->op_end());
-          ArgIndices.insert(Indices);
-          LoadInst *OrigLoad;
-          if (LoadInst *L = dyn_cast<LoadInst>(User))
-            OrigLoad = L;
-          else
-            OrigLoad = cast<LoadInst>(User->use_back());
-          OriginalLoads[Indices] = OrigLoad;
-        }
+        assert(isa<LoadInst>(User) || isa<GetElementPtrInst>(User));
+        std::vector<Value*> Indices(User->op_begin()+1, User->op_end());
+        ArgIndices.insert(Indices);
+        LoadInst *OrigLoad;
+        if (LoadInst *L = dyn_cast<LoadInst>(User))
+          OrigLoad = L;
+        else
+          OrigLoad = cast<LoadInst>(User->use_back());
+        OriginalLoads[Indices] = OrigLoad;
       }
 
       // Add a parameter to the function for each element passed in.






More information about the llvm-commits mailing list