Skip to content

Commit 4ff1d0f

Browse files
[MLIR][OpenMP] Add support for declaring critical construct names
Add an operation omp.critical.declare to declare names/symbols of critical sections. Named omp.critical operations should use symbols declared by omp.critical.declare. Having a declare operation ensures that the names of critical sections are global and unique. In the lowering flow to LLVM IR, the OpenMP IRBuilder creates unique names for critical sections. Reviewed By: ftynse, jeanPerier Differential Revision: https://reviews.llvm.org/D108713
1 parent 406415a commit 4ff1d0f

File tree

6 files changed

+55
-9
lines changed

6 files changed

+55
-9
lines changed

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,21 @@ def MasterOp : OpenMP_Op<"master"> {
337337
//===----------------------------------------------------------------------===//
338338
// 2.17.1 critical Construct
339339
//===----------------------------------------------------------------------===//
340+
def CriticalDeclareOp : OpenMP_Op<"critical.declare", [Symbol]> {
341+
let summary = "declares a named critical section.";
342+
343+
let description = [{
344+
Declares a named critical section.
345+
346+
The name can be used in critical constructs in the dialect.
347+
}];
348+
349+
let arguments = (ins SymbolNameAttr:$sym_name);
350+
351+
let assemblyFormat = "$sym_name attr-dict";
352+
}
353+
354+
340355
// TODO: Autogenerate this from OMP.td in llvm/include/Frontend
341356
def omp_sync_hint_none: I32EnumAttrCase<"none", 0>;
342357
def omp_sync_hint_uncontended: I32EnumAttrCase<"uncontended", 1>;

mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,17 @@ static LogicalResult verifyCriticalOp(CriticalOp op) {
10071007
(op.hint().getValue() != SyncHintKind::none))
10081008
return op.emitOpError() << "must specify a name unless the effect is as if "
10091009
"hint(none) is specified";
1010+
1011+
if (op.nameAttr()) {
1012+
auto symbolRef = op.nameAttr().cast<SymbolRefAttr>();
1013+
auto decl =
1014+
SymbolTable::lookupNearestSymbolFrom<CriticalDeclareOp>(op, symbolRef);
1015+
if (!decl) {
1016+
return op.emitOpError() << "expected symbol reference " << symbolRef
1017+
<< " to point to a critical declaration";
1018+
}
1019+
}
1020+
10101021
return success();
10111022
}
10121023

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -833,14 +833,18 @@ LogicalResult OpenMPDialectLLVMIRTranslationInterface::convertOperation(
833833
.Case([&](omp::WsLoopOp) {
834834
return convertOmpWsLoop(*op, builder, moduleTranslation);
835835
})
836-
.Case<omp::YieldOp, omp::TerminatorOp, omp::ReductionDeclareOp>(
837-
[](auto op) {
838-
// `yield` and `terminator` can be just omitted. The block structure
839-
// was created in the region that handles their parent operation.
840-
// `reduction.declare` will be used by reductions and is not
841-
// converted directly, skip it.
842-
return success();
843-
})
836+
.Case<omp::YieldOp, omp::TerminatorOp, omp::ReductionDeclareOp,
837+
omp::CriticalDeclareOp>([](auto op) {
838+
// `yield` and `terminator` can be just omitted. The block structure
839+
// was created in the region that handles their parent operation.
840+
// `reduction.declare` will be used by reductions and is not
841+
// converted directly, skip it.
842+
// `critical.declare` is only used to declare names of critical
843+
// sections which will be used by `critical` ops and hence can be
844+
// ignored for lowering. The OpenMP IRBuilder will create unique
845+
// name for critical section names.
846+
return success();
847+
})
844848
.Default([&](Operation *inst) {
845849
return inst->emitError("unsupported OpenMP operation: ")
846850
<< inst->getName();

mlir/test/Dialect/OpenMP/invalid.mlir

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,10 +296,20 @@ func @foo(%lb : index, %ub : index, %step : index, %mem : memref<1xf32>) {
296296

297297
// -----
298298

299-
func @omp_critical() -> () {
299+
func @omp_critical1() -> () {
300300
// expected-error @below {{must specify a name unless the effect is as if hint(none) is specified}}
301301
omp.critical hint(nonspeculative) {
302302
omp.terminator
303303
}
304304
return
305305
}
306+
307+
// -----
308+
309+
func @omp_critical2() -> () {
310+
// expected-error @below {{expected symbol reference @excl to point to a critical declaration}}
311+
omp.critical(@excl) hint(speculative) {
312+
omp.terminator
313+
}
314+
return
315+
}

mlir/test/Dialect/OpenMP/ops.mlir

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,10 @@ func @reduction2(%lb : index, %ub : index, %step : index) {
367367
return
368368
}
369369

370+
// CHECK: omp.critical.declare
371+
// CHECK-LABEL: @mutex
372+
omp.critical.declare @mutex
373+
370374
// CHECK-LABEL: omp_critical
371375
func @omp_critical() -> () {
372376
omp.critical {

mlir/test/Target/LLVMIR/openmp-llvm.mlir

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,8 @@ llvm.func @collapse_wsloop(
541541

542542
// -----
543543

544+
omp.critical.declare @mutex
545+
544546
// CHECK-LABEL: @omp_critical
545547
llvm.func @omp_critical(%x : !llvm.ptr<i32>, %xval : i32) -> () {
546548
// CHECK: call void @__kmpc_critical_with_hint({{.*}}critical_user_.var{{.*}}, i32 0)

0 commit comments

Comments
 (0)