summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-04 16:08:48 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-04 16:08:48 +0200
commitefb64d6f99685ab548ac60183dfcddec09c01960 (patch)
tree441fe40ff506aa678b3cc543459ee8c364cccc41
parent3157406ba5fde2fcbd6a212ac5476b2697f6e0ce (diff)
gimple-escaper
-rw-r--r--gcc/collect-types.c2
-rw-r--r--gcc/expr-escaper.hpp6
-rw-r--r--gcc/gimple-collector.c86
-rw-r--r--gcc/gimple-collector.hpp8
-rw-r--r--gcc/gimple-escaper.c81
-rw-r--r--gcc/gimple-escaper.hpp19
-rw-r--r--gcc/gimple-walker.c121
-rw-r--r--gcc/gimple-walker.hpp33
-rw-r--r--gcc/ipa-prototype.c20
-rw-r--r--gcc/type-escaper.hpp8
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);
}