diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-04-15 16:33:45 +0200 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-04-28 23:35:50 +0200 |
commit | f9ffbaade6abfd768e28327bc9bda4d0a541d0e5 (patch) | |
tree | 89b1fc0d4aef992f2966d1a0d1bbca2b78a99405 | |
parent | decef57e82b184a34da13c6bb6ea0a29ecd47312 (diff) |
escape analysis working
-rw-r--r-- | gcc/ipa-hello-world.c | 112 |
1 files changed, 105 insertions, 7 deletions
diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-hello-world.c index a074c83bbd6..17c6fd0562a 100644 --- a/gcc/ipa-hello-world.c +++ b/gcc/ipa-hello-world.c @@ -560,28 +560,126 @@ calculate_escaping_types_from_function_signatures ( } void +find_calls_to_undefined_functions_from_call(gimple *stmt, hash_set<tree> &set, type_map &escape_map) +{ + gcc_assert(stmt); + const enum gimple_code code = gimple_code(stmt); + const bool is_gimple_call = GIMPLE_CALL == code; + gcc_assert(is_gimple_call); + + gcall *call = dyn_cast<gcall *>(stmt); + tree fn = gimple_call_fndecl(stmt); + + // Function pointer? + if (!fn) return; + + // if fn is in set... then it means that it is undefined. + if (!set.contains(fn)) return; + + unsigned num_arguments = gimple_call_num_args(call); + for (unsigned i = 0; i < num_arguments; i++) + { + tree argument = gimple_call_arg(stmt, i); + /* + // TODO: Why is this the case? + gimple *def_for_arg = SSA_NAME_DEF_STMT(argument); + gcc_assert(def_for_arg); + const enum gimple_code code2 = gimple_code(def_for_arg); + const bool is_gimple_call2 = GIMPLE_CALL == code2; + const bool is_gimple_assign = GIMPLE_ASSIGN == code2; + const bool is_assignable = is_gimple_call2 ^ is_gimple_assign; + gcc_assert(is_assignable); + + tree arg_var = is_gimple_assign ? gimple_assign_lhs(def_for_arg) : gimple_call_lhs(def_for_arg); + gcc_assert(arg_var); + */ + tree arg_type = TREE_TYPE(argument); + gcc_assert(arg_type); + + bool is_escaping = true; + escaping_reason reason = new_escaping_reason(); + reason.parameter_is_visible = is_escaping; + update_escape_info(arg_type, escape_map, is_escaping, reason); + } +} + +void +find_calls_to_undefined_functions_from_stmt(gimple *stmt, hash_set<tree> &set, type_map &escape_map) +{ + gcc_assert(stmt); + const enum gimple_code code = gimple_code (stmt); + const bool is_gimple_call = GIMPLE_CALL == code; + if (!is_gimple_call) return; + + find_calls_to_undefined_functions_from_call(stmt, set, escape_map); +} + + +void +find_calls_to_undefined_functions_from_bb(basic_block bb, hash_set<tree> &set, 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); + find_calls_to_undefined_functions_from_stmt(stmt, set, escape_map); + } +} + +void +find_calls_to_undefined_functions_from_function(cgraph_node *cnode, hash_set<tree> &set, type_map &escape_map) +{ + gcc_assert(cnode); + cnode->get_untransformed_body (); + function *func = DECL_STRUCT_FUNCTION(cnode->decl); + basic_block bb = NULL; + push_cfun(func); + FOR_EACH_BB_FN(bb, func) + { + find_calls_to_undefined_functions_from_bb(bb, set, escape_map); + } + pop_cfun(); +} + +void is_any_function_escaping(type_map &escape_map) { cgraph_node *cnode = NULL; - hash_set<cgraph_node *> not_defined_functions; + hash_set<tree> not_defined_functions; FOR_EACH_FUNCTION (cnode) { gcc_assert(cnode); - not_defined_functions.add(cnode); + const char* _free = "free"; + const char* _memset = "memset"; + const char* _malloc = "malloc"; + const char* _realloc = "realloc"; + const char* _calloc= "calloc"; + const char* ob_name = cnode->name(); + if (strcmp(ob_name, _free) == 0) continue; + if (strcmp(ob_name, _memset) == 0) continue; + if (strcmp(ob_name, _malloc) == 0) continue; + if (strcmp(ob_name, _realloc) == 0) continue; + if (strcmp(ob_name, _calloc) == 0) continue; + + not_defined_functions.add(cnode->decl); } -/* FOR_EACH_DEFINED_FUNCTION(cnode) + FOR_EACH_DEFINED_FUNCTION(cnode) { gcc_assert(cnode); cnode->get_untransformed_body(); - not_defined_functions.remove(cnode); - calculate_escaping_types_from_function_signatures (cnode, escape_map); + not_defined_functions.remove(cnode->decl); + calculate_escaping_types_from_function_signatures (cnode, &escape_map); } -*/ - not_defined_functions.traverse<type_map *, calculate_escaping_types_from_function_signatures> (&escape_map); + // not_defined_functions.traverse<type_map *, calculate_escaping_types_from_function_signatures> (&escape_map); + //TODO: Walk gimple code and identify GIMPLE_CALL to see if function is not defined... + FOR_EACH_DEFINED_FUNCTION(cnode) + { + find_calls_to_undefined_functions_from_function(cnode, not_defined_functions, escape_map); + } } void |