diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-04 16:08:48 +0200 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-04 16:08:48 +0200 |
commit | efb64d6f99685ab548ac60183dfcddec09c01960 (patch) | |
tree | 441fe40ff506aa678b3cc543459ee8c364cccc41 | |
parent | 3157406ba5fde2fcbd6a212ac5476b2697f6e0ce (diff) |
gimple-escaper
-rw-r--r-- | gcc/collect-types.c | 2 | ||||
-rw-r--r-- | gcc/expr-escaper.hpp | 6 | ||||
-rw-r--r-- | gcc/gimple-collector.c | 86 | ||||
-rw-r--r-- | gcc/gimple-collector.hpp | 8 | ||||
-rw-r--r-- | gcc/gimple-escaper.c | 81 | ||||
-rw-r--r-- | gcc/gimple-escaper.hpp | 19 | ||||
-rw-r--r-- | gcc/gimple-walker.c | 121 | ||||
-rw-r--r-- | gcc/gimple-walker.hpp | 33 | ||||
-rw-r--r-- | gcc/ipa-prototype.c | 20 | ||||
-rw-r--r-- | gcc/type-escaper.hpp | 8 |
10 files changed, 243 insertions, 141 deletions
diff --git a/gcc/collect-types.c b/gcc/collect-types.c index 81d4d740cdd..b3febdd57d7 100644 --- a/gcc/collect-types.c +++ b/gcc/collect-types.c @@ -41,10 +41,10 @@ points_to_record_sets_s::insert(const_tree type, bool in_points_to_record) gcc_assert(type); this->universe.insert(type); in_points_to_record ? this->points_to_record.insert(type) : this->complement.insert(type); - // let's just double check... const bool in_points_to_set = this->in_points_to_record(type); const bool in_complement = this->in_complement(type); const bool _xor = in_points_to_set != in_complement; + // sanity check... gcc_assert(_xor); } diff --git a/gcc/expr-escaper.hpp b/gcc/expr-escaper.hpp index cae97ccea11..4455d50bef9 100644 --- a/gcc/expr-escaper.hpp +++ b/gcc/expr-escaper.hpp @@ -4,9 +4,9 @@ class ExprEscaper : public ExprWalker { public: - ExprEscaper() {}; + ExprEscaper(ptrset_t types) : typeEscaper(types) {}; void update(const_tree t, Reason r); - static TypeEscaper *typeEscaper; + TypeEscaper typeEscaper; private: Reason _r; virtual void _walk_pre(const_tree e); @@ -25,7 +25,7 @@ ExprEscaper::_walk_pre(const_tree e) { const_tree t = TREE_TYPE(e); gcc_assert(t); - typeEscaper->update(t, _r); + typeEscaper.update(t, _r); } diff --git a/gcc/gimple-collector.c b/gcc/gimple-collector.c index 1f9f7162762..2e23fc1e3ab 100644 --- a/gcc/gimple-collector.c +++ b/gcc/gimple-collector.c @@ -42,91 +42,9 @@ #include "gimple-collector.hpp" void -GimpleTypeCollector::collect() +GimpleTypeCollector::_walk_pre(const_tree t) { - _collect_globals(); - - cgraph_node *node = NULL; - long unsigned i = 0; - FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) - { - node->get_untransformed_body(); - collect(node); - } -} - -void -GimpleTypeCollector::_collect_globals() -{ - varpool_node *vnode = NULL; - unsigned long i = 0; - FOR_EACH_VARIABLE(vnode) - { - _collect_global(vnode); - } -} - -void -GimpleTypeCollector::_collect_global(varpool_node *vnode) -{ - gcc_assert(vnode); - struct ipa_ref *ref = NULL; - for (unsigned i = 0; vnode->iterate_referring(i, ref); i++) - { - tree var_decl = vnode->decl; - exprCollector.walk(var_decl); - } -} - -void -GimpleTypeCollector::collect(cgraph_node *cnode) -{ - gcc_assert(cnode); - _collect_decl(cnode); - _collect_locals(cnode); - _collect_ssa_names(cnode); - walk(cnode); -} - -void -GimpleTypeCollector::_collect_decl(cgraph_node *cnode) -{ - const_tree decl = cnode->decl; - gcc_assert(decl); - exprCollector.walk(decl); -} - -void -GimpleTypeCollector::_collect_ssa_names(cgraph_node *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); - FOR_EACH_SSA_NAME(i, ssa_name, cfun) - { - gcc_assert(ssa_name); - exprCollector.walk(ssa_name); - } -} - -void -GimpleTypeCollector::_collect_locals(cgraph_node *cnode) -{ - const_tree decl = cnode->decl; - gcc_assert(decl); - function *func = DECL_STRUCT_FUNCTION(decl); - gcc_assert(func); - int i = 0; - tree var_decl = NULL; - FOR_EACH_LOCAL_DECL(func, i, var_decl) - { - gcc_assert(var_decl); - exprCollector.walk(decl); - } + exprCollector.walk(t); } void diff --git a/gcc/gimple-collector.hpp b/gcc/gimple-collector.hpp index 30a5f61846f..23b5fe1276f 100644 --- a/gcc/gimple-collector.hpp +++ b/gcc/gimple-collector.hpp @@ -9,15 +9,9 @@ private: ExprCollector exprCollector; public: GimpleTypeCollector() {}; - void collect(); ptrset_t get_pointer_set() { return exprCollector.get_pointer_set(); } private: - void _collect_globals(); - void _collect_global(varpool_node *); - void collect(cgraph_node *cnode); - void _collect_decl(cgraph_node *); - void _collect_locals(cgraph_node *); - void _collect_ssa_names(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; diff --git a/gcc/gimple-escaper.c b/gcc/gimple-escaper.c new file mode 100644 index 00000000000..20a71e1a476 --- /dev/null +++ b/gcc/gimple-escaper.c @@ -0,0 +1,81 @@ +#include "gimple-escaper.hpp" + +void +GimpleEscaper::_init() +{ + cgraph_node *cnode = NULL; + 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.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.erase(decl); + } +} + +void +GimpleEscaper::_walk_pre(const_tree t) +{ + // Is any global variable escaping? + Reason reason; + exprEscaper.update(expr, reason); +} + +void +GimpleEscaper::_walk_pre(gassign *s) +{ + Reason reason; + exprEscaper.update(expr, reason); +} + +void +GimpleEscaper::_walk_pre(greturn *s) +{ + Reason reason; + exprEscaper.update(expr, reason); +} + +void +GimpleEscaper::_walk_pre(gcond *s) +{ + Reason reason; + exprEscaper.update(expr, reason); +} + +void +GimpleEscaper::_walk_pre(gcall *s) +{ + tree fn = gimple_call_fndecl(s); + const bool is_undefined = undefined.find(fn) != undefined.end(); + + Reason arg_reason; + 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++) + { + const_tree a = gimple_call_arg(s, i); + gcc_assert(a); + exprEscaper.update(a, arg_reason); + } + + 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 new file mode 100644 index 00000000000..38259a6393f --- /dev/null +++ b/gcc/gimple-escaper.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "gimple-walker.hpp" +#include "expr-escaper.hpp" + +class GimpleEscaper : public GimpleWalker +{ +public: + GimpleEscaper(ptrset_t types) : exprEscaper(types) { _init() }; +private: + typedef std::set<const_tree> undefset; + undefset undefined; + ExprEscaper exprEscaper; + 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/gimple-walker.c b/gcc/gimple-walker.c index 2f4edf1c6e1..4735960c076 100644 --- a/gcc/gimple-walker.c +++ b/gcc/gimple-walker.c @@ -42,7 +42,91 @@ #include "gimple-walker.hpp" void -GimpleWalker::walk(cgraph_node* cnode) +GimpleWalker::walk() +{ + _walk_globals(); + + cgraph_node *node = NULL; + long unsigned i = 0; + FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) + { + node->get_untransformed_body(); + _walk_cnode(node); + } +} + +void +GimpleWalker::_walk_globals() +{ + varpool_node *vnode = NULL; + unsigned long i = 0; + FOR_EACH_VARIABLE(vnode) + { + gcc_assert(vnode); + struct ipa_ref *ref = NULL; + for (unsigned i = 0; vnode->iterate_referring(i, ref); i++) + { + tree var_decl = vnode->decl; + walk(var_decl); + } + } +} + +void +GimpleWalker::_walk_ssa_names(cgraph_node *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); + FOR_EACH_SSA_NAME(i, ssa_name, cfun) + { + gcc_assert(ssa_name); + walk(ssa_name); + } + pop_cfun(); +} + +void +GimpleWalker::_walk_cnode(cgraph_node *cnode) +{ + gcc_assert(cnode); + _walk_decl(cnode); + _walk_locals(cnode); + _walk_ssa_names(cnode); + _walk_bb(cnode); +} + +void +GimpleWalker::_walk_decl(cgraph_node *cnode) +{ + const_tree decl = cnode->decl; + gcc_assert(decl); + walk(decl); +} + +void +GimpleWalker::_walk_locals(cgraph_node *cnode) +{ + const_tree decl = cnode->decl; + gcc_assert(decl); + function *func = DECL_STRUCT_FUNCTION(decl); + gcc_assert(func); + int i = 0; + tree var_decl = NULL; + FOR_EACH_LOCAL_DECL(func, i, var_decl) + { + gcc_assert(var_decl); + walk(var_decl); + } +} + + +void +GimpleWalker::_walk_bb(cgraph_node* cnode) { gcc_assert(cnode); cnode->get_untransformed_body(); @@ -54,13 +138,13 @@ GimpleWalker::walk(cgraph_node* cnode) push_cfun(func); FOR_EACH_BB_FN(bb, func) { - walk(bb); + _walk(bb); } pop_cfun(); } void -GimpleWalker::walk(basic_block bb) +GimpleWalker::_walk(basic_block bb) { gcc_assert(bb); for (auto gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) @@ -84,7 +168,7 @@ GimpleWalker::_walk(gimple *stmt) gcc_assert(stmt); #define GimpleWalkerWalk(type) \ - if (type *s = dyn_cast<type *>(stmt)) \ + if (type s = dyn_cast< type >(stmt)) \ { \ _walk_pre(stmt); \ walk(s); \ @@ -92,12 +176,12 @@ GimpleWalker::_walk(gimple *stmt) return; \ } - GimpleWalkerWalk(gassign); - GimpleWalkerWalk(greturn); - GimpleWalkerWalk(gcond); - GimpleWalkerWalk(gcall); - GimpleWalkerWalk(glabel); - GimpleWalkerWalk(gswitch); + GimpleWalkerWalk(gassign*); + GimpleWalkerWalk(greturn*); + GimpleWalkerWalk(gcond*); + GimpleWalkerWalk(gcall*); + GimpleWalkerWalk(glabel*); + GimpleWalkerWalk(gswitch*); const enum gimple_code code = gimple_code (stmt); @@ -113,7 +197,7 @@ GimpleWalker::_walk(gimple *stmt) #define GimpleWalkerFuncDef(type) \ void \ -GimpleWalker::walk (type *e) \ +GimpleWalker::walk (type e) \ { \ _walk_pre (e); \ _walk (e); \ @@ -121,13 +205,14 @@ GimpleWalker::walk (type *e) \ } \ \ void \ -GimpleWalker::_walk(type *e) \ +GimpleWalker::_walk (type e) \ { \ } -GimpleWalkerFuncDef(gassign); -GimpleWalkerFuncDef(greturn); -GimpleWalkerFuncDef(gcond); -GimpleWalkerFuncDef(gcall); -GimpleWalkerFuncDef(glabel); -GimpleWalkerFuncDef(gswitch); +GimpleWalkerFuncDef(const_tree); +GimpleWalkerFuncDef(gassign *); +GimpleWalkerFuncDef(greturn *); +GimpleWalkerFuncDef(gcond *); +GimpleWalkerFuncDef(gcall *); +GimpleWalkerFuncDef(glabel *); +GimpleWalkerFuncDef(gswitch *); diff --git a/gcc/gimple-walker.hpp b/gcc/gimple-walker.hpp index 40d92257efe..7604cb7f505 100644 --- a/gcc/gimple-walker.hpp +++ b/gcc/gimple-walker.hpp @@ -4,24 +4,31 @@ class GimpleWalker { public: GimpleWalker() {}; - void walk(cgraph_node *cnode); + void walk(); private: - void walk(basic_block bb); + void _walk_globals(); + void _walk_ssa_names(cgraph_node *cnode); + void _walk_cnode(cgraph_node *cnode); + void _walk_decl(cgraph_node *cnode); + void _walk_locals(cgraph_node *cnode); + void _walk_bb(cgraph_node *cnode); + void _walk(basic_block bb); #define GimpleWalkerFuncDecl(type) \ - virtual void _walk_pre(type *stmt) {}; \ - void walk(type *stmt); \ - void _walk(type *stmt); \ - virtual void _walk_post(type *stmt) {} + virtual void _walk_pre(type stmt) {}; \ + void walk(type stmt); \ + void _walk(type stmt); \ + virtual void _walk_post(type stmt) {} - GimpleWalkerFuncDecl(gimple); - GimpleWalkerFuncDecl(gassign); - GimpleWalkerFuncDecl(greturn); - GimpleWalkerFuncDecl(gcond); - GimpleWalkerFuncDecl(gcall); - GimpleWalkerFuncDecl(glabel); - GimpleWalkerFuncDecl(gswitch); + GimpleWalkerFuncDecl(const_tree); + GimpleWalkerFuncDecl(gimple*); + GimpleWalkerFuncDecl(gassign*); + GimpleWalkerFuncDecl(greturn*); + GimpleWalkerFuncDecl(gcond*); + GimpleWalkerFuncDecl(gcall*); + GimpleWalkerFuncDecl(glabel*); + GimpleWalkerFuncDecl(gswitch*); }; diff --git a/gcc/ipa-prototype.c b/gcc/ipa-prototype.c index 8288f6d23f3..06f0de6f1f4 100644 --- a/gcc/ipa-prototype.c +++ b/gcc/ipa-prototype.c @@ -678,22 +678,19 @@ print_escaping_types_in_set(ptrset_t &types) } -ptrset_t *TypeEscaper::types = NULL; -typemap TypeEscaper::calc; -static TypeEscaper _typeEscaper; -static ExprEscaper exprEscaper; -TypeEscaper *ExprEscaper::typeEscaper = NULL; +static ExprEscaper *exprEscaperGlobal; +static TypeEscaper *typeEscaperGlobal; static void update_escape_info( const_tree type, ptrset_t &types, Reason reason, typemap &calc) { - _typeEscaper.update(type, reason); + typeEscaperGlobal->update(type, reason); } static void update_escape_info_expr(ptrset_t &types, typemap &calc, const_tree expr, Reason reason) { - exprEscaper.update(expr, reason); + exprEscaperGlobal->update(expr, reason); } @@ -702,17 +699,18 @@ iphw_execute() { GimpleTypeCollector collector; - collector.collect(); + collector.walk(); ptrset_t types = collector.get_pointer_set(); - TypeEscaper::types = &types; - ExprEscaper::typeEscaper = &_typeEscaper; + ExprEscaper exprEscaper(types); + exprEscaperGlobal = &exprEscaper; + typeEscaperGlobal = &exprEscaper.typeEscaper; 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, _typeEscaper.calc); + place_escaping_types_in_set(types, typeEscaperGlobal->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.hpp b/gcc/type-escaper.hpp index c0bea8383fa..14d695bf785 100644 --- a/gcc/type-escaper.hpp +++ b/gcc/type-escaper.hpp @@ -5,10 +5,10 @@ class TypeEscaper : public TypeWalker { public: - TypeEscaper() : _inside_union(0) {}; + TypeEscaper(ptrset_t p) : _inside_union(0), _ptrset(p) {}; void update(const_tree t, Reason r); - static ptrset_t *types; - static typemap calc; + ptrset_t _ptrset; + typemap calc; private: virtual void _walk_pointer_pre(const_tree t); virtual void _walk_reference_pre(const_tree t); @@ -42,7 +42,7 @@ TypeEscaper::is_memoized(const_tree t) void TypeEscaper::update(const_tree t, Reason r) { - gcc_assert(t && types); + gcc_assert(t); _reason = r; walk(t); } |