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

moved some stuff around


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136998

Files:
  clang/lib/CodeGen/CGClass.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.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,7 @@
 typedef void (*fptr_t)(A);
 fptr_t fn1() { return [](A) {}; }
 
+// CHECK: define internal x86_thiscallcc void @"?__invoke@<lambda_0>@?0??fn1@@YAP6AXVA@@@ZXZ@CA?A?<auto>@@0@Z"
+// CHECK-SAME: (ptr inalloca(<{ %class.A, [3 x i8] }>) %0)
+// CHECK: %1 = getelementptr inbounds <{ %class.A, [3 x i8] }>, ptr %0, i32 0, i32 0
+// CHECK: ret void
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -3554,6 +3554,18 @@
     EmitGlobalFunctionDefinition(GD, GV);
 }
 
+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 &CGABI, const CXXMethodDecl *MD) {
+  return TI.getCXXABI().isMicrosoft() && 
+    llvm::any_of(MD->parameters(), [&](ParmVarDecl *P) {
+        return isInAllocaArg(CGABI, P->getType());
+      });
+}
+
 void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) {
   const auto *D = cast<ValueDecl>(GD.getDecl());
 
@@ -3580,6 +3592,14 @@
       // This is necessary for the generation of certain thunks.
       if (isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method))
         ABI->emitCXXStructor(GD);
+      // Special path for emitting lambda static invokers with inalloca parameters.
+      else if (Method->isLambdaStaticInvoker() && 
+               hasInAllocaArg(getTarget(), getCXXABI(), Method)) {
+        // Emit the call operator definition before emitting a static invoker.
+        const CXXMethodDecl *CallOp = Method->getParent()->getLambdaCallOperator();
+        EmitGlobalFunctionDefinition(GlobalDecl(CallOp), nullptr);
+        CodeGenFunction(*this).EmitClonedLambdaStaticInvoke(Method);
+      }
       else if (FD->isMultiVersion())
         EmitMultiVersionFunctionDefinition(GD, GV);
       else
Index: clang/lib/CodeGen/CodeGenFunction.h
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.h
+++ clang/lib/CodeGen/CodeGenFunction.h
@@ -2223,6 +2223,8 @@
   void EmitLambdaBlockInvokeBody();
   void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD);
   void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD);
+  void EmitClonedLambdaStaticInvoke(const CXXMethodDecl *MD);
+
   void EmitLambdaVLACapture(const VariableArrayType *VAT, LValue LV) {
     EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
   }
Index: clang/lib/CodeGen/CGClass.cpp
===================================================================
--- clang/lib/CodeGen/CGClass.cpp
+++ clang/lib/CodeGen/CGClass.cpp
@@ -26,8 +26,10 @@
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/TargetBuiltins.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
+#include "llvm/IR/Instructions.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/Metadata.h"
+#include "llvm/Transforms/Utils/Cloning.h"
 #include "llvm/Transforms/Utils/SanitizerStats.h"
 
 using namespace clang;
@@ -3044,3 +3046,38 @@
 
   EmitLambdaDelegatingInvokeBody(MD);
 }
+
+void CodeGenFunction::EmitClonedLambdaStaticInvoke(const CXXMethodDecl *MD) {
+  llvm::Function *Fn =
+    cast<llvm::Function>(CGM.GetAddrOfFunction(GlobalDecl(MD)));
+
+  const CXXMethodDecl *CallOp = MD->getParent()->getLambdaCallOperator();
+  llvm::Function *CallOpFn =
+    cast<llvm::Function>(CGM.GetAddrOfFunction(GlobalDecl(CallOp)));
+
+  // Clone from call operator, which we've made sure is already emitted.
+  llvm::ValueToValueMapTy VMap;
+
+  for (llvm::Argument &I : CallOpFn->args()) {
+    // Don't copy the %this argument.
+    if (I.getName().equals("this")) {
+      VMap[&I] = llvm::Constant::getNullValue(I.getType());
+    } else {
+      // Try to map the inalloca arg from the call op fn to the invoker fn.
+      for (llvm::Argument &DestI : Fn->args()) {
+        if (DestI.getType() == I.getType()) {
+          VMap[&I] = &DestI;
+          break;
+        }
+      }
+    }
+  }
+
+  Fn->setAttributes(CallOpFn->getAttributes());
+  Fn->setCallingConv(CallOpFn->getCallingConv());
+  Fn->setLinkage(CallOpFn->getLinkage());
+
+  SmallVector<llvm::ReturnInst *, 8> Returns;
+  llvm::CloneFunctionInto(Fn, CallOpFn, VMap, 
+      llvm::CloneFunctionChangeType::LocalChangesOnly, Returns, "", nullptr);
+}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to