Skip to content

Commit 55e5842

Browse files
authored
[mlir][OpenMP] Remove deprecated omp.reduction (#92732)
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 #79308 and #80019
1 parent 1d0e8b2 commit 55e5842

File tree

6 files changed

+10
-195
lines changed

6 files changed

+10
-195
lines changed

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

Lines changed: 7 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,9 @@ def ParallelOp : OpenMP_Op<"parallel", [
152152
variable should be passed into the reduction region by value or by reference
153153
in `reduction_vars_byref`. Each reduction is identified by the accumulator
154154
it uses and accumulators must not be repeated in the same reduction. The
155-
`omp.reduction` operation accepts the accumulator and a partial value which
156-
is considered to be produced by the thread for the given reduction. If
157-
multiple values are produced for the same accumulator, i.e. there are
158-
multiple `omp.reduction`s, the last value is taken. The reduction
159-
declaration specifies how to combine the values from each thread into the
160-
final value, which is available in the accumulator after all the threads
161-
complete.
155+
reduction declaration specifies how to combine the values from each thread
156+
into the final value, which is available in the accumulator after all the
157+
threads complete.
162158

163159
The optional $proc_bind_val attribute controls the thread affinity for the execution
164160
of the parallel region.
@@ -307,13 +303,9 @@ def SectionsOp : OpenMP_Op<"sections", [AttrSizedOperandSegments,
307303
accumulator variables in `reduction_vars` and symbols referring to reduction
308304
declarations in the `reductions` attribute. Each reduction is identified
309305
by the accumulator it uses and accumulators must not be repeated in the same
310-
reduction. The `omp.reduction` operation accepts the accumulator and a
311-
partial value which is considered to be produced by the section for the
312-
given reduction. If multiple values are produced for the same accumulator,
313-
i.e. there are multiple `omp.reduction`s, the last value is taken. The
314-
reduction declaration specifies how to combine the values from each section
315-
into the final value, which is available in the accumulator after all the
316-
sections complete.
306+
reduction. The reduction declaration specifies how to combine the values
307+
from each section into the final value, which is available in the
308+
accumulator after all the sections complete.
317309

318310
The $allocators_vars and $allocate_vars parameters are a variadic list of values
319311
that specify the memory allocator to be used to obtain storage for private values.
@@ -912,11 +904,7 @@ def TaskloopOp : OpenMP_Op<"taskloop", [AttrSizedOperandSegments,
912904
variables in `reduction_vars` or `in_reduction_vars` and symbols referring
913905
to reduction declarations in the `reductions` or `in_reductions` attribute.
914906
Each reduction is identified by the accumulator it uses and accumulators
915-
must not be repeated in the same reduction. The `omp.reduction` operation
916-
accepts the accumulator and a partial value which is considered to be
917-
produced by the current loop iteration for the given reduction. If multiple
918-
values are produced for the same accumulator, i.e. there are multiple
919-
`omp.reduction`s, the last value is taken. The reduction declaration
907+
must not be repeated in the same reduction. The reduction declaration
920908
specifies how to combine the values from each iteration into the final
921909
value, which is available in the accumulator after the loop completes.
922910

@@ -2159,24 +2147,4 @@ def DeclareReductionOp : OpenMP_Op<"declare_reduction", [Symbol,
21592147
let hasRegionVerifier = 1;
21602148
}
21612149

2162-
//===----------------------------------------------------------------------===//
2163-
// 2.19.5.4 reduction clause
2164-
//===----------------------------------------------------------------------===//
2165-
2166-
def ReductionOp : OpenMP_Op<"reduction"> {
2167-
let summary = "reduction construct";
2168-
let description = [{
2169-
Indicates the value that is produced by the current reduction-participating
2170-
entity for a reduction requested in some ancestor. The reduction is
2171-
identified by the accumulator, but the value of the accumulator may not be
2172-
updated immediately.
2173-
}];
2174-
2175-
let arguments= (ins AnyType:$operand, OpenMP_PointerLikeType:$accumulator);
2176-
let assemblyFormat = [{
2177-
$operand `,` $accumulator attr-dict `:` type($operand) `,` type($accumulator)
2178-
}];
2179-
let hasVerifier = 1;
2180-
}
2181-
21822150
#endif // OPENMP_OPS

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
@@ -334,54 +334,6 @@ convertOmpCritical(Operation &opInst, llvm::IRBuilderBase &builder,
334334
return success();
335335
}
336336

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

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

mlir/test/Dialect/OpenMP/invalid.mlir

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,6 @@ func.func @foo(%lb : index, %ub : index, %step : index) {
648648
omp.wsloop reduction(@foo %0 -> %prv : !llvm.ptr) {
649649
omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
650650
%2 = arith.constant 2.0 : f32
651-
omp.reduction %2, %1 : f32, !llvm.ptr
652651
omp.yield
653652
}
654653
omp.terminator
@@ -678,7 +677,6 @@ func.func @foo(%lb : index, %ub : index, %step : index) {
678677
omp.wsloop reduction(@add_f32 %0 -> %prv : !llvm.ptr, @add_f32 %0 -> %prv1 : !llvm.ptr) {
679678
omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
680679
%2 = arith.constant 2.0 : f32
681-
omp.reduction %2, %0 : f32, !llvm.ptr
682680
omp.yield
683681
}
684682
omp.terminator
@@ -713,7 +711,6 @@ func.func @foo(%lb : index, %ub : index, %step : index, %mem : memref<1xf32>) {
713711
omp.wsloop reduction(@add_f32 %mem -> %prv : memref<1xf32>) {
714712
omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
715713
%2 = arith.constant 2.0 : f32
716-
omp.reduction %2, %mem : f32, memref<1xf32>
717714
omp.yield
718715
}
719716
omp.terminator

mlir/test/Dialect/OpenMP/ops.mlir

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,8 +1003,6 @@ func.func @omp_teams(%lb : i32, %ub : i32, %if_cond : i1, %num_threads : i32,
10031003
// CHECK: omp.teams reduction(@add_f32 -> %{{.+}} : !llvm.ptr) {
10041004
omp.teams reduction(@add_f32 -> %0 : !llvm.ptr) {
10051005
%1 = arith.constant 2.0 : f32
1006-
// CHECK: omp.reduction %{{.+}}, %{{.+}}
1007-
omp.reduction %1, %0 : f32, !llvm.ptr
10081006
// CHECK: omp.terminator
10091007
omp.terminator
10101008
}
@@ -1028,15 +1026,11 @@ func.func @sections_reduction() {
10281026
// CHECK: omp.section
10291027
omp.section {
10301028
%1 = arith.constant 2.0 : f32
1031-
// CHECK: omp.reduction %{{.+}}, %{{.+}}
1032-
omp.reduction %1, %0 : f32, !llvm.ptr
10331029
omp.terminator
10341030
}
10351031
// CHECK: omp.section
10361032
omp.section {
10371033
%1 = arith.constant 3.0 : f32
1038-
// CHECK: omp.reduction %{{.+}}, %{{.+}}
1039-
omp.reduction %1, %0 : f32, !llvm.ptr
10401034
omp.terminator
10411035
}
10421036
omp.terminator
@@ -1130,14 +1124,10 @@ func.func @sections_reduction2() {
11301124
omp.sections reduction(@add2_f32 -> %0 : memref<1xf32>) {
11311125
omp.section {
11321126
%1 = arith.constant 2.0 : f32
1133-
// CHECK: omp.reduction
1134-
omp.reduction %1, %0 : f32, memref<1xf32>
11351127
omp.terminator
11361128
}
11371129
omp.section {
11381130
%1 = arith.constant 2.0 : f32
1139-
// CHECK: omp.reduction
1140-
omp.reduction %1, %0 : f32, memref<1xf32>
11411131
omp.terminator
11421132
}
11431133
omp.terminator

0 commit comments

Comments
 (0)