akhuang updated this revision to Diff 476634.
akhuang added a comment.

cleanup


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137872/new/

https://reviews.llvm.org/D137872

Files:
  clang/include/clang/CodeGen/CGFunctionInfo.h
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGCall.h
  clang/lib/CodeGen/CGClass.cpp
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenABITypes.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenTypes.h
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGenCXX/inalloca-lambda.cpp

Index: clang/test/CodeGenCXX/inalloca-lambda.cpp
===================================================================
--- clang/test/CodeGenCXX/inalloca-lambda.cpp
+++ clang/test/CodeGenCXX/inalloca-lambda.cpp
@@ -1,7 +1,4 @@
-// RUN: not %clang_cc1 -triple i686-windows-msvc -emit-llvm -o /dev/null %s  2>&1 | FileCheck %s
-
-// PR28299
-// CHECK: error: cannot compile this forwarded non-trivially copyable parameter yet
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -o - %s  2>&1 | FileCheck %s
 
 class A {
   A(const A &);
@@ -9,3 +6,23 @@
 typedef void (*fptr_t)(A);
 fptr_t fn1() { return [](A) {}; }
 
+
+// CHECK: define internal void @"?__invoke@<lambda_0>@?0??fn1@@YAP6AXVA@@@ZXZ@CA?A?<auto>@@0@Z"
+// CHECK-SAME:  (ptr inalloca(<{ %class.A, [3 x i8] }>) %0)
+// CHECK: %unused.capture = alloca %class.anon, align 1
+// CHECK: %1 = getelementptr inbounds <{ %class.A, [3 x i8] }>, ptr %0, i32 0, i32 0
+// CHECK: call x86_thiscallcc void @"??R<lambda_0>@?0??fn1@@YAP6AXVA@@@ZXZ@QBE?A?<auto>@@0...@z.impl"
+// CHECK-SAME: (ptr noundef %unused.capture, ptr noundef %1)
+// CHECK: ret void
+
+// CHECK: define internal x86_thiscallcc void @"??R<lambda_0>@?0??fn1@@YAP6AXVA@@@ZXZ@QBE?A?<auto>@@0@Z"
+// CHECK-SAME:  (ptr noundef %this, ptr inalloca(<{ %class.A, [3 x i8] }>) %0)
+// CHECK: call x86_thiscallcc void @"??R<lambda_0>@?0??fn1@@YAP6AXVA@@@ZXZ@QBE?A?<auto>@@0...@z.impl"
+// CHECK-SAME: (ptr noundef %unused.capture, ptr noundef %1)
+
+// CHECK: define internal x86_thiscallcc void @"??R<lambda_0>@?0??fn1@@YAP6AXVA@@@ZXZ@QBE?A?<auto>@@0...@z.impl"
+// CHECK-SAME: (ptr noundef %this, ptr noundef %0)
+// CHECK: %this.addr = alloca ptr, align 4
+// CHECK: store ptr %this, ptr %this.addr, align 4
+// CHECK: %this1 = load ptr, ptr %this.addr, align 4
+// CHECK: ret void
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -1187,7 +1187,7 @@
 
   Class classify(QualType Ty) const;
   ABIArgInfo classifyReturnType(QualType RetTy, CCState &State) const;
-  ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State) const;
+  ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State, bool NoInAlloca) const;
 
   /// Updates the number of available free registers, returns
   /// true if any registers were allocated.
@@ -1824,7 +1824,8 @@
 }
 
 ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
-                                               CCState &State) const {
+                                               CCState &State,
+                                               bool NoInAlloca) const {
   // FIXME: Set alignment on indirect arguments.
   bool IsFastCall = State.CC == llvm::CallingConv::X86_FastCall;
   bool IsRegCall = State.CC == llvm::CallingConv::X86_RegCall;
@@ -1840,6 +1841,8 @@
     if (RAA == CGCXXABI::RAA_Indirect) {
       return getIndirectResult(Ty, false, State);
     } else if (RAA == CGCXXABI::RAA_DirectInMemory) {
+      if (NoInAlloca)
+        return getIndirectResult(Ty, false, State);
       // The field index doesn't matter, we'll fix it up later.
       return ABIArgInfo::getInAlloca(/*FieldIndex=*/0);
     }
@@ -2014,7 +2017,7 @@
     if (State.IsPreassigned.test(I))
       continue;
 
-    Args[I].info = classifyArgumentType(Args[I].type, State);
+    Args[I].info = classifyArgumentType(Args[I].type, State, FI.isAvoidingInAlloca());
     UsedInAlloca |= (Args[I].info.getKind() == ABIArgInfo::InAlloca);
   }
 
