Improved array dpin construction

This commit is contained in:
York Jasper Niebuhr 2026-04-05 12:04:33 +02:00
parent e7851641a1
commit 2abac5ea1e

View File

@ -22,53 +22,45 @@ static std::string make_dpin_symbol() {
std::to_string(next_dpin_uid++); std::to_string(next_dpin_uid++);
} }
static bool compile_datapin(tree type, DataPin& pin, std::size_t offset = 0, std::size_t level = 0) { static std::list<DataPin::Component> compile_datapin_record_components(tree type);
bool res = false; static std::list<DataPin::Component> compile_datapin_array_components(tree type);
static std::list<DataPin::Component> compile_datapin_components(tree type) {
std::list<DataPin::Component> components;
const TargetType* relevant = TargetType::find(type); const TargetType* relevant = TargetType::find(type);
if (relevant) { if (relevant) {
pin.components.push_back(DataPin::Component{ components.push_back(DataPin::Component{
.offset = offset, .offset = 0,
.level = level, .level = 0,
.target = relevant->uid() .target = relevant->uid()
}); });
res = true;
} }
if (TREE_CODE(type) == ARRAY_TYPE) { std::list<DataPin::Component> sub_components;
tree elem_type = TREE_TYPE(type); if (TREE_CODE(type) == RECORD_TYPE) {
tree domain = TYPE_DOMAIN(type); sub_components = compile_datapin_record_components(type);
if (!elem_type || !domain) } else if (TREE_CODE(type) == ARRAY_TYPE) {
return res; sub_components = compile_datapin_array_components(type);
}
tree min_t = TYPE_MIN_VALUE(domain); for (const DataPin::Component& sc : sub_components) {
tree max_t = TYPE_MAX_VALUE(domain); components.push_back(DataPin::Component{
if (!min_t || !max_t || .offset = sc.offset,
TREE_CODE(min_t) != INTEGER_CST || .level = sc.level + 1,
TREE_CODE(max_t) != INTEGER_CST) .target = sc.target
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;
} }
// Note -> should probably make sure that randomized structs are never used in unions! // 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 components;
return res; }
std::list<DataPin::Component> compile_datapin_record_components(tree type) {
std::list<DataPin::Component> components;
if (TREE_CODE(type) != RECORD_TYPE)
return components;
for (tree field = TYPE_FIELDS(type); field; field = TREE_CHAIN(field)) { for (tree field = TYPE_FIELDS(type); field; field = TREE_CHAIN(field)) {
if (TREE_CODE(field) != FIELD_DECL) 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; bool field_bitfield;
if (!field_info(field, &field_offset, nullptr, nullptr, &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) if (field_bitfield)
continue; continue;
tree field_type = TREE_TYPE(field); tree field_type = TREE_TYPE(field);
bool sub_res = compile_datapin(field_type, pin, offset + field_offset, level + 1); std::list<DataPin::Component> field_components = compile_datapin_components(field_type);
res = (res || sub_res); 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<DataPin::Component> compile_datapin_array_components(tree type) {
std::list<DataPin::Component> components;
if (TREE_CODE(type) != ARRAY_TYPE)
return components;
tree elem_type = TREE_TYPE(type);
if (!elem_type)
return components;
std::list<DataPin::Component> 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) { static void on_static_var(tree var) {