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 | |
parent | b75bdd292f589b7dc457145842a511579159b055 (diff) | |
download | gcc-d025732d199d5fda6718e4e52661ae027421a5b4.zip gcc-d025732d199d5fda6718e4e52661ae027421a5b4.tar.gz gcc-d025732d199d5fda6718e4e52661ae027421a5b4.tar.bz2 |
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')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/gimple.c | 33 | ||||
-rw-r--r-- | gcc/gimple.h | 2 | ||||
-rw-r--r-- | gcc/lto-streamer-in.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/lto9.adb | 15 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/lto9_pkg1.ads | 24 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/lto9_pkg2.adb | 10 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/lto9_pkg2.ads | 21 |
9 files changed, 117 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 05a01ab..61d0842 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2010-05-15 Eric Botcazou <ebotcazou@adacore.com> + + * 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. + 2010-05-15 Nathan Froyd <froydnj@codesourcery.com> * tree.h (ctor_to_list): Delete. diff --git a/gcc/gimple.c b/gcc/gimple.c index ace53b9..1ff9b3a 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; diff --git a/gcc/gimple.h b/gcc/gimple.h index e9d21a9..d54550c 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -954,7 +954,7 @@ extern bool is_gimple_call_addr (tree); extern tree get_call_expr_in (tree t); extern void recalculate_side_effects (tree); -extern bool compare_field_offset (tree, tree); +extern bool gimple_compare_field_offset (tree, tree); extern tree gimple_register_type (tree); extern void print_gimple_types_stats (void); extern void free_gimple_type_tables (void); diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 3c31b04..5c6658a 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -1094,7 +1094,9 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, { if (tem == field || (TREE_TYPE (tem) == TREE_TYPE (field) - && compare_field_offset (tem, field))) + && DECL_NONADDRESSABLE_P (tem) + == DECL_NONADDRESSABLE_P (field) + && gimple_compare_field_offset (tem, field))) break; } /* In case of type mismatches across units we can fail diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 441b2a4..1ce44f0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-05-15 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/lto9.adb: New test. + * gnat.dg/lto9_pkg1.ads: New helper. + * gnat.dg/lto9_pkg2.ad[sb]: Likewise. + 2010-05-15 Jan Hubicka <jh@suse.cz> * gcc.dg/lto/ipareference_1.c: Rename to ... diff --git a/gcc/testsuite/gnat.dg/lto9.adb b/gcc/testsuite/gnat.dg/lto9.adb new file mode 100644 index 0000000..f4ec040 --- /dev/null +++ b/gcc/testsuite/gnat.dg/lto9.adb @@ -0,0 +1,15 @@ +-- { dg-do run } +-- { dg-options "-flto" { target lto } } + +with Lto9_Pkg1; use Lto9_Pkg1; + +procedure Lto9 is + +begin + + District_Subscription_Lists.Put + (List => District_01_Subscribers, + Elem_Ptr => New_Subscriber_01'Access, + Location => 1); + +end; diff --git a/gcc/testsuite/gnat.dg/lto9_pkg1.ads b/gcc/testsuite/gnat.dg/lto9_pkg1.ads new file mode 100644 index 0000000..a094392 --- /dev/null +++ b/gcc/testsuite/gnat.dg/lto9_pkg1.ads @@ -0,0 +1,24 @@ +with Lto9_Pkg2; + +package Lto9_Pkg1 is + + subtype Lengths is Natural range 0 .. 50; + + type Subscriber (NLen, ALen: Lengths := 50) is record + Name : String(1 .. NLen); + Address : String(1 .. ALen); + end record; + + type Subscriber_Ptr is access all Subscriber; + + package District_Subscription_Lists is new Lto9_Pkg2 + (Element_Type => Subscriber, + Element_Ptr => Subscriber_Ptr, + Size => 100); + + District_01_Subscribers : District_Subscription_Lists.List_Type; + + New_Subscriber_01 : aliased Subscriber := + (12, 23, "Brown, Silas", "King's Pyland, Dartmoor"); + +end Lto9_Pkg1; diff --git a/gcc/testsuite/gnat.dg/lto9_pkg2.adb b/gcc/testsuite/gnat.dg/lto9_pkg2.adb new file mode 100644 index 0000000..0291d60 --- /dev/null +++ b/gcc/testsuite/gnat.dg/lto9_pkg2.adb @@ -0,0 +1,10 @@ +package body Lto9_Pkg2 is + + procedure Put (List : in out List_Type; + Elem_Ptr : in Element_Ptr; + Location : in Index) is + begin + List.Elements(Location) := Elem_Ptr; + end Put; + +end Lto9_Pkg2; diff --git a/gcc/testsuite/gnat.dg/lto9_pkg2.ads b/gcc/testsuite/gnat.dg/lto9_pkg2.ads new file mode 100644 index 0000000..881d02b --- /dev/null +++ b/gcc/testsuite/gnat.dg/lto9_pkg2.ads @@ -0,0 +1,21 @@ +generic + + Size : in Positive; + type Element_Type (<>) is private; + type Element_Ptr is access all Element_Type; + +package Lto9_Pkg2 is + + subtype Index is Positive range 1 .. (Size + 1); + + type List_Array is array (Index) of Element_Ptr; + + type List_Type is record + Elements : List_Array; + end record; + + procedure Put (List : in out List_Type; + Elem_Ptr : in Element_Ptr; + Location : in Index); + +end Lto9_Pkg2; |