summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-17 12:40:33 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-17 13:10:06 +0200
commitc91c8ab11faa895584fdb3776acf45f02011c7b4 (patch)
treef752801fbb59b51422db5fa66834013d6d0c251b
parent7bb28ab761e556581a6ecd4cb59c7bf903b8f4fc (diff)
can deal with arrays
-rw-r--r--gcc/expr-rewriter.c10
-rw-r--r--gcc/expr-walker.c6
-rw-r--r--gcc/gimple-escaper.c3
-rw-r--r--gcc/gimple-walker.c2
-rw-r--r--gcc/ipa-type-escape-analysis.c6
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-field-reads-0.c20
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-05-rewrite-local-decl-0.c23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-06-field-writes-0.c24
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-07-delete-first-field-0.c23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-08-modify-double-struct-0.c30
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-09-modify-int-struct-0.c22
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-10-array-0.c9
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-5-field-reads-0.c18
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-5-rewrite-local-decl-0.c15
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-6-field-writes-0.c16
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-7-delete-first-field-0.c23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-8-modify-double-struct-0.c33
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-structreorg-9-modify-int-struct-0.c18
-rw-r--r--gcc/type-escaper.c6
-rw-r--r--gcc/type-reconstructor.c126
-rw-r--r--gcc/type-reconstructor.hpp5
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);