diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2010-05-15 19:05:06 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2010-05-15 19:05:06 +0000 |
commit | d025732d199d5fda6718e4e52661ae027421a5b4 (patch) | |
tree | 9ec7215e04633e60cb2651e0efe00d834802916f /gcc/gimple.c | |
parent | b75bdd292f589b7dc457145842a511579159b055 (diff) | |
download | gcc-d025732d199d5fda6718e4e52661ae027421a5b4.tar.gz |
gimple.h (compare_field_offset): Rename into...
* gimple.h (compare_field_offset): Rename into...
(gimple_compare_field_offset): ...this.
* gimple.c (compare_field_offset): Rename into...
(gimple_compare_field_offset): ...this. Compare the full access if
the offset is self-referential.
(gimple_types_compatible_p): Adjust for above renaming.
* lto-streamer-in.c (input_gimple_stmt): Likewise. Also compare the
DECL_NONADDRESSABLE_P flag of fields before merging them.
From-SVN: r159438
Diffstat (limited to 'gcc/gimple.c')
-rw-r--r-- | gcc/gimple.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/gcc/gimple.c b/gcc/gimple.c index ace53b92f87..1ff9b3a63f6 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -3219,16 +3219,35 @@ compare_type_names_p (tree t1, tree t2, bool for_completion_p) return false; } -/* Return true if the field decls F1 and F2 are at the same offset. */ +/* Return true if the field decls F1 and F2 are at the same offset. + + This is intended to be used on GIMPLE types only. In order to + compare GENERIC types, use fields_compatible_p instead. */ bool -compare_field_offset (tree f1, tree f2) +gimple_compare_field_offset (tree f1, tree f2) { if (DECL_OFFSET_ALIGN (f1) == DECL_OFFSET_ALIGN (f2)) - return (operand_equal_p (DECL_FIELD_OFFSET (f1), - DECL_FIELD_OFFSET (f2), 0) - && tree_int_cst_equal (DECL_FIELD_BIT_OFFSET (f1), - DECL_FIELD_BIT_OFFSET (f2))); + { + tree offset1 = DECL_FIELD_OFFSET (f1); + tree offset2 = DECL_FIELD_OFFSET (f2); + return ((offset1 == offset2 + /* Once gimplification is done, self-referential offsets are + instantiated as operand #2 of the COMPONENT_REF built for + each access and reset. Therefore, they are not relevant + anymore and fields are interchangeable provided that they + represent the same access. */ + || (TREE_CODE (offset1) == PLACEHOLDER_EXPR + && TREE_CODE (offset2) == PLACEHOLDER_EXPR + && (DECL_SIZE (f1) == DECL_SIZE (f2) + || (TREE_CODE (DECL_SIZE (f1)) == PLACEHOLDER_EXPR + && TREE_CODE (DECL_SIZE (f2)) == PLACEHOLDER_EXPR) + || operand_equal_p (DECL_SIZE (f1), DECL_SIZE (f2), 0)) + && DECL_ALIGN (f1) == DECL_ALIGN (f2)) + || operand_equal_p (offset1, offset2, 0)) + && tree_int_cst_equal (DECL_FIELD_BIT_OFFSET (f1), + DECL_FIELD_BIT_OFFSET (f2))); + } /* Fortran and C do not always agree on what DECL_OFFSET_ALIGN should be, so handle differing ones specially by decomposing @@ -3576,7 +3595,7 @@ gimple_types_compatible_p (tree t1, tree t2) /* The fields must have the same name, offset and type. */ if (DECL_NAME (f1) != DECL_NAME (f2) || DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2) - || !compare_field_offset (f1, f2) + || !gimple_compare_field_offset (f1, f2) || !gimple_types_compatible_p (TREE_TYPE (f1), TREE_TYPE (f2))) goto different_types; |