Skip to content

Commit

Permalink
Reland "Try to implement lambdas with inalloca parameters by forwardi…
Browse files Browse the repository at this point in the history
…ng without use of inallocas."t

This reverts commit 8ed7aa5.

Differential Revision: https://reviews.llvm.org/D154007
  • Loading branch information
amykhuang committed Jul 26, 2023
1 parent 63458d9 commit 27dab4d
Show file tree
Hide file tree
Showing 11 changed files with 322 additions and 127 deletions.
29 changes: 16 additions & 13 deletions clang/include/clang/CodeGen/CGFunctionInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,10 @@ class CGFunctionInfo final
/// Whether this is a chain call.
unsigned ChainCall : 1;

/// Whether this function is called by forwarding arguments.
/// This doesn't support inalloca or varargs.
unsigned DelegateCall : 1;

/// Whether this function is a CMSE nonsecure call
unsigned CmseNSCall : 1;

Expand Down Expand Up @@ -616,14 +620,11 @@ class CGFunctionInfo final
CGFunctionInfo() : Required(RequiredArgs::All) {}

public:
static CGFunctionInfo *create(unsigned llvmCC,
bool instanceMethod,
bool chainCall,
const FunctionType::ExtInfo &extInfo,
ArrayRef<ExtParameterInfo> paramInfos,
CanQualType resultType,
ArrayRef<CanQualType> argTypes,
RequiredArgs required);
static CGFunctionInfo *
create(unsigned llvmCC, bool instanceMethod, bool chainCall,
bool delegateCall, const FunctionType::ExtInfo &extInfo,
ArrayRef<ExtParameterInfo> paramInfos, CanQualType resultType,
ArrayRef<CanQualType> argTypes, RequiredArgs required);
void operator delete(void *p) { ::operator delete(p); }

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

bool isChainCall() const { return ChainCall; }

bool isDelegateCall() const { return DelegateCall; }

bool isCmseNSCall() const { return CmseNSCall; }

bool isNoReturn() const { return NoReturn; }
Expand Down Expand Up @@ -749,6 +752,7 @@ class CGFunctionInfo final
ID.AddInteger(getASTCallingConvention());
ID.AddBoolean(InstanceMethod);
ID.AddBoolean(ChainCall);
ID.AddBoolean(DelegateCall);
ID.AddBoolean(NoReturn);
ID.AddBoolean(ReturnsRetained);
ID.AddBoolean(NoCallerSavedRegs);
Expand All @@ -766,17 +770,16 @@ class CGFunctionInfo final
for (const auto &I : arguments())
I.type.Profile(ID);
}
static void Profile(llvm::FoldingSetNodeID &ID,
bool InstanceMethod,
bool ChainCall,
static void Profile(llvm::FoldingSetNodeID &ID, bool InstanceMethod,
bool ChainCall, bool IsDelegateCall,
const FunctionType::ExtInfo &info,
ArrayRef<ExtParameterInfo> paramInfos,
RequiredArgs required,
CanQualType resultType,
RequiredArgs required, CanQualType resultType,
ArrayRef<CanQualType> argTypes) {
ID.AddInteger(info.getCC());
ID.AddBoolean(InstanceMethod);
ID.AddBoolean(ChainCall);
ID.AddBoolean(IsDelegateCall);
ID.AddBoolean(info.getNoReturn());
ID.AddBoolean(info.getProducesResult());
ID.AddBoolean(info.getNoCallerSavedRegs());
Expand Down
144 changes: 69 additions & 75 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> FTNP) {
// When translating an unprototyped function type, always use a
// variadic type.
return arrangeLLVMFunctionInfo(FTNP->getReturnType().getUnqualifiedType(),
/*instanceMethod=*/false,
/*chainCall=*/false, std::nullopt,
FnInfoOpts::None, std::nullopt,
FTNP->getExtInfo(), {}, RequiredArgs(0));
}

Expand Down Expand Up @@ -189,10 +188,10 @@ arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool instanceMethod,
appendParameterTypes(CGT, prefix, paramInfos, FTP);
CanQualType resultType = FTP->getReturnType().getUnqualifiedType();

return CGT.arrangeLLVMFunctionInfo(resultType, instanceMethod,
/*chainCall=*/false, prefix,
FTP->getExtInfo(), paramInfos,
Required);
FnInfoOpts opts =
instanceMethod ? FnInfoOpts::IsInstanceMethod : FnInfoOpts::None;
return CGT.arrangeLLVMFunctionInfo(resultType, opts, prefix,
FTP->getExtInfo(), paramInfos, Required);
}

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

