@@ -35,39 +35,6 @@ struct InductionVariableInfo {
35
35
using LoopNestToIndVarMap =
36
36
llvm::MapVector<fir::DoLoopOp, InductionVariableInfo>;
37
37
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
-
71
38
// / For the \p doLoop parameter, find the operation that declares its iteration
72
39
// / variable or allocates memory for it.
73
40
// /
@@ -84,19 +51,20 @@ bool isIndVarUltimateOperand(mlir::Operation *op, fir::DoLoopOp doLoop) {
84
51
// / ```
85
52
// /
86
53
// / 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.
87
58
mlir::Operation *findLoopIterationVarMemDecl (fir::DoLoopOp doLoop) {
88
59
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
+ }
100
68
101
69
assert (result != nullptr && result.getDefiningOp () != nullptr );
102
70
return result.getDefiningOp ();
@@ -239,6 +207,10 @@ class DoConcurrentConversion : public mlir::OpConversionPattern<fir::DoLoopOp> {
239
207
mlir::LogicalResult
240
208
matchAndRewrite (fir::DoLoopOp doLoop, OpAdaptor adaptor,
241
209
mlir::ConversionPatternRewriter &rewriter) const override {
210
+ if (mapToDevice)
211
+ return doLoop.emitError (
212
+ " not yet implemented: Mapping `do concurrent` loops to device" );
213
+
242
214
looputils::LoopNestToIndVarMap loopNest;
243
215
bool hasRemainingNestedLoops =
244
216
failed (looputils::collectLoopNest (doLoop, loopNest));
@@ -407,8 +379,6 @@ class DoConcurrentConversionPass
407
379
408
380
if (mlir::failed (mlir::applyFullConversion (getOperation (), target,
409
381
std::move (patterns)))) {
410
- mlir::emitError (mlir::UnknownLoc::get (context),
411
- " error in converting do-concurrent op" );
412
382
signalPassFailure ();
413
383
}
414
384
}
0 commit comments