Skip to content

Commit 0150493

Browse files
committed
Try to implement lambdas with inalloca parameters by forwarding without use of inallocas.
Differential Revision: https://reviews.llvm.org/D137872
1 parent 72df12c commit 0150493

File tree

11 files changed

+297
-127
lines changed

11 files changed

+297
-127
lines changed

clang/include/clang/CodeGen/CGFunctionInfo.h

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,10 @@ class CGFunctionInfo final
567567
/// Whether this is a chain call.
568568
unsigned ChainCall : 1;
569569

570+
/// Whether this function is called by forwarding arguments.
571+
/// This doesn't support inalloca or varargs.
572+
unsigned DelegateCall : 1;
573+
570574
/// Whether this function is a CMSE nonsecure call
571575
unsigned CmseNSCall : 1;
572576

@@ -616,14 +620,11 @@ class CGFunctionInfo final
616620
CGFunctionInfo() : Required(RequiredArgs::All) {}
617621

618622
public:
619-
static CGFunctionInfo *create(unsigned llvmCC,
620-
bool instanceMethod,
621-
bool chainCall,
622-
const FunctionType::ExtInfo &extInfo,
623-
ArrayRef<ExtParameterInfo> paramInfos,
624-
CanQualType resultType,
625-
ArrayRef<CanQualType> argTypes,
626-
RequiredArgs required);
623+
static CGFunctionInfo *
624+
create(unsigned llvmCC, bool instanceMethod, bool chainCall,
625+
bool delegateCall, const FunctionType::ExtInfo &extInfo,
626+
ArrayRef<ExtParameterInfo> paramInfos, CanQualType resultType,
627+
ArrayRef<CanQualType> argTypes, RequiredArgs required);
627628
void operator delete(void *p) { ::operator delete(p); }
628629

629630
// Friending class TrailingObjects is apparently not good enough for MSVC,
@@ -663,6 +664,8 @@ class CGFunctionInfo final
663664

664665
bool isChainCall() const { return ChainCall; }
665666

667+
bool isDelegateCall() const { return DelegateCall; }
668+
666669
bool isCmseNSCall() const { return CmseNSCall; }
667670

668671
bool isNoReturn() const { return NoReturn; }
@@ -749,6 +752,7 @@ class CGFunctionInfo final
749752
ID.AddInteger(getASTCallingConvention());
750753
ID.AddBoolean(InstanceMethod);
751754
ID.AddBoolean(ChainCall);
755+
ID.AddBoolean(DelegateCall);
752756
ID.AddBoolean(NoReturn);
753757
ID.AddBoolean(ReturnsRetained);
754758
ID.AddBoolean(NoCallerSavedRegs);
@@ -766,17 +770,16 @@ class CGFunctionInfo final
766770
for (const auto &I : arguments())
767771
I.type.Profile(ID);
768772
}
769-
static void Profile(llvm::FoldingSetNodeID &ID,
770-
bool InstanceMethod,
771-
bool ChainCall,
773+
static void Profile(llvm::FoldingSetNodeID &ID, bool InstanceMethod,
774+
bool ChainCall, bool IsDelegateCall,
772775
const FunctionType::ExtInfo &info,
773776
ArrayRef<ExtParameterInfo> paramInfos,
774-
RequiredArgs required,
775-
CanQualType resultType,
777+
RequiredArgs required, CanQualType resultType,
776778
ArrayRef<CanQualType> argTypes) {
777779
ID.AddInteger(info.getCC());
778780
ID.AddBoolean(InstanceMethod);
779781
ID.AddBoolean(ChainCall);
782+
ID.AddBoolean(IsDelegateCall);
780783
ID.AddBoolean(info.getNoReturn());
781784
ID.AddBoolean(info.getProducesResult());
782785
ID.AddBoolean(info.getNoCallerSavedRegs());

clang/lib/CodeGen/CGCall.cpp

Lines changed: 69 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,7 @@ CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> FTNP) {
111111
// When translating an unprototyped function type, always use a
112112
// variadic type.
113113
return arrangeLLVMFunctionInfo(FTNP->getReturnType().getUnqualifiedType(),
114-
/*instanceMethod=*/false,
115-
/*chainCall=*/false, std::nullopt,
114+
FnInfoOpts::None, std::nullopt,
116115
FTNP->getExtInfo(), {}, RequiredArgs(0));
117116
}
118117

@@ -188,10 +187,10 @@ arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool instanceMethod,
188187
appendParameterTypes(CGT, prefix, paramInfos, FTP);
189188
CanQualType resultType = FTP->getReturnType().getUnqualifiedType();
190189

191-
return CGT.arrangeLLVMFunctionInfo(resultType, instanceMethod,
192-
/*chainCall=*/false, prefix,
193-
FTP->getExtInfo(), paramInfos,
194-
Required);
190+
FnInfoOpts opts =
191+
instanceMethod ? FnInfoOpts::IsInstanceMethod : FnInfoOpts::None;
192+
return CGT.arrangeLLVMFunctionInfo(resultType, opts, prefix,
193+
FTP->getExtInfo(), paramInfos, Required);
195194
}
196195

