summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-16 13:47:25 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-16 13:47:25 +0200
commit5986d24b5593fad84caa8b3270f6bab95fad6985 (patch)
tree86200be25d8352cd74068a51881acd60cc11ba9a
parent606a16466ebebff9715e159651ea123778cc2e57 (diff)
removes escaping types from reorg
-rw-r--r--gcc/ipa-type-escape-analysis.c22
-rw-r--r--gcc/type-reconstructor.c81
-rw-r--r--gcc/type-reconstructor.hpp6
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);