summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-16 16:24:26 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-16 16:24:26 +0200
commit5468db8b6e1d8220707fe2d9debbc09bd5f49159 (patch)
tree6a63e5f4effbf5a55eeccda13f72dc54dd629bad
parent5986d24b5593fad84caa8b3270f6bab95fad6985 (diff)
wip
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/expr-rewriter.c34
-rw-r--r--gcc/expr-rewriter.hpp15
-rw-r--r--gcc/gimple-rewriter.c64
-rw-r--r--gcc/gimple-rewriter.hpp19
-rw-r--r--gcc/ipa-type-escape-analysis.c11
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-04-layout-compile-0.c (renamed from gcc/testsuite/gcc.dg/ipa/ipa-structreorg-4-layout-compile-0.c)3
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-3-new-offsets-0.c15
-rw-r--r--gcc/type-reconstructor.c63
-rw-r--r--gcc/type-reconstructor.hpp3
10 files changed, 173 insertions, 56 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 7b7de74905b..a2acf92617d 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1419,6 +1419,8 @@ OBJS = \
expr-collector.o \
gimple-collector.o \
gimple-caster.o \
+ gimple-rewriter.o \
+ expr-rewriter.o \
type-escaper.o \
type-structural-equality.o \
type-structural-main-variant.o \
diff --git a/gcc/expr-rewriter.c b/gcc/expr-rewriter.c
new file mode 100644
index 00000000000..4ada49a3a7c
--- /dev/null
+++ b/gcc/expr-rewriter.c
@@ -0,0 +1,34 @@
+#include "expr-rewriter.hpp"
+#include "type-stringifier.hpp"
+#include <string>
+#include <map>
+
+void
+ExprTypeRewriter::_walk_post(const_tree e)
+{
+ gcc_assert(e);
+ tree t = TREE_TYPE(e);
+ const bool in_map = _map.find(t) != _map.end();
+ if (!in_map) return;
+
+ tree r_t = _map[t];
+ TREE_TYPE((tree)e) = r_t;
+ TypeStringifier stringifer;
+ const std::string t_name = stringifer.stringify(t);
+ const std::string r_t_name = stringifer.stringify(r_t);
+ log("replacing %s with %s\n", t_name.c_str(), r_t_name.c_str());
+}
+
+void
+ExprTypeRewriter::_walk_COMPONENT_REF_pre(const_tree e)
+{
+ // TODO: I need to rewrite the field
+ const_tree f = TREE_OPERAND(e, 1);
+ // So, what we need is a map between this field and the new field
+ const bool in_map = _map2.find(f) != _map2.end();
+ if (!in_map) return;
+
+ tree n_f = _map2[f];
+ TREE_OPERAND(e, 1) = n_f;
+ log("replacing field %s with %s\n", TypeStringifier::get_field_identifier(f).c_str(), TypeStringifier::get_field_identifier(n_f).c_str());
+}
diff --git a/gcc/expr-rewriter.hpp b/gcc/expr-rewriter.hpp
new file mode 100644
index 00000000000..29a30a2dc38
--- /dev/null
+++ b/gcc/expr-rewriter.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "expr-walker.hpp"
+#include "type-reconstructor.hpp"
+
+class ExprTypeRewriter : public ExprWalker
+{
+public:
+ ExprTypeRewriter(TypeReconstructor::reorg_record_map_t map, TypeReconstructor::reorg_field_map_t map2) : _map(map), _map2(map2) {};
+private:
+ TypeReconstructor::reorg_record_map_t _map;
+ TypeReconstructor::reorg_field_map_t _map2;
+ void _walk_post(const_tree e);
+ void _walk_COMPONENT_REF_pre(const_tree e);
+};
diff --git a/gcc/gimple-rewriter.c b/gcc/gimple-rewriter.c
new file mode 100644
index 00000000000..28e0d5f6841
--- /dev/null
+++ b/gcc/gimple-rewriter.c
@@ -0,0 +1,64 @@
+#include "gimple-rewriter.hpp"
+
+void
+GimpleTypeRewriter::_walk_pre(const_tree e)
+{
+ // This is for local variables
+ // and other declarations
+ exprTypeRewriter.walk(e);
+}
+
+void
+GimpleTypeRewriter::_walk_pre(gimple *s)
+{
+}
+
+void
+GimpleTypeRewriter::_walk_pre(gcall *s)
+{
+}
+
+void
+GimpleTypeRewriter::_walk_pre(greturn *s)
+{
+}
+
+void
+GimpleTypeRewriter::_walk_pre(gassign *s)
+{
+ const enum gimple_rhs_class code = gimple_assign_rhs_class(s);
+ switch (code)
+ {
+ case GIMPLE_TERNARY_RHS:
+ {
+ const_tree rhs3 = gimple_assign_rhs3(s);
+ exprTypeRewriter.walk(rhs3);
+ }
+ /* fall-through */
+ case GIMPLE_BINARY_RHS:
+ {
+ const_tree rhs2 = gimple_assign_rhs2(s);
+ exprTypeRewriter.walk(rhs2);
+ }
+ /* fall-through */
+ case GIMPLE_UNARY_RHS:
+ case GIMPLE_SINGLE_RHS:
+ {
+ const_tree rhs1 = gimple_assign_rhs1(s);
+ exprTypeRewriter.walk(rhs1);
+ const_tree lhs = gimple_assign_lhs(s);
+ if (!lhs) break;
+ exprTypeRewriter.walk(lhs);
+ }
+ break;
+ default:
+ gcc_unreachable();
+ break;
+ }
+
+}
+
+void
+GimpleTypeRewriter::_walk_pre(gcond *s)
+{
+}
diff --git a/gcc/gimple-rewriter.hpp b/gcc/gimple-rewriter.hpp
new file mode 100644
index 00000000000..67894485a27
--- /dev/null
+++ b/gcc/gimple-rewriter.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "gimple-walker.hpp"
+#include "expr-rewriter.hpp"
+#include "type-reconstructor.hpp"
+
+class GimpleTypeRewriter : public GimpleWalker
+{
+public:
+ GimpleTypeRewriter(TypeReconstructor::reorg_record_map_t map, TypeReconstructor::reorg_field_map_t map2) : exprTypeRewriter(map, map2) {};
+private:
+ ExprTypeRewriter exprTypeRewriter;
+ virtual void _walk_pre(const_tree) final;
+ virtual void _walk_pre(gimple*) final;
+ virtual void _walk_pre(gcall *s) final;
+ virtual void _walk_pre(greturn *s) final;
+ virtual void _walk_pre(gassign *s) final;
+ virtual void _walk_pre(gcond *s) final;
+};
diff --git a/gcc/ipa-type-escape-analysis.c b/gcc/ipa-type-escape-analysis.c
index 774a83fec52..f17dd5ded9e 100644
--- a/gcc/ipa-type-escape-analysis.c
+++ b/gcc/ipa-type-escape-analysis.c
@@ -29,6 +29,7 @@
#include "type-stringifier.hpp"
#include "type-incomplete-equality.hpp"
#include "type-reconstructor.hpp"
+#include "gimple-rewriter.hpp"
#include <vector>
@@ -273,18 +274,18 @@ collect_types()
}
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();
+ TypeReconstructor::reorg_field_map_t field_map = reconstructor.get_field_map();
for (auto i = map.cbegin(), e = map.cend(); i != e; ++i)
{
@@ -295,5 +296,11 @@ collect_types()
log("%s -> %s\n", name_from.c_str(), name_to.c_str());
}
+ GimpleTypeRewriter rewriter(map, field_map);
+ rewriter.walk();
+
+ GimpleWalker walker;
+ walker.walk(); // Just for printing...
+
log("FINISHED\n");
}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-4-layout-compile-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-04-layout-compile-0.c
index d933f3a5e85..8d6359d2144 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-4-layout-compile-0.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-04-layout-compile-0.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-flto -flto-partition=none -fipa-dead-field-eliminate -fdump-ipa-structure-reorg -fipa-typelist-field=b -fipa-typelist-struct=astruct_s" } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */
#include <stddef.h>
@@ -19,4 +19,3 @@ main (int argc, char **argv)
char ch[d == 1 ? 1 : -1];
}
-/* "Executing structreorg" "typelist" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-3-new-offsets-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-3-new-offsets-0.c
deleted file mode 100644
index 07d6ea35e0f..00000000000
--- a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-3-new-offsets-0.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-do run } */
-/* { dg-options "-flto -flto-partition=none -fipa-dead-field-eliminate -fdump-ipa-structure-reorg -fipa-typelist-field=b -fipa-typelist-struct=astruct_s" } */
-
-int
-main ()
-{
- struct astruct_s
- {
- _Bool a;
- _Bool b;
- _Bool c;
- };
- struct astruct_s astruct;
- return 0;
-}
diff --git a/gcc/type-reconstructor.c b/gcc/type-reconstructor.c
index 350d9bd4989..1faae9652af 100644
--- a/gcc/type-reconstructor.c
+++ b/gcc/type-reconstructor.c
@@ -73,6 +73,8 @@ get_new_identifier(const_tree type)
void
TypeReconstructor::_walk_ARRAY_TYPE_pre(const_tree t)
{
+ const bool in_map = _reorg_map.find(t) != _reorg_map.end();
+ gcc_assert(!in_map);
_working_stack.push(build_distinct_type_copy((tree)t));
}
@@ -91,6 +93,7 @@ TypeReconstructor::_walk_ARRAY_TYPE_post(const_tree t)
TREE_TYPE(t_reorg) = inner_reorg_type;
TYPE_NAME((tree)t_reorg) = get_new_identifier(t_reorg);
_reorg_map[t] = t_reorg;
+ layout_type(t_reorg);
log("working type %s\n", t_reorg ? "t" : "f");
}
@@ -117,6 +120,7 @@ TypeReconstructor::_walk_POINTER_TYPE_post(const_tree t)
TREE_TYPE((tree)t_reorg) = inner_type_reorg;
TYPE_NAME((tree)t_reorg) = get_new_identifier(t_reorg);
_reorg_map[t] = t_reorg;;
+ layout_type(t_reorg);
log("working type %s\n", t_reorg ? "t" : "f");
}
@@ -173,12 +177,7 @@ TypeReconstructor::_walk_UNION_TYPE_post(const_tree t)
void
TypeReconstructor::_walk_RECORD_TYPE_post(const_tree t)
{
- const bool already_changed = _reorg_map.find(t) != _reorg_map.end();
type_vector_t fields_to_keep = _field_decls.top();
- for (auto i = fields_to_keep.cbegin(), e = fields_to_keep.cend(); i != e; ++i)
- {
- const_tree field = *i;
- }
type_vector_t fields_to_eliminate = _eliminated_fields.top();
_eliminated_fields.pop();
_field_decls.pop();
@@ -196,9 +195,7 @@ TypeReconstructor::_walk_RECORD_TYPE_post(const_tree t)
// There are no fields to keep
// Can be an incomplete type
- // It is already changed, so just pop the stacks and that's it.
- if (already_changed) return;
-
+ // TODO: What if all fields have been deleted?
if (fields_to_keep.empty())
{
layout_type(working_type);
@@ -207,32 +204,21 @@ TypeReconstructor::_walk_RECORD_TYPE_post(const_tree t)
return;
}
- tree f = (tree) fields_to_keep[0];
- tree tf = TREE_TYPE(f);
- bool field_type_in_reorg_map = _reorg_map.find(tf) != _reorg_map.end();
- if (field_type_in_reorg_map)
+ for (auto i = fields_to_keep.cbegin(), e = fields_to_keep.cend(); i != e; ++i)
{
- TREE_TYPE(f) = _reorg_map[tf];
+ const_tree original_field = *i;
+ const_tree original_type = TREE_TYPE(original_field);
+ const bool is_rewritten = _reorg_map.find(original_type) != _reorg_map.end();
+ //tree modified_field = is_rewritten ? copy_node((tree)original_field) : NULL;
+ //if (modified_field) TREE_TYPE(modified_field) = _reorg_map[original_type];
+ // Ok, so now we are keeping track of which fields
+ // are rewritten...
+ //_reorg_fields[original_field] = is_rewritten ? modified_field : (tree)original_field;
}
- TYPE_FIELDS((tree)working_type) = f;
- unsigned s = fields_to_keep.size();
- for (unsigned i = 1; i < s; i++)
- {
- tree current = (tree) fields_to_keep[i];
- tree tf = TREE_TYPE(current);
- field_type_in_reorg_map = _reorg_map.find(tf) != _reorg_map.end();
- if (field_type_in_reorg_map)
- {
- TREE_TYPE(current) = _reorg_map[tf];
- }
- DECL_CHAIN(f) = current;
- f = current;
- }
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;
}
@@ -241,6 +227,14 @@ TypeReconstructor::_walk_RECORD_TYPE_post(const_tree t)
void
TypeReconstructor::_walk_field_pre(const_tree t)
{
+ // What do I want?
+ // I want something that after going through all fields
+ // I get a map from old fields to new field...
+}
+
+void
+TypeReconstructor::_walk_field_post(const_tree t)
+{
unsigned f_offset = tree_to_uhwi(DECL_FIELD_OFFSET(t));
unsigned f_offset_2 = tree_to_uhwi(DECL_FIELD_BIT_OFFSET(t));
unsigned f_offset_3 = f_offset * 8 + f_offset_2;
@@ -248,17 +242,12 @@ TypeReconstructor::_walk_field_pre(const_tree t)
const bool should_be_deleted = field_offsets.find(f_offset_3) != field_offsets.end();
const bool should_be_modified = _modifying.top();
if (should_be_modified && should_be_deleted) {
- type_vector_t &vec_ = _eliminated_fields.top();
- vec_.push_back(t);
- return;
+ type_vector_t &vec_ = _eliminated_fields.top();
+ vec_.push_back(t);
+ return;
}
// This is a field declaration, that should be saved.
type_vector_t &vec = _field_decls.top();
- vec.push_back(copy_node((tree)t));
-}
-
-void
-TypeReconstructor::_walk_field_post(const_tree t)
-{
+ vec.push_back(t);
}
diff --git a/gcc/type-reconstructor.hpp b/gcc/type-reconstructor.hpp
index b8378897b1a..e0364327300 100644
--- a/gcc/type-reconstructor.hpp
+++ b/gcc/type-reconstructor.hpp
@@ -11,6 +11,7 @@ class TypeReconstructor : public TypeWalker
{
public:
typedef std::map<const_tree, tree> reorg_record_map_t;
+ typedef std::map<const_tree, tree> reorg_field_map_t;
private:
typedef std::set<unsigned> field_offsets_t;
typedef std::map<const_tree, field_offsets_t> record_field_offset_map_t;
@@ -21,6 +22,7 @@ private:
typedef std::stack<type_vector_t> type_vector_stack_t;
typedef std::stack<bool> bool_stack_t;
record_field_offset_map_t _records;
+ reorg_field_map_t _reorg_fields;
reorg_record_map_t _reorg_map;
field_stack_t _field_stack;
record_stack_t _record_stack;
@@ -43,4 +45,5 @@ public:
virtual bool is_memoized(const_tree t);
TypeReconstructor(record_field_offset_map_t records) : _records(records) {};
reorg_record_map_t get_map() { return _reorg_map; };
+ reorg_field_map_t get_field_map() { return _reorg_fields; };
};