@@ -49,8 +49,9 @@ struct AffineIfAnalysis;
49
49
// / second when doing rewrite.
50
50
struct AffineFunctionAnalysis {
51
51
explicit AffineFunctionAnalysis (mlir::func::FuncOp funcOp) {
52
- for (fir::DoLoopOp op : funcOp.getOps <fir::DoLoopOp>())
53
- loopAnalysisMap.try_emplace (op, op, *this );
52
+ funcOp->walk ([&](fir::DoLoopOp doloop) {
53
+ loopAnalysisMap.try_emplace (doloop, doloop, *this );
54
+ });
54
55
}
55
56
56
57
AffineLoopAnalysis getChildLoopAnalysis (fir::DoLoopOp op) const ;
@@ -102,10 +103,23 @@ struct AffineLoopAnalysis {
102
103
return true ;
103
104
}
104
105
106
+ bool analysisResults (fir::DoLoopOp loopOperation) {
107
+ if (loopOperation.getFinalValue () &&
108
+ !loopOperation.getResult (0 ).use_empty ()) {
109
+ LLVM_DEBUG (
110
+ llvm::dbgs ()
111
+ << " AffineLoopAnalysis: cannot promote loop final value\n " ;);
112
+ return false ;
113
+ }
114
+
115
+ return true ;
116
+ }
117
+
105
118
bool analyzeLoop (fir::DoLoopOp loopOperation,
106
119
AffineFunctionAnalysis &functionAnalysis) {
107
120
LLVM_DEBUG (llvm::dbgs () << " AffineLoopAnalysis: \n " ; loopOperation.dump (););
108
121
return analyzeMemoryAccess (loopOperation) &&
122
+ analysisResults (loopOperation) &&
109
123
analyzeBody (loopOperation, functionAnalysis);
110
124
}
111
125
@@ -461,14 +475,28 @@ class AffineLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
461
475
LLVM_ATTRIBUTE_UNUSED auto loopAnalysis =
462
476
functionAnalysis.getChildLoopAnalysis (loop);
463
477
auto &loopOps = loop.getBody ()->getOperations ();
478
+ auto resultOp = cast<fir::ResultOp>(loop.getBody ()->getTerminator ());
479
+ auto results = resultOp.getOperands ();
480
+ auto loopResults = loop->getResults ();
464
481
auto loopAndIndex = createAffineFor (loop, rewriter);
465
482
auto affineFor = loopAndIndex.first ;
466
483
auto inductionVar = loopAndIndex.second ;
467
484
485
+ if (loop.getFinalValue ()) {
486
+ results = results.drop_front ();
487
+ loopResults = loopResults.drop_front ();
488
+ }
489
+
468
490
rewriter.startOpModification (affineFor.getOperation ());
469
491
affineFor.getBody ()->getOperations ().splice (
470
492
std::prev (affineFor.getBody ()->end ()), loopOps, loopOps.begin (),
471
493
std::prev (loopOps.end ()));
494
+ rewriter.replaceAllUsesWith (loop.getRegionIterArgs (),
495
+ affineFor.getRegionIterArgs ());
496
+ if (!results.empty ()) {
497
+ rewriter.setInsertionPointToEnd (affineFor.getBody ());
498
+ rewriter.create <affine::AffineYieldOp>(resultOp->getLoc (), results);
499
+ }
472
500
rewriter.finalizeOpModification (affineFor.getOperation ());
473
501
474
502
rewriter.startOpModification (loop.getOperation ());
@@ -479,7 +507,8 @@ class AffineLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
479
507
480
508
LLVM_DEBUG (llvm::dbgs () << " AffineLoopConversion: loop rewriten to:\n " ;
481
509
affineFor.dump (););
482
- rewriter.replaceOp (loop, affineFor.getOperation ()->getResults ());
510
+ rewriter.replaceAllUsesWith (loopResults, affineFor->getResults ());
511
+ rewriter.eraseOp (loop);
483
512
return success ();
484
513
}
485
514
@@ -503,7 +532,7 @@ class AffineLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
503
532
ValueRange (op.getUpperBound ()),
504
533
mlir::AffineMap::get (0 , 1 ,
505
534
1 + mlir::getAffineSymbolExpr (0 , op.getContext ())),
506
- step);
535
+ step, op. getIterOperands () );
507
536
return std::make_pair (affineFor, affineFor.getInductionVar ());
508
537
}
509
538
@@ -528,7 +557,7 @@ class AffineLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
528
557
genericUpperBound.getResult (),
529
558
mlir::AffineMap::get (0 , 1 ,
530
559
1 + mlir::getAffineSymbolExpr (0 , op.getContext ())),
531
- 1 );
560
+ 1 , op. getIterOperands () );
532
561
rewriter.setInsertionPointToStart (affineFor.getBody ());
533
562
auto actualIndex = rewriter.create <affine::AffineApplyOp>(
534
563
op.getLoc (), actualIndexMap,
0 commit comments