From 2abac5ea1e40c685090bb3052a00f76724964f8c Mon Sep 17 00:00:00 2001 From: York Jasper Niebuhr Date: Sun, 5 Apr 2026 12:04:33 +0200 Subject: [PATCH] Improved array dpin construction --- pinpoint/stage0/on_finish_decl.cpp | 130 ++++++++++++++++++++--------- 1 file changed, 90 insertions(+), 40 deletions(-) diff --git a/pinpoint/stage0/on_finish_decl.cpp b/pinpoint/stage0/on_finish_decl.cpp index 3e26921..754454d 100644 --- a/pinpoint/stage0/on_finish_decl.cpp +++ b/pinpoint/stage0/on_finish_decl.cpp @@ -22,53 +22,45 @@ static std::string make_dpin_symbol() { std::to_string(next_dpin_uid++); } -static bool compile_datapin(tree type, DataPin& pin, std::size_t offset = 0, std::size_t level = 0) { - bool res = false; +static std::list compile_datapin_record_components(tree type); +static std::list compile_datapin_array_components(tree type); + +static std::list compile_datapin_components(tree type) { + std::list components; const TargetType* relevant = TargetType::find(type); if (relevant) { - pin.components.push_back(DataPin::Component{ - .offset = offset, - .level = level, + components.push_back(DataPin::Component{ + .offset = 0, + .level = 0, .target = relevant->uid() }); - - res = true; } - if (TREE_CODE(type) == ARRAY_TYPE) { - tree elem_type = TREE_TYPE(type); - tree domain = TYPE_DOMAIN(type); - if (!elem_type || !domain) - return res; + std::list sub_components; + if (TREE_CODE(type) == RECORD_TYPE) { + sub_components = compile_datapin_record_components(type); + } else if (TREE_CODE(type) == ARRAY_TYPE) { + sub_components = compile_datapin_array_components(type); + } - tree min_t = TYPE_MIN_VALUE(domain); - tree max_t = TYPE_MAX_VALUE(domain); - if (!min_t || !max_t || - TREE_CODE(min_t) != INTEGER_CST || - TREE_CODE(max_t) != INTEGER_CST) - return res; - - HOST_WIDE_INT min_i = tree_to_shwi(min_t); - HOST_WIDE_INT max_i = tree_to_shwi(max_t); - std::size_t elem_size = tree_to_uhwi(TYPE_SIZE_UNIT(elem_type)); - - for (HOST_WIDE_INT i = min_i; i <= max_i; ++i) { - bool sub_res = compile_datapin( - elem_type, - pin, - offset + (std::size_t)(i - min_i) * elem_size, - level + 1 - ); - res = res || sub_res; - } - - return res; + for (const DataPin::Component& sc : sub_components) { + components.push_back(DataPin::Component{ + .offset = sc.offset, + .level = sc.level + 1, + .target = sc.target + }); } // Note -> should probably make sure that randomized structs are never used in unions! - if (TREE_CODE(type) != RECORD_TYPE /* && TREE_CODE(type) != UNION_TYPE */) - return res; + return components; +} + +std::list compile_datapin_record_components(tree type) { + std::list components; + + if (TREE_CODE(type) != RECORD_TYPE) + return components; for (tree field = TYPE_FIELDS(type); field; field = TREE_CHAIN(field)) { if (TREE_CODE(field) != FIELD_DECL) @@ -78,18 +70,76 @@ static bool compile_datapin(tree type, DataPin& pin, std::size_t offset = 0, std bool field_bitfield; if (!field_info(field, &field_offset, nullptr, nullptr, &field_bitfield)) - pinpoint_fatal("compile_datapin failed to get field info"); + pinpoint_fatal("compile_datapin_record_components failed to get field info"); if (field_bitfield) continue; tree field_type = TREE_TYPE(field); - bool sub_res = compile_datapin(field_type, pin, offset + field_offset, level + 1); - res = (res || sub_res); + std::list field_components = compile_datapin_components(field_type); + for (const DataPin::Component& fc : field_components) { + components.push_back(DataPin::Component{ + .offset = field_offset + fc.offset, + .level = fc.level, + .target = fc.target + }); + } } - return res; + return components; +} + +std::list compile_datapin_array_components(tree type) { + std::list components; + + if (TREE_CODE(type) != ARRAY_TYPE) + return components; + + tree elem_type = TREE_TYPE(type); + if (!elem_type) + return components; + + std::list elem_components = compile_datapin_components(elem_type); + if (elem_components.empty()) + return components; + + tree domain = TYPE_DOMAIN(type); + if (!domain) + pinpoint_fatal("compile_datapin_array_components failed to get domain for relevant element type"); + + tree min_t = TYPE_MIN_VALUE(domain); + tree max_t = TYPE_MAX_VALUE(domain); + if (!min_t || !max_t || TREE_CODE(min_t) != INTEGER_CST || TREE_CODE(max_t) != INTEGER_CST) + pinpoint_fatal("compile_datapin_array_components failed to get array dimensions for relevant element type"); + + HOST_WIDE_INT min_i = tree_to_shwi(min_t); + HOST_WIDE_INT max_i = tree_to_shwi(max_t); + + tree elem_size_t = TYPE_SIZE_UNIT(elem_type); + if (!elem_size_t || TREE_CODE(elem_size_t) != INTEGER_CST) + pinpoint_fatal("compile_datapin_array_components failed to get constant element size for relevant element type"); + + std::size_t elem_size = tree_to_uhwi(elem_size_t); + + for (HOST_WIDE_INT i = min_i; i <= max_i; ++i) { + std::size_t element_offset = (std::size_t)(i - min_i) * elem_size; + + for (const DataPin::Component& ec : elem_components) { + components.push_back(DataPin::Component{ + .offset = element_offset + ec.offset, + .level = ec.level, + .target = ec.target + }); + } + } + + return components; +} + +static bool compile_datapin(tree type, DataPin& pin) { + pin.components = compile_datapin_components(type); + return !pin.components.empty(); } static void on_static_var(tree var) {