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

Owen Anderson resistor at mac.com
Sat Sep 2 14:19:59 PDT 2006



Changes in directory llvm/lib/Transforms/IPO:

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

Make ArgumentPromotion handle recursive functions that pass pointers in their recursive calls.


---
Diffs of the changes:  (+33 -11)

 ArgumentPromotion.cpp |   44 +++++++++++++++++++++++++++++++++-----------
 1 files changed, 33 insertions(+), 11 deletions(-)


Index: llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
diff -u llvm/lib/Transforms/IPO/ArgumentPromotion.cpp:1.22 llvm/lib/Transforms/IPO/ArgumentPromotion.cpp:1.23
--- llvm/lib/Transforms/IPO/ArgumentPromotion.cpp:1.22	Sun Aug 27 17:42:52 2006
+++ llvm/lib/Transforms/IPO/ArgumentPromotion.cpp	Sat Sep  2 16:19:44 2006
@@ -186,6 +186,8 @@
 /// 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;
@@ -240,6 +242,25 @@
         }
         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.
     }
@@ -264,8 +285,7 @@
   // 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) {
@@ -360,15 +380,17 @@
       for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E;
            ++UI) {
         Instruction *User = cast<Instruction>(*UI);
-        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;
+        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;
+        }
       }
 
       // Add a parameter to the function for each element passed in.






More information about the llvm-commits mailing list