llvm.org GIT mirror llvm / b833e5a
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 Owen Anderson 13 years ago
2 changed file(s) with 49 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
185185 /// elements of the aggregate in order to avoid exploding the number of
186186 /// arguments passed in.
187187 bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg) const {
188 AliasAnalysis &AA = getAnalysis();
189
188190 // We can only promote this argument if all of the uses are loads, or are GEP
189191 // instructions (with constant indices) that are subsequently loaded.
190192 bool HasLoadInEntryBlock = false;
239241 }
240242 GEPIndices.push_back(Operands);
241243 }
244 } else if (CallInst* CI = dyn_cast(*UI)) {
245 // Is this a recursive call?
246 if (CI->getCalledFunction() != Arg->getParent())
247 return false;
248
249 // Find out what position argument we're dealing with.
250 unsigned Position = 0;
251 Function::arg_iterator ArgPos = Arg->getParent()->arg_begin();
252 while (Arg != ArgPos) {
253 assert(ArgPos != Arg->getParent()->arg_end() &&
254 "Arg not in parent's arg list?");
255 Position++;
256 ArgPos++;
257 }
258
259 // We only know that the call is safe if it's passing the argument in
260 // the same position that it came in at.
261 if (UI.getOperandNo() != Position+1)
262 return false;
242263 } else {
243264 return false; // Not a load or a GEP.
244265 }
263284 // Because there could be several/many load instructions, remember which
264285 // blocks we know to be transparent to the load.
265286 std::set TranspBlocks;
266
267 AliasAnalysis &AA = getAnalysis();
287
268288 TargetData &TD = getAnalysis();
269289
270290 for (unsigned i = 0, e = Loads.size(); i != e; ++i) {
359379 for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E;
360380 ++UI) {
361381 Instruction *User = cast(*UI);
362 assert(isa(User) || isa(User));
363 std::vector Indices(User->op_begin()+1, User->op_end());
364 ArgIndices.insert(Indices);
365 LoadInst *OrigLoad;
366 if (LoadInst *L = dyn_cast(User))
367 OrigLoad = L;
368 else
369 OrigLoad = cast(User->use_back());
370 OriginalLoads[Indices] = OrigLoad;
382 if (!isa(User)) {
383 assert(isa(User) || isa(User));
384 std::vector Indices(User->op_begin()+1, User->op_end());
385 ArgIndices.insert(Indices);
386 LoadInst *OrigLoad;
387 if (LoadInst *L = dyn_cast(User))
388 OrigLoad = L;
389 else
390 OrigLoad = cast(User->use_back());
391 OriginalLoads[Indices] = OrigLoad;
392 }
371393 }
372394
373395 // Add a parameter to the function for each element passed in.
0 ; RUN: llvm-as < %s | opt -argpromotion | llvm-dis | grep x.val
1 ; ModuleID = 'recursive2.bc'
2
3 implementation ; Functions:
4
5 internal int %foo(int* %x) {
6 entry:
7 %tmp.foo = load int* %x
8 ret int %tmp.foo
9 }
10
11 int %bar(int* %x) {
12 entry:
13 %tmp3 = call int %foo( int* %x) ; [#uses=1]
14 ret int %tmp3
15 }