summaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorStephen Lin <stephenwlin@gmail.com>2013-04-20 05:14:40 +0000
committerStephen Lin <stephenwlin@gmail.com>2013-04-20 05:14:40 +0000
commit456ca048af35163b9f52187e92a23ee0a9f059e8 (patch)
treef7b4d4711424b927d5b323a9e4ef4d97742beeb4 /lib/CodeGen
parent5c34e08b9fff9d4df2421e4f41ff15b85f638dd1 (diff)
downloadllvm-456ca048af35163b9f52187e92a23ee0a9f059e8.tar.gz
llvm-456ca048af35163b9f52187e92a23ee0a9f059e8.tar.bz2
llvm-456ca048af35163b9f52187e92a23ee0a9f059e8.tar.xz
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')
-rw-r--r--lib/CodeGen/Analysis.cpp26
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp18
2 files changed, 37 insertions, 7 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;
+ }
+ }
}
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index ce40cd6a0c..c1c8be4387 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -5232,6 +5232,7 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee,
Entry.isSRet = true;
Entry.isNest = false;
Entry.isByVal = false;
+ Entry.isReturned = false;
Entry.Alignment = Align;
Args.push_back(Entry);
RetTy = Type::getVoidTy(FTy->getContext());
@@ -5249,13 +5250,14 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee,
Entry.Node = ArgNode; Entry.Ty = V->getType();
unsigned attrInd = i - CS.arg_begin() + 1;
- Entry.isSExt = CS.paramHasAttr(attrInd, Attribute::SExt);
- Entry.isZExt = CS.paramHasAttr(attrInd, Attribute::ZExt);
- Entry.isInReg = CS.paramHasAttr(attrInd, Attribute::InReg);
- Entry.isSRet = CS.paramHasAttr(attrInd, Attribute::StructRet);
- Entry.isNest = CS.paramHasAttr(attrInd, Attribute::Nest);
- Entry.isByVal = CS.paramHasAttr(attrInd, Attribute::ByVal);
- Entry.Alignment = CS.getParamAlignment(attrInd);
+ Entry.isSExt = CS.paramHasAttr(attrInd, Attribute::SExt);
+ Entry.isZExt = CS.paramHasAttr(attrInd, Attribute::ZExt);
+ Entry.isInReg = CS.paramHasAttr(attrInd, Attribute::InReg);
+ Entry.isSRet = CS.paramHasAttr(attrInd, Attribute::StructRet);
+ Entry.isNest = CS.paramHasAttr(attrInd, Attribute::Nest);
+ Entry.isByVal = CS.paramHasAttr(attrInd, Attribute::ByVal);
+ Entry.isReturned = CS.paramHasAttr(attrInd, Attribute::Returned);
+ Entry.Alignment = CS.getParamAlignment(attrInd);
Args.push_back(Entry);
}
@@ -6430,6 +6432,8 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
}
if (Args[i].isNest)
Flags.setNest();
+ if (Args[i].isReturned)
+ Flags.setReturned();
Flags.setOrigAlign(OriginalAlignment);
MVT PartVT = getRegisterType(CLI.RetTy->getContext(), VT);