diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-04-16 11:41:33 +0200 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-04-28 23:35:52 +0200 |
commit | f9e344f641cf61514e552b2b1d8f896c6e3d44c5 (patch) | |
tree | 2924ba0eb590caedd6bb59575aa3bdc7a3aa7744 | |
parent | 560a513b546bca3b6299ac5c7c41df99b06cbbd6 (diff) |
Looks at GIMPLE_CALL for field accesses
-rw-r--r-- | gcc/ipa-hello-world.c | 90 | ||||
-rw-r--r-- | gcc/ipa-hello-world.h | 17 | ||||
-rw-r--r-- | gcc/ipa-str-reorg-dead-field-eliminate.c | 22 |
3 files changed, 114 insertions, 15 deletions
diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-hello-world.c index bc993400050..3d438cf00ee 100644 --- a/gcc/ipa-hello-world.c +++ b/gcc/ipa-hello-world.c @@ -31,6 +31,7 @@ #include "ipa-type-escape-analysis.h" #include "ipa-str-reorg-utils.h" +#include "ipa-hello-world.h" //TODO: place in header file @@ -44,7 +45,6 @@ print_function (cgraph_node *cnode) dump_function_to_file (cnode->decl, dump_file, TDF_NONE); } -typedef std::pair<const_tree /* record */, const_tree /* field */> fields; //TODO: do not use pair. //This names are unintelligible typedef std::pair<unsigned /* reads */, unsigned /* writes */> accesses; @@ -104,7 +104,6 @@ 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 }; @@ -166,6 +165,25 @@ count_access_for_type_in_component_ref(const_tree component_ref, const record_se } } +static inline void +is_addr_expr_p(const_tree expr) +{ + gcc_assert(expr); + const enum tree_code code = TREE_CODE(expr); + const bool is_addr_expr = ADDR_EXPR == code; + gcc_assert(is_addr_expr); +} + +void count_access_for_types_in_expr(const_tree expr, const record_set &non_escaping_records, field_access_counter &counter, const enum access_code access); + +void +count_access_for_type_in_addr_expr(const_tree expr, const record_set &non_escaping_records, field_access_counter &counter, const enum access_code access) +{ + is_addr_expr_p(expr); + const_tree op0 = TREE_OPERAND(expr, 0); + count_access_for_types_in_expr(op0, non_escaping_records, counter, access); +} + void count_access_for_types_in_expr(const_tree expr, const record_set &non_escaping_records, field_access_counter &counter, const enum access_code access) { @@ -174,6 +192,7 @@ count_access_for_types_in_expr(const_tree expr, const record_set &non_escaping_r switch (tree_code_expr) { case COMPONENT_REF: count_access_for_type_in_component_ref(expr, non_escaping_records, counter, access); break; + case ADDR_EXPR: count_access_for_type_in_addr_expr(expr, non_escaping_records, counter, access); break; default: break; } } @@ -184,12 +203,18 @@ count_access_for_types_in_lhs(gimple *stmt, const record_set &non_escaping_recor gcc_assert(stmt); const enum gimple_code gimple_code_stmt = gimple_code(stmt); const bool is_assign = GIMPLE_ASSIGN == gimple_code_stmt; - gcc_assert(is_assign); + const bool is_call = GIMPLE_CALL == gimple_code_stmt; + const bool is_valid = is_assign || is_call; + gcc_assert(is_valid); + + + const_tree lhs = is_assign ? gimple_assign_lhs (stmt) : gimple_call_lhs (stmt); + /* GIMPLE_CALL might have a lhs null. + * E.g. + * foo() + */ + if (!lhs) return; - const_tree lhs = gimple_assign_lhs (stmt); - //FIXME: I think if we do not access from GIMPLE_ASSIGN - //this is no longer an invariant... - gcc_assert(lhs); count_access_for_types_in_expr(lhs, non_escaping_records, counter, WRITE_ACCESS); } @@ -229,18 +254,58 @@ count_access_for_types_in_rhs(gimple *stmt, const record_set &non_escaping_recor } } -void -count_access_for_types_in_assign(gimple *stmt, const record_set &non_escaping_records, field_access_counter &counter) +inline static void +is_gimple_assign_p(gimple *stmt) { gcc_assert(stmt); - const enum gimple_code gimple_code_stmt = gimple_code(stmt); - const bool is_assign = GIMPLE_ASSIGN == gimple_code_stmt; + const enum gimple_code code = gimple_code(stmt); + const bool is_assign = GIMPLE_ASSIGN == code; gcc_assert(is_assign); +} + +inline static void +is_gimple_call_p(gimple *stmt) +{ + gcc_assert(stmt); + const enum gimple_code code = gimple_code(stmt); + const bool is_call = GIMPLE_CALL == code; + gcc_assert(is_call); + +} + +void +count_access_for_types_in_assign(gimple *stmt, const record_set &non_escaping_records, field_access_counter &counter) +{ + is_gimple_assign_p(stmt); count_access_for_types_in_rhs(stmt, non_escaping_records, counter); count_access_for_types_in_lhs(stmt, non_escaping_records, counter); } +static void +count_access_for_types_in_call_rhs(gimple *stmt, const record_set &non_escaping_records, field_access_counter &counter) +{ + is_gimple_call_p(stmt); + + unsigned args = gimple_call_num_args (stmt); + for (unsigned i = 0; i < args; i++) + { + const_tree arg = gimple_call_arg (stmt, i); + count_access_for_types_in_expr(arg, non_escaping_records, counter, READ_ACCESS); + } + +} + +void +count_access_for_types_in_call(gimple *stmt, const record_set &non_escaping_records, field_access_counter &counter) +{ + is_gimple_call_p(stmt); + count_access_for_types_in_lhs(stmt, non_escaping_records, counter); + + /* TODO: We need to iterate over each argument and find out if it is a read */ + count_access_for_types_in_call_rhs(stmt, non_escaping_records, counter); +} + void count_access_for_types_in_stmt(gimple *stmt, const record_set &non_escaping_records, field_access_counter &counter) { @@ -251,6 +316,9 @@ count_access_for_types_in_stmt(gimple *stmt, const record_set &non_escaping_reco case GIMPLE_ASSIGN: count_access_for_types_in_assign(stmt, non_escaping_records, counter); break; + case GIMPLE_CALL: + count_access_for_types_in_call(stmt, non_escaping_records, counter); + break; default: break; } diff --git a/gcc/ipa-hello-world.h b/gcc/ipa-hello-world.h new file mode 100644 index 00000000000..7a06d2223b3 --- /dev/null +++ b/gcc/ipa-hello-world.h @@ -0,0 +1,17 @@ +#ifndef GCC_IPA_HELLO_WORLD_H +#define GCC_IPA_HELLO_WORLD_H +#pragma once + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tree.h" + +#include <set> + +//TODO: do not use pair. +//This names are unintelligible +typedef std::pair<const_tree /* record */, const_tree /* field */> fields; +typedef std::set<fields> record_field_set; + +#endif diff --git a/gcc/ipa-str-reorg-dead-field-eliminate.c b/gcc/ipa-str-reorg-dead-field-eliminate.c index f110b4e7585..76a498541a9 100644 --- a/gcc/ipa-str-reorg-dead-field-eliminate.c +++ b/gcc/ipa-str-reorg-dead-field-eliminate.c @@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see #include "ipa-structure-reorg.h" #include "ipa-utils.h" #include "ipa-str-reorg-utils.h" +#include "ipa-hello-world.h" #define test_write(M, ...) \ if (dump_file) \ @@ -572,14 +573,27 @@ get_field_with_name (const_tree record, const char *identifier) static bool filter_out_boring_type (const_tree type, hash_set<const_tree> &map); +inline static void +is_record_p(const_tree record) +{ + gcc_assert(record); + const enum tree_code code = TREE_CODE(record); + const bool is_record = RECORD_TYPE == code; + gcc_assert(is_record); +} + +static bool +is_interesting_record_field_pair (fields &f, record_field_set &set) +{ +} + static bool is_interesting_struct (const_tree record_1) { - gcc_assert(record_1); - gcc_assert( TREE_CODE(record_1) == RECORD_TYPE); + is_record_p(record_1); + const_tree record = TYPE_MAIN_VARIANT(record_1); - enum tree_code code = TREE_CODE (record); - gcc_assert (code == RECORD_TYPE); + is_record_p(record); const char *record_name = get_type_name (record); const int buffer_size = 1024; |