Skip to content

[flang][codegen] Update FIR codegen to use mlir.llvm opaque pointers #69692

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 2 additions & 24 deletions flang/include/flang/Optimizer/CodeGen/TypeConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class LLVMTypeConverter : public mlir::LLVMTypeConverter {

/// Convert fir.box type to the corresponding llvm struct type instead of a
/// pointer to this struct type.
mlir::Type convertBoxTypeAsStruct(BaseBoxType box) const;
mlir::Type convertBoxTypeAsStruct(BaseBoxType box, int = unknownRank()) const;

// fir.boxproc<any> --> llvm<"{ any*, i8* }">
mlir::Type convertBoxProcType(BoxProcType boxproc) const;
Expand All @@ -97,29 +97,7 @@ class LLVMTypeConverter : public mlir::LLVMTypeConverter {
}

template <typename A> mlir::Type convertPointerLike(A &ty) const {
mlir::Type eleTy = ty.getEleTy();
// A sequence type is a special case. A sequence of runtime size on its
// interior dimensions lowers to a memory reference. In that case, we
// degenerate the array and do not want a the type to become `T**` but
// merely `T*`.
if (auto seqTy = eleTy.dyn_cast<fir::SequenceType>()) {
if (seqTy.hasDynamicExtents() ||
characterWithDynamicLen(seqTy.getEleTy())) {
if (seqTy.getConstantRows() > 0)
return convertType(seqTy);
eleTy = seqTy.getEleTy();
}
}
// fir.ref<fir.box> is a special case because fir.box type is already
// a pointer to a Fortran descriptor at the LLVM IR level. This implies
// that a fir.ref<fir.box>, that is the address of fir.box is actually
// the same as a fir.box at the LLVM level.
// The distinction is kept in fir to denote when a descriptor is expected
// to be mutable (fir.ref<fir.box>) and when it is not (fir.box).
if (eleTy.isa<fir::BaseBoxType>())
return convertType(eleTy);

return mlir::LLVM::LLVMPointerType::get(convertType(eleTy));
return mlir::LLVM::LLVMPointerType::get(ty.getContext());
}

// convert a front-end kind value to either a std or LLVM IR dialect type
Expand Down
462 changes: 231 additions & 231 deletions flang/lib/Optimizer/CodeGen/CodeGen.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion flang/lib/Optimizer/CodeGen/DescriptorModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ TypeBuilderFunc getModel();
template <>
TypeBuilderFunc getModel<void *>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::LLVM::LLVMPointerType::get(mlir::IntegerType::get(context, 8));
return mlir::LLVM::LLVMPointerType::get(context);
};
}
template <>
Expand Down
43 changes: 17 additions & 26 deletions flang/lib/Optimizer/CodeGen/TypeConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,7 @@ namespace fir {

LLVMTypeConverter::LLVMTypeConverter(mlir::ModuleOp module, bool applyTBAA,
bool forceUnifiedTBAATree)
: mlir::LLVMTypeConverter(module.getContext(),
[&] {
mlir::LowerToLLVMOptions options(
module.getContext());
options.useOpaquePointers = false;
return options;
}()),
: mlir::LLVMTypeConverter(module.getContext()),
kindMapping(getKindMapping(module)),
specifics(CodeGenSpecifics::get(module.getContext(),
getTargetTriple(module),
Expand Down Expand Up @@ -205,7 +199,8 @@ bool LLVMTypeConverter::requiresExtendedDesc(mlir::Type boxElementType) const {

// This corresponds to the descriptor as defined in ISO_Fortran_binding.h and
// the addendum defined in descriptor.h.
mlir::Type LLVMTypeConverter::convertBoxType(BaseBoxType box, int rank) const {
mlir::Type LLVMTypeConverter::convertBoxTypeAsStruct(BaseBoxType box,
int rank) const {
// (base_addr*, elem_len, version, rank, type, attribute, f18Addendum, [dim]
llvm::SmallVector<mlir::Type> dataDescFields;
mlir::Type ele = box.getEleTy();
Expand All @@ -217,7 +212,8 @@ mlir::Type LLVMTypeConverter::convertBoxType(BaseBoxType box, int rank) const {
if (ele.isa<SequenceType>() && eleTy.isa<mlir::LLVM::LLVMPointerType>())
dataDescFields.push_back(eleTy);
else
dataDescFields.push_back(mlir::LLVM::LLVMPointerType::get(eleTy));
dataDescFields.push_back(
mlir::LLVM::LLVMPointerType::get(eleTy.getContext()));
// elem_len
dataDescFields.push_back(
getDescFieldTypeModel<kElemLenPosInBox>()(&getContext()));
Expand Down Expand Up @@ -266,28 +262,24 @@ mlir::Type LLVMTypeConverter::convertBoxType(BaseBoxType box, int rank) const {
mlir::LLVM::LLVMArrayType::get(rowTy, numLenParams));
}
}
// TODO: send the box type and the converted LLVM structure layout
// to tbaaBuilder for proper creation of TBAATypeDescriptorOp.
return mlir::LLVM::LLVMPointerType::get(
mlir::LLVM::LLVMStructType::getLiteral(&getContext(), dataDescFields,
/*isPacked=*/false));
return mlir::LLVM::LLVMStructType::getLiteral(&getContext(), dataDescFields,
/*isPacked=*/false);
}

/// Convert fir.box type to the corresponding llvm struct type instead of a
/// pointer to this struct type.
mlir::Type LLVMTypeConverter::convertBoxTypeAsStruct(BaseBoxType box) const {
return convertBoxType(box)
.cast<mlir::LLVM::LLVMPointerType>()
.getElementType();
mlir::Type LLVMTypeConverter::convertBoxType(BaseBoxType box, int rank) const {
// TODO: send the box type and the converted LLVM structure layout
// to tbaaBuilder for proper creation of TBAATypeDescriptorOp.
return mlir::LLVM::LLVMPointerType::get(box.getContext());
}

// fir.boxproc<any> --> llvm<"{ any*, i8* }">
mlir::Type LLVMTypeConverter::convertBoxProcType(BoxProcType boxproc) const {
auto funcTy = convertType(boxproc.getEleTy());
auto i8PtrTy = mlir::LLVM::LLVMPointerType::get(
mlir::IntegerType::get(&getContext(), 8));
llvm::SmallVector<mlir::Type, 2> tuple = {funcTy, i8PtrTy};
return mlir::LLVM::LLVMStructType::getLiteral(&getContext(), tuple,
auto voidPtrTy = mlir::LLVM::LLVMPointerType::get(boxproc.getContext());
llvm::SmallVector<mlir::Type, 2> tuple = {funcTy, voidPtrTy};
return mlir::LLVM::LLVMStructType::getLiteral(boxproc.getContext(), tuple,
/*isPacked=*/false);
}

Expand Down Expand Up @@ -315,7 +307,7 @@ mlir::Type LLVMTypeConverter::convertRealType(fir::KindTy kind) const {
mlir::Type LLVMTypeConverter::convertSequenceType(SequenceType seq) const {
auto baseTy = convertType(seq.getEleTy());
if (characterWithDynamicLen(seq.getEleTy()))
return mlir::LLVM::LLVMPointerType::get(baseTy);
return baseTy;
auto shape = seq.getShape();
auto constRows = seq.getConstantRows();
if (constRows) {
Expand All @@ -328,16 +320,15 @@ mlir::Type LLVMTypeConverter::convertSequenceType(SequenceType seq) const {
if (!seq.hasDynamicExtents())
return baseTy;
}
return mlir::LLVM::LLVMPointerType::get(baseTy);
return baseTy;
}

// fir.tdesc<any> --> llvm<"i8*">
// TODO: For now use a void*, however pointer identity is not sufficient for
// the f18 object v. class distinction (F2003).
mlir::Type
LLVMTypeConverter::convertTypeDescType(mlir::MLIRContext *ctx) const {
return mlir::LLVM::LLVMPointerType::get(
mlir::IntegerType::get(&getContext(), 8));
return mlir::LLVM::LLVMPointerType::get(ctx);
}

// Relay TBAA tag attachment to TBAABuilder.
Expand Down
Loading