[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2025-02-12 Thread Alexey Bataev via cfe-commits

alexey-bataev wrote:

> > #if dispatch transformed to
> > #pragma omp taskwait depend(out:x)
> > #pragma omp dispatch nocontext(c2)
> > foo(); --> with traits call to foo_variant_dispatch(i,j)
> > you should have 2 captured regions - one for taskwait and one for dispatch. 
> > It does not mean, >you need to transform the AST node, there should be 
> > single AST node with 2 captured regions >(one caotures another), just like 
> > it is done for combined constructs.
> 
> I do not have this code anymore in SemaOpenMP.cpp. I am having code for 
> adding AnnotateAttr. In CodeGen this exact comment has been taken care of.

I'm saying how it should be implemented. Otherwise, it may crash in some cases 
or work incorrectly.

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2025-02-12 Thread via cfe-commits

SunilKuravinakop wrote:

>#if dispatch transformed to
>
>#pragma omp taskwait depend(out:x)
>#pragma omp dispatch nocontext(c2)
>foo(); --> with traits call to foo_variant_dispatch(i,j)
>
>you should have 2 captured regions - one for taskwait and one for dispatch. It 
>does not mean, >you need to transform the AST node, there should be single AST 
>node with 2 captured regions >(one caotures another), just like it is done for 
>combined constructs.

I do not have this code anymore in SemaOpenMP.cpp. I am having code for adding 
AnnotateAttr.

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2025-02-12 Thread via cfe-commits


@@ -,6 +,105 @@ void CodeGenFunction::EmitOMPMasterDirective(const 
OMPMasterDirective &S) {
   emitMaster(*this, S);
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {

SunilKuravinakop wrote:

The code has changed. I do not have this any more in SemaOpenMP.cpp. The aim in 
SemaOpenMP.cpp is to add an AnnotateAttr. Now, I have written
void SemaOpenMP::annotateAStmt()
static Expr *getNewTraitsOrDirectCall()


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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2025-02-12 Thread Alexey Bataev via cfe-commits


@@ -5965,6 +5967,269 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  StmtResult ResultAssocStmt;
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+ResultAssocStmt = NewStmt;
+  }
+  return ResultAssocStmt;
+}
+
+/// replaceWithNewTraitsOrDirectCall() is for transforming the call traits.
+/// Call traits associated with a function call are removed and replaced with
+/// a direct call. For clause "nocontext" only, the direct call is then
+/// modified to have call traits for a non-dispatch variant.
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context,
+  Expr *AssocExpr,
+  SemaOpenMP *SemaPtr,
+  bool NoContext) {
+  BinaryOperator *BinaryCopyOpr = nullptr;
+  bool IsBinaryOp = false;
+  Expr *PseudoObjExprOrCall = AssocExpr;
+  if (auto *BinOprExpr = dyn_cast(AssocExpr)) {
+IsBinaryOp = true;
+BinaryCopyOpr = BinaryOperator::Create(
+Context, BinOprExpr->getLHS(), BinOprExpr->getRHS(),
+BinOprExpr->getOpcode(), BinOprExpr->getType(),
+BinOprExpr->getValueKind(), BinOprExpr->getObjectKind(),
+BinOprExpr->getOperatorLoc(), FPOptionsOverride());
+PseudoObjExprOrCall = BinaryCopyOpr->getRHS();
+  }
+
+  Expr *CallWithoutInvariants = PseudoObjExprOrCall;
+  // Change PseudoObjectExpr to a direct call
+  if (auto *PseudoObjExpr = dyn_cast(PseudoObjExprOrCall))
+CallWithoutInvariants = *((PseudoObjExpr->semantics_begin()) - 1);
+
+  Expr *FinalCall = CallWithoutInvariants; // For noinvariants clause
+  if (NoContext) {
+// example to explain the changes done for "nocontext" clause:
+//
+// #pragma omp declare variant(foo_variant_dispatch)
+//  match(construct = {dispatch})
+// #pragma omp declare variant(foo_variant_allCond)
+// match(user = {condition(1)})
+// ...
+// #pragma omp dispatch nocontext(cond_true)
+// foo(i, j); // with traits: CodeGen call to
+// foo_variant_dispatch(i,j)
+// dispatch construct is changed to:
+// if (cond_true) {
+//foo(i,j) // with traits: CodeGen call to foo_variant_allCond(i,j)
+// } else {
+//   #pragma omp dispatch
+//   foo(i,j)  // with traits: CodeGen call to foo_variant_dispatch(i,j)
+// }

alexey-bataev wrote:

if dispatch transformed to 
```
#pragma omp taskwait depend(out:x)
#pragma omp dispatch nocontext(c2)
foo(); --> with traits call to foo_varian

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2025-02-12 Thread Alexey Bataev via cfe-commits


@@ -,6 +,105 @@ void CodeGenFunction::EmitOMPMasterDirective(const 
OMPMasterDirective &S) {
   emitMaster(*this, S);
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {

alexey-bataev wrote:

Why do you need it?

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2025-02-12 Thread via cfe-commits

SunilKuravinakop wrote:

> Hi!
> 
> FYI -- I have a partial implementation of semantic & codegen support for 
> "dispatch" directives also. I've created a draft PR for it here: #126914
> 
> Obviously there's no point in duplicating effort on this feature, but perhaps 
> bits from my implementation might be helpful. I noticed a few OpenMP_VV tests 
> fail with this patch that succeed with mine -- I'll update with further 
> details shortly.
> 
> HTH!

Hello Julian,
Thank you for the help. I am going through your implementation to see how I can 
use it into mine.  Thanks a lot. 
I am also waiting for Alexey to reply back to my changes.
--Sunil

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2025-02-12 Thread Julian Brown via cfe-commits

jtb20 wrote:

The failures with this patch and not mine are just:

PASS->FAIL: tests/5.1/dispatch/test_dispatch_is_device_ptr.c run
PASS->FAIL: tests/5.1/dispatch/test_dispatch_nowait.c run

that's actually probably neither here nor there, the clauses in question aren't 
implemented in my patch yet so the tests are likely succeeding "by accident".

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2025-02-05 Thread via cfe-commits

https://github.com/SunilKuravinakop edited 
https://github.com/llvm/llvm-project/pull/117904
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2025-02-04 Thread via cfe-commits

https://github.com/SunilKuravinakop edited 
https://github.com/llvm/llvm-project/pull/117904
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2025-02-04 Thread via cfe-commits


@@ -5965,6 +5967,269 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  StmtResult ResultAssocStmt;
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+ResultAssocStmt = NewStmt;
+  }
+  return ResultAssocStmt;
+}
+
+/// replaceWithNewTraitsOrDirectCall() is for transforming the call traits.
+/// Call traits associated with a function call are removed and replaced with
+/// a direct call. For clause "nocontext" only, the direct call is then
+/// modified to have call traits for a non-dispatch variant.
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context,
+  Expr *AssocExpr,
+  SemaOpenMP *SemaPtr,
+  bool NoContext) {
+  BinaryOperator *BinaryCopyOpr = nullptr;
+  bool IsBinaryOp = false;
+  Expr *PseudoObjExprOrCall = AssocExpr;
+  if (auto *BinOprExpr = dyn_cast(AssocExpr)) {
+IsBinaryOp = true;
+BinaryCopyOpr = BinaryOperator::Create(
+Context, BinOprExpr->getLHS(), BinOprExpr->getRHS(),
+BinOprExpr->getOpcode(), BinOprExpr->getType(),
+BinOprExpr->getValueKind(), BinOprExpr->getObjectKind(),
+BinOprExpr->getOperatorLoc(), FPOptionsOverride());
+PseudoObjExprOrCall = BinaryCopyOpr->getRHS();
+  }
+
+  Expr *CallWithoutInvariants = PseudoObjExprOrCall;
+  // Change PseudoObjectExpr to a direct call
+  if (auto *PseudoObjExpr = dyn_cast(PseudoObjExprOrCall))
+CallWithoutInvariants = *((PseudoObjExpr->semantics_begin()) - 1);
+
+  Expr *FinalCall = CallWithoutInvariants; // For noinvariants clause
+  if (NoContext) {
+// example to explain the changes done for "nocontext" clause:
+//
+// #pragma omp declare variant(foo_variant_dispatch)
+//  match(construct = {dispatch})
+// #pragma omp declare variant(foo_variant_allCond)
+// match(user = {condition(1)})
+// ...
+// #pragma omp dispatch nocontext(cond_true)
+// foo(i, j); // with traits: CodeGen call to
+// foo_variant_dispatch(i,j)
+// dispatch construct is changed to:
+// if (cond_true) {
+//foo(i,j) // with traits: CodeGen call to foo_variant_allCond(i,j)
+// } else {
+//   #pragma omp dispatch
+//   foo(i,j)  // with traits: CodeGen call to foo_variant_dispatch(i,j)
+// }

SunilKuravinakop wrote:

I have moved the helpers to codegen. Is it not preferable to add AnnotateAttr 
in Sema and make use of it in the helpers in Codegen? 

https

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2025-02-04 Thread Alexey Bataev via cfe-commits


@@ -5965,6 +5967,269 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  StmtResult ResultAssocStmt;
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+ResultAssocStmt = NewStmt;
+  }
+  return ResultAssocStmt;
+}
+
+/// replaceWithNewTraitsOrDirectCall() is for transforming the call traits.
+/// Call traits associated with a function call are removed and replaced with
+/// a direct call. For clause "nocontext" only, the direct call is then
+/// modified to have call traits for a non-dispatch variant.
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context,
+  Expr *AssocExpr,
+  SemaOpenMP *SemaPtr,
+  bool NoContext) {
+  BinaryOperator *BinaryCopyOpr = nullptr;
+  bool IsBinaryOp = false;
+  Expr *PseudoObjExprOrCall = AssocExpr;
+  if (auto *BinOprExpr = dyn_cast(AssocExpr)) {
+IsBinaryOp = true;
+BinaryCopyOpr = BinaryOperator::Create(
+Context, BinOprExpr->getLHS(), BinOprExpr->getRHS(),
+BinOprExpr->getOpcode(), BinOprExpr->getType(),
+BinOprExpr->getValueKind(), BinOprExpr->getObjectKind(),
+BinOprExpr->getOperatorLoc(), FPOptionsOverride());
+PseudoObjExprOrCall = BinaryCopyOpr->getRHS();
+  }
+
+  Expr *CallWithoutInvariants = PseudoObjExprOrCall;
+  // Change PseudoObjectExpr to a direct call
+  if (auto *PseudoObjExpr = dyn_cast(PseudoObjExprOrCall))
+CallWithoutInvariants = *((PseudoObjExpr->semantics_begin()) - 1);
+
+  Expr *FinalCall = CallWithoutInvariants; // For noinvariants clause
+  if (NoContext) {
+// example to explain the changes done for "nocontext" clause:
+//
+// #pragma omp declare variant(foo_variant_dispatch)
+//  match(construct = {dispatch})
+// #pragma omp declare variant(foo_variant_allCond)
+// match(user = {condition(1)})
+// ...
+// #pragma omp dispatch nocontext(cond_true)
+// foo(i, j); // with traits: CodeGen call to
+// foo_variant_dispatch(i,j)
+// dispatch construct is changed to:
+// if (cond_true) {
+//foo(i,j) // with traits: CodeGen call to foo_variant_allCond(i,j)
+// } else {
+//   #pragma omp dispatch
+//   foo(i,j)  // with traits: CodeGen call to foo_variant_dispatch(i,j)
+// }

alexey-bataev wrote:

There are some extra additions. Sema should not produce extra OpenMP 
constructs. You can generate required CaturedStmt (one for outer  taskwai

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2025-01-02 Thread Alexey Bataev via cfe-commits


@@ -5965,6 +5967,269 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  StmtResult ResultAssocStmt;
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+ResultAssocStmt = NewStmt;
+  }
+  return ResultAssocStmt;
+}
+
+/// replaceWithNewTraitsOrDirectCall() is for transforming the call traits.
+/// Call traits associated with a function call are removed and replaced with
+/// a direct call. For clause "nocontext" only, the direct call is then
+/// modified to have call traits for a non-dispatch variant.
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context,
+  Expr *AssocExpr,
+  SemaOpenMP *SemaPtr,
+  bool NoContext) {
+  BinaryOperator *BinaryCopyOpr = nullptr;
+  bool IsBinaryOp = false;
+  Expr *PseudoObjExprOrCall = AssocExpr;
+  if (auto *BinOprExpr = dyn_cast(AssocExpr)) {
+IsBinaryOp = true;
+BinaryCopyOpr = BinaryOperator::Create(
+Context, BinOprExpr->getLHS(), BinOprExpr->getRHS(),
+BinOprExpr->getOpcode(), BinOprExpr->getType(),
+BinOprExpr->getValueKind(), BinOprExpr->getObjectKind(),
+BinOprExpr->getOperatorLoc(), FPOptionsOverride());
+PseudoObjExprOrCall = BinaryCopyOpr->getRHS();
+  }
+
+  Expr *CallWithoutInvariants = PseudoObjExprOrCall;
+  // Change PseudoObjectExpr to a direct call
+  if (auto *PseudoObjExpr = dyn_cast(PseudoObjExprOrCall))
+CallWithoutInvariants = *((PseudoObjExpr->semantics_begin()) - 1);
+
+  Expr *FinalCall = CallWithoutInvariants; // For noinvariants clause
+  if (NoContext) {
+// example to explain the changes done for "nocontext" clause:
+//
+// #pragma omp declare variant(foo_variant_dispatch)
+//  match(construct = {dispatch})
+// #pragma omp declare variant(foo_variant_allCond)
+// match(user = {condition(1)})
+// ...
+// #pragma omp dispatch nocontext(cond_true)
+// foo(i, j); // with traits: CodeGen call to
+// foo_variant_dispatch(i,j)
+// dispatch construct is changed to:
+// if (cond_true) {
+//foo(i,j) // with traits: CodeGen call to foo_variant_allCond(i,j)
+// } else {
+//   #pragma omp dispatch
+//   foo(i,j)  // with traits: CodeGen call to foo_variant_dispatch(i,j)
+// }

alexey-bataev wrote:

I assume all these helpers can be directly codegened instead of building them 
in sema

https://github.com/llvm/llvm-project/pull/117904
__

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2025-01-02 Thread via cfe-commits

https://github.com/SunilKuravinakop updated 
https://github.com/llvm/llvm-project/pull/117904

>From 1703aa62cfe35538aedbacb28e907535e838248c Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop 
Date: Fri, 20 Sep 2024 01:41:29 -0500
Subject: [PATCH 01/11] Support for dispatch construct (Sema & Codegen)
 support. Support for clauses depend, novariants & nocontext.

---
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Basic/OpenMPKinds.h   |   6 +
 clang/include/clang/Sema/SemaOpenMP.h |   7 +
 clang/lib/Basic/OpenMPKinds.cpp   |   5 +
 clang/lib/CodeGen/CGStmt.cpp  |   2 +-
 clang/lib/CodeGen/CGStmtOpenMP.cpp|   4 +
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Sema/SemaOpenMP.cpp | 301 ++-
 clang/test/OpenMP/dispatch_codegen.cpp| 359 ++
 clang/test/OpenMP/dispatch_unsupported.c  |   7 -
 .../include/llvm/Frontend/OpenMP/OMPContext.h |   6 +
 11 files changed, 687 insertions(+), 14 deletions(-)
 create mode 100644 clang/test/OpenMP/dispatch_codegen.cpp
 delete mode 100644 clang/test/OpenMP/dispatch_unsupported.c

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8495884dcd058f..81b876f9fd85c5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11774,6 +11774,9 @@ def err_omp_clause_requires_dispatch_construct : Error<
   "'%0' clause requires 'dispatch' context selector">;
 def err_omp_append_args_with_varargs : Error<
   "'append_args' is not allowed with varargs functions">;
+def warn_omp_dispatch_clause_novariants_nocontext : Warning<
+  "only 'novariants' clause is supported when 'novariants' & 'nocontext' 
clauses occur on the same dispatch construct">,
+  InGroup;
 def err_openmp_vla_in_task_untied : Error<
   "variable length arrays are not supported in OpenMP tasking regions with 
'untied' clause">;
 def warn_omp_unterminated_declare_target : Warning<
diff --git a/clang/include/clang/Basic/OpenMPKinds.h 
b/clang/include/clang/Basic/OpenMPKinds.h
index 900ad6ca6d66f6..7579fab43dbb19 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -269,6 +269,12 @@ bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind);
 /// parallel', otherwise - false.
 bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind);
 
+/// Checks if the specified directive is a dispatch-kind directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a dispatch-like directive like 'omp
+/// dispatch', otherwise - false.
+bool isOpenMPDispatchDirective(OpenMPDirectiveKind DKind);
+
 /// Checks if the specified directive is a target code offload directive.
 /// \param DKind Specified directive.
 /// \return true - the directive is a target code offload directive like
diff --git a/clang/include/clang/Sema/SemaOpenMP.h 
b/clang/include/clang/Sema/SemaOpenMP.h
index 3d1cc4fab1c10f..80cee9e7583051 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -1462,6 +1462,13 @@ class SemaOpenMP : public SemaBase {
: OMPDeclareVariantScopes.back().TI;
   }
 
+  StmtResult transformDispatchDirective(OpenMPDirectiveKind Kind,
+const DeclarationNameInfo &DirName,
+OpenMPDirectiveKind CancelRegion,
+ArrayRef Clauses,
+Stmt *AStmt, SourceLocation StartLoc,
+SourceLocation EndLoc);
+
   /// The current `omp begin/end declare variant` scopes.
   SmallVector OMPDeclareVariantScopes;
 
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 62a13f01481b28..44ee63df46adb5 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -621,6 +621,11 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind 
DKind) {
  llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel);
 }
 
+bool clang::isOpenMPDispatchDirective(OpenMPDirectiveKind DKind) {
+  return DKind == OMPD_dispatch ||
+ llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
+}
+
 bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
   return DKind == OMPD_target ||
  llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 698baf853507f4..f3eedb79844378 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -417,7 +417,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, 
ArrayRef Attrs) {
 EmitOMPInteropDirective(cast(*S));
 break;
   case Stmt::OMPDispatchDirectiveClass:
-CGM.ErrorUnsupported(S, "OpenMP dispatch directive");
+ 

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2025-01-02 Thread via cfe-commits


@@ -5965,6 +5967,269 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  StmtResult ResultAssocStmt;
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+ResultAssocStmt = NewStmt;
+  }
+  return ResultAssocStmt;
+}
+
+/// replaceWithNewTraitsOrDirectCall() is for transforming the call traits.
+/// Call traits associated with a function call are removed and replaced with
+/// a direct call. For clause "nocontext" only, the direct call is then
+/// modified to have call traits for a non-dispatch variant.
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context,
+  Expr *AssocExpr,
+  SemaOpenMP *SemaPtr,
+  bool NoContext) {
+  BinaryOperator *BinaryCopyOpr = nullptr;
+  bool IsBinaryOp = false;
+  Expr *PseudoObjExprOrCall = AssocExpr;
+  if (auto *BinOprExpr = dyn_cast(AssocExpr)) {
+IsBinaryOp = true;
+BinaryCopyOpr = BinaryOperator::Create(
+Context, BinOprExpr->getLHS(), BinOprExpr->getRHS(),
+BinOprExpr->getOpcode(), BinOprExpr->getType(),
+BinOprExpr->getValueKind(), BinOprExpr->getObjectKind(),
+BinOprExpr->getOperatorLoc(), FPOptionsOverride());
+PseudoObjExprOrCall = BinaryCopyOpr->getRHS();
+  }
+
+  Expr *CallWithoutInvariants = PseudoObjExprOrCall;
+  // Change PseudoObjectExpr to a direct call
+  if (auto *PseudoObjExpr = dyn_cast(PseudoObjExprOrCall))
+CallWithoutInvariants = *((PseudoObjExpr->semantics_begin()) - 1);
+
+  Expr *FinalCall = CallWithoutInvariants; // For noinvariants clause
+  if (NoContext) {
+// example to explain the changes done for "nocontext" clause:
+//
+// #pragma omp declare variant(foo_variant_dispatch)
+//  match(construct = {dispatch})
+// #pragma omp declare variant(foo_variant_allCond)
+// match(user = {condition(1)})
+// ...
+// #pragma omp dispatch nocontext(cond_true)
+// foo(i, j); // with traits: CodeGen call to
+// foo_variant_dispatch(i,j)
+// dispatch construct is changed to:
+// if (cond_true) {
+//foo(i,j) // with traits: CodeGen call to foo_variant_allCond(i,j)
+// } else {
+//   #pragma omp dispatch
+//   foo(i,j)  // with traits: CodeGen call to foo_variant_dispatch(i,j)
+// }

SunilKuravinakop wrote:

With your suggestion, Source code statement of the form:
```
#pragma omp dispatch depend(out: x) nocontext(c2)
foo(); --> with traits call t

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-24 Thread Alexey Bataev via cfe-commits


@@ -5965,6 +5967,269 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  StmtResult ResultAssocStmt;
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+ResultAssocStmt = NewStmt;
+  }
+  return ResultAssocStmt;
+}
+
+/// replaceWithNewTraitsOrDirectCall() is for transforming the call traits.
+/// Call traits associated with a function call are removed and replaced with
+/// a direct call. For clause "nocontext" only, the direct call is then
+/// modified to have call traits for a non-dispatch variant.
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context,
+  Expr *AssocExpr,
+  SemaOpenMP *SemaPtr,
+  bool NoContext) {
+  BinaryOperator *BinaryCopyOpr = nullptr;
+  bool IsBinaryOp = false;
+  Expr *PseudoObjExprOrCall = AssocExpr;
+  if (auto *BinOprExpr = dyn_cast(AssocExpr)) {
+IsBinaryOp = true;
+BinaryCopyOpr = BinaryOperator::Create(
+Context, BinOprExpr->getLHS(), BinOprExpr->getRHS(),
+BinOprExpr->getOpcode(), BinOprExpr->getType(),
+BinOprExpr->getValueKind(), BinOprExpr->getObjectKind(),
+BinOprExpr->getOperatorLoc(), FPOptionsOverride());
+PseudoObjExprOrCall = BinaryCopyOpr->getRHS();
+  }
+
+  Expr *CallWithoutInvariants = PseudoObjExprOrCall;
+  // Change PseudoObjectExpr to a direct call
+  if (auto *PseudoObjExpr = dyn_cast(PseudoObjExprOrCall))
+CallWithoutInvariants = *((PseudoObjExpr->semantics_begin()) - 1);
+
+  Expr *FinalCall = CallWithoutInvariants; // For noinvariants clause
+  if (NoContext) {
+// example to explain the changes done for "nocontext" clause:
+//
+// #pragma omp declare variant(foo_variant_dispatch)
+//  match(construct = {dispatch})
+// #pragma omp declare variant(foo_variant_allCond)
+// match(user = {condition(1)})
+// ...
+// #pragma omp dispatch nocontext(cond_true)
+// foo(i, j); // with traits: CodeGen call to
+// foo_variant_dispatch(i,j)
+// dispatch construct is changed to:
+// if (cond_true) {
+//foo(i,j) // with traits: CodeGen call to foo_variant_allCond(i,j)
+// } else {
+//   #pragma omp dispatch
+//   foo(i,j)  // with traits: CodeGen call to foo_variant_dispatch(i,j)
+// }

alexey-bataev wrote:

Sema should generate only required statements/expressions. If something can be 
emitted in codegen, better to emit in codegen, to avoid extra s

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-18 Thread via cfe-commits


@@ -11774,6 +11774,9 @@ def err_omp_clause_requires_dispatch_construct : Error<
   "'%0' clause requires 'dispatch' context selector">;
 def err_omp_append_args_with_varargs : Error<
   "'append_args' is not allowed with varargs functions">;
+def warn_omp_dispatch_clause_novariants_nocontext : Warning<
+  "only 'novariants' clause is supported when 'novariants' & 'nocontext' 
clauses occur on the same dispatch construct">,

SunilKuravinakop wrote:

I have re-worded the warning message to:
`'nocontext' clause is ignored, only 'novariants' clause is applied`
 Please check.

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-18 Thread via cfe-commits

https://github.com/SunilKuravinakop edited 
https://github.com/llvm/llvm-project/pull/117904
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-18 Thread via cfe-commits

https://github.com/SunilKuravinakop edited 
https://github.com/llvm/llvm-project/pull/117904
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-18 Thread via cfe-commits

https://github.com/SunilKuravinakop edited 
https://github.com/llvm/llvm-project/pull/117904
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-18 Thread via cfe-commits


@@ -5965,6 +5967,269 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  StmtResult ResultAssocStmt;
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+ResultAssocStmt = NewStmt;
+  }
+  return ResultAssocStmt;
+}
+
+/// replaceWithNewTraitsOrDirectCall() is for transforming the call traits.
+/// Call traits associated with a function call are removed and replaced with
+/// a direct call. For clause "nocontext" only, the direct call is then
+/// modified to have call traits for a non-dispatch variant.
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context,
+  Expr *AssocExpr,
+  SemaOpenMP *SemaPtr,
+  bool NoContext) {
+  BinaryOperator *BinaryCopyOpr = nullptr;
+  bool IsBinaryOp = false;
+  Expr *PseudoObjExprOrCall = AssocExpr;
+  if (auto *BinOprExpr = dyn_cast(AssocExpr)) {
+IsBinaryOp = true;
+BinaryCopyOpr = BinaryOperator::Create(
+Context, BinOprExpr->getLHS(), BinOprExpr->getRHS(),
+BinOprExpr->getOpcode(), BinOprExpr->getType(),
+BinOprExpr->getValueKind(), BinOprExpr->getObjectKind(),
+BinOprExpr->getOperatorLoc(), FPOptionsOverride());
+PseudoObjExprOrCall = BinaryCopyOpr->getRHS();
+  }
+
+  Expr *CallWithoutInvariants = PseudoObjExprOrCall;
+  // Change PseudoObjectExpr to a direct call
+  if (auto *PseudoObjExpr = dyn_cast(PseudoObjExprOrCall))
+CallWithoutInvariants = *((PseudoObjExpr->semantics_begin()) - 1);
+
+  Expr *FinalCall = CallWithoutInvariants; // For noinvariants clause
+  if (NoContext) {
+// example to explain the changes done for "nocontext" clause:
+//
+// #pragma omp declare variant(foo_variant_dispatch)
+//  match(construct = {dispatch})
+// #pragma omp declare variant(foo_variant_allCond)
+// match(user = {condition(1)})
+// ...
+// #pragma omp dispatch nocontext(cond_true)
+// foo(i, j); // with traits: CodeGen call to
+// foo_variant_dispatch(i,j)
+// dispatch construct is changed to:
+// if (cond_true) {
+//foo(i,j) // with traits: CodeGen call to foo_variant_allCond(i,j)
+// } else {
+//   #pragma omp dispatch
+//   foo(i,j)  // with traits: CodeGen call to foo_variant_dispatch(i,j)
+// }

SunilKuravinakop wrote:

I am sorry for the detailed explanation below:

For a code like 
```
#pragma omp dispatch nocontext(cond) depend(in:i)
 foo(

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-18 Thread via cfe-commits

https://github.com/SunilKuravinakop updated 
https://github.com/llvm/llvm-project/pull/117904

>From 1703aa62cfe35538aedbacb28e907535e838248c Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop 
Date: Fri, 20 Sep 2024 01:41:29 -0500
Subject: [PATCH 01/10] Support for dispatch construct (Sema & Codegen)
 support. Support for clauses depend, novariants & nocontext.

---
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Basic/OpenMPKinds.h   |   6 +
 clang/include/clang/Sema/SemaOpenMP.h |   7 +
 clang/lib/Basic/OpenMPKinds.cpp   |   5 +
 clang/lib/CodeGen/CGStmt.cpp  |   2 +-
 clang/lib/CodeGen/CGStmtOpenMP.cpp|   4 +
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Sema/SemaOpenMP.cpp | 301 ++-
 clang/test/OpenMP/dispatch_codegen.cpp| 359 ++
 clang/test/OpenMP/dispatch_unsupported.c  |   7 -
 .../include/llvm/Frontend/OpenMP/OMPContext.h |   6 +
 11 files changed, 687 insertions(+), 14 deletions(-)
 create mode 100644 clang/test/OpenMP/dispatch_codegen.cpp
 delete mode 100644 clang/test/OpenMP/dispatch_unsupported.c

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8495884dcd058f..81b876f9fd85c5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11774,6 +11774,9 @@ def err_omp_clause_requires_dispatch_construct : Error<
   "'%0' clause requires 'dispatch' context selector">;
 def err_omp_append_args_with_varargs : Error<
   "'append_args' is not allowed with varargs functions">;
+def warn_omp_dispatch_clause_novariants_nocontext : Warning<
+  "only 'novariants' clause is supported when 'novariants' & 'nocontext' 
clauses occur on the same dispatch construct">,
+  InGroup;
 def err_openmp_vla_in_task_untied : Error<
   "variable length arrays are not supported in OpenMP tasking regions with 
'untied' clause">;
 def warn_omp_unterminated_declare_target : Warning<
diff --git a/clang/include/clang/Basic/OpenMPKinds.h 
b/clang/include/clang/Basic/OpenMPKinds.h
index 900ad6ca6d66f6..7579fab43dbb19 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -269,6 +269,12 @@ bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind);
 /// parallel', otherwise - false.
 bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind);
 
+/// Checks if the specified directive is a dispatch-kind directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a dispatch-like directive like 'omp
+/// dispatch', otherwise - false.
+bool isOpenMPDispatchDirective(OpenMPDirectiveKind DKind);
+
 /// Checks if the specified directive is a target code offload directive.
 /// \param DKind Specified directive.
 /// \return true - the directive is a target code offload directive like
diff --git a/clang/include/clang/Sema/SemaOpenMP.h 
b/clang/include/clang/Sema/SemaOpenMP.h
index 3d1cc4fab1c10f..80cee9e7583051 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -1462,6 +1462,13 @@ class SemaOpenMP : public SemaBase {
: OMPDeclareVariantScopes.back().TI;
   }
 
+  StmtResult transformDispatchDirective(OpenMPDirectiveKind Kind,
+const DeclarationNameInfo &DirName,
+OpenMPDirectiveKind CancelRegion,
+ArrayRef Clauses,
+Stmt *AStmt, SourceLocation StartLoc,
+SourceLocation EndLoc);
+
   /// The current `omp begin/end declare variant` scopes.
   SmallVector OMPDeclareVariantScopes;
 
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 62a13f01481b28..44ee63df46adb5 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -621,6 +621,11 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind 
DKind) {
  llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel);
 }
 
+bool clang::isOpenMPDispatchDirective(OpenMPDirectiveKind DKind) {
+  return DKind == OMPD_dispatch ||
+ llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
+}
+
 bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
   return DKind == OMPD_target ||
  llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 698baf853507f4..f3eedb79844378 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -417,7 +417,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, 
ArrayRef Attrs) {
 EmitOMPInteropDirective(cast(*S));
 break;
   case Stmt::OMPDispatchDirectiveClass:
-CGM.ErrorUnsupported(S, "OpenMP dispatch directive");
+ 

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-17 Thread Alexey Bataev via cfe-commits


@@ -11774,6 +11774,9 @@ def err_omp_clause_requires_dispatch_construct : Error<
   "'%0' clause requires 'dispatch' context selector">;
 def err_omp_append_args_with_varargs : Error<
   "'append_args' is not allowed with varargs functions">;
+def warn_omp_dispatch_clause_novariants_nocontext : Warning<
+  "only 'novariants' clause is supported when 'novariants' & 'nocontext' 
clauses occur on the same dispatch construct">,

alexey-bataev wrote:

We do not use such format of the warnings, please check the wording for other 
warnings and try to replicate what standard actual says

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-17 Thread Alexey Bataev via cfe-commits


@@ -5965,6 +5967,269 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  StmtResult ResultAssocStmt;
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+ResultAssocStmt = NewStmt;
+  }
+  return ResultAssocStmt;
+}
+
+/// replaceWithNewTraitsOrDirectCall() is for transforming the call traits.
+/// Call traits associated with a function call are removed and replaced with
+/// a direct call. For clause "nocontext" only, the direct call is then
+/// modified to have call traits for a non-dispatch variant.
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context,
+  Expr *AssocExpr,
+  SemaOpenMP *SemaPtr,
+  bool NoContext) {
+  BinaryOperator *BinaryCopyOpr = nullptr;
+  bool IsBinaryOp = false;
+  Expr *PseudoObjExprOrCall = AssocExpr;
+  if (auto *BinOprExpr = dyn_cast(AssocExpr)) {
+IsBinaryOp = true;
+BinaryCopyOpr = BinaryOperator::Create(
+Context, BinOprExpr->getLHS(), BinOprExpr->getRHS(),
+BinOprExpr->getOpcode(), BinOprExpr->getType(),
+BinOprExpr->getValueKind(), BinOprExpr->getObjectKind(),
+BinOprExpr->getOperatorLoc(), FPOptionsOverride());
+PseudoObjExprOrCall = BinaryCopyOpr->getRHS();
+  }
+
+  Expr *CallWithoutInvariants = PseudoObjExprOrCall;
+  // Change PseudoObjectExpr to a direct call
+  if (auto *PseudoObjExpr = dyn_cast(PseudoObjExprOrCall))
+CallWithoutInvariants = *((PseudoObjExpr->semantics_begin()) - 1);
+
+  Expr *FinalCall = CallWithoutInvariants; // For noinvariants clause
+  if (NoContext) {
+// example to explain the changes done for "nocontext" clause:
+//
+// #pragma omp declare variant(foo_variant_dispatch)
+//  match(construct = {dispatch})
+// #pragma omp declare variant(foo_variant_allCond)
+// match(user = {condition(1)})
+// ...
+// #pragma omp dispatch nocontext(cond_true)
+// foo(i, j); // with traits: CodeGen call to
+// foo_variant_dispatch(i,j)
+// dispatch construct is changed to:
+// if (cond_true) {
+//foo(i,j) // with traits: CodeGen call to foo_variant_allCond(i,j)
+// } else {
+//   #pragma omp dispatch
+//   foo(i,j)  // with traits: CodeGen call to foo_variant_dispatch(i,j)
+// }

alexey-bataev wrote:

Why you cannot do this directly in codegen?

https://github.com/llvm/llvm-project/pull/117904
___
c

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-16 Thread via cfe-commits

SunilKuravinakop wrote:

> update the openmp doc and clang release note as well?

Done.

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-16 Thread via cfe-commits

https://github.com/SunilKuravinakop updated 
https://github.com/llvm/llvm-project/pull/117904

>From 1703aa62cfe35538aedbacb28e907535e838248c Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop 
Date: Fri, 20 Sep 2024 01:41:29 -0500
Subject: [PATCH 1/8] Support for dispatch construct (Sema & Codegen) support.
 Support for clauses depend, novariants & nocontext.

---
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Basic/OpenMPKinds.h   |   6 +
 clang/include/clang/Sema/SemaOpenMP.h |   7 +
 clang/lib/Basic/OpenMPKinds.cpp   |   5 +
 clang/lib/CodeGen/CGStmt.cpp  |   2 +-
 clang/lib/CodeGen/CGStmtOpenMP.cpp|   4 +
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Sema/SemaOpenMP.cpp | 301 ++-
 clang/test/OpenMP/dispatch_codegen.cpp| 359 ++
 clang/test/OpenMP/dispatch_unsupported.c  |   7 -
 .../include/llvm/Frontend/OpenMP/OMPContext.h |   6 +
 11 files changed, 687 insertions(+), 14 deletions(-)
 create mode 100644 clang/test/OpenMP/dispatch_codegen.cpp
 delete mode 100644 clang/test/OpenMP/dispatch_unsupported.c

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8495884dcd058f..81b876f9fd85c5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11774,6 +11774,9 @@ def err_omp_clause_requires_dispatch_construct : Error<
   "'%0' clause requires 'dispatch' context selector">;
 def err_omp_append_args_with_varargs : Error<
   "'append_args' is not allowed with varargs functions">;
+def warn_omp_dispatch_clause_novariants_nocontext : Warning<
+  "only 'novariants' clause is supported when 'novariants' & 'nocontext' 
clauses occur on the same dispatch construct">,
+  InGroup;
 def err_openmp_vla_in_task_untied : Error<
   "variable length arrays are not supported in OpenMP tasking regions with 
'untied' clause">;
 def warn_omp_unterminated_declare_target : Warning<
diff --git a/clang/include/clang/Basic/OpenMPKinds.h 
b/clang/include/clang/Basic/OpenMPKinds.h
index 900ad6ca6d66f6..7579fab43dbb19 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -269,6 +269,12 @@ bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind);
 /// parallel', otherwise - false.
 bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind);
 
+/// Checks if the specified directive is a dispatch-kind directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a dispatch-like directive like 'omp
+/// dispatch', otherwise - false.
+bool isOpenMPDispatchDirective(OpenMPDirectiveKind DKind);
+
 /// Checks if the specified directive is a target code offload directive.
 /// \param DKind Specified directive.
 /// \return true - the directive is a target code offload directive like
diff --git a/clang/include/clang/Sema/SemaOpenMP.h 
b/clang/include/clang/Sema/SemaOpenMP.h
index 3d1cc4fab1c10f..80cee9e7583051 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -1462,6 +1462,13 @@ class SemaOpenMP : public SemaBase {
: OMPDeclareVariantScopes.back().TI;
   }
 
+  StmtResult transformDispatchDirective(OpenMPDirectiveKind Kind,
+const DeclarationNameInfo &DirName,
+OpenMPDirectiveKind CancelRegion,
+ArrayRef Clauses,
+Stmt *AStmt, SourceLocation StartLoc,
+SourceLocation EndLoc);
+
   /// The current `omp begin/end declare variant` scopes.
   SmallVector OMPDeclareVariantScopes;
 
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 62a13f01481b28..44ee63df46adb5 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -621,6 +621,11 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind 
DKind) {
  llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel);
 }
 
+bool clang::isOpenMPDispatchDirective(OpenMPDirectiveKind DKind) {
+  return DKind == OMPD_dispatch ||
+ llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
+}
+
 bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
   return DKind == OMPD_target ||
  llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 698baf853507f4..f3eedb79844378 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -417,7 +417,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, 
ArrayRef Attrs) {
 EmitOMPInteropDirective(cast(*S));
 break;
   case Stmt::OMPDispatchDirectiveClass:
-CGM.ErrorUnsupported(S, "OpenMP dispatch directive");
+   

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-15 Thread via cfe-commits

https://github.com/SunilKuravinakop updated 
https://github.com/llvm/llvm-project/pull/117904

>From 1703aa62cfe35538aedbacb28e907535e838248c Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop 
Date: Fri, 20 Sep 2024 01:41:29 -0500
Subject: [PATCH 1/7] Support for dispatch construct (Sema & Codegen) support.
 Support for clauses depend, novariants & nocontext.

---
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Basic/OpenMPKinds.h   |   6 +
 clang/include/clang/Sema/SemaOpenMP.h |   7 +
 clang/lib/Basic/OpenMPKinds.cpp   |   5 +
 clang/lib/CodeGen/CGStmt.cpp  |   2 +-
 clang/lib/CodeGen/CGStmtOpenMP.cpp|   4 +
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Sema/SemaOpenMP.cpp | 301 ++-
 clang/test/OpenMP/dispatch_codegen.cpp| 359 ++
 clang/test/OpenMP/dispatch_unsupported.c  |   7 -
 .../include/llvm/Frontend/OpenMP/OMPContext.h |   6 +
 11 files changed, 687 insertions(+), 14 deletions(-)
 create mode 100644 clang/test/OpenMP/dispatch_codegen.cpp
 delete mode 100644 clang/test/OpenMP/dispatch_unsupported.c

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8495884dcd058f..81b876f9fd85c5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11774,6 +11774,9 @@ def err_omp_clause_requires_dispatch_construct : Error<
   "'%0' clause requires 'dispatch' context selector">;
 def err_omp_append_args_with_varargs : Error<
   "'append_args' is not allowed with varargs functions">;
+def warn_omp_dispatch_clause_novariants_nocontext : Warning<
+  "only 'novariants' clause is supported when 'novariants' & 'nocontext' 
clauses occur on the same dispatch construct">,
+  InGroup;
 def err_openmp_vla_in_task_untied : Error<
   "variable length arrays are not supported in OpenMP tasking regions with 
'untied' clause">;
 def warn_omp_unterminated_declare_target : Warning<
diff --git a/clang/include/clang/Basic/OpenMPKinds.h 
b/clang/include/clang/Basic/OpenMPKinds.h
index 900ad6ca6d66f6..7579fab43dbb19 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -269,6 +269,12 @@ bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind);
 /// parallel', otherwise - false.
 bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind);
 
+/// Checks if the specified directive is a dispatch-kind directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a dispatch-like directive like 'omp
+/// dispatch', otherwise - false.
+bool isOpenMPDispatchDirective(OpenMPDirectiveKind DKind);
+
 /// Checks if the specified directive is a target code offload directive.
 /// \param DKind Specified directive.
 /// \return true - the directive is a target code offload directive like
diff --git a/clang/include/clang/Sema/SemaOpenMP.h 
b/clang/include/clang/Sema/SemaOpenMP.h
index 3d1cc4fab1c10f..80cee9e7583051 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -1462,6 +1462,13 @@ class SemaOpenMP : public SemaBase {
: OMPDeclareVariantScopes.back().TI;
   }
 
+  StmtResult transformDispatchDirective(OpenMPDirectiveKind Kind,
+const DeclarationNameInfo &DirName,
+OpenMPDirectiveKind CancelRegion,
+ArrayRef Clauses,
+Stmt *AStmt, SourceLocation StartLoc,
+SourceLocation EndLoc);
+
   /// The current `omp begin/end declare variant` scopes.
   SmallVector OMPDeclareVariantScopes;
 
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 62a13f01481b28..44ee63df46adb5 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -621,6 +621,11 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind 
DKind) {
  llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel);
 }
 
+bool clang::isOpenMPDispatchDirective(OpenMPDirectiveKind DKind) {
+  return DKind == OMPD_dispatch ||
+ llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
+}
+
 bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
   return DKind == OMPD_target ||
  llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 698baf853507f4..f3eedb79844378 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -417,7 +417,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, 
ArrayRef Attrs) {
 EmitOMPInteropDirective(cast(*S));
 break;
   case Stmt::OMPDispatchDirectiveClass:
-CGM.ErrorUnsupported(S, "OpenMP dispatch directive");
+   

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-15 Thread via cfe-commits


@@ -11774,6 +11774,9 @@ def err_omp_clause_requires_dispatch_construct : Error<
   "'%0' clause requires 'dispatch' context selector">;
 def err_omp_append_args_with_varargs : Error<
   "'append_args' is not allowed with varargs functions">;
+def warn_omp_dispatch_clause_novariants_nocontext : Warning<
+  "only 'novariants' clause is supported when 'novariants' & 'nocontext' 
clauses occur on the same dispatch construct">,

SunilKuravinakop wrote:

I have added extra tests in clang/test/OpenMP/dispatch_messages.cpp.

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-15 Thread via cfe-commits


@@ -5965,6 +5967,264 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  StmtResult ResultAssocStmt;
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+ResultAssocStmt = NewStmt;
+  }
+  return ResultAssocStmt;
+}
+
+/// replaceWithNewTraitsOrDirectCall() is for transforming the call traits.
+/// Call traits associated with a function call are removed and replaced with
+/// a direct call. For clause "nocontext" only, the direct call is then
+/// modified to have call traits for a non-dispatch variant.
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context,
+  Expr *AssocExpr,
+  SemaOpenMP *SemaPtr,
+  bool NoContext) {
+  BinaryOperator *BinaryCopyOpr = nullptr;
+  bool IsBinaryOp = false;
+  Expr *PseudoObjExprOrCall = AssocExpr;
+  if (auto *BinOprExpr = dyn_cast(AssocExpr)) {
+IsBinaryOp = true;
+BinaryCopyOpr = BinaryOperator::Create(
+Context, BinOprExpr->getLHS(), BinOprExpr->getRHS(),
+BinOprExpr->getOpcode(), BinOprExpr->getType(),
+BinOprExpr->getValueKind(), BinOprExpr->getObjectKind(),
+BinOprExpr->getOperatorLoc(), FPOptionsOverride());
+PseudoObjExprOrCall = BinaryCopyOpr->getRHS();
+  }
+
+  Expr *CallWithoutInvariants = PseudoObjExprOrCall;
+  // Change PseudoObjectExpr to a direct call
+  if (auto *PseudoObjExpr = dyn_cast(PseudoObjExprOrCall))
+CallWithoutInvariants = *((PseudoObjExpr->semantics_begin()) - 1);
+
+  Expr *FinalCall = CallWithoutInvariants; // For noinvariants clause
+  if (NoContext) {
+// example to explain the changes done for "nocontext" clause:
+//
+// #pragma omp declare variant(foo_variant_dispatch)
+//  match(construct = {dispatch})
+// #pragma omp declare variant(foo_variant_allCond)
+// match(user = {condition(1)})
+// ...
+// #pragma omp dispatch nocontext(cond_true)
+// foo(i, j); // with traits: CodeGen call to
+// foo_variant_dispatch(i,j)
+// dispatch construct is changed to:
+// if (cond_true) {
+//foo(i,j) // with traits: CodeGen call to foo_variant_allCond(i,j)
+// } else {
+//   #pragma omp dispatch
+//   foo(i,j)  // with traits: CodeGen call to foo_variant_dispatch(i,j)
+// }
+
+// Convert StmtResult to a CallExpr before calling ActOnOpenMPCall()
+auto *CallExprWithinStmt = cast(CallWithoutInvariants);
+int NumArgs = CallExprWithinStmt->getNum

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-15 Thread via cfe-commits

https://github.com/SunilKuravinakop updated 
https://github.com/llvm/llvm-project/pull/117904

>From 1703aa62cfe35538aedbacb28e907535e838248c Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop 
Date: Fri, 20 Sep 2024 01:41:29 -0500
Subject: [PATCH 1/6] Support for dispatch construct (Sema & Codegen) support.
 Support for clauses depend, novariants & nocontext.

---
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Basic/OpenMPKinds.h   |   6 +
 clang/include/clang/Sema/SemaOpenMP.h |   7 +
 clang/lib/Basic/OpenMPKinds.cpp   |   5 +
 clang/lib/CodeGen/CGStmt.cpp  |   2 +-
 clang/lib/CodeGen/CGStmtOpenMP.cpp|   4 +
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Sema/SemaOpenMP.cpp | 301 ++-
 clang/test/OpenMP/dispatch_codegen.cpp| 359 ++
 clang/test/OpenMP/dispatch_unsupported.c  |   7 -
 .../include/llvm/Frontend/OpenMP/OMPContext.h |   6 +
 11 files changed, 687 insertions(+), 14 deletions(-)
 create mode 100644 clang/test/OpenMP/dispatch_codegen.cpp
 delete mode 100644 clang/test/OpenMP/dispatch_unsupported.c

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8495884dcd058f..81b876f9fd85c5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11774,6 +11774,9 @@ def err_omp_clause_requires_dispatch_construct : Error<
   "'%0' clause requires 'dispatch' context selector">;
 def err_omp_append_args_with_varargs : Error<
   "'append_args' is not allowed with varargs functions">;
+def warn_omp_dispatch_clause_novariants_nocontext : Warning<
+  "only 'novariants' clause is supported when 'novariants' & 'nocontext' 
clauses occur on the same dispatch construct">,
+  InGroup;
 def err_openmp_vla_in_task_untied : Error<
   "variable length arrays are not supported in OpenMP tasking regions with 
'untied' clause">;
 def warn_omp_unterminated_declare_target : Warning<
diff --git a/clang/include/clang/Basic/OpenMPKinds.h 
b/clang/include/clang/Basic/OpenMPKinds.h
index 900ad6ca6d66f6..7579fab43dbb19 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -269,6 +269,12 @@ bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind);
 /// parallel', otherwise - false.
 bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind);
 
+/// Checks if the specified directive is a dispatch-kind directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a dispatch-like directive like 'omp
+/// dispatch', otherwise - false.
+bool isOpenMPDispatchDirective(OpenMPDirectiveKind DKind);
+
 /// Checks if the specified directive is a target code offload directive.
 /// \param DKind Specified directive.
 /// \return true - the directive is a target code offload directive like
diff --git a/clang/include/clang/Sema/SemaOpenMP.h 
b/clang/include/clang/Sema/SemaOpenMP.h
index 3d1cc4fab1c10f..80cee9e7583051 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -1462,6 +1462,13 @@ class SemaOpenMP : public SemaBase {
: OMPDeclareVariantScopes.back().TI;
   }
 
+  StmtResult transformDispatchDirective(OpenMPDirectiveKind Kind,
+const DeclarationNameInfo &DirName,
+OpenMPDirectiveKind CancelRegion,
+ArrayRef Clauses,
+Stmt *AStmt, SourceLocation StartLoc,
+SourceLocation EndLoc);
+
   /// The current `omp begin/end declare variant` scopes.
   SmallVector OMPDeclareVariantScopes;
 
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 62a13f01481b28..44ee63df46adb5 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -621,6 +621,11 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind 
DKind) {
  llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel);
 }
 
+bool clang::isOpenMPDispatchDirective(OpenMPDirectiveKind DKind) {
+  return DKind == OMPD_dispatch ||
+ llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
+}
+
 bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
   return DKind == OMPD_target ||
  llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 698baf853507f4..f3eedb79844378 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -417,7 +417,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, 
ArrayRef Attrs) {
 EmitOMPInteropDirective(cast(*S));
 break;
   case Stmt::OMPDispatchDirectiveClass:
-CGM.ErrorUnsupported(S, "OpenMP dispatch directive");
+   

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-15 Thread via cfe-commits


@@ -11774,6 +11774,9 @@ def err_omp_clause_requires_dispatch_construct : Error<
   "'%0' clause requires 'dispatch' context selector">;
 def err_omp_append_args_with_varargs : Error<
   "'append_args' is not allowed with varargs functions">;
+def warn_omp_dispatch_clause_novariants_nocontext : Warning<
+  "only 'novariants' clause is supported when 'novariants' & 'nocontext' 
clauses occur on the same dispatch construct">,

SunilKuravinakop wrote:

In case of 
   `#pragma omp dispatch nocontext(c1) novariants(c2) depend(inout:x)`
the alternative warning message that you have suggested may not be proper 
because it indicates `depend` is also not expected.

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-13 Thread Alexey Bataev via cfe-commits


@@ -5965,6 +5967,264 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  StmtResult ResultAssocStmt;
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+ResultAssocStmt = NewStmt;
+  }
+  return ResultAssocStmt;
+}
+
+/// replaceWithNewTraitsOrDirectCall() is for transforming the call traits.
+/// Call traits associated with a function call are removed and replaced with
+/// a direct call. For clause "nocontext" only, the direct call is then
+/// modified to have call traits for a non-dispatch variant.
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context,
+  Expr *AssocExpr,
+  SemaOpenMP *SemaPtr,
+  bool NoContext) {
+  BinaryOperator *BinaryCopyOpr = nullptr;
+  bool IsBinaryOp = false;
+  Expr *PseudoObjExprOrCall = AssocExpr;
+  if (auto *BinOprExpr = dyn_cast(AssocExpr)) {
+IsBinaryOp = true;
+BinaryCopyOpr = BinaryOperator::Create(
+Context, BinOprExpr->getLHS(), BinOprExpr->getRHS(),
+BinOprExpr->getOpcode(), BinOprExpr->getType(),
+BinOprExpr->getValueKind(), BinOprExpr->getObjectKind(),
+BinOprExpr->getOperatorLoc(), FPOptionsOverride());
+PseudoObjExprOrCall = BinaryCopyOpr->getRHS();
+  }
+
+  Expr *CallWithoutInvariants = PseudoObjExprOrCall;
+  // Change PseudoObjectExpr to a direct call
+  if (auto *PseudoObjExpr = dyn_cast(PseudoObjExprOrCall))
+CallWithoutInvariants = *((PseudoObjExpr->semantics_begin()) - 1);
+
+  Expr *FinalCall = CallWithoutInvariants; // For noinvariants clause
+  if (NoContext) {
+// example to explain the changes done for "nocontext" clause:
+//
+// #pragma omp declare variant(foo_variant_dispatch)
+//  match(construct = {dispatch})
+// #pragma omp declare variant(foo_variant_allCond)
+// match(user = {condition(1)})
+// ...
+// #pragma omp dispatch nocontext(cond_true)
+// foo(i, j); // with traits: CodeGen call to
+// foo_variant_dispatch(i,j)
+// dispatch construct is changed to:
+// if (cond_true) {
+//foo(i,j) // with traits: CodeGen call to foo_variant_allCond(i,j)
+// } else {
+//   #pragma omp dispatch
+//   foo(i,j)  // with traits: CodeGen call to foo_variant_dispatch(i,j)
+// }
+
+// Convert StmtResult to a CallExpr before calling ActOnOpenMPCall()
+auto *CallExprWithinStmt = cast(CallWithoutInvariants);
+int NumArgs = CallExprWithinStmt->getNum

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-13 Thread Alexey Bataev via cfe-commits


@@ -11774,6 +11774,9 @@ def err_omp_clause_requires_dispatch_construct : Error<
   "'%0' clause requires 'dispatch' context selector">;
 def err_omp_append_args_with_varargs : Error<
   "'append_args' is not allowed with varargs functions">;
+def warn_omp_dispatch_clause_novariants_nocontext : Warning<
+  "only 'novariants' clause is supported when 'novariants' & 'nocontext' 
clauses occur on the same dispatch construct">,

alexey-bataev wrote:

1.
```suggestion
  "only 'novariants' clause is expected">,
```
or something like this.

2. No test for this warning


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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-13 Thread Shilei Tian via cfe-commits

https://github.com/shiltian edited 
https://github.com/llvm/llvm-project/pull/117904
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-13 Thread Shilei Tian via cfe-commits

https://github.com/shiltian edited 
https://github.com/llvm/llvm-project/pull/117904
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-13 Thread Shilei Tian via cfe-commits


@@ -141,6 +141,12 @@ struct VariantMatchInfo {
   ISATraits.push_back(RawString);
 
 RequiredTraits.set(unsigned(Property));
+#if 0

shiltian wrote:

what is this for?

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-13 Thread Shilei Tian via cfe-commits

shiltian wrote:

@alexey-bataev What do you think? I'm not very familiar with some front end 
concepts used in this PR.

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-13 Thread Shilei Tian via cfe-commits

https://github.com/shiltian commented:

update the openmp doc as well?

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-12 Thread via cfe-commits

SunilKuravinakop wrote:

I ran `./install/bin/clang-tidy -p=build clang/lib/Sema/SemaOpenMP.cpp 
-checks=llvm-*` and did not find any changes being suggested for the code 
changes which I have done. Is there any other tool other than clang-tidy which 
I can run before uploading? I have been using git-clang-format for quite 
sometime now. 

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-10 Thread via cfe-commits


@@ -5965,6 +5967,266 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+return NewStmt;
+  }
+  return static_cast(nullptr);
+}
+
+/// replaceWithNewTraitsOrDirectCall() is for transforming the call traits.
+/// Call traits associated with a function call are removed and replaced with
+/// a direct call. For clause "nocontext" only, the direct call is then
+/// modified to have call traits for a non-dispatch variant.
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context,
+  Expr *AssocExpr,
+  SemaOpenMP *SemaPtr,
+  bool NoContext) {
+  BinaryOperator *BinaryCopyOpr = nullptr;
+  bool IsBinaryOp = false;
+  Expr *PseudoObjExprOrCall = AssocExpr;
+  if (auto *BinOprExpr = dyn_cast(AssocExpr)) {
+IsBinaryOp = true;
+BinaryCopyOpr = BinaryOperator::Create(
+Context, BinOprExpr->getLHS(), BinOprExpr->getRHS(),
+BinOprExpr->getOpcode(), BinOprExpr->getType(),
+BinOprExpr->getValueKind(), BinOprExpr->getObjectKind(),
+BinOprExpr->getOperatorLoc(), FPOptionsOverride());
+PseudoObjExprOrCall = BinaryCopyOpr->getRHS();
+  }
+
+  Expr *CallWithoutInvariants = PseudoObjExprOrCall;
+  // Change PseudoObjectExpr to a direct call
+  if (auto *PseudoObjExpr = dyn_cast(PseudoObjExprOrCall))
+CallWithoutInvariants = *((PseudoObjExpr->semantics_begin()) - 1);
+
+  Expr *FinalCall = CallWithoutInvariants; // For noinvariants clause
+  if (NoContext) {
+// example to explain the changes done for "nocontext" clause:
+//
+// #pragma omp declare variant(foo_variant_dispatch)
+//  match(construct = {dispatch})
+// #pragma omp declare variant(foo_variant_allCond)
+// match(user = {condition(1)})
+// ...
+// #pragma omp dispatch nocontext(cond_true)
+// foo(i, j); // with traits: CodeGen call to
+// foo_variant_dispatch(i,j)
+// dispatch construct is changed to:
+// if (cond_true) {
+//foo(i,j) // with traits: CodeGen call to foo_variant_allCond(i,j)
+// } else {
+//   #pragma omp dispatch
+//   foo(i,j)  // with traits: CodeGen call to foo_variant_dispatch(i,j)
+// }
+
+// Convert StmtResult to a CallExpr before calling ActOnOpenMPCall()
+auto *CallExprWithinStmt = cast(CallWithoutInvariants);
+int NumArgs = CallExprWithinStmt->getNumArgs();
+clang::Expr **Args = Cal

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-10 Thread via cfe-commits


@@ -5965,6 +5967,266 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+return NewStmt;
+  }
+  return static_cast(nullptr);

SunilKuravinakop wrote:

I am now returning an empty uninitialized StmtResult in case  the 
AssociatedStmt is not a "CapturedStmt".

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-10 Thread via cfe-commits

https://github.com/SunilKuravinakop updated 
https://github.com/llvm/llvm-project/pull/117904

>From 1703aa62cfe35538aedbacb28e907535e838248c Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop 
Date: Fri, 20 Sep 2024 01:41:29 -0500
Subject: [PATCH 1/5] Support for dispatch construct (Sema & Codegen) support.
 Support for clauses depend, novariants & nocontext.

---
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Basic/OpenMPKinds.h   |   6 +
 clang/include/clang/Sema/SemaOpenMP.h |   7 +
 clang/lib/Basic/OpenMPKinds.cpp   |   5 +
 clang/lib/CodeGen/CGStmt.cpp  |   2 +-
 clang/lib/CodeGen/CGStmtOpenMP.cpp|   4 +
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Sema/SemaOpenMP.cpp | 301 ++-
 clang/test/OpenMP/dispatch_codegen.cpp| 359 ++
 clang/test/OpenMP/dispatch_unsupported.c  |   7 -
 .../include/llvm/Frontend/OpenMP/OMPContext.h |   6 +
 11 files changed, 687 insertions(+), 14 deletions(-)
 create mode 100644 clang/test/OpenMP/dispatch_codegen.cpp
 delete mode 100644 clang/test/OpenMP/dispatch_unsupported.c

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8495884dcd058f..81b876f9fd85c5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11774,6 +11774,9 @@ def err_omp_clause_requires_dispatch_construct : Error<
   "'%0' clause requires 'dispatch' context selector">;
 def err_omp_append_args_with_varargs : Error<
   "'append_args' is not allowed with varargs functions">;
+def warn_omp_dispatch_clause_novariants_nocontext : Warning<
+  "only 'novariants' clause is supported when 'novariants' & 'nocontext' 
clauses occur on the same dispatch construct">,
+  InGroup;
 def err_openmp_vla_in_task_untied : Error<
   "variable length arrays are not supported in OpenMP tasking regions with 
'untied' clause">;
 def warn_omp_unterminated_declare_target : Warning<
diff --git a/clang/include/clang/Basic/OpenMPKinds.h 
b/clang/include/clang/Basic/OpenMPKinds.h
index 900ad6ca6d66f6..7579fab43dbb19 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -269,6 +269,12 @@ bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind);
 /// parallel', otherwise - false.
 bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind);
 
+/// Checks if the specified directive is a dispatch-kind directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a dispatch-like directive like 'omp
+/// dispatch', otherwise - false.
+bool isOpenMPDispatchDirective(OpenMPDirectiveKind DKind);
+
 /// Checks if the specified directive is a target code offload directive.
 /// \param DKind Specified directive.
 /// \return true - the directive is a target code offload directive like
diff --git a/clang/include/clang/Sema/SemaOpenMP.h 
b/clang/include/clang/Sema/SemaOpenMP.h
index 3d1cc4fab1c10f..80cee9e7583051 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -1462,6 +1462,13 @@ class SemaOpenMP : public SemaBase {
: OMPDeclareVariantScopes.back().TI;
   }
 
+  StmtResult transformDispatchDirective(OpenMPDirectiveKind Kind,
+const DeclarationNameInfo &DirName,
+OpenMPDirectiveKind CancelRegion,
+ArrayRef Clauses,
+Stmt *AStmt, SourceLocation StartLoc,
+SourceLocation EndLoc);
+
   /// The current `omp begin/end declare variant` scopes.
   SmallVector OMPDeclareVariantScopes;
 
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 62a13f01481b28..44ee63df46adb5 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -621,6 +621,11 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind 
DKind) {
  llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel);
 }
 
