Skip to content

Commit 36e1890

Browse files
committed
[flang][hlfir] Handle box and non constant must_free in end_associate.
Differential Revision: https://reviews.llvm.org/D142700
1 parent 86e6a8c commit 36e1890

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed

flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -331,24 +331,25 @@ struct AssociateOpConversion
331331
}
332332
};
333333

334-
static void genFreeIfMustFree(mlir::Location loc,
335-
mlir::ConversionPatternRewriter &rewriter,
334+
static void genFreeIfMustFree(mlir::Location loc, fir::FirOpBuilder &builder,
336335
mlir::Value var, mlir::Value mustFree) {
337336
auto genFree = [&]() {
338-
if (var.getType().isa<fir::BaseBoxType>())
339-
TODO(loc, "unbox");
340-
if (!var.getType().isa<fir::HeapType>())
341-
var = rewriter.create<fir::ConvertOp>(
342-
loc, fir::HeapType::get(fir::unwrapRefType(var.getType())), var);
343-
rewriter.create<fir::FreeMemOp>(loc, var);
337+
// fir::FreeMemOp operand type must be a fir::HeapType.
338+
mlir::Type heapType = fir::HeapType::get(
339+
hlfir::getFortranElementOrSequenceType(var.getType()));
340+
if (var.getType().isa<fir::BaseBoxType, fir::BoxCharType>())
341+
var = builder.create<fir::BoxAddrOp>(loc, heapType, var);
342+
else if (!var.getType().isa<fir::HeapType>())
343+
var = builder.create<fir::ConvertOp>(loc, heapType, var);
344+
builder.create<fir::FreeMemOp>(loc, var);
344345
};
345346
if (auto cstMustFree = fir::getIntIfConstant(mustFree)) {
346347
if (*cstMustFree != 0)
347348
genFree();
348-
// else, nothing to do.
349+
// else, mustFree is false, nothing to do.
349350
return;
350351
}
351-
TODO(loc, "conditional free");
352+
builder.genIfThen(loc, mustFree).genThen(genFree).end();
352353
}
353354

354355
struct EndAssociateOpConversion
@@ -360,7 +361,9 @@ struct EndAssociateOpConversion
360361
matchAndRewrite(hlfir::EndAssociateOp endAssociate, OpAdaptor adaptor,
361362
mlir::ConversionPatternRewriter &rewriter) const override {
362363
mlir::Location loc = endAssociate->getLoc();
363-
genFreeIfMustFree(loc, rewriter, adaptor.getVar(), adaptor.getMustFree());
364+
auto module = endAssociate->getParentOfType<mlir::ModuleOp>();
365+
fir::FirOpBuilder builder(rewriter, fir::getKindMapping(module));
366+
genFreeIfMustFree(loc, builder, adaptor.getVar(), adaptor.getMustFree());
364367
rewriter.eraseOp(endAssociate);
365368
return mlir::success();
366369
}
@@ -378,9 +381,11 @@ struct DestroyOpConversion
378381
mlir::Location loc = destroy->getLoc();
379382
mlir::Value bufferizedExpr = getBufferizedExprStorage(adaptor.getExpr());
380383
if (!fir::isa_trivial(bufferizedExpr.getType())) {
384+
auto module = destroy->getParentOfType<mlir::ModuleOp>();
385+
fir::FirOpBuilder builder(rewriter, fir::getKindMapping(module));
381386
mlir::Value mustFree = getBufferizedExprMustFreeFlag(adaptor.getExpr());
382387
mlir::Value firBase = hlfir::Entity(bufferizedExpr).getFirBase();
383-
genFreeIfMustFree(loc, rewriter, firBase, mustFree);
388+
genFreeIfMustFree(loc, builder, firBase, mustFree);
384389
}
385390
rewriter.eraseOp(destroy);
386391
return mlir::success();

flang/test/HLFIR/associate-codegen.fir

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,43 @@ func.func @associate_char(%arg0: !fir.boxchar<1> ) {
7979
// CHECK-NOT: fir.freemem
8080

8181

82+
func.func @test_end_associate_box(%var: !fir.box<!fir.array<?xf64>>) {
83+
%true = arith.constant 1 : i1
84+
hlfir.end_associate %var, %true : !fir.box<!fir.array<?xf64>>, i1
85+
return
86+
}
87+
// CHECK-LABEL: func.func @test_end_associate_box(
88+
// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xf64>>) {
89+
// CHECK: %[[VAL_1:.*]] = arith.constant true
90+
// CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.heap<!fir.array<?xf64>>
91+
// CHECK: fir.freemem %[[VAL_2]] : !fir.heap<!fir.array<?xf64>>
92+
93+
94+
func.func @test_end_associate_boxchar(%var: !fir.boxchar<2>) {
95+
%true = arith.constant 1 : i1
96+
hlfir.end_associate %var, %true : !fir.boxchar<2>, i1
97+
return
98+
}
99+
// CHECK-LABEL: func.func @test_end_associate_boxchar(
100+
// CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<2>) {
101+
// CHECK: %[[VAL_1:.*]] = arith.constant true
102+
// CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_0]] : (!fir.boxchar<2>) -> !fir.heap<!fir.char<2,?>>
103+
// CHECK: fir.freemem %[[VAL_2]] : !fir.heap<!fir.char<2,?>>
104+
105+
106+
func.func @test_end_associate_box_dynamic(%var: !fir.box<!fir.array<?xf64>>, %must_free: i1) {
107+
hlfir.end_associate %var, %must_free : !fir.box<!fir.array<?xf64>>, i1
108+
return
109+
}
110+
// CHECK-LABEL: func.func @test_end_associate_box_dynamic(
111+
// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xf64>>,
112+
// CHECK-SAME: %[[VAL_1:.*]]: i1) {
113+
// CHECK: fir.if %[[VAL_1]] {
114+
// CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.heap<!fir.array<?xf64>>
115+
// CHECK: fir.freemem %[[VAL_2]] : !fir.heap<!fir.array<?xf64>>
116+
// CHECK: }
117+
118+
82119
func.func private @take_i4(!fir.ref<i32>)
83120
func.func private @take_r4(!fir.ref<f32>)
84121
func.func private @take_l4(!fir.ref<!fir.logical<4>>)

0 commit comments

Comments
 (0)