Skip to content

Commit b09426f

Browse files
clementvaljeanPerierschweitzpgi
committed
[flang] Cleanup code and add test from fir-dev
This patch clean up some code for upstreaming and add couple of missing tests that were left in fir-dev. This patch is part of the upstreaming effort from fir-dev branch. Reviewed By: jeanPerier, PeteSteinfeld Differential Revision: https://reviews.llvm.org/D128258 Co-authored-by: Jean Perier <[email protected]> Co-authored-by: Eric Schweitz <[email protected]>
1 parent ac62b8f commit b09426f

File tree

13 files changed

+715
-3
lines changed

13 files changed

+715
-3
lines changed

flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,8 @@ class ArrayCoorConversion : public mlir::OpRewritePattern<fir::ArrayCoorOp> {
260260

261261
class CodeGenRewrite : public fir::CodeGenRewriteBase<CodeGenRewrite> {
262262
public:
263-
void runOnOperation() override final {
264-
auto op = getOperation();
263+
void runOn(mlir::Operation *op, mlir::Region &region) {
264+
// auto op = getOperation();
265265
auto &context = getContext();
266266
mlir::OpBuilder rewriter(&context);
267267
mlir::ConversionTarget target(context);
@@ -284,7 +284,60 @@ class CodeGenRewrite : public fir::CodeGenRewriteBase<CodeGenRewrite> {
284284
"error in running the pre-codegen conversions");
285285
signalPassFailure();
286286
}
287+
// Erase any residual.
288+
simplifyRegion(region);
289+
}
290+
291+
void runOnOperation() override final {
292+
// Call runOn on all top level regions that may contain emboxOp/arrayCoorOp.
293+
auto mod = getOperation();
294+
for (auto func : mod.getOps<mlir::func::FuncOp>())
295+
runOn(func, func.getBody());
296+
for (auto global : mod.getOps<fir::GlobalOp>())
297+
runOn(global, global.getRegion());
298+
}
299+
300+
// Clean up the region.
301+
void simplifyRegion(mlir::Region &region) {
302+
for (auto &block : region.getBlocks())
303+
for (auto &op : block.getOperations()) {
304+
for (auto &reg : op.getRegions())
305+
simplifyRegion(reg);
306+
maybeEraseOp(&op);
307+
}
308+
doDCE();
309+
}
310+
311+
/// Run a simple DCE cleanup to remove any dead code after the rewrites.
312+
void doDCE() {
313+
std::vector<mlir::Operation *> workList;
314+
workList.swap(opsToErase);
315+
while (!workList.empty()) {
316+
for (auto *op : workList) {
317+
std::vector<mlir::Value> opOperands(op->operand_begin(),
318+
op->operand_end());
319+
LLVM_DEBUG(llvm::dbgs() << "DCE on " << *op << '\n');
320+
++numDCE;
321+
op->erase();
322+
for (auto opnd : opOperands)
323+
maybeEraseOp(opnd.getDefiningOp());
324+
}
325+
workList.clear();
326+
workList.swap(opsToErase);
327+
}
287328
}
329+
330+
void maybeEraseOp(mlir::Operation *op) {
331+
if (!op)
332+
return;
333+
if (op->hasTrait<mlir::OpTrait::IsTerminator>())
334+
return;
335+
if (mlir::isOpTriviallyDead(op))
336+
opsToErase.push_back(op);
337+
}
338+
339+
private:
340+
std::vector<mlir::Operation *> opsToErase;
288341
};
289342

290343
} // namespace

flang/test/Fir/array-coor.fir

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: tco %s | FileCheck %s
2+
3+
func.func @array_coor_box_value(%29 : !fir.box<!fir.array<2xf64>>,
4+
%33 : index) -> f64 {
5+
%34 = fir.array_coor %29 %33 : (!fir.box<!fir.array<2xf64>>, index) ->
6+
!fir.ref<f64>
7+
%35 = fir.load %34 : !fir.ref<f64>
8+
return %35 : f64
9+
}
10+
11+
// CHECK-LABEL: define double @array_coor_box_value
12+
// CHECK: %[[t3:.*]] = sub i64 %{{.*}}, 1
13+
// CHECK: %[[t4:.*]] = mul i64 %[[t3]], 1
14+
// CHECK: %[[t5:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %{{.*}}, i32 0, i32 7, i64 0, i32 2
15+
// CHECK: %[[t6:.*]] = load i64, ptr %[[t5]]
16+
// CHECK: %[[t7:.*]] = mul i64 %[[t4]], %[[t6]]
17+
// CHECK: %[[t8:.*]] = add i64 %[[t7]], 0
18+
// CHECK: %[[t9:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %{{.*}}, i32 0, i32 0
19+
// CHECK: %[[t10:.*]] = load ptr, ptr %[[t9]]
20+
// CHECK: %[[t11:.*]] = getelementptr i8, ptr %[[t10]], i64 %[[t8]]
21+
// CHECK: %[[t12:.*]] = load double, ptr %[[t11]]
22+
// CHECK: ret double %[[t12]]

