aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2010-05-15 19:05:06 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2010-05-15 19:05:06 +0000
commitd025732d199d5fda6718e4e52661ae027421a5b4 (patch)
tree9ec7215e04633e60cb2651e0efe00d834802916f /gcc
parentb75bdd292f589b7dc457145842a511579159b055 (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--gcc/gimple.c33
-rw-r--r--gcc/gimple.h2
-rw-r--r--gcc/lto-streamer-in.c4
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gnat.dg/lto9.adb15
-rw-r--r--gcc/testsuite/gnat.dg/lto9_pkg1.ads24
-rw-r--r--gcc/testsuite/gnat.dg/lto9_pkg2.adb10
-rw-r--r--gcc/testsuite/gnat.dg/lto9_pkg2.ads21
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;