]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
utils.c (lookup_and_insert_pad_type): New function extracted from...
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 31 Jul 2014 13:57:42 +0000 (13:57 +0000)
committerArnaud Charlet <charlet@gcc.gnu.org>
Thu, 31 Jul 2014 13:57:42 +0000 (15:57 +0200)
2014-07-31  Eric Botcazou  <ebotcazou@adacore.com>

        * gcc-interface/utils.c (lookup_and_insert_pad_type): New function
        extracted from...
        (maybe_pad_type): ...here.  Call it to canonicalize the pad type.
        * gcc-interface/gigi.h: Update comment.

From-SVN: r213374

gcc/ada/ChangeLog
gcc/ada/gcc-interface/gigi.h
gcc/ada/gcc-interface/utils.c

index e3f2fa39da0980d9f828361566462595e38d9230..c10a9d98a226125e66a4c060dfdae8c7d939f46c 100644 (file)
@@ -1,3 +1,10 @@
+2014-07-31  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/utils.c (lookup_and_insert_pad_type): New function
+        extracted from...
+        (maybe_pad_type): ...here.  Call it to canonicalize the pad type.
+       * gcc-interface/gigi.h: Update comment.
+
 2014-07-31  Javier Miranda  <miranda@adacore.com>
 
        * debug.adb Remove documentation of -gnatd.k (no longer needed).
index e9e634e52286a999680f7bce84ecf662348fe77e..15120d58f47013123b47815777a95b099494e181 100644 (file)
@@ -143,7 +143,7 @@ extern tree make_packable_type (tree type, bool in_record);
 extern tree make_type_from_size (tree type, tree size_tree, bool for_biased);
 
 /* Ensure that TYPE has SIZE and ALIGN.  Make and return a new padded type
-   if needed.  We have already verified that SIZE and TYPE are large enough.
+   if needed.  We have already verified that SIZE and ALIGN are large enough.
    GNAT_ENTITY is used to name the resulting record and to issue a warning.
    IS_COMPONENT_TYPE is true if this is being done for the component type of
    an array.  IS_USER_TYPE is true if the original type needs to be completed.
index fa6f791c452c1c8454eaf9d9d5ba58ede01a1a5d..f2afc73fae33108602e90f90a0dc97163772c513 100644 (file)
@@ -1037,8 +1037,39 @@ pad_type_hash_eq (const void *p1, const void *p2)
     && TYPE_ADA_SIZE (type1) == TYPE_ADA_SIZE (type2);
 }
 
+/* Look up the padded TYPE in the hash table and return its canonical version
+   if it exists; otherwise, insert it into the hash table.  */
+
+static tree
+lookup_and_insert_pad_type (tree type)
+{
+  hashval_t hashcode;
+  struct pad_type_hash in, *h;
+  void **loc;
+
+  hashcode
+    = iterative_hash_object (TYPE_HASH (TREE_TYPE (TYPE_FIELDS (type))), 0);
+  hashcode = iterative_hash_expr (TYPE_SIZE (type), hashcode);
+  hashcode = iterative_hash_hashval_t (TYPE_ALIGN (type), hashcode);
+  hashcode = iterative_hash_expr (TYPE_ADA_SIZE (type), hashcode);
+
+  in.hash = hashcode;
+  in.type = type;
+  h = (struct pad_type_hash *)
+       htab_find_with_hash (pad_type_hash_table, &in, hashcode);
+  if (h)
+    return h->type;
+
+  h = ggc_alloc<pad_type_hash> ();
+  h->hash = hashcode;
+  h->type = type;
+  loc = htab_find_slot_with_hash (pad_type_hash_table, h, hashcode, INSERT);
+  *loc = (void *)h;
+  return NULL_TREE;
+}
+
 /* Ensure that TYPE has SIZE and ALIGN.  Make and return a new padded type
-   if needed.  We have already verified that SIZE and TYPE are large enough.
+   if needed.  We have already verified that SIZE and ALIGN are large enough.
    GNAT_ENTITY is used to name the resulting record and to issue a warning.
    IS_COMPONENT_TYPE is true if this is being done for the component type of
    an array.  IS_USER_TYPE is true if the original type needs to be completed.
@@ -1158,39 +1189,19 @@ maybe_pad_type (tree type, tree size, unsigned int align,
   /* Set the RM size if requested.  */
   if (set_rm_size)
     {
+      tree canonical_pad_type;
+
       SET_TYPE_ADA_SIZE (record, size ? size : orig_size);
 
       /* If the padded type is complete and has constant size, we canonicalize
         it by means of the hash table.  This is consistent with the language
         semantics and ensures that gigi and the middle-end have a common view
         of these padded types.  */
-      if (TREE_CONSTANT (TYPE_SIZE (record)))
+      if (TREE_CONSTANT (TYPE_SIZE (record))
+         && (canonical_pad_type = lookup_and_insert_pad_type (record)))
        {
-         hashval_t hashcode;
-         struct pad_type_hash in, *h;
-         void **loc;
-
-         hashcode = iterative_hash_object (TYPE_HASH (type), 0);
-         hashcode = iterative_hash_expr (TYPE_SIZE (record), hashcode);
-         hashcode = iterative_hash_hashval_t (TYPE_ALIGN (record), hashcode);
-         hashcode = iterative_hash_expr (TYPE_ADA_SIZE (record), hashcode);
-
-         in.hash = hashcode;
-         in.type = record;
-         h = (struct pad_type_hash *)
-               htab_find_with_hash (pad_type_hash_table, &in, hashcode);
-         if (h)
-           {
-             record = h->type;
-             goto built;
-           }
-
-         h = ggc_alloc<pad_type_hash> ();
-         h->hash = hashcode;
-         h->type = record;
-         loc = htab_find_slot_with_hash (pad_type_hash_table, h, hashcode,
-                                         INSERT);
-         *loc = (void *)h;
+         record = canonical_pad_type;
+         goto built;
        }
     }