Skip to content

Commit ffc94b2

Browse files
committed
[mlir][OpenMP] Remove deprecated omp.reduction
This operation did not model the behaviour of reductions in the openmp standard. It has since been replaced by block arguments on the outer operation. See llvm#79308 and llvm#80019
1 parent d90159a commit ffc94b2

File tree

6 files changed

+10
-276
lines changed

6 files changed

+10
-276
lines changed

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

Lines changed: 7 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -277,13 +277,9 @@ def ParallelOp : OpenMP_Op<"parallel", [
277277
variable should be passed into the reduction region by value or by reference
278278
in `reduction_vars_byref`. Each reduction is identified by the accumulator
279279
it uses and accumulators must not be repeated in the same reduction. The
280-
`omp.reduction` operation accepts the accumulator and a partial value which
281-
is considered to be produced by the thread for the given reduction. If
282-
multiple values are produced for the same accumulator, i.e. there are
283-
multiple `omp.reduction`s, the last value is taken. The reduction
284-
declaration specifies how to combine the values from each thread into the
285-
final value, which is available in the accumulator after all the threads
286-
complete.
280+
reduction declaration specifies how to combine the values from each thread
281+
into the final value, which is available in the accumulator after all the
282+
threads complete.
287283

288284
The optional $proc_bind_val attribute controls the thread affinity for the execution
289285
of the parallel region.
@@ -449,13 +445,9 @@ def SectionsOp : OpenMP_Op<"sections", [AttrSizedOperandSegments,
449445
accumulator variables in `reduction_vars` and symbols referring to reduction
450446
declarations in the `reductions` attribute. Each reduction is identified
451447
by the accumulator it uses and accumulators must not be repeated in the same
452-
reduction. The `omp.reduction` operation accepts the accumulator and a
453-
partial value which is considered to be produced by the section for the
454-
given reduction. If multiple values are produced for the same accumulator,
455-
i.e. there are multiple `omp.reduction`s, the last value is taken. The
456-
reduction declaration specifies how to combine the values from each section
457-
into the final value, which is available in the accumulator after all the
458-
sections complete.
448+
reduction. The reduction declaration specifies how to combine the values
449+
from each section into the final value, which is available in the
450+
accumulator after all the sections complete.
459451

460452
The $allocators_vars and $allocate_vars parameters are a variadic list of values
461453
that specify the memory allocator to be used to obtain storage for private values.
@@ -1074,11 +1066,7 @@ def TaskloopOp : OpenMP_Op<"taskloop", [AttrSizedOperandSegments,
10741066
variables in `reduction_vars` or `in_reduction_vars` and symbols referring
10751067
to reduction declarations in the `reductions` or `in_reductions` attribute.
10761068
Each reduction is identified by the accumulator it uses and accumulators
1077-
must not be repeated in the same reduction. The `omp.reduction` operation
1078-
accepts the accumulator and a partial value which is considered to be
1079-
produced by the current loop iteration for the given reduction. If multiple
1080-
values are produced for the same accumulator, i.e. there are multiple
1081-
`omp.reduction`s, the last value is taken. The reduction declaration
1069+
must not be repeated in the same reduction. The reduction declaration
10821070
specifies how to combine the values from each iteration into the final
10831071
value, which is available in the accumulator after the loop completes.
10841072

@@ -2357,26 +2345,6 @@ def DeclareReductionOp : OpenMP_Op<"declare_reduction", [Symbol,
23572345
let hasRegionVerifier = 1;
23582346
}
23592347

2360-
//===----------------------------------------------------------------------===//
2361-
// 2.19.5.4 reduction clause
2362-
//===----------------------------------------------------------------------===//
2363-
2364-
def ReductionOp : OpenMP_Op<"reduction"> {
2365-
let summary = "reduction construct";
2366-
let description = [{
2367-
Indicates the value that is produced by the current reduction-participating
2368-
entity for a reduction requested in some ancestor. The reduction is
2369-
identified by the accumulator, but the value of the accumulator may not be
2370-
updated immediately.
2371-
}];
2372-
2373-
let arguments= (ins AnyType:$operand, OpenMP_PointerLikeType:$accumulator);
2374-
let assemblyFormat = [{
2375-
$operand `,` $accumulator attr-dict `:` type($operand) `,` type($accumulator)
2376-
}];
2377-
let hasVerifier = 1;
2378-
}
2379-
23802348
//===----------------------------------------------------------------------===//
23812349
// 8.2 requires directive
23822350
//===----------------------------------------------------------------------===//

mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -185,21 +185,6 @@ struct MapInfoOpConversion : public ConvertOpToLLVMPattern<omp::MapInfoOp> {
185185
}
186186
};
187187

188-
struct ReductionOpConversion : public ConvertOpToLLVMPattern<omp::ReductionOp> {
189-
using ConvertOpToLLVMPattern<omp::ReductionOp>::ConvertOpToLLVMPattern;
190-
LogicalResult
191-
matchAndRewrite(omp::ReductionOp curOp, OpAdaptor adaptor,
192-
ConversionPatternRewriter &rewriter) const override {
193-
if (isa<MemRefType>(curOp.getAccumulator().getType())) {
194-
// TODO: Support memref type in variable operands
195-
return rewriter.notifyMatchFailure(curOp, "memref is not supported yet");
196-
}
197-
rewriter.replaceOpWithNewOp<omp::ReductionOp>(
198-
curOp, TypeRange(), adaptor.getOperands(), curOp->getAttrs());
199-
return success();
200-
}
201-
};
202-
203188
template <typename OpType>
204189
struct MultiRegionOpConversion : public ConvertOpToLLVMPattern<OpType> {
205190
using ConvertOpToLLVMPattern<OpType>::ConvertOpToLLVMPattern;
@@ -246,9 +231,6 @@ void mlir::configureOpenMPToLLVMConversionLegality(
246231
return typeConverter.isLegal(op->getOperandTypes()) &&
247232
typeConverter.isLegal(op->getResultTypes());
248233
});
249-
target.addDynamicallyLegalOp<mlir::omp::ReductionOp>([&](Operation *op) {
250-
return typeConverter.isLegal(op->getOperandTypes());
251-
});
252234
target.addDynamicallyLegalOp<
253235
mlir::omp::AtomicUpdateOp, mlir::omp::CriticalOp, mlir::omp::TargetOp,
254236
mlir::omp::TargetDataOp, mlir::omp::LoopNestOp,
@@ -275,11 +257,11 @@ void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter,
275257
[&](omp::MapBoundsType type) -> Type { return type; });
276258

277259
patterns.add<
278-
AtomicReadOpConversion, MapInfoOpConversion, ReductionOpConversion,
260+
AtomicReadOpConversion, MapInfoOpConversion,
279261
MultiRegionOpConversion<omp::DeclareReductionOp>,
280262
MultiRegionOpConversion<omp::PrivateClauseOp>,
281263
RegionOpConversion<omp::CriticalOp>, RegionOpConversion<omp::LoopNestOp>,
282-
RegionOpConversion<omp::MasterOp>, ReductionOpConversion,
264+
RegionOpConversion<omp::MasterOp>,
283265
RegionOpConversion<omp::OrderedRegionOp>,
284266
RegionOpConversion<omp::ParallelOp>, RegionOpConversion<omp::WsloopOp>,
285267
RegionOpConversion<omp::SectionsOp>, RegionOpConversion<omp::SectionOp>,

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

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,7 +1789,7 @@ LogicalResult DistributeOp::verify() {
17891789
}
17901790

17911791
//===----------------------------------------------------------------------===//
1792-
// ReductionOp
1792+
// DeclareReductionOp
17931793
//===----------------------------------------------------------------------===//
17941794

17951795
static ParseResult parseAtomicReductionRegion(OpAsmParser &parser,
@@ -1881,21 +1881,6 @@ LogicalResult DeclareReductionOp::verifyRegions() {
18811881
return success();
18821882
}
18831883

1884-
LogicalResult ReductionOp::verify() {
1885-
auto *op = (*this)->getParentWithTrait<ReductionClauseInterface::Trait>();
1886-
if (!op)
1887-
return emitOpError() << "must be used within an operation supporting "
1888-
"reduction clause interface";
1889-
while (op) {
1890-
for (const auto &var :
1891-
cast<ReductionClauseInterface>(op).getAllReductionVars())
1892-
if (var == getAccumulator())
1893-
return success();
1894-
op = op->getParentWithTrait<ReductionClauseInterface::Trait>();
1895-
}
1896-
return emitOpError() << "the accumulator is not used by the parent";
1897-
}
1898-
18991884
//===----------------------------------------------------------------------===//
19001885
// TaskOp
19011886
//===----------------------------------------------------------------------===//

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

Lines changed: 0 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -333,54 +333,6 @@ convertOmpCritical(Operation &opInst, llvm::IRBuilderBase &builder,
333333
return success();
334334
}
335335

336-
/// Returns a reduction declaration that corresponds to the given reduction
337-
/// operation in the given container. Currently only supports reductions inside
338-
/// WsloopOp and ParallelOp but can be easily extended as long as the given
339-
/// construct implements getNumReductionVars.
340-
template <typename T>
341-
static std::optional<omp::DeclareReductionOp>
342-
findReductionDeclInContainer(T container, omp::ReductionOp reduction) {
343-
for (unsigned i = 0, e = container.getNumReductionVars(); i < e; ++i) {
344-
if (container.getReductionVars()[i] != reduction.getAccumulator())
345-
continue;
346-
347-
SymbolRefAttr reductionSymbol =
348-
cast<SymbolRefAttr>((*container.getReductions())[i]);
349-
auto declareOp =
350-
SymbolTable::lookupNearestSymbolFrom<omp::DeclareReductionOp>(
351-
container, reductionSymbol);
352-
return declareOp;
353-
}
354-
return std::nullopt;
355-
}
356-
357-
/// Searches for a reduction in a provided region and the regions
358-
/// it is nested in
359-
static omp::DeclareReductionOp findReductionDecl(Operation &containerOp,
360-
omp::ReductionOp reduction) {
361-
std::optional<omp::DeclareReductionOp> declareOp = std::nullopt;
362-
Operation *container = &containerOp;
363-
364-
while (!declareOp.has_value() && container) {
365-
// Check if current container is supported for reductions searches
366-
if (auto par = dyn_cast<omp::ParallelOp>(*container)) {
367-
declareOp = findReductionDeclInContainer(par, reduction);
368-
} else if (auto loop = dyn_cast<omp::WsloopOp>(*container)) {
369-
declareOp = findReductionDeclInContainer(loop, reduction);
370-
} else {
371-
break;
372-
}
373-
374-
// See if we can search parent for reductions as well
375-
container = containerOp.getParentOp();
376-
}
377-
378-
assert(declareOp.has_value() &&
379-
"reduction operation must be associated with a declaration");
380-
381-
return *declareOp;
382-
}
383-
384336
/// Populates `reductions` with reduction declarations used in the given loop.
385337
template <typename T>
386338
static void
@@ -1785,62 +1737,6 @@ convertOmpAtomicCapture(omp::AtomicCaptureOp atomicCaptureOp,
17851737
return updateGenStatus;
17861738
}
17871739

1788-
/// Converts an OpenMP reduction operation using OpenMPIRBuilder. Expects the
1789-
/// mapping between reduction variables and their private equivalents to have
1790-
/// been stored on the ModuleTranslation stack. Currently only supports
1791-
/// reduction within WsloopOp and ParallelOp, but can be easily extended.
1792-
static LogicalResult
1793-
convertOmpReductionOp(omp::ReductionOp reductionOp,
1794-
llvm::IRBuilderBase &builder,
1795-
LLVM::ModuleTranslation &moduleTranslation) {
1796-
// Find the declaration that corresponds to the reduction op.
1797-
omp::DeclareReductionOp declaration;
1798-
Operation *reductionParent = reductionOp->getParentOp();
1799-
if (dyn_cast<omp::ParallelOp>(reductionParent) ||
1800-
dyn_cast<omp::WsloopOp>(reductionParent)) {
1801-
declaration = findReductionDecl(*reductionParent, reductionOp);
1802-
} else {
1803-
llvm_unreachable("Unhandled reduction container");
1804-
}
1805-
assert(declaration && "could not find reduction declaration");
1806-
1807-
// Retrieve the mapping between reduction variables and their private
1808-
// equivalents.
1809-
const DenseMap<Value, llvm::Value *> *reductionVariableMap = nullptr;
1810-
moduleTranslation.stackWalk<OpenMPVarMappingStackFrame>(
1811-
[&](const OpenMPVarMappingStackFrame &frame) {
1812-
if (frame.mapping.contains(reductionOp.getAccumulator())) {
1813-
reductionVariableMap = &frame.mapping;
1814-
return WalkResult::interrupt();
1815-
}
1816-
return WalkResult::advance();
1817-
});
1818-
assert(reductionVariableMap && "couldn't find private reduction variables");
1819-
// Translate the reduction operation by emitting the body of the corresponding
1820-
// reduction declaration.
1821-
Region &reductionRegion = declaration.getReductionRegion();
1822-
llvm::Value *privateReductionVar =
1823-
reductionVariableMap->lookup(reductionOp.getAccumulator());
1824-
llvm::Value *reductionVal = builder.CreateLoad(
1825-
moduleTranslation.convertType(reductionOp.getOperand().getType()),
1826-
privateReductionVar);
1827-
1828-
moduleTranslation.mapValue(reductionRegion.front().getArgument(0),
1829-
reductionVal);
1830-
moduleTranslation.mapValue(
1831-
reductionRegion.front().getArgument(1),
1832-
moduleTranslation.lookupValue(reductionOp.getOperand()));
1833-
1834-
SmallVector<llvm::Value *> phis;
1835-
if (failed(inlineConvertOmpRegions(reductionRegion, "omp.reduction.body",
1836-
builder, moduleTranslation, &phis)))
1837-
return failure();
1838-
assert(phis.size() == 1 && "expected one value to be yielded from "
1839-
"the reduction body declaration region");
1840-
builder.CreateStore(phis[0], privateReductionVar);
1841-
return success();
1842-
}
1843-
18441740
/// Converts an OpenMP Threadprivate operation into LLVM IR using
18451741
/// OpenMPIRBuilder.
18461742
static LogicalResult
@@ -3349,9 +3245,6 @@ convertHostOrTargetOperation(Operation *op, llvm::IRBuilderBase &builder,
33493245
.Case([&](omp::ParallelOp op) {
33503246
return convertOmpParallel(op, builder, moduleTranslation);
33513247
})
3352-
.Case([&](omp::ReductionOp reductionOp) {
3353-
return convertOmpReductionOp(reductionOp, builder, moduleTranslation);
3354-
})
33553248
.Case([&](omp::MasterOp) {
33563249
return convertOmpMaster(*op, builder, moduleTranslation);
33573250
})

mlir/test/Dialect/OpenMP/invalid.mlir

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -639,90 +639,6 @@ cleanup {
639639

640640
// -----
641641

642-
func.func @foo(%lb : index, %ub : index, %step : index) {
643-
%c1 = arith.constant 1 : i32
644-
%0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
645-
%1 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
646-
647-
// expected-error @below {{expected symbol reference @foo to point to a reduction declaration}}
648-
omp.wsloop reduction(@foo %0 -> %prv : !llvm.ptr) {
649-
omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
650-
%2 = arith.constant 2.0 : f32
651-
omp.reduction %2, %1 : f32, !llvm.ptr
652-
omp.yield
653-
}
654-
omp.terminator
655-
}
656-
return
657-
}
658-
659-
// -----
660-
661-
omp.declare_reduction @add_f32 : f32
662-
init {
663-
^bb0(%arg: f32):
664-
%0 = arith.constant 0.0 : f32
665-
omp.yield (%0 : f32)
666-
}
667-
combiner {
668-
^bb1(%arg0: f32, %arg1: f32):
669-
%1 = arith.addf %arg0, %arg1 : f32
670-
omp.yield (%1 : f32)
671-
}
672-
673-
func.func @foo(%lb : index, %ub : index, %step : index) {
674-
%c1 = arith.constant 1 : i32
675-
%0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
676-
677-
// expected-error @below {{accumulator variable used more than once}}
678-
omp.wsloop reduction(@add_f32 %0 -> %prv : !llvm.ptr, @add_f32 %0 -> %prv1 : !llvm.ptr) {
679-
omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
680-
%2 = arith.constant 2.0 : f32
681-
omp.reduction %2, %0 : f32, !llvm.ptr
682-
omp.yield
683-
}
684-
omp.terminator
685-
}
686-
return
687-
}
688-
689-
// -----
690-
691-
omp.declare_reduction @add_f32 : f32
692-
init {
693-
^bb0(%arg: f32):
694-
%0 = arith.constant 0.0 : f32
695-
omp.yield (%0 : f32)
696-
}
697-
combiner {
698-
^bb1(%arg0: f32, %arg1: f32):
699-
%1 = arith.addf %arg0, %arg1 : f32
700-
omp.yield (%1 : f32)
701-
}
702-
atomic {
703-
^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):
704-
%2 = llvm.load %arg3 : !llvm.ptr -> f32
705-
llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32
706-
omp.yield
707-
}
708-
709-
func.func @foo(%lb : index, %ub : index, %step : index, %mem : memref<1xf32>) {
710-
%c1 = arith.constant 1 : i32
711-
712-
// expected-error @below {{expected accumulator ('memref<1xf32>') to be the same type as reduction declaration ('!llvm.ptr')}}
713-
omp.wsloop reduction(@add_f32 %mem -> %prv : memref<1xf32>) {
714-
omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
715-
%2 = arith.constant 2.0 : f32
716-
omp.reduction %2, %mem : f32, memref<1xf32>
717-
omp.yield
718-
}
719-
omp.terminator
720-
}
721-
return
722-
}
723-
724-
// -----
725-
726642
func.func @omp_critical2() -> () {
727643
// expected-error @below {{expected symbol reference @excl to point to a critical declaration}}
728644
omp.critical(@excl) {

0 commit comments

Comments
 (0)