197196
/// Arrange the argument and result information for a value of the
@@ -270,7 +269,7 @@ CodeGenTypes::arrangeCXXMethodType(const CXXRecordDecl *RD,
270269
argTypes.push_back(DeriveThisType(RD, MD));
271270

272271
return ::arrangeLLVMFunctionInfo(
273-
*this, true, argTypes,
272+
*this, /*instanceMethod=*/true, argTypes,
274273
FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>());
275274
}
276275

@@ -362,9 +361,8 @@ CodeGenTypes::arrangeCXXStructorDeclaration(GlobalDecl GD) {
362361
: TheCXXABI.hasMostDerivedReturn(GD)
363362
? CGM.getContext().VoidPtrTy
364363
: Context.VoidTy;
365-
return arrangeLLVMFunctionInfo(resultType, /*instanceMethod=*/true,
366-
/*chainCall=*/false, argTypes, extInfo,
367-
paramInfos, required);
364+
return arrangeLLVMFunctionInfo(resultType, FnInfoOpts::IsInstanceMethod,
365+
argTypes, extInfo, paramInfos, required);
368366
}
369367

370368
static SmallVector<CanQualType, 16>
@@ -438,9 +436,9 @@ CodeGenTypes::arrangeCXXConstructorCall(const CallArgList &args,
438436
addExtParameterInfosForCall(ParamInfos, FPT.getTypePtr(), TotalPrefixArgs,
439437
ArgTypes.size());
440438
}
441-
return arrangeLLVMFunctionInfo(ResultType, /*instanceMethod=*/true,
442-
/*chainCall=*/false, ArgTypes, Info,
443-
ParamInfos, Required);
439+
440+
return arrangeLLVMFunctionInfo(ResultType, FnInfoOpts::IsInstanceMethod,
441+
ArgTypes, Info, ParamInfos, Required);
444442
}
445443

446444
/// Arrange the argument and result information for the declaration or
@@ -459,10 +457,9 @@ CodeGenTypes::arrangeFunctionDeclaration(const FunctionDecl *FD) {
459457
// When declaring a function without a prototype, always use a
460458
// non-variadic type.
461459
if (CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>()) {
462-
return arrangeLLVMFunctionInfo(
463-
noProto->getReturnType(), /*instanceMethod=*/false,
464-
/*chainCall=*/false, std::nullopt, noProto->getExtInfo(), {},
465-
RequiredArgs::All);
460+
return arrangeLLVMFunctionInfo(noProto->getReturnType(), FnInfoOpts::None,
461+
std::nullopt, noProto->getExtInfo(), {},
462+
RequiredArgs::All);
466463
}
467464

468465
return arrangeFreeFunctionType(FTy.castAs<FunctionProtoType>());
@@ -511,9 +508,9 @@ CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD,
511508
RequiredArgs required =
512509
(MD->isVariadic() ? RequiredArgs(argTys.size()) : RequiredArgs::All);
513510

514-
return arrangeLLVMFunctionInfo(
515-
GetReturnType(MD->getReturnType()), /*instanceMethod=*/false,
516-
/*chainCall=*/false, argTys, einfo, extParamInfos, required);
511+
return arrangeLLVMFunctionInfo(GetReturnType(MD->getReturnType()),
512+
FnInfoOpts::None, argTys, einfo, extParamInfos,
513+
required);
517514
}
518515

