[flang-commits] [flang] 7a49d50 - [flang] support fir.unreachable in stack arrays pass

Tom Eccles via flang-commits flang-commits at lists.llvm.org
Tue Feb 14 05:45:53 PST 2023


Author: Tom Eccles
Date: 2023-02-14T13:44:59Z
New Revision: 7a49d50f22ad577d91cda7904c8a162c2cecd4a8

URL: https://github.com/llvm/llvm-project/commit/7a49d50f22ad577d91cda7904c8a162c2cecd4a8
DIFF: https://github.com/llvm/llvm-project/commit/7a49d50f22ad577d91cda7904c8a162c2cecd4a8.diff

LOG: [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

Added: 
    

Modified: 
    flang/lib/Optimizer/Transforms/StackArrays.cpp
    flang/test/Transforms/stack-arrays.fir

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/Transforms/StackArrays.cpp b/flang/lib/Optimizer/Transforms/StackArrays.cpp
index a0cd6def7a38d..c0a981e5f5ee6 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<LatticePoint>(child);
+  auto joinOperationLattice = [&](mlir::Operation *op) {
+    const LatticePoint *lattice = solver.lookupState<LatticePoint>(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<mlir::Value> freedValues;
   point.appendFreedValues(freedValues);
 

diff  --git a/flang/test/Transforms/stack-arrays.fir b/flang/test/Transforms/stack-arrays.fir
index d34d662ca2c43..7b73bf0930743 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<!fir.array<42xi32>>
+  %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: }


        


More information about the flang-commits mailing list