Skip to content

Commit 2e637db

Browse files
authored
[flang] Canonicalize redundant pointer converts. (#121864)
This patch adds a canonicalization pattern for optimizing redundant "pointer" fir.converts. Such converts prevent the StackArrays pass to recognize fir.freemem for the corresponding fir.allocmem, e.g.: ``` %69 = fir.allocmem !fir.array<2xi32> %71:2 = hlfir.declare %69(%70) {uniq_name = ".tmp.arrayctor"} : (!fir.heap<!fir.array<2xi32>>, !fir.shape<1>) -> (!fir.heap<!fir.array<2xi32>>, !fir.heap<!fir.array<2xi32>>) %95 = fir.convert %71#1 : (!fir.heap<!fir.array<2xi32>>) -> !fir.ref<!fir.array<2xi32>> %100 = fir.convert %95 : (!fir.ref<!fir.array<2xi32>>) -> !fir.heap<!fir.array<2xi32>> fir.freemem %100 : !fir.heap<!fir.array<2xi32>> ``` I found this in `tonto`, but the change does not affect performance at all. Anyway, it looks like a reasonable thing to do, and it makes easier to compare the performance profiles with other compilers'.
1 parent 51c9c82 commit 2e637db

File tree

5 files changed

+30
-5
lines changed

5 files changed

+30
-5
lines changed

flang/include/flang/Optimizer/Dialect/CanonicalizationPatterns.td

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ def StrictSmallerWidthPred : Constraint<CPred<
5757
"$0.getType().getIntOrFloatBitWidth() < "
5858
"$1.getType().getIntOrFloatBitWidth()">>;
5959

60+
def PointerCompatiblePred
61+
: Constraint<CPred<"fir::ConvertOp::isPointerCompatible($0.getType())">>;
62+
6063
// floats or ints that undergo successive extensions or successive truncations.
6164
def ConvertConvertOptPattern
6265
: Pat<(fir_ConvertOp:$res (fir_ConvertOp:$irm $arg)),
@@ -112,4 +115,18 @@ def ForwardConstantConvertPattern
112115
(createConstantOp $res, $attr),
113116
[(IndexTypePred $res), (IntegerTypePred $cnt)]>;
114117

118+
// Optimize redundant pointer conversions, e.g.:
119+
// %1 = fir.convert %0 :
120+
// (!fir.heap<!fir.array<2xf32>>) -> !fir.ref<!fir.array<2xf32>>
121+
// %2 = fir.convert %1 :
122+
// (!fir.ref<!fir.array<2xf32>>) -> !fir.heap<!fir.array<2xf32>>
123+
// Will be optimized into:
124+
// %2 = fir.convert %0 :
125+
// (!fir.heap<!fir.array<2xf32>>) -> !fir.heap<!fir.array<2xf32>>
126+
// which is redundant due to RedundantConvertOptPattern.
127+
def ChainedPointerConvertsPattern
128+
: Pat<(fir_ConvertOp:$res(fir_ConvertOp:$irm $arg)), (fir_ConvertOp $arg),
129+
[(PointerCompatiblePred $arg), (PointerCompatiblePred $irm),
130+
(PointerCompatiblePred $res)]>;
131+
115132
#endif // FORTRAN_FIR_REWRITE_PATTERNS

flang/lib/Optimizer/Dialect/FIROps.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1313,7 +1313,8 @@ void fir::ConvertOp::getCanonicalizationPatterns(
13131313
results.insert<ConvertConvertOptPattern, ConvertAscendingIndexOptPattern,
13141314
ConvertDescendingIndexOptPattern, RedundantConvertOptPattern,
13151315
CombineConvertOptPattern, CombineConvertTruncOptPattern,
1316-
ForwardConstantConvertPattern>(context);
1316+
ForwardConstantConvertPattern, ChainedPointerConvertsPattern>(
1317+
context);
13171318
}
13181319

13191320
mlir::OpFoldResult fir::ConvertOp::fold(FoldAdaptor adaptor) {

flang/test/Fir/convert-fold.fir

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,12 @@ func.func @ctest() -> index {
3535
// CHECK-NEXT: return %{{.*}} : index
3636
return %2 : index
3737
}
38+
39+
// CHECK-LABEL: func.func @ptrtest(
40+
// CHECK-SAME: %[[VAL_0:.*]]: !fir.heap<!fir.array<2xf32>>) -> !fir.heap<!fir.array<2xf32>> {
41+
func.func @ptrtest(%0 : !fir.heap<!fir.array<2xf32>>) -> !fir.heap<!fir.array<2xf32>> {
42+
%1 = fir.convert %0 : (!fir.heap<!fir.array<2xf32>>) -> !fir.ref<!fir.array<2xf32>>
43+
%2 = fir.convert %1 : (!fir.ref<!fir.array<2xf32>>) -> !fir.heap<!fir.array<2xf32>>
44+
// CHECK: return %[[VAL_0]] : !fir.heap<!fir.array<2xf32>>
45+
return %2 : !fir.heap<!fir.array<2xf32>>
46+
}

flang/test/Lower/array-substring.f90

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@
2424
! CHECK: %[[VAL_16:.*]] = fir.array_coor %[[VAL_7]](%[[VAL_9]]) {{\[}}%[[VAL_10]]] %[[VAL_15]] : (!fir.ref<!fir.array<1x!fir.char<1,12>>>, !fir.shape<1>, !fir.slice<1>, index) -> !fir.ref<!fir.char<1,12>>
2525
! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (!fir.ref<!fir.char<1,12>>) -> !fir.ref<!fir.array<12x!fir.char<1>>>
2626
! CHECK: %[[VAL_18:.*]] = fir.coordinate_of %[[VAL_17]], %[[VAL_2]] : (!fir.ref<!fir.array<12x!fir.char<1>>>, index) -> !fir.ref<!fir.char<1>>
27-
! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<!fir.char<1,?>>
2827
! CHECK: %[[VAL_20:.*]] = fir.array_coor %[[VAL_11]](%[[VAL_9]]) %[[VAL_15]] : (!fir.ref<!fir.array<1x!fir.char<1,8>>>, !fir.shape<1>, index) -> !fir.ref<!fir.char<1,8>>
29-
! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
28+
! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_18]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<i8>
3029
! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.ref<!fir.char<1,8>>) -> !fir.ref<i8>
3130
! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
3231
! CHECK: %[[VAL_24:.*]] = fir.call @_FortranACharacterCompareScalar1(%[[VAL_21]], %[[VAL_22]], %[[VAL_23]], %[[VAL_23]]) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64, i64) -> i32

flang/test/Lower/vector-subscript-io.f90

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,12 +325,11 @@ subroutine substring(x, y, i, j)
325325
! CHECK: %[[VAL_230:.*]] = arith.subi %[[VAL_216]], %[[VAL_210]] : index
326326
! CHECK: %[[VAL_231:.*]] = fir.convert %[[VAL_228]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.array<?x!fir.char<1>>>
327327
! CHECK: %[[VAL_232:.*]] = fir.coordinate_of %[[VAL_231]], %[[VAL_230]] : (!fir.ref<!fir.array<?x!fir.char<1>>>, index) -> !fir.ref<!fir.char<1>>
328-
! CHECK: %[[VAL_233:.*]] = fir.convert %[[VAL_232]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<!fir.char<1,?>>
329328
! CHECK: %[[VAL_234:.*]] = arith.subi %[[VAL_219]], %[[VAL_216]] : index
330329
! CHECK: %[[VAL_235:.*]] = arith.addi %[[VAL_234]], %[[VAL_210]] : index
331330
! CHECK: %[[VAL_236:.*]] = arith.cmpi slt, %[[VAL_235]], %[[VAL_209]] : index
332331
! CHECK: %[[VAL_237:.*]] = arith.select %[[VAL_236]], %[[VAL_209]], %[[VAL_235]] : index
333-
! CHECK: %[[VAL_238:.*]] = fir.convert %[[VAL_233]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
332+
! CHECK: %[[VAL_238:.*]] = fir.convert %[[VAL_232]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<i8>
334333
! CHECK: %[[VAL_239:.*]] = fir.convert %[[VAL_237]] : (index) -> i64
335334
! CHECK: %[[VAL_240:.*]] = fir.call @_FortranAioInputAscii(%[[VAL_213]], %[[VAL_238]], %[[VAL_239]]) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1
336335
! CHECK: %[[VAL_241:.*]] = arith.addi %[[VAL_221]], %[[VAL_210]] overflow<nsw> : index

0 commit comments

Comments
 (0)