[fir] Add fir.box type conversion
This patch add the `!fir.box` type conversion to llvm. `fir.box` is converted to the descriptor as defined in the ISO_Fortran_binding.h and the addendum defined in descriptor.h. This patch is part of the upstreaming effort from fir-dev branch. Reviewed By: awarzynski Differential Revision: https://reviews.llvm.org/D113288 Co-authored-by: Jean Perier <jperier@nvidia.com> Co-authored-by: Eric Schweitz <eschweitz@nvidia.com> Co-authored-by: V Donaldson <vdonaldson@nvidia.com>
This commit is contained in:
parent
17d9560294
commit
7e92b759ed
|
|
@ -29,6 +29,7 @@ public:
|
||||||
LLVM_DEBUG(llvm::dbgs() << "FIR type converter\n");
|
LLVM_DEBUG(llvm::dbgs() << "FIR type converter\n");
|
||||||
|
|
||||||
// Each conversion should return a value of type mlir::Type.
|
// Each conversion should return a value of type mlir::Type.
|
||||||
|
addConversion([&](BoxType box) { return convertBoxType(box); });
|
||||||
addConversion(
|
addConversion(
|
||||||
[&](fir::RecordType derived) { return convertRecordType(derived); });
|
[&](fir::RecordType derived) { return convertRecordType(derived); });
|
||||||
addConversion(
|
addConversion(
|
||||||
|
|
@ -60,6 +61,78 @@ public:
|
||||||
return mlir::Type();
|
return mlir::Type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is an extended descriptor needed given the element type of a fir.box type ?
|
||||||
|
// Extended descriptors are required for derived types.
|
||||||
|
bool requiresExtendedDesc(mlir::Type boxElementType) {
|
||||||
|
auto eleTy = fir::unwrapSequenceType(boxElementType);
|
||||||
|
return eleTy.isa<fir::RecordType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magic value to indicate we do not know the rank of an entity, either
|
||||||
|
// because it is assumed rank or because we have not determined it yet.
|
||||||
|
static constexpr int unknownRank() { return -1; }
|
||||||
|
|
||||||
|
// This corresponds to the descriptor as defined in ISO_Fortran_binding.h and
|
||||||
|
// the addendum defined in descriptor.h.
|
||||||
|
mlir::Type convertBoxType(BoxType box, int rank = unknownRank()) {
|
||||||
|
// (base_addr*, elem_len, version, rank, type, attribute, f18Addendum, [dim]
|
||||||
|
SmallVector<mlir::Type> dataDescFields;
|
||||||
|
mlir::Type ele = box.getEleTy();
|
||||||
|
// remove fir.heap/fir.ref/fir.ptr
|
||||||
|
if (auto removeIndirection = fir::dyn_cast_ptrEleTy(ele))
|
||||||
|
ele = removeIndirection;
|
||||||
|
auto eleTy = convertType(ele);
|
||||||
|
// base_addr*
|
||||||
|
if (ele.isa<SequenceType>() && eleTy.isa<mlir::LLVM::LLVMPointerType>())
|
||||||
|
dataDescFields.push_back(eleTy);
|
||||||
|
else
|
||||||
|
dataDescFields.push_back(mlir::LLVM::LLVMPointerType::get(eleTy));
|
||||||
|
// elem_len
|
||||||
|
dataDescFields.push_back(getDescFieldTypeModel<1>()(&getContext()));
|
||||||
|
// version
|
||||||
|
dataDescFields.push_back(getDescFieldTypeModel<2>()(&getContext()));
|
||||||
|
// rank
|
||||||
|
dataDescFields.push_back(getDescFieldTypeModel<3>()(&getContext()));
|
||||||
|
// type
|
||||||
|
dataDescFields.push_back(getDescFieldTypeModel<4>()(&getContext()));
|
||||||
|
// attribute
|
||||||
|
dataDescFields.push_back(getDescFieldTypeModel<5>()(&getContext()));
|
||||||
|
// f18Addendum
|
||||||
|
dataDescFields.push_back(getDescFieldTypeModel<6>()(&getContext()));
|
||||||
|
// [dims]
|
||||||
|
if (rank == unknownRank()) {
|
||||||
|
if (auto seqTy = ele.dyn_cast<SequenceType>())
|
||||||
|
rank = seqTy.getDimension();
|
||||||
|
else
|
||||||
|
rank = 0;
|
||||||
|
}
|
||||||
|
if (rank > 0) {
|
||||||
|
auto rowTy = getDescFieldTypeModel<7>()(&getContext());
|
||||||
|
dataDescFields.push_back(mlir::LLVM::LLVMArrayType::get(rowTy, rank));
|
||||||
|
}
|
||||||
|
// opt-type-ptr: i8* (see fir.tdesc)
|
||||||
|
if (requiresExtendedDesc(ele)) {
|
||||||
|
dataDescFields.push_back(
|
||||||
|
getExtendedDescFieldTypeModel<8>()(&getContext()));
|
||||||
|
auto rowTy = getExtendedDescFieldTypeModel<9>()(&getContext());
|
||||||
|
dataDescFields.push_back(mlir::LLVM::LLVMArrayType::get(rowTy, 1));
|
||||||
|
if (auto recTy = fir::unwrapSequenceType(ele).dyn_cast<fir::RecordType>())
|
||||||
|
if (recTy.getNumLenParams() > 0) {
|
||||||
|
// The descriptor design needs to be clarified regarding the number of
|
||||||
|
// length parameters in the addendum. Since it can change for
|
||||||
|
// polymorphic allocatables, it seems all length parameters cannot
|
||||||
|
// always possibly be placed in the addendum.
|
||||||
|
TODO_NOLOC("extended descriptor derived with length parameters");
|
||||||
|
unsigned numLenParams = recTy.getNumLenParams();
|
||||||
|
dataDescFields.push_back(
|
||||||
|
mlir::LLVM::LLVMArrayType::get(rowTy, numLenParams));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mlir::LLVM::LLVMPointerType::get(
|
||||||
|
mlir::LLVM::LLVMStructType::getLiteral(&getContext(), dataDescFields,
|
||||||
|
/*isPacked=*/false));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename A>
|
template <typename A>
|
||||||
mlir::Type convertPointerLike(A &ty) {
|
mlir::Type convertPointerLike(A &ty) {
|
||||||
mlir::Type eleTy = ty.getEleTy();
|
mlir::Type eleTy = ty.getEleTy();
|
||||||
|
|
|
||||||
|
|
@ -29,3 +29,22 @@ func private @foo1(%arg0: !fir.ref<!fir.array<10xf32>>)
|
||||||
// CHECK-LABEL: foo1
|
// CHECK-LABEL: foo1
|
||||||
// CHECK-SAME: !llvm.ptr<array<10 x f32>>
|
// CHECK-SAME: !llvm.ptr<array<10 x f32>>
|
||||||
|
|
||||||
|
// -----
|
||||||
|
|
||||||
|
// Test box types `!fir.box`
|
||||||
|
|
||||||
|
func private @foo0(%arg0: !fir.box<!fir.array<?xf32>>)
|
||||||
|
// CHECK-LABEL: foo0
|
||||||
|
// CHECK-SAME: !llvm.ptr<struct<(ptr<f32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i{{.*}}>>)>>
|
||||||
|
|
||||||
|
func private @foo1(%arg0: !fir.box<!fir.array<10xf32>>)
|
||||||
|
// CHECK-LABEL: foo1
|
||||||
|
// CHECK-SAME: !llvm.ptr<struct<(ptr<array<10 x f32>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i{{.*}}>>)>>
|
||||||
|
|
||||||
|
func private @foo2(%arg0: !fir.box<!fir.ref<i64>>)
|
||||||
|
// CHECK-LABEL: foo2
|
||||||
|
// CHECK-SAME: !llvm.ptr<struct<(ptr<i64>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>>
|
||||||
|
|
||||||
|
func private @foo3(%arg0: !fir.box<!fir.type<derived{f:f32}>>)
|
||||||
|
// CHECK-LABEL: foo3
|
||||||
|
// CHECK-SAME: !llvm.ptr<struct<(ptr<struct<"derived", (f32)>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr<i{{.*}}>, array<1 x i{{.*}}>)>>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue