[clang] [llvm] [Clang][OpenMP] Support for dispatch construct (Sema & Codegen) support (PR #117904)
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)
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)
@@ -,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)
@@ -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)
@@ -,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)
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)
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)
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)
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)
@@ -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)
@@ -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)
@@ -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)
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)
@@ -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)
@@ -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)
@@ -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)
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)
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)
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)
@@ -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)
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)
@@ -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)
@@ -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)
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)
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)
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)
@@ -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)
@@ -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)
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)
@@ -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)
@@ -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)
@@ -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)
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)
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)
@@ -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)
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)
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)
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)
@@ -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)
@@ -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)
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)
@@ -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)
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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
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