diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-17 12:40:33 +0200 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-17 13:10:06 +0200 |
commit | c91c8ab11faa895584fdb3776acf45f02011c7b4 (patch) | |
tree | f752801fbb59b51422db5fa66834013d6d0c251b | |
parent | 7bb28ab761e556581a6ecd4cb59c7bf903b8f4fc (diff) |
can deal with arrays
21 files changed, 291 insertions, 147 deletions
diff --git a/gcc/expr-rewriter.c b/gcc/expr-rewriter.c index 616271d96c7..6ea2b42c580 100644 --- a/gcc/expr-rewriter.c +++ b/gcc/expr-rewriter.c @@ -13,16 +13,16 @@ ExprTypeRewriter::_walk_post(const_tree e) 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()); + //TypeStringifier stringifer; + //const std::string r_t_name = stringifer.stringify(r_t); + //const std::string t_name = stringifer.stringify(t); + //log("replacing %s with %s\n", t_name.c_str(), r_t_name.c_str()); } void ExprTypeRewriter::_walk_COMPONENT_REF_post(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(); diff --git a/gcc/expr-walker.c b/gcc/expr-walker.c index 6f219f02f78..a86fde979b3 100644 --- a/gcc/expr-walker.c +++ b/gcc/expr-walker.c @@ -108,7 +108,7 @@ ExprWalker::_walk(const_tree e) default: { log("missing %s\n", get_tree_code_name(code)); - //gcc_unreachable(); + gcc_unreachable(); } break; } @@ -119,9 +119,11 @@ void \ ExprWalker::walk_ ## code (const_tree e) \ { \ assert_is_type(e, code); \ + _walk_pre(e); \ _walk_ ## code ## _pre (e); \ _walk_ ## code (e); \ _walk_ ## code ## _post (e); \ + _walk_post(e); \ } ExprWalkerFuncDef(CONSTRUCTOR) @@ -157,7 +159,7 @@ ExprWalker::_walk_op_n(const_tree e, unsigned n) gcc_assert(e); const_tree op_n = TREE_OPERAND(e, n); gcc_assert(op_n); - _walk(op_n); + walk(op_n); } void diff --git a/gcc/gimple-escaper.c b/gcc/gimple-escaper.c index 82e41d0490e..b683a7c4d1b 100644 --- a/gcc/gimple-escaper.c +++ b/gcc/gimple-escaper.c @@ -27,6 +27,7 @@ #include "cfg.h" // needed for gimple-iterator.h #include "gimple-iterator.h" #include "gimple-ssa.h" +#include "gimple-pretty-print.h" #include <stdbool.h> #include "gimple-escaper.hpp" @@ -238,7 +239,7 @@ GimpleEscaper::_walk_pre(gcall *s) { const_tree a = gimple_call_arg(s, i); gcc_assert(a); - exprEscaper.update(a, arg_reason); + exprEscaper.update_single_level(a, arg_reason); } const_tree lhs = gimple_call_lhs(s); diff --git a/gcc/gimple-walker.c b/gcc/gimple-walker.c index e61b49f0a98..c9dd51fb810 100644 --- a/gcc/gimple-walker.c +++ b/gcc/gimple-walker.c @@ -208,7 +208,7 @@ GimpleWalker::_walk(gimple *stmt) } const char* name = gimple_code_name[code]; log("gimple code name %s\n", name); - // gcc_unreachable(); + gcc_unreachable(); } #define GimpleWalkerFuncDef(type) \ diff --git a/gcc/ipa-type-escape-analysis.c b/gcc/ipa-type-escape-analysis.c index f17dd5ded9e..fe48b552997 100644 --- a/gcc/ipa-type-escape-analysis.c +++ b/gcc/ipa-type-escape-analysis.c @@ -278,9 +278,11 @@ collect_types() 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) + for (auto i = types.points_to_record.cbegin(), e = types.points_to_record.cend(); i != e; ++i) { - const_tree record = i->first; + const_tree record = *i; + std::string name_from = stringifier.stringify(record); + log("%s\n", name_from.c_str()); reconstructor.walk(record); } diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-field-reads-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-field-reads-0.c new file mode 100644 index 00000000000..18e8fe0a596 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-field-reads-0.c @@ -0,0 +1,20 @@ +/* { dg-do run } */ +/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */ + +int +main () +{ + struct astruct_s + { + _Bool a; + _Bool b; + _Bool c; + }; + struct astruct_s astruct; + _Bool a = astruct.a; + _Bool c = astruct.c; + return 0; +} + +/* { dg-final { scan-ipa-dump "replacing field a 0 with a 0" "type-escape-analysis" } } */ +/* { dg-final { scan-ipa-dump "replacing field c 16 with a 8" "type-escape-analysis" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-rewrite-local-decl-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-rewrite-local-decl-0.c new file mode 100644 index 00000000000..13aa56ed9ee --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-rewrite-local-decl-0.c @@ -0,0 +1,23 @@ +/* { dg-do run } */ +/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */ + +#include <stdio.h> + +int +main () +{ + struct astruct_s + { + _Bool a; + _Bool b; + _Bool c; + }; + struct astruct_s astruct; + printf("%d %d\n", astruct.a, astruct.c); + return 0; +} + +// This is different from previous because here we are replacing a local declaration +/* { dg-final { scan-ipa-dump "replacing field a 0 with a 0" "type-escape-analysis" } } */ +/* { dg-final { scan-ipa-dump "replacing field c 16 with c 8" "type-escape-analysis" } } */ + diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-06-field-writes-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-06-field-writes-0.c new file mode 100644 index 00000000000..41396bfe4d3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-06-field-writes-0.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */ + +#include <stdio.h> + +int +main () +{ + struct astruct_s + { + _Bool a; + _Bool b; + _Bool c; + }; + struct astruct_s astruct; + astruct.c = 0; + printf("%d %d\n", astruct.a, astruct.c); + return 0; +} + +/* { dg-final { scan-ipa-dump "replacing field a 0 with a 0" "type-escape-analysis" } } */ +// There's two... mmm.. not sure how to convey this here to the test +/* { dg-final { scan-ipa-dump "replacing field c 16 with c 8" "type-escape-analysis" } } */ +/* { dg-final { scan-ipa-dump "replacing field c 16 with c 8" "type-escape-analysis" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-07-delete-first-field-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-07-delete-first-field-0.c new file mode 100644 index 00000000000..a9c40ba0eda --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-07-delete-first-field-0.c @@ -0,0 +1,23 @@ +/* { dg-do run } */ +/* { dg-options "-w -flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */ + +#include <assert.h> +#include <stdio.h> + +int +main () +{ + struct astruct_s + { + _Bool b; + _Bool a; + _Bool c; + _Bool d; + }; + struct astruct_s astruct; + + printf("%d %d %d\n", astruct.a, astruct.c, astruct.d); + _Bool *a_ptr = &astruct.a; + struct astruct_s *s_ptr = &astruct; + assert(a_ptr == s_ptr); +} diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-08-modify-double-struct-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-08-modify-double-struct-0.c new file mode 100644 index 00000000000..0706c7b22ea --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-08-modify-double-struct-0.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */ + +#include <assert.h> +int +main () +{ + struct inner_s + { + _Bool a; + _Bool b; + _Bool c; + _Bool d; + }; + struct astruct_s + { + struct inner_s a; + struct inner_s b; + struct inner_s c; + struct inner_s d; + }; + struct astruct_s astruct; + struct inner_s *a_ptr = &(astruct.a); + struct inner_s *c_ptr = &(astruct.c); + struct inner_s *d_ptr = &(astruct.d); + struct inner_s *c_ptr_2 = a_ptr + 1; + struct inner_s *a_ptr_2 = d_ptr - 2; + assert(c_ptr_2 == c_ptr); + assert(a_ptr == a_ptr_2); +} diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-09-modify-int-struct-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-09-modify-int-struct-0.c new file mode 100644 index 00000000000..e5e80860034 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-09-modify-int-struct-0.c @@ -0,0 +1,22 @@ +/* { dg-do run } */ +/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis " } */ + +#include <assert.h> + +int +main () +{ + struct astruct_s + { + int a; + int b; + int c; + int d; + }; + struct astruct_s astruct; + int *a = &(astruct.a); + int *c = &(astruct.c); + int *d = &(astruct.d); + assert (c - 1 == a); + assert (a + 2 == d); +} diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-10-array-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-10-array-0.c index af0c175515a..8e828b8c6ed 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-10-array-0.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-10-array-0.c @@ -1,5 +1,8 @@ /* { 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 <assert.h> +#include <stdio.h> int main () @@ -11,6 +14,10 @@ main () _Bool c; }; struct astruct_s a; + printf("%d %d\n", a.a, a.c); struct astruct_s b[2]; a = b[0]; + _Bool *a_ptr = &a.a; + _Bool *c_ptr = &a.c; + assert(a_ptr + 1 == c_ptr); } diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-5-field-reads-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-5-field-reads-0.c deleted file mode 100644 index 3e37a780774..00000000000 --- a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-5-field-reads-0.c +++ /dev/null @@ -1,18 +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; - _Bool c = astruct.c; - return 0; -} - -/* "rewrite,field_offset,c,1" "typelist" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-5-rewrite-local-decl-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-5-rewrite-local-decl-0.c deleted file mode 100644 index 07d6ea35e0f..00000000000 --- a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-5-rewrite-local-decl-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/testsuite/gcc.dg/ipa/ipa-structreorg-6-field-writes-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-6-field-writes-0.c deleted file mode 100644 index c7092516692..00000000000 --- a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-6-field-writes-0.c +++ /dev/null @@ -1,16 +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; - astruct.c = 0; - return 0; -} diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-7-delete-first-field-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-7-delete-first-field-0.c deleted file mode 100644 index b0fdc15d63e..00000000000 --- a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-7-delete-first-field-0.c +++ /dev/null @@ -1,23 +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" } */ - -#include <assert.h> - -int -main () -{ - struct astruct_s - { - _Bool b; - _Bool a; - _Bool c; - _Bool d; - }; - struct astruct_s astruct; - - _Bool *a_ptr = &astruct.a; - struct astruct_s *astruct_ptr = &astruct; - _Bool test = (_Bool *) astruct_ptr == a_ptr; - char compile_test[test ? 1 : -1]; - assert (test); -} diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-8-modify-double-struct-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-8-modify-double-struct-0.c deleted file mode 100644 index 83c508ee24e..00000000000 --- a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-8-modify-double-struct-0.c +++ /dev/null @@ -1,33 +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" } */ - -#include <assert.h> -int -main () -{ - struct inner_s - { - _Bool a; - _Bool b; - _Bool c; - _Bool d; - }; - struct astruct_s - { - struct inner_s a; - struct inner_s b; - struct inner_s c; - struct inner_s d; - }; - struct astruct_s astruct; - struct inner_s a = astruct.a; - struct inner_s c = astruct.c; - struct inner_s d = astruct.d; - _Bool *pa = (_Bool *) &(astruct.a); - _Bool *pc = (_Bool *) &(astruct.c); - _Bool *pd = (_Bool *) &(astruct.d); - _Bool *c_1 = pa + 4; - _Bool *d_1 = pa + 8; - assert (pc == c_1); - assert (pd == d_1); -} diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-9-modify-int-struct-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-9-modify-int-struct-0.c deleted file mode 100644 index be51f9e06e9..00000000000 --- a/gcc/testsuite/gcc.dg/ipa/ipa-structreorg-9-modify-int-struct-0.c +++ /dev/null @@ -1,18 +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 - { - int a; - int b; - int c; - int d; - }; - struct astruct_s astruct; - int a = astruct.a; - int c = astruct.c; - int d = astruct.d; -} diff --git a/gcc/type-escaper.c b/gcc/type-escaper.c index edfb55eb44b..ef81af37589 100644 --- a/gcc/type-escaper.c +++ b/gcc/type-escaper.c @@ -36,17 +36,15 @@ 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; + const bool will_not_escape = !_reason.is_escaping(); if (will_not_escape) return true; - const bool already_escaping = in_set && calc[t].is_escaping; + const bool already_escaping = in_set && calc[t].is_escaping(); if (already_escaping) return true; - */ return false; } diff --git a/gcc/type-reconstructor.c b/gcc/type-reconstructor.c index ac3cb8b6e2e..26796eacf2b 100644 --- a/gcc/type-reconstructor.c +++ b/gcc/type-reconstructor.c @@ -34,6 +34,50 @@ #include "type-stringifier.hpp" #include "stor-layout.h" +void +TypeReconstructor::set_is_not_modified_yet(const_tree t) +{ + gcc_assert(t); + const bool is_in_reorg_map = _reorg_map.find(t) != _reorg_map.end(); + modified_map[t] = false; + + const_tree tt = TREE_TYPE(t); + if (!tt) return; + + const bool is_in_reorg_map_2 = _reorg_map.find(tt) != _reorg_map.end(); + if (!is_in_reorg_map_2) return; + log("is in reorg map\n"); + + tree type = _reorg_map[tt]; + log("name = %s\n", TypeStringifier::get_type_identifier(type).c_str()); + const bool is_modified = strstr(TypeStringifier::get_type_identifier(type).c_str(), ".reorg"); + if (!is_modified) return; + + mark_all_pointing_here_as_modified(); + +} + +void +TypeReconstructor::mark_all_pointing_here_as_modified() +{ + for (auto i = modified_map.begin(), e = modified_map.end(); i != e; ++i) + { + const_tree type = i->first; + i->second = true; + } +} + +bool +TypeReconstructor::get_is_modified(const_tree t) +{ + gcc_assert(t); + const bool in_map = modified_map.find(t) != modified_map.end(); + gcc_assert(in_map); + bool retval = modified_map[t]; + modified_map.erase(t); + return retval; +} + bool TypeReconstructor::is_memoized(const_tree t) { @@ -73,30 +117,74 @@ get_new_identifier(const_tree type) void TypeReconstructor::_walk_ARRAY_TYPE_pre(const_tree t) { + for_reference.push(t); + set_is_not_modified_yet(t); + + tree copy = build_variant_type_copy((tree) t); + in_progress.push(copy); + } void TypeReconstructor::_walk_ARRAY_TYPE_post(const_tree t) { + const_tree t2 = for_reference.top(); + gcc_assert(t2 == t); + for_reference.pop(); + tree copy = in_progress.top(); + in_progress.pop(); + + bool is_modified = get_is_modified(t); + + copy = is_modified ? build_distinct_type_copy(copy) : copy; + log("array is modified ? %s\n", is_modified ? "t" : "f"); + TREE_TYPE(copy) = is_modified ? _reorg_map[TREE_TYPE(t)] : TREE_TYPE(copy); + TYPE_NAME(copy) = is_modified ? get_new_identifier(copy) : TYPE_NAME(copy); + // This is useful so that we go again through type layout + TYPE_SIZE(copy) = is_modified ? NULL : TYPE_SIZE(copy); + if (is_modified) layout_type(copy); + + _reorg_map[t] = is_modified ? copy : (tree)t; } void TypeReconstructor::_walk_POINTER_TYPE_pre(const_tree t) { + for_reference.push(t); + set_is_not_modified_yet(t); + + tree copy = build_variant_type_copy((tree) t); + in_progress.push(copy); } void TypeReconstructor::_walk_POINTER_TYPE_post(const_tree t) { + const_tree t2 = for_reference.top(); + gcc_assert(t2 == t); + for_reference.pop(); + tree copy = in_progress.top(); + in_progress.pop(); + + bool is_modified = get_is_modified(t); + + copy = is_modified ? build_distinct_type_copy(copy) : copy; + TYPE_NAME(copy) = is_modified ? get_new_identifier(copy) : TYPE_NAME(copy); + // This is useful so that we go again through type layout + TYPE_SIZE(copy) = is_modified ? NULL : TYPE_SIZE(copy); + if (is_modified) layout_type(copy); + + _reorg_map[t] = is_modified ? copy : (tree)t; } void TypeReconstructor::_walk_RECORD_TYPE_pre(const_tree t) { + set_is_not_modified_yet(t); for_reference.push(t); // We don't know if we will modify this type t // So, let's make a copy. Just in case. - tree copy = build_distinct_type_copy((tree) t); + tree copy = build_variant_type_copy((tree) t); in_progress.push(copy); field_list_stack.push( field_tuple_list_t() ); } @@ -140,13 +228,30 @@ TypeReconstructor::_walk_RECORD_TYPE_post(const_tree t) } + bool is_modified = get_is_modified(t); // Ok, so now that we have fixed the TYPE_FIELDS of the copy... // We need to call layout_type - TYPE_NAME(copy) = get_new_identifier(copy); + copy = is_modified ? build_distinct_type_copy(copy) : copy; + TYPE_NAME(copy) = is_modified ? get_new_identifier(copy) : TYPE_NAME(copy); // This is useful so that we go again through type layout - TYPE_SIZE(copy) = NULL; - layout_type(copy); - _reorg_map[t] = copy; + TYPE_SIZE(copy) = is_modified ? NULL : TYPE_SIZE(copy); + if (is_modified) layout_type(copy); + _reorg_map[t] = is_modified ? copy : (tree)t; + + /* + if (for_reference.empty()) return; + gcc_assert(!in_progress.empty()); + + // Now we need to find out + // if we are modifying something in the parent as well? + const_tree possible_field = for_reference.top(); + const enum tree_code code = TREE_CODE(possible_field); + const bool is_field = FIELD_DECL == code; + if (!is_field) return; + + tree field_in_progress = in_progress.top(); + TREE_TYPE(field_in_progress) = copy; + */ } void @@ -167,7 +272,7 @@ TypeReconstructor::_walk_field_pre(const_tree t) // that we are working on. So proactively, let's make // a copy tree copy = copy_node((tree) t); - tree type_copy = build_distinct_type_copy((tree)(TREE_TYPE(t))); + tree type_copy = build_variant_type_copy((tree)(TREE_TYPE(t))); TREE_TYPE(copy) = type_copy; // To communicate this field to the other methods, // let's put it in the "in_progress" stack. @@ -201,10 +306,15 @@ TypeReconstructor::_walk_field_post(const_tree t) unsigned f_bit_offset = tree_to_uhwi(DECL_FIELD_BIT_OFFSET(t)); unsigned f_offset = 8 * f_byte_offset + f_bit_offset; + const bool can_field_be_deleted = field_offsets.find(f_offset) != field_offsets.end(); - field_tuple_t tuple = std::make_pair(t, can_field_be_deleted ? NULL : copy); + if (can_field_be_deleted) mark_all_pointing_here_as_modified(); + const_tree original_type = TREE_TYPE(t); + const bool type_memoized = is_memoized(original_type); + // here we did a modification - log("can field %s be deleted ? %s\n", TypeStringifier::get_field_identifier(t).c_str(), can_field_be_deleted ? "t" : "f"); + TREE_TYPE(copy) = type_memoized ? _reorg_map[TREE_TYPE(t)] : TREE_TYPE(copy); + field_tuple_t tuple = std::make_pair(t, can_field_be_deleted ? NULL : copy); // Put the field into the vector field_tuple_list_t &field_tuple_list = field_list_stack.top(); diff --git a/gcc/type-reconstructor.hpp b/gcc/type-reconstructor.hpp index 79e6fad8a73..e70776a073b 100644 --- a/gcc/type-reconstructor.hpp +++ b/gcc/type-reconstructor.hpp @@ -12,6 +12,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; + typedef std::map<const_tree, bool> is_modified_map_t; typedef std::set<unsigned> field_offsets_t; typedef std::map<const_tree, field_offsets_t> record_field_offset_map_t; private: @@ -24,6 +25,10 @@ private: field_tuple_list_stack_t field_list_stack; reorg_record_map_t _reorg_map; reorg_field_map_t _reorg_fields; + is_modified_map_t modified_map; + void set_is_not_modified_yet(const_tree); + void mark_all_pointing_here_as_modified(); + bool get_is_modified(const_tree); virtual void _walk_field_pre(const_tree); virtual void _walk_field_post(const_tree); virtual void _walk_RECORD_TYPE_pre(const_tree); |