summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-03-12 12:04:57 +0100
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-04-28 23:35:52 +0200
commit1e4fc358def3efb824b4148a0456865903c88ad4 (patch)
tree7299a455d825f842c94b00e464bcbc9266aace72
parent07d0e6f31c1509829a28bae1d611518e89003b2c (diff)
Determines which fields can be deleted
-rw-r--r--gcc/ipa-hello-world.c75
1 files changed, 72 insertions, 3 deletions
diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-hello-world.c
index 6d911082b58..30b260e7934 100644
--- a/gcc/ipa-hello-world.c
+++ b/gcc/ipa-hello-world.c
@@ -61,7 +61,6 @@ struct field_comparator
const enum tree_code tree_code_right_record = TREE_CODE(right_record);
const bool is_left_record_type = RECORD_TYPE == tree_code_left_record;
const bool is_right_record_type = RECORD_TYPE == tree_code_right_record;
- log("left type is weird %s\n", get_type_name(left_record));
gcc_assert(is_left_record_type);
gcc_assert(is_right_record_type);
const bool are_left_and_right_valid = is_left_record_type && is_right_record_type;
@@ -105,6 +104,8 @@ struct field_comparator
typedef std::map<fields, accesses, field_comparator> field_access_counter;
typedef std::set<const_tree> record_set;
+typedef std::set<fields> record_field_set;
+
enum access_code { READ_ACCESS, WRITE_ACCESS };
void
@@ -284,6 +285,26 @@ count_access_for_types_in_function(cgraph_node *cnode, const record_set &non_esc
pop_cfun();
}
+void
+init_field_access_counter(field_access_counter &counter, const record_set &non_escaping_records)
+{
+ for (auto it = non_escaping_records.cbegin(); it != non_escaping_records.cend(); ++it)
+ {
+ const_tree record = *it;
+ gcc_assert(record);
+ enum tree_code tree_code_record_type = TREE_CODE(record);
+ const bool is_record_type = RECORD_TYPE == tree_code_record_type;
+ gcc_assert(is_record_type);
+
+ for (tree field = TYPE_FIELDS (record); field; field = DECL_CHAIN (field))
+ {
+ gcc_assert(field);
+ const std::pair<const_tree, const_tree> struct_field_pair = std::make_pair(record, field);
+ counter[struct_field_pair] = { 0, 0 };
+ }
+ }
+}
+
/* INFO:
* Yes, I know we are returning a std::map.
* Bad pattern? Maybe, but this will only be called once
@@ -299,6 +320,7 @@ field_access_counter
count_access_for_types_in_linking_unit(const record_set &non_escaping_records)
{
field_access_counter counter;
+ init_field_access_counter(counter, non_escaping_records);
cgraph_node *cnode = NULL;
FOR_EACH_DEFINED_FUNCTION(cnode)
{
@@ -338,13 +360,60 @@ calculate_non_escaping_records(type_map &escaping_type_info)
return non_escaping_records;
}
-static unsigned int
-iphw_execute()
+static field_access_counter
+count_field_accesses()
{
+
type_map escaping_types;
calculate_escaping_types(escaping_types);
const record_set non_escaping_records = calculate_non_escaping_records(escaping_types);
field_access_counter counter = count_access_for_types_in_linking_unit(non_escaping_records);
+ return counter;
+}
+
+static record_field_set
+get_fields_to_reorg()
+{
+ const field_access_counter counter = count_field_accesses();
+ record_field_set records_and_fields_to_reorg;
+ for (auto it = counter.cbegin(); it != counter.cend(); ++it)
+ {
+ fields record_field_pair = it->first;
+ accesses counter = it->second;
+ const_tree record = record_field_pair.first;
+ const_tree field = record_field_pair.second;
+ // We are interested in reads == 0;
+ unsigned reads = counter.first;
+ log("final count for %s.%s = %d\n", get_type_name(record), get_field_name(field), reads);
+ if (0 != reads) continue;
+
+ records_and_fields_to_reorg.insert(record_field_pair);
+ }
+
+ return records_and_fields_to_reorg;
+}
+
+static void
+print_record_field_set(const record_field_set &to_reorg)
+{
+ log("I am about to print\n");
+ for (auto it = to_reorg.cbegin(); it != to_reorg.cend(); ++it)
+ {
+ fields record_field_pair = *it;
+ const_tree record = record_field_pair.first;
+ const_tree field = record_field_pair.second;
+ // TODO: Some fields / records might be anonymous
+ log("will eliminate %s.%s\n", get_type_name(record), get_field_name(field));
+ }
+}
+
+
+static unsigned int
+iphw_execute()
+{
+ const record_field_set to_reorg = get_fields_to_reorg();
+ log("I am about to enter print function\n");
+ print_record_field_set(to_reorg);
return 0;
}