[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