-
Notifications
You must be signed in to change notification settings - Fork 12k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[OpenMP] Introduce support for OMPX extensions and taskgraph frontend #66919
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-openmp @llvm/pr-subscribers-clang-codegen ChangesThis patch introduces initial support for OpenMP experimental directives and clauses through the "ompx" sentinel. The "taskgraph" ompx directive frontend is implemented as a use case to interface with the existing OpenMP host runtime support for record and replay. The taskgraph directive generates an outlined region where instantiated tasks are recorded and replayed in subsequent executions, using the record & replay mechanism. The "__kmpc_taskgraph" function is implemented in the OpenMP runtime to wrap the existing "__kmpc_start_record_task" and "__kmpc_end_record_task" functions within the associated statement. The macro "OMPX_TASKGRAPH," previously necessary for building the record and replay mechanism, has been removed, as the record and replay mechanism has been tested in previous patches. The tests have been updated to make use of the new taskgraph directive instead of relying on raw runtime calls. Patch is 100.08 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/66919.diff 62 Files Affected:
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 1b91feabd584c50..ce5688b82920255 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -2140,7 +2140,11 @@ enum CXCursorKind {
*/
CXCursor_OMPScopeDirective = 306,
- CXCursor_LastStmt = CXCursor_OMPScopeDirective,
+ /** OpenMP taskgraph directive.
+ */
+ CXCursor_OMPTaskgraphDirective = 307,
+
+ CXCursor_LastStmt = CXCursor_OMPTaskgraphDirective,
/**
* Cursor that represents the translation unit itself.
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index d4146d52893ffb1..49fe2ea4070bddf 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3027,6 +3027,9 @@ DEF_TRAVERSE_STMT(OMPBarrierDirective,
DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPTaskgraphDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPTaskgroupDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h
index 2725747e051e728..4eba370ad7d362d 100644
--- a/clang/include/clang/AST/StmtOpenMP.h
+++ b/clang/include/clang/AST/StmtOpenMP.h
@@ -2729,6 +2729,55 @@ class OMPTaskwaitDirective : public OMPExecutableDirective {
}
};
+/// This represents '#pragma ompx taskgraph' directive.
+/// Available with OMPX extensions.
+///
+/// \code
+/// #pragma ompx taskgraph
+/// \endcode
+///
+class OMPTaskgraphDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPTaskgraphDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(OMPTaskgraphDirectiveClass,
+ llvm::omp::OMPD_taskgraph, StartLoc, EndLoc) {}
+
+ /// Build an empty directive.
+ ///
+ explicit OMPTaskgraphDirective()
+ : OMPExecutableDirective(OMPTaskgraphDirectiveClass,
+ llvm::omp::OMPD_taskgraph, SourceLocation(),
+ SourceLocation()) {}
+
+public:
+ /// Creates directive.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ ///
+ static OMPTaskgraphDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+
+ /// Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPTaskgraphDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTaskgraphDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp taskgroup' directive.
///
/// \code
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 178761bdcf4d5e3..f96715abeb58105 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1176,6 +1176,8 @@ def warn_pragma_ms_fenv_access : Warning<
def warn_pragma_extra_tokens_at_eol : Warning<
"extra tokens at end of '#pragma %0' - ignored">,
InGroup<IgnoredPragmas>;
+def err_omp_extension_without_ompx : Error<
+ "Using extension directive '%0' in #pragma omp instead of #pragma ompx">;
def warn_pragma_expected_comma : Warning<
"expected ',' in '#pragma %0'">, InGroup<IgnoredPragmas>;
def warn_pragma_expected_punc : Warning<
@@ -1400,6 +1402,12 @@ def warn_omp_unknown_assumption_clause_missing_id
def warn_omp_unknown_assumption_clause_without_args
: Warning<"%0 clause should not be followed by arguments; tokens will be ignored">,
InGroup<OpenMPClauses>;
+def warn_omp_extension_directive_not_enabled
+ : Warning<"OpenMP Extensions not enabled. Ignoring OpenMP Extension Directive '#pragma ompx %0'">,
+ InGroup<IgnoredPragmas>;
+def warn_omp_extension_clause_not_enabled
+ : Warning<"OpenMP Extensions not enabled. Ignoring OpenMP Extension Clause '%0'">,
+ InGroup<IgnoredPragmas>;
def note_omp_assumption_clause_continue_here
: Note<"the ignored tokens spans until here">;
def err_omp_declare_target_unexpected_clause: Error<
diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td
index cec301dfca2817b..10f3ed16a06259d 100644
--- a/clang/include/clang/Basic/StmtNodes.td
+++ b/clang/include/clang/Basic/StmtNodes.td
@@ -243,6 +243,7 @@ def OMPTaskDirective : StmtNode<OMPExecutableDirective>;
def OMPTaskyieldDirective : StmtNode<OMPExecutableDirective>;
def OMPBarrierDirective : StmtNode<OMPExecutableDirective>;
def OMPTaskwaitDirective : StmtNode<OMPExecutableDirective>;
+def OMPTaskgraphDirective : StmtNode<OMPExecutableDirective>;
def OMPTaskgroupDirective : StmtNode<OMPExecutableDirective>;
def OMPFlushDirective : StmtNode<OMPExecutableDirective>;
def OMPDepobjDirective : StmtNode<OMPExecutableDirective>;
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 72e8df8c793a7b6..d4e30368a985780 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -937,10 +937,13 @@ PRAGMA_ANNOTATION(pragma_opencl_extension)
// distinguish between a real pragma and a converted pragma. It is not marked
// as a PRAGMA_ANNOTATION because it doesn't get generated from a #pragma.
ANNOTATION(attr_openmp)
+ANNOTATION(attr_openmp_extension)
// The lexer produces these so that they only take effect when the parser
// handles #pragma omp ... directives.
PRAGMA_ANNOTATION(pragma_openmp)
PRAGMA_ANNOTATION(pragma_openmp_end)
+// For support of OpenMP extensions. These tokens handle #pragma ompx ... directives
+PRAGMA_ANNOTATION(pragma_openmp_extension)
// Annotations for loop pragma directives #pragma clang loop ...
// The lexer produces these so that they only take effect when the parser
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index f599b8b98d031fb..e8c014dfd0bf7a0 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -175,6 +175,7 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> FPContractHandler;
std::unique_ptr<PragmaHandler> OpenCLExtensionHandler;
std::unique_ptr<PragmaHandler> OpenMPHandler;
+ std::unique_ptr<PragmaHandler> OpenMPXHandler;
std::unique_ptr<PragmaHandler> PCSectionHandler;
std::unique_ptr<PragmaHandler> MSCommentHandler;
std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
@@ -2894,7 +2895,8 @@ class Parser : public CodeCompletionHandler {
}
void ParseOpenMPAttributeArgs(IdentifierInfo *AttrName,
- CachedTokens &OpenMPTokens);
+ CachedTokens &OpenMPTokens,
+ bool isOpenMPExtension);
void ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
CachedTokens &OpenMPTokens,
@@ -3400,6 +3402,14 @@ class Parser : public CodeCompletionHandler {
const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
Callback,
bool AllowScopeSpecifier);
+
+ /// Check if clause is extension and extensions are enabled.
+ ///
+ /// \param Kind Kind of the clause
+ /// \param Loc Location of the clause
+ ///
+ bool CheckOpenMPClauseExtension(OpenMPClauseKind Kind, SourceLocation Loc);
+
/// Parses declarative or executable directive.
///
/// \param StmtCtx The context in which we're parsing the directive.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 47379e00a7445e3..9ef6d2a7c9ca442 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11651,6 +11651,10 @@ class Sema final {
StmtResult ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// Called on well-formed '\#pragma ompx taskgraph'.
+ StmtResult ActOnOpenMPTaskgraphDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc);
/// Called on well-formed '\#pragma omp taskgroup'.
StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 9e115f2a5cce3f9..b6cab03730d284e 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -1954,6 +1954,7 @@ enum StmtCode {
STMT_OMP_ERROR_DIRECTIVE,
STMT_OMP_BARRIER_DIRECTIVE,
STMT_OMP_TASKWAIT_DIRECTIVE,
+ STMT_OMP_TASKGRAPH_DIRECTIVE,
STMT_OMP_FLUSH_DIRECTIVE,
STMT_OMP_DEPOBJ_DIRECTIVE,
STMT_OMP_SCAN_DIRECTIVE,
diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp
index 426b35848cb5c89..1978017a021b725 100644
--- a/clang/lib/AST/StmtOpenMP.cpp
+++ b/clang/lib/AST/StmtOpenMP.cpp
@@ -804,6 +804,21 @@ OMPTaskwaitDirective *OMPTaskwaitDirective::CreateEmpty(const ASTContext &C,
return createEmptyDirective<OMPTaskwaitDirective>(C, NumClauses);
}
+OMPTaskgraphDirective *OMPTaskgraphDirective::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+ auto *Dir = createDirective<OMPTaskgraphDirective>(
+ C, Clauses, AssociatedStmt, /*NumChildren=*/1, StartLoc, EndLoc);
+ return Dir;
+}
+
+OMPTaskgraphDirective *OMPTaskgraphDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ EmptyShell) {
+ return createEmptyDirective<OMPTaskgraphDirective>(
+ C, NumClauses, /*HasAssociatedStmt=*/true, /*NumChildren=*/1);
+}
+
OMPTaskgroupDirective *OMPTaskgroupDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *ReductionRef) {
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index a31aa0cfeeed8de..cd1793edf685ab9 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -854,6 +854,11 @@ void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
PrintOMPExecutableDirective(Node);
}
+void StmtPrinter::VisitOMPTaskgraphDirective(OMPTaskgraphDirective *Node) {
+ Indent() << "#pragma ompx taskgraph";
+ PrintOMPExecutableDirective(Node);
+}
+
void StmtPrinter::VisitOMPErrorDirective(OMPErrorDirective *Node) {
Indent() << "#pragma omp error";
PrintOMPExecutableDirective(Node);
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 27f71edd6f99b32..1fd98118c8eaab0 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -1054,6 +1054,10 @@ void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) {
VisitOMPExecutableDirective(S);
}
+void StmtProfiler::VisitOMPTaskgraphDirective(const OMPTaskgraphDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
void StmtProfiler::VisitOMPErrorDirective(const OMPErrorDirective *S) {
VisitOMPExecutableDirective(S);
}
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 86de067da134a0a..05221ac547ee722 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -834,6 +834,9 @@ void clang::getOpenMPCaptureRegions(
CaptureRegions.push_back(OMPD_teams);
CaptureRegions.push_back(OMPD_parallel);
break;
+ case OMPD_taskgraph:
+ CaptureRegions.push_back(OMPD_taskgraph);
+ break;
case OMPD_nothing:
CaptureRegions.push_back(OMPD_nothing);
break;
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 92b7c8d4aa546f0..fad9c70a935f672 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -60,6 +60,8 @@ class CGOpenMPRegionInfo : public CodeGenFunction::CGCapturedStmtInfo {
ParallelOutlinedRegion,
/// Region with outlined function for standalone 'task' directive.
TaskOutlinedRegion,
+ /// Region with outlined function for standalone 'taskgraph' directive.
+ TaskgraphOutlinedRegion,
/// Region for constructs that do not require function outlining,
/// like 'for', 'sections', 'atomic' etc. directives.
InlinedRegion,
@@ -234,6 +236,26 @@ class CGOpenMPTaskOutlinedRegionInfo final : public CGOpenMPRegionInfo {
const UntiedTaskActionTy &Action;
};
+/// API for captured statement code generation in OpenMP taskgraphs.
+class CGOpenMPTaskgraphRegionInfo final : public CGOpenMPRegionInfo {
+public:
+ CGOpenMPTaskgraphRegionInfo(const CapturedStmt &CS,
+ const RegionCodeGenTy &CodeGen)
+ : CGOpenMPRegionInfo(CS, TaskgraphOutlinedRegion, CodeGen,
+ llvm::omp::OMPD_taskgraph, false) {}
+
+ const VarDecl *getThreadIDVariable() const override { return 0; }
+
+ /// Get the name of the capture helper.
+ StringRef getHelperName() const override { return "taskgraph.omp_outlined."; }
+
+ static bool classof(const CGCapturedStmtInfo *Info) {
+ return CGOpenMPRegionInfo::classof(Info) &&
+ cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
+ TaskgraphOutlinedRegion;
+ }
+};
+
/// API for inlined captured statement code generation in OpenMP
/// constructs.
class CGOpenMPInlinedRegionInfo : public CGOpenMPRegionInfo {
@@ -5779,6 +5801,48 @@ void CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc,
Region->emitUntiedSwitch(CGF);
}
+void CGOpenMPRuntime::emitTaskgraphCall(CodeGenFunction &CGF,
+ SourceLocation Loc,
+ const OMPExecutableDirective &D) {
+ if (!CGF.HaveInsertPoint())
+ return;
+
+ // Building kmp_taskgraph_flags_t flags for kmpc_taskgraph. C.f., kmp.h
+ enum {
+ NowaitFlag = 0x1, // Not used yet.
+ ReRecordFlag = 0x2,
+ };
+
+ unsigned Flags = 0;
+
+ CodeGenFunction OutlinedCGF(CGM, true);
+
+ const CapturedStmt *CS = cast<CapturedStmt>(D.getAssociatedStmt());
+
+ auto &&BodyGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) {
+ CGF.EmitStmt(CS->getCapturedStmt());
+ };
+
+ LValue CapStruct = CGF.InitCapturedStruct(*CS);
+ CGOpenMPTaskgraphRegionInfo TaskgraphRegion(*CS, BodyGen);
+ CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(OutlinedCGF,
+ &TaskgraphRegion);
+ llvm::Function *FnT = OutlinedCGF.GenerateCapturedStmtFunction(*CS);
+
+ std::vector<llvm::Value *> Args{
+ emitUpdateLocation(CGF, Loc),
+ getThreadID(CGF, Loc),
+ CGF.Builder.getInt32(Flags),
+ CGF.Builder.getInt32(D.getBeginLoc().getHashValue()),
+ CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(FnT, CGM.VoidPtrTy),
+ CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
+ CapStruct.getPointer(OutlinedCGF), CGM.VoidPtrTy)};
+
+ CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
+ CGM.getModule(), OMPRTL___kmpc_taskgraph),
+ Args);
+}
+
void CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF,
OpenMPDirectiveKind InnerKind,
const RegionCodeGenTy &CodeGen,
@@ -6192,6 +6256,7 @@ const Expr *CGOpenMPRuntime::getNumTeamsExprForTargetDirective(
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
+ case OMPD_taskgraph:
case OMPD_taskgroup:
case OMPD_atomic:
case OMPD_flush:
@@ -8955,6 +9020,7 @@ getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
+ case OMPD_taskgraph:
case OMPD_taskgroup:
case OMPD_atomic:
case OMPD_flush:
@@ -9814,6 +9880,7 @@ void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S,
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
+ case OMPD_taskgraph:
case OMPD_taskgroup:
case OMPD_atomic:
case OMPD_flush:
@@ -10419,6 +10486,7 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall(
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
+ case OMPD_taskgraph:
case OMPD_taskgroup:
case OMPD_atomic:
case OMPD_flush:
@@ -12156,6 +12224,12 @@ void CGOpenMPSIMDRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
llvm_unreachable("Not supported in SIMD-only mode");
}
+void CGOpenMPSIMDRuntime::emitTaskgraphCall(CodeGenFunction &CGF,
+ SourceLocation Loc,
+ const OMPExecutableDirective &D) {
+ llvm_unreachable("Not supported in SIMD-only mode");
+}
+
void CGOpenMPSIMDRuntime::emitCancellationPointCall(
CodeGenFunction &CGF, SourceLocation Loc,
OpenMPDirectiveKind CancelRegion) {
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h
index 74b528d6cd7f8cc..3a81852c5c3596a 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.h
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -1332,6 +1332,10 @@ class CGOpenMPRuntime {
virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc,
const OMPTaskDataTy &Data);
+ /// Emit code for 'taskgraph' directive.
+ virtual void emitTaskgraphCall(CodeGenFunction &CGF, SourceLocation Loc,
+ const OMPExecutableDirective &D);
+
/// Emit code for 'cancellation point' construct.
/// \param CancelRegion Region kind for which the cancellation point must be
/// emitted.
@@ -2137,6 +2141,10 @@ class CGOpenMPSIMDRuntime final : public CGOpenMPRuntime {
void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc,
const OMPTaskDataTy &Data) override;
+ /// Emit code for 'taskgraph' directive.
+ void emitTaskgraphCall(CodeGenFunction &CGF, SourceLocation Loc,
+ const OMPExecutableDirective &D) override;
+
/// Emit code for 'cancellation point' construct.
/// \param CancelRegion Region kind for which the cancellation point must be
/// emitted.
diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
index 93819ab815add08..6c14dd918333266 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
@@ -618,6 +618,7 @@ static bool hasNestedSPMDDirective(ASTContext &Ctx,
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
+ case OMPD_taskgraph:
case OMPD_taskgroup:
case OMPD_atomic:
case OMPD_flush:
@@ -701,6 +702,7 @@ static bool supportsSPMDExecutionMode(ASTContext &Ctx,
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
+ case OMPD_taskgraph:
case OMPD_taskgroup:
case OMPD_atomic:
case OMPD_flush:
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 6674aa2409a5947..0ca1e159ce38e09 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -266,6 +266,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) {
case Stmt::OMPTaskwaitDirectiveClass:
EmitOMPTaskwaitDirective(cast<OMPTaskwaitDirective>(*S));
break;
+ case Stmt::OMPTaskgraphDirectiveClass:
+ EmitOMPTaskgraphDirective(cast<OMPTaskgraphDirective>(*S));
+ break;
case Stmt::OMPTaskgroupDirectiveClass:
EmitOMPTaskgroup...
[truncated]
|
ANNOTATION(attr_openmp_extension) | ||
// The lexer produces these so that they only take effect when the parser | ||
// handles #pragma omp ... directives. | ||
PRAGMA_ANNOTATION(pragma_openmp) | ||
PRAGMA_ANNOTATION(pragma_openmp_end) | ||
// For support of OpenMP extensions. These tokens handle #pragma ompx ... directives | ||
PRAGMA_ANNOTATION(pragma_openmp_extension) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try to reuse the existing tokens
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I implemented this part, but I couldn't find a way to reuse the tokens and maintain independence. We need to differentiate if it is an extension or not. What do you suggest we do to reuse a token and check if it is omp
or ompx
?
Since that is an extension, we have to check |
openmp/runtime/CMakeLists.txt
Outdated
@@ -347,10 +347,6 @@ if(LIBOMP_OMPD_SUPPORT AND ((NOT LIBOMP_OMPT_SUPPORT) OR (NOT "${CMAKE_SYSTEM_NA | |||
set(LIBOMP_OMPD_SUPPORT FALSE) | |||
endif() | |||
|
|||
# OMPX Taskgraph support |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if I asked it before, but if possible can we run some task benchmark suites, like BOLT, to see the overhead? If no overhead, it'd be great to remove the macro.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, do you know where can we find the BOLT benchmark suite? Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The easiest one off the top of my head is SPEC OMP 2012.
@jdoerfert ping |
Waiting for the evaluation, if possible |
Thanks Shilei, Chenle is working on the evaluation. The one aspect that we are still not sure what to do about is if we should split this up into multiple PRs or not. |
I'd prefer to split it into at least one front end and one runtime, both with proper tests. |
My concern is how to split it up is I do not know a set of features that can work independently to each other. We can add the ompx infrastructure in one, but it won't be used by anything in that PR. Will that be ok? |
By "ompx infrastructure" do you mean the frond end code? |
I mean front end code minus the taskgraph directive part. Just the part that allows for ompx to be used. If we include the taskgraph, then it will generate code that cannot be linked. So it would be a PR that will not work for programs. |
It's fine that it will generate code that cannot be linked, as long as we don't have runtime use. We just need to check generated IR. |
This patch introduces initial support for OpenMP experimental directives and clauses through the "ompx" sentinel. The "taskgraph" ompx directive frontend is implemented as a use case to interface with the existing OpenMP host runtime support for record and replay. The taskgraph directive generates an outlined region where instantiated tasks are recorded and replayed in subsequent executions, using the record & replay mechanism. The "__kmpc_taskgraph" function is implemented in the OpenMP runtime to wrap the existing "__kmpc_start_record_task" and "__kmpc_end_record_task" functions within the associated statement. The macro "OMPX_TASKGRAPH," previously necessary for building the record and replay mechanism, has been removed, as the record and replay mechanism has been tested in previous patches. The tests have been updated to make use of the new taskgraph directive instead of relying on raw runtime calls.
90702c1
to
ac32877
Compare
This patch is now only for the front end. @shiltian @alexey-bataev, let us know what you think about landing just this. We are going to push another PR with the runtime changes, and that one will include numbers for performance. |
Not all my previous comments were addressed/answered |
Sorry, @alexey-bataev, some were marked as resolved, and we did not see them. The wording on my previous question needed to be corrected, too. I did not mean to ask if this is ready to land as is but instead if the division of the original PR into just this front-end part is what you would suggest we do. |
Yes, this is what suggest |
} else if (!getLangOpts().OpenMPExtensions) { | ||
Diag(Loc, diag::warn_omp_extension_directive_not_enabled) | ||
<< getOpenMPDirectiveName(DKind); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I rather doubt there should be this check, better to enable ompx pragma handler only if getLangOpts().OpenMPExtensions is true.
struct PragmaNoOpenMPXHandler : public PragmaHandler { | ||
PragmaNoOpenMPXHandler() : PragmaHandler("ompx") {} | ||
void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, | ||
Token &FirstToken) override; | ||
}; | ||
|
||
struct PragmaOpenMPXHandler : public PragmaHandler { | ||
PragmaOpenMPXHandler() : PragmaHandler("ompx") {} | ||
void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, | ||
Token &FirstToken) override; | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why existing openmp handlers cannot be reused?
Hi @josemonsalve2 if you want to help move this along it would be best to break this into at least three separate PRs.
In whatever order makes sense to you. |
Hi Mike,
Thanks for the suggestion.
Chenle or Adrian divided this PR into multiple ones. They may be able to
provide info on it.
That was last year. I went on paternity leave and lost track of the
progress on these PRs. I have yet to find the time to pick up on this work.
I will post more once I get the chance. Sorry.
Jose
…On Wed, Feb 28, 2024 at 12:20 PM Mike Rice ***@***.***> wrote:
Hi @josemonsalve2 <https://github.com/josemonsalve2> if you want to help
move this along it would be best to break this into at least three separate
PRs.
1. Parsing/Sema/Serialization
2. CodeGen
3. Extension checking framework
In whatever order makes sense to you.
We've added several extension directives in our downstream so I should be
able to help here if you can break these up a bit.
—
Reply to this email directly, view it on GitHub
<#66919 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAMFHAC7GRQ5N4QNRFBVQ43YV5YO3AVCNFSM6AAAAAA5AEF27SVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNRZGU3TMOBQGU>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
--
---------------------------------------------------------------------------------------------
José Manuel Monsalve Díaz
Ingeniero Electrónico
|
Hi! Can someone post a link here to the PR for the OMP runtime changes? Thanks! |
Hi! This PR initially contained both frontend and runtime changes. However the runtime changes were reverted for easier review. The PR for runtime is not created yet, but you can find all the initial changes (frontend+runtime) in the first commit of this PR:[] 5314fbb) The record and replay mechanism commit is: (36d4e4c) We will now split this frontend PR in several ones, as @mikerice1969 suggested, and later create the runtime PR. |
This patch introduces initial support for OpenMP experimental directives and clauses through the "ompx" sentinel. The "taskgraph" ompx directive frontend is implemented as a use case to interface with the existing OpenMP host runtime support for record and replay.
The taskgraph directive generates an outlined region where instantiated tasks are recorded and replayed in subsequent executions, using the record & replay mechanism.