Skip to content

Commit

Permalink
[flang][codegen] Update FIR codegen to use mlir.llvm opaque pointers (#…
Browse files Browse the repository at this point in the history
…69692)

!llvm.ptr<T> typed pointers are depreciated in MLIR LLVM dialects. Flang
codegen still generated them and relied on mlir.llvm codegen to LLVM to
turn them into opaque pointers.

This patch update FIR codegen to directly emit and work with LLVM opaque
pointers.

Addresses #69303

- All places generating GEPs need to add an extra type argument with the
base type (the T that was previously in the llvm.ptr<T> of the base).

- llvm.alloca must also be provided the object type. In the process, I
doscovered that we were shamelessly copying all the attribute from
fir.alloca to the llvm.alloca, which makes no sense for the operand
segments. The updated code that cannot take an attribute dictionnary in
the llvm.alloca builder with opaque pointers only propagate the "pinned"
and "bindc_name" attributes to help debugging the generated IR.

- Updating all the places that rely on getting the llvm object type from
lowered llvm.ptr<T> arguments to get it from a type conversion of the
original fir types.

- Updating all the places that were generating llvm.ptr<T> types to
generate the opaque llvm.ptr type.

- Updating all the codegen tests checking generated MLIR llvm dialect.
Many tests are testing directly LLVM IR, and this change is a no-op for
those (which is expected).
  • Loading branch information
jeanPerier committed Oct 25, 2023
1 parent bf3a981 commit 8a1ce2d
Show file tree
Hide file tree
Showing 18 changed files with 970 additions and 1,065 deletions.
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

0 comments on commit 8a1ce2d

Please sign in to comment.