@@ -35,39 +35,6 @@ struct InductionVariableInfo {
3535using 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.
8758mlir::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 }
0 commit comments