Skip to content

Commit a8bea8e

Browse files
committed
Make extern weak symbols for type descriptor not defined in translation unit
If a derived type is defined in a module in another translation unit, its "<scope mangling>.dt.<typename>" global is not declared in the current translation unit in lowering, and therefore not accessible in codegen. The symbol is not lowered because it is not use associated in any of the program units lowered in the current translation unit. If we wanted to deal with this in lowering, we would need to start lowering declaration for all variables from the module used by the lowered program units, which is not the current approach in lowering). Declare a tentative (extern weak) type descriptor symbol in codegen if no global exists for the type descriptor symbol. It may be resolved at link time, and will otherwise be a nullptr (so far, do not make it a link error if the symbol is defined nowhere to support codegen of FIR files produced without runtime info symbols for debug purposes).
1 parent 6c1b99c commit a8bea8e

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,9 +1172,21 @@ struct EmboxCommonConversion : public FIROpConversion<OP> {
11721172
return rewriter.create<mlir::LLVM::AddressOfOp>(loc, ty,
11731173
global.sym_name());
11741174
}
1175-
// Builtin derived types have no type descriptors. Return nullptr, that is
1176-
// what the runtime expects for these types.
1177-
return rewriter.create<mlir::LLVM::NullOp>(loc, this->voidPtrTy());
1175+
// The global does not exist in the current translation unit, but may be
1176+
// defined elsewhere (e.g., type defined in a module).
1177+
// For now, create a extern_weak symbols (will become nullptr if unresolved)
1178+
// to support generating code without the front-end generated symbols.
1179+
// These could be made available_externally to require the symbols to be
1180+
// defined elsewhere and to cause link-time failure otherwise.
1181+
auto i8Ty = rewriter.getIntegerType(8);
1182+
mlir::OpBuilder modBuilder(module.getBodyRegion());
1183+
// TODO: The symbol should be lowered to constant in lowering, they are read
1184+
// only.
1185+
modBuilder.create<mlir::LLVM::GlobalOp>(loc, i8Ty, /*isConstant=*/false,
1186+
mlir::LLVM::Linkage::ExternWeak,
1187+
name, mlir::Attribute{});
1188+
auto ty = mlir::LLVM::LLVMPointerType::get(i8Ty);
1189+
return rewriter.create<mlir::LLVM::AddressOfOp>(loc, ty, name);
11781190
}
11791191

11801192
template <typename BOX>

flang/test/Fir/type-descriptor.fir

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
// RUN: tco -o - %s | FileCheck %s
22

3+
!type_defined_elsewhere = type !fir.type<_QMsome_moduleTtype_defined_elsewhere{j:i32}>
4+
fir.global internal @_QFfooEx2 : !fir.box<!fir.heap<!type_defined_elsewhere>> {
5+
%0 = fir.zero_bits !fir.heap<!type_defined_elsewhere>
6+
%1 = fir.embox %0 : (!fir.heap<!type_defined_elsewhere>) -> !fir.box<!fir.heap<!type_defined_elsewhere>>
7+
fir.has_value %1 : !fir.box<!fir.heap<!type_defined_elsewhere>>
8+
}
9+
// CHECK: @_QMsome_moduleE.dt.type_defined_elsewhere = extern_weak global i8
10+
// CHECK: @_QFfooEx2 = internal global { %_QMsome_moduleTtype_defined_elsewhere*, i64, i32, i8, i8, i8, i8, i8*, [1 x i64] }
11+
// CHECK-SAME: { %_QMsome_moduleTtype_defined_elsewhere* null, i64 ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64),
12+
// CHECK-SAME: i32 20180515, i8 0, i8 34, i8 2, i8 1, i8* @_QMsome_moduleE.dt.type_defined_elsewhere, [1 x i64] undef }
13+
314
!sometype = type !fir.type<_QFfooTsometype{num:i32,values:!fir.box<!fir.ptr<!fir.array<?x?xf32>>>}>
415
fir.global internal @_QFfooE.dt.sometype : i8
516
fir.global internal @_QFfooEx : !fir.box<!fir.heap<!sometype>> {
617
%0 = fir.zero_bits !fir.heap<!sometype>
718
%1 = fir.embox %0 : (!fir.heap<!sometype>) -> !fir.box<!fir.heap<!sometype>>
819
fir.has_value %1 : !fir.box<!fir.heap<!sometype>>
920
}
10-
1121
// CHECK: @_QFfooEx = internal global { %_QFfooTsometype*, i64, i32, i8, i8, i8, i8, i8*, [1 x i64] }
1222
// CHECK-SAME: { %_QFfooTsometype* null, i64 ptrtoint (%_QFfooTsometype* getelementptr (%_QFfooTsometype, %_QFfooTsometype* null, i32 1) to i64),
1323
// CHECK-SAME: i32 20180515, i8 0, i8 34, i8 2, i8 1, i8* @_QFfooE.dt.sometype, [1 x i64] undef }

0 commit comments

Comments
 (0)