+bool clang::isOpenMPDispatchDirective(OpenMPDirectiveKind DKind) {
+  return DKind == OMPD_dispatch ||
+ llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
+}
+
 bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
   return DKind == OMPD_target ||
  llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 698baf853507f4..f3eedb79844378 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -417,7 +417,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, 
ArrayRef Attrs) {
 EmitOMPInteropDirective(cast(*S));
 break;
   case Stmt::OMPDispatchDirectiveClass:
-CGM.ErrorUnsupported(S, "OpenMP dispatch directive");
+   

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-10 Thread Shilei Tian via cfe-commits


@@ -5965,6 +5967,266 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+return NewStmt;
+  }
+  return static_cast(nullptr);

shiltian wrote:

I'm confused by this return. Why do you want to cast a `nullptr` to a `Stmt *`, 
and then implicit cast it to `StmtResult`?

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-10 Thread via cfe-commits

https://github.com/SunilKuravinakop updated 
https://github.com/llvm/llvm-project/pull/117904

>From 1703aa62cfe35538aedbacb28e907535e838248c Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop 
Date: Fri, 20 Sep 2024 01:41:29 -0500
Subject: [PATCH 1/4] Support for dispatch construct (Sema & Codegen) support.
 Support for clauses depend, novariants & nocontext.

