summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-05-13 20:57:30 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-09-08 08:57:59 +0200
commit2ee19712d27247fdeb1a596176f2e729ebf0700e (patch)
tree067b6f2f1c858e8d6b5e5b96b77331b21e06e355
parent995088af14f31903189463bd4e26953c138bcc3e (diff)
working on escape analysis
-rw-r--r--gcc/Makefile.in1
-rw-r--r--gcc/compare-types.c1
-rw-r--r--gcc/ipa-escape-analysis.c (renamed from gcc/ipa-hello-world.c)236
3 files changed, 236 insertions, 2 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 589c35cb0f7..7bb373a8451 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1410,6 +1410,7 @@ OBJS = \
internal-fn.o \
ipa-type-escape-analysis.o \
ipa-hello-world.o \
+ ipa-escape-analysis.o \
compare-types.o \
collect-types.o \
name-types.o \
diff --git a/gcc/compare-types.c b/gcc/compare-types.c
index e8a2611eca0..cc81577fc9b 100644
--- a/gcc/compare-types.c
+++ b/gcc/compare-types.c
@@ -57,7 +57,6 @@ eq_canonical_internal(const_tree a, const_tree b)
gcc_assert(a && b);
const_tree canonical_a = TYPE_CANONICAL(a);
const_tree canonical_b = TYPE_CANONICAL(b);
- gcc_assert(canonical_a && canonical_b);
const bool are_equal = canonical_a == canonical_b;
return are_equal;
}
diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-escape-analysis.c
index 678faed9f1f..b9119009042 100644
--- a/gcc/ipa-hello-world.c
+++ b/gcc/ipa-escape-analysis.c
@@ -68,7 +68,205 @@ static type_comparison_func_t comparisons[type_comparisons] = {
eq_type_compare
};
}
+static void collect_types_from_expr(const_tree expr, typeset &types);
+inline void
+is_gimple_code(gimple *stmt, const enum gimple_code ex_code)
+{
+ gcc_assert(stmt);
+ const enum gimple_code ob_code = gimple_code(stmt);
+ const bool succeeds = ex_code == ob_code;
+ gcc_assert(succeeds);
+}
+
+inline void
+is_gimple_rhs_class(gimple *stmt, const enum gimple_rhs_class ex_class)
+{
+ gcc_assert(stmt);
+ is_gimple_code(stmt, GIMPLE_ASSIGN);
+ const enum gimple_rhs_class ob_class = gimple_assign_rhs_class(stmt);
+ const bool succeeds = ex_class == ob_class;
+ gcc_assert(succeeds);
+}
+
+static void
+collect_types_from_ssa_name(const_tree expr, typeset &types)
+{
+ assert_is_type(expr, SSA_NAME);
+ const_tree type = TREE_TYPE(expr);
+ gcc_assert(type);
+ collect_types(type, types);
+}
+
+static void
+collect_types_from_component_ref(const_tree expr, typeset &types)
+{
+ assert_is_type(expr, COMPONENT_REF);
+ const_tree _struct = TREE_OPERAND(expr, 0);
+ collect_types_from_expr(_struct, types);
+ gcc_assert(_struct);
+ const_tree _field = TREE_OPERAND(expr, 1);
+ gcc_assert(_field);
+ collect_types_from_expr(_field, types);
+}
+
+static void
+collect_types_from_var_decl(const_tree expr, typeset &types)
+{
+ assert_is_type(expr, VAR_DECL);
+ const_tree type = TREE_TYPE(expr);
+ gcc_assert(type);
+ collect_types(type, types);
+}
+
+static void
+collect_types_from_field_decl(const_tree expr, typeset &types)
+{
+}
+
+static void
+collect_types_from_expr(const_tree expr, typeset &types)
+{
+ // We are interested in collecting all types which
+ // point to a RECORD_TYPE.
+ // Therefore, it is not necessary to consider unfeasible paths.
+ gcc_assert(expr);
+ const enum tree_code code = TREE_CODE(expr);
+ switch (code)
+ {
+ case COMPONENT_REF:
+ collect_types_from_component_ref(expr, types);
+ break;
+ case SSA_NAME:
+ collect_types_from_ssa_name(expr, types);
+ break;
+ case VAR_DECL:
+ collect_types_from_var_decl(expr, types);
+ break;
+ case FIELD_DECL:
+ collect_types_from_field_decl(expr, types);
+ break;
+ break;
+ default:
+ log("tree_code: %s\n", get_tree_code_name(code));
+ break;
+ }
+}
+
+static void
+collect_types_from_stmt_assign_lhs(gimple *stmt, typeset &types)
+{
+ is_gimple_code(stmt, GIMPLE_ASSIGN);
+ const_tree lhs = gimple_assign_lhs(stmt);
+ gcc_assert(lhs);
+ collect_types_from_expr(lhs, types);
+}
+
+static void
+collect_types_from_stmt_assign_rhs3(gimple *stmt, typeset &types)
+{
+ is_gimple_rhs_class(stmt, GIMPLE_TERNARY_RHS);
+ const_tree rhs = gimple_assign_rhs3(stmt);
+ gcc_assert(rhs);
+ collect_types_from_expr(rhs, types);
+}
+
+static void
+collect_types_from_stmt_assign_rhs2(gimple *stmt, typeset &types)
+{
+ is_gimple_code(stmt, GIMPLE_ASSIGN);
+ const enum gimple_rhs_class gclass = gimple_assign_rhs_class(stmt);
+ const bool is_ternary = GIMPLE_TERNARY_RHS == gclass;
+ const bool is_binary = GIMPLE_BINARY_RHS == gclass;
+ const bool is_valid_input = is_ternary || is_binary;
+ gcc_assert(is_valid_input);
+ const_tree rhs = gimple_assign_rhs2(stmt);
+ gcc_assert(rhs);
+ collect_types_from_expr(rhs, types);
+}
+
+static void
+collect_types_from_stmt_assign_rhs1(gimple *stmt, typeset &types)
+{
+ is_gimple_code(stmt, GIMPLE_ASSIGN);
+ const enum gimple_rhs_class gclass = gimple_assign_rhs_class(stmt);
+ const bool is_ternary = GIMPLE_TERNARY_RHS == gclass;
+ const bool is_binary = GIMPLE_BINARY_RHS == gclass;
+ const bool is_unary = GIMPLE_UNARY_RHS == gclass;
+ const bool is_single = GIMPLE_SINGLE_RHS == gclass;
+ const bool is_valid_input = is_ternary || is_binary || is_unary || is_single;
+ gcc_assert(is_valid_input);
+ const_tree rhs = gimple_assign_rhs1(stmt);
+ gcc_assert(rhs);
+ collect_types_from_expr(rhs, types);
+}
+
+static void
+collect_types_from_stmt_assign_rhs(gimple *stmt, typeset &types)
+{
+ is_gimple_code(stmt, GIMPLE_ASSIGN);
+ const enum gimple_rhs_class gclass = gimple_assign_rhs_class(stmt);
+ switch (gclass)
+ {
+ case GIMPLE_TERNARY_RHS:
+ collect_types_from_stmt_assign_rhs3(stmt, types);
+ /* fall-through */
+ case GIMPLE_BINARY_RHS:
+ collect_types_from_stmt_assign_rhs2(stmt, types);
+ /* fall-through */
+ case GIMPLE_UNARY_RHS:
+ case GIMPLE_SINGLE_RHS:
+ collect_types_from_stmt_assign_rhs1(stmt, types);
+ break;
+ default:
+ gcc_unreachable();
+ break;
+ }
+}
+
+static void
+collect_types_from_stmt_assign(gimple *stmt, typeset &types)
+{
+ is_gimple_code(stmt, GIMPLE_ASSIGN);
+ collect_types_from_stmt_assign_lhs(stmt, types);
+ collect_types_from_stmt_assign_rhs(stmt, types);
+}
+
+static void
+collect_types_from_stmt_call(gimple *stmt, typeset &types)
+{
+ is_gimple_code(stmt, GIMPLE_CALL);
+ //TODO:
+}
+
+static void
+collect_types_from_stmt_cond(gimple *stmt, typeset &types)
+{
+ is_gimple_code(stmt, GIMPLE_COND);
+ //TODO:
+}
+
+static void
+collect_types_from_stmt(gimple *stmt, typeset &types)
+{
+ gcc_assert(stmt);
+ const enum gimple_code code = gimple_code(stmt);
+ switch (code)
+ {
+ case GIMPLE_ASSIGN:
+ collect_types_from_stmt_assign(stmt, types);
+ break;
+ case GIMPLE_CALL:
+ collect_types_from_stmt_call(stmt, types);
+ break;
+ case GIMPLE_COND:
+ collect_types_from_stmt_cond(stmt, types);
+ break;
+ default:
+ //TODO:
+ break;
+ }
+}
static void
collect_types_from_cnode_decl(cgraph_node *cnode, typeset &types)
@@ -125,12 +323,44 @@ collect_types_from_cnode_ssa_names(cgraph_node *cnode, typeset &types)
}
static void
+collect_types_from_bb(basic_block bb, typeset &types)
+{
+ gcc_assert(bb);
+ for (auto gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi))
+ {
+ gimple *stmt = gsi_stmt(gsi);
+ gcc_assert(stmt);
+ collect_types_from_stmt(stmt, types);
+ }
+}
+
+static void
+collect_types_from_cnode_bb(cgraph_node *cnode, typeset &types)
+{
+ gcc_assert(cnode);
+ cnode->get_untransformed_body();
+ tree decl = cnode->decl;
+ gcc_assert(decl);
+ function *func = DECL_STRUCT_FUNCTION(decl);
+ gcc_assert(func);
+ basic_block bb = NULL;
+ push_cfun(func);
+ FOR_EACH_BB_FN(bb, func)
+ {
+ gcc_assert(bb);
+ collect_types_from_bb(bb, types);
+ }
+ pop_cfun();
+}
+
+static void
collect_types_from_functions_with_gimple_body(cgraph_node *cnode, typeset &types)
{
gcc_assert(cnode);
collect_types_from_cnode_decl(cnode, types);
collect_types_from_cnode_locals(cnode, types);
- //collect_types_from_cnode_ssa_names(cnode, types);
+ collect_types_from_cnode_ssa_names(cnode, types);
+ collect_types_from_cnode_bb(cnode, types);
}
static void
@@ -253,12 +483,16 @@ iphw_execute()
//test_naming_types::run_tests();
cgraph_node *node = NULL;
typeset types;
+
FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node)
{
node->get_untransformed_body();
collect_types_from_functions_with_gimple_body(node, types);
}
+ // We still need to collect types from
+ // the function signatures of functions without gimple bodies...
+
filter_out_types_in_set(types);
compare_types_in_set(types);
return 0;