mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-19 08:24:12 +00:00
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
This commit is contained in:
parent
5f450d2948
commit
b833e5ac3f
@ -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.
|
||||
|
16
test/Transforms/ArgumentPromotion/recursion.ll
Normal file
16
test/Transforms/ArgumentPromotion/recursion.ll
Normal file
@ -0,0 +1,16 @@
|
||||
; RUN: llvm-as < %s | opt -argpromotion | llvm-dis | grep x.val
|
||||
; ModuleID = 'recursive2.bc'
|
||||
|
||||
implementation ; Functions:
|
||||
|
||||
internal int %foo(int* %x) {
|
||||
entry:
|
||||
%tmp.foo = load int* %x
|
||||
ret int %tmp.foo
|
||||
}
|
||||
|
||||
int %bar(int* %x) {
|
||||
entry:
|
||||
%tmp3 = call int %foo( int* %x) ; <int>[#uses=1]
|
||||
ret int %tmp3
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user