summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-04-15 16:33:45 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-04-28 23:35:50 +0200
commitf9ffbaade6abfd768e28327bc9bda4d0a541d0e5 (patch)
tree89b1fc0d4aef992f2966d1a0d1bbca2b78a99405
parentdecef57e82b184a34da13c6bb6ea0a29ecd47312 (diff)
escape analysis working
-rw-r--r--gcc/ipa-hello-world.c112
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