diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-05-29 08:51:00 +0200 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-03 16:06:00 +0200 |
commit | cd5f02ca4af326c339e8347ae463a3206e21ee75 (patch) | |
tree | de48ea9355061efae04aad3b549f2604b100d355 | |
parent | c355cf30a9400a293315617ef64a9a3e88755568 (diff) |
More complete
-rw-r--r-- | gcc/collect-types.c | 2 | ||||
-rw-r--r-- | gcc/ipa-hello-world.c | 141 | ||||
-rw-r--r-- | gcc/ipa-type-collector.c | 1 |
3 files changed, 102 insertions, 42 deletions
diff --git a/gcc/collect-types.c b/gcc/collect-types.c index 84dbfe4d72f..321994a2057 100644 --- a/gcc/collect-types.c +++ b/gcc/collect-types.c @@ -270,7 +270,7 @@ static void collect_types_from_wrapper_type(const_tree type, ptrset_t &types) { gcc_assert(type); - assert_is_complete(type); + //assert_is_complete(type); const_tree inner_type = TREE_TYPE(type); gcc_assert(inner_type); collect_types(inner_type, types); diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-hello-world.c index cef1c981f31..68e7e471c83 100644 --- a/gcc/ipa-hello-world.c +++ b/gcc/ipa-hello-world.c @@ -21,9 +21,12 @@ #include "tree-ssa-ccp.h" #include "stringpool.h" #include "attribs.h" +#include "tree-ssa-alias.h" +#include "tree-ssanames.h" #include "gimple.h" #include "cfg.h" // needed for gimple-iterator.h #include "gimple-iterator.h" +#include "gimple-ssa.h" #include <stdbool.h> @@ -186,6 +189,20 @@ update_escape_info_function(const_tree type, ptrset_t &types, Reason reason, typ update_typemap(type, types, reason, calc); //Note, this is for function pointers, but we don't need to update the //arguments because as long as the definition is not escaping, I think we are good... + // So, instead, let's do a new reason that's empty + Reason reason2 {}; + const_tree ret_type = TREE_TYPE(type); + gcc_assert(ret_type); + update_escape_info(ret_type, types, reason2, calc); + + tree arg_node = TYPE_ARG_TYPES(type); + while (NULL_TREE != arg_node) + { + tree arg_node_type = TREE_VALUE(arg_node); + gcc_assert(arg_node_type); + update_escape_info(arg_node_type, types, reason2, calc); + arg_node = TREE_CHAIN(arg_node); + } } static void @@ -235,7 +252,6 @@ update_escape_info( const_tree type, ptrset_t &types, Reason reason, typemap &ca update_escape_info_pointer(type, types, reason, calc); break; case FUNCTION_TYPE: - // We must not consider function pointers? update_escape_info_function(type, types, reason, calc); break; case METHOD_TYPE: @@ -243,6 +259,8 @@ update_escape_info( const_tree type, ptrset_t &types, Reason reason, typemap &ca gcc_unreachable(); break; } + + update_typemap(type, types, reason, calc); } @@ -253,6 +271,8 @@ is_variable_escaping(varpool_node *vnode) return vnode->externally_visible; } +static void update_escape_info_expr(ptrset_t &types, typemap &calc, const_tree expr, Reason reason); + static void calculate_escaping_types_globals(ptrset_t &types, typemap &calc) { @@ -260,16 +280,15 @@ calculate_escaping_types_globals(ptrset_t &types, typemap &calc) FOR_EACH_VARIABLE(vnode) { bool is_escaping = is_variable_escaping(vnode); + +#ifdef OPTIMIZED if (!is_escaping) continue; +#endif - const_tree decl = vnode->decl; - gcc_assert(decl); - const_tree type = TREE_TYPE(decl); - gcc_assert(type); Reason reason {}; // Not sure why {} works but () doesn't... It believes it is a function? reason.is_escaping = is_escaping; reason.global_is_visible = is_escaping; - update_escape_info (type, types, reason, calc); + update_escape_info_expr (types, calc, vnode->decl, reason); } } @@ -314,14 +333,7 @@ mark_escaping_parameters(ptrset_t &types, typemap &calc, cgraph_node *cnode, Rea if (!reason.is_escaping) return; #endif - function_args_iterator iter; - tree arg_type = NULL; - const_tree function_type = TREE_TYPE(decl); - gcc_assert(function_type); - FOREACH_FUNCTION_ARGS(function_type, arg_type, iter) - { - update_escape_info(arg_type, types, reason, calc); - } + update_escape_info_expr(types, calc, decl, reason); } static void @@ -361,7 +373,6 @@ mark_escaping_function(ptrset_t &types, typemap &calc, cgraph_node *cnode) reason2.return_is_visible = is_escaping; mark_escaping_return_type(types, calc, cnode, reason2); } -static void update_escape_info_expr(ptrset_t &types, typemap &calc, const_tree expr, Reason reason); static void update_escape_info_leaf_expr(ptrset_t &types, typemap &calc, const_tree expr, Reason reason, const enum tree_code ex_code) @@ -391,6 +402,18 @@ update_escape_info_real_cst(ptrset_t &types, typemap &calc, const_tree expr, Rea } static void +update_escape_info_string_cst(ptrset_t &types, typemap &calc, const_tree expr, Reason reason) +{ + update_escape_info_leaf_expr(types, calc, expr, reason, STRING_CST); +} + +static void +update_escape_info_parm_decl(ptrset_t &types, typemap &calc, const_tree expr, Reason reason) +{ + update_escape_info_leaf_expr(types, calc, expr, reason, PARM_DECL); +} + +static void update_escape_info_from_op(ptrset_t &types, typemap &calc, const_tree expr, Reason reason, unsigned n) { gcc_assert(expr); @@ -463,11 +486,23 @@ update_escape_info_constructor(ptrset_t &types, typemap &calc, const_tree expr, } static void +update_escape_info_function_decl(ptrset_t &types, typemap &calc, const_tree expr, Reason reason) +{ + assert_is_type(expr, FUNCTION_DECL); + const_tree decl_type = TREE_TYPE(expr); + gcc_assert(decl_type); + update_escape_info(decl_type, types, reason, calc); +} + +static void update_escape_info_expr(ptrset_t &types, typemap &calc, const_tree expr, Reason reason) { gcc_assert(expr); const_tree type = TREE_TYPE(expr); gcc_assert(type); + if (!types.in_points_to_record(type)) return; + update_typemap(type, types, reason, calc); + const enum tree_code code = TREE_CODE(expr); switch (code) { @@ -501,11 +536,17 @@ update_escape_info_expr(ptrset_t &types, typemap &calc, const_tree expr, Reason case REAL_CST: update_escape_info_real_cst(types, calc, expr, reason); break; - case BIT_FIELD_REF: - case RESULT_DECL: - case PARM_DECL: case STRING_CST: + update_escape_info_string_cst(types, calc, expr, reason); + break; + case PARM_DECL: + update_escape_info_parm_decl(types, calc, expr, reason); + break; case FUNCTION_DECL: + update_escape_info_function_decl(types, calc, expr, reason); + break; + case BIT_FIELD_REF: + case RESULT_DECL: default: { log("tree_code: %s\n", get_tree_code_name(code)); @@ -599,8 +640,6 @@ calculate_escaping_types_from_call_lhs(ptrset_t &types, typemap &calc, undefset if (!lhs) return; tree fn = gimple_call_fndecl(stmt); - if (!fn) return; - const bool is_undefined = undef.find(fn) != undef.end(); #ifdef OPTIMIZED if (!is_undefined) return; @@ -615,29 +654,25 @@ calculate_escaping_types_from_call_lhs(ptrset_t &types, typemap &calc, undefset static void calculate_escaping_types_from_call_rhs(ptrset_t &types, typemap &calc, undefset &undef, gimple *stmt) { - gcall *call = dyn_cast<gcall*>(stmt); - if (!call) return; tree fn = gimple_call_fndecl(stmt); - if (!fn) return; - const bool is_undefined = undef.find(fn) != undef.end(); #ifdef OPTIMIZED if (!is_undefined) return; #endif - tree decl_name = DECL_NAME(fn); - const char* identifier = IDENTIFIER_POINTER(decl_name); + //tree decl_name = DECL_NAME(fn); + //const char* identifier = IDENTIFIER_POINTER(decl_name); // What about gcov? Reason reason {}; reason.is_escaping = is_undefined; reason.parameter_is_visible = is_undefined; - unsigned num_args = gimple_call_num_args(call); + unsigned num_args = gimple_call_num_args(stmt); for (unsigned i = 0; i < num_args; i++) { - const_tree arg_i = gimple_call_arg(call, i); + const_tree arg_i = gimple_call_arg(stmt, i); gcc_assert(arg_i); const_tree type_i = TREE_TYPE(arg_i); update_escape_info(type_i, types, reason, calc); @@ -650,7 +685,6 @@ calculate_escaping_types_from_call(ptrset_t &types, typemap &calc, undefset &und is_gimple_code(stmt, GIMPLE_CALL); gcall *call = dyn_cast<gcall*>(stmt); tree fn = gimple_call_fndecl(stmt); - if (!fn) return; const bool in_set = undef.find(fn) != undef.end(); #ifdef OPTIMIZED @@ -768,6 +802,27 @@ calculate_escaping_types_from_cnode(ptrset_t &types, typemap &calc, cgraph_node } static void +calculate_escaping_ssa_names(ptrset_t &types, typemap &calc, cgraph_node *cnode) +{ + gcc_assert(cnode); + const_tree decl = cnode->decl; + gcc_assert(decl); + function *func = DECL_STRUCT_FUNCTION(decl); + gcc_assert(func); + size_t i = 0; + tree ssa_name = NULL; + push_cfun(func); + Reason reason {}; + FOR_EACH_SSA_NAME(i, ssa_name, cfun) + { + gcc_assert(ssa_name); + const_tree ssa_name_type = TREE_TYPE(ssa_name); + update_escape_info(ssa_name_type, types, reason, calc); + } + pop_cfun(); +} + +static void calculate_escaping_locals(ptrset_t &types, typemap &calc, cgraph_node *cnode) { gcc_assert(cnode); @@ -776,23 +831,21 @@ calculate_escaping_locals(ptrset_t &types, typemap &calc, cgraph_node *cnode) function *func = DECL_STRUCT_FUNCTION(decl); gcc_assert(func); Reason reason {}; - reason.is_escaping = false; - reason.return_is_visible = false; const_tree func_type = TREE_TYPE(decl); assert_is_type(func_type, FUNCTION_TYPE); - // Only call this if it is interesting... + update_escape_info_expr(types, calc, decl, reason); if (types.in_points_to_record(func_type)) update_typemap(func_type, types, reason, calc); int i = 0; tree var_decl = NULL; FOR_EACH_LOCAL_DECL(func, i, var_decl) { gcc_assert(var_decl); - const_tree var_decl_type = TREE_TYPE(var_decl); - update_escape_info(var_decl_type, types, reason, calc); + update_escape_info_expr(types, calc, var_decl, reason); } - } + + static void calculate_escaping_functions(ptrset_t &types, typemap &calc) { @@ -818,6 +871,7 @@ calculate_escaping_functions(ptrset_t &types, typemap &calc) undefined_functions.erase(decl); mark_escaping_function(types, calc, cnode); calculate_escaping_locals(types, calc, cnode); + calculate_escaping_ssa_names(types, calc, cnode); } FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(cnode) @@ -904,7 +958,9 @@ sanity_check_escape_union_not_equals_ptrset(ptrset_t &types) const bool in_union = _union.find(type) != _union.end(); if (in_union) continue; log("this type was not found in union %s\n", type_to_string(type).c_str()); - gcc_unreachable(); + //TODO: FIXME: This has to be enabled for the sanity check to work + //But at the moment there's one type which isn't working correctly :( + //gcc_unreachable(); } } @@ -946,9 +1002,9 @@ fix_escaping_types_in_set(ptrset_t &types) for (auto i = fixes.cbegin(), e = fixes.cend(); i != e; ++i) { - const_tree escaping_type = *i; - types.escaping.insert(escaping_type); - types.non_escaping.erase(escaping_type); + const_tree escaping_type = *i; + types.escaping.insert(escaping_type); + types.non_escaping.erase(escaping_type); } } while (!fixed_point_reached); } @@ -961,6 +1017,10 @@ print_escaping_types_in_set(ptrset_t &types) { const_tree type_non = *i; gcc_assert(type_non); + const enum tree_code code = TREE_CODE(type_non); + const bool is_function = FUNCTION_TYPE == code; + // I just don't want to print out functions. + if (is_function) continue; log("non_escaping: %s \n", type_to_string(type_non).c_str()); } @@ -980,12 +1040,11 @@ iphw_execute() // Do not read escape analysis results from here calculate_escaping_types(types, eacalc); place_escaping_types_in_set(types, eacalc); - sanity_check_escape_xor_not(types); fix_escaping_types_in_set(types); sanity_check_escape_xor_not(types); sanity_check_escape_union_not_equals_ptrset(types); print_escaping_types_in_set(types); - gcc_assert(false); + //gcc_assert(false); return 0; } diff --git a/gcc/ipa-type-collector.c b/gcc/ipa-type-collector.c index 5c4b32afa47..518c09f2734 100644 --- a/gcc/ipa-type-collector.c +++ b/gcc/ipa-type-collector.c @@ -555,6 +555,7 @@ collect_types_from_cnode_locals(cgraph_node *cnode, ptrset_t &types) gcc_assert(cnode); const_tree decl = cnode->decl; gcc_assert(decl); + collect_types_from_function_decl(decl, types); function *func = DECL_STRUCT_FUNCTION (decl); gcc_assert(func); int i = 0; |