@@ -76,33 +76,6 @@ inline std::string create_prefixed_name(Args&&... args) {
7676
7777namespace typedb {
7878
79- struct GlobalTypeData {
80- struct TypeData {
81- llvm::Constant* type_struct;
82- llvm::GlobalVariable* type;
83- llvm::Constant* name;
84- llvm::Constant* offset;
85- llvm::Constant* count;
86- };
87- llvm::StringMap<TypeData> global_type_data;
88-
89- inline bool has_type_name (llvm::StringRef name) const {
90- #if LLVM_VERSION_MAJOR > 17
91- return global_type_data.contains (name);
92- #else
93- return global_type_data.find (name) != global_type_data.end ();
94- #endif
95- }
96-
97- inline const TypeData& get_type (llvm::StringRef name) const {
98- #if LLVM_VERSION_MAJOR > 17
99- return global_type_data.at (name);
100- #else
101- return global_type_data.find (name)->second ;
102- #endif
103- }
104- };
105-
10679struct GlobalTypeCallback {
10780 llvm::Module* module_;
10881 const TAFunctionQuery* f_query_;
@@ -245,7 +218,6 @@ struct GlobalTypeRegistrar {
245218 llvm::IRBuilder<> ir_build;
246219 GlobalTypeCallback type_callback;
247220 llvm::StructType* struct_layout_type_;
248- GlobalTypeData global_types_;
249221 TypeHelper types_helper;
250222 const bool builtin_emit_name{false };
251223
@@ -267,119 +239,108 @@ struct GlobalTypeRegistrar {
267239
268240 llvm::GlobalVariable* create_global (
269241 llvm::StringRef name, llvm::Type* type, llvm::Constant* init = nullptr ,
270- llvm::GlobalVariable::LinkageTypes link_type = llvm::GlobalValue::WeakODRLinkage) const {
271- // TODO: https://llvm.org/docs/LangRef.html#linkage w.r.t. forward declared types
242+ llvm::GlobalVariable::LinkageTypes link_type = llvm::GlobalValue::PrivateLinkage) const {
272243 auto * global_struct =
273244 new llvm::GlobalVariable (*module_, type, true , link_type, init, helper::create_prefixed_name (name));
274245 return global_struct;
275246 }
276247
277- llvm::Constant* make_gep (llvm::Type* type, llvm::GlobalVariable* global) {
278- auto * i32_zero_const = llvm::ConstantInt::get (ir_build.getInt32Ty (), 0 );
279- return llvm::ConstantExpr::getInBoundsGetElementPtr (
280- type, global, llvm::ArrayRef<llvm::Constant*>{i32_zero_const, i32_zero_const});
281- }
282-
283- llvm::Constant* create_global_constant_string (llvm::StringRef name) {
284- // TODO think about linkage
285- // auto* name_str = ir_build.CreateGlobalStringPtr(name, helper::create_prefixed_name("typename_", name), 0,
286- // module_);
248+ llvm::Constant* create_global_constant_string (llvm::StringRef name, llvm::StringRef payload) {
287249 auto * global_string =
288- ir_build.CreateGlobalString (name , helper::create_prefixed_name (" typename_" , name), 0 , module_);
250+ ir_build.CreateGlobalString (payload , helper::create_prefixed_name (" typename_" , name), 0 , module_);
289251 global_string->setConstant (true );
290- global_string->setLinkage (llvm::GlobalValue::WeakODRLinkage );
291- return make_gep ( global_string-> getValueType (), global_string) ;
252+ global_string->setLinkage (llvm::GlobalValue::PrivateLinkage );
253+ return global_string;
292254 }
293255
294- llvm::Constant* create_global_array_ptr (const llvm::StringRef name, llvm::ArrayRef<uint64_t > values) {
295- if (values.empty ()) {
296- LOG_DEBUG (" No values for global array, returning nullptr" )
256+ template <typename InputRange, typename ConversionFunc>
257+ llvm::Constant* create_global_array_from_range (llvm::StringRef global_name, const InputRange& inputs,
258+ llvm::Type* element_type, ConversionFunc&& convert_element) {
259+ if (inputs.empty ()) {
260+ LOG_DEBUG (" No values for global array, returning nullptr" );
297261 return types_helper.get_constant_nullptr ();
298262 }
299263
300264 std::vector<llvm::Constant*> constants;
301- constants.reserve (values.size ());
302- for (uint64_t val : values) {
303- constants.push_back (types_helper.get_constant_for (IGlobalType::member_offsets, val));
265+ constants.reserve (inputs.size ());
266+
267+ for (const auto & val : inputs) {
268+ constants.push_back (convert_element (val));
304269 }
305270
306- auto * array_ty = llvm::ArrayType::get (types_helper. get_type_for (IGlobalType::member_offsets, true ), values .size ());
271+ auto * array_ty = llvm::ArrayType::get (element_type, inputs .size ());
307272 auto * constant_array = llvm::ConstantArray::get (array_ty, constants);
308- auto * gv = create_global (name, array_ty, constant_array);
309- return make_gep (array_ty, gv);
310- }
311-
312- llvm::GlobalVariable* registerGlobalStruct (const std::string& name, int type_id, uint64_t type_size,
313- uint64_t member_count, llvm::Constant* offset_ptr,
314- llvm::Constant* members_data_ptr, llvm::Constant* count_ptr,
315- StructTypeFlag flag = StructTypeFlag::USER_DEFINED) {
316- const auto name_struct = flag == StructTypeFlag::FWD_DECL ? helper::concat (name, " _fwd" ) : name;
317273
318- llvm::GlobalVariable* global_struct = create_global (name_struct, struct_layout_type_);
319- global_struct->setConstant (false );
320-
321- // In the current scheme, built-ins do not need to produce a name string (Built)
322- const bool is_builtin = flag == StructTypeFlag::BUILTIN;
323- const bool emit_builtin_typename = is_builtin && builtin_emit_name;
324- llvm::Constant* name_str = (emit_builtin_typename || !is_builtin) ? create_global_constant_string (name)
325- : types_helper.get_constant_nullptr ();
326-
327- std::vector<llvm::Constant*> members = {
328- types_helper.get_constant_for (IGlobalType::type_id, type_id),
329- types_helper.get_constant_for (IGlobalType::extent, type_size),
330- types_helper.get_constant_for (IGlobalType::member_count, member_count),
331- types_helper.get_constant_for (IGlobalType::type_flag,
332- static_cast <int >(flag)), // TODO: use real type
333- name_str, //
334- offset_ptr, //
335- count_ptr, //
336- members_data_ptr};
337- llvm::Constant* init = llvm::ConstantStruct::get (struct_layout_type_, members);
338- global_struct->setInitializer (init);
274+ return create_global (global_name, array_ty, constant_array);
275+ }
339276
340- global_types_.global_type_data .try_emplace (
341- name, GlobalTypeData::TypeData{init, global_struct, name_str, offset_ptr, count_ptr});
277+ llvm::Constant* create_global_array_ptr (const llvm::StringRef name, llvm::ArrayRef<uint64_t > values,
278+ IGlobalType type = IGlobalType::member_offsets) {
279+ return create_global_array_from_range (name, values, types_helper.get_type_for (IGlobalType::member_offsets, true ),
280+ [&](uint64_t val) { return types_helper.get_constant_for (type, val); });
281+ }
342282
343- return global_struct;
283+ llvm::Constant* create_global_member_array_ptr (const llvm::StringRef name, llvm::ArrayRef<int > member_types) {
284+ return create_global_array_from_range (name, member_types, types_helper.get_type_for (IGlobalType::member_types),
285+ [&](int member_id) { return getOrRegister (member_id); });
344286 }
345287
346288 llvm::GlobalVariable* registerTypeStruct (const StructTypeInfo* type_struct) {
347- const auto name = type_struct->name ;
348- const auto type_size = type_struct->extent ;
289+ const auto base_name = type_struct->name ;
290+ const bool is_fwd = type_struct->flag == StructTypeFlag::FWD_DECL;
291+ const auto link_name = is_fwd ? helper::concat (base_name, " _fwd" ) : base_name;
349292
350- if (type_struct->flag == StructTypeFlag::FWD_DECL) {
351- LOG_DEBUG (" Type is forward decl " << name)
352- // return registerGlobalStructDecl(name);
293+ if (is_fwd) {
294+ LOG_DEBUG (" Type is forward decl " << base_name)
353295 }
354296
355- llvm::Constant* offset_ptr = create_global_array_ptr (helper::concat (" offsets_" , name), type_struct->offsets );
356- llvm::Constant* count_ptr = create_global_array_ptr (helper::concat (" counts_" , name), type_struct->array_sizes );
297+ llvm::Constant* offsets_ptr = create_global_array_ptr (helper::concat (" offsets_" , link_name), type_struct->offsets );
298+ llvm::Constant* counts_ptr = create_global_array_ptr (helper::concat (" counts_" , link_name), type_struct->array_sizes ,
299+ IGlobalType::member_count);
300+ llvm::Constant* members_ptr =
301+ create_global_member_array_ptr (helper::concat (" member_types_" , link_name), type_struct->member_types );
357302
358- llvm::Constant* members_array;
359- llvm::Type* ptr_type{nullptr }; // TODO: make this unqual?
360- std::vector<llvm::Constant*> member_types{};
303+ const bool is_builtin = type_struct->flag == StructTypeFlag::BUILTIN;
304+ const bool emit_name = !is_builtin || builtin_emit_name;
361305
362- for (auto member_type_id : type_struct->member_types ) {
363- llvm::Constant* member = getOrRegister (member_type_id);
364- if (ptr_type == nullptr ) {
365- ptr_type = member->getType ();
366- }
367- member_types.emplace_back (member);
368- }
306+ llvm::Constant* name_str_ptr =
307+ emit_name ? create_global_constant_string (link_name, base_name) : types_helper.get_constant_nullptr ();
369308
370- const auto member_count = type_struct->member_types .size ();
371- if (ptr_type != nullptr ) {
372- assert (member_count == type_struct->num_members );
373- llvm::ArrayType* member_array_ty = llvm::ArrayType::get (ptr_type, member_count);
374- llvm::Constant* init = llvm::ConstantArray::get (member_array_ty, member_types);
375- members_array = create_global (helper::concat (" member_types_" , name), member_array_ty, init);
376- } else {
377- llvm::Constant* null_member = types_helper.get_constant_nullptr ();
378- members_array = null_member;
309+ llvm::GlobalVariable* global_struct =
310+ create_global (link_name, struct_layout_type_, nullptr , llvm::GlobalValue::LinkOnceODRLinkage);
311+ global_struct->setConstant (false );
312+
313+ std::vector<llvm::Constant*> init_fields = {
314+ types_helper.get_constant_for (IGlobalType::type_id, type_struct->type_id ),
315+ types_helper.get_constant_for (IGlobalType::extent, type_struct->extent ),
316+ types_helper.get_constant_for (IGlobalType::member_count, type_struct->member_types .size ()),
317+ types_helper.get_constant_for (IGlobalType::type_flag, static_cast <int >(type_struct->flag )),
318+ name_str_ptr,
319+ offsets_ptr,
320+ counts_ptr,
321+ members_ptr};
322+
323+ llvm::Constant* init = llvm::ConstantStruct::get (struct_layout_type_, init_fields);
324+ global_struct->setInitializer (init);
325+
326+ {
327+ llvm::Comdat* comdat = this ->module_ ->getOrInsertComdat (helper::create_prefixed_name (link_name));
328+ comdat->setSelectionKind (llvm::Comdat::Any);
329+ global_struct->setComdat (comdat);
330+
331+ auto add_to_comdat = [&](llvm::Constant* ptr) {
332+ if (auto * global = llvm::dyn_cast_or_null<llvm::GlobalObject>(ptr)) {
333+ global->setComdat (comdat);
334+ }
335+ };
336+
337+ add_to_comdat (offsets_ptr);
338+ add_to_comdat (counts_ptr);
339+ add_to_comdat (members_ptr);
340+ add_to_comdat (name_str_ptr);
379341 }
380342
381- return registerGlobalStruct (name, type_struct->type_id , type_size, member_count, offset_ptr, members_array,
382- count_ptr, type_struct->flag );
343+ return global_struct;
383344 }
384345
385346 llvm::GlobalVariable* registerBuiltin (int type_id) {
0 commit comments