Improved array dpin construction
This commit is contained in:
parent
e7851641a1
commit
2abac5ea1e
@ -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) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user