flang/test/Fir/array-modify.fir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func.func @overlap(%arg0: !fir.ref<!fir.array<100xf32>>) {
123123
// CHECK: %[[VAL_42:.*]] = fir.load %[[VAL_41]] : !fir.ref<f32>
124124
// CHECK: fir.store %[[VAL_42]] to %[[VAL_45]] : !fir.ref<f32>
125125
// CHECK: }
126-
// CHECK: fir.freemem %[[VAL_8]]
126+
// CHECK: fir.freemem %[[VAL_8]] : !fir.heap<!fir.array<100xf32>>
127127
// CHECK: return
128128
// CHECK: }
129129

flang/test/Fir/box.fir

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
// RUN: tco -o - %s | FileCheck %s
2+
3+
// Global box initialization (test must come first because llvm globals are emitted first).
4+
// CHECK-LABEL: @globalx = internal global { ptr, i64, i32, i8, i8, i8, i8 } { ptr null, i64 4, i32 20180515, i8 0, i8 9, i8 2, i8 0 }
5+
fir.global internal @globalx : !fir.box<!fir.heap<i32>> {
6+
%c0 = arith.constant 0 : index
7+
%0 = fir.convert %c0 : (index) -> !fir.heap<i32>
8+
%1 = fir.embox %0 : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
9+
fir.has_value %1 : !fir.box<!fir.heap<i32>>
10+
}
11+
12+
// CHECK-LABEL: @globaly = internal global { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } { ptr null, i64 4, i32 20180515, i8 1, i8 27, i8 2, i8 0,{{.*}}[3 x i64] [i64 1, i64 0, i64 4]
13+
fir.global internal @globaly : !fir.box<!fir.heap<!fir.array<?xf32>>> {
14+
%c0 = arith.constant 0 : index
15+
%0 = fir.convert %c0 : (index) -> !fir.heap<!fir.array<?xf32>>
16+
%1 = fir.shape %c0 : (index) -> !fir.shape<1>
17+
%2 = fir.embox %0(%1) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
18+
fir.has_value %2 : !fir.box<!fir.heap<!fir.array<?xf32>>>
19+
}
20+
21+
// CHECK-LABEL: declare void @g(ptr)
22+
func.func private @g(%b : !fir.box<f32>)
23+
// CHECK-LABEL: declare void @ga(ptr)
24+
func.func private @ga(%b : !fir.box<!fir.array<?xf32>>)
25+
26+
// CHECK-LABEL: define void @f
27+
// CHECK: (ptr %[[ARG:.*]])
28+
func.func @f(%a : !fir.ref<f32>) {
29+
// CHECK: %[[DESC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8 }
30+
// CHECK: %[[INS0:.*]] = insertvalue {{.*}} { ptr undef, i64 4, i32 20180515, i8 0, i8 27, i8 0, i8 0 }, ptr %[[ARG]], 0
31+
// CHECK: store {{.*}} %[[INS0]], {{.*}} %[[DESC]]
32+
%b = fir.embox %a : (!fir.ref<f32>) -> !fir.box<f32>
33+
34+
// CHECK: call void @g({{.*}} %[[DESC]])
35+
fir.call @g(%b) : (!fir.box<f32>) -> ()
36+
// CHECK: ret void
37+
return
38+
}
39+
40+
// CHECK-LABEL: define void @fa
41+
// CHECK: (ptr %[[ARG:.*]])
42+
func.func @fa(%a : !fir.ref<!fir.array<100xf32>>) {
43+
%c = fir.convert %a : (!fir.ref<!fir.array<100xf32>>) -> !fir.ref<!fir.array<?xf32>>
44+
%c1 = arith.constant 1 : index
45+
%c100 = arith.constant 100 : index
46+
%d = fir.shape %c100 : (index) -> !fir.shape<1>
47+
// CHECK: %[[INS70:.*]] = insertvalue {{.*}} { ptr undef, i64 4, i32 20180515, i8 1, i8 27, i8 0, i8 0, {{.*}} }, ptr %{{.*}}, 0
48+
%b = fir.embox %c(%d) : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
49+
// CHECK: call void @ga(
50+
fir.call @ga(%b) : (!fir.box<!fir.array<?xf32>>) -> ()
51+
// CHECK: ret void
52+
return
53+
}
54+
55+
// Boxing of a scalar character of dynamic length
56+
// CHECK-LABEL: define void @b1(
57+
// CHECK-SAME: ptr %[[res:.*]], ptr %[[arg0:.*]], i64 %[[arg1:.*]])
58+
func.func @b1(%arg0 : !fir.ref<!fir.char<1,?>>, %arg1 : index) -> !fir.box<!fir.char<1,?>> {
59+
// CHECK: insertvalue {{.*}} undef, i64 %[[arg1]], 1
60+
// CHECK: insertvalue {{.*}} i32 20180515, 2
61+
// CHECK: insertvalue {{.*}} ptr %[[arg0]], 0
62+
%x = fir.embox %arg0 typeparams %arg1 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
63+
// CHECK: store {{.*}}, ptr %[[res]]
64+
return %x : !fir.box<!fir.char<1,?>>
65+
}
66+
67+
// Boxing of a dynamic array of character with static length (5)
68+
// CHECK-LABEL: define void @b2(
69+
// CHECK-SAME: ptr %[[res]],
70+
// CHECK-SAME: ptr %[[arg0:.*]], i64 %[[arg1:.*]])
71+
func.func @b2(%arg0 : !fir.ref<!fir.array<?x!fir.char<1,5>>>, %arg1 : index) -> !fir.box<!fir.array<?x!fir.char<1,5>>> {
72+
%1 = fir.shape %arg1 : (index) -> !fir.shape<1>
73+
// CHECK: insertvalue {{.*}} { ptr undef, i64 5, i32 20180515, i8 1, i8 40, i8 0, i8 0, {{.*}} }, i64 %[[arg1]], 7, 0, 1
74+
// CHECK: insertvalue {{.*}} %{{.*}}, i64 5, 7, 0, 2
75+
// CHECK: insertvalue {{.*}} ptr %[[arg0]], 0
76+
%2 = fir.embox %arg0(%1) : (!fir.ref<!fir.array<?x!fir.char<1,5>>>, !fir.shape<1>) -> !fir.box<!fir.array<?x!fir.char<1,5>>>
77+
// CHECK: store {{.*}}, ptr %[[res]]
78+
return %2 : !fir.box<!fir.array<?x!fir.char<1,5>>>
79+
}
80+
81+
// Boxing of a dynamic array of character of dynamic length
82+
// CHECK-LABEL: define void @b3(
83+
// CHECK-SAME: ptr %[[res:.*]], ptr %[[arg0:.*]], i64 %[[arg1:.*]], i64 %[[arg2:.*]])
84+
func.func @b3(%arg0 : !fir.ref<!fir.array<?x!fir.char<1,?>>>, %arg1 : index, %arg2 : index) -> !fir.box<!fir.array<?x!fir.char<1,?>>> {
85+
%1 = fir.shape %arg2 : (index) -> !fir.shape<1>
86+
// CHECK: insertvalue {{.*}} i64 %[[arg1]], 1
87+
// CHECK: insertvalue {{.*}} i32 20180515, 2
88+
// CHECK: insertvalue {{.*}} i64 %[[arg2]], 7, 0, 1
89+
// CHECK: insertvalue {{.*}} i64 %[[arg1]], 7, 0, 2
90+
// CHECK: insertvalue {{.*}} ptr %[[arg0]], 0
91+
%2 = fir.embox %arg0(%1) typeparams %arg1 : (!fir.ref<!fir.array<?x!fir.char<1,?>>>, !fir.shape<1>, index) -> !fir.box<!fir.array<?x!fir.char<1,?>>>
92+
// CHECK: store {{.*}}, ptr %[[res]]
93+
return %2 : !fir.box<!fir.array<?x!fir.char<1,?>>>
94+
}
95+
96+
// Boxing of a static array of character of dynamic length
97+
// CHECK-LABEL: define void @b4(
98+
// CHECK-SAME: ptr %[[res:.*]], ptr %[[arg0:.*]], i64 %[[arg1:.*]])
99+
func.func @b4(%arg0 : !fir.ref<!fir.array<7x!fir.char<1,?>>>, %arg1 : index) -> !fir.box<!fir.array<7x!fir.char<1,?>>> {
100+
%c_7 = arith.constant 7 : index
101+
%1 = fir.shape %c_7 : (index) -> !fir.shape<1>
102+
// CHECK: insertvalue {{.*}} i64 %[[arg1]], 1
103+
// CHECK: insertvalue {{.*}} i32 20180515, 2
104+
// CHECK: insertvalue {{.*}} i64 7, 7, 0, 1
105+
// CHECK: insertvalue {{.*}} i64 %[[arg1]], 7, 0, 2
106+
// CHECK: insertvalue {{.*}} ptr %[[arg0]], 0
107+
%x = fir.embox %arg0(%1) typeparams %arg1 : (!fir.ref<!fir.array<7x!fir.char<1,?>>>, !fir.shape<1>, index) -> !fir.box<!fir.array<7x!fir.char<1,?>>>
108+
// CHECK: store {{.*}}, ptr %[[res]]
109+
return %x : !fir.box<!fir.array<7x!fir.char<1,?>>>
110+
}
111+
112+
// Storing a fir.box into a fir.ref<fir.box> (modifying descriptors).
113+
// CHECK-LABEL: define void @b5(
114+
// CHECK-SAME: ptr %[[arg0:.*]], ptr %[[arg1:.*]])
115+
func.func @b5(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>, %arg1 : !fir.box<!fir.heap<!fir.array<?x?xf32>>>) {
116+
fir.store %arg1 to %arg0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>
117+
// CHECK: %[[boxLoad:.*]] = load { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] }, ptr %[[arg1]]
118+
// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %[[boxLoad]], ptr %[[arg0]]
119+
return
120+
}
121+
122+
func.func private @callee6(!fir.box<none>) -> i32
123+
124+
// CHECK-LABEL: define i32 @box6(
125+
// CHECK-SAME: ptr %[[ARG0:.*]], i64 %[[ARG1:.*]], i64 %[[ARG2:.*]])
126+
func.func @box6(%0 : !fir.ref<!fir.array<?x?x?x?xf32>>, %1 : index, %2 : index) -> i32 {
127+
%c100 = arith.constant 100 : index
128+
%c50 = arith.constant 50 : index
129+
%c30 = arith.constant 30 : index
130+
%c6 = arith.constant 6 : index
131+
%shape = fir.shape %c100, %c50, %c30, %c6 : (index, index, index, index) -> !fir.shape<4>
132+
%3 = fir.undefined index
133+
%c41 = arith.constant 41 : index
134+
%c2 = arith.constant 2 : index
135+
%c24 = arith.constant 24 : index
136+
%c1 = arith.constant 1 : index
137+
%c3 = arith.constant 3 : index
138+
139+
// CHECK: %[[i:.*]] = sub i64 %[[ARG1]], 1
140+
// CHECK: %[[i100:.*]] = mul i64 %[[i]], 100
141+
// CHECK: %[[i100p40:.*]] = add i64 %[[i100]], 40
142+
// CHECK: %[[diff:.*]] = sub i64 %[[ARG2]], %[[ARG1]]
143+
// CHECK: %[[dp2:.*]] = add i64 %[[diff]], 2
144+
// CHECK: %[[sdp2:.*]] = sdiv i64 %[[dp2]], 2
145+
// CHECK: %[[cmp:.*]] = icmp sgt i64 %[[sdp2]], 0
146+
// CHECK: %[[extent:.*]] = select i1 %[[cmp]], i64 %[[sdp2]], i64 0
147+
// CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } { ptr undef, i64 4, i32 20180515, i8 2, i8 27, i8 0, i8 0, [2 x [3 x i64]] [{{\[}}3 x i64] [i64 1, i64 undef, i64 undef], [3 x i64] undef] }, i64 %[[extent]], 7, 0, 1
148+
// CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, i64 800, 7, 0, 2
149+
// CHECK: %[[op25:.*]] = add i64 25000, %[[i100p40]]
150+
// CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, i64 1, 7, 1, 0
151+
// CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, i64 4, 7, 1, 1
152+
// CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, i64 120000, 7, 1, 2
153+
// CHECK: %[[op300:.*]] = add i64 300000, %[[op25]]
154+
// CHECK: %[[ptr:.*]] = getelementptr float, ptr %[[ARG0]], i64 %[[op300]]
155+
// CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, ptr %[[ptr]], 0
156+
// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [2 x [3 x i64]] } %{{.*}}, ptr %[[mem:[0-9]+]]
157+
158+
159+
%slice = fir.slice %c41, %3, %3, %1, %2, %c2, %c6, %c24, %c6, %c3, %3, %3 : (index, index, index, index, index, index, index, index, index, index, index, index) -> !fir.slice<4>
160+
%box = fir.embox %0(%shape)[%slice] : (!fir.ref<!fir.array<?x?x?x?xf32>>, !fir.shape<4>, !fir.slice<4>) -> !fir.box<!fir.array<?x?x?x?xf32>>
161+
%nonebox = fir.convert %box : (!fir.box<!fir.array<?x?x?x?xf32>>) -> !fir.box<none>
162+
// CHECK: %[[call:.*]] = call i32 @callee6(ptr %[[mem]])
163+
%rv = fir.call @callee6(%nonebox) : (!fir.box<none>) -> i32
164+
// CHECK: ret i32 %[[call]]
165+
return %rv : i32
166+
}

0 commit comments

Comments
 (0)