diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-16 13:47:25 +0200 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-16 13:47:25 +0200 |
commit | 5986d24b5593fad84caa8b3270f6bab95fad6985 (patch) | |
tree | 86200be25d8352cd74068a51881acd60cc11ba9a | |
parent | 606a16466ebebff9715e159651ea123778cc2e57 (diff) |
removes escaping types from reorg
-rw-r--r-- | gcc/ipa-type-escape-analysis.c | 22 | ||||
-rw-r--r-- | gcc/type-reconstructor.c | 81 | ||||
-rw-r--r-- | gcc/type-reconstructor.hpp | 6 |
3 files changed, 77 insertions, 32 deletions
diff --git a/gcc/ipa-type-escape-analysis.c b/gcc/ipa-type-escape-analysis.c index bdd9f09fc3d..774a83fec52 100644 --- a/gcc/ipa-type-escape-analysis.c +++ b/gcc/ipa-type-escape-analysis.c @@ -178,6 +178,7 @@ collect_types() // We need to say that for all records on field_map... if two are equal // then we will need to mark OR the accesses to fields TypeIncompleteEquality equality; + bool has_fields_that_can_be_deleted = false; typedef std::set<unsigned> field_offsets_t; typedef std::map<const_tree, field_offsets_t> record_field_offset_map_t; record_field_offset_map_t record_field_offset_map; @@ -236,11 +237,16 @@ collect_types() const typeset &non_escaping = casting.non_escaping; + + std::vector<const_tree> to_erase; for (auto i = record_field_offset_map.begin(), e = record_field_offset_map.end(); i != e; ++i) { const_tree record = i->first; const bool in_set = non_escaping.find(record) != non_escaping.end(); - if (!in_set) continue; + if (!in_set) { + to_erase.push_back(record); + continue; + } field_offsets_t field_offset = i->second; for (tree field = TYPE_FIELDS(record); field; field = DECL_CHAIN(field)) @@ -254,28 +260,38 @@ collect_types() continue; } field_offset.insert(f_offset); + has_fields_that_can_be_deleted = true; log("%s.%s may be deleted\n", TypeStringifier::get_type_identifier(record).c_str(), TypeStringifier::get_field_identifier(field).c_str()); } record_field_offset_map[record] = field_offset; } + for (auto i = to_erase.begin(), e = to_erase.end(); i != e; ++i) + { + const_tree record = *i; + record_field_offset_map.erase(record); + } + + if (!has_fields_that_can_be_deleted) return; TypeReconstructor reconstructor(record_field_offset_map); + TypeStringifier stringifier; for (auto i = record_field_offset_map.cbegin(), e = record_field_offset_map.cend(); i != e; ++i) { const_tree record = i->first; + std::string name_from = stringifier.stringify(record); + log("record %s\n", name_from.c_str()); reconstructor.walk(record); } TypeReconstructor::reorg_record_map_t map = reconstructor.get_map(); - TypeStringifier stringifier; for (auto i = map.cbegin(), e = map.cend(); i != e; ++i) { const_tree from = i->first; const_tree to = i->second; std::string name_from = stringifier.stringify(from); - std::string name_to = stringifier.stringify(to); + std::string name_to = to ? stringifier.stringify(to) : std::string("NULL"); log("%s -> %s\n", name_from.c_str(), name_to.c_str()); } diff --git a/gcc/type-reconstructor.c b/gcc/type-reconstructor.c index 530569c074f..350d9bd4989 100644 --- a/gcc/type-reconstructor.c +++ b/gcc/type-reconstructor.c @@ -49,7 +49,6 @@ get_new_identifier(const_tree type) gcc_assert(!is_new_type); char *new_name; asprintf(&new_name, "%s.reorg", identifier); - log("old %s new %s\n", identifier, new_name); return get_identifier(new_name); } @@ -58,6 +57,8 @@ get_new_identifier(const_tree type) // // Invariant for all _post functions: // _reorg_map[TREE_TYPE(t)] != NULL +// unless TREE_TYPE(t) is not a type which points to a record +// a.k.a. no modifications // // To preserve invariant, we must include // the following at the end of all _post functions: @@ -80,16 +81,17 @@ TypeReconstructor::_walk_ARRAY_TYPE_post(const_tree t) { const_tree inner_type = TREE_TYPE(t); gcc_assert(inner_type); - tree inner_reorg_type = (tree)_reorg_map[inner_type]; - gcc_assert(inner_reorg_type); - tree t_reorg = (tree)_working_stack.top(); + const bool in_map = _reorg_map.find(inner_type) != _reorg_map.end(); + tree t_reorg = _working_stack.top(); _working_stack.pop(); + if (!in_map) return; + + tree inner_reorg_type = _reorg_map[inner_type]; TREE_TYPE(t_reorg) = inner_reorg_type; TYPE_NAME((tree)t_reorg) = get_new_identifier(t_reorg); _reorg_map[t] = t_reorg; - - + log("working type %s\n", t_reorg ? "t" : "f"); } void @@ -103,23 +105,19 @@ TypeReconstructor::_walk_POINTER_TYPE_pre(const_tree t) void TypeReconstructor::_walk_POINTER_TYPE_post(const_tree t) { - const bool already_changed = _reorg_map.find(t) != _reorg_map.end(); - const_tree modifications = _working_stack.top(); + tree t_reorg = _working_stack.top(); _working_stack.pop(); - if (already_changed) return; - tree tt = TREE_TYPE(t); - bool field_type_in_reorg_map = _reorg_map.find(tt) != _reorg_map.end(); - if (!field_type_in_reorg_map) { - TYPE_NAME((tree)modifications) = get_new_identifier(modifications); - _reorg_map[t] = modifications; - return; - } + const_tree inner_type = TREE_TYPE(t); + const bool in_map = _reorg_map.find(inner_type) != _reorg_map.end(); + // We are pointing to an integer or something like that. + if (!in_map) return; - tree tf = (tree)_reorg_map[tt]; - TREE_TYPE((tree)modifications) = tf; - TYPE_NAME((tree)modifications) = get_new_identifier(modifications); - _reorg_map[t] = modifications; + tree inner_type_reorg = _reorg_map[inner_type]; + TREE_TYPE((tree)t_reorg) = inner_type_reorg; + TYPE_NAME((tree)t_reorg) = get_new_identifier(t_reorg); + _reorg_map[t] = t_reorg;; + log("working type %s\n", t_reorg ? "t" : "f"); } void @@ -143,6 +141,34 @@ TypeReconstructor::_walk_RECORD_TYPE_pre(const_tree t) _eliminated_fields.push(vec2); } +void +TypeReconstructor::_walk_UNION_TYPE_pre(const_tree t) +{ + const bool in_map = _records.find(t) != _records.end(); + // The modifying stack let's us know if the current record + // type is being modified. + gcc_assert(!in_map); + _modifying.push(in_map); + + field_offsets_t empty; + _record_stack.push(in_map ? _records[t] : empty); + + // We really should only make a distinct type copy if + // it points to a pointer that will be rewritten... + _working_stack.push(build_distinct_type_copy((tree)t)); + + type_vector_t vec; + type_vector_t vec2; + _field_decls.push(vec); + _eliminated_fields.push(vec2); +} + +void +TypeReconstructor::_walk_UNION_TYPE_post(const_tree t) +{ + _walk_RECORD_TYPE_post(t); +} + void TypeReconstructor::_walk_RECORD_TYPE_post(const_tree t) @@ -156,7 +182,7 @@ TypeReconstructor::_walk_RECORD_TYPE_post(const_tree t) type_vector_t fields_to_eliminate = _eliminated_fields.top(); _eliminated_fields.pop(); _field_decls.pop(); - const_tree working_type = _working_stack.top(); + tree working_type = _working_stack.top(); _working_stack.pop(); _record_stack.pop(); const bool should_be_modified = _modifying.top(); @@ -175,8 +201,8 @@ TypeReconstructor::_walk_RECORD_TYPE_post(const_tree t) if (fields_to_keep.empty()) { - layout_type((tree)working_type); - TYPE_NAME((tree)working_type) = get_new_identifier(working_type); + layout_type(working_type); + TYPE_NAME(working_type) = get_new_identifier(working_type); _reorg_map[t] = working_type; return; } @@ -186,7 +212,7 @@ TypeReconstructor::_walk_RECORD_TYPE_post(const_tree t) bool field_type_in_reorg_map = _reorg_map.find(tf) != _reorg_map.end(); if (field_type_in_reorg_map) { - TREE_TYPE(f) = (tree) _reorg_map[tf]; + TREE_TYPE(f) = _reorg_map[tf]; } TYPE_FIELDS((tree)working_type) = f; unsigned s = fields_to_keep.size(); @@ -198,14 +224,15 @@ TypeReconstructor::_walk_RECORD_TYPE_post(const_tree t) field_type_in_reorg_map = _reorg_map.find(tf) != _reorg_map.end(); if (field_type_in_reorg_map) { - TREE_TYPE(current) = (tree) _reorg_map[tf]; + TREE_TYPE(current) = _reorg_map[tf]; } DECL_CHAIN(f) = current; f = current; } - layout_type((tree)working_type); - TYPE_NAME((tree)working_type) = get_new_identifier(working_type); + layout_type(working_type); + TYPE_NAME(working_type) = get_new_identifier(working_type); + log("working type %s\n", working_type ? "t" : "f"); _reorg_map[t] = working_type; } diff --git a/gcc/type-reconstructor.hpp b/gcc/type-reconstructor.hpp index 12260f9a48b..b8378897b1a 100644 --- a/gcc/type-reconstructor.hpp +++ b/gcc/type-reconstructor.hpp @@ -10,13 +10,13 @@ class TypeReconstructor : public TypeWalker { public: - typedef std::map<const_tree, const_tree> reorg_record_map_t; + typedef std::map<const_tree, tree> reorg_record_map_t; private: typedef std::set<unsigned> field_offsets_t; typedef std::map<const_tree, field_offsets_t> record_field_offset_map_t; typedef std::stack<bool> field_stack_t; typedef std::stack<field_offsets_t> record_stack_t; - typedef std::stack<const_tree> type_stack_t; + typedef std::stack<tree> type_stack_t; typedef std::vector<const_tree> type_vector_t; typedef std::stack<type_vector_t> type_vector_stack_t; typedef std::stack<bool> bool_stack_t; @@ -33,6 +33,8 @@ private: virtual void _walk_field_post(const_tree); virtual void _walk_RECORD_TYPE_pre(const_tree); virtual void _walk_RECORD_TYPE_post(const_tree); + virtual void _walk_UNION_TYPE_pre(const_tree); + virtual void _walk_UNION_TYPE_post(const_tree); virtual void _walk_ARRAY_TYPE_pre(const_tree); virtual void _walk_ARRAY_TYPE_post(const_tree); virtual void _walk_POINTER_TYPE_pre(const_tree); |