diff options
author | Owen Anderson <resistor@mac.com> | 2006-09-02 21:19:44 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2006-09-02 21:19:44 +0000 |
commit | b833e5ac3fc9230947cbdfd50c7d8782a0c17d60 (patch) | |
tree | c62d141a5788fc27f5ee5e9e10c9d9b6c4c99ffa /lib | |
parent | 5f450d2948ac5bd83a31fbfff89e17b0e2536a80 (diff) |
Make ArgumentPromotion handle recursive functions that pass pointers in their recursive calls.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30057 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/IPO/ArgumentPromotion.cpp | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp index 5183d43bc7..fb9090327d 100644 --- a/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -186,6 +186,8 @@ static bool AllCalleesPassInValidPointerForArgument(Argument *Arg) { /// 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 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg) const { } 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 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg) const { // 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 @@ Function *ArgPromotion::DoPromotion(Function *F, 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. |