Skip to content

Commit 711aa35

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 30d6c39 commit 711aa35

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
@@ -352,6 +352,21 @@ def MasterOp : OpenMP_Op<"master"> {
352352
//===----------------------------------------------------------------------===//
353353
// 2.17.1 critical Construct
354354
//===----------------------------------------------------------------------===//
355+
def CriticalDeclareOp : OpenMP_Op<"critical.declare", [Symbol]> {
356+
let summary = "declares a named critical section.";
357+
358+
let description = [{
359+
Declares a named critical section.
360+
361+
The name can be used in critical constructs in the dialect.
362+
}];
363+
364+
let arguments = (ins SymbolNameAttr:$sym_name);
365+
366+
let assemblyFormat = "$sym_name attr-dict";
367+
}
368+
369+
355370
// TODO: Autogenerate this from OMP.td in llvm/include/Frontend
356371
def omp_sync_hint_none: I32EnumAttrCase<"none", 0>;
357372
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
@@ -976,6 +976,17 @@ static LogicalResult verifyCriticalOp(CriticalOp op) {
976976
(op.hint().getValue() != SyncHintKind::none))
977977
return op.emitOpError() << "must specify a name unless the effect is as if "
978978
"hint(none) is specified";
979+
980+
if (op.nameAttr()) {
981+
auto symbolRef = op.nameAttr().cast<SymbolRefAttr>();
982+
auto decl =
983+
SymbolTable::lookupNearestSymbolFrom<CriticalDeclareOp>(op, symbolRef);
984+
if (!decl) {
985+
return op.emitOpError() << "expected symbol reference " << symbolRef
986+
<< " to point to a critical declaration";
987+
}
988+
}
989+
979990
return success();
980991
}
981992

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -805,14 +805,18 @@ LogicalResult OpenMPDialectLLVMIRTranslationInterface::convertOperation(
805805
.Case([&](omp::WsLoopOp) {
806806
return convertOmpWsLoop(*op, builder, moduleTranslation);
807807
})
808-
.Case<omp::YieldOp, omp::TerminatorOp, omp::ReductionDeclareOp>(
809-
[](auto op) {
810-
// `yield` and `terminator` can be just omitted. The block structure
811-
// was created in the region that handles their parent operation.
812-
// `reduction.declare` will be used by reductions and is not
813-
// converted directly, skip it.
814-
return success();
815-
})
808+
.Case<omp::YieldOp, omp::TerminatorOp, omp::ReductionDeclareOp,
809+
omp::CriticalDeclareOp>([](auto op) {
810+
// `yield` and `terminator` can be just omitted. The block structure
811+
// was created in the region that handles their parent operation.
812+
// `reduction.declare` will be used by reductions and is not
813+
// converted directly, skip it.
814+
// `critical.declare` is only used to declare names of critical
815+
// sections which will be used by `critical` ops and hence can be
816+
// ignored for lowering. The OpenMP IRBuilder will create unique
817+
// name for critical section names.
818+
return success();
819+
})
816820
.Default([&](Operation *inst) {
817821
return inst->emitError("unsupported OpenMP operation: ")
818822
<< 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
@@ -369,6 +369,10 @@ func @reduction2(%lb : index, %ub : index, %step : index) {
369369
return
370370
}
371371

372+
// CHECK: omp.critical.declare
373+
// CHECK-LABEL: @mutex
374+
omp.critical.declare @mutex
375+
372376
// CHECK-LABEL: omp_critical
373377
func @omp_critical() -> () {
374378
omp.critical {

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,8 @@ llvm.func @test_omp_wsloop_guided(%lb : i64, %ub : i64, %step : i64) -> () {
469469

470470
// -----
471471

472+
omp.critical.declare @mutex
473+
472474
// CHECK-LABEL: @omp_critical
473475
llvm.func @omp_critical(%x : !llvm.ptr<i32>, %xval : i32) -> () {
474476
// CHECK: call void @__kmpc_critical_with_hint({{.*}}critical_user_.var{{.*}}, i32 0)

0 commit comments

Comments
 (0)