519516
const CGFunctionInfo &
@@ -522,9 +519,8 @@ CodeGenTypes::arrangeUnprototypedObjCMessageSend(QualType returnType,
522519
auto argTypes = getArgTypesForCall(Context, args);
523520
FunctionType::ExtInfo einfo;
524521

525-
return arrangeLLVMFunctionInfo(
526-
GetReturnType(returnType), /*instanceMethod=*/false,
527-
/*chainCall=*/false, argTypes, einfo, {}, RequiredArgs::All);
522+
return arrangeLLVMFunctionInfo(GetReturnType(returnType), FnInfoOpts::None,
523+
argTypes, einfo, {}, RequiredArgs::All);
528524
}
529525

530526
const CGFunctionInfo &
@@ -549,8 +545,7 @@ CodeGenTypes::arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD) {
549545
assert(MD->isVirtual() && "only methods have thunks");
550546
CanQual<FunctionProtoType> FTP = GetFormalType(MD);
551547
CanQualType ArgTys[] = {DeriveThisType(MD->getParent(), MD)};
552-
return arrangeLLVMFunctionInfo(Context.VoidTy, /*instanceMethod=*/false,
553-
/*chainCall=*/false, ArgTys,
548+
return arrangeLLVMFunctionInfo(Context.VoidTy, FnInfoOpts::None, ArgTys,
554549
FTP->getExtInfo(), {}, RequiredArgs(1));
555550
}
556551

@@ -569,9 +564,8 @@ CodeGenTypes::arrangeMSCtorClosure(const CXXConstructorDecl *CD,
569564
ArgTys.push_back(Context.IntTy);
570565
CallingConv CC = Context.getDefaultCallingConvention(
571566
/*IsVariadic=*/false, /*IsCXXMethod=*/true);
572-
return arrangeLLVMFunctionInfo(Context.VoidTy, /*instanceMethod=*/true,
573-
/*chainCall=*/false, ArgTys,
574-
FunctionType::ExtInfo(CC), {},
567+
return arrangeLLVMFunctionInfo(Context.VoidTy, FnInfoOpts::IsInstanceMethod,
568+
ArgTys, FunctionType::ExtInfo(CC), {},
575569
RequiredArgs::All);
576570
}
577571

@@ -615,10 +609,10 @@ arrangeFreeFunctionLikeCall(CodeGenTypes &CGT,
615609
SmallVector<CanQualType, 16> argTypes;
616610
for (const auto &arg : args)
617611
argTypes.push_back(CGT.getContext().getCanonicalParamType(arg.Ty));
612+
FnInfoOpts opts = chainCall ? FnInfoOpts::IsChainCall : FnInfoOpts::None;
618613
return CGT.arrangeLLVMFunctionInfo(GetReturnType(fnType->getReturnType()),
619-
/*instanceMethod=*/false, chainCall,
620-
argTypes, fnType->getExtInfo(), paramInfos,
621-
required);
614+
opts, argTypes, fnType->getExtInfo(),
615+
paramInfos, required);
622616
}
623617

624618
/// Figure out the rules for calling a function with the given formal
@@ -649,8 +643,8 @@ CodeGenTypes::arrangeBlockFunctionDeclaration(const FunctionProtoType *proto,
649643
auto argTypes = getArgTypesForDeclaration(Context, params);
650644

651645
return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
652-
/*instanceMethod*/ false, /*chainCall*/ false,
653-
argTypes, proto->getExtInfo(), paramInfos,
646+
FnInfoOpts::None, argTypes,
647+
proto->getExtInfo(), paramInfos,
654648
RequiredArgs::forPrototypePlus(proto, 1));
655649
}
656650

