From a89b85cdcd75aa36836967894a99d24bbc37338a Mon Sep 17 00:00:00 2001 From: Erick Ochoa Date: Thu, 14 May 2020 16:00:00 +0200 Subject: Refactored code works in mcf --- gcc/ipa-escape-analysis.c | 32 ++- gcc/ipa-escape-analysis.h | 5 + gcc/ipa-str-reorg-dead-field-eliminate.c | 18 +- gcc/ipa-type-escape-analysis.c | 321 +++---------------------------- 4 files changed, 60 insertions(+), 316 deletions(-) create mode 100644 gcc/ipa-escape-analysis.h diff --git a/gcc/ipa-escape-analysis.c b/gcc/ipa-escape-analysis.c index 04023a406a5..6c4e9105254 100644 --- a/gcc/ipa-escape-analysis.c +++ b/gcc/ipa-escape-analysis.c @@ -36,6 +36,8 @@ #include "collect-types.h" #include "name-types.h" +#include "ipa-escape-analysis.h" + //#define FUZZ_MODE 1 namespace type_playground { @@ -289,6 +291,16 @@ collect_types_from_result_decl(const_tree expr, ptrset_t &types) collect_types_from_leaf_expr(expr, types, RESULT_DECL); } +static void +collect_types_from_function_decl(const_tree expr, ptrset_t &types) +{ + assert_is_type(expr, FUNCTION_DECL); + const_tree decl_type = TREE_TYPE(expr); + gcc_assert(decl_type); + // This will collect return, arguments and decl_type itself + collect_types(decl_type, types); +} + static void collect_types_from_expr(const_tree expr, ptrset_t &types) { @@ -345,6 +357,9 @@ collect_types_from_expr(const_tree expr, ptrset_t &types) case STRING_CST: collect_types_from_string_cst(expr, types); break; + case FUNCTION_DECL: + collect_types_from_function_decl(expr, types); + break; default: log("tree_code: %s\n", get_tree_code_name(code)); gcc_unreachable(); @@ -491,7 +506,8 @@ collect_types_from_stmt_return(gimple *stmt, ptrset_t &types) { is_gimple_code(stmt, GIMPLE_RETURN); const_tree retval = gimple_return_retval(stmt); - gcc_assert(retval); + if (!retval) return; + collect_types_from_expr(retval, types); } @@ -515,6 +531,8 @@ collect_types_from_stmt(gimple *stmt, ptrset_t &types) break; case GIMPLE_LABEL: case GIMPLE_PREDICT: + case GIMPLE_DEBUG: + case GIMPLE_SWITCH: #ifdef FUZZ_MODE gcc_unreachable(); #endif @@ -529,20 +547,14 @@ collect_types_from_stmt(gimple *stmt, ptrset_t &types) } } + static void collect_types_from_cnode_decl(cgraph_node *cnode, ptrset_t &types) { gcc_assert(cnode); const_tree decl = cnode->decl; gcc_assert(decl); - const_tree decl_type = TREE_TYPE(decl); - gcc_assert(decl_type); - function *func = DECL_STRUCT_FUNCTION (decl); - gcc_assert(func); - push_cfun(func); - // This will collect return, arguments and decl_type itself - collect_types(decl_type, types); - pop_cfun(); + collect_types_from_function_decl(decl, types); } static void @@ -760,7 +772,7 @@ filter_out_types_in_set(ptrset_t &types) } -static void +void collect_types(ptrset_t &types) { collect_types_from_globals(types); diff --git a/gcc/ipa-escape-analysis.h b/gcc/ipa-escape-analysis.h new file mode 100644 index 00000000000..16611c2db56 --- /dev/null +++ b/gcc/ipa-escape-analysis.h @@ -0,0 +1,5 @@ +#pragma once + +#include "collect-types.h" + +void collect_types(ptrset_t &types); diff --git a/gcc/ipa-str-reorg-dead-field-eliminate.c b/gcc/ipa-str-reorg-dead-field-eliminate.c index f86ed1f866a..a3d20f64283 100644 --- a/gcc/ipa-str-reorg-dead-field-eliminate.c +++ b/gcc/ipa-str-reorg-dead-field-eliminate.c @@ -2705,15 +2705,15 @@ iphw_execute_escape_analysis() gcc_assert(!flag_ipa_typelist_struct && !flag_ipa_typelist_field); const record_field_set to_reorg = get_fields_to_reorg(); print_record_field_set(to_reorg); - //separate_set_of_pairs_into_pair_of_sets(to_reorg, interesting_records, interesting_fields); - - //hash_set orig_type_map; - //collect_orig_structs (orig_type_map); - //t_map mod_type_map; - //compute_modified_structs (orig_type_map, mod_type_map); - //t_map inverse_type_map; - //compute_inverse_type_map (mod_type_map, inverse_type_map); - //rewrite_references_to_modified_structs (mod_type_map, inverse_type_map); + separate_set_of_pairs_into_pair_of_sets(to_reorg, interesting_records, interesting_fields); + + hash_set orig_type_map; + collect_orig_structs (orig_type_map); + t_map mod_type_map; + compute_modified_structs (orig_type_map, mod_type_map); + t_map inverse_type_map; + compute_inverse_type_map (mod_type_map, inverse_type_map); + rewrite_references_to_modified_structs (mod_type_map, inverse_type_map); } static void diff --git a/gcc/ipa-type-escape-analysis.c b/gcc/ipa-type-escape-analysis.c index f4db0b6183f..368644912ca 100644 --- a/gcc/ipa-type-escape-analysis.c +++ b/gcc/ipa-type-escape-analysis.c @@ -31,6 +31,7 @@ #include "ipa-str-reorg-utils.h" #include "ipa-type-escape-analysis.h" +#include "ipa-escape-analysis.h" // First we need to collect all types @@ -242,42 +243,6 @@ filter_parm_declarations (const_tree parm_decl, type_map &escape_map) return filter_type(escape_map, type); } -static void -collect_global(type_map &escape_map, varpool_node *vnode) -{ - log("collect_global\n"); - gcc_assert(vnode); - - struct ipa_ref *ref = NULL; - for (int i = 0; vnode->iterate_referring (i, ref); i++) - { - log("inside vnode loop\n"); - tree decl = vnode->decl; - gcc_assert(decl); - enum tree_code code = TREE_CODE(decl); - gcc_assert(VAR_DECL == code); - bool filter_out = filter_var_decl(escape_map, decl); - if (filter_out) continue; - - tree type = TREE_TYPE(decl); - gcc_assert(type); - log("collecting global type escape analysis %s\n", get_type_name(type)); - escaping_reason reason = new_escaping_reason(); - escaping_info info = { type, false, reason }; - escape_map.put (type, info); - //escape_map.put (TYPE_MAIN_VARIANT(type), info); - } -} - -static void -collect_globals(type_map &escape_map) -{ - varpool_node *vnode; - FOR_EACH_VARIABLE (vnode) - { - collect_global(escape_map, vnode); - } -} static void collect_parm_declarations (cgraph_node *cnode, type_map &escape_map) @@ -300,266 +265,6 @@ collect_parm_declarations (cgraph_node *cnode, type_map &escape_map) } } -static void -collect_local_declarations (cgraph_node *cnode, type_map &escape_map) -{ - gcc_assert(cnode); - int i = 0; - function *func = DECL_STRUCT_FUNCTION (cnode->decl); - cnode->get_untransformed_body (); - tree var_decl = NULL; - FOR_EACH_LOCAL_DECL (func, i, var_decl) - { - gcc_assert(var_decl); - bool filter_out = filter_var_decl(escape_map, var_decl); - if (filter_out) continue; - - tree tree_type = TREE_TYPE(var_decl); - gcc_assert(tree_type); - escaping_reason reason = new_escaping_reason(); - escaping_info info = { tree_type, false, reason}; - escape_map.put(tree_type, info); - } -} - -static void collect_expr (const_tree expr, type_map &escape_map); - -static void -collect_expr_in_component_ref(const_tree cref, type_map &escape_map) -{ - gcc_assert(cref); - const enum tree_code code = TREE_CODE(cref); - const bool is_cref = COMPONENT_REF == code; - gcc_assert(is_cref); - - const_tree _struct = TREE_OPERAND(cref, 0); - gcc_assert(_struct); - - const_tree _struct_type = TREE_TYPE(_struct); - log("we are in collect_expr_in_component_ref %s\n", get_type_name(_struct_type)); - escaping_reason reason = new_escaping_reason(); - escaping_info info = { _struct_type, false , reason}; - escape_map.put(_struct_type, info); - - collect_expr(_struct, escape_map); - -} - -static void -collect_expr (const_tree expr, type_map &escape_map) -{ - gcc_assert(expr); - enum tree_code tree_code_expr = TREE_CODE(expr); - switch (tree_code_expr) - { - case COMPONENT_REF: - collect_expr_in_component_ref(expr, escape_map); - break; - default: - break; - } -} - -static void -collect_pointer_plus (tree lhs, tree rhs1, tree rhs2, type_map &escape_map) -{ - log("collect_pointer_plus\n"); - const_tree lhs_type = lhs ? TREE_TYPE(lhs) : NULL; - bool is_lhs_boring = lhs_type ? filter_type(escape_map, lhs_type) : true; - const_tree rhs1_type = rhs1 ? TREE_TYPE(rhs1) : NULL; - bool is_rhs1_boring = rhs1_type ? filter_type(escape_map, rhs1_type) : true; - const_tree rhs2_type = rhs2 ? TREE_TYPE(rhs2) : NULL; - bool is_rhs2_boring = rhs2_type ? filter_type(escape_map, rhs2_type) : true; - - if (!is_lhs_boring) - { - escaping_reason reason = new_escaping_reason(); - escaping_info info = { lhs_type , false, reason }; - escape_map.put(lhs_type, info); - } - if (!is_rhs1_boring) - { - collect_expr(rhs1, escape_map); - } - if (!is_rhs2_boring) - { - collect_expr(rhs2, escape_map); - } -} - -static void -collect_assign_rhs (gimple *stmt, type_map &escape_map) -{ - enum tree_code code = gimple_expr_code (stmt); - switch (code) - { - case POINTER_PLUS_EXPR: - case POINTER_DIFF_EXPR: - case COMPONENT_REF: - { - tree rhs2 = gimple_assign_rhs2(stmt); - tree rhs1 = gimple_assign_rhs1(stmt); - tree lhs = gimple_assign_lhs (stmt); - collect_pointer_plus (lhs, rhs1, rhs2, escape_map); - break; - } - default: - break; - } -} - -static void -collect_assign (gimple *stmt, type_map &escape_map) -{ - gcc_assert(stmt); - collect_assign_rhs (stmt, escape_map); -} - -static void -collect_call_lhs (gimple *stmt, type_map &escape_map) -{ - gcc_assert(stmt); - tree lhs = gimple_call_lhs (stmt); - if (!lhs) return; - - collect_expr (lhs, escape_map); -} - -static void -collect_call_rhs (gimple *stmt, type_map &escape_map) -{ - gcc_assert(stmt); - tree fn = gimple_call_fn (stmt); - - gcc_assert (fn); - gcall *call = dyn_cast (stmt); - //struct cgraph_node *n = cgraph_node::get (fn); - //if (n) log ("collecting arguments for %s \n", n->name()); - - tree return_type = gimple_call_return_type (call); - bool is_return_type_boring = filter_type(escape_map, return_type); - - if (!is_return_type_boring) { - escaping_reason reason = new_escaping_reason(); - escaping_info info = {return_type, false, reason}; - escape_map.put(return_type, info); - } - - unsigned args = gimple_call_num_args (stmt); - for (unsigned i = 0; i < args; i++) - { - tree arg = gimple_call_arg (stmt, i); - tree arg_type = TREE_TYPE(arg); - log("collecting argument of type %s\n", get_type_name(arg_type)); - bool is_arg_boring = filter_type(escape_map, arg_type); - if (is_arg_boring) continue; - - escaping_reason reason = new_escaping_reason(); - escaping_info info = {arg_type, false, reason}; - escape_map.put(arg_type, info); - - } -} - -static void -collect_call(gimple *stmt, type_map &escape_map) -{ - gcc_assert(stmt); - collect_call_lhs (stmt, escape_map); - collect_call_rhs (stmt, escape_map); -} - -static void -collect_stmt (gimple *stmt, type_map &escape_map) -{ - gcc_assert (stmt); - const enum gimple_code code = gimple_code (stmt); - switch (code) - { - case GIMPLE_ASSIGN: - collect_assign(stmt, escape_map); - break; - case GIMPLE_CALL: - collect_call(stmt, escape_map); - break; - default: - break; - } - - return; -} - -static void -collect_basic_block (basic_block bb, type_map &escape_map) -{ - gcc_assert(bb); - for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next(&gsi)) - { - gimple *stmt = gsi_stmt (gsi); - collect_stmt (stmt, escape_map); - } -} - -static void -collect_function_body (cgraph_node *cnode, type_map &escape_map) -{ - gcc_assert (cnode); - cnode->get_untransformed_body(); - basic_block bb = NULL; - tree decl = cnode->decl; - gcc_assert(decl); - function *func = DECL_STRUCT_FUNCTION (decl); - gcc_assert(func); - push_cfun(func); - FOR_EACH_BB_FN (bb, func) - { - gcc_assert(bb); - collect_basic_block (bb, escape_map); - } - pop_cfun(); -} - -static void -collect_return_type (cgraph_node *cnode, type_map &escape_map) -{ - gcc_assert(cnode); - - const_tree decl = cnode->decl; - const enum tree_code code = TREE_CODE(decl); - const bool is_function_decl = FUNCTION_DECL == code; - gcc_assert (is_function_decl); - - const_tree fn_type = TREE_TYPE (decl); - const enum tree_code fn_type_code = TREE_CODE(fn_type); - const bool is_fn_type = FUNCTION_TYPE == fn_type_code; - gcc_assert (is_fn_type); - - const_tree ret_type = TREE_TYPE(fn_type); - gcc_assert (ret_type); - - const bool is_boring = filter_type(escape_map, ret_type); - if (is_boring) return; - - escaping_reason reason = new_escaping_reason(); - escaping_info info = {ret_type, false, reason}; - escape_map.put(ret_type, info); - return; -} - -static void -collect_types(type_map &escape_map) -{ - collect_globals(escape_map); - - cgraph_node *cnode = NULL; - FOR_EACH_DEFINED_FUNCTION (cnode) - { - collect_function_body (cnode, escape_map); - collect_local_declarations (cnode, escape_map); - collect_parm_declarations (cnode, escape_map); - collect_return_type (cnode, escape_map); - } -} bool _print_types( const_tree const &type, escaping_info *info, __attribute__((unused)) void*) @@ -965,6 +670,26 @@ cast_to_void_in_program(type_map &escape_map) } } +void +ptrset_to_typemap(ptrset_t &ptrset, type_map &escape_map) +{ + // ptrset contains 3 sets + // a universe set (which arguably contains all trees) + // a points to record set (which contains trees which points to records) + // a complement set (which contains trees which are everything else) + // we need to put all trees from points to record set + // into the type_map + // we also want to create the info data structure... + for (auto i = ptrset.points_to_record.cbegin(); i != ptrset.points_to_record.cend(); ++i) + { + const_tree type = *i; + gcc_assert(type); + escaping_reason reason = new_escaping_reason(); + escaping_info info = { type, false, reason }; + escape_map.put(type, info); + } +} + /* INFO: * Yes, I know we are returning a std::map. * Bad pattern? Maybe, but this will only be called once @@ -979,7 +704,9 @@ cast_to_void_in_program(type_map &escape_map) void calculate_escaping_types(type_map &escape_map) { - collect_types(escape_map); + ptrset_t types; + collect_types(types); + ptrset_to_typemap(types, escape_map); is_any_variable_escaping(escape_map); is_any_function_escaping(escape_map); cast_to_void_in_program(escape_map); -- cgit v1.2.3