diff options
author | Stephen Lin <stephenwlin@gmail.com> | 2013-04-20 05:14:40 +0000 |
---|---|---|
committer | Stephen Lin <stephenwlin@gmail.com> | 2013-04-20 05:14:40 +0000 |
commit | 456ca048af35163b9f52187e92a23ee0a9f059e8 (patch) | |
tree | f7b4d4711424b927d5b323a9e4ef4d97742beeb4 /lib/CodeGen/Analysis.cpp | |
parent | 5c34e08b9fff9d4df2421e4f41ff15b85f638dd1 (diff) |
Add CodeGen support for functions that always return arguments via a new parameter attribute 'returned', which is taken advantage of in target-independent tail call opportunity detection and in ARM call lowering (when placed on an integral first parameter).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179925 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/Analysis.cpp')
-rw-r--r-- | lib/CodeGen/Analysis.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/lib/CodeGen/Analysis.cpp b/lib/CodeGen/Analysis.cpp index 9723f8080c..4731af5089 100644 --- a/lib/CodeGen/Analysis.cpp +++ b/lib/CodeGen/Analysis.cpp @@ -261,6 +261,32 @@ static bool sameNoopInput(const Value *V1, const Value *V2, TLI.getPointerTy().getSizeInBits() == cast<IntegerType>(I->getType())->getBitWidth()) NoopInput = Op; + } else if (isa<CallInst>(I)) { + // Look through call + for (User::const_op_iterator i = I->op_begin(), + // Skip Callee + e = I->op_end() - 1; + i != e; ++i) { + unsigned attrInd = i - I->op_begin() + 1; + if (cast<CallInst>(I)->paramHasAttr(attrInd, Attribute::Returned) && + isNoopBitcast((*i)->getType(), I->getType(), TLI)) { + NoopInput = *i; + break; + } + } + } else if (isa<InvokeInst>(I)) { + // Look through invoke + for (User::const_op_iterator i = I->op_begin(), + // Skip BB, BB, Callee + e = I->op_end() - 3; + i != e; ++i) { + unsigned attrInd = i - I->op_begin() + 1; + if (cast<InvokeInst>(I)->paramHasAttr(attrInd, Attribute::Returned) && + isNoopBitcast((*i)->getType(), I->getType(), TLI)) { + NoopInput = *i; + break; + } + } } } |