diff options
Diffstat (limited to 'gcc/ipa-hello-world.c')
-rw-r--r-- | gcc/ipa-hello-world.c | 75 |
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; } |