mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-13 22:24:07 +00:00
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
This commit is contained in:
@ -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 ||
|
||||
|
Reference in New Issue
Block a user