return ::arrangeLLVMFunctionInfo(
*this, true, argTypes,
*this, /*instanceMethod=*/true, argTypes,
FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>());
}

Expand Down Expand Up @@ -363,9 +362,8 @@ CodeGenTypes::arrangeCXXStructorDeclaration(GlobalDecl GD) {
: TheCXXABI.hasMostDerivedReturn(GD)
? CGM.getContext().VoidPtrTy
: Context.VoidTy;
return arrangeLLVMFunctionInfo(resultType, /*instanceMethod=*/true,
/*chainCall=*/false, argTypes, extInfo,
paramInfos, required);
return arrangeLLVMFunctionInfo(resultType, FnInfoOpts::IsInstanceMethod,
argTypes, extInfo, paramInfos, required);
}

static SmallVector<CanQualType, 16>
Expand Down Expand Up @@ -439,9 +437,9 @@ CodeGenTypes::arrangeCXXConstructorCall(const CallArgList &args,
addExtParameterInfosForCall(ParamInfos, FPT.getTypePtr(), TotalPrefixArgs,
ArgTypes.size());
}
return arrangeLLVMFunctionInfo(ResultType, /*instanceMethod=*/true,
/*chainCall=*/false, ArgTypes, Info,
ParamInfos, Required);

return arrangeLLVMFunctionInfo(ResultType, FnInfoOpts::IsInstanceMethod,
ArgTypes, Info, ParamInfos, Required);
}

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

return arrangeFreeFunctionType(FTy.castAs<FunctionProtoType>());
Expand Down Expand Up @@ -512,9 +509,9 @@ CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD,
RequiredArgs required =
(MD->isVariadic() ? RequiredArgs(argTys.size()) : RequiredArgs::All);

return arrangeLLVMFunctionInfo(
GetReturnType(MD->getReturnType()), /*instanceMethod=*/false,
/*chainCall=*/false, argTys, einfo, extParamInfos, required);
return arrangeLLVMFunctionInfo(GetReturnType(MD->getReturnType()),
FnInfoOpts::None, argTys, einfo, extParamInfos,
required);
}

const CGFunctionInfo &
Expand All @@ -523,9 +520,8 @@ CodeGenTypes::arrangeUnprototypedObjCMessageSend(QualType returnType,
auto argTypes = getArgTypesForCall(Context, args);
FunctionType::ExtInfo einfo;

return arrangeLLVMFunctionInfo(
GetReturnType(returnType), /*instanceMethod=*/false,
/*chainCall=*/false, argTypes, einfo, {}, RequiredArgs::All);
return arrangeLLVMFunctionInfo(GetReturnType(returnType), FnInfoOpts::None,
argTypes, einfo, {}, RequiredArgs::All);
}

