summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-03 13:52:46 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-03 16:06:03 +0200
commit7492af8c8acefcc10175f8518dc83735c16380d0 (patch)
tree50e698b662a59387d512c6fff55c9902933fc63c
parent2d7e68c5921fdce1cca9ebcd4a3d883c6060db0e (diff)
type escaper
-rw-r--r--gcc/collect-types.c3
-rw-r--r--gcc/ipa-hello-world.c5
-rw-r--r--gcc/ipa-hello-world.h6
-rw-r--r--gcc/type-escaper.hpp113
4 files changed, 122 insertions, 5 deletions
diff --git a/gcc/collect-types.c b/gcc/collect-types.c
index 96ea3a656f2..77257a8b8e0 100644
--- a/gcc/collect-types.c
+++ b/gcc/collect-types.c
@@ -47,9 +47,6 @@ points_to_record_sets_s::insert(const_tree type, bool in_points_to_record)
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;
- if (!_xor) {
- log("points_to_record %s type %s != %s %s\n", in_points_to_record ? "t" : "f", in_points_to_set ? "t" : "f", in_complement ? "t": "f", name.c_str());
- }
gcc_assert(_xor);
}
diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-hello-world.c
index 3acab60d194..52ad819bc5b 100644
--- a/gcc/ipa-hello-world.c
+++ b/gcc/ipa-hello-world.c
@@ -39,6 +39,7 @@
#include "type-stringifier.hpp"
#include <map>
#include <vector>
+#include "type-escaper.hpp"
//#define OPTIMIZED
#define SANITY_CHECKS
@@ -79,7 +80,6 @@ Reason::operator|=(const Reason &other)
return *this;
}
-typedef std::map<const_tree, Reason> typemap;
static inline void
assert_type_is_in_universe(const_tree type, ptrset_t &types)
@@ -1036,12 +1036,15 @@ print_escaping_types_in_set(ptrset_t &types)
}
+ptrset_t *TypeEscaper::types = NULL;
+typemap TypeEscaper::calc;
static unsigned int
iphw_execute()
{
ptrset_t types;
TypeCollector::ptrset = &types;
+ TypeEscaper::types = &types;
collect_types(types);
typemap eacalc; // Escape Analysis Calculation
diff --git a/gcc/ipa-hello-world.h b/gcc/ipa-hello-world.h
index c55968162e3..77413d5c218 100644
--- a/gcc/ipa-hello-world.h
+++ b/gcc/ipa-hello-world.h
@@ -1,5 +1,7 @@
#pragma once
+#include <map>
+
struct Reason {
bool is_escaping : 1;
bool global_is_visible : 1;
@@ -14,4 +16,6 @@ struct Reason {
Reason() : is_escaping(0), global_is_visible(0), parameter_is_visible(0), type_is_casted(0), type_is_volatile(0), type_is_in_union(0) {};
};
-//typedef std::map<const_tree, Reason> typemap;
+
+typedef std::map<const_tree, Reason> typemap;
+
diff --git a/gcc/type-escaper.hpp b/gcc/type-escaper.hpp
new file mode 100644
index 00000000000..76a04d2642a
--- /dev/null
+++ b/gcc/type-escaper.hpp
@@ -0,0 +1,113 @@
+#pragma once
+
+#include "ipa-hello-world.h"
+
+class TypeEscaper : public TypeWalker
+{
+public:
+ TypeEscaper() : _inside_union(0) {};
+ void update(const_tree t, Reason r);
+ virtual void _walk_pointer_pre(const_tree t);
+ virtual void _walk_reference_pre(const_tree t);
+ virtual void _walk_array_pre(const_tree t);
+ virtual void _walk_record_pre(const_tree t);
+ virtual void _walk_union_pre(const_tree t);
+ virtual void _walk_union_post(const_tree t);
+ virtual void _walk_method_pre(const_tree t);
+ virtual void _walk_function_pre(const_tree t);
+ virtual bool is_memoized(const_tree t);
+ static ptrset_t *types;
+ static typemap calc;
+private:
+ unsigned _inside_union;
+ Reason _reason;
+ 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 && types);
+ _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);
+}