diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-03-09 16:24:25 +0100 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-04-28 23:35:48 +0200 |
commit | aafa2ae8cef4b41127c5e0e7f4f4940d8037e0c5 (patch) | |
tree | 480c4d7e7685c1833bea7e72d14b3ae22e8cd84d | |
parent | 85bf30ba742a1142f7c3249b87fb72d829f40aca (diff) |
Finding out casts
-rw-r--r-- | gcc/ipa-hello-world.c | 138 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ipa/ipa-ea-11-cast-to-void-ptr-0.c | 26 |
2 files changed, 161 insertions, 3 deletions
diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-hello-world.c index 67cc996bbf7..df08d76ceeb 100644 --- a/gcc/ipa-hello-world.c +++ b/gcc/ipa-hello-world.c @@ -16,6 +16,8 @@ #include "tree-vrp.h" #include "ipa-prop.h" #include "tree-pretty-print.h" +#include "tree-cfg.h" +#include "gimple-pretty-print.h" #include "tree-inline.h" #include "ipa-fnsummary.h" #include "ipa-utils.h" @@ -167,12 +169,15 @@ static void collect_parm_declarations (cgraph_node *cnode, type_map &escape_map) { gcc_assert(cnode); + log("does function %s have parameters?\n", cnode->name()); for (tree parm = DECL_ARGUMENTS (cnode->decl); parm; parm = DECL_CHAIN (parm)) { + tree type = TREE_TYPE(parm); + log("about to enter parameter type %s\n", get_type_name(type)); bool filter_out = filter_parm_declarations (parm, escape_map); if (filter_out) continue; - tree type = TREE_TYPE(parm); + log("putting parameter type %s\n", get_type_name(type)); gcc_assert(type); escaping_info info = { type, false }; escape_map.put(type, info); @@ -225,7 +230,6 @@ collect_pointer_plus (tree lhs, tree rhs1, tree rhs2, type_map &escape_map) escaping_info info = {rhs2_type, false}; escape_map.put(rhs2_type, info); } - } static void @@ -311,9 +315,9 @@ collect_types(type_map &escape_map) cgraph_node *cnode = NULL; FOR_EACH_DEFINED_FUNCTION (cnode) { - collect_parm_declarations (cnode, escape_map); collect_function_body (cnode, escape_map); collect_local_declarations (cnode, escape_map); + collect_parm_declarations (cnode, escape_map); } } @@ -430,6 +434,133 @@ is_any_variable_escaping(type_map &escape_map) } } +inline static void +print_function (cgraph_node *cnode) +{ + if (!dump_file) + return; + gcc_assert (cnode); + cnode->get_untransformed_body (); + dump_function_to_file (cnode->decl, dump_file, TDF_NONE); +} + +static void +cast_to_void_in_assign(const_tree lhs, const_tree rhs, type_map &escape_map) +{ + gcc_assert(lhs); + gcc_assert(rhs); + tree tree_type_lhs = TREE_TYPE(lhs); + gcc_assert(tree_type_lhs); + tree tree_type_rhs = TREE_TYPE(rhs); + gcc_assert(tree_type_rhs); + const char* const type_name_lhs = get_type_name(tree_type_lhs); + const char* const type_name_rhs = get_type_name(tree_type_rhs); + enum tree_code tree_code_rhs = TREE_CODE(rhs); + bool is_ssa_name = SSA_NAME == tree_code_rhs; + bool is_var_decl = VAR_DECL == tree_code_rhs; + bool is_var_decl_or_ssa_name = is_ssa_name || is_var_decl; + log("lhs = %s, rhs = %s\n", type_name_lhs, type_name_rhs); + if (!is_var_decl_or_ssa_name) return; + + bool is_casting_stmt = tree_type_lhs != tree_type_rhs; + log("is casting stmt ? %s\n", is_casting_stmt ? "true" : "false"); + if (!is_casting_stmt) return; + + escaping_info *info_lhs = escape_map.get(tree_type_lhs); + if (info_lhs) + { + log("escaping lhs %s\n", type_name_lhs); + info_lhs->is_escaping = true; + } + + escaping_info *info_rhs = escape_map.get(tree_type_rhs); + if (info_rhs) + { + log("escaping rhs %s\n", type_name_rhs); + info_rhs->is_escaping = true; + } +} + +static void +cast_to_void_in_assign (gimple *stmt, type_map &escape_map) +{ + enum gimple_code gcode = gimple_code (stmt); + const char* const gcode_str = gimple_code_name[gcode]; + gcc_assert(gcode_str); + + switch (gimple_assign_rhs_class (stmt)) + { + case GIMPLE_SINGLE_RHS: + case GIMPLE_UNARY_RHS: + { + tree lhs = gimple_assign_lhs(stmt); + tree rhs = gimple_assign_rhs1(stmt); + cast_to_void_in_assign(lhs, rhs, escape_map); + } + default: + break; + } +} + +static void +cast_to_void_in_stmt (gimple *stmt, type_map &escape_map) +{ + gcc_assert (stmt); + const enum gimple_code code = gimple_code (stmt); + switch (code) + { + case GIMPLE_ASSIGN: + cast_to_void_in_assign(stmt, escape_map); + break; + default: + break; + } + + return; +} + +static void +cast_to_void_in_bb(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); + cast_to_void_in_stmt (stmt, escape_map); + } +} + +static void +cast_to_void_in_function(cgraph_node *cnode, type_map &escape_map) +{ + gcc_assert (cnode); + print_function (cnode); + 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); + cast_to_void_in_bb(bb, escape_map); + } + pop_cfun(); +} + +static void +cast_to_void_in_program(type_map &escape_map) +{ + cgraph_node *cnode = NULL; + FOR_EACH_FUNCTION (cnode) + { + gcc_assert(cnode); + cnode->get_untransformed_body(); + cast_to_void_in_function(cnode, escape_map); + } +} + static unsigned int iphw_execute() { @@ -437,6 +568,7 @@ iphw_execute() collect_types(escape_map); is_any_variable_escaping(escape_map); is_any_function_escaping(escape_map); + cast_to_void_in_program(escape_map); print_types(escape_map); return 0; } diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-11-cast-to-void-ptr-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-11-cast-to-void-ptr-0.c new file mode 100644 index 00000000000..2bd1b62e284 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-11-cast-to-void-ptr-0.c @@ -0,0 +1,26 @@ +/* { dg-do link } */ +/* { dg-options "-flto -fipa-hello-world -fdump-ipa-hello-world" } */ + +#include <stddef.h> + +struct astruct_s { _Bool a; _Bool b; _Bool c;}; +struct astruct_s astruct; // This should not escape +struct bstruct_s { _Bool a; _Bool b; _Bool c;}; +struct bstruct_s bstruct; // This should not escape + +void casting_to_void (struct astruct_s *s) +{ + void *nullify_non_escape = s; +} + +int main() +{ + astruct.a = 0; + bstruct.b = 0; +} + + +/* { dg-final { scan-wpa-ipa-dump "collected,astruct_s" "hello-world" } } */ +/* { dg-final { scan-wpa-ipa-dump "type astruct_s\\\* is escaping true" "hello-world" } } */ +/* { dg-final { scan-wpa-ipa-dump "collected,bstruct_s" "hello-world" } } */ +/* { dg-final { scan-wpa-ipa-dump "type bstruct_s is escaping false" "hello-world" } } */ |