Index: clang/lib/CodeGen/CodeGenTypes.h
===================================================================
--- clang/lib/CodeGen/CodeGenTypes.h
+++ clang/lib/CodeGen/CodeGenTypes.h
@@ -260,8 +260,7 @@
   ///
   /// \param argTypes - must all actually be canonical as params
   const CGFunctionInfo &arrangeLLVMFunctionInfo(CanQualType returnType,
-                                                bool instanceMethod,
-                                                bool chainCall,
+                                                FnInfoOptions opts,
                                                 ArrayRef<CanQualType> argTypes,
                                                 FunctionType::ExtInfo info,
                     ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
Index: clang/lib/CodeGen/CodeGenFunction.h
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.h
+++ clang/lib/CodeGen/CodeGenFunction.h
@@ -2219,10 +2219,16 @@
   void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S);
 
   void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator,
-                                  CallArgList &CallArgs);
+                                  CallArgList &CallArgs,
+                                  const CGFunctionInfo *CallOpFnInfo = nullptr,
+                                  llvm::Constant *CallOpFn = nullptr);
   void EmitLambdaBlockInvokeBody();
   void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD);
   void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD);
+  void EmitLambdaInAllocaCallOpFn(const CXXMethodDecl *MD);
+  void EmitLambdaInAllocaImplFn(const CXXMethodDecl *CallOp,
+                                      const CGFunctionInfo **ImplFnInfo,
+                                      llvm::Function **ImplFn);
   void EmitLambdaVLACapture(const VariableArrayType *VAT, LValue LV) {
     EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
   }
Index: clang/lib/CodeGen/CodeGenABITypes.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenABITypes.cpp
+++ clang/lib/CodeGen/CodeGenABITypes.cpp
@@ -65,9 +65,8 @@
                                  ArrayRef<CanQualType> argTypes,
                                  FunctionType::ExtInfo info,
                                  RequiredArgs args) {
-  return CGM.getTypes().arrangeLLVMFunctionInfo(
-      returnType, /*instanceMethod=*/false, /*chainCall=*/false, argTypes,
-      info, {}, args);
+  return CGM.getTypes().arrangeLLVMFunctionInfo(returnType, FnInfoOptions(),
+                                                argTypes, info, {}, args);
 }
 
 ImplicitCXXConstructorArgs
Index: clang/lib/CodeGen/CGDeclCXX.cpp
===================================================================
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -278,7 +278,7 @@
   }
 
   const CGFunctionInfo &FI = CGM.getTypes().arrangeLLVMFunctionInfo(
-      getContext().IntTy, /*instanceMethod=*/false, /*chainCall=*/false,
+      getContext().IntTy, FnInfoOptions(),
       {getContext().IntTy}, FunctionType::ExtInfo(), {}, RequiredArgs::All);
 
   // Get the stub function type, int(*)(int,...).
