Skip to content

Commit fdc2434

Browse files
jeanPerierrlavaee
authored andcommitted
Revert "[flang] add option to generate runtime type info as external" (llvm#146064)
Reverts llvm#145901 Broke shared library builds because of the usage of `skipExternalRttiDefinition` in Lowering.
1 parent c76d11a commit fdc2434

File tree

15 files changed

+153
-256
lines changed

15 files changed

+153
-256
lines changed

flang/include/flang/Evaluate/tools.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1585,7 +1585,6 @@ bool IsExtensibleType(const DerivedTypeSpec *);
15851585
bool IsSequenceOrBindCType(const DerivedTypeSpec *);
15861586
bool IsBuiltinDerivedType(const DerivedTypeSpec *derived, const char *name);
15871587
bool IsBuiltinCPtr(const Symbol &);
1588-
bool IsFromBuiltinModule(const Symbol &);
15891588
bool IsEventType(const DerivedTypeSpec *);
15901589
bool IsLockType(const DerivedTypeSpec *);
15911590
bool IsNotifyType(const DerivedTypeSpec *);

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,6 @@ struct FIRToLLVMPassOptions {
3939
// that such programs would crash at runtime if the derived type descriptors
4040
// are required by the runtime, so this is only an option to help debugging.
4141
bool ignoreMissingTypeDescriptors = false;
42-
// Similar to ignoreMissingTypeDescriptors, but generate external declaration
43-
// for the missing type descriptor globals instead.
44-
bool skipExternalRttiDefinition = false;
4542

4643
// Generate TBAA information for FIR types and memory accessing operations.
4744
bool applyTBAA = false;

flang/include/flang/Optimizer/Passes/CommandLineOpts.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,6 @@ extern llvm::cl::opt<std::size_t> arrayStackAllocationThreshold;
3232
/// generated by the frontend.
3333
extern llvm::cl::opt<bool> ignoreMissingTypeDescriptors;
3434

35-
/// Shared option in tools to only generate rtti static object definitions for
36-
/// derived types defined in the current compilation unit. Derived type
37-
/// descriptor object for types defined in other objects will only be declared
38-
/// as external. This also changes the linkage of rtti objects defined in the
39-
/// current compilation unit from linkonce_odr to external so that unused rtti
40-
/// objects are retained and can be accessed from other compilation units. This
41-
/// is an experimental option to explore compilation speed improvements and is
42-
/// an ABI breaking change because of the linkage change.
43-
/// It will also require linking against module file objects of modules defining
44-
/// only types (even for trivial types without type bound procedures, which
45-
/// differs from most compilers).
46-
extern llvm::cl::opt<bool> skipExternalRttiDefinition;
47-
4835
/// Default optimization level used to create Flang pass pipeline is O0.
4936
extern llvm::OptimizationLevel defaultOptLevel;
5037

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,32 @@ inline std::int64_t toInt(mlir::arith::ConstantOp cop) {
3535
.getSExtValue();
3636
}
3737

38+
// Reconstruct binding tables for dynamic dispatch.
39+
using BindingTable = llvm::DenseMap<llvm::StringRef, unsigned>;
40+
using BindingTables = llvm::DenseMap<llvm::StringRef, BindingTable>;
41+
42+
inline void buildBindingTables(BindingTables &bindingTables,
43+
mlir::ModuleOp mod) {
44+
45+
// The binding tables are defined in FIR after lowering inside fir.type_info
46+
// operations. Go through each binding tables and store the procedure name and
47+
// binding index for later use by the fir.dispatch conversion pattern.
48+
for (auto typeInfo : mod.getOps<fir::TypeInfoOp>()) {
49+
unsigned bindingIdx = 0;
50+
BindingTable bindings;
51+
if (typeInfo.getDispatchTable().empty()) {
52+
bindingTables[typeInfo.getSymName()] = bindings;
53+
continue;
54+
}
55+
for (auto dtEntry :
56+
typeInfo.getDispatchTable().front().getOps<fir::DTEntryOp>()) {
57+
bindings[dtEntry.getMethod()] = bindingIdx;
58+
++bindingIdx;
59+
}
60+
bindingTables[typeInfo.getSymName()] = bindings;
61+
}
62+
}
63+
3864
// Translate front-end KINDs for use in the IR and code gen.
3965
inline std::vector<fir::KindTy>
4066
fromDefaultKinds(const Fortran::common::IntrinsicTypeDefaultKinds &defKinds) {

flang/include/flang/Semantics/runtime-type-info.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@ RuntimeDerivedTypeTables BuildRuntimeDerivedTypeTables(SemanticsContext &);
3838
/// to describe other derived types at runtime in flang descriptor.
3939
constexpr char typeInfoBuiltinModule[]{"__fortran_type_info"};
4040

41-
/// Name of the builtin derived type in __fortran_type_inf that is used for
42-
/// derived type descriptors.
43-
constexpr char typeDescriptorTypeName[]{"derivedtype"};
44-
4541
/// Name of the bindings descriptor component in the DerivedType type of the
4642
/// __Fortran_type_info module
4743
constexpr char bindingDescCompName[]{"binding"};

flang/lib/Evaluate/tools.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2334,11 +2334,6 @@ bool IsBuiltinCPtr(const Symbol &symbol) {
23342334
return false;
23352335
}
23362336

2337-
bool IsFromBuiltinModule(const Symbol &symbol) {
2338-
const Scope &scope{symbol.GetUltimate().owner()};
2339-
return IsSameModule(&scope, scope.context().GetBuiltinsScope());
2340-
}
2341-
23422337
bool IsIsoCType(const DerivedTypeSpec *derived) {
23432338
return IsBuiltinDerivedType(derived, "c_ptr") ||
23442339
IsBuiltinDerivedType(derived, "c_funptr");

flang/lib/Lower/Bridge.cpp

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
#include "flang/Optimizer/Dialect/FIROps.h"
5353
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
5454
#include "flang/Optimizer/HLFIR/HLFIROps.h"
55-
#include "flang/Optimizer/Passes/CommandLineOpts.h"
5655
#include "flang/Optimizer/Support/DataLayout.h"
5756
#include "flang/Optimizer/Support/FatalError.h"
5857
#include "flang/Optimizer/Support/InternalNames.h"
@@ -263,7 +262,6 @@ class TypeInfoConverter {
263262
}
264263

265264
void createTypeInfo(Fortran::lower::AbstractConverter &converter) {
266-
createTypeInfoForTypeDescriptorBuiltinType(converter);
267265
while (!registeredTypeInfoA.empty()) {
268266
currentTypeInfoStack = &registeredTypeInfoB;
269267
for (const TypeInfo &info : registeredTypeInfoA)
@@ -279,22 +277,10 @@ class TypeInfoConverter {
279277
private:
280278
void createTypeInfoOpAndGlobal(Fortran::lower::AbstractConverter &converter,
281279
const TypeInfo &info) {
282-
if (!::skipExternalRttiDefinition)
283-
Fortran::lower::createRuntimeTypeInfoGlobal(converter, info.symbol.get());
280+
Fortran::lower::createRuntimeTypeInfoGlobal(converter, info.symbol.get());
284281
createTypeInfoOp(converter, info);
285282
}
286283

287-
void createTypeInfoForTypeDescriptorBuiltinType(
288-
Fortran::lower::AbstractConverter &converter) {
289-
if (registeredTypeInfoA.empty())
290-
return;
291-
auto builtinTypeInfoType = llvm::cast<fir::RecordType>(
292-
converter.genType(registeredTypeInfoA[0].symbol.get()));
293-
converter.getFirOpBuilder().createTypeInfoOp(
294-
registeredTypeInfoA[0].loc, builtinTypeInfoType,
295-
/*parentType=*/fir::RecordType{});
296-
}
297-
298284
void createTypeInfoOp(Fortran::lower::AbstractConverter &converter,
299285
const TypeInfo &info) {
300286
fir::RecordType parentType{};

flang/lib/Lower/ConvertVariable.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
#include "flang/Optimizer/Dialect/FIROps.h"
3939
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
4040
#include "flang/Optimizer/HLFIR/HLFIROps.h"
41-
#include "flang/Optimizer/Passes/CommandLineOpts.h"
4241
#include "flang/Optimizer/Support/FatalError.h"
4342
#include "flang/Optimizer/Support/InternalNames.h"
4443
#include "flang/Optimizer/Support/Utils.h"
@@ -653,13 +652,8 @@ getLinkageAttribute(fir::FirOpBuilder &builder,
653652
// Runtime type info for a same derived type is identical in each compilation
654653
// unit. It desired to avoid having to link against module that only define a
655654
// type. Therefore the runtime type info is generated everywhere it is needed
656-
// with `linkonce_odr` LLVM linkage (unless the skipExternalRttiDefinition
657-
// option is set, in which case one will need to link against objects of
658-
// modules defining types). Builtin objects rtti is always generated because
659-
// the builtin module is currently not compiled or part of the runtime.
660-
if (var.isRuntimeTypeInfoData() &&
661-
(!::skipExternalRttiDefinition ||
662-
Fortran::semantics::IsFromBuiltinModule(var.getSymbol())))
655+
// with `linkonce_odr` LLVM linkage.
656+
if (var.isRuntimeTypeInfoData())
663657
return builder.createLinkOnceODRLinkage();
664658
if (var.isModuleOrSubmoduleVariable())
665659
return {}; // external linkage

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 49 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,51 +1294,6 @@ genCUFAllocDescriptor(mlir::Location loc,
12941294
.getResult();
12951295
}
12961296

1297-
/// Get the address of the type descriptor global variable that was created by
1298-
/// lowering for derived type \p recType.
1299-
template <typename ModOpTy>
1300-
static mlir::Value
1301-
getTypeDescriptor(ModOpTy mod, mlir::ConversionPatternRewriter &rewriter,
1302-
mlir::Location loc, fir::RecordType recType,
1303-
const fir::FIRToLLVMPassOptions &options) {
1304-
std::string name =
1305-
options.typeDescriptorsRenamedForAssembly
1306-
? fir::NameUniquer::getTypeDescriptorAssemblyName(recType.getName())
1307-
: fir::NameUniquer::getTypeDescriptorName(recType.getName());
1308-
mlir::Type llvmPtrTy = ::getLlvmPtrType(mod.getContext());
1309-
if (auto global = mod.template lookupSymbol<fir::GlobalOp>(name))
1310-
return rewriter.create<mlir::LLVM::AddressOfOp>(loc, llvmPtrTy,
1311-
global.getSymName());
1312-
// The global may have already been translated to LLVM.
1313-
if (auto global = mod.template lookupSymbol<mlir::LLVM::GlobalOp>(name))
1314-
return rewriter.create<mlir::LLVM::AddressOfOp>(loc, llvmPtrTy,
1315-
global.getSymName());
1316-
// Type info derived types do not have type descriptors since they are the
1317-
// types defining type descriptors.
1318-
if (options.ignoreMissingTypeDescriptors ||
1319-
fir::NameUniquer::belongsToModule(
1320-
name, Fortran::semantics::typeInfoBuiltinModule))
1321-
return rewriter.create<mlir::LLVM::ZeroOp>(loc, llvmPtrTy);
1322-
1323-
if (!options.skipExternalRttiDefinition)
1324-
fir::emitFatalError(loc,
1325-
"runtime derived type info descriptor was not "
1326-
"generated and skipExternalRttiDefinition and "
1327-
"ignoreMissingTypeDescriptors options are not set");
1328-
1329-
// Rtti for a derived type defined in another compilation unit and for which
1330-
// rtti was not defined in lowering because of the skipExternalRttiDefinition
1331-
// option. Generate the object declaration now.
1332-
auto insertPt = rewriter.saveInsertionPoint();
1333-
rewriter.setInsertionPoint(mod.getBody(), mod.getBody()->end());
1334-
mlir::LLVM::GlobalOp global = rewriter.create<mlir::LLVM::GlobalOp>(
1335-
loc, llvmPtrTy, /*constant=*/true, mlir::LLVM::Linkage::External, name,
1336-
mlir::Attribute());
1337-
rewriter.restoreInsertionPoint(insertPt);
1338-
return rewriter.create<mlir::LLVM::AddressOfOp>(loc, llvmPtrTy,
1339-
global.getSymName());
1340-
}
1341-
13421297
/// Common base class for embox to descriptor conversion.
13431298
template <typename OP>
13441299
struct EmboxCommonConversion : public fir::FIROpConversion<OP> {
@@ -1451,6 +1406,36 @@ struct EmboxCommonConversion : public fir::FIROpConversion<OP> {
14511406
stride);
14521407
}
14531408

1409+
/// Get the address of the type descriptor global variable that was created by
1410+
/// lowering for derived type \p recType.
1411+
template <typename ModOpTy>
1412+
mlir::Value
1413+
getTypeDescriptor(ModOpTy mod, mlir::ConversionPatternRewriter &rewriter,
1414+
mlir::Location loc, fir::RecordType recType) const {
1415+
std::string name =
1416+
this->options.typeDescriptorsRenamedForAssembly
1417+
? fir::NameUniquer::getTypeDescriptorAssemblyName(recType.getName())
1418+
: fir::NameUniquer::getTypeDescriptorName(recType.getName());
1419+
mlir::Type llvmPtrTy = ::getLlvmPtrType(mod.getContext());
1420+
if (auto global = mod.template lookupSymbol<fir::GlobalOp>(name)) {
1421+
return rewriter.create<mlir::LLVM::AddressOfOp>(loc, llvmPtrTy,
1422+
global.getSymName());
1423+
}
1424+
if (auto global = mod.template lookupSymbol<mlir::LLVM::GlobalOp>(name)) {
1425+
// The global may have already been translated to LLVM.
1426+
return rewriter.create<mlir::LLVM::AddressOfOp>(loc, llvmPtrTy,
1427+
global.getSymName());
1428+
}
1429+
// Type info derived types do not have type descriptors since they are the
1430+
// types defining type descriptors.
1431+
if (!this->options.ignoreMissingTypeDescriptors &&
1432+
!fir::NameUniquer::belongsToModule(
1433+
name, Fortran::semantics::typeInfoBuiltinModule))
1434+
fir::emitFatalError(
1435+
loc, "runtime derived type info descriptor was not generated");
1436+
return rewriter.create<mlir::LLVM::ZeroOp>(loc, llvmPtrTy);
1437+
}
1438+
14541439
template <typename ModOpTy>
14551440
mlir::Value populateDescriptor(mlir::Location loc, ModOpTy mod,
14561441
fir::BaseBoxType boxTy, mlir::Type inputType,
@@ -1515,17 +1500,16 @@ struct EmboxCommonConversion : public fir::FIROpConversion<OP> {
15151500
mlir::Type innerType = fir::unwrapInnerType(inputType);
15161501
if (innerType && mlir::isa<fir::RecordType>(innerType)) {
15171502
auto recTy = mlir::dyn_cast<fir::RecordType>(innerType);
1518-
typeDesc =
1519-
getTypeDescriptor(mod, rewriter, loc, recTy, this->options);
1503+
typeDesc = getTypeDescriptor(mod, rewriter, loc, recTy);
15201504
} else {
15211505
// Unlimited polymorphic type descriptor with no record type. Set
15221506
// type descriptor address to a clean state.
15231507
typeDesc = rewriter.create<mlir::LLVM::ZeroOp>(
15241508
loc, ::getLlvmPtrType(mod.getContext()));
15251509
}
15261510
} else {
1527-
typeDesc = getTypeDescriptor(
1528-
mod, rewriter, loc, fir::unwrapIfDerived(boxTy), this->options);
1511+
typeDesc = getTypeDescriptor(mod, rewriter, loc,
1512+
fir::unwrapIfDerived(boxTy));
15291513
}
15301514
}
15311515
if (typeDesc)
@@ -3037,10 +3021,22 @@ struct TypeDescOpConversion : public fir::FIROpConversion<fir::TypeDescOp> {
30373021
assert(mlir::isa<fir::RecordType>(inTy) && "expecting fir.type");
30383022
auto recordType = mlir::dyn_cast<fir::RecordType>(inTy);
30393023
auto module = typeDescOp.getOperation()->getParentOfType<mlir::ModuleOp>();
3040-
mlir::Value typeDesc = getTypeDescriptor(
3041-
module, rewriter, typeDescOp.getLoc(), recordType, this->options);
3042-
rewriter.replaceOp(typeDescOp, typeDesc);
3043-
return mlir::success();
3024+
std::string typeDescName =
3025+
this->options.typeDescriptorsRenamedForAssembly
3026+
? fir::NameUniquer::getTypeDescriptorAssemblyName(
3027+
recordType.getName())
3028+
: fir::NameUniquer::getTypeDescriptorName(recordType.getName());
3029+
auto llvmPtrTy = ::getLlvmPtrType(typeDescOp.getContext());
3030+
if (auto global = module.lookupSymbol<mlir::LLVM::GlobalOp>(typeDescName)) {
3031+
rewriter.replaceOpWithNewOp<mlir::LLVM::AddressOfOp>(
3032+
typeDescOp, llvmPtrTy, global.getSymName());
3033+
return mlir::success();
3034+
} else if (auto global = module.lookupSymbol<fir::GlobalOp>(typeDescName)) {
3035+
rewriter.replaceOpWithNewOp<mlir::LLVM::AddressOfOp>(
3036+
typeDescOp, llvmPtrTy, global.getSymName());
3037+
return mlir::success();
3038+
}
3039+
return mlir::failure();
30443040
}
30453041
};
30463042

flang/lib/Optimizer/Passes/CommandLineOpts.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,6 @@ cl::opt<bool> ignoreMissingTypeDescriptors(
3939
"translating FIR to LLVM"),
4040
cl::init(false), cl::Hidden);
4141

42-
cl::opt<bool> skipExternalRttiDefinition(
43-
"skip-external-rtti-definition", llvm::cl::init(false),
44-
llvm::cl::desc("do not define rtti static objects for types belonging to "
45-
"other compilation units"),
46-
cl::Hidden);
47-
4842
OptimizationLevel defaultOptLevel{OptimizationLevel::O0};
4943

5044
codegenoptions::DebugInfoKind noDebugInfo{codegenoptions::NoDebugInfo};

flang/lib/Optimizer/Passes/Pipelines.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ void addFIRToLLVMPass(mlir::PassManager &pm,
108108
const MLIRToLLVMPassPipelineConfig &config) {
109109
fir::FIRToLLVMPassOptions options;
110110
options.ignoreMissingTypeDescriptors = ignoreMissingTypeDescriptors;
111-
options.skipExternalRttiDefinition = skipExternalRttiDefinition;
112111
options.applyTBAA = config.AliasAnalysis;
113112
options.forceUnifiedTBAATree = useOldAliasTags;
114113
options.typeDescriptorsRenamedForAssembly =

0 commit comments

Comments
 (0)