================
@@ -695,6 +695,112 @@ static llvm::Function *emitOutlinedFunctionPrologue(
   return F;
 }
 
+static llvm::Function *emitOutlinedFunctionPrologueAggregate(
+    CodeGenFunction &CGF, FunctionArgList &Args,
+    llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>>
+        &LocalAddrs,
+    llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>>
+        &VLASizes,
+    llvm::Value *&CXXThisValue, llvm::Value *&ContextV, const CapturedStmt &CS,
+    SourceLocation Loc, StringRef FunctionName) {
+  const CapturedDecl *CD = CS.getCapturedDecl();
+  const RecordDecl *RD = CS.getCapturedRecordDecl();
+
+  CXXThisValue = nullptr;
+  CodeGenModule &CGM = CGF.CGM;
+  ASTContext &Ctx = CGM.getContext();
+  Args.push_back(CD->getContextParam());
+
+  const CGFunctionInfo &FuncInfo =
+      CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
+  llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo);
+
+  auto *F =
+      llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
+                             FunctionName, &CGM.getModule());
+  CGM.SetInternalFunctionAttributes(CD, F, FuncInfo);
+  if (CD->isNothrow())
+    F->setDoesNotThrow();
+  F->setDoesNotRecurse();
+
+  CGF.StartFunction(CD, Ctx.VoidTy, F, FuncInfo, Args, Loc, Loc);
+  Address ContextAddr = CGF.GetAddrOfLocalVar(CD->getContextParam());
+  ContextV = CGF.Builder.CreateLoad(ContextAddr);
+
+  // The runtime passes arguments as a flat array of promoted intptr_t values.
+  llvm::Type *IntPtrTy = CGF.IntPtrTy;
+  llvm::Type *PtrTy = CGF.Builder.getPtrTy();
+  llvm::Align PtrAlign = CGM.getDataLayout().getPointerABIAlignment(0);
+  CharUnits SlotAlign = CharUnits::fromQuantity(PtrAlign.value());
+
+  for (auto [FD, C, FieldIdx] :
+       llvm::zip(RD->fields(), CS.captures(),
+                 llvm::seq<unsigned>(RD->getNumFields()))) {
+    llvm::Value *Slot =
+        CGF.Builder.CreateConstInBoundsGEP1_32(IntPtrTy, ContextV, FieldIdx);
+
+    // Generate the appropriate load from the GEP into the __context struct.
+    // This includes all of the user arguments as well as the implicit kernel
+    // argument pointer.
+    if (C.capturesVariableByCopy() && FD->getType()->isAnyPointerType()) {
+      const VarDecl *CurVD = C.getCapturedVar();
+      Slot->setName(CurVD->getName());
+      Address SlotAddr(Slot, PtrTy, SlotAlign);
+      LocalAddrs.insert({FD, {CurVD, SlotAddr}});
+    } else if (FD->hasCapturedVLAType()) {
+      // VLA size is stored as intptr_t directly in the slot.
+      Address SlotAddr(Slot, CGF.ConvertTypeForMem(FD->getType()), SlotAlign);
+      LValue ArgLVal =
+          CGF.MakeAddrLValue(SlotAddr, FD->getType(), AlignmentSource::Decl);
+      llvm::Value *ExprArg = CGF.EmitLoadOfScalar(ArgLVal, C.getLocation());
+      const VariableArrayType *VAT = FD->getCapturedVLAType();
+      VLASizes.try_emplace(FD, VAT->getSizeExpr(), ExprArg);
+    } else if (C.capturesVariable()) {
+      const VarDecl *Var = C.getCapturedVar();
+      QualType VarTy = Var->getType();
+
+      if (VarTy->isVariablyModifiedType() && VarTy->isPointerType()) {
+        Slot->setName(Var->getName() + ".addr");
+        Address SlotAddr(Slot, PtrTy, SlotAlign);
+        LocalAddrs.insert({FD, {Var, SlotAddr}});
+      } else {
+        llvm::Value *VarAddr = CGF.Builder.CreateAlignedLoad(
+            PtrTy, Slot, PtrAlign, Var->getName());
+        LocalAddrs.insert({FD,
+                           {Var, Address(VarAddr, CGF.ConvertTypeForMem(VarTy),
+                                         Ctx.getDeclAlign(Var))}});
+      }
+    } else if (C.capturesVariableByCopy()) {
+      assert(!FD->getType()->isAnyPointerType() &&
+             "Not expecting a captured pointer.");
+      const VarDecl *Var = C.getCapturedVar();
+      QualType FieldTy = FD->getType();
+
+      // Scalar values are promoted and stored directly in the slot.
+      Address SlotAddr(Slot, CGF.ConvertTypeForMem(FieldTy), SlotAlign);
+      Address CopyAddr =
+          CGF.CreateMemTemp(FieldTy, Ctx.getDeclAlign(FD), Var->getName());
+      LValue SrcLVal =
+          CGF.MakeAddrLValue(SlotAddr, FieldTy, AlignmentSource::Decl);
+      LValue CopyLVal =
+          CGF.MakeAddrLValue(CopyAddr, FieldTy, AlignmentSource::Decl);
+
+      RValue ArgRVal = CGF.EmitLoadOfLValue(SrcLVal, C.getLocation());
+      CGF.EmitStoreThroughLValue(ArgRVal, CopyLVal);
+
+      LocalAddrs.insert({FD, {Var, CopyAddr}});
+    } else {
+      assert(C.capturesThis());
----------------
alexey-bataev wrote:

Add assertion message

https://github.com/llvm/llvm-project/pull/186261
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to