Index: clang/lib/CodeGen/CGClass.cpp
===================================================================
--- clang/lib/CodeGen/CGClass.cpp
+++ clang/lib/CodeGen/CGClass.cpp
@@ -2935,13 +2935,16 @@
 
 void CodeGenFunction::EmitForwardingCallToLambda(
                                       const CXXMethodDecl *callOperator,
-                                      CallArgList &callArgs) {
+                                      CallArgList &callArgs,
+                                      const CGFunctionInfo *calleeFnInfo,
+                                      llvm::Constant *calleePtr) {
   // Get the address of the call operator.
-  const CGFunctionInfo &calleeFnInfo =
-    CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
-  llvm::Constant *calleePtr =
-    CGM.GetAddrOfFunction(GlobalDecl(callOperator),
-                          CGM.getTypes().GetFunctionType(calleeFnInfo));
+  if (!calleeFnInfo)
+    calleeFnInfo = &CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
+
+  if (!calleePtr)
+    calleePtr = CGM.GetAddrOfFunction(GlobalDecl(callOperator),
+                            CGM.getTypes().GetFunctionType(*calleeFnInfo));
 
   // Prepare the return slot.
   const FunctionProtoType *FPT =
@@ -2949,8 +2952,8 @@
   QualType resultType = FPT->getReturnType();
   ReturnValueSlot returnSlot;
   if (!resultType->isVoidType() &&
-      calleeFnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect &&
-      !hasScalarEvaluationKind(calleeFnInfo.getReturnType()))
+      calleeFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
+      !hasScalarEvaluationKind(calleeFnInfo->getReturnType()))
     returnSlot =
         ReturnValueSlot(ReturnValue, resultType.isVolatileQualified(),
                         /*IsUnused=*/false, /*IsExternallyDestructed=*/true);
@@ -2961,7 +2964,7 @@
 
   // Now emit our call.
   auto callee = CGCallee::forDirect(calleePtr, GlobalDecl(callOperator));
-  RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, callArgs);
+  RValue RV = EmitCall(*calleeFnInfo, callee, returnSlot, callArgs);
 
   // If necessary, copy the returned value into the slot.
   if (!resultType->isVoidType() && returnSlot.isNull()) {
@@ -3003,6 +3006,18 @@
   EmitForwardingCallToLambda(CallOp, CallArgs);
 }
 
+static bool isInAllocaArg(CGCXXABI &ABI, QualType T) {
+  const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
+  return RD && ABI.getRecordArgABI(RD) == CGCXXABI::RAA_DirectInMemory;
+}
+
+static bool hasInAllocaArg(const TargetInfo &TI, CGCXXABI &ABI, const CXXMethodDecl *MD) {
+  return TI.getCXXABI().isMicrosoft() &&
+    llvm::any_of(MD->parameters(), [&](ParmVarDecl *P) {
+          return isInAllocaArg(ABI, P->getType());
+        });
+}
+
 void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) {
   const CXXRecordDecl *Lambda = MD->getParent();
 
@@ -3031,6 +3046,17 @@
     assert(CorrespondingCallOpSpecialization);
     CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
   }
+
+  // Special lambda forwarding when there are inalloca parameters.
+  if (hasInAllocaArg(getTarget(), CGM.getCXXABI(), MD)) {
+    const CGFunctionInfo *ImplFnInfo = nullptr;
+    llvm::Function *ImplFn = nullptr;
+    EmitLambdaInAllocaImplFn(CallOp, &ImplFnInfo, &ImplFn);
+
+    EmitForwardingCallToLambda(CallOp, CallArgs, ImplFnInfo, ImplFn);
+    return;
+  }
+
   EmitForwardingCallToLambda(CallOp, CallArgs);
 }
 
@@ -3042,5 +3068,80 @@
     return;
   }
 
+  // If there are inalloca params, generate a new function containing the lambda body
+  // and make the invoker and original call operator call that function.
+  // Emit the new call operator here.
+  if (hasInAllocaArg(getTarget(), CGM.getCXXABI(), MD))
+    EmitLambdaInAllocaCallOpFn(MD);
+
   EmitLambdaDelegatingInvokeBody(MD);
 }