@@ -661,28 +655,27 @@ CodeGenTypes::arrangeBuiltinFunctionCall(QualType resultType,
661655
SmallVector<CanQualType, 16> argTypes;
662656
for (const auto &Arg : args)
663657
argTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
664-
return arrangeLLVMFunctionInfo(
665-
GetReturnType(resultType), /*instanceMethod=*/false,
666-
/*chainCall=*/false, argTypes, FunctionType::ExtInfo(),
667-
/*paramInfos=*/ {}, RequiredArgs::All);
658+
return arrangeLLVMFunctionInfo(GetReturnType(resultType), FnInfoOpts::None,
659+
argTypes, FunctionType::ExtInfo(),
660+
/*paramInfos=*/{}, RequiredArgs::All);
668661
}
669662

670663
const CGFunctionInfo &
671664
CodeGenTypes::arrangeBuiltinFunctionDeclaration(QualType resultType,
672665
const FunctionArgList &args) {
673666
auto argTypes = getArgTypesForDeclaration(Context, args);
674667

675-
return arrangeLLVMFunctionInfo(
676-
GetReturnType(resultType), /*instanceMethod=*/false, /*chainCall=*/false,
677-
argTypes, FunctionType::ExtInfo(), {}, RequiredArgs::All);
668+
return arrangeLLVMFunctionInfo(GetReturnType(resultType), FnInfoOpts::None,
669+
argTypes, FunctionType::ExtInfo(), {},
670+
RequiredArgs::All);
678671
}
679672

680673
const CGFunctionInfo &
681674
CodeGenTypes::arrangeBuiltinFunctionDeclaration(CanQualType resultType,
682675
ArrayRef<CanQualType> argTypes) {
683-
return arrangeLLVMFunctionInfo(
684-
resultType, /*instanceMethod=*/false, /*chainCall=*/false,
685-
argTypes, FunctionType::ExtInfo(), {}, RequiredArgs::All);
676+
return arrangeLLVMFunctionInfo(resultType, FnInfoOpts::None, argTypes,
677+
FunctionType::ExtInfo(), {},
678+
RequiredArgs::All);
686679
}
687680

688681
/// Arrange a call to a C++ method, passing the given arguments.
@@ -705,15 +698,15 @@ CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args,
705698
auto argTypes = getArgTypesForCall(Context, args);
706699

707700
FunctionType::ExtInfo info = proto->getExtInfo();
708-
return arrangeLLVMFunctionInfo(
709-
GetReturnType(proto->getReturnType()), /*instanceMethod=*/true,
710-
/*chainCall=*/false, argTypes, info, paramInfos, required);
701+
return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
702+
FnInfoOpts::IsInstanceMethod, argTypes, info,
703+
paramInfos, required);
711704
}
712705

713706
const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() {
714-
return arrangeLLVMFunctionInfo(
715-
getContext().VoidTy, /*instanceMethod=*/false, /*chainCall=*/false,
716-
std::nullopt, FunctionType::ExtInfo(), {}, RequiredArgs::All);
707+
return arrangeLLVMFunctionInfo(getContext().VoidTy, FnInfoOpts::None,
708+
std::nullopt, FunctionType::ExtInfo(), {},
709+
RequiredArgs::All);
717710
}
718711