---
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Basic/OpenMPKinds.h   |   6 +
 clang/include/clang/Sema/SemaOpenMP.h |   7 +
 clang/lib/Basic/OpenMPKinds.cpp   |   5 +
 clang/lib/CodeGen/CGStmt.cpp  |   2 +-
 clang/lib/CodeGen/CGStmtOpenMP.cpp|   4 +
 clang/lib/CodeGen/CodeGenFunction.h   |   1 +
 clang/lib/Sema/SemaOpenMP.cpp | 301 ++-
 clang/test/OpenMP/dispatch_codegen.cpp| 359 ++
 clang/test/OpenMP/dispatch_unsupported.c  |   7 -
 .../include/llvm/Frontend/OpenMP/OMPContext.h |   6 +
 11 files changed, 687 insertions(+), 14 deletions(-)
 create mode 100644 clang/test/OpenMP/dispatch_codegen.cpp
 delete mode 100644 clang/test/OpenMP/dispatch_unsupported.c

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8495884dcd058f..81b876f9fd85c5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11774,6 +11774,9 @@ def err_omp_clause_requires_dispatch_construct : Error<
   "'%0' clause requires 'dispatch' context selector">;
 def err_omp_append_args_with_varargs : Error<
   "'append_args' is not allowed with varargs functions">;
