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/IR/Verifier.cpp | |
parent | 5c34e08b9fff9d4df2421e4f41ff15b85f638dd1 (diff) | |
download | external_llvm-456ca048af35163b9f52187e92a23ee0a9f059e8.zip external_llvm-456ca048af35163b9f52187e92a23ee0a9f059e8.tar.gz external_llvm-456ca048af35163b9f52187e92a23ee0a9f059e8.tar.bz2 |
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/IR/Verifier.cpp')
-rw-r--r-- | lib/IR/Verifier.cpp | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index ec01edf..69cb5dc 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -694,8 +694,9 @@ void Verifier::VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty, Assert1(!Attrs.hasAttribute(Idx, Attribute::ByVal) && !Attrs.hasAttribute(Idx, Attribute::Nest) && !Attrs.hasAttribute(Idx, Attribute::StructRet) && - !Attrs.hasAttribute(Idx, Attribute::NoCapture), - "Attribute 'byval', 'nest', 'sret', and 'nocapture' " + !Attrs.hasAttribute(Idx, Attribute::NoCapture) && + !Attrs.hasAttribute(Idx, Attribute::Returned), + "Attribute 'byval', 'nest', 'sret', 'nocapture', and 'returned' " "do not apply to return values!", V); // Check for mutually incompatible attributes. @@ -750,6 +751,7 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, return; bool SawNest = false; + bool SawReturned = false; for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) { unsigned Idx = Attrs.getSlotIndex(i); @@ -764,11 +766,22 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, VerifyParameterAttrs(Attrs, Idx, Ty, Idx == 0, V); - if (Attrs.hasAttribute(i, Attribute::Nest)) { + if (Idx == 0) + continue; + + if (Attrs.hasAttribute(Idx, Attribute::Nest)) { Assert1(!SawNest, "More than one parameter has attribute nest!", V); SawNest = true; } + if (Attrs.hasAttribute(Idx, Attribute::Returned)) { + Assert1(!SawReturned, "More than one parameter has attribute returned!", + V); + Assert1(Ty->canLosslesslyBitCastTo(FT->getReturnType()), "Incompatible " + "argument and return types for 'returned' attribute", V); + SawReturned = true; + } + if (Attrs.hasAttribute(Idx, Attribute::StructRet)) Assert1(Idx == 1, "Attribute sret is not on first parameter!", V); } @@ -1348,15 +1361,41 @@ void Verifier::VerifyCallSite(CallSite CS) { // Verify call attributes. VerifyFunctionAttrs(FTy, Attrs, I); - if (FTy->isVarArg()) + if (FTy->isVarArg()) { + // FIXME? is 'nest' even legal here? + bool SawNest = false; + bool SawReturned = false; + + for (unsigned Idx = 1; Idx < 1 + FTy->getNumParams(); ++Idx) { + if (Attrs.hasAttribute(Idx, Attribute::Nest)) + SawNest = true; + if (Attrs.hasAttribute(Idx, Attribute::Returned)) + SawReturned = true; + } + // Check attributes on the varargs part. for (unsigned Idx = 1 + FTy->getNumParams(); Idx <= CS.arg_size(); ++Idx) { - VerifyParameterAttrs(Attrs, Idx, CS.getArgument(Idx-1)->getType(), - false, I); + Type *Ty = CS.getArgument(Idx-1)->getType(); + VerifyParameterAttrs(Attrs, Idx, Ty, false, I); + + if (Attrs.hasAttribute(Idx, Attribute::Nest)) { + Assert1(!SawNest, "More than one parameter has attribute nest!", I); + SawNest = true; + } + + if (Attrs.hasAttribute(Idx, Attribute::Returned)) { + Assert1(!SawReturned, "More than one parameter has attribute returned!", + I); + Assert1(Ty->canLosslesslyBitCastTo(FTy->getReturnType()), + "Incompatible argument and return types for 'returned' " + "attribute", I); + SawReturned = true; + } Assert1(!Attrs.hasAttribute(Idx, Attribute::StructRet), "Attribute 'sret' cannot be used for vararg call arguments!", I); } + } // Verify that there's no metadata unless it's a direct call to an intrinsic. if (CS.getCalledFunction() == 0 || |