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