+
+void CodeGenFunction::EmitLambdaInAllocaImplFn(const CXXMethodDecl *CallOp,
+                                               const CGFunctionInfo **ImplFnInfo,
+                                               llvm::Function **ImplFn) {
+  const CGFunctionInfo &FnInfo =
+    CGM.getTypes().arrangeCXXMethodDeclaration(CallOp);
+  llvm::Function *CallOpFn =
+    cast<llvm::Function>(CGM.GetAddrOfFunction(GlobalDecl(CallOp)));
+
+  // Emit impl function containing the original lambda body.
+  SmallVector<CanQualType, 4> ArgTypes;
+  for (auto I = FnInfo.arg_begin(); I != FnInfo.arg_end(); ++I)
+    ArgTypes.push_back(I->type);
+  FnInfoOptions Opts(/*IsInstanceMethod*/false, /*IsChainCall*/false, /*DontInAlloca*/true);
+  *ImplFnInfo = &CGM.getTypes().arrangeLLVMFunctionInfo(
+        FnInfo.getReturnType(), Opts, ArgTypes,
+        FnInfo.getExtInfo(), {}, FnInfo.getRequiredArgs());
+
+  std::string ImplName = (CallOpFn->getName() + ".impl").str();
+  llvm::Function *Fn = CallOpFn->getParent()->getFunction(ImplName);
+  if (!Fn) {
+    Fn = llvm::Function::Create(CGM.getTypes().GetFunctionType(**ImplFnInfo), 
+                                    llvm::GlobalValue::InternalLinkage,
+                                    ImplName, CGM.getModule());
+    CGM.SetInternalFunctionAttributes(CallOp, Fn, **ImplFnInfo);
+    CodeGenFunction CGF(CGM);
+    CGF.CurGD = GlobalDecl(CallOp);
+    const FunctionDecl *FD = cast<FunctionDecl>(CurGD.getDecl());
+
+    FunctionArgList Args;
+    QualType ResTy = CGF.BuildFunctionArgList(CurGD, Args);
+
+    CGF.StartFunction(CurGD, ResTy, Fn, **ImplFnInfo, Args,
+        FD->getLocation(), FD->getLocation());
+    CGF.EmitFunctionBody(FD->getBody());
+    CGF.FinishFunction();
+  }
+  *ImplFn = Fn;
+}
+
+void CodeGenFunction::EmitLambdaInAllocaCallOpFn(const CXXMethodDecl *MD) {
+  const CXXMethodDecl *CallOp = MD->getParent()->getLambdaCallOperator();
+  const CGFunctionInfo &FnInfo =
+    CGM.getTypes().arrangeCXXMethodDeclaration(CallOp);
+  llvm::Function *CallOpFn =
+    cast<llvm::Function>(CGM.GetAddrOfFunction(GlobalDecl(CallOp)));
+
+  // Emit new call operator.
+  llvm::Function *Fn = llvm::Function::Create(CGM.getTypes().GetFunctionType(FnInfo),
+                                              llvm::GlobalValue::InternalLinkage,
+                                              "tmp", CGM.getModule()); 
+  CGM.SetInternalFunctionAttributes(CallOp, Fn, FnInfo);
+
+  CodeGenFunction CGF(CGM);
+  CGF.CurGD = GlobalDecl(CallOp);
+  const FunctionDecl *FD = cast<FunctionDecl>(CGF.CurGD.getDecl());
+
+  FunctionArgList Args;
+  QualType ResTy = CGF.BuildFunctionArgList(CGF.CurGD, Args);
+
+  CGF.StartFunction(CGF.CurGD, ResTy, Fn, FnInfo, Args, 
+                    FD->getLocation(), FD->getLocation());
+  CGF.EmitLambdaDelegatingInvokeBody(CallOp);
+  CGF.FinishFunction();
+
+  CallOpFn->replaceAllUsesWith(Fn);
+  Fn->takeName(CallOpFn);
+  CallOpFn->eraseFromParent();
+}
Index: clang/lib/CodeGen/CGCall.h
===================================================================
--- clang/lib/CodeGen/CGCall.h
+++ clang/lib/CodeGen/CGCall.h
@@ -377,6 +377,22 @@
   bool isExternallyDestructed() const { return IsExternallyDestructed; }
 };
 
+class FnInfoOptions {
+  unsigned IsInstanceMethod : 1;
+  unsigned IsChainCall : 1;
+  unsigned DontInAlloca : 1; 
+
+public:
+  FnInfoOptions()
+    : IsInstanceMethod(false), IsChainCall(false), DontInAlloca(false) {} 
+  FnInfoOptions(bool IsInstanceMethod, bool IsChainCall, bool DontInAlloca)
+    : IsInstanceMethod(IsInstanceMethod), IsChainCall(IsChainCall), DontInAlloca(DontInAlloca) {}
+
+  bool isInstanceMethod() const { return IsInstanceMethod; }
+  bool isChainCall() const { return IsChainCall; }
+  bool isAvoidInAlloca() const { return DontInAlloca; }
+};
+
 } // end namespace CodeGen
 } // end namespace clang
 
