@@ -4529,59 +4529,144 @@ void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {
45294529 emitMaster (*this , S);
45304530}
45314531
4532- static Expr *replaceWithNewTraitsOrDirectCall (Stmt *AssocExpr,
4533- CallExpr *ReplacementFunction) {
4534- Expr *FinalCall = ReplacementFunction;
4535-
4536- if (BinaryOperator *BinaryCopyOpr = dyn_cast<BinaryOperator>(AssocExpr)) {
4537- BinaryCopyOpr->setRHS (FinalCall);
4538- return BinaryCopyOpr;
4532+ static Expr *replaceWithNewTraitsOrDirectCall (CapturedDecl *CDecl,
4533+ Expr *NewExpr) {
4534+ Expr *CurrentCallExpr = nullptr ;
4535+ Stmt *CallExprStmt = CDecl->getBody ();
4536+
4537+ if (BinaryOperator *BinaryCopyOpr = dyn_cast<BinaryOperator>(CallExprStmt)) {
4538+ CurrentCallExpr = BinaryCopyOpr->getRHS ();
4539+ BinaryCopyOpr->setRHS (NewExpr);
4540+ } else {
4541+ CurrentCallExpr = dyn_cast<Expr>(CallExprStmt);
4542+ CDecl->setBody (NewExpr);
45394543 }
45404544
4541- return FinalCall ;
4545+ return CurrentCallExpr ;
45424546}
45434547
4544- static void transformCallInStmt (Stmt *StmtP) {
4545- if (auto *AssocStmt = dyn_cast<CapturedStmt>(StmtP)) {
4546- CapturedDecl *CDecl = AssocStmt->getCapturedDecl ();
4548+ static Expr *transformCallInStmt (Stmt *StmtP, bool NoContext = false ) {
4549+ Expr *CurrentExpr = nullptr ;
4550+ if (auto *CptStmt = dyn_cast<CapturedStmt>(StmtP)) {
4551+ CapturedDecl *CDecl = CptStmt->getCapturedDecl ();
45474552
4548- // Access AnnotateAttr
45494553 CallExpr *NewCallExpr = nullptr ;
45504554 for (const auto *attr : CDecl->attrs ()) {
4551- if (const auto *annotateAttr = llvm::dyn_cast<clang::AnnotateAttr>(attr);
4552- annotateAttr &&
4553- annotateAttr->getAnnotation () == " NoContextInvariant" ) {
4554- NewCallExpr = llvm::dyn_cast<CallExpr>(*annotateAttr->args_begin ());
4555+ if (NoContext) {
4556+ if (const auto *annotateAttr =
4557+ llvm::dyn_cast<clang::AnnotateAttr>(attr);
4558+ annotateAttr && annotateAttr->getAnnotation () == " NoContextAttr" ) {
4559+ NewCallExpr = llvm::dyn_cast<CallExpr>(*annotateAttr->args_begin ());
4560+ }
4561+ } else {
4562+ if (const auto *annotateAttr =
4563+ llvm::dyn_cast<clang::AnnotateAttr>(attr);
4564+ annotateAttr && annotateAttr->getAnnotation () == " NoVariantsAttr" ) {
4565+ NewCallExpr = llvm::dyn_cast<CallExpr>(*annotateAttr->args_begin ());
4566+ }
45554567 }
45564568 }
45574569
4558- Stmt *CallExprStmt = CDecl->getBody ();
4559- Stmt *NewCallExprStmt =
4560- replaceWithNewTraitsOrDirectCall (CallExprStmt, NewCallExpr);
4561- CDecl->setBody (NewCallExprStmt);
4570+ CurrentExpr = replaceWithNewTraitsOrDirectCall (CDecl, NewCallExpr);
45624571 }
4572+ return CurrentExpr;
45634573}
45644574
4565- static void emitIfElse (CodeGenFunction *CGF, Expr *Condition,
4566- Stmt *AssociatedStmt) {
4575+ // emitIfElse is used for the following conditions:
4576+ //
4577+ // NoVariants = 0 && NoContext = 1
4578+ // if (Condition_NoContext) {
4579+ // foo_variant2(); // Present in AnnotationAttr
4580+ // } else {
4581+ // foo_variant();
4582+ // }
4583+ //
4584+ // NoVariants = 1 && NoContext = 0
4585+ // if (Condition_NoVariants) {
4586+ // foo();
4587+ // } else {
4588+ // foo_variant();
4589+ // }
4590+ //
4591+ // NoVariants = 1 && NoContext = 1
4592+ // if (Condition_NoVariants) { // ==> label if.then.NoVariants
4593+ // foo();
4594+ // } else { // ==> label else.NoVariants
4595+ // if (Condition_NoContext) { // ==> label if.then.NoContext
4596+ // foo_variant2(); // Present in AnnotationAttr
4597+ // } else { // ==> label else
4598+ // foo_variant();
4599+ // }
4600+ // }
4601+ //
4602+ static void emitIfElse (CodeGenFunction *CGF, Stmt *AssociatedStmt,
4603+ Expr *Condition_NoVariants, Expr *Condition_NoContext) {
45674604 llvm::BasicBlock *ThenBlock = CGF->createBasicBlock (" if.then" );
45684605 llvm::BasicBlock *ElseBlock = CGF->createBasicBlock (" if.else" );
45694606 llvm::BasicBlock *MergeBlock = CGF->createBasicBlock (" if.end" );
4607+ llvm::BasicBlock *ThenNoVariantsBlock = nullptr ;
4608+ llvm::BasicBlock *ElseNoVariantsBlock = nullptr ;
4609+ llvm::BasicBlock *ThenNoContextBlock = nullptr ;
4610+ Expr *ElseCall = nullptr ;
45704611
4571- CGF->EmitBranchOnBoolExpr (Condition, ThenBlock, ElseBlock, 0 );
4612+ if (Condition_NoVariants && Condition_NoContext) {
4613+ ThenNoVariantsBlock = CGF->createBasicBlock (" if.then.NoVariants" );
4614+ ElseNoVariantsBlock = CGF->createBasicBlock (" else.NoVariants" );
4615+ ThenNoContextBlock = CGF->createBasicBlock (" if.then.NoContext" );
4616+
4617+ CGF->EmitBranchOnBoolExpr (Condition_NoVariants, ThenNoVariantsBlock,
4618+ ElseNoVariantsBlock, 0 );
4619+
4620+ } else if (Condition_NoVariants)
4621+ CGF->EmitBranchOnBoolExpr (Condition_NoVariants, ThenBlock, ElseBlock, 0 );
4622+ else
4623+ CGF->EmitBranchOnBoolExpr (Condition_NoContext, ThenBlock, ElseBlock, 0 );
4624+
4625+ if (Condition_NoVariants && Condition_NoContext) {
4626+ // Emit the NoVariants (if then, for the NoVariants) block.
4627+ CGF->EmitBlock (ThenNoVariantsBlock);
4628+ Stmt *ThenStmt = AssociatedStmt;
4629+ ElseCall = transformCallInStmt (ThenStmt, false );
4630+ CGF->EmitStmt (ThenStmt);
4631+ CGF->Builder .CreateBr (MergeBlock);
4632+
4633+ CGF->EmitBlock (ElseNoVariantsBlock);
4634+ CGF->EmitBranchOnBoolExpr (Condition_NoVariants, ThenNoContextBlock,
4635+ ElseBlock, 0 );
4636+ // Emit the NoContext (else if, for the NoContext) block.
4637+ CGF->EmitBlock (ThenNoContextBlock);
4638+ Stmt *ThenNoContextStmt = AssociatedStmt;
4639+ transformCallInStmt (ThenNoContextStmt, true );
4640+ CGF->EmitStmt (ThenNoContextStmt);
4641+ CGF->Builder .CreateBr (MergeBlock);
4642+
4643+ } else if (Condition_NoVariants) {
4644+ // Emit the NoVariants (then) block.
4645+ CGF->EmitBlock (ThenBlock);
4646+ Stmt *ThenStmt = AssociatedStmt;
4647+ ElseCall = transformCallInStmt (ThenStmt, false );
4648+ CGF->EmitStmt (ThenStmt);
4649+ CGF->Builder .CreateBr (MergeBlock);
4650+
4651+ } else if (Condition_NoContext) {
4652+ // Emit the NoContext (then) block.
4653+ CGF->EmitBlock (ThenBlock);
4654+ Stmt *ThenStmt = AssociatedStmt;
4655+ ElseCall = transformCallInStmt (ThenStmt, true );
4656+ CGF->EmitStmt (ThenStmt);
4657+ CGF->Builder .CreateBr (MergeBlock);
4658+ }
45724659
45734660 // Emit the else block.
4574- Stmt *ElseStmt = AssociatedStmt;
45754661 CGF->EmitBlock (ElseBlock);
4662+ Stmt *ElseStmt = AssociatedStmt;
4663+ if (auto *CaptStmt = dyn_cast<CapturedStmt>(ElseStmt)) {
4664+ CapturedDecl *CDecl = CaptStmt->getCapturedDecl ();
4665+ replaceWithNewTraitsOrDirectCall (CDecl, ElseCall);
4666+ }
45764667 CGF->EmitStmt (ElseStmt);
45774668 CGF->Builder .CreateBr (MergeBlock);
45784669
4579- // Emit the then block.
4580- Stmt *ThenStmt = AssociatedStmt;
4581- transformCallInStmt (ThenStmt);
4582- CGF->EmitBlock (ThenBlock);
4583- CGF->EmitStmt (ThenStmt);
4584- CGF->Builder .CreateBr (MergeBlock);
45854670 CGF->EmitBlock (MergeBlock);
45864671}
45874672
@@ -4598,25 +4683,32 @@ void CodeGenFunction::EmitOMPDispatchDirective(const OMPDispatchDirective &S) {
45984683 if (!CapturedStmtInfo)
45994684 CapturedStmtInfo = &CapStmtInfo;
46004685
4686+ Expr *NoVariantsCondition = nullptr ;
4687+ Expr *NoContextCondition = nullptr ;
46014688 if (!Clauses.empty ()) {
46024689 if (S.hasClausesOfKind <OMPDependClause>())
46034690 EmitOMPDispatchToTaskwaitDirective (S);
46044691
46054692 if (S.hasClausesOfKind <OMPNovariantsClause>() ||
46064693 S.hasClausesOfKind <OMPNocontextClause>()) {
4607- Expr *Condition = nullptr ;
46084694 if (const OMPNovariantsClause *NoVariantsC =
46094695 OMPExecutableDirective::getSingleClause<OMPNovariantsClause>(
46104696 Clauses)) {
4611- Condition = NoVariantsC->getCondition ();
4697+ NoVariantsCondition = NoVariantsC->getCondition ();
4698+ if (const OMPNocontextClause *NoContextC =
4699+ OMPExecutableDirective::getSingleClause<OMPNocontextClause>(
4700+ Clauses)) {
4701+ NoContextCondition = NoContextC->getCondition ();
4702+ }
46124703 } else {
46134704 const OMPNocontextClause *NoContextC =
46144705 OMPExecutableDirective::getSingleClause<OMPNocontextClause>(
46154706 Clauses);
4616- Condition = NoContextC->getCondition ();
4707+ NoContextCondition = NoContextC->getCondition ();
46174708 }
4709+
46184710 OMPLexicalScope Scope (*this , S, OMPD_dispatch);
4619- emitIfElse (this , Condition, AssociatedStmt );
4711+ emitIfElse (this , AssociatedStmt, NoVariantsCondition, NoContextCondition );
46204712 }
46214713 } else
46224714 EmitStmt (AssociatedStmt);
0 commit comments