[flang] implement sizeof lowering for polymorphic entities (#84498)

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).
This commit is contained in:
jeanPerier 2024-03-12 09:04:25 +01:00 committed by GitHub
parent 103469b5f7
commit 85f6669de5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 42 additions and 0 deletions

View File

@ -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>);

View File

@ -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",
@ -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) {

View File

@ -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>