Skip to content

Commit

Permalink
[flang] implement sizeof lowering for polymorphic entities (#84498)
Browse files Browse the repository at this point in the history
For non polymorphic entities, semantics knows the type size and rewrite
sizeof to `"cst element size" * size(x)`.

Lowering has to deal with the polymorphic case where the type size must
be retrieved from the descriptor (note that the lowering implementation
would work with any entity, polymorphic on not, it is just not used for
the non polymorphic cases).
  • Loading branch information
jeanPerier committed Mar 12, 2024
1 parent 103469b commit 85f6669
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
1 change: 1 addition & 0 deletions flang/include/flang/Optimizer/Builder/IntrinsicCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ struct IntrinsicLibrary {
mlir::Value genSign(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genSind(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genSize(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genSizeOf(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genSpacing(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args);
fir::ExtendedValue genSpread(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
Expand Down
18 changes: 18 additions & 0 deletions flang/lib/Optimizer/Builder/IntrinsicCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,10 @@ static constexpr IntrinsicHandler handlers[]{
{"dim", asAddr, handleDynamicOptional},
{"kind", asValue}}},
/*isElemental=*/false},
{"sizeof",
&I::genSizeOf,
{{{"a", asBox}}},
/*isElemental=*/false},
{"sleep", &I::genSleep, {{{"seconds", asValue}}}, /*isElemental=*/false},
{"spacing", &I::genSpacing},
{"spread",
Expand Down Expand Up @@ -5946,6 +5950,20 @@ IntrinsicLibrary::genSize(mlir::Type resultType,
.getResults()[0];
}

// SIZEOF
fir::ExtendedValue
IntrinsicLibrary::genSizeOf(mlir::Type resultType,
llvm::ArrayRef<fir::ExtendedValue> args) {
assert(args.size() == 1);
mlir::Value box = fir::getBase(args[0]);
mlir::Value eleSize = builder.create<fir::BoxEleSizeOp>(loc, resultType, box);
if (!fir::isArray(args[0]))
return eleSize;
mlir::Value arraySize = builder.createConvert(
loc, resultType, fir::runtime::genSize(builder, loc, box));
return builder.create<mlir::arith::MulIOp>(loc, eleSize, arraySize);
}

// TAND
mlir::Value IntrinsicLibrary::genTand(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args) {
Expand Down
23 changes: 23 additions & 0 deletions flang/test/Lower/Intrinsics/sizeof.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
! Test SIZEOF lowering for polymorphic entities.
! RUN: bbc -emit-hlfir --polymorphic-type -o - %s | FileCheck %s

integer(8) function test1(x)
class(*) :: x
test1 = sizeof(x)
end function
! CHECK-LABEL: func.func @_QPtest1(
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFtest1Ex"} : (!fir.class<none>) -> (!fir.class<none>, !fir.class<none>)
! CHECK: %[[VAL_4:.*]] = fir.box_elesize %[[VAL_3]]#1 : (!fir.class<none>) -> i64
! CHECK: hlfir.assign %[[VAL_4]] to %{{.*}} : i64, !fir.ref<i64>

integer(8) function test2(x)
class(*) :: x(:, :)
test2 = sizeof(x)
end function
! CHECK-LABEL: func.func @_QPtest2(
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFtest2Ex"} : (!fir.class<!fir.array<?x?xnone>>) -> (!fir.class<!fir.array<?x?xnone>>, !fir.class<!fir.array<?x?xnone>>)
! CHECK: %[[VAL_4:.*]] = fir.box_elesize %[[VAL_3]]#1 : (!fir.class<!fir.array<?x?xnone>>) -> i64
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
! CHECK: %[[VAL_9:.*]] = fir.call @_FortranASize(%[[VAL_7]], %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> i64
! CHECK: %[[VAL_10:.*]] = arith.muli %[[VAL_4]], %[[VAL_9]] : i64
! CHECK: hlfir.assign %[[VAL_10]] to %{{.*}} : i64, !fir.ref<i64>

0 comments on commit 85f6669

Please sign in to comment.