summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-04-16 11:41:33 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-04-28 23:35:52 +0200
commitf9e344f641cf61514e552b2b1d8f896c6e3d44c5 (patch)
tree2924ba0eb590caedd6bb59575aa3bdc7a3aa7744
parent560a513b546bca3b6299ac5c7c41df99b06cbbd6 (diff)
Looks at GIMPLE_CALL for field accesses
-rw-r--r--gcc/ipa-hello-world.c90
-rw-r--r--gcc/ipa-hello-world.h17
-rw-r--r--gcc/ipa-str-reorg-dead-field-eliminate.c22
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;