diff --git a/README.md b/README.md index 9c7f4784..cf56a7c5 100644 --- a/README.md +++ b/README.md @@ -203,13 +203,14 @@ Type serialization for each user-defined type (mode `hybrid`) or *all* types (mo struct GlobalTypeInfo { std::int32_t type_id; const std::uint32_t extent; - const std::uint16_t num_members; - const std::uint16_t flag; + const GlobalTypeInfoData* data; // nullptr for built-ins +}; +struct GlobalTypeInfoData { const char* type_name; - const std::uint16_t* offsets; - const std::uint16_t* array_sizes; + // data : [ num_member, flag, offsets[num_member], array_sizes[num_member] ]: + const std::uint16_t* data; const GlobalTypeInfo** member_types; -}; +} ``` Each type is registered at startup with the TypeART runtime using the callback `void __typeart_register_type(const void* type_ptr);`. This adds the type information to the type database (for user queries) and assigns a unique `type-id`. diff --git a/lib/passes/analysis/MemOpVisitor.cpp b/lib/passes/analysis/MemOpVisitor.cpp index 3abc4f97..7c11a58c 100644 --- a/lib/passes/analysis/MemOpVisitor.cpp +++ b/lib/passes/analysis/MemOpVisitor.cpp @@ -167,33 +167,75 @@ std::optional getSingleUserAs(llvm::Instruction* value) { using MallocGeps = SmallPtrSet; using MallocBcasts = SmallPtrSet; -std::pair collectRelevantMallocUsers(llvm::CallBase& ci) { - auto geps = MallocGeps{}; - auto bcasts = MallocBcasts{}; - for (auto user : ci.users()) { - // Simple case: Pointer is immediately casted - if (auto inst = dyn_cast(user)) { - bcasts.insert(inst); - } - // Pointer is first stored, then loaded and subsequently casted - if (auto storeInst = dyn_cast(user)) { - auto storeAddr = storeInst->getPointerOperand(); - for (auto storeUser : storeAddr->users()) { // TODO: Ensure that load occurs after store? - if (auto loadInst = dyn_cast(storeUser)) { - for (auto loadUser : loadInst->users()) { - if (auto bcastInst = dyn_cast(loadUser)) { - // LOG_MSG(*bcastInst) - bcasts.insert(bcastInst); - } - } +// std::pair collectRelevantMallocUsers(llvm::CallBase& ci) { +// auto geps = MallocGeps{}; +// auto bcasts = MallocBcasts{}; +// for (auto user : ci.users()) { +// // Simple case: Pointer is immediately casted +// if (auto inst = dyn_cast(user)) { +// bcasts.insert(inst); +// } +// // Pointer is first stored, then loaded and subsequently casted +// if (auto storeInst = dyn_cast(user)) { +// auto storeAddr = storeInst->getPointerOperand(); +// if (!(storeAddr == nullptr || llvm::isa(storeAddr))) { +// for (auto storeUser : storeAddr->users()) { // TODO: Ensure that load occurs after store? +// if (auto loadInst = dyn_cast(storeUser)) { +// for (auto loadUser : loadInst->users()) { +// if (auto bcastInst = dyn_cast(loadUser)) { +// // LOG_MSG(*bcastInst) +// bcasts.insert(bcastInst); +// } +// } +// } +// } +// } else { +// LOG_DEBUG("Null, must skip") +// } +// } +// // GEP indicates that an array cookie is added to the allocation. (Fixes #13) +// if (auto gep = dyn_cast(user)) { +// geps.insert(gep); +// } +// } +// return {geps, bcasts}; +// } + +void collect_casts_from_stack(llvm::StoreInst* store_inst, MallocBcasts& out_bcasts) { + auto* slot = store_inst->getPointerOperand(); + + // Guard: Skip invalid or null storage locations + if (llvm::isa(slot)) { + LOG_DEBUG("Skipping null storage"); + return; + } + + for (auto* slot_user : slot->users()) { + // TODO: Ensure that load occurs after store? + if (auto* load_inst = llvm::dyn_cast(slot_user)) { + for (auto* load_user : load_inst->users()) { + if (auto* bit_cast = llvm::dyn_cast(load_user)) { + out_bcasts.insert(bit_cast); } } } - // GEP indicates that an array cookie is added to the allocation. (Fixes #13) - if (auto gep = dyn_cast(user)) { - geps.insert(gep); + } +} + +std::pair collectRelevantMallocUsers(llvm::CallBase& call_inst) { + auto geps = MallocGeps{}; + auto bcasts = MallocBcasts{}; + + for (auto* user : call_inst.users()) { + if (auto* bit_cast = llvm::dyn_cast(user)) { + bcasts.insert(bit_cast); + } else if (auto* gep_inst = llvm::dyn_cast(user)) { + geps.insert(gep_inst); + } else if (auto* store_inst = llvm::dyn_cast(user)) { + collect_casts_from_stack(store_inst, bcasts); } } + return {geps, bcasts}; } diff --git a/lib/passes/instrumentation/TypeIDProvider.cpp b/lib/passes/instrumentation/TypeIDProvider.cpp index b24a46a6..eb3e2a34 100644 --- a/lib/passes/instrumentation/TypeIDProvider.cpp +++ b/lib/passes/instrumentation/TypeIDProvider.cpp @@ -8,6 +8,7 @@ #include "support/ConfigurationBase.h" #include "support/Logger.h" +#include #include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include namespace typeart { @@ -72,6 +74,40 @@ inline std::string create_prefixed_name(Args&&... args) { return name; } +namespace detail { +template +T safe_cast(SourceT val) { + // Check if value exceeds the maximum limit of the target type T + // We cast max() to size_t to ensure we are comparing compatible types safely + assert(static_cast(val) <= static_cast(std::numeric_limits::max()) && + "Data loss detected: Value exceeds target type limits!"); + return static_cast(val); +} +} // namespace detail + +template +std::vector get_serialized_members_for(const StructTypeInfo& info) { + using namespace detail; + std::vector dest; + const size_t required_space = info.offsets.size() + info.array_sizes.size() + 2; + dest.reserve(required_space); + + // Layout : [ num_member, flag, offsets...[num_member], array_sizes...[num_member] ] + + dest.push_back(safe_cast(info.num_members)); + dest.push_back(safe_cast(static_cast>(info.flag))); + + for (size_t offset : info.offsets) { + dest.push_back(safe_cast(offset)); + } + + for (size_t size : info.array_sizes) { + dest.push_back(safe_cast(size)); + } + + return dest; +} + } // namespace helper namespace typedb { @@ -151,7 +187,8 @@ enum class IGlobalType : short { member_types, member_count, type_flag, - ptr + ptr, + info_holder }; struct TypeHelper { @@ -181,13 +218,14 @@ struct TypeHelper { } case IGlobalType::name: case IGlobalType::ptr: + case IGlobalType::info_holder: #if LLVM_VERSION_MAJOR < 15 return ir_build_.getInt8PtrTy(); #else return ir_build_.getPtrTy(); #endif } - llvm_unreachable("Should not be reached disk"); + llvm_unreachable("Should not be reached"); } llvm::Constant* get_constant_for(IGlobalType type, size_t value) { @@ -218,6 +256,7 @@ struct GlobalTypeRegistrar { llvm::IRBuilder<> ir_build; GlobalTypeCallback type_callback; llvm::StructType* struct_layout_type_; + llvm::StructType* struct_layout_type_cold_; TypeHelper types_helper; const bool builtin_emit_name{false}; @@ -225,15 +264,15 @@ struct GlobalTypeRegistrar { auto& context = module_->getContext(); struct_layout_type_ = llvm::StructType::create(context, "struct._typeart_struct_layout_t"); struct_layout_type_->setBody({ - types_helper.get_type_for(IGlobalType::type_id), // int type_id - types_helper.get_type_for(IGlobalType::extent), // uint32 extent - types_helper.get_type_for(IGlobalType::num_members), // uint16 num_members - types_helper.get_type_for(IGlobalType::type_flag), // uint16 type_flag + types_helper.get_type_for(IGlobalType::type_id), // uint32 type_id + types_helper.get_type_for(IGlobalType::extent), // uint32 extent + types_helper.get_type_for(IGlobalType::info_holder), + }); + struct_layout_type_cold_ = llvm::StructType::create(context, "struct._typeart_struct_layout_info_t"); + struct_layout_type_cold_->setBody({ types_helper.get_type_for(IGlobalType::name), // const char* name types_helper.get_type_for(IGlobalType::member_offsets), // const uint16* offsets - types_helper.get_type_for(IGlobalType::member_count), // const uint16* count types_helper.get_type_for(IGlobalType::member_types), // const typeart_struct_layout_t** member_types - }); } @@ -274,10 +313,11 @@ struct GlobalTypeRegistrar { return create_global(global_name, array_ty, constant_array); } - llvm::Constant* create_global_array_ptr(const llvm::StringRef name, llvm::ArrayRef values, + template + llvm::Constant* create_global_array_ptr(const llvm::StringRef name, llvm::ArrayRef values, IGlobalType type = IGlobalType::member_offsets) { return create_global_array_from_range(name, values, types_helper.get_type_for(IGlobalType::member_offsets, true), - [&](uint64_t val) { return types_helper.get_constant_for(type, val); }); + [&](const T& val) { return types_helper.get_constant_for(type, val); }); } llvm::Constant* create_global_member_array_ptr(const llvm::StringRef name, llvm::ArrayRef member_types) { @@ -294,51 +334,55 @@ struct GlobalTypeRegistrar { LOG_DEBUG("Type is forward decl " << base_name) } - llvm::Constant* offsets_ptr = create_global_array_ptr(helper::concat("offsets_", link_name), type_struct->offsets); - llvm::Constant* counts_ptr = create_global_array_ptr(helper::concat("counts_", link_name), type_struct->array_sizes, - IGlobalType::member_count); - llvm::Constant* members_ptr = - create_global_member_array_ptr(helper::concat("member_types_", link_name), type_struct->member_types); - const bool is_builtin = type_struct->flag == StructTypeFlag::BUILTIN; const bool emit_name = !is_builtin || builtin_emit_name; - llvm::Constant* name_str_ptr = - emit_name ? create_global_constant_string(link_name, base_name) : types_helper.get_constant_nullptr(); - llvm::GlobalVariable* global_struct = create_global(link_name, struct_layout_type_, nullptr, llvm::GlobalValue::LinkOnceODRLinkage); global_struct->setConstant(false); - std::vector init_fields = { - types_helper.get_constant_for(IGlobalType::type_id, type_struct->type_id), - types_helper.get_constant_for(IGlobalType::extent, type_struct->extent), - types_helper.get_constant_for(IGlobalType::member_count, type_struct->member_types.size()), - types_helper.get_constant_for(IGlobalType::type_flag, static_cast(type_struct->flag)), - name_str_ptr, - offsets_ptr, - counts_ptr, - members_ptr}; - - llvm::Constant* init = llvm::ConstantStruct::get(struct_layout_type_, init_fields); - global_struct->setInitializer(init); + llvm::Comdat* comdat = this->module_->getOrInsertComdat(helper::create_prefixed_name(link_name)); + comdat->setSelectionKind(llvm::Comdat::Any); + global_struct->setComdat(comdat); - { - llvm::Comdat* comdat = this->module_->getOrInsertComdat(helper::create_prefixed_name(link_name)); - comdat->setSelectionKind(llvm::Comdat::Any); - global_struct->setComdat(comdat); + auto add_to_comdat = [&](llvm::Constant* ptr) { + if (auto* global = llvm::dyn_cast_or_null(ptr)) { + global->setComdat(comdat); + } + }; - auto add_to_comdat = [&](llvm::Constant* ptr) { - if (auto* global = llvm::dyn_cast_or_null(ptr)) { - global->setComdat(comdat); + const auto get_info_object = [&]() -> llvm::Constant* { + if (emit_name) { + llvm::Constant* name_str_ptr = create_global_constant_string(link_name, base_name); + const auto info_data = helper::get_serialized_members_for(*type_struct); + llvm::Constant* data_ptr = + create_global_array_ptr(helper::concat("info_data_", link_name), info_data); + llvm::Constant* members_ptr = + create_global_member_array_ptr(helper::concat("member_types_", link_name), type_struct->member_types); + + llvm::GlobalVariable* global_struct_info = + create_global(helper::concat(link_name, "_info"), struct_layout_type_cold_, nullptr); + + std::vector init_fields_cold = {name_str_ptr, data_ptr, members_ptr}; + global_struct_info->setInitializer(llvm::ConstantStruct::get(struct_layout_type_cold_, init_fields_cold)); + + { + add_to_comdat(global_struct_info); + add_to_comdat(data_ptr); + add_to_comdat(members_ptr); + add_to_comdat(name_str_ptr); } - }; - add_to_comdat(offsets_ptr); - add_to_comdat(counts_ptr); - add_to_comdat(members_ptr); - add_to_comdat(name_str_ptr); - } + return global_struct_info; + } + return types_helper.get_constant_nullptr(); + }; + + std::vector init_fields = { + types_helper.get_constant_for(IGlobalType::type_id, type_struct->type_id), + types_helper.get_constant_for(IGlobalType::extent, type_struct->extent), get_info_object()}; + llvm::Constant* init = llvm::ConstantStruct::get(struct_layout_type_, init_fields); + global_struct->setInitializer(init); return global_struct; } diff --git a/lib/runtime/AllocationTracking.cpp b/lib/runtime/AllocationTracking.cpp index c22c2072..279e5272 100644 --- a/lib/runtime/AllocationTracking.cpp +++ b/lib/runtime/AllocationTracking.cpp @@ -292,7 +292,7 @@ void __typeart_leave_scope_omp(int alloca_count) { void __typeart_alloc_mty(const void* addr, const void* info, size_t count) { TYPEART_RUNTIME_GUARD; const void* retAddr = __builtin_return_address(0); - const auto type_id = reinterpret_cast(info)->type_id; + const auto type_id = reinterpret_cast(info)->type_id; auto& rt = typeart::RuntimeSystem::get(); assert(type_id == rt.type_translator().get_type_id_for(info) && "Type ID of global and lookup must match"); rt.allocation_tracker().onAlloc(addr, type_id, count, retAddr); @@ -301,7 +301,7 @@ void __typeart_alloc_mty(const void* addr, const void* info, size_t count) { void __typeart_alloc_stack_mty(const void* addr, const void* info, size_t count) { TYPEART_RUNTIME_GUARD; const void* retAddr = __builtin_return_address(0); - const auto type_id = reinterpret_cast(info)->type_id; + const auto type_id = reinterpret_cast(info)->type_id; auto& rt = typeart::RuntimeSystem::get(); assert(type_id == rt.type_translator().get_type_id_for(info) && "Type ID of global and lookup must match"); rt.allocation_tracker().onAllocStack(addr, type_id, count, retAddr); @@ -310,7 +310,7 @@ void __typeart_alloc_stack_mty(const void* addr, const void* info, size_t count) void __typeart_alloc_global_mty(const void* addr, const void* info, size_t count) { TYPEART_RUNTIME_GUARD; const void* retAddr = __builtin_return_address(0); - const auto type_id = reinterpret_cast(info)->type_id; + const auto type_id = reinterpret_cast(info)->type_id; auto& rt = typeart::RuntimeSystem::get(); assert(type_id == rt.type_translator().get_type_id_for(info) && "Type ID of global and lookup must match"); rt.allocation_tracker().onAllocGlobal(addr, type_id, count, retAddr); @@ -319,7 +319,7 @@ void __typeart_alloc_global_mty(const void* addr, const void* info, size_t count void __typeart_alloc_omp_mty(const void* addr, const void* info, size_t count) { TYPEART_RUNTIME_GUARD; const void* retAddr = __builtin_return_address(0); - const auto type_id = reinterpret_cast(info)->type_id; + const auto type_id = reinterpret_cast(info)->type_id; auto& rt = typeart::RuntimeSystem::get(); assert(type_id == rt.type_translator().get_type_id_for(info) && "Type ID of global and lookup must match"); rt.allocation_tracker().onAlloc(addr, type_id, count, retAddr); @@ -328,7 +328,7 @@ void __typeart_alloc_omp_mty(const void* addr, const void* info, size_t count) { void __typeart_alloc_stack_omp_mty(const void* addr, const void* info, size_t count) { TYPEART_RUNTIME_GUARD; const void* retAddr = __builtin_return_address(0); - const auto type_id = reinterpret_cast(info)->type_id; + const auto type_id = reinterpret_cast(info)->type_id; auto& rt = typeart::RuntimeSystem::get(); assert(type_id == rt.type_translator().get_type_id_for(info) && "Type ID of global and lookup must match"); rt.allocation_tracker().onAllocStack(addr, type_id, count, retAddr); diff --git a/lib/runtime/GlobalTypeDefCallbacks.cpp b/lib/runtime/GlobalTypeDefCallbacks.cpp index e59ec73f..c1ab03da 100644 --- a/lib/runtime/GlobalTypeDefCallbacks.cpp +++ b/lib/runtime/GlobalTypeDefCallbacks.cpp @@ -8,12 +8,110 @@ #include "typelib/TypeDatabase.h" #include +#include #include #include #include namespace typeart { +namespace global_types { +struct GlobalTypeInfoData { + private: + const char* name_; + // Layout : [ num_member, flag, offsets...[num_member], array_sizes...[num_member] ] + const std::uint16_t* data_; + const GlobalTypeInfo** member_types_; + + public: + [[nodiscard]] const char* name() const { + assert(name_ != nullptr && "Name should not be NULL"); + return name_; + } + + [[nodiscard]] const GlobalTypeInfo** member_types() const { + return member_types_; + } + + [[nodiscard]] uint16_t num_member() const { + assert(data_ != nullptr && "Data should not be NULL"); + return data_[0]; + } + + [[nodiscard]] uint16_t flag() const { + assert(data_ != nullptr && "Data should not be NULL"); + return data_[1]; + } + + [[nodiscard]] const uint16_t* offsets() const { + return &data_[2]; + } + + [[nodiscard]] const uint16_t* array_sizes() const { + return &data_[2 + num_member()]; + } +}; +} // namespace global_types + +using namespace typeart::global_types; + +class TypeInfoHandle { + public: + explicit TypeInfoHandle(const GlobalTypeInfo* info) : info_(info) { + } + + [[nodiscard]] bool is_valid() const { + return info_ != nullptr; + } + + [[nodiscard]] const GlobalTypeInfo* handle() const { + return info_; + } + + [[nodiscard]] std::int32_t type_id() const { + return info_->type_id; + } + + [[nodiscard]] std::uint32_t extent() const { + return info_->extent; + } + + [[nodiscard]] bool is_builtin() const { + return builtins::BuiltInQuery::is_builtin_type(type_id()); + } + + [[nodiscard]] bool has_metadata() const { + return info_->data != nullptr; + } + + [[nodiscard]] const char* name() const { + return info_->data->name(); + } + + [[nodiscard]] std::uint16_t num_members() const { + return info_->data->num_member(); + } + + [[nodiscard]] std::uint16_t flags() const { + return info_->data->flag(); + } + + [[nodiscard]] TypeInfoHandle get_member_type(size_t index) const { + return TypeInfoHandle(info_->data->member_types()[index]); + } + + [[nodiscard]] std::uint16_t get_offset(size_t index) const { + return info_->data->offsets()[index]; + } + + [[nodiscard]] std::uint16_t get_array_size(size_t index) const { + return info_->data->array_sizes()[index]; + } + + private: + const GlobalTypeInfo* info_; +}; + #define unlikely(x) __builtin_expect(!!(x), 0) #define CONCAT_(x, y) x##y #define CONCAT(x, y) CONCAT_(x, y) @@ -37,9 +135,10 @@ class GlobalTypeTranslator::Impl { int next_type_id(const GlobalTypeInfo* type) { // a fwd_decl and the decl must have the same type_id: { - const auto& struct_list = type_db_.getStructList(); + const auto& struct_list = type_db_.getStructList(); + const auto* const global_type_name = type->data->name(); for (const auto& type_in_db : struct_list) { - if (type_in_db.name == type->name) { + if (type_in_db.name == global_type_name) { return type_in_db.type_id; } } @@ -49,36 +148,40 @@ class GlobalTypeTranslator::Impl { return id; } - int register_t(const GlobalTypeInfo* type) { // NOLINT(misc-no-recursion) - if (unlikely(type == nullptr)) { + int register_t(TypeInfoHandle type_handle) { + if (unlikely(!type_handle.is_valid())) { LOG_ERROR("Type descriptor is NULL, is it a weak extern global due to fwd decl?"); return TYPEART_UNKNOWN_TYPE; } - if (auto element = translator_map_.find(type); element != translator_map_.end()) { + if (auto element = translator_map_.find(type_handle.handle()); element != translator_map_.end()) { return element->second; } - const bool built_in = builtins::BuiltInQuery::is_builtin_type(type->type_id); - if (built_in) { - translator_map_.try_emplace(type, type->type_id); - return type->type_id; + if (type_handle.is_builtin()) { + translator_map_.try_emplace(type_handle.handle(), type_handle.type_id()); + return type_handle.type_id(); } + assert(type_handle.has_metadata() && "Required metadata is NULL"); + StructTypeInfo type_descriptor; - type_descriptor.type_id = next_type_id(type); - type_descriptor.name = type->name; - type_descriptor.extent = type->extent; - type_descriptor.num_members = type->num_members; - type_descriptor.flag = static_cast(type->flag); - - type_descriptor.array_sizes.reserve(type->num_members); - type_descriptor.offsets.reserve(type->num_members); - type_descriptor.member_types.reserve(type->num_members); - for (uint32_t i = 0; i < type->num_members; ++i) { - const auto member_id = register_t(type->member_types[i]); - const auto array_size = type->array_sizes[i]; - const auto offset = type->offsets[i]; + type_descriptor.type_id = next_type_id(type_handle.handle()); + type_descriptor.name = type_handle.name(); + type_descriptor.extent = type_handle.extent(); + type_descriptor.num_members = type_handle.num_members(); + type_descriptor.flag = static_cast(type_handle.flags()); + + const auto member_count = type_descriptor.num_members; + type_descriptor.array_sizes.reserve(member_count); + type_descriptor.offsets.reserve(member_count); + type_descriptor.member_types.reserve(member_count); + + for (size_t i = 0; i < member_count; ++i) { + const auto member_id = register_t(type_handle.get_member_type(i)); + const auto array_size = type_handle.get_array_size(i); + const auto offset = type_handle.get_offset(i); + type_descriptor.array_sizes.emplace_back(array_size); type_descriptor.offsets.emplace_back(offset); type_descriptor.member_types.emplace_back(member_id); @@ -91,14 +194,15 @@ class GlobalTypeTranslator::Impl { LOG_DEBUG(" Extent: " << type_descriptor.extent); LOG_DEBUG(" Num Members: " << type_descriptor.num_members); LOG_DEBUG(" Flag: " << static_cast(type_descriptor.flag)); - for (uint32_t i = 0; i < type->num_members; ++i) { + for (uint32_t i = 0; i < type_descriptor.num_members; ++i) { LOG_DEBUG(" Member[" << i << "]: " << "ID=" << type_db_.getTypeName(type_descriptor.member_types[i]) << ", Offset=" << type_descriptor.offsets[i] << ", ArraySize=" << type_descriptor.array_sizes[i]); } } + type_db_.registerStruct(type_descriptor, not fwd_decl); - translator_map_.try_emplace(type, type_descriptor.type_id); + translator_map_.try_emplace(type_handle.handle(), type_descriptor.type_id); return type_descriptor.type_id; } @@ -110,9 +214,8 @@ GlobalTypeTranslator::GlobalTypeTranslator(TypeDatabase& db) : pImpl(std::make_u GlobalTypeTranslator::~GlobalTypeTranslator() = default; void GlobalTypeTranslator::register_type(const void* type) { - const auto* info_struct = reinterpret_cast(type); - const auto type_id = pImpl->register_t(info_struct); - LOG_DEBUG("Type id reset: " << info_struct->name << " " << info_struct->type_id << " vs. " << type_id) + const auto* info_struct = reinterpret_cast(type); + const auto type_id = pImpl->register_t(TypeInfoHandle{info_struct}); const_cast(info_struct)->type_id = type_id; } diff --git a/lib/runtime/RuntimeData.h b/lib/runtime/RuntimeData.h index 6253655e..e62ef524 100644 --- a/lib/runtime/RuntimeData.h +++ b/lib/runtime/RuntimeData.h @@ -70,17 +70,14 @@ struct PointerInfo final { MemAddr debug{nullptr}; }; +namespace global_types { +struct GlobalTypeInfoData; struct GlobalTypeInfo { std::int32_t type_id; const std::uint32_t extent; - const std::uint16_t num_members; - const std::uint16_t flag; - - const char* name; - const std::uint16_t* offsets; - const std::uint16_t* array_sizes; - const GlobalTypeInfo** member_types; + const GlobalTypeInfoData* data; }; +} // namespace global_types struct RuntimeT { using Stack = std::vector; diff --git a/test/pass/inline_types/01_simple_malloc_int.c b/test/pass/inline_types/01_simple_malloc_int.c index 69c16ab5..9bc4ce2f 100644 --- a/test/pass/inline_types/01_simple_malloc_int.c +++ b/test/pass/inline_types/01_simple_malloc_int.c @@ -5,7 +5,7 @@ // RUN: %c-to-llvm %s | %apply-typeart -typeart-type-serialization=file -S 2>&1 | %filecheck %s --check-prefix FILE -// REQUIRES: llvm-18 || llvm-19 +// REQUIRES: !llvm-14 // clang-format on #include @@ -17,7 +17,7 @@ void test() { // CHECK-NEXT: Free{{[ ]*}}:{{[ ]*}}0 // CHECK-NEXT: Alloca{{[ ]*}}:{{[ ]*}}0 -// CHECK: %struct._typeart_struct_layout_t = type { i32, i32, i16, i16, ptr, ptr, ptr, ptr } +// CHECK: %struct._typeart_struct_layout_t = type { i32, i32, ptr } // CHECK: [[POINTER:%[0-9a-z]+]] = call noalias{{( align [0-9]+)?}} ptr @malloc // CHECK-NEXT: call void @__typeart_alloc_mty(ptr [[POINTER]], ptr {{.*}}, i64 42) diff --git a/test/pass/inline_types/05_malloc_struct_nested.c b/test/pass/inline_types/05_malloc_struct_nested.c index 36f880c5..2a2855ff 100644 --- a/test/pass/inline_types/05_malloc_struct_nested.c +++ b/test/pass/inline_types/05_malloc_struct_nested.c @@ -23,6 +23,6 @@ int main(void) { // clang-format off // CHECK-DAG: @_typeart_member_types_DataNested = private constant [1 x ptr] [ptr @_typeart_ptr], comdat($_typeart_DataNested) -// CHECK-DAG: @_typeart_DataHolder = linkonce_odr global %struct._typeart_struct_layout_t { i32 256, i32 24, i16 4, i16 1, ptr @_typeart_typename_DataHolder, ptr @_typeart_offsets_DataHolder, ptr @_typeart_counts_DataHolder, ptr @_typeart_member_types_DataHolder }, comdat +// CHECK-DAG: @_typeart_DataHolder = linkonce_odr global %struct._typeart_struct_layout_t { i32 256, i32 24, ptr @_typeart_DataHolder_info }, comdat // CHECK-DAG: @_typeart_member_types_DataHolder = private constant [4 x ptr] [ptr @_typeart_double, ptr @_typeart_float, ptr @_typeart_int, ptr @_typeart_DataNested], comdat($_typeart_DataHolder) // CHECK-DAG: @_typeart_typename_DataHolder = private unnamed_addr constant [11 x i8] c"DataHolder\00", comdat($_typeart_DataHolder), align 1 diff --git a/test/pass/new_delete/19_array_cookie_dynamic_size_opaque.cpp b/test/pass/new_delete/19_array_cookie_dynamic_size_opaque.cpp index 48ede9f1..ca82eaf8 100644 --- a/test/pass/new_delete/19_array_cookie_dynamic_size_opaque.cpp +++ b/test/pass/new_delete/19_array_cookie_dynamic_size_opaque.cpp @@ -1,6 +1,6 @@ // clang-format off // RUN: %cpp-to-llvm %s | %apply-typeart --typeart-type-serialization=file -S 2>&1 | %filecheck %s -// REQUIRES: llvm-18 || llvm-19 +// REQUIRES: !llvm-14 // clang-format on // CHECK: TypeArtPass [Heap] diff --git a/test/pass/new_delete/20_no_array_cookie_lulesh_ad.llin b/test/pass/new_delete/20_no_array_cookie_lulesh_ad.llin index 43d30f97..8497e07c 100644 --- a/test/pass/new_delete/20_no_array_cookie_lulesh_ad.llin +++ b/test/pass/new_delete/20_no_array_cookie_lulesh_ad.llin @@ -1,5 +1,5 @@ ; RUN: %apply-typeart --typeart-type-serialization=file -S < %s | %filecheck %s -; REQUIRES: llvm-18 || llvm-19 +; REQUIRES: !llvm-14 ; llvm-reduce on lulesh.cc with culprit chunk.hpp:allocateData() where pattern is similar to array cookie.