719712
const CGFunctionInfo &
@@ -733,12 +726,15 @@ CodeGenTypes::arrangeCall(const CGFunctionInfo &signature,
733726
auto argTypes = getArgTypesForCall(Context, args);
734727

735728
assert(signature.getRequiredArgs().allowsOptionalArgs());
736-
return arrangeLLVMFunctionInfo(signature.getReturnType(),
737-
signature.isInstanceMethod(),
738-
signature.isChainCall(),
739-
argTypes,
740-
signature.getExtInfo(),
741-
paramInfos,
729+
FnInfoOpts opts = FnInfoOpts::None;
730+
if (signature.isInstanceMethod())
731+
opts |= FnInfoOpts::IsInstanceMethod;
732+
if (signature.isChainCall())
733+
opts |= FnInfoOpts::IsChainCall;
734+
if (signature.isDelegateCall())
735+
opts |= FnInfoOpts::IsDelegateCall;
736+
return arrangeLLVMFunctionInfo(signature.getReturnType(), opts, argTypes,
737+
signature.getExtInfo(), paramInfos,
742738
signature.getRequiredArgs());
743739
}
744740

@@ -751,21 +747,24 @@ void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
751747
/// Arrange the argument and result information for an abstract value
752748
/// of a given function type. This is the method which all of the
753749
/// above functions ultimately defer to.
754-
const CGFunctionInfo &
755-
CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType,
756-
bool instanceMethod,
757-
bool chainCall,
758-
ArrayRef<CanQualType> argTypes,
759-
FunctionType::ExtInfo info,
760-
ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
761-
RequiredArgs required) {
750+
const CGFunctionInfo &CodeGenTypes::arrangeLLVMFunctionInfo(
751+
CanQualType resultType, FnInfoOpts opts, ArrayRef<CanQualType> argTypes,
752+
FunctionType::ExtInfo info,
753+
ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
754+
RequiredArgs required) {
762755
assert(llvm::all_of(argTypes,
763756
[](CanQualType T) { return T.isCanonicalAsParam(); }));
764757

765758
// Lookup or create unique function info.
766759
llvm::FoldingSetNodeID ID;
767-
CGFunctionInfo::Profile(ID, instanceMethod, chainCall, info, paramInfos,
768-
required, resultType, argTypes);
760+
bool isInstanceMethod =
761+
(opts & FnInfoOpts::IsInstanceMethod) == FnInfoOpts::IsInstanceMethod;
762+
bool isChainCall =
763+
(opts & FnInfoOpts::IsChainCall) == FnInfoOpts::IsChainCall;
764+
bool isDelegateCall =
765+
(opts & FnInfoOpts::IsDelegateCall) == FnInfoOpts::IsDelegateCall;
766+
CGFunctionInfo::Profile(ID, isInstanceMethod, isChainCall, isDelegateCall,
767+
info, paramInfos, required, resultType, argTypes);
769768

770769
void *insertPos = nullptr;
771770
CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos);
@@ -775,8 +774,8 @@ CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType,
775774
unsigned CC = ClangCallConvToLLVMCallConv(info.getCC());
776775

777776
// Construct the function info. We co-allocate the ArgInfos.
778-
FI = CGFunctionInfo::create(CC, instanceMethod, chainCall, info,
779-
paramInfos, resultType, argTypes, required);
777+
FI = CGFunctionInfo::create(CC, isInstanceMethod, isChainCall, isDelegateCall,
778+
info, paramInfos, resultType, argTypes, required);
780779
FunctionInfos.InsertNode(FI, insertPos);
781780

782781
bool inserted = FunctionsBeingProcessed.insert(FI).second;
@@ -811,9 +810,8 @@ CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType,
811810
return *FI;
812811
}
813812

814-
CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC,
815-
bool instanceMethod,
816-
bool chainCall,
813+
CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC, bool instanceMethod,
814+
bool chainCall, bool delegateCall,
817815
const FunctionType::ExtInfo &info,
818816
ArrayRef<ExtParameterInfo> paramInfos,
819817
CanQualType resultType,
@@ -833,6 +831,7 @@ CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC,
833831
FI->ASTCallingConvention = info.getCC();
834832
FI->InstanceMethod = instanceMethod;
835833
FI->ChainCall = chainCall;
834+
FI->DelegateCall = delegateCall;
836835
FI->CmseNSCall = info.getCmseNSCall();
837836
FI->NoReturn = info.getNoReturn();
838837
FI->ReturnsRetained = info.getProducesResult();
@@ -3985,10 +3984,6 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args,
39853984

39863985
QualType type = param->getType();
39873986

3988-
if (isInAllocaArgument(CGM.getCXXABI(), type)) {
3989-
CGM.ErrorUnsupported(param, "forwarded non-trivially copyable parameter");
3990-
}
3991-
39923987
// GetAddrOfLocalVar returns a pointer-to-pointer for references,
39933988
// but the argument needs to be the original pointer.
39943989
if (type->isReferenceType()) {

0 commit comments

Comments
 (0)