From 7492af8c8acefcc10175f8518dc83735c16380d0 Mon Sep 17 00:00:00 2001 From: Erick Ochoa Date: Wed, 3 Jun 2020 13:52:46 +0200 Subject: type escaper --- gcc/collect-types.c | 3 -- gcc/ipa-hello-world.c | 5 ++- gcc/ipa-hello-world.h | 6 ++- gcc/type-escaper.hpp | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 gcc/type-escaper.hpp 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 #include +#include "type-escaper.hpp" //#define OPTIMIZED #define SANITY_CHECKS @@ -79,7 +80,6 @@ Reason::operator|=(const Reason &other) return *this; } -typedef std::map 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 + 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 typemap; + +typedef std::map 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); +} -- cgit v1.2.3