================
@@ -4529,6 +4529,191 @@ void CodeGenFunction::EmitOMPMasterDirective(const 
OMPMasterDirective &S) {
   emitMaster(*this, S);
 }
 
+static Expr *replaceWithNewTraitsOrDirectCall(CapturedDecl *CDecl,
+                                              Expr *NewExpr) {
+  Expr *CurrentCallExpr = nullptr;
+  Stmt *CallExprStmt = CDecl->getBody();
+
+  if (BinaryOperator *BinaryCopyOpr = dyn_cast<BinaryOperator>(CallExprStmt)) {
+    CurrentCallExpr = BinaryCopyOpr->getRHS();
+    BinaryCopyOpr->setRHS(NewExpr);
+  } else {
+    CurrentCallExpr = dyn_cast<Expr>(CallExprStmt);
+    CDecl->setBody(NewExpr);
+  }
+
+  return CurrentCallExpr;
+}
+
+static Expr *transformCallInStmt(Stmt *StmtP, bool NoContext = false) {
+  Expr *CurrentExpr = nullptr;
+  if (auto *CptStmt = dyn_cast<CapturedStmt>(StmtP)) {
+    CapturedDecl *CDecl = CptStmt->getCapturedDecl();
+
+    CallExpr *NewCallExpr = nullptr;
+    for (const auto *attr : CDecl->attrs()) {
+      if (NoContext) {
+        if (const auto *annotateAttr =
+                llvm::dyn_cast<clang::AnnotateAttr>(attr);
+            annotateAttr && annotateAttr->getAnnotation() == "NoContextAttr") {
+          NewCallExpr = llvm::dyn_cast<CallExpr>(*annotateAttr->args_begin());
+        }
+      } else {
+        if (const auto *annotateAttr =
+                llvm::dyn_cast<clang::AnnotateAttr>(attr);
+            annotateAttr && annotateAttr->getAnnotation() == "NoVariantsAttr") 
{
+          NewCallExpr = llvm::dyn_cast<CallExpr>(*annotateAttr->args_begin());
+        }
+      }
+    }
+
+    CurrentExpr = replaceWithNewTraitsOrDirectCall(CDecl, NewCallExpr);
+  }
+  return CurrentExpr;
+}
+
+// emitIfElse is used for the following conditions:
+//
+// NoVariants = 0 && NoContext = 1
+//   if (Condition_NoContext) {
+//     foo_variant2(); // Present in AnnotationAttr
+//   } else {
+//     foo_variant();
+//   }
+//
+// NoVariants = 1 && NoContext = 0
+//   if (Condition_NoVariants) {
+//     foo();
+//   } else {
+//     foo_variant();
+//   }
+//
+// NoVariants = 1 && NoContext = 1
+//   if (Condition_NoVariants) {   // ==> label if.then.NoVariants
+//     foo();
+//   } else {  // ==> label else.NoVariants
+//     if (Condition_NoContext) {   // ==> label if.then.NoContext
+//       foo_variant2(); // Present in AnnotationAttr
+//     } else {   // ==> label else
+//       foo_variant();
+//     }
+//   }
+//
+static void emitIfElse(CodeGenFunction *CGF, Stmt *AssociatedStmt,
+                       Expr *Condition_NoVariants, Expr *Condition_NoContext) {
+  llvm::BasicBlock *ThenBlock = CGF->createBasicBlock("if.then");
+  llvm::BasicBlock *ElseBlock = CGF->createBasicBlock("if.else");
+  llvm::BasicBlock *MergeBlock = CGF->createBasicBlock("if.end");
+  llvm::BasicBlock *ThenNoVariantsBlock = nullptr;
+  llvm::BasicBlock *ElseNoVariantsBlock = nullptr;
+  llvm::BasicBlock *ThenNoContextBlock = nullptr;
+  Expr *ElseCall = nullptr;
+
+  if (Condition_NoVariants && Condition_NoContext) {
+    ThenNoVariantsBlock = CGF->createBasicBlock("if.then.NoVariants");
+    ElseNoVariantsBlock = CGF->createBasicBlock("else.NoVariants");
+    ThenNoContextBlock = CGF->createBasicBlock("if.then.NoContext");
+
+    CGF->EmitBranchOnBoolExpr(Condition_NoVariants, ThenNoVariantsBlock,
+                              ElseNoVariantsBlock, 0);
+
+  } else if (Condition_NoVariants)
+    CGF->EmitBranchOnBoolExpr(Condition_NoVariants, ThenBlock, ElseBlock, 0);
+  else
+    CGF->EmitBranchOnBoolExpr(Condition_NoContext, ThenBlock, ElseBlock, 0);
+
+  if (Condition_NoVariants && Condition_NoContext) {
+    // Emit the NoVariants (if then, for the NoVariants)  block.
+    CGF->EmitBlock(ThenNoVariantsBlock);
+    Stmt *ThenStmt = AssociatedStmt;
+    ElseCall = transformCallInStmt(ThenStmt, false);
+    CGF->EmitStmt(ThenStmt);
+    CGF->Builder.CreateBr(MergeBlock);
+
+    CGF->EmitBlock(ElseNoVariantsBlock);
+    CGF->EmitBranchOnBoolExpr(Condition_NoVariants, ThenNoContextBlock,
+                              ElseBlock, 0);
+    // Emit the NoContext (else if, for the NoContext) block.
+    CGF->EmitBlock(ThenNoContextBlock);
+    Stmt *ThenNoContextStmt = AssociatedStmt;
+    transformCallInStmt(ThenNoContextStmt, true);
+    CGF->EmitStmt(ThenNoContextStmt);
+    CGF->Builder.CreateBr(MergeBlock);
+
+  } else if (Condition_NoVariants) {
+    // Emit the NoVariants (then) block.
+    CGF->EmitBlock(ThenBlock);
+    Stmt *ThenStmt = AssociatedStmt;
+    ElseCall = transformCallInStmt(ThenStmt, false);
+    CGF->EmitStmt(ThenStmt);
+    CGF->Builder.CreateBr(MergeBlock);
+
+  } else if (Condition_NoContext) {
+    // Emit the NoContext (then) block.
+    CGF->EmitBlock(ThenBlock);
+    Stmt *ThenStmt = AssociatedStmt;
+    ElseCall = transformCallInStmt(ThenStmt, true);
+    CGF->EmitStmt(ThenStmt);
+    CGF->Builder.CreateBr(MergeBlock);
+  }
+
+  // Emit the else block.
+  CGF->EmitBlock(ElseBlock);
+  Stmt *ElseStmt = AssociatedStmt;
+  if (auto *CaptStmt = dyn_cast<CapturedStmt>(ElseStmt)) {
+    CapturedDecl *CDecl = CaptStmt->getCapturedDecl();
+    replaceWithNewTraitsOrDirectCall(CDecl, ElseCall);
+  }
+  CGF->EmitStmt(ElseStmt);
+  CGF->Builder.CreateBr(MergeBlock);
+
+  CGF->EmitBlock(MergeBlock);
+}
+
+void CodeGenFunction::EmitOMPDispatchDirective(const OMPDispatchDirective &S) {
+  ArrayRef<OMPClause *> Clauses = S.clauses();
+
+  Stmt *AssociatedStmt = const_cast<Stmt *>(S.getAssociatedStmt());
+  if (auto *AssocStmt = dyn_cast<CapturedStmt>(AssociatedStmt))
+    if (auto *InnerCapturedStmt =
+            dyn_cast<CapturedStmt>(AssocStmt->getCapturedStmt())) {
+      AssociatedStmt = InnerCapturedStmt;
+    }
+  CodeGenFunction::CGCapturedStmtInfo CapStmtInfo;
+  if (!CapturedStmtInfo)
+    CapturedStmtInfo = &CapStmtInfo;
+
+  Expr *NoVariantsCondition = nullptr;
+  Expr *NoContextCondition = nullptr;
+  if (!Clauses.empty()) {
+    if (S.hasClausesOfKind<OMPDependClause>())
+      EmitOMPDispatchToTaskwaitDirective(S);
+
+    if (S.hasClausesOfKind<OMPNovariantsClause>() ||
+        S.hasClausesOfKind<OMPNocontextClause>()) {
+      if (const OMPNovariantsClause *NoVariantsC =
+              OMPExecutableDirective::getSingleClause<OMPNovariantsClause>(
+                  Clauses)) {
+        NoVariantsCondition = NoVariantsC->getCondition();
+        if (const OMPNocontextClause *NoContextC =
+                OMPExecutableDirective::getSingleClause<OMPNocontextClause>(
+                    Clauses)) {
+          NoContextCondition = NoContextC->getCondition();
+        }
+      } else {
+        const OMPNocontextClause *NoContextC =
+            OMPExecutableDirective::getSingleClause<OMPNocontextClause>(
+                Clauses);
+        NoContextCondition = NoContextC->getCondition();
+      }
+
+      OMPLexicalScope Scope(*this, S, OMPD_dispatch);
+      emitIfElse(this, AssociatedStmt, NoVariantsCondition, 
NoContextCondition);
+    }
+  } else
+    EmitStmt(AssociatedStmt);
----------------
alexey-bataev wrote:

```suggestion
  } else {
    EmitStmt(AssociatedStmt);
  }
```


https://github.com/llvm/llvm-project/pull/131838
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to