From 46f022a7f105211d5ea2c394e406d1943b80908c Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Fri, 15 Sep 2006 05:22:51 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30385 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/ArgumentPromotion.cpp | 80 ++++++++++++++---------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp index fb9090327d1..a929df05d88 100644 --- a/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -179,6 +179,40 @@ static bool AllCalleesPassInValidPointerForArgument(Argument *Arg) { 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 Worklist; + Worklist.push_back(Arg->getParent()->begin()); + + std::set 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(I) || isa(I)) { + ContainsAccess = true; + break; + } + + if (ContainsAccess) continue; + + TerminatorInst* TI = BB->getTerminator(); + if (isa(TI) || isa(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 @@ 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(); - // 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 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg) const { } GEPIndices.push_back(Operands); } - } else if (CallInst* CI = dyn_cast(*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 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg) const { // 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 @@ 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 TranspBlocks; - + + AliasAnalysis &AA = getAnalysis(); TargetData &TD = getAnalysis(); for (unsigned i = 0, e = Loads.size(); i != e; ++i) { @@ -380,17 +394,15 @@ Function *ArgPromotion::DoPromotion(Function *F, for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) { Instruction *User = cast(*UI); - if (!isa(User)) { - assert(isa(User) || isa(User)); - std::vector Indices(User->op_begin()+1, User->op_end()); - ArgIndices.insert(Indices); - LoadInst *OrigLoad; - if (LoadInst *L = dyn_cast(User)) - OrigLoad = L; - else - OrigLoad = cast(User->use_back()); - OriginalLoads[Indices] = OrigLoad; - } + assert(isa(User) || isa(User)); + std::vector Indices(User->op_begin()+1, User->op_end()); + ArgIndices.insert(Indices); + LoadInst *OrigLoad; + if (LoadInst *L = dyn_cast(User)) + OrigLoad = L; + else + OrigLoad = cast(User->use_back()); + OriginalLoads[Indices] = OrigLoad; } // Add a parameter to the function for each element passed in. -- 2.34.1