diff --git a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp index c57f5140c29e..fdf24028c5f9 100644 --- a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp +++ b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp @@ -18,8 +18,8 @@ #include "flang/Optimizer/Dialect/FIROps.h" #include "flang/Optimizer/Dialect/FIRType.h" #include "flang/Optimizer/Dialect/Support/FIRContext.h" +#include "mlir/IR/Iterators.h" #include "mlir/Transforms/DialectConversion.h" -#include "mlir/Transforms/RegionUtils.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Debug.h" @@ -325,6 +325,25 @@ public: } }; +/// Simple DCE to erase fir.shape/shift/slice/unused shape operands after this +/// pass (fir.shape and like have no codegen). +/// mlir::RegionDCE is expensive and requires running +/// mlir::eraseUnreachableBlocks. It does things that are not needed here, like +/// removing unused block arguments. fir.shape/shift/slice cannot be block +/// arguments. +/// This helper does a naive backward walk of the IR. It is not even guaranteed +/// to walk blocks according to backward dominance, but that is good enough for +/// what is done here, fir.shape/shift/slice have no usages anymore. The +/// backward walk allows getting rid of most of the unused operands, it is not a +/// problem to leave some in the weird cases. +static void simpleDCE(mlir::RewriterBase &rewriter, mlir::Operation *op) { + op->walk( + [&](mlir::Operation *subOp) { + if (mlir::isOpTriviallyDead(subOp)) + rewriter.eraseOp(subOp); + }); +} + class CodeGenRewrite : public fir::impl::CodeGenRewriteBase { public: using CodeGenRewriteBase::CodeGenRewriteBase; @@ -356,7 +375,7 @@ public: } // Erase any residual (fir.shape, fir.slice...). mlir::IRRewriter rewriter(&context); - (void)mlir::runRegionDCE(rewriter, mod->getRegions()); + simpleDCE(rewriter, mod.getOperation()); } }; diff --git a/flang/test/Fir/declare-codegen.fir b/flang/test/Fir/declare-codegen.fir index c5879facb157..fe8d84ef2d19 100644 --- a/flang/test/Fir/declare-codegen.fir +++ b/flang/test/Fir/declare-codegen.fir @@ -38,3 +38,17 @@ func.func @useless_shape_with_duplicate_extent_operand(%arg0: !fir.ref>) { + %c10 = arith.constant 10 : index + %2 = fir.declare %arg0 typeparams %c10 {uniq_name = "live_code"} : (!fir.ref>, index) -> (!fir.ref>) + return +^bb2: // no predecessors + %3 = fir.declare %arg0 typeparams %c10 {uniq_name = "dead_code"} : (!fir.ref>, index) -> (!fir.ref>) + fir.unreachable +} +// NODECL-LABEL: func.func @unreachable_code( +// NODECL-NOT: uniq_name = "live_code" +// DECL-LABEL: func.func @unreachable_code( +// DECL: uniq_name = "live_code"