Skip to content

Commit 2720590

Browse files
committed
Handle review comments
1 parent 20619fd commit 2720590

File tree

2 files changed

+45
-46
lines changed

2 files changed

+45
-46
lines changed

flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp

+16-46
Original file line numberDiff line numberDiff line change
@@ -35,39 +35,6 @@ struct InductionVariableInfo {
3535
using LoopNestToIndVarMap =
3636
llvm::MapVector<fir::DoLoopOp, InductionVariableInfo>;
3737

38-
/// Given an operation `op`, this returns true if one of `op`'s operands is
39-
/// "ultimately" the loop's induction variable. This helps in cases where the
40-
/// induction variable's use is "hidden" behind a convert/cast.
41-
///
42-
/// For example, give the following loop:
43-
/// ```
44-
/// fir.do_loop %ind_var = %lb to %ub step %s unordered {
45-
/// %ind_var_conv = fir.convert %ind_var : (index) -> i32
46-
/// fir.store %ind_var_conv to %i#1 : !fir.ref<i32>
47-
/// ...
48-
/// }
49-
/// ```
50-
///
51-
/// If \p op is the `fir.store` operation, then this function will return true
52-
/// since the IV is the "ultimate" operand to the `fir.store` op through the
53-
/// `%ind_var_conv` -> `%ind_var` conversion sequence.
54-
///
55-
/// For why this is useful, see its use in `findLoopIndVarMemDecl`.
56-
bool isIndVarUltimateOperand(mlir::Operation *op, fir::DoLoopOp doLoop) {
57-
while (op != nullptr && op->getNumOperands() > 0) {
58-
auto ivIt = llvm::find_if(op->getOperands(), [&](mlir::Value operand) {
59-
return operand == doLoop.getInductionVar();
60-
});
61-
62-
if (ivIt != op->getOperands().end())
63-
return true;
64-
65-
op = op->getOperand(0).getDefiningOp();
66-
}
67-
68-
return false;
69-
}
70-
7138
/// For the \p doLoop parameter, find the operation that declares its iteration
7239
/// variable or allocates memory for it.
7340
///
@@ -84,19 +51,20 @@ bool isIndVarUltimateOperand(mlir::Operation *op, fir::DoLoopOp doLoop) {
8451
/// ```
8552
///
8653
/// This function returns the `hlfir.declare` op for `%i`.
54+
///
55+
/// Note: The current implementation is dependent on how flang emits loop
56+
/// bodies; which is sufficient for the current simple test/use cases. If this
57+
/// proves to be insufficient, this should be made more generic.
8758
mlir::Operation *findLoopIterationVarMemDecl(fir::DoLoopOp doLoop) {
8859
mlir::Value result = nullptr;
89-
mlir::visitUsedValuesDefinedAbove(
90-
doLoop.getRegion(), [&](mlir::OpOperand *operand) {
91-
if (result)
92-
return;
93-
94-
if (isIndVarUltimateOperand(operand->getOwner(), doLoop)) {
95-
assert(result == nullptr &&
96-
"loop can have only one induction variable");
97-
result = operand->get();
98-
}
99-
});
60+
for (mlir::Operation &op : doLoop) {
61+
// The first `fir.store` op we come across should be the op that updates the
62+
// loop's iteration variable.
63+
if (auto storeOp = mlir::dyn_cast<fir::StoreOp>(op)) {
64+
result = storeOp.getMemref();
65+
break;
66+
}
67+
}
10068

10169
assert(result != nullptr && result.getDefiningOp() != nullptr);
10270
return result.getDefiningOp();
@@ -239,6 +207,10 @@ class DoConcurrentConversion : public mlir::OpConversionPattern<fir::DoLoopOp> {
239207
mlir::LogicalResult
240208
matchAndRewrite(fir::DoLoopOp doLoop, OpAdaptor adaptor,
241209
mlir::ConversionPatternRewriter &rewriter) const override {
210+
if (mapToDevice)
211+
return doLoop.emitError(
212+
"not yet implemented: Mapping `do concurrent` loops to device");
213+
242214
looputils::LoopNestToIndVarMap loopNest;
243215
bool hasRemainingNestedLoops =
244216
failed(looputils::collectLoopNest(doLoop, loopNest));
@@ -407,8 +379,6 @@ class DoConcurrentConversionPass
407379

408380
if (mlir::failed(mlir::applyFullConversion(getOperation(), target,
409381
std::move(patterns)))) {
410-
mlir::emitError(mlir::UnknownLoc::get(context),
411-
"error in converting do-concurrent op");
412382
signalPassFailure();
413383
}
414384
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: fir-opt --omp-do-concurrent-conversion="map-to=device" -verify-diagnostics %s
2+
3+
func.func @do_concurrent_basic() attributes {fir.bindc_name = "do_concurrent_basic"} {
4+
%0 = fir.alloca i32 {bindc_name = "i"}
5+
%1:2 = hlfir.declare %0 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
6+
%2 = fir.address_of(@_QFEa) : !fir.ref<!fir.array<10xi32>>
7+
%c10 = arith.constant 10 : index
8+
%3 = fir.shape %c10 : (index) -> !fir.shape<1>
9+
%4:2 = hlfir.declare %2(%3) {uniq_name = "_QFEa"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
10+
%c1_i32 = arith.constant 1 : i32
11+
%7 = fir.convert %c1_i32 : (i32) -> index
12+
%c10_i32 = arith.constant 10 : i32
13+
%8 = fir.convert %c10_i32 : (i32) -> index
14+
%c1 = arith.constant 1 : index
15+
16+
// expected-error@+2 {{not yet implemented: Mapping `do concurrent` loops to device}}
17+
// expected-error@below {{failed to legalize operation 'fir.do_loop'}}
18+
fir.do_loop %arg0 = %7 to %8 step %c1 unordered {
19+
%13 = fir.convert %arg0 : (index) -> i32
20+
fir.store %13 to %1#1 : !fir.ref<i32>
21+
%14 = fir.load %1#0 : !fir.ref<i32>
22+
%15 = fir.load %1#0 : !fir.ref<i32>
23+
%16 = fir.convert %15 : (i32) -> i64
24+
%17 = hlfir.designate %4#0 (%16) : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
25+
hlfir.assign %14 to %17 : i32, !fir.ref<i32>
26+
}
27+
28+
return
29+
}

0 commit comments

Comments
 (0)