diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-05-13 20:57:30 +0200 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-09-08 08:57:59 +0200 |
commit | 2ee19712d27247fdeb1a596176f2e729ebf0700e (patch) | |
tree | 067b6f2f1c858e8d6b5e5b96b77331b21e06e355 | |
parent | 995088af14f31903189463bd4e26953c138bcc3e (diff) |
working on escape analysis
-rw-r--r-- | gcc/Makefile.in | 1 | ||||
-rw-r--r-- | gcc/compare-types.c | 1 | ||||
-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; |