const CGFunctionInfo &
Expand All @@ -550,8 +546,7 @@ CodeGenTypes::arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD) {
assert(MD->isVirtual() && "only methods have thunks");
CanQual<FunctionProtoType> FTP = GetFormalType(MD);
CanQualType ArgTys[] = {DeriveThisType(MD->getParent(), MD)};
return arrangeLLVMFunctionInfo(Context.VoidTy, /*instanceMethod=*/false,
/*chainCall=*/false, ArgTys,
return arrangeLLVMFunctionInfo(Context.VoidTy, FnInfoOpts::None, ArgTys,
FTP->getExtInfo(), {}, RequiredArgs(1));
}

Expand All @@ -570,9 +565,8 @@ CodeGenTypes::arrangeMSCtorClosure(const CXXConstructorDecl *CD,
ArgTys.push_back(Context.IntTy);
CallingConv CC = Context.getDefaultCallingConvention(
/*IsVariadic=*/false, /*IsCXXMethod=*/true);
return arrangeLLVMFunctionInfo(Context.VoidTy, /*instanceMethod=*/true,
/*chainCall=*/false, ArgTys,
FunctionType::ExtInfo(CC), {},
return arrangeLLVMFunctionInfo(Context.VoidTy, FnInfoOpts::IsInstanceMethod,
ArgTys, FunctionType::ExtInfo(CC), {},
RequiredArgs::All);
}

Expand Down Expand Up @@ -616,10 +610,10 @@ arrangeFreeFunctionLikeCall(CodeGenTypes &CGT,
SmallVector<CanQualType, 16> argTypes;
for (const auto &arg : args)
argTypes.push_back(CGT.getContext().getCanonicalParamType(arg.Ty));
FnInfoOpts opts = chainCall ? FnInfoOpts::IsChainCall : FnInfoOpts::None;
return CGT.arrangeLLVMFunctionInfo(GetReturnType(fnType->getReturnType()),
/*instanceMethod=*/false, chainCall,
argTypes, fnType->getExtInfo(), paramInfos,
required);
opts, argTypes, fnType->getExtInfo(),
paramInfos, required);
}

/// Figure out the rules for calling a function with the given formal
Expand Down Expand Up @@ -650,8 +644,8 @@ CodeGenTypes::arrangeBlockFunctionDeclaration(const FunctionProtoType *proto,
auto argTypes = getArgTypesForDeclaration(Context, params);

return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
/*instanceMethod*/ false, /*chainCall*/ false,
argTypes, proto->getExtInfo(), paramInfos,
FnInfoOpts::None, argTypes,
proto->getExtInfo(), paramInfos,
RequiredArgs::forPrototypePlus(proto, 1));
}

Expand All @@ -662,28 +656,27 @@ CodeGenTypes::arrangeBuiltinFunctionCall(QualType resultType,
SmallVector<CanQualType, 16> argTypes;
for (const auto &Arg : args)
argTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
return arrangeLLVMFunctionInfo(
GetReturnType(resultType), /*instanceMethod=*/false,
/*chainCall=*/false, argTypes, FunctionType::ExtInfo(),
/*paramInfos=*/ {}, RequiredArgs::All);
return arrangeLLVMFunctionInfo(GetReturnType(resultType), FnInfoOpts::None,
argTypes, FunctionType::ExtInfo(),
/*paramInfos=*/{}, RequiredArgs::All);
}

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

return arrangeLLVMFunctionInfo(
GetReturnType(resultType), /*instanceMethod=*/false, /*chainCall=*/false,
argTypes, FunctionType::ExtInfo(), {}, RequiredArgs::All);
return arrangeLLVMFunctionInfo(GetReturnType(resultType), FnInfoOpts::None,
argTypes, FunctionType::ExtInfo(), {},
RequiredArgs::All);
}

const CGFunctionInfo &
CodeGenTypes::arrangeBuiltinFunctionDeclaration(CanQualType resultType,
ArrayRef<CanQualType> argTypes) {
return arrangeLLVMFunctionInfo(
resultType, /*instanceMethod=*/false, /*chainCall=*/false,
argTypes, FunctionType::ExtInfo(), {}, RequiredArgs::All);
return arrangeLLVMFunctionInfo(resultType, FnInfoOpts::None, argTypes,
FunctionType::ExtInfo(), {},
RequiredArgs::All);
}

/// Arrange a call to a C++ method, passing the given arguments.
Expand All @@ -706,15 +699,15 @@ CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args,
auto argTypes = getArgTypesForCall(Context, args);

FunctionType::ExtInfo info = proto->getExtInfo();
return arrangeLLVMFunctionInfo(
GetReturnType(proto->getReturnType()), /*instanceMethod=*/true,
/*chainCall=*/false, argTypes, info, paramInfos, required);
return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
FnInfoOpts::IsInstanceMethod, argTypes, info,
paramInfos, required);
}

const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() {
return arrangeLLVMFunctionInfo(
getContext().VoidTy, /*instanceMethod=*/false, /*chainCall=*/false,
std::nullopt, FunctionType::ExtInfo(), {}, RequiredArgs::All);
return arrangeLLVMFunctionInfo(getContext().VoidTy, FnInfoOpts::None,
std::nullopt, FunctionType::ExtInfo(), {},
RequiredArgs::All);
}

