diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-16 16:24:26 +0200 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-16 16:24:26 +0200 |
commit | 5468db8b6e1d8220707fe2d9debbc09bd5f49159 (patch) | |
tree | 6a63e5f4effbf5a55eeccda13f72dc54dd629bad | |
parent | 5986d24b5593fad84caa8b3270f6bab95fad6985 (diff) |
wip
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/expr-rewriter.c | 34 | ||||
-rw-r--r-- | gcc/expr-rewriter.hpp | 15 | ||||
-rw-r--r-- | gcc/gimple-rewriter.c | 64 | ||||
-rw-r--r-- | gcc/gimple-rewriter.hpp | 19 | ||||
-rw-r--r-- | gcc/ipa-type-escape-analysis.c | 11 | ||||
-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.c | 15 | ||||
-rw-r--r-- | gcc/type-reconstructor.c | 63 | ||||
-rw-r--r-- | gcc/type-reconstructor.hpp | 3 |
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; }; }; |