Index: clang/lib/CodeGen/CGCall.cpp
===================================================================
--- clang/lib/CodeGen/CGCall.cpp
+++ clang/lib/CodeGen/CGCall.cpp
@@ -111,9 +111,8 @@
   // When translating an unprototyped function type, always use a
   // variadic type.
   return arrangeLLVMFunctionInfo(FTNP->getReturnType().getUnqualifiedType(),
-                                 /*instanceMethod=*/false,
-                                 /*chainCall=*/false, None,
-                                 FTNP->getExtInfo(), {}, RequiredArgs(0));
+                                 FnInfoOptions(), None, FTNP->getExtInfo(), {},
+                                 RequiredArgs(0));
 }
 
 static void addExtParameterInfosForCall(
@@ -188,10 +187,9 @@
   appendParameterTypes(CGT, prefix, paramInfos, FTP);
   CanQualType resultType = FTP->getReturnType().getUnqualifiedType();
 
-  return CGT.arrangeLLVMFunctionInfo(resultType, instanceMethod,
-                                     /*chainCall=*/false, prefix,
-                                     FTP->getExtInfo(), paramInfos,
-                                     Required);
+  FnInfoOptions opts(instanceMethod, /*IsChainCall*/false, /*DontInAlloca*/false);
+  return CGT.arrangeLLVMFunctionInfo(resultType, opts, prefix, FTP->getExtInfo(),
+                                     paramInfos, Required);
 }
 
 /// Arrange the argument and result information for a value of the
@@ -270,7 +268,7 @@
   argTypes.push_back(DeriveThisType(RD, MD));
 
   return ::arrangeLLVMFunctionInfo(
-      *this, true, argTypes,
+      *this, /*instanceMethod=*/true, argTypes,
       FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>());
 }
 
@@ -360,9 +358,8 @@
                                : TheCXXABI.hasMostDerivedReturn(GD)
                                      ? CGM.getContext().VoidPtrTy
                                      : Context.VoidTy;
-  return arrangeLLVMFunctionInfo(resultType, /*instanceMethod=*/true,
-                                 /*chainCall=*/false, argTypes, extInfo,
-                                 paramInfos, required);
+  FnInfoOptions opts(/*IsInstanceMethod*/true, /*IsChainCall*/false, /*DontInAlloca*/false);
+  return arrangeLLVMFunctionInfo(resultType, opts, argTypes, extInfo, paramInfos, required);
 }
 
 static SmallVector<CanQualType, 16>
@@ -436,9 +433,9 @@
     addExtParameterInfosForCall(ParamInfos, FPT.getTypePtr(), TotalPrefixArgs,
                                 ArgTypes.size());
   }
-  return arrangeLLVMFunctionInfo(ResultType, /*instanceMethod=*/true,
-                                 /*chainCall=*/false, ArgTypes, Info,
-                                 ParamInfos, Required);
+
+  FnInfoOptions Opts(/*IsInstanceMethod=*/true, /*IsChainCall*/false, /*DontInAlloca*/false);
+  return arrangeLLVMFunctionInfo(ResultType, Opts, ArgTypes, Info, ParamInfos, Required);
 }
 
 /// Arrange the argument and result information for the declaration or
@@ -458,8 +455,8 @@
   // non-variadic type.
   if (CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>()) {
     return arrangeLLVMFunctionInfo(
-        noProto->getReturnType(), /*instanceMethod=*/false,
-        /*chainCall=*/false, None, noProto->getExtInfo(), {},RequiredArgs::All);
+        noProto->getReturnType(), FnInfoOptions(), 
+        None, noProto->getExtInfo(), {},RequiredArgs::All);
   }
 
   return arrangeFreeFunctionType(FTy.castAs<FunctionProtoType>());
@@ -509,8 +506,7 @@
     (MD->isVariadic() ? RequiredArgs(argTys.size()) : RequiredArgs::All);
 
   return arrangeLLVMFunctionInfo(
-      GetReturnType(MD->getReturnType()), /*instanceMethod=*/false,
-      /*chainCall=*/false, argTys, einfo, extParamInfos, required);
+      GetReturnType(MD->getReturnType()), FnInfoOptions(), argTys, einfo, extParamInfos, required);
 }
 
 const CGFunctionInfo &
