aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/ParseOpenMP.cpp
diff options
context:
space:
mode:
authorJohannes Doerfert <johannes@jdoerfert.de>2023-03-02 18:35:15 -0800
committerJohannes Doerfert <johannes@jdoerfert.de>2023-07-24 22:04:45 -0700
commitef9ec4bbcca2fa4f64df47bc426f1d1c59ea47e2 (patch)
treeb3f8edde0b515fde75774548bf3dbb07eb98e640 /clang/lib/Parse/ParseOpenMP.cpp
parentfb2a971c015fa991b47aa8d93bd97379c012cb68 (diff)
downloadllvm-ef9ec4bbcca2fa4f64df47bc426f1d1c59ea47e2.zip
llvm-ef9ec4bbcca2fa4f64df47bc426f1d1c59ea47e2.tar.gz
llvm-ef9ec4bbcca2fa4f64df47bc426f1d1c59ea47e2.tar.bz2
[OpenMP] Add the `ompx_attribute` clause for target directives
CUDA and HIP have kernel attributes to tune the code generation (in the backend). To reuse this functionality for OpenMP target regions we introduce the `ompx_attribute` clause that takes these kernel attributes and emits code as if they had been attached to the kernel fuction (which is implicitly generated). To limit the impact, we only support three kernel attributes: `amdgpu_waves_per_eu`, for AMDGPU `amdgpu_flat_work_group_size`, for AMDGPU `launch_bounds`, for NVPTX The existing implementations of those attributes are used for error checking and code generation. `ompx_attribute` can be attached to any executable target region and it can hold more than one kernel attribute. Differential Revision: https://reviews.llvm.org/D156184
Diffstat (limited to 'clang/lib/Parse/ParseOpenMP.cpp')
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 96d2e2c..66cabb1 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -3411,6 +3411,9 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
<< getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
break;
+ case OMPC_ompx_attribute:
+ Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
+ break;
default:
break;
}
@@ -3691,6 +3694,62 @@ OMPClause *Parser::ParseOpenMPInteropClause(OpenMPClauseKind Kind,
llvm_unreachable("Unexpected interop variable clause.");
}
+OMPClause *Parser::ParseOpenMPOMPXAttributesClause(bool ParseOnly) {
+ SourceLocation Loc = ConsumeToken();
+ // Parse '('.
+ BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
+ if (T.expectAndConsume(diag::err_expected_lparen_after,
+ getOpenMPClauseName(OMPC_ompx_attribute).data()))
+ return nullptr;
+
+ ParsedAttributes ParsedAttrs(AttrFactory);
+ ParseAttributes(PAKM_GNU | PAKM_CXX11, ParsedAttrs);
+
+ // Parse ')'.
+ if (T.consumeClose())
+ return nullptr;
+
+ if (ParseOnly)
+ return nullptr;
+
+ SmallVector<Attr *> Attrs;
+ for (const ParsedAttr &PA : ParsedAttrs) {
+ switch (PA.getKind()) {
+ case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
+ if (!PA.checkExactlyNumArgs(Actions, 2))
+ continue;
+ if (auto *A = Actions.CreateAMDGPUFlatWorkGroupSizeAttr(
+ PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1)))
+ Attrs.push_back(A);
+ continue;
+ case ParsedAttr::AT_AMDGPUWavesPerEU:
+ if (!PA.checkAtLeastNumArgs(Actions, 1) ||
+ !PA.checkAtMostNumArgs(Actions, 2))
+ continue;
+ if (auto *A = Actions.CreateAMDGPUWavesPerEUAttr(
+ PA, PA.getArgAsExpr(0),
+ PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) : nullptr))
+ Attrs.push_back(A);
+ continue;
+ case ParsedAttr::AT_CUDALaunchBounds:
+ if (!PA.checkAtLeastNumArgs(Actions, 1) ||
+ !PA.checkAtMostNumArgs(Actions, 2))
+ continue;
+ if (auto *A = Actions.CreateLaunchBoundsAttr(
+ PA, PA.getArgAsExpr(0),
+ PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) : nullptr))
+ Attrs.push_back(A);
+ continue;
+ default:
+ Diag(Loc, diag::warn_omp_invalid_attribute_for_ompx_attributes) << PA;
+ continue;
+ };
+ }
+
+ return Actions.ActOnOpenMPXAttributeClause(Attrs, Loc, T.getOpenLocation(),
+ T.getCloseLocation());
+}
+
/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
///
/// default-clause: