summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-04 16:48:24 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-04 16:48:24 +0200
commitb49aa30869c09910acb6c6e83f37b7fec15b25c7 (patch)
treede9f3ded031e5346e12493d2813295c53252d211
parentefb64d6f99685ab548ac60183dfcddec09c01960 (diff)
gimple-escaper
-rw-r--r--gcc/Makefile.in9
-rw-r--r--gcc/expr-escaper.c52
-rw-r--r--gcc/expr-escaper.hpp24
-rw-r--r--gcc/gimple-escaper.c80
-rw-r--r--gcc/gimple-escaper.hpp9
-rw-r--r--gcc/ipa-prototype.c464
-rw-r--r--gcc/type-escaper.c121
-rw-r--r--gcc/type-escaper.hpp93
8 files changed, 271 insertions, 581 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 5a105ba8632..9a3c9ee1f33 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1408,12 +1408,15 @@ OBJS = \
init-regs.o \
internal-fn.o \
ipa-prototype.o \
- expr-walker.o \
- expr-collector.o \
type-walker.o \
+ expr-walker.o \
+ gimple-walker.o \
type-collector.o \
+ expr-collector.o \
gimple-collector.o \
- gimple-walker.o \
+ type-escaper.o \
+ expr-escaper.o \
+ gimple-escaper.o \
type-stringifier.o \
collect-types.o \
ipa-cp.o \
diff --git a/gcc/expr-escaper.c b/gcc/expr-escaper.c
new file mode 100644
index 00000000000..31e66582c21
--- /dev/null
+++ b/gcc/expr-escaper.c
@@ -0,0 +1,52 @@
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "tree.h"
+#include "gimple-expr.h"
+#include "predict.h"
+#include "alloc-pool.h"
+#include "tree-pass.h"
+#include "cgraph.h"
+#include "diagnostic.h"
+#include "fold-const.h"
+#include "gimple-fold.h"
+#include "symbol-summary.h"
+#include "tree-vrp.h"
+#include "ipa-prop.h"
+#include "tree-pretty-print.h"
+#include "tree-inline.h"
+#include "ipa-fnsummary.h"
+#include "ipa-utils.h"
+#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>
+
+
+#include "types-inlines.h"
+#include "type-escaper.hpp"
+#include "expr-escaper.hpp"
+
+void
+ExprEscaper::update(const_tree t, Reason r)
+{
+ gcc_assert(t);
+ _r = r;
+ walk(t);
+}
+
+void
+ExprEscaper::_walk_pre(const_tree e)
+{
+ const_tree t = TREE_TYPE(e);
+ gcc_assert(t);
+ typeEscaper.update(t, _r);
+}
+
diff --git a/gcc/expr-escaper.hpp b/gcc/expr-escaper.hpp
index 4455d50bef9..75e4de23196 100644
--- a/gcc/expr-escaper.hpp
+++ b/gcc/expr-escaper.hpp
@@ -1,31 +1,19 @@
+#pragma once
+
#include "ipa-prototype.h"
#include "expr-walker.hpp"
+#include "type-escaper.hpp"
+#include "collect-types.h"
class ExprEscaper : public ExprWalker
{
public:
- ExprEscaper(ptrset_t types) : typeEscaper(types) {};
- void update(const_tree t, Reason r);
TypeEscaper typeEscaper;
+ ExprEscaper(ptrset_t &types) : typeEscaper(types) {};
+ void update(const_tree t, Reason r);
private:
Reason _r;
virtual void _walk_pre(const_tree e);
};
-void
-ExprEscaper::update(const_tree t, Reason r)
-{
- gcc_assert(t);
- _r = r;
- walk(t);
-}
-
-void
-ExprEscaper::_walk_pre(const_tree e)
-{
- const_tree t = TREE_TYPE(e);
- gcc_assert(t);
- typeEscaper.update(t, _r);
-}
-
diff --git a/gcc/gimple-escaper.c b/gcc/gimple-escaper.c
index 20a71e1a476..4e5794e6300 100644
--- a/gcc/gimple-escaper.c
+++ b/gcc/gimple-escaper.c
@@ -1,3 +1,34 @@
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "tree.h"
+#include "gimple-expr.h"
+#include "predict.h"
+#include "alloc-pool.h"
+#include "tree-pass.h"
+#include "cgraph.h"
+#include "diagnostic.h"
+#include "fold-const.h"
+#include "gimple-fold.h"
+#include "symbol-summary.h"
+#include "tree-vrp.h"
+#include "ipa-prop.h"
+#include "tree-pretty-print.h"
+#include "tree-inline.h"
+#include "ipa-fnsummary.h"
+#include "ipa-utils.h"
+#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>
+
#include "gimple-escaper.hpp"
void
@@ -7,7 +38,7 @@ GimpleEscaper::_init()
FOR_EACH_FUNCTION(cnode)
{
gcc_assert(cnode);
- const bool filter = filter_known_function(cnode);
+ const bool filter = GimpleEscaper::filter_known_function(cnode);
if (filter) continue;
const_tree decl = cnode->decl;
@@ -25,33 +56,64 @@ GimpleEscaper::_init()
}
}
+bool
+GimpleEscaper::is_function_escaping(cgraph_node *cnode)
+{
+ const bool filter = GimpleEscaper::filter_known_function(cnode);
+ if (filter) return false;
+
+ gcc_assert(cnode);
+ return cnode->externally_visible;
+}
+
+bool
+GimpleEscaper::filter_known_function(cgraph_node *node)
+{
+ gcc_assert(node);
+ bool filter = false;
+ const char *_free = "free";
+ const char *_malloc = "malloc";
+ const char *_realloc = "realloc";
+ const char *_calloc = "calloc";
+ const char *_memset = "memset";
+ const char *name = node->name();
+ gcc_assert(name);
+ filter |= strcmp(_free, name) == 0;
+ filter |= strcmp(_malloc, name) == 0;
+ filter |= strcmp(_realloc, name) == 0;
+ filter |= strcmp(_memset, name) == 0;
+ filter |= strcmp(_calloc, name) == 0;
+ return filter;
+}
+
void
GimpleEscaper::_walk_pre(const_tree t)
{
// Is any global variable escaping?
Reason reason;
- exprEscaper.update(expr, reason);
+ //exprEscaper.update(expr, reason);
}
void
GimpleEscaper::_walk_pre(gassign *s)
{
Reason reason;
- exprEscaper.update(expr, reason);
+ // We really should also walk over the different assigns...
+ //exprEscaper.update(expr, reason);
}
void
GimpleEscaper::_walk_pre(greturn *s)
{
Reason reason;
- exprEscaper.update(expr, reason);
+ //exprEscaper.update(expr, reason);
}
void
GimpleEscaper::_walk_pre(gcond *s)
{
Reason reason;
- exprEscaper.update(expr, reason);
+ //exprEscaper.update(expr, reason);
}
void
@@ -64,18 +126,18 @@ GimpleEscaper::_walk_pre(gcall *s)
arg_reason.is_escaping = is_undefined;
arg_reason.parameter_is_visible = is_undefined;
unsigned n = gimple_call_num_args(s);
- for (unsigned i = 0; i < num_args; i++)
+ for (unsigned i = 0; i < n; i++)
{
const_tree a = gimple_call_arg(s, i);
gcc_assert(a);
exprEscaper.update(a, arg_reason);
}
+ const_tree lhs = gimple_call_lhs(s);
+ if (!lhs) return;
+
Reason return_reason;
return_reason.is_escaping = is_undefined;
return_reason.return_is_visible = is_undefined;
-
- const_tree lhs = gimple_call_lhs(s);
- if (!lhs) return;
exprEscaper.update(lhs, return_reason);
}
diff --git a/gcc/gimple-escaper.hpp b/gcc/gimple-escaper.hpp
index 38259a6393f..7ed2a89907e 100644
--- a/gcc/gimple-escaper.hpp
+++ b/gcc/gimple-escaper.hpp
@@ -6,14 +6,17 @@
class GimpleEscaper : public GimpleWalker
{
public:
- GimpleEscaper(ptrset_t types) : exprEscaper(types) { _init() };
+ GimpleEscaper(ptrset_t &types) : exprEscaper(types) { _init(); };
+ ExprEscaper exprEscaper;
private:
typedef std::set<const_tree> undefset;
undefset undefined;
- ExprEscaper exprEscaper;
+ void _init();
+ static bool filter_known_function(cgraph_node *);
+ static bool is_function_escaping(cgraph_node *);
virtual void _walk_pre(const_tree) final;
virtual void _walk_pre(gassign *s) final;
virtual void _walk_pre(greturn *s) final;
virtual void _walk_pre(gcond *s) final;
virtual void _walk_pre(gcall *s) final;
-}
+};
diff --git a/gcc/ipa-prototype.c b/gcc/ipa-prototype.c
index 06f0de6f1f4..0017e9d71b1 100644
--- a/gcc/ipa-prototype.c
+++ b/gcc/ipa-prototype.c
@@ -40,6 +40,7 @@
#include "expr-escaper.hpp"
#include "gimple-walker.hpp"
#include "gimple-collector.hpp"
+#include "gimple-escaper.hpp"
//#define OPTIMIZED
#define SANITY_CHECKS
@@ -98,8 +99,6 @@ assert_type_is_in_ptrset(const_tree type, ptrset_t &types)
}
-static void update_escape_info( const_tree type, ptrset_t &types, Reason reason, typemap &calc);
-
static bool
is_variable_escaping(varpool_node *vnode)
{
@@ -107,442 +106,6 @@ 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)
-{
- varpool_node *vnode = NULL;
- FOR_EACH_VARIABLE(vnode)
- {
- bool is_escaping = is_variable_escaping(vnode);
-
-#ifdef OPTIMIZED
- if (!is_escaping) continue;
-#endif
-
- 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_expr (types, calc, vnode->decl, reason);
- }
-}
-
-static bool
-filter_known_function(cgraph_node *node)
-{
- gcc_assert(node);
- bool filter = false;
- const char *_free = "free";
- const char *_malloc = "malloc";
- const char *_realloc = "realloc";
- const char *_calloc = "calloc";
- const char *_memset = "memset";
- const char *name = node->name();
- gcc_assert(name);
- filter |= strcmp(_free, name) == 0;
- filter |= strcmp(_malloc, name) == 0;
- filter |= strcmp(_realloc, name) == 0;
- filter |= strcmp(_memset, name) == 0;
- filter |= strcmp(_calloc, name) == 0;
- return filter;
-}
-
-static bool
-is_function_escaping(cgraph_node *cnode)
-{
- const bool filter = filter_known_function(cnode);
- if (filter) return false;
-
- gcc_assert(cnode);
- return cnode->externally_visible;
-}
-
-static void
-mark_escaping_parameters(ptrset_t &types, typemap &calc, cgraph_node *cnode, Reason reason)
-{
- gcc_assert(cnode);
- const_tree decl = cnode->decl;
- gcc_assert(decl);
- assert_is_type(decl, FUNCTION_DECL);
-#ifdef OPTIMIZED
- if (!reason.is_escaping) return;
-#endif
-
- update_escape_info_expr(types, calc, decl, reason);
-}
-
-static void
-mark_escaping_return_type(ptrset_t &types, typemap &calc, cgraph_node *cnode, Reason reason)
-{
- gcc_assert(cnode);
- const_tree decl = cnode->decl;
- gcc_assert(decl);
- assert_is_type(decl, FUNCTION_DECL);
-#ifdef OPTIMIZED
- if (!reason.is_escaping) return;
-#endif
-
- const_tree func_type = TREE_TYPE(decl);
- assert_is_type(func_type, FUNCTION_TYPE);
- const_tree ret_type = TREE_TYPE(func_type);
- gcc_assert(ret_type);
- update_escape_info(ret_type, types, reason, calc);
-}
-
-static void
-mark_escaping_function(ptrset_t &types, typemap &calc, cgraph_node *cnode)
-{
- gcc_assert(cnode);
- const bool is_escaping = is_function_escaping(cnode);
-#ifdef OPTIMIZED
- if (!is_escaping) return;
-#endif
-
- Reason reason1 {};
- reason1.is_escaping = is_escaping;
- reason1.parameter_is_visible = is_escaping;
- mark_escaping_parameters(types, calc, cnode, reason1);
-
- Reason reason2 {};
- reason2.is_escaping = is_escaping;
- reason2.return_is_visible = is_escaping;
- mark_escaping_return_type(types, calc, cnode, reason2);
-}
-
-static void
-calculate_escaping_types_from_cast(ptrset_t &types, typemap &calc, gimple *stmt)
-{
- is_gimple_code(stmt, GIMPLE_ASSIGN);
- const_tree lhs = gimple_assign_lhs(stmt);
- gcc_assert(lhs);
- const_tree rhs = gimple_assign_rhs1(stmt);
- gcc_assert(rhs);
-}
-
-static void
-calculate_escaping_types_from_assign_lhs(ptrset_t &types, typemap &calc, gimple *stmt)
-{
- is_gimple_code(stmt, GIMPLE_ASSIGN);
- const_tree lhs = gimple_assign_lhs(stmt);
- gcc_assert(lhs);
- Reason reason {};
- update_escape_info_expr(types, calc, lhs, reason);
-}
-
-static void
-calculate_escaping_types_from_assign_rhs3(ptrset_t &types, typemap &calc, gimple *stmt)
-{
- is_gimple_rhs_class(stmt, GIMPLE_TERNARY_RHS);
- const_tree rhs = gimple_assign_rhs3(stmt);
- gcc_assert(rhs);
- Reason reason {};
- update_escape_info_expr(types, calc, rhs, reason);
-}
-
-static void
-calculate_escaping_types_from_assign_rhs2(ptrset_t &types, typemap &calc, gimple *stmt)
-{
- const_tree rhs = gimple_assign_rhs2(stmt);
- gcc_assert(rhs);
- Reason reason {};
- update_escape_info_expr(types, calc, rhs, reason);
-}
-
-static void
-calculate_escaping_types_from_assign_rhs1(ptrset_t &types, typemap &calc, gimple *stmt)
-{
- const_tree rhs = gimple_assign_rhs1(stmt);
- gcc_assert(rhs);
- Reason reason {};
- update_escape_info_expr(types, calc, rhs, reason);
-}
-
-static void
-calculate_escaping_types_from_assign(ptrset_t &types, typemap &calc, gimple *stmt)
-{
- is_gimple_code(stmt, GIMPLE_ASSIGN);
- calculate_escaping_types_from_assign_lhs(types, calc, stmt);
- // If it is a cast, we must look at the lhs and the rhs...
- const enum gimple_rhs_class gclass = gimple_assign_rhs_class(stmt);
- switch(gclass)
- {
- case GIMPLE_TERNARY_RHS:
- calculate_escaping_types_from_assign_rhs3(types, calc, stmt);
- /* fall-through */
- case GIMPLE_BINARY_RHS:
- calculate_escaping_types_from_assign_rhs2(types, calc, stmt);
- /* fall-through */
- case GIMPLE_UNARY_RHS:
- case GIMPLE_SINGLE_RHS:
- calculate_escaping_types_from_assign_rhs1(types, calc, stmt);
- calculate_escaping_types_from_cast(types, calc, stmt);
- break;
- default:
- gcc_unreachable();
- break;
- }
-}
-
-static void
-calculate_escaping_types_from_call_lhs(ptrset_t &types, typemap &calc, undefset &undef, gimple *stmt)
-{
- gcall *call = dyn_cast<gcall*>(stmt);
- if (!call) return;
-
- const_tree lhs = gimple_call_lhs(stmt);
- if (!lhs) return;
-
- tree fn = gimple_call_fndecl(stmt);
- const bool is_undefined = undef.find(fn) != undef.end();
-#ifdef OPTIMIZED
- if (!is_undefined) return;
-#endif
-
- Reason reason {};
- reason.is_escaping = is_undefined;
- reason.return_is_visible = is_undefined;
- update_escape_info_expr(types, calc, lhs, reason);
-}
-
-static void
-calculate_escaping_types_from_call_rhs(ptrset_t &types, typemap &calc, undefset &undef, gimple *stmt)
-{
-
- tree fn = gimple_call_fndecl(stmt);
- 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);
- // What about gcov?
-
- Reason reason {};
- reason.is_escaping = is_undefined;
- reason.parameter_is_visible = is_undefined;
-
- unsigned num_args = gimple_call_num_args(stmt);
- for (unsigned i = 0; i < num_args; 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);
- }
-}
-
-static void
-calculate_escaping_types_from_call(ptrset_t &types, typemap &calc, undefset &undef, gimple *stmt)
-{
- is_gimple_code(stmt, GIMPLE_CALL);
- gcall *call = dyn_cast<gcall*>(stmt);
- tree fn = gimple_call_fndecl(stmt);
-
- const bool in_set = undef.find(fn) != undef.end();
-#ifdef OPTIMIZED
- if (!in_set) return;
-#endif
-
- calculate_escaping_types_from_call_lhs(types, calc, undef, stmt);
- calculate_escaping_types_from_call_rhs(types, calc, undef, stmt);
-}
-
-static void
-calculate_escaping_types_from_cond_lhs(ptrset_t &types, typemap &calc, gimple *stmt)
-{
- is_gimple_code(stmt, GIMPLE_COND);
- const_tree lhs = gimple_cond_lhs(stmt);
- gcc_assert(lhs);
- Reason reason {};
- update_escape_info_expr(types, calc, lhs, reason);
-}
-
-static void
-calculate_escaping_types_from_cond_rhs(ptrset_t &types, typemap &calc, gimple *stmt)
-{
- is_gimple_code(stmt, GIMPLE_COND);
- const_tree rhs = gimple_cond_rhs(stmt);
- Reason reason {};
- update_escape_info_expr(types, calc, rhs, reason);
-}
-
-static void
-calculate_escaping_types_from_cond(ptrset_t &types, typemap &calc, gimple *stmt)
-{
- is_gimple_code(stmt, GIMPLE_COND);
- calculate_escaping_types_from_cond_lhs(types, calc, stmt);
- calculate_escaping_types_from_cond_rhs(types, calc, stmt);
-}
-
-static void
-calculate_escaping_types_from_return(ptrset_t &types, typemap &calc, gimple *stmt)
-{
- is_gimple_code(stmt, GIMPLE_RETURN);
- const_tree retval = gimple_return_retval(stmt);
- if (!retval) return;
-
- Reason reason {};
- update_escape_info_expr(types, calc, retval, reason);
-}
-
-static void
-calculate_escaping_types_from_stmt(ptrset_t &types, typemap &calc, undefset &undef, gimple *stmt)
-{
- // Should be the same as ipa-type-collector.c
- // Otherwise, we might be skipping exploring some paths...
- gcc_assert(stmt);
- const enum gimple_code code = gimple_code (stmt);
- switch (code)
- {
- case GIMPLE_ASSIGN:
- calculate_escaping_types_from_assign(types, calc, stmt);
- break;
- case GIMPLE_CALL:
- calculate_escaping_types_from_call(types, calc, undef, stmt);
- break;
- case GIMPLE_COND:
- calculate_escaping_types_from_cond(types, calc, stmt);
- break;
- case GIMPLE_RETURN:
- calculate_escaping_types_from_return(types, calc, stmt);
- break;
- case GIMPLE_LABEL:
- case GIMPLE_PREDICT:
- case GIMPLE_DEBUG:
- case GIMPLE_SWITCH:
-#ifdef FUZZ_MODE
- gcc_unreachable();
-#endif
- break;
- default:
- {
- const char* name = gimple_code_name[code];
- log("gimple code name %s\n", name);
- gcc_unreachable();
- }
- break;
- }
-}
-
-static void
-calculate_escaping_types_from_bb(ptrset_t &types, typemap &calc, undefset &undef, basic_block bb)
-{
- gcc_assert(bb);
- for (auto gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi))
- {
- gimple *stmt = gsi_stmt(gsi);
- calculate_escaping_types_from_stmt(types, calc, undef, stmt);
- }
-}
-
-static void
-calculate_escaping_types_from_cnode(ptrset_t &types, typemap &calc, cgraph_node *cnode, undefset &undef)
-{
- gcc_assert(cnode);
- cnode->get_untransformed_body();
- const_tree decl = cnode->decl;
- gcc_assert(decl);
- function *func = DECL_STRUCT_FUNCTION(decl);
- gcc_assert(func);
- basic_block bb = NULL;
- push_cfun(func);
- FOR_EACH_BB_FN(bb, func)
- {
- calculate_escaping_types_from_bb(types, calc, undef, bb);
- }
- pop_cfun();
-}
-
-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);
- const_tree decl = cnode->decl;
- gcc_assert(decl);
- function *func = DECL_STRUCT_FUNCTION(decl);
- gcc_assert(func);
- Reason reason {};
- const_tree func_type = TREE_TYPE(decl);
- assert_is_type(func_type, FUNCTION_TYPE);
- update_escape_info_expr(types, calc, decl, reason);
- if (types.in_points_to_record(func_type)) update_escape_info(func_type, types, reason, calc);
- int i = 0;
- tree var_decl = NULL;
- FOR_EACH_LOCAL_DECL(func, i, var_decl)
- {
- gcc_assert(var_decl);
- update_escape_info_expr(types, calc, var_decl, reason);
- }
-}
-
-
-
-static void
-calculate_escaping_functions(ptrset_t &types, typemap &calc)
-{
- cgraph_node *cnode = NULL;
- undefset undefined_functions;
- FOR_EACH_FUNCTION(cnode)
- {
- gcc_assert(cnode);
- const bool filter = filter_known_function(cnode);
- if (filter) continue;
-
- const_tree decl = cnode->decl;
- gcc_assert(decl);
- undefined_functions.insert(decl);
- }
-
- FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(cnode)
- {
- gcc_assert(cnode);
- cnode->get_untransformed_body();
- const_tree decl = cnode->decl;
- gcc_assert(decl);
- 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)
- {
- gcc_assert(cnode);
- calculate_escaping_types_from_cnode(types, calc, cnode, undefined_functions);
- }
-}
-
-static void
-calculate_escaping_types(ptrset_t &types, typemap &calc)
-{
- calculate_escaping_types_globals(types, calc);
- calculate_escaping_functions(types, calc);
-}
-
-
static void
place_escaping_types_in_set(ptrset_t &types, typemap &calc)
{
@@ -678,22 +241,6 @@ print_escaping_types_in_set(ptrset_t &types)
}
-static ExprEscaper *exprEscaperGlobal;
-static TypeEscaper *typeEscaperGlobal;
-
-static void
-update_escape_info( const_tree type, ptrset_t &types, Reason reason, typemap &calc)
-{
- typeEscaperGlobal->update(type, reason);
-}
-
-static void
-update_escape_info_expr(ptrset_t &types, typemap &calc, const_tree expr, Reason reason)
-{
- exprEscaperGlobal->update(expr, reason);
-}
-
-
static unsigned int
iphw_execute()
{
@@ -702,15 +249,14 @@ iphw_execute()
collector.walk();
ptrset_t types = collector.get_pointer_set();
- ExprEscaper exprEscaper(types);
- exprEscaperGlobal = &exprEscaper;
- typeEscaperGlobal = &exprEscaper.typeEscaper;
+ GimpleEscaper gimpleEscaper(types);
+ gimpleEscaper.walk();
typemap eacalc; // Escape Analysis Calculation
// Intermediate results
// Do not read escape analysis results from here
- calculate_escaping_types(types, eacalc);
- place_escaping_types_in_set(types, typeEscaperGlobal->calc);
+ //calculate_escaping_types(types, eacalc);
+ place_escaping_types_in_set(types, gimpleEscaper.exprEscaper.typeEscaper.calc);
fix_escaping_types_in_set(types);
print_escaping_types_in_set(types);
sanity_check_escape_xor_not(types);
diff --git a/gcc/type-escaper.c b/gcc/type-escaper.c
new file mode 100644
index 00000000000..32d39611ea1
--- /dev/null
+++ b/gcc/type-escaper.c
@@ -0,0 +1,121 @@
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "tree.h"
+#include "gimple-expr.h"
+#include "predict.h"
+#include "alloc-pool.h"
+#include "tree-pass.h"
+#include "cgraph.h"
+#include "diagnostic.h"
+#include "fold-const.h"
+#include "gimple-fold.h"
+#include "symbol-summary.h"
+#include "tree-vrp.h"
+#include "ipa-prop.h"
+#include "tree-pretty-print.h"
+#include "tree-inline.h"
+#include "ipa-fnsummary.h"
+#include "ipa-utils.h"
+#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>
+#include "types-inlines.h"
+
+#include "type-escaper.hpp"
+
+bool
+TypeEscaper::is_memoized(const_tree t)
+{
+ const bool in_set = calc.find(t) != calc.end();
+ if (!in_set) return false;
+
+ const bool will_not_escape = !_reason.is_escaping;
+ if (will_not_escape) return true;
+
+ const bool already_escaping = in_set && calc[t].is_escaping;
+ if (already_escaping) return true;
+
+ return false;
+}
+
+void
+TypeEscaper::update(const_tree t, Reason r)
+{
+ gcc_assert(t);
+ _reason = r;
+ walk(t);
+}
+
+void
+TypeEscaper::_update(const_tree t)
+{
+ gcc_assert(t);
+ // assert type is in universe
+ const bool already_in_typemap = calc.find(t) != calc.end();
+ already_in_typemap ? calc[t] |= _reason : calc[t] = _reason;
+}
+
+void
+TypeEscaper::_walk_array_pre(const_tree t)
+{
+ _update(t);
+}
+
+void
+TypeEscaper::_walk_pointer_pre(const_tree t)
+{
+ _update(t);
+}
+
+void
+TypeEscaper::_walk_reference_pre(const_tree t)
+{
+ _update(t);
+}
+
+void
+TypeEscaper::_walk_record_pre(const_tree t)
+{
+ _update(t);
+}
+
+void
+TypeEscaper::_walk_union_pre(const_tree t)
+{
+ _inside_union++;
+ bool is_escaping = _inside_union > 0;
+ _update(t);
+ // After us... so that we can see what is our previous value
+ _reason.type_is_in_union |= is_escaping;
+ _reason.is_escaping |= is_escaping;
+}
+
+void
+TypeEscaper::_walk_union_post(const_tree t)
+{
+ _inside_union--;
+ Reason prev = calc[t];
+ _update(t);
+ _reason = prev;
+}
+
+void
+TypeEscaper::_walk_function_pre(const_tree t)
+{
+ _update(t);
+}
+
+void
+TypeEscaper::_walk_method_pre(const_tree t)
+{
+ _update(t);
+}
diff --git a/gcc/type-escaper.hpp b/gcc/type-escaper.hpp
index 14d695bf785..ccd7534e293 100644
--- a/gcc/type-escaper.hpp
+++ b/gcc/type-escaper.hpp
@@ -1,13 +1,15 @@
#pragma once
+#include "type-walker.hpp"
#include "ipa-prototype.h"
+#include "collect-types.h"
class TypeEscaper : public TypeWalker
{
public:
- TypeEscaper(ptrset_t p) : _inside_union(0), _ptrset(p) {};
+ TypeEscaper(ptrset_t &p) : _inside_union(0), _ptrset(p) {};
void update(const_tree t, Reason r);
- ptrset_t _ptrset;
+ ptrset_t &_ptrset;
typemap calc;
private:
virtual void _walk_pointer_pre(const_tree t);
@@ -24,90 +26,3 @@ private:
void _update(const_tree t);
};
-bool
-TypeEscaper::is_memoized(const_tree t)
-{
- const bool in_set = calc.find(t) != calc.end();
- if (!in_set) return false;
-
- const bool will_not_escape = !_reason.is_escaping;
- if (will_not_escape) return true;
-
- const bool already_escaping = in_set && calc[t].is_escaping;
- if (already_escaping) return true;
-
- return false;
-}
-
-void
-TypeEscaper::update(const_tree t, Reason r)
-{
- gcc_assert(t);
- _reason = r;
- walk(t);
-}
-
-void
-TypeEscaper::_update(const_tree t)
-{
- gcc_assert(t);
- // assert type is in universe
- const bool already_in_typemap = calc.find(t) != calc.end();
- already_in_typemap ? calc[t] |= _reason : calc[t] = _reason;
-}
-
-void
-TypeEscaper::_walk_array_pre(const_tree t)
-{
- _update(t);
-}
-
-void
-TypeEscaper::_walk_pointer_pre(const_tree t)
-{
- _update(t);
-}
-
-void
-TypeEscaper::_walk_reference_pre(const_tree t)
-{
- _update(t);
-}
-
-void
-TypeEscaper::_walk_record_pre(const_tree t)
-{
- _update(t);
-}
-
-void
-TypeEscaper::_walk_union_pre(const_tree t)
-{
- _inside_union++;
- bool is_escaping = _inside_union > 0;
- _update(t);
- // After us... so that we can see what is our previous value
- _reason.type_is_in_union |= is_escaping;
- _reason.is_escaping |= is_escaping;
-}
-
-void
-TypeEscaper::_walk_union_post(const_tree t)
-{
- _inside_union--;
- Reason prev = calc[t];
- _update(t);
- _reason = prev;
-}
-
-void
-TypeEscaper::_walk_function_pre(const_tree t)
-{
- _update(t);
-}
-
-void
-TypeEscaper::_walk_method_pre(const_tree t)
-{
- _update(t);
-}