@@ -520,8 +516,8 @@
   FunctionType::ExtInfo einfo;
 
   return arrangeLLVMFunctionInfo(
-      GetReturnType(returnType), /*instanceMethod=*/false,
-      /*chainCall=*/false, argTypes, einfo, {}, RequiredArgs::All);
+      GetReturnType(returnType), FnInfoOptions(), argTypes, einfo, {},
+      RequiredArgs::All);
 }
 
 const CGFunctionInfo &
@@ -546,8 +542,7 @@
   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, FnInfoOptions(), ArgTys,
                                  FTP->getExtInfo(), {}, RequiredArgs(1));
 }
 
@@ -566,10 +561,9 @@
     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), {},
-                                 RequiredArgs::All);
+  FnInfoOptions Opts(/*IsInstanceMethod=*/true, /*IsChainCall*/false, /*DontInAlloca*/false);
+  return arrangeLLVMFunctionInfo(Context.VoidTy, Opts, ArgTys, FunctionType::ExtInfo(CC),
+                                 {}, RequiredArgs::All);
 }
 
 /// Arrange a call as unto a free function, except possibly with an
@@ -612,8 +606,8 @@
   SmallVector<CanQualType, 16> argTypes;
   for (const auto &arg : args)
     argTypes.push_back(CGT.getContext().getCanonicalParamType(arg.Ty));
-  return CGT.arrangeLLVMFunctionInfo(GetReturnType(fnType->getReturnType()),
-                                     /*instanceMethod=*/false, chainCall,
+  FnInfoOptions opts(/*IsInstanceMethod=*/false, chainCall, /*DontInAlloca=*/false);
+  return CGT.arrangeLLVMFunctionInfo(GetReturnType(fnType->getReturnType()), opts,
                                      argTypes, fnType->getExtInfo(), paramInfos,
                                      required);
 }
@@ -645,8 +639,7 @@
   auto paramInfos = getExtParameterInfosForCall(proto, 1, params.size());
   auto argTypes = getArgTypesForDeclaration(Context, params);
 
-  return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
-                                 /*instanceMethod*/ false, /*chainCall*/ false,
+  return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()), FnInfoOptions(),
                                  argTypes, proto->getExtInfo(), paramInfos,
                                  RequiredArgs::forPrototypePlus(proto, 1));
 }
@@ -659,8 +652,8 @@
   for (const auto &Arg : args)
     argTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
   return arrangeLLVMFunctionInfo(
-      GetReturnType(resultType), /*instanceMethod=*/false,
-      /*chainCall=*/false, argTypes, FunctionType::ExtInfo(),
+      GetReturnType(resultType), FnInfoOptions(),
+      argTypes, FunctionType::ExtInfo(),
       /*paramInfos=*/ {}, RequiredArgs::All);
 }
 
@@ -670,16 +663,16 @@
   auto argTypes = getArgTypesForDeclaration(Context, args);
 
   return arrangeLLVMFunctionInfo(
-      GetReturnType(resultType), /*instanceMethod=*/false, /*chainCall=*/false,
-      argTypes, FunctionType::ExtInfo(), {}, RequiredArgs::All);
+      GetReturnType(resultType), FnInfoOptions(), 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);
+      resultType, FnInfoOptions(), argTypes, FunctionType::ExtInfo(), {},
+      RequiredArgs::All);
 }
 
 /// Arrange a call to a C++ method, passing the given arguments.
@@ -702,15 +695,15 @@
   auto argTypes = getArgTypesForCall(Context, args);
 
   FunctionType::ExtInfo info = proto->getExtInfo();
