Skip to content

Commit 8a1ce2d

Browse files
authored
[flang][codegen] Update FIR codegen to use mlir.llvm opaque pointers (#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).
1 parent bf3a981 commit 8a1ce2d

18 files changed

+970
-1065
lines changed

flang/include/flang/Optimizer/CodeGen/TypeConverter.h

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class LLVMTypeConverter : public mlir::LLVMTypeConverter {
7474

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

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

9999
template <typename A> mlir::Type convertPointerLike(A &ty) const {
100-
mlir::Type eleTy = ty.getEleTy();
101-
// A sequence type is a special case. A sequence of runtime size on its
102-
// interior dimensions lowers to a memory reference. In that case, we
103-
// degenerate the array and do not want a the type to become `T**` but
104-
// merely `T*`.
105-
if (auto seqTy = eleTy.dyn_cast<fir::SequenceType>()) {
106-
if (seqTy.hasDynamicExtents() ||
107-
characterWithDynamicLen(seqTy.getEleTy())) {
108-
if (seqTy.getConstantRows() > 0)
109-
return convertType(seqTy);
110-
eleTy = seqTy.getEleTy();
111-
}
112-
}
113-
// fir.ref<fir.box> is a special case because fir.box type is already
114-
// a pointer to a Fortran descriptor at the LLVM IR level. This implies
115-
// that a fir.ref<fir.box>, that is the address of fir.box is actually
116-
// the same as a fir.box at the LLVM level.
117-
// The distinction is kept in fir to denote when a descriptor is expected
118-
// to be mutable (fir.ref<fir.box>) and when it is not (fir.box).
119-
if (eleTy.isa<fir::BaseBoxType>())
120-
return convertType(eleTy);
121-
122-
return mlir::LLVM::LLVMPointerType::get(convertType(eleTy));
100+
return mlir::LLVM::LLVMPointerType::get(ty.getContext());
123101
}
124102

125103
// convert a front-end kind value to either a std or LLVM IR dialect type

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 231 additions & 231 deletions
Large diffs are not rendered by default.

flang/lib/Optimizer/CodeGen/DescriptorModel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ TypeBuilderFunc getModel();
4040
template <>
4141
TypeBuilderFunc getModel<void *>() {
4242
return [](mlir::MLIRContext *context) -> mlir::Type {
43-
return mlir::LLVM::LLVMPointerType::get(mlir::IntegerType::get(context, 8));
43+
return mlir::LLVM::LLVMPointerType::get(context);
4444
};
4545
}
4646
template <>

flang/lib/Optimizer/CodeGen/TypeConverter.cpp

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,7 @@ namespace fir {
2828

2929
LLVMTypeConverter::LLVMTypeConverter(mlir::ModuleOp module, bool applyTBAA,
3030
bool forceUnifiedTBAATree)
31-
: mlir::LLVMTypeConverter(module.getContext(),
32-
[&] {
33-
mlir::LowerToLLVMOptions options(
34-
module.getContext());
35-
options.useOpaquePointers = false;
36-
return options;
37-
}()),
31+
: mlir::LLVMTypeConverter(module.getContext()),
3832
kindMapping(getKindMapping(module)),
3933
specifics(CodeGenSpecifics::get(module.getContext(),
4034
getTargetTriple(module),
@@ -205,7 +199,8 @@ bool LLVMTypeConverter::requiresExtendedDesc(mlir::Type boxElementType) const {
205199

206200
// This corresponds to the descriptor as defined in ISO_Fortran_binding.h and
207201
// the addendum defined in descriptor.h.
208-
mlir::Type LLVMTypeConverter::convertBoxType(BaseBoxType box, int rank) const {
202+
mlir::Type LLVMTypeConverter::convertBoxTypeAsStruct(BaseBoxType box,
203+
int rank) const {
209204
// (base_addr*, elem_len, version, rank, type, attribute, f18Addendum, [dim]
210205
llvm::SmallVector<mlir::Type> dataDescFields;
211206
mlir::Type ele = box.getEleTy();
@@ -217,7 +212,8 @@ mlir::Type LLVMTypeConverter::convertBoxType(BaseBoxType box, int rank) const {
217212
if (ele.isa<SequenceType>() && eleTy.isa<mlir::LLVM::LLVMPointerType>())
218213
dataDescFields.push_back(eleTy);
219214
else
220-
dataDescFields.push_back(mlir::LLVM::LLVMPointerType::get(eleTy));
215+
dataDescFields.push_back(
216+
mlir::LLVM::LLVMPointerType::get(eleTy.getContext()));
221217
// elem_len
222218
dataDescFields.push_back(
223219
getDescFieldTypeModel<kElemLenPosInBox>()(&getContext()));
@@ -266,28 +262,24 @@ mlir::Type LLVMTypeConverter::convertBoxType(BaseBoxType box, int rank) const {
266262
mlir::LLVM::LLVMArrayType::get(rowTy, numLenParams));
267263
}
268264
}
269-
// TODO: send the box type and the converted LLVM structure layout
270-
// to tbaaBuilder for proper creation of TBAATypeDescriptorOp.
271-
return mlir::LLVM::LLVMPointerType::get(
272-
mlir::LLVM::LLVMStructType::getLiteral(&getContext(), dataDescFields,
273-
/*isPacked=*/false));
265+
return mlir::LLVM::LLVMStructType::getLiteral(&getContext(), dataDescFields,
266+
/*isPacked=*/false);
274267
}
275268

276269
/// Convert fir.box type to the corresponding llvm struct type instead of a
277270
/// pointer to this struct type.
278-
mlir::Type LLVMTypeConverter::convertBoxTypeAsStruct(BaseBoxType box) const {
279-
return convertBoxType(box)
280-
.cast<mlir::LLVM::LLVMPointerType>()
281-
.getElementType();
271+
mlir::Type LLVMTypeConverter::convertBoxType(BaseBoxType box, int rank) const {
272+
// TODO: send the box type and the converted LLVM structure layout
273+
// to tbaaBuilder for proper creation of TBAATypeDescriptorOp.
274+
return mlir::LLVM::LLVMPointerType::get(box.getContext());
282275
}
283276

284277
// fir.boxproc<any> --> llvm<"{ any*, i8* }">
285278
mlir::Type LLVMTypeConverter::convertBoxProcType(BoxProcType boxproc) const {
286279
auto funcTy = convertType(boxproc.getEleTy());
287-
auto i8PtrTy = mlir::LLVM::LLVMPointerType::get(
288-
mlir::IntegerType::get(&getContext(), 8));
289-
llvm::SmallVector<mlir::Type, 2> tuple = {funcTy, i8PtrTy};
290-
return mlir::LLVM::LLVMStructType::getLiteral(&getContext(), tuple,
280+
auto voidPtrTy = mlir::LLVM::LLVMPointerType::get(boxproc.getContext());
281+
llvm::SmallVector<mlir::Type, 2> tuple = {funcTy, voidPtrTy};
282+
return mlir::LLVM::LLVMStructType::getLiteral(boxproc.getContext(), tuple,
291283
/*isPacked=*/false);
292284
}
293285

@@ -315,7 +307,7 @@ mlir::Type LLVMTypeConverter::convertRealType(fir::KindTy kind) const {
315307
mlir::Type LLVMTypeConverter::convertSequenceType(SequenceType seq) const {
316308
auto baseTy = convertType(seq.getEleTy());
317309
if (characterWithDynamicLen(seq.getEleTy()))
318-
return mlir::LLVM::LLVMPointerType::get(baseTy);
310+
return baseTy;
319311
auto shape = seq.getShape();
320312
auto constRows = seq.getConstantRows();
321313
if (constRows) {
@@ -328,16 +320,15 @@ mlir::Type LLVMTypeConverter::convertSequenceType(SequenceType seq) const {
328320
if (!seq.hasDynamicExtents())
329321
return baseTy;
330322
}
331-
return mlir::LLVM::LLVMPointerType::get(baseTy);
323+
return baseTy;
332324
}
333325

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

343334
// Relay TBAA tag attachment to TBAABuilder.

0 commit comments

Comments
 (0)