summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-03-09 16:24:25 +0100
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-04-28 23:35:48 +0200
commitaafa2ae8cef4b41127c5e0e7f4f4940d8037e0c5 (patch)
tree480c4d7e7685c1833bea7e72d14b3ae22e8cd84d
parent85bf30ba742a1142f7c3249b87fb72d829f40aca (diff)
Finding out casts
-rw-r--r--gcc/ipa-hello-world.c138
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-11-cast-to-void-ptr-0.c26
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" } } */