const CGFunctionInfo &
Expand All @@ -734,12 +727,15 @@ CodeGenTypes::arrangeCall(const CGFunctionInfo &signature,
auto argTypes = getArgTypesForCall(Context, args);

assert(signature.getRequiredArgs().allowsOptionalArgs());
return arrangeLLVMFunctionInfo(signature.getReturnType(),
signature.isInstanceMethod(),
signature.isChainCall(),
argTypes,
signature.getExtInfo(),
paramInfos,
FnInfoOpts opts = FnInfoOpts::None;
if (signature.isInstanceMethod())
opts |= FnInfoOpts::IsInstanceMethod;
if (signature.isChainCall())
opts |= FnInfoOpts::IsChainCall;
if (signature.isDelegateCall())
opts |= FnInfoOpts::IsDelegateCall;
return arrangeLLVMFunctionInfo(signature.getReturnType(), opts, argTypes,
signature.getExtInfo(), paramInfos,
signature.getRequiredArgs());
}

Expand All @@ -752,21 +748,24 @@ void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
/// Arrange the argument and result information for an abstract value
/// of a given function type. This is the method which all of the
/// above functions ultimately defer to.
const CGFunctionInfo &
CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType,
bool instanceMethod,
bool chainCall,
ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info,
ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
RequiredArgs required) {
const CGFunctionInfo &CodeGenTypes::arrangeLLVMFunctionInfo(
CanQualType resultType, FnInfoOpts opts, ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info,
ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
RequiredArgs required) {
assert(llvm::all_of(argTypes,
[](CanQualType T) { return T.isCanonicalAsParam(); }));

// Lookup or create unique function info.
llvm::FoldingSetNodeID ID;
CGFunctionInfo::Profile(ID, instanceMethod, chainCall, info, paramInfos,
required, resultType, argTypes);
bool isInstanceMethod =
(opts & FnInfoOpts::IsInstanceMethod) == FnInfoOpts::IsInstanceMethod;
bool isChainCall =
(opts & FnInfoOpts::IsChainCall) == FnInfoOpts::IsChainCall;
bool isDelegateCall =
(opts & FnInfoOpts::IsDelegateCall) == FnInfoOpts::IsDelegateCall;
CGFunctionInfo::Profile(ID, isInstanceMethod, isChainCall, isDelegateCall,
info, paramInfos, required, resultType, argTypes);

void *insertPos = nullptr;
CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos);
Expand All @@ -776,8 +775,8 @@ CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType,
unsigned CC = ClangCallConvToLLVMCallConv(info.getCC());

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

bool inserted = FunctionsBeingProcessed.insert(FI).second;
Expand Down Expand Up @@ -812,9 +811,8 @@ CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType,
return *FI;
}

CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC,
bool instanceMethod,
bool chainCall,
CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC, bool instanceMethod,
bool chainCall, bool delegateCall,
const FunctionType::ExtInfo &info,
ArrayRef<ExtParameterInfo> paramInfos,
CanQualType resultType,
Expand All @@ -834,6 +832,7 @@ CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC,
FI->ASTCallingConvention = info.getCC();
FI->InstanceMethod = instanceMethod;
FI->ChainCall = chainCall;
FI->DelegateCall = delegateCall;
FI->CmseNSCall = info.getCmseNSCall();
FI->NoReturn = info.getNoReturn();
FI->ReturnsRetained = info.getProducesResult();
Expand Down Expand Up @@ -3989,10 +3988,6 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args,

QualType type = param->getType();

if (isInAllocaArgument(CGM.getCXXABI(), type)) {
CGM.ErrorUnsupported(param, "forwarded non-trivially copyable parameter");
}

// GetAddrOfLocalVar returns a pointer-to-pointer for references,
// but the argument needs to be the original pointer.
if (type->isReferenceType()) {
Expand Down Expand Up @@ -5105,7 +5100,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
"indirect argument must be in alloca address space");

bool NeedCopy = false;

if (Addr.getAlignment() < Align &&
llvm::getOrEnforceKnownAlignment(V, Align.getAsAlign(), *TD) <
Align.getAsAlign()) {
Expand Down

0 comments on commit 27dab4d

Please sign in to comment.