@@ -629,6 +629,102 @@ static llvm::Function *emitOutlinedFunctionPrologue(
629
629
return F;
630
630
}
631
631
632
+ static llvm::Function *emitOutlinedFunctionPrologueAggregate (
633
+ CodeGenFunction &CGF, FunctionArgList &Args,
634
+ llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>>
635
+ &LocalAddrs,
636
+ llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>>
637
+ &VLASizes,
638
+ llvm::Value *&CXXThisValue, const CapturedStmt &CS, SourceLocation Loc,
639
+ StringRef FunctionName) {
640
+ const CapturedDecl *CD = CS.getCapturedDecl ();
641
+ const RecordDecl *RD = CS.getCapturedRecordDecl ();
642
+
643
+ CXXThisValue = nullptr ;
644
+ // Build the argument list.
645
+ CodeGenModule &CGM = CGF.CGM ;
646
+ ASTContext &Ctx = CGM.getContext ();
647
+ Args.append (CD->param_begin (), CD->param_end ());
648
+
649
+ // Create the function declaration.
650
+ const CGFunctionInfo &FuncInfo =
651
+ CGM.getTypes ().arrangeBuiltinFunctionDeclaration (Ctx.VoidTy , Args);
652
+ llvm::FunctionType *FuncLLVMTy = CGM.getTypes ().GetFunctionType (FuncInfo);
653
+
654
+ auto *F =
655
+ llvm::Function::Create (FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
656
+ FunctionName, &CGM.getModule ());
657
+ CGM.SetInternalFunctionAttributes (CD, F, FuncInfo);
658
+ if (CD->isNothrow ())
659
+ F->setDoesNotThrow ();
660
+ F->setDoesNotRecurse ();
661
+
662
+ // Generate the function.
663
+ CGF.StartFunction (CD, Ctx.VoidTy , F, FuncInfo, Args, Loc, Loc);
664
+ Address ContextAddr = CGF.GetAddrOfLocalVar (CD->getContextParam ());
665
+ llvm::Value *ContextV = CGF.Builder .CreateLoad (ContextAddr);
666
+ LValue ContextLV = CGF.MakeNaturalAlignAddrLValue (
667
+ ContextV, CGM.getContext ().getTagDeclType (RD));
668
+ auto I = CS.captures ().begin ();
669
+ for (const FieldDecl *FD : RD->fields ()) {
670
+ LValue FieldLV = CGF.EmitLValueForFieldInitialization (ContextLV, FD);
671
+ // Do not map arguments if we emit function with non-original types.
672
+ Address LocalAddr = FieldLV.getAddress (CGF);
673
+ // If we are capturing a pointer by copy we don't need to do anything, just
674
+ // use the value that we get from the arguments.
675
+ if (I->capturesVariableByCopy () && FD->getType ()->isAnyPointerType ()) {
676
+ const VarDecl *CurVD = I->getCapturedVar ();
677
+ LocalAddrs.insert ({FD, {CurVD, LocalAddr}});
678
+ ++I;
679
+ continue ;
680
+ }
681
+
682
+ LValue ArgLVal =
683
+ CGF.MakeAddrLValue (LocalAddr, FD->getType (), AlignmentSource::Decl);
684
+ if (FD->hasCapturedVLAType ()) {
685
+ llvm::Value *ExprArg = CGF.EmitLoadOfScalar (ArgLVal, I->getLocation ());
686
+ const VariableArrayType *VAT = FD->getCapturedVLAType ();
687
+ VLASizes.try_emplace (FD, VAT->getSizeExpr (), ExprArg);
688
+ } else if (I->capturesVariable ()) {
689
+ const VarDecl *Var = I->getCapturedVar ();
690
+ QualType VarTy = Var->getType ();
691
+ Address ArgAddr = ArgLVal.getAddress (CGF);
692
+ if (ArgLVal.getType ()->isLValueReferenceType ()) {
693
+ ArgAddr = CGF.EmitLoadOfReference (ArgLVal);
694
+ } else if (!VarTy->isVariablyModifiedType () || !VarTy->isPointerType ()) {
695
+ assert (ArgLVal.getType ()->isPointerType ());
696
+ ArgAddr = CGF.EmitLoadOfPointer (
697
+ ArgAddr, ArgLVal.getType ()->castAs <PointerType>());
698
+ }
699
+ LocalAddrs.insert (
700
+ {FD,
701
+ {Var, Address (ArgAddr.getBasePointer (), ArgAddr.getElementType (),
702
+ Ctx.getDeclAlign (Var))}});
703
+ } else if (I->capturesVariableByCopy ()) {
704
+ assert (!FD->getType ()->isAnyPointerType () &&
705
+ " Not expecting a captured pointer." );
706
+ const VarDecl *Var = I->getCapturedVar ();
707
+ Address CopyAddr = CGF.CreateMemTemp (FD->getType (), Ctx.getDeclAlign (FD),
708
+ Var->getName ());
709
+ LValue CopyLVal =
710
+ CGF.MakeAddrLValue (CopyAddr, FD->getType (), AlignmentSource::Decl);
711
+
712
+ RValue ArgRVal = CGF.EmitLoadOfLValue (ArgLVal, I->getLocation ());
713
+ CGF.EmitStoreThroughLValue (ArgRVal, CopyLVal);
714
+
715
+ LocalAddrs.insert ({FD, {Var, CopyAddr}});
716
+ } else {
717
+ // If 'this' is captured, load it into CXXThisValue.
718
+ assert (I->capturesThis ());
719
+ CXXThisValue = CGF.EmitLoadOfScalar (ArgLVal, I->getLocation ());
720
+ LocalAddrs.insert ({FD, {nullptr , ArgLVal.getAddress (CGF)}});
721
+ }
722
+ ++I;
723
+ }
724
+
725
+ return F;
726
+ }
727
+
632
728
llvm::Function *
633
729
CodeGenFunction::GenerateOpenMPCapturedStmtFunction (const CapturedStmt &S,
634
730
SourceLocation Loc) {
@@ -711,6 +807,36 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S,
711
807
return WrapperF;
712
808
}
713
809
810
+ llvm::Function *CodeGenFunction::GenerateOpenMPCapturedStmtFunctionAggregate (
811
+ const CapturedStmt &S, SourceLocation Loc) {
812
+ assert (
813
+ CapturedStmtInfo &&
814
+ " CapturedStmtInfo should be set when generating the captured function" );
815
+ const CapturedDecl *CD = S.getCapturedDecl ();
816
+ // Build the argument list.
817
+ FunctionArgList Args;
818
+ llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>> LocalAddrs;
819
+ llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> VLASizes;
820
+ StringRef FunctionName = CapturedStmtInfo->getHelperName ();
821
+ llvm::Function *F = emitOutlinedFunctionPrologueAggregate (
822
+ *this , Args, LocalAddrs, VLASizes, CXXThisValue, S, Loc, FunctionName);
823
+ CodeGenFunction::OMPPrivateScope LocalScope (*this );
824
+ for (const auto &LocalAddrPair : LocalAddrs) {
825
+ if (LocalAddrPair.second .first ) {
826
+ LocalScope.addPrivate (LocalAddrPair.second .first ,
827
+ LocalAddrPair.second .second );
828
+ }
829
+ }
830
+ (void )LocalScope.Privatize ();
831
+ for (const auto &VLASizePair : VLASizes)
832
+ VLASizeMap[VLASizePair.second .first ] = VLASizePair.second .second ;
833
+ PGO.assignRegionCounters (GlobalDecl (CD), F);
834
+ CapturedStmtInfo->EmitBody (*this , CD->getBody ());
835
+ (void )LocalScope.ForceCleanup ();
836
+ FinishFunction (CD->getBodyRBrace ());
837
+ return F;
838
+ }
839
+
714
840
// ===----------------------------------------------------------------------===//
715
841
// OpenMP Directive Emission
716
842
// ===----------------------------------------------------------------------===//
0 commit comments