+  FnInfoOptions opts(
+      /*IsInstanceMethod=*/true, /*IsChainCall=*/false, /*DontInAlloca=*/false);
   return arrangeLLVMFunctionInfo(
-      GetReturnType(proto->getReturnType()), /*instanceMethod=*/true,
-      /*chainCall=*/false, argTypes, info, paramInfos, required);
+      GetReturnType(proto->getReturnType()), opts, argTypes, info, paramInfos, required);
 }
 
 const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() {
   return arrangeLLVMFunctionInfo(
-      getContext().VoidTy, /*instanceMethod=*/false, /*chainCall=*/false,
-      None, FunctionType::ExtInfo(), {}, RequiredArgs::All);
+      getContext().VoidTy, FnInfoOptions(), None, FunctionType::ExtInfo(), {}, RequiredArgs::All);
 }
 
 const CGFunctionInfo &
@@ -730,9 +723,10 @@
   auto argTypes = getArgTypesForCall(Context, args);
 
   assert(signature.getRequiredArgs().allowsOptionalArgs());
+  FnInfoOptions opts(signature.isInstanceMethod(), signature.isChainCall(), 
+                     signature.isAvoidingInAlloca());
   return arrangeLLVMFunctionInfo(signature.getReturnType(),
-                                 signature.isInstanceMethod(),
-                                 signature.isChainCall(),
+                                 opts,
                                  argTypes,
                                  signature.getExtInfo(),
                                  paramInfos,
@@ -750,8 +744,7 @@
 /// above functions ultimately defer to.
 const CGFunctionInfo &
 CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType,
-                                      bool instanceMethod,
-                                      bool chainCall,
+                                      FnInfoOptions opts,
                                       ArrayRef<CanQualType> argTypes,
                                       FunctionType::ExtInfo info,
                      ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
@@ -761,7 +754,7 @@
 
   // Lookup or create unique function info.
   llvm::FoldingSetNodeID ID;
-  CGFunctionInfo::Profile(ID, instanceMethod, chainCall, info, paramInfos,
+  CGFunctionInfo::Profile(ID, opts.isInstanceMethod(), opts.isChainCall(), info, paramInfos,
                           required, resultType, argTypes);
 
   void *insertPos = nullptr;
@@ -772,8 +765,9 @@
   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, opts.isInstanceMethod(), opts.isChainCall(), 
+                              opts.isAvoidInAlloca(), info, paramInfos, resultType,
+                              argTypes, required);
   FunctionInfos.InsertNode(FI, insertPos);
 
   bool inserted = FunctionsBeingProcessed.insert(FI).second;
@@ -811,6 +805,7 @@
 CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC,
                                        bool instanceMethod,
                                        bool chainCall,
+                                       bool dontInAlloca,
                                        const FunctionType::ExtInfo &info,
                                        ArrayRef<ExtParameterInfo> paramInfos,
                                        CanQualType resultType,
@@ -830,6 +825,7 @@
   FI->ASTCallingConvention = info.getCC();
   FI->InstanceMethod = instanceMethod;
   FI->ChainCall = chainCall;
+  FI->DontInAlloca = dontInAlloca,
   FI->CmseNSCall = info.getCmseNSCall();
   FI->NoReturn = info.getNoReturn();
   FI->ReturnsRetained = info.getProducesResult();
@@ -3806,10 +3802,6 @@
 
   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()) {
Index: clang/include/clang/CodeGen/CGFunctionInfo.h
===================================================================
--- clang/include/clang/CodeGen/CGFunctionInfo.h
+++ clang/include/clang/CodeGen/CGFunctionInfo.h
@@ -567,6 +567,9 @@
   /// Whether this is a chain call.
   unsigned ChainCall : 1;
 
+  /// Whether this function should avoid inalloca arguments.
+  unsigned DontInAlloca: 1;
+
   /// Whether this function is a CMSE nonsecure call
   unsigned CmseNSCall : 1;
 
@@ -619,6 +622,7 @@
   static CGFunctionInfo *create(unsigned llvmCC,
                                 bool instanceMethod,
                                 bool chainCall,
+                                bool dontInAlloca,
                                 const FunctionType::ExtInfo &extInfo,
                                 ArrayRef<ExtParameterInfo> paramInfos,
                                 CanQualType resultType,
@@ -663,6 +667,8 @@
 
   bool isChainCall() const { return ChainCall; }
 
+  bool isAvoidingInAlloca() const { return DontInAlloca; }
+
   bool isCmseNSCall() const { return CmseNSCall; }
 
   bool isNoReturn() const { return NoReturn; }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to