From 7a49d50f22ad577d91cda7904c8a162c2cecd4a8 Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Mon, 13 Feb 2023 15:45:47 +0000 Subject: [PATCH] [flang] support fir.unreachable in stack arrays pass Some functions (e.g. the main function) end with a call to the STOP statement instead of a func.return. This is lowered as a call to the stop runtime function followed by a fir.unreachable. fir.unreachable is a terminator and so this can cause functions to have no func.return. The stack arrays pass looks to see which heap allocations have always been freed by the time a function returns. Without any returns, the pass does not detect any freed allocations. This patch changes this behaviour so that fir.unreachable is checked as well as func.return. This allows 15 heap allocations for array temporaries in spec2017 exchange2's main function to be moved to the stack. Differential Revision: https://reviews.llvm.org/D143918 --- flang/lib/Optimizer/Transforms/StackArrays.cpp | 8 +++++--- flang/test/Transforms/stack-arrays.fir | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/flang/lib/Optimizer/Transforms/StackArrays.cpp b/flang/lib/Optimizer/Transforms/StackArrays.cpp index a0cd6de..c0a981e 100644 --- a/flang/lib/Optimizer/Transforms/StackArrays.cpp +++ b/flang/lib/Optimizer/Transforms/StackArrays.cpp @@ -431,12 +431,14 @@ void StackArraysAnalysisWrapper::analyseFunction(mlir::Operation *func) { } LatticePoint point{func}; - func->walk([&](mlir::func::ReturnOp child) { - const LatticePoint *lattice = solver.lookupState(child); + auto joinOperationLattice = [&](mlir::Operation *op) { + const LatticePoint *lattice = solver.lookupState(op); // there will be no lattice for an unreachable block if (lattice) point.join(*lattice); - }); + }; + func->walk([&](mlir::func::ReturnOp child) { joinOperationLattice(child); }); + func->walk([&](fir::UnreachableOp child) { joinOperationLattice(child); }); llvm::DenseSet freedValues; point.appendFreedValues(freedValues); diff --git a/flang/test/Transforms/stack-arrays.fir b/flang/test/Transforms/stack-arrays.fir index d34d662..7b73bf0 100644 --- a/flang/test/Transforms/stack-arrays.fir +++ b/flang/test/Transforms/stack-arrays.fir @@ -307,3 +307,20 @@ func.func @omp_placement1() { // CHECK-NEXT: } // CHECK-NEXT: return // CHECK-NEXT: } + +// function terminated by stop statement +func.func @stop_terminator() { + %0 = fir.allocmem !fir.array<42xi32> + fir.freemem %0 : !fir.heap> + %c0_i32 = arith.constant 0 : i32 + %false = arith.constant false + %none = fir.call @_FortranAStopStatement(%c0_i32, %false, %false) : (i32, i1, i1) -> none + fir.unreachable +} +// CHECK: func.func @stop_terminator() { +// CHECK-NEXT: fir.alloca !fir.array<42xi32> +// CHECK-NEXT: %[[ZERO:.*]] = arith.constant 0 : i32 +// CHECK-NEXT: %[[FALSE:.*]] = arith.constant false +// CHECK-NEXT: %[[NONE:.*]] = fir.call @_FortranAStopStatement(%[[ZERO]], %[[FALSE]], %[[FALSE]]) : (i32, i1, i1) -> none +// CHECK-NEXT: fir.unreachable +// CHECK-NEXT: } -- 2.7.4