[flang-commits] [flang] 36e1890 - [flang][hlfir] Handle box and non constant must_free in end_associate.
Jean Perier via flang-commits
flang-commits at lists.llvm.org
Fri Jan 27 03:52:53 PST 2023
Author: Jean Perier
Date: 2023-01-27T12:52:20+01:00
New Revision: 36e1890f6bf50c247519b1867838ffc1ed7eca54
URL: https://github.com/llvm/llvm-project/commit/36e1890f6bf50c247519b1867838ffc1ed7eca54
DIFF: https://github.com/llvm/llvm-project/commit/36e1890f6bf50c247519b1867838ffc1ed7eca54.diff
LOG: [flang][hlfir] Handle box and non constant must_free in end_associate.
Differential Revision: https://reviews.llvm.org/D142700
Added:
Modified:
flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp
flang/test/HLFIR/associate-codegen.fir
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp
index 8e200ed52118..ad5c04a96758 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp
@@ -331,24 +331,25 @@ struct AssociateOpConversion
}
};
-static void genFreeIfMustFree(mlir::Location loc,
- mlir::ConversionPatternRewriter &rewriter,
+static void genFreeIfMustFree(mlir::Location loc, fir::FirOpBuilder &builder,
mlir::Value var, mlir::Value mustFree) {
auto genFree = [&]() {
- if (var.getType().isa<fir::BaseBoxType>())
- TODO(loc, "unbox");
- if (!var.getType().isa<fir::HeapType>())
- var = rewriter.create<fir::ConvertOp>(
- loc, fir::HeapType::get(fir::unwrapRefType(var.getType())), var);
- rewriter.create<fir::FreeMemOp>(loc, var);
+ // fir::FreeMemOp operand type must be a fir::HeapType.
+ mlir::Type heapType = fir::HeapType::get(
+ hlfir::getFortranElementOrSequenceType(var.getType()));
+ if (var.getType().isa<fir::BaseBoxType, fir::BoxCharType>())
+ var = builder.create<fir::BoxAddrOp>(loc, heapType, var);
+ else if (!var.getType().isa<fir::HeapType>())
+ var = builder.create<fir::ConvertOp>(loc, heapType, var);
+ builder.create<fir::FreeMemOp>(loc, var);
};
if (auto cstMustFree = fir::getIntIfConstant(mustFree)) {
if (*cstMustFree != 0)
genFree();
- // else, nothing to do.
+ // else, mustFree is false, nothing to do.
return;
}
- TODO(loc, "conditional free");
+ builder.genIfThen(loc, mustFree).genThen(genFree).end();
}
struct EndAssociateOpConversion
@@ -360,7 +361,9 @@ struct EndAssociateOpConversion
matchAndRewrite(hlfir::EndAssociateOp endAssociate, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const override {
mlir::Location loc = endAssociate->getLoc();
- genFreeIfMustFree(loc, rewriter, adaptor.getVar(), adaptor.getMustFree());
+ auto module = endAssociate->getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, fir::getKindMapping(module));
+ genFreeIfMustFree(loc, builder, adaptor.getVar(), adaptor.getMustFree());
rewriter.eraseOp(endAssociate);
return mlir::success();
}
@@ -378,9 +381,11 @@ struct DestroyOpConversion
mlir::Location loc = destroy->getLoc();
mlir::Value bufferizedExpr = getBufferizedExprStorage(adaptor.getExpr());
if (!fir::isa_trivial(bufferizedExpr.getType())) {
+ auto module = destroy->getParentOfType<mlir::ModuleOp>();
+ fir::FirOpBuilder builder(rewriter, fir::getKindMapping(module));
mlir::Value mustFree = getBufferizedExprMustFreeFlag(adaptor.getExpr());
mlir::Value firBase = hlfir::Entity(bufferizedExpr).getFirBase();
- genFreeIfMustFree(loc, rewriter, firBase, mustFree);
+ genFreeIfMustFree(loc, builder, firBase, mustFree);
}
rewriter.eraseOp(destroy);
return mlir::success();
diff --git a/flang/test/HLFIR/associate-codegen.fir b/flang/test/HLFIR/associate-codegen.fir
index 8eae3fd2f223..c08ade44837d 100644
--- a/flang/test/HLFIR/associate-codegen.fir
+++ b/flang/test/HLFIR/associate-codegen.fir
@@ -79,6 +79,43 @@ func.func @associate_char(%arg0: !fir.boxchar<1> ) {
// CHECK-NOT: fir.freemem
+func.func @test_end_associate_box(%var: !fir.box<!fir.array<?xf64>>) {
+ %true = arith.constant 1 : i1
+ hlfir.end_associate %var, %true : !fir.box<!fir.array<?xf64>>, i1
+ return
+}
+// CHECK-LABEL: func.func @test_end_associate_box(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xf64>>) {
+// CHECK: %[[VAL_1:.*]] = arith.constant true
+// CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.heap<!fir.array<?xf64>>
+// CHECK: fir.freemem %[[VAL_2]] : !fir.heap<!fir.array<?xf64>>
+
+
+func.func @test_end_associate_boxchar(%var: !fir.boxchar<2>) {
+ %true = arith.constant 1 : i1
+ hlfir.end_associate %var, %true : !fir.boxchar<2>, i1
+ return
+}
+// CHECK-LABEL: func.func @test_end_associate_boxchar(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<2>) {
+// CHECK: %[[VAL_1:.*]] = arith.constant true
+// CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_0]] : (!fir.boxchar<2>) -> !fir.heap<!fir.char<2,?>>
+// CHECK: fir.freemem %[[VAL_2]] : !fir.heap<!fir.char<2,?>>
+
+
+func.func @test_end_associate_box_dynamic(%var: !fir.box<!fir.array<?xf64>>, %must_free: i1) {
+ hlfir.end_associate %var, %must_free : !fir.box<!fir.array<?xf64>>, i1
+ return
+}
+// CHECK-LABEL: func.func @test_end_associate_box_dynamic(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xf64>>,
+// CHECK-SAME: %[[VAL_1:.*]]: i1) {
+// CHECK: fir.if %[[VAL_1]] {
+// CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.heap<!fir.array<?xf64>>
+// CHECK: fir.freemem %[[VAL_2]] : !fir.heap<!fir.array<?xf64>>
+// CHECK: }
+
+
func.func private @take_i4(!fir.ref<i32>)
func.func private @take_r4(!fir.ref<f32>)
func.func private @take_l4(!fir.ref<!fir.logical<4>>)
More information about the flang-commits
mailing list