+def warn_omp_dispatch_clause_novariants_nocontext : Warning<
+  "only 'novariants' clause is supported when 'novariants' & 'nocontext' 
clauses occur on the same dispatch construct">,
+  InGroup;
 def err_openmp_vla_in_task_untied : Error<
   "variable length arrays are not supported in OpenMP tasking regions with 
'untied' clause">;
 def warn_omp_unterminated_declare_target : Warning<
diff --git a/clang/include/clang/Basic/OpenMPKinds.h 
b/clang/include/clang/Basic/OpenMPKinds.h
index 900ad6ca6d66f6..7579fab43dbb19 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -269,6 +269,12 @@ bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind);
 /// parallel', otherwise - false.
 bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind);
 
+/// Checks if the specified directive is a dispatch-kind directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a dispatch-like directive like 'omp
+/// dispatch', otherwise - false.
+bool isOpenMPDispatchDirective(OpenMPDirectiveKind DKind);
+
 /// Checks if the specified directive is a target code offload directive.
 /// \param DKind Specified directive.
 /// \return true - the directive is a target code offload directive like
diff --git a/clang/include/clang/Sema/SemaOpenMP.h 
b/clang/include/clang/Sema/SemaOpenMP.h
index 3d1cc4fab1c10f..80cee9e7583051 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -1462,6 +1462,13 @@ class SemaOpenMP : public SemaBase {
: OMPDeclareVariantScopes.back().TI;
   }
 
+  StmtResult transformDispatchDirective(OpenMPDirectiveKind Kind,
+const DeclarationNameInfo &DirName,
+OpenMPDirectiveKind CancelRegion,
+ArrayRef Clauses,
+Stmt *AStmt, SourceLocation StartLoc,
+SourceLocation EndLoc);
+
   /// The current `omp begin/end declare variant` scopes.
   SmallVector OMPDeclareVariantScopes;
 
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 62a13f01481b28..44ee63df46adb5 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -621,6 +621,11 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind 
DKind) {
  llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel);
 }
 
+bool clang::isOpenMPDispatchDirective(OpenMPDirectiveKind DKind) {
+  return DKind == OMPD_dispatch ||
+ llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
+}
+
 bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
   return DKind == OMPD_target ||
  llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 698baf853507f4..f3eedb79844378 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -417,7 +417,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, 
ArrayRef Attrs) {
 EmitOMPInteropDirective(cast(*S));
 break;
   case Stmt::OMPDispatchDirectiveClass:
-CGM.ErrorUnsupported(S, "OpenMP dispatch directive");
+   

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-10 Thread Shilei Tian via cfe-commits


@@ -5965,6 +5967,266 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+return NewStmt;
+  }
+  return static_cast(nullptr);
+}
+
+/// replaceWithNewTraitsOrDirectCall() is for transforming the call traits.
+/// Call traits associated with a function call are removed and replaced with
+/// a direct call. For clause "nocontext" only, the direct call is then
+/// modified to have call traits for a non-dispatch variant.
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context,
+  Expr *AssocExpr,
+  SemaOpenMP *SemaPtr,
+  bool NoContext) {
+  BinaryOperator *BinaryCopyOpr = nullptr;
+  bool IsBinaryOp = false;
+  Expr *PseudoObjExprOrCall = AssocExpr;
+  if (auto *BinOprExpr = dyn_cast(AssocExpr)) {
+IsBinaryOp = true;
+BinaryCopyOpr = BinaryOperator::Create(
+Context, BinOprExpr->getLHS(), BinOprExpr->getRHS(),
+BinOprExpr->getOpcode(), BinOprExpr->getType(),
+BinOprExpr->getValueKind(), BinOprExpr->getObjectKind(),
+BinOprExpr->getOperatorLoc(), FPOptionsOverride());
+PseudoObjExprOrCall = BinaryCopyOpr->getRHS();
+  }
+
+  Expr *CallWithoutInvariants = PseudoObjExprOrCall;
+  // Change PseudoObjectExpr to a direct call
+  if (auto *PseudoObjExpr = dyn_cast(PseudoObjExprOrCall))
+CallWithoutInvariants = *((PseudoObjExpr->semantics_begin()) - 1);
+
+  Expr *FinalCall = CallWithoutInvariants; // For noinvariants clause
+  if (NoContext) {
+// example to explain the changes done for "nocontext" clause:
+//
+// #pragma omp declare variant(foo_variant_dispatch)
+//  match(construct = {dispatch})
+// #pragma omp declare variant(foo_variant_allCond)
+// match(user = {condition(1)})
+// ...
+// #pragma omp dispatch nocontext(cond_true)
+// foo(i, j); // with traits: CodeGen call to
+// foo_variant_dispatch(i,j)
+// dispatch construct is changed to:
+// if (cond_true) {
+//foo(i,j) // with traits: CodeGen call to foo_variant_allCond(i,j)
+// } else {
+//   #pragma omp dispatch
+//   foo(i,j)  // with traits: CodeGen call to foo_variant_dispatch(i,j)
+// }
+
+// Convert StmtResult to a CallExpr before calling ActOnOpenMPCall()
+auto *CallExprWithinStmt = cast(CallWithoutInvariants);
+int NumArgs = CallExprWithinStmt->getNumArgs();
+clang::Expr **Args = Cal

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-10 Thread Shilei Tian via cfe-commits


@@ -5965,6 +5967,266 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+return NewStmt;
+  }
+  return static_cast(nullptr);
+}
+
+/// replaceWithNewTraitsOrDirectCall() is for transforming the call traits.
+/// Call traits associated with a function call are removed and replaced with
+/// a direct call. For clause "nocontext" only, the direct call is then
+/// modified to have call traits for a non-dispatch variant.
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context,
+  Expr *AssocExpr,
+  SemaOpenMP *SemaPtr,
+  bool NoContext) {
+  BinaryOperator *BinaryCopyOpr = nullptr;
+  bool IsBinaryOp = false;
+  Expr *PseudoObjExprOrCall = AssocExpr;
+  if (auto *BinOprExpr = dyn_cast(AssocExpr)) {
+IsBinaryOp = true;
+BinaryCopyOpr = BinaryOperator::Create(
+Context, BinOprExpr->getLHS(), BinOprExpr->getRHS(),
+BinOprExpr->getOpcode(), BinOprExpr->getType(),
+BinOprExpr->getValueKind(), BinOprExpr->getObjectKind(),
+BinOprExpr->getOperatorLoc(), FPOptionsOverride());
+PseudoObjExprOrCall = BinaryCopyOpr->getRHS();
+  }
+
+  Expr *CallWithoutInvariants = PseudoObjExprOrCall;
+  // Change PseudoObjectExpr to a direct call
+  if (auto *PseudoObjExpr = dyn_cast(PseudoObjExprOrCall))
+CallWithoutInvariants = *((PseudoObjExpr->semantics_begin()) - 1);
+
+  Expr *FinalCall = CallWithoutInvariants; // For noinvariants clause
+  if (NoContext) {
+// example to explain the changes done for "nocontext" clause:
+//
+// #pragma omp declare variant(foo_variant_dispatch)
+//  match(construct = {dispatch})
+// #pragma omp declare variant(foo_variant_allCond)
+// match(user = {condition(1)})
+// ...
+// #pragma omp dispatch nocontext(cond_true)
+// foo(i, j); // with traits: CodeGen call to
+// foo_variant_dispatch(i,j)
+// dispatch construct is changed to:
+// if (cond_true) {
+//foo(i,j) // with traits: CodeGen call to foo_variant_allCond(i,j)
+// } else {
+//   #pragma omp dispatch
+//   foo(i,j)  // with traits: CodeGen call to foo_variant_dispatch(i,j)
+// }
+
+// Convert StmtResult to a CallExpr before calling ActOnOpenMPCall()
+auto *CallExprWithinStmt = cast(CallWithoutInvariants);
+int NumArgs = CallExprWithinStmt->getNumArgs();
+clang::Expr **Args = Cal

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-10 Thread Shilei Tian via cfe-commits


@@ -5965,6 +5967,266 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+return NewStmt;
+  }
+  return static_cast(nullptr);
+}
+
+/// replaceWithNewTraitsOrDirectCall() is for transforming the call traits.
+/// Call traits associated with a function call are removed and replaced with
+/// a direct call. For clause "nocontext" only, the direct call is then
+/// modified to have call traits for a non-dispatch variant.
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context,
+  Expr *AssocExpr,
+  SemaOpenMP *SemaPtr,
+  bool NoContext) {
+  BinaryOperator *BinaryCopyOpr = nullptr;
+  bool IsBinaryOp = false;
+  Expr *PseudoObjExprOrCall = AssocExpr;
+  if (auto *BinOprExpr = dyn_cast(AssocExpr)) {
+IsBinaryOp = true;
+BinaryCopyOpr = BinaryOperator::Create(
+Context, BinOprExpr->getLHS(), BinOprExpr->getRHS(),
+BinOprExpr->getOpcode(), BinOprExpr->getType(),
+BinOprExpr->getValueKind(), BinOprExpr->getObjectKind(),
+BinOprExpr->getOperatorLoc(), FPOptionsOverride());
+PseudoObjExprOrCall = BinaryCopyOpr->getRHS();
+  }
+
+  Expr *CallWithoutInvariants = PseudoObjExprOrCall;
+  // Change PseudoObjectExpr to a direct call
+  if (auto *PseudoObjExpr = dyn_cast(PseudoObjExprOrCall))
+CallWithoutInvariants = *((PseudoObjExpr->semantics_begin()) - 1);
+
+  Expr *FinalCall = CallWithoutInvariants; // For noinvariants clause
+  if (NoContext) {
+// example to explain the changes done for "nocontext" clause:
+//
+// #pragma omp declare variant(foo_variant_dispatch)
+//  match(construct = {dispatch})
+// #pragma omp declare variant(foo_variant_allCond)
+// match(user = {condition(1)})
+// ...
+// #pragma omp dispatch nocontext(cond_true)
+// foo(i, j); // with traits: CodeGen call to
+// foo_variant_dispatch(i,j)
+// dispatch construct is changed to:
+// if (cond_true) {
+//foo(i,j) // with traits: CodeGen call to foo_variant_allCond(i,j)
+// } else {
+//   #pragma omp dispatch
+//   foo(i,j)  // with traits: CodeGen call to foo_variant_dispatch(i,j)
+// }
+
+// Convert StmtResult to a CallExpr before calling ActOnOpenMPCall()
+auto *CallExprWithinStmt = cast(CallWithoutInvariants);
+int NumArgs = CallExprWithinStmt->getNumArgs();
+clang::Expr **Args = Cal

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-10 Thread Shilei Tian via cfe-commits


@@ -5965,6 +5967,266 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema 
&SemaRef) {
   return Checker.teamsLoopCanBeParallelFor();
 }
 
+static Expr *getInitialExprFromCapturedExpr(Expr *Cond) {
+
+  Expr *SubExpr = Cond->IgnoreParenImpCasts();
+
+  if (auto *DeclRef = dyn_cast(SubExpr)) {
+if (auto *CapturedExprDecl =
+dyn_cast(DeclRef->getDecl())) {
+
+  // Retrieve the initial expression from the captured expression
+  return CapturedExprDecl->getInit();
+}
+  }
+  return nullptr;
+}
+
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context, Expr 
*,
+  SemaOpenMP *, bool);
+
+/// cloneAssociatedStmt() function is for cloning the Associated Statement
+/// present with a Directive and then modifying it. By this we avoid modifying
+/// the original Associated Statement.
+static StmtResult cloneAssociatedStmt(const ASTContext &Context, Stmt *StmtP,
+  SemaOpenMP *SemaPtr, bool NoContext) {
+  if (auto *AssocStmt = dyn_cast(StmtP)) {
+CapturedDecl *CDecl = AssocStmt->getCapturedDecl();
+Stmt *AssocExprStmt = AssocStmt->getCapturedStmt();
+auto *AssocExpr = dyn_cast(AssocExprStmt);
+Expr *NewCallOrPseudoObjOrBinExpr = replaceWithNewTraitsOrDirectCall(
+Context, AssocExpr, SemaPtr, NoContext);
+
+// Copy Current Captured Decl to a New Captured Decl for noting the
+// Annotation
+CapturedDecl *NewDecl =
+CapturedDecl::Create(const_cast(Context),
+ CDecl->getDeclContext(), CDecl->getNumParams());
+NewDecl->setBody(static_cast(NewCallOrPseudoObjOrBinExpr));
+for (unsigned I : llvm::seq(CDecl->getNumParams())) {
+  if (I != CDecl->getContextParamPosition())
+NewDecl->setParam(I, CDecl->getParam(I));
+  else
+NewDecl->setContextParam(I, CDecl->getContextParam());
+}
+
+// Create a New Captured Stmt containing the New Captured Decl
+SmallVector Captures;
+SmallVector CaptureInits;
+for (const CapturedStmt::Capture &Capture : AssocStmt->captures())
+  Captures.push_back(Capture);
+for (Expr *CaptureInit : AssocStmt->capture_inits())
+  CaptureInits.push_back(CaptureInit);
+auto *NewStmt = CapturedStmt::Create(
+Context, AssocStmt->getCapturedStmt(),
+AssocStmt->getCapturedRegionKind(), Captures, CaptureInits, NewDecl,
+const_cast(AssocStmt->getCapturedRecordDecl()));
+
+return NewStmt;
+  }
+  return static_cast(nullptr);
+}
+
+/// replaceWithNewTraitsOrDirectCall() is for transforming the call traits.
+/// Call traits associated with a function call are removed and replaced with
+/// a direct call. For clause "nocontext" only, the direct call is then
+/// modified to have call traits for a non-dispatch variant.
+static Expr *replaceWithNewTraitsOrDirectCall(const ASTContext &Context,
+  Expr *AssocExpr,
+  SemaOpenMP *SemaPtr,
+  bool NoContext) {
+  BinaryOperator *BinaryCopyOpr = nullptr;
+  bool IsBinaryOp = false;
+  Expr *PseudoObjExprOrCall = AssocExpr;
+  if (auto *BinOprExpr = dyn_cast(AssocExpr)) {
+IsBinaryOp = true;
+BinaryCopyOpr = BinaryOperator::Create(
+Context, BinOprExpr->getLHS(), BinOprExpr->getRHS(),
+BinOprExpr->getOpcode(), BinOprExpr->getType(),
+BinOprExpr->getValueKind(), BinOprExpr->getObjectKind(),
+BinOprExpr->getOperatorLoc(), FPOptionsOverride());
+PseudoObjExprOrCall = BinaryCopyOpr->getRHS();
+  }
+
+  Expr *CallWithoutInvariants = PseudoObjExprOrCall;
+  // Change PseudoObjectExpr to a direct call
+  if (auto *PseudoObjExpr = dyn_cast(PseudoObjExprOrCall))
+CallWithoutInvariants = *((PseudoObjExpr->semantics_begin()) - 1);
+
+  Expr *FinalCall = CallWithoutInvariants; // For noinvariants clause
+  if (NoContext) {
+// example to explain the changes done for "nocontext" clause:
+//
+// #pragma omp declare variant(foo_variant_dispatch)
+//  match(construct = {dispatch})
+// #pragma omp declare variant(foo_variant_allCond)
+// match(user = {condition(1)})
+// ...
+// #pragma omp dispatch nocontext(cond_true)
+// foo(i, j); // with traits: CodeGen call to
+// foo_variant_dispatch(i,j)
+// dispatch construct is changed to:
+// if (cond_true) {
+//foo(i,j) // with traits: CodeGen call to foo_variant_allCond(i,j)
+// } else {
+//   #pragma omp dispatch
+//   foo(i,j)  // with traits: CodeGen call to foo_variant_dispatch(i,j)
+// }
+
+// Convert StmtResult to a CallExpr before calling ActOnOpenMPCall()
+auto *CallExprWithinStmt = cast(CallWithoutInvariants);
+int NumArgs = CallExprWithinStmt->getNumArgs();
+clang::Expr **Args = Cal

[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-10 Thread Shilei Tian via cfe-commits


@@ -10520,11 +10794,22 @@ StmtResult 
SemaOpenMP::ActOnOpenMPSectionDirective(Stmt *AStmt,
  DSAStack->isCancelRegion());
 }
 
+/// PseudoObjectExpr is a Trait for dispatch containing the
+/// function and its variant. Returning only the function.
+static Expr *RemovePseudoObjectExpr(Expr *PseudoObjExprOrDirectCall) {

shiltian wrote:

```suggestion
static Expr *removePseudoObjectExpr(Expr *PseudoObjExprOrDirectCall) {
```

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-10 Thread Shilei Tian via cfe-commits


@@ -5979,6 +6241,17 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective(
   OMPExecutableDirective::getSingleClause(Clauses))
 BindKind = BC->getBindKind();
 
+  if ((Kind == OMPD_dispatch) && (Clauses.size() > 0)) {

shiltian wrote:

```suggestion
  if ((Kind == OMPD_dispatch) && (!Clauses.empty())) {
```

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-10 Thread Shilei Tian via cfe-commits


@@ -7209,8 +7482,9 @@ ExprResult SemaOpenMP::ActOnOpenMPCall(ExprResult Call, 
Scope *Scope,
 Exprs.erase(Exprs.begin() + BestIdx);
   } while (!VMIs.empty());
 
-  if (!NewCall.isUsable())
+  if (!NewCall.isUsable()) {
 return Call;
+  }

shiltian wrote:

unrelated

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-10 Thread Shilei Tian via cfe-commits


@@ -10556,15 +10841,18 @@ 
SemaOpenMP::ActOnOpenMPDispatchDirective(ArrayRef Clauses,
 E = E->IgnoreParenCasts()->IgnoreImplicit();
 
 if (auto *BO = dyn_cast(E)) {
-  if (BO->getOpcode() == BO_Assign)
+  if (BO->getOpcode() == BO_Assign) {
 TargetCall = getDirectCallExpr(BO->getRHS());
+  }
 } else {
   if (auto *COCE = dyn_cast(E))
 if (COCE->getOperator() == OO_Equal)
   TargetCall = getDirectCallExpr(COCE->getArg(1));
-  if (!TargetCall)
+  if (!TargetCall) {
 TargetCall = getDirectCallExpr(E);
+  }
 }
+

shiltian wrote:

unrelated changes

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


[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)

2024-12-10 Thread Shilei Tian via cfe-commits

https://github.com/shiltian edited 
https://github.com/llvm/llvm-project/pull/117904
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits