Skip to content

Commit 4ccd57d

Browse files
authored
[flang][nfc] replace fir.dispatch_table with more generic fir.type_info (#68309)
The goal is to progressively propagate all the derived type info that is currently in the runtime type info globals into a FIR operation that can be easily queried and used by FIR/HLFIR passes. When this will be complete, the last step will be to stop generating the runtime info global in lowering, but to do that later in or just before codegen to keep the FIR files readable (on the added type-info.f90 tests, the lowered runtime info globals takes a whooping 2.6 millions characters on 1600 lines of the FIR textual output. The fir.type_info that contains all the info required to generate those globals for such "trivial" types takes 1721 characters on 9 lines). So far this patch simply starts by replacing the fir.dispatch_table operation by the fir.type_info operation and to add the noinit/ nofinal/nodestroy flags to it. These flags will soon be used in HLFIR to better rewrite hlfir.assign with derived types.
1 parent 98341df commit 4ccd57d

File tree

16 files changed

+292
-258
lines changed

16 files changed

+292
-258
lines changed

flang/include/flang/Lower/AbstractConverter.h

+4-6
Original file line numberDiff line numberDiff line change
@@ -212,12 +212,10 @@ class AbstractConverter {
212212

213213
/// Register a runtime derived type information object symbol to ensure its
214214
/// object will be generated as a global.
215-
virtual void registerRuntimeTypeInfo(mlir::Location loc,
216-
SymbolRef typeInfoSym) = 0;
217-
218-
virtual void registerDispatchTableInfo(
219-
mlir::Location loc,
220-
const Fortran::semantics::DerivedTypeSpec *typeSpec) = 0;
215+
virtual void
216+
registerTypeInfo(mlir::Location loc, SymbolRef typeInfoSym,
217+
const Fortran::semantics::DerivedTypeSpec &typeSpec,
218+
fir::RecordType type) = 0;
221219

222220
//===--------------------------------------------------------------------===//
223221
// Locations

flang/include/flang/Optimizer/Builder/FIRBuilder.h

-5
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,6 @@ class FirOpBuilder : public mlir::OpBuilder, public mlir::OpBuilder::Listener {
254254
bodyBuilder, linkage);
255255
}
256256

257-
/// Create a fir::DispatchTable operation.
258-
fir::DispatchTableOp createDispatchTableOp(mlir::Location loc,
259-
llvm::StringRef name,
260-
llvm::StringRef parentName);
261-
262257
/// Convert a StringRef string into a fir::StringLitOp.
263258
fir::StringLitOp createStringLitOp(mlir::Location loc,
264259
llvm::StringRef string);

flang/include/flang/Optimizer/Dialect/FIROps.td

+47-18
Original file line numberDiff line numberDiff line change
@@ -2778,6 +2778,10 @@ def fir_GlobalOp : fir_Op<"global", [IsolatedFromAbove, Symbol]> {
27782778
(*this)->getAttrOfType<mlir::StringAttr>(
27792779
mlir::SymbolTable::getSymbolAttrName()).getValue());
27802780
}
2781+
2782+
bool isInitialized() {
2783+
return getInitVal() || hasInitializationBody();
2784+
}
27812785
}];
27822786
}
27832787

@@ -2809,20 +2813,31 @@ def fir_GlobalLenOp : fir_Op<"global_len", []> {
28092813

28102814
def ImplicitFirTerminator : SingleBlockImplicitTerminator<"FirEndOp">;
28112815

2812-
def fir_DispatchTableOp : fir_Op<"dispatch_table",
2816+
def fir_TypeInfoOp : fir_Op<"type_info",
28132817
[IsolatedFromAbove, Symbol, ImplicitFirTerminator]> {
2814-
let summary = "Dispatch table definition";
2818+
let summary = "Derived type information";
28152819

28162820
let description = [{
2817-
Define a dispatch table for a derived type with type-bound procedures.
2821+
Define extra information about a !fir.type<> that represents
2822+
a Fortran derived type.
28182823

2819-
A dispatch table is an untyped symbol that contains a list of associations
2824+
The optional dispatch table region defines a dispatch table with the derived
2825+
type type-bound procedures. It contains a list of associations
28202826
between method identifiers and corresponding `FuncOp` symbols.
2821-
28222827
The ordering of associations in the map is determined by the front end.
28232828

2829+
The "no_init" flag indicates that this type has no components requiring default
2830+
initialization (including setting allocatable component to a clean deallocated
2831+
state).
2832+
2833+
The "no_destroy" flag indicates that there are no allocatable components
2834+
that require deallocation.
2835+
2836+
The "no_final" flag indicates that there are no final methods for this type,
2837+
for its parents ,or for components.
2838+
28242839
```mlir
2825-
fir.dispatch_table @_QDTMquuzTfoo {
2840+
fir.type_info @_QMquuzTfoo noinit nofinal : !fir.type<_QMquuzTfoo{i:i32}> dispatch_table {
28262841
fir.dt_entry method1, @_QFNMquuzTfooPmethod1AfooR
28272842
fir.dt_entry method2, @_QFNMquuzTfooPmethod2AfooII
28282843
}
@@ -2831,32 +2846,46 @@ def fir_DispatchTableOp : fir_Op<"dispatch_table",
28312846

28322847
let arguments = (ins
28332848
SymbolNameAttr:$sym_name,
2834-
OptionalAttr<StrAttr>:$parent
2849+
TypeAttr:$type,
2850+
OptionalAttr<TypeAttr>:$parent_type,
2851+
UnitAttr:$no_init,
2852+
UnitAttr:$no_destroy,
2853+
UnitAttr:$no_final
28352854
);
28362855

2837-
let hasCustomAssemblyFormat = 1;
28382856
let hasVerifier = 1;
28392857

2840-
let regions = (region AnyRegion:$region);
2858+
let regions = (region MaxSizedRegion<1>:$dispatch_table);
28412859

2842-
let skipDefaultBuilders = 1;
28432860
let builders = [
2844-
OpBuilder<(ins "llvm::StringRef":$name, "mlir::Type":$type,
2845-
"llvm::StringRef":$parent,
2861+
OpBuilder<(ins "fir::RecordType":$type, "fir::RecordType":$parent_type,
28462862
CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attrs)>
28472863
];
28482864

2849-
let extraClassDeclaration = [{
2850-
static constexpr llvm::StringRef getParentAttrNameStr() { return "parent"; }
2851-
static constexpr llvm::StringRef getExtendsKeyword() { return "extends"; }
2865+
let assemblyFormat = [{
2866+
$sym_name (`noinit` $no_init^)? (`nodestroy` $no_destroy^)?
2867+
(`nofinal` $no_final^)? (`extends` $parent_type^)? attr-dict `:` $type
2868+
(`dispatch_table` $dispatch_table^)?
2869+
}];
28522870

2853-
mlir::Block &getBlock() {
2854-
return getRegion().front();
2871+
let extraClassDeclaration = [{
2872+
fir::RecordType getRecordType() {
2873+
return mlir::cast<fir::RecordType>(getType());
2874+
}
2875+
fir::RecordType getIfParentType() {
2876+
if (auto parentType = getParentType())
2877+
return mlir::cast<fir::RecordType>(*parentType);
2878+
return {};
2879+
}
2880+
std::optional<llvm::StringRef> getIfParentName() {
2881+
if (auto parentType = getIfParentType())
2882+
return parentType.getName();
2883+
return std::nullopt;
28552884
}
28562885
}];
28572886
}
28582887

2859-
def fir_DTEntryOp : fir_Op<"dt_entry", [HasParent<"DispatchTableOp">]> {
2888+
def fir_DTEntryOp : fir_Op<"dt_entry", [HasParent<"TypeInfoOp">]> {
28602889
let summary = "map entry in a dispatch table";
28612890

28622891
let description = [{

flang/include/flang/Optimizer/Support/Utils.h

+8-7
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,22 @@ using BindingTables = llvm::DenseMap<llvm::StringRef, BindingTable>;
3636
inline void buildBindingTables(BindingTables &bindingTables,
3737
mlir::ModuleOp mod) {
3838

39-
// The binding tables are defined in FIR from lowering as fir.dispatch_table
40-
// operation. Go through each binding tables and store the procedure name and
39+
// The binding tables are defined in FIR after lowering inside fir.type_info
40+
// operations. Go through each binding tables and store the procedure name and
4141
// binding index for later use by the fir.dispatch conversion pattern.
42-
for (auto dispatchTableOp : mod.getOps<fir::DispatchTableOp>()) {
42+
for (auto typeInfo : mod.getOps<fir::TypeInfoOp>()) {
4343
unsigned bindingIdx = 0;
4444
BindingTable bindings;
45-
if (dispatchTableOp.getRegion().empty()) {
46-
bindingTables[dispatchTableOp.getSymName()] = bindings;
45+
if (typeInfo.getDispatchTable().empty()) {
46+
bindingTables[typeInfo.getSymName()] = bindings;
4747
continue;
4848
}
49-
for (auto dtEntry : dispatchTableOp.getBlock().getOps<fir::DTEntryOp>()) {
49+
for (auto dtEntry :
50+
typeInfo.getDispatchTable().front().getOps<fir::DTEntryOp>()) {
5051
bindings[dtEntry.getMethod()] = bindingIdx;
5152
++bindingIdx;
5253
}
53-
bindingTables[dispatchTableOp.getSymName()] = bindings;
54+
bindingTables[typeInfo.getSymName()] = bindings;
5455
}
5556
}
5657

0 commit comments

Comments
 (0)