diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-04 16:48:24 +0200 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-04 16:48:24 +0200 |
commit | b49aa30869c09910acb6c6e83f37b7fec15b25c7 (patch) | |
tree | de9f3ded031e5346e12493d2813295c53252d211 | |
parent | efb64d6f99685ab548ac60183dfcddec09c01960 (diff) |
gimple-escaper
-rw-r--r-- | gcc/Makefile.in | 9 | ||||
-rw-r--r-- | gcc/expr-escaper.c | 52 | ||||
-rw-r--r-- | gcc/expr-escaper.hpp | 24 | ||||
-rw-r--r-- | gcc/gimple-escaper.c | 80 | ||||
-rw-r--r-- | gcc/gimple-escaper.hpp | 9 | ||||
-rw-r--r-- | gcc/ipa-prototype.c | 464 | ||||
-rw-r--r-- | gcc/type-escaper.c | 121 | ||||
-rw-r--r-- | gcc/type-escaper.hpp | 93 |
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); -} |