-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[flang] Do not use dialect conversion in AffineDialectPromotion
#156171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-flang-fir-hlfir Author: Matthias Springer (matthias-springer) ChangesThis pass uses the rewriter API incorrectly: it calls Instead of a dialect conversion, use the walk-patterns driver, which is also more efficient. Full diff: https://github.com/llvm/llvm-project/pull/156171.diff 1 Files Affected:
diff --git a/flang/lib/Optimizer/Transforms/AffinePromotion.cpp b/flang/lib/Optimizer/Transforms/AffinePromotion.cpp
index b032767eef6f0..061a7d201edd3 100644
--- a/flang/lib/Optimizer/Transforms/AffinePromotion.cpp
+++ b/flang/lib/Optimizer/Transforms/AffinePromotion.cpp
@@ -25,7 +25,7 @@
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/IntegerSet.h"
#include "mlir/IR/Visitors.h"
-#include "mlir/Transforms/DialectConversion.h"
+#include "mlir/Transforms/WalkPatternRewriteDriver.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Debug.h"
#include <optional>
@@ -451,10 +451,10 @@ static void rewriteStore(fir::StoreOp storeOp,
}
static void rewriteMemoryOps(Block *block, mlir::PatternRewriter &rewriter) {
- for (auto &bodyOp : block->getOperations()) {
+ for (auto &bodyOp : llvm::make_early_inc_range(block->getOperations())) {
if (isa<fir::LoadOp>(bodyOp))
rewriteLoad(cast<fir::LoadOp>(bodyOp), rewriter);
- if (isa<fir::StoreOp>(bodyOp))
+ else if (isa<fir::StoreOp>(bodyOp))
rewriteStore(cast<fir::StoreOp>(bodyOp), rewriter);
}
}
@@ -476,6 +476,8 @@ class AffineLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
loop.dump(););
LLVM_ATTRIBUTE_UNUSED auto loopAnalysis =
functionAnalysis.getChildLoopAnalysis(loop);
+ if (!loopAnalysis.canPromoteToAffine())
+ return rewriter.notifyMatchFailure(loop, "cannot promote to affine");
auto &loopOps = loop.getBody()->getOperations();
auto resultOp = cast<fir::ResultOp>(loop.getBody()->getTerminator());
auto results = resultOp.getOperands();
@@ -576,12 +578,14 @@ class AffineIfConversion : public mlir::OpRewritePattern<fir::IfOp> {
public:
using OpRewritePattern::OpRewritePattern;
AffineIfConversion(mlir::MLIRContext *context, AffineFunctionAnalysis &afa)
- : OpRewritePattern(context) {}
+ : OpRewritePattern(context), functionAnalysis(afa) {}
llvm::LogicalResult
matchAndRewrite(fir::IfOp op,
mlir::PatternRewriter &rewriter) const override {
LLVM_DEBUG(llvm::dbgs() << "AffineIfConversion: rewriting if:\n";
op.dump(););
+ if (!functionAnalysis.getChildIfAnalysis(op).canPromoteToAffine())
+ return rewriter.notifyMatchFailure(op, "cannot promote to affine");
auto &ifOps = op.getThenRegion().front().getOperations();
auto affineCondition = AffineIfCondition(op.getCondition());
if (!affineCondition.hasIntegerSet()) {
@@ -611,6 +615,8 @@ class AffineIfConversion : public mlir::OpRewritePattern<fir::IfOp> {
rewriter.replaceOp(op, affineIf.getOperation()->getResults());
return success();
}
+
+ AffineFunctionAnalysis &functionAnalysis;
};
/// Promote fir.do_loop and fir.if to affine.for and affine.if, in the cases
@@ -627,28 +633,11 @@ class AffineDialectPromotion
mlir::RewritePatternSet patterns(context);
patterns.insert<AffineIfConversion>(context, functionAnalysis);
patterns.insert<AffineLoopConversion>(context, functionAnalysis);
- mlir::ConversionTarget target = *context;
- target.addLegalDialect<mlir::affine::AffineDialect, FIROpsDialect,
- mlir::scf::SCFDialect, mlir::arith::ArithDialect,
- mlir::func::FuncDialect>();
- target.addDynamicallyLegalOp<IfOp>([&functionAnalysis](fir::IfOp op) {
- return !(functionAnalysis.getChildIfAnalysis(op).canPromoteToAffine());
- });
- target.addDynamicallyLegalOp<DoLoopOp>([&functionAnalysis](
- fir::DoLoopOp op) {
- return !(functionAnalysis.getChildLoopAnalysis(op).canPromoteToAffine());
- });
-
LLVM_DEBUG(llvm::dbgs()
<< "AffineDialectPromotion: running promotion on: \n";
function.print(llvm::dbgs()););
// apply the patterns
- if (mlir::failed(mlir::applyPartialConversion(function, target,
- std::move(patterns)))) {
- mlir::emitError(mlir::UnknownLoc::get(context),
- "error in converting to affine dialect\n");
- signalPassFailure();
- }
+ walkAndApplyPatterns(function, std::move(patterns));
}
};
} // namespace
|
43163c9
to
f4dbd0d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
f4dbd0d
to
fee875b
Compare
…eAllUsesWith` (#155244) This commit generalizes `replaceUsesOfBlockArgument` to `replaceAllUsesWith`. In rollback mode, the same restrictions keep applying: a value cannot be replaced multiple times and a call to `replaceAllUsesWith` will replace all current and future uses of the `from` value. `replaceAllUsesWith` is now fully supported and its behavior is consistent with the remaining dialect conversion API. Before this commit, `replaceAllUsesWith` was immediately reflected in the IR when running in rollback mode. After this commit, `replaceAllUsesWith` changes are materialized in a delayed fashion, at the end of the dialect conversion. This is consistent with the `replaceUsesOfBlockArgument` and `replaceOp` APIs. `replaceAllUsesExcept` etc. are still not supported and will be deactivated on the `ConversionPatternRewriter` (when running in rollback mode) in a follow-up commit. Note for LLVM integration: Replace `replaceUsesOfBlockArgument` with `replaceAllUsesWith`. If you are seeing failures, you may have patterns that use `replaceAllUsesWith` incorrectly (e.g., being called multiple times on the same value) or bypass the rewriter API entirely. E.g., such failures were mitigated in Flang by switching to the walk-patterns driver (#156171). You can temporarily reactivate the old behavior by calling `RewriterBase::replaceAllUsesWith`. However, note that that behavior is faulty in a dialect conversion. E.g., the base `RewriterBase::replaceAllUsesWith` implementation does not see uses of the `from` value that have not materialized yet and will, therefore, not replace them.
This pass uses the rewriter API incorrectly: it calls
replaceAllUsesWith
. This will start failing with #155244.Instead of a dialect conversion, use the walk-patterns driver, which is also more efficient.
Depends on #156169.