Patchwork rewrite Ada's build_subst_list to build a VEC

login
register
mail settings
Submitter Nathan Froyd
Date July 16, 2010, 1:51 a.m.
Message ID <20100716015102.GW12333@codesourcery.com>
Download mbox | patch
Permalink /patch/59061/
State New
Headers show

Comments

Nathan Froyd - July 16, 2010, 1:51 a.m.
This patch does as $SUBJECT suggests; one less use of TREE_LIST is a
step in the right direction.  I confess that I'm not knowledgeable about
Ada, so I don't really have much more to say.  I used a heap-allocated
VEC in the interest of keeping temporary things out of GC memory; I'm
happy to use GC allocation if people thing it would be more appropriate.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

	* gcc-interface/decl.c (subst): Declare.  Declare a VEC of it.
	(build_subst_list): Return a VEC instead of a tree.
	(build_variant_list): Take a VEC for subst_list.  Adjust
	accordingly.
	(create_field_decl_from): Likewise.
	(create_variant_part_from): Likewise.
	(copy_and_substitute_in_size): Likewise.
	(gnat_to_gnu_entity): Adjust for new interface to build_subst_list.
	Free the built vector.
Eric Botcazou - Aug. 4, 2010, 3:38 p.m.
> This patch does as $SUBJECT suggests; one less use of TREE_LIST is a
> step in the right direction.  I confess that I'm not knowledgeable about
> Ada, so I don't really have much more to say.  I used a heap-allocated
> VEC in the interest of keeping temporary things out of GC memory; I'm
> happy to use GC allocation if people thing it would be more appropriate.
>
> 	* gcc-interface/decl.c (subst): Declare.  Declare a VEC of it.
> 	(build_subst_list): Return a VEC instead of a tree.
> 	(build_variant_list): Take a VEC for subst_list.  Adjust
> 	accordingly.
> 	(create_field_decl_from): Likewise.
> 	(create_variant_part_from): Likewise.
> 	(copy_and_substitute_in_size): Likewise.
> 	(gnat_to_gnu_entity): Adjust for new interface to build_subst_list.
> 	Free the built vector.

OK modulo the following changes:
 - rename subst_d/subst into subst_pair_d/subst_pair,
 - remove the blank line added to build_subst_list.

Patch

diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 54d0222..0ecf7be 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -109,6 +109,14 @@  static struct incomplete *defer_limited_with;
 static int defer_finalize_level = 0;
 static VEC (tree,heap) *defer_finalize_list;
 
+typedef struct GTY(()) subst_d {
+  tree discriminant;
+  tree replacement;
+} subst;
+
+DEF_VEC_O(subst);
+DEF_VEC_ALLOC_O(subst,heap);
+
 /* A hash table used to cache the result of annotate_value.  */
 static GTY ((if_marked ("tree_int_map_marked_p"),
 	     param_is (struct tree_int_map))) htab_t annotate_value_cache;
@@ -146,19 +154,21 @@  static void components_to_record (tree, Node_Id, tree, int, bool, tree *,
 static Uint annotate_value (tree);
 static void annotate_rep (Entity_Id, tree);
 static tree build_position_list (tree, bool, tree, tree, unsigned int, tree);
-static tree build_subst_list (Entity_Id, Entity_Id, bool);
-static tree build_variant_list (tree, tree, tree);
+static VEC(subst,heap) *build_subst_list (Entity_Id, Entity_Id, bool);
+static tree build_variant_list (tree, VEC(subst,heap) *, tree);
 static tree validate_size (Uint, tree, Entity_Id, enum tree_code, bool, bool);
 static void set_rm_size (Uint, tree, Entity_Id);
 static tree make_type_from_size (tree, tree, bool);
 static unsigned int validate_alignment (Uint, Entity_Id, unsigned int);
 static unsigned int ceil_alignment (unsigned HOST_WIDE_INT);
 static void check_ok_for_atomic (tree, Entity_Id, bool);
-static tree create_field_decl_from (tree, tree, tree, tree, tree, tree);
+static tree create_field_decl_from (tree, tree, tree, tree, tree,
+				    VEC(subst,heap) *);
 static tree get_rep_part (tree);
 static tree get_variant_part (tree);
-static tree create_variant_part_from (tree, tree, tree, tree, tree);
-static void copy_and_substitute_in_size (tree, tree, tree);
+static tree create_variant_part_from (tree, tree, tree, tree,
+				      VEC(subst,heap) *);
+static void copy_and_substitute_in_size (tree, tree, VEC(subst,heap) *);
 static void rest_of_type_decl_compilation_no_defer (tree);
 
 /* The relevant constituents of a subprogram binding to a GCC builtin.  Used
@@ -3038,7 +3048,7 @@  gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
 	      && Present (Discriminant_Constraint (gnat_entity))
 	      && Stored_Constraint (gnat_entity) != No_Elist)
 	    {
-	      tree gnu_subst_list
+	      VEC(subst,heap) *gnu_subst_list
 		= build_subst_list (gnat_entity, gnat_base_type, definition);
 	      tree gnu_unpad_base_type, gnu_rep_part, gnu_variant_part, t;
 	      tree gnu_variant_list, gnu_pos_list, gnu_field_list = NULL_TREE;
@@ -3315,6 +3325,8 @@  gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
 					 gnat_entity);
 		}
 
+	      VEC_free (subst, heap, gnu_subst_list);
+
 	      /* Now we can finalize it.  */
 	      rest_of_record_type_compilation (gnu_type);
 	    }
@@ -7506,20 +7518,20 @@  build_position_list (tree gnu_type, bool do_not_flatten_variant, tree gnu_pos,
   return gnu_list;
 }
 
-/* Return a TREE_LIST describing the substitutions needed to reflect the
+/* Return a VEC describing the substitutions needed to reflect the
    discriminant substitutions from GNAT_TYPE to GNAT_SUBTYPE.  They can
-   be in any order.  TREE_PURPOSE gives the tree for the discriminant and
-   TREE_VALUE is the replacement value.  They are in the form of operands
-   to SUBSTITUTE_IN_EXPR.  DEFINITION is true if this is for a definition
-   of GNAT_SUBTYPE.  */
+   be in any order.  The values in an element of the VEC are in the form
+   of operands to SUBSTITUTE_IN_EXPR.  DEFINITION is true if this is for
+   a definition of GNAT_SUBTYPE.  */
 
-static tree
+static VEC(subst,heap) *
 build_subst_list (Entity_Id gnat_subtype, Entity_Id gnat_type, bool definition)
 {
-  tree gnu_list = NULL_TREE;
+  VEC(subst,heap) *gnu_vec = NULL;
   Entity_Id gnat_discrim;
   Node_Id gnat_value;
 
+
   for (gnat_discrim = First_Stored_Discriminant (gnat_type),
        gnat_value = First_Elmt (Stored_Constraint (gnat_subtype));
        Present (gnat_discrim);
@@ -7529,16 +7541,17 @@  build_subst_list (Entity_Id gnat_subtype, Entity_Id gnat_type, bool definition)
     if (!Is_Access_Type (Etype (Node (gnat_value))))
       {
 	tree gnu_field = gnat_to_gnu_field_decl (gnat_discrim);
-	gnu_list = tree_cons (gnu_field,
-			      convert (TREE_TYPE (gnu_field),
-				       elaborate_expression
-				       (Node (gnat_value), gnat_subtype,
-					get_entity_name (gnat_discrim),
-					definition, true, false)),
-			      gnu_list);
+	tree replacement = convert (TREE_TYPE (gnu_field),
+				    elaborate_expression
+				    (Node (gnat_value), gnat_subtype,
+				     get_entity_name (gnat_discrim),
+				     definition, true, false));
+	subst *s = VEC_safe_push (subst, heap, gnu_vec, NULL);
+	s->discriminant = gnu_field;
+	s->replacement = replacement;
       }
 
-  return gnu_list;
+  return gnu_vec;
 }
 
 /* Scan all fields in QUAL_UNION_TYPE and return a TREE_LIST describing the
@@ -7549,7 +7562,8 @@  build_subst_list (Entity_Id gnat_subtype, Entity_Id gnat_type, bool definition)
    list to be chained to the newly created entries.  */
 
 static tree
-build_variant_list (tree qual_union_type, tree subst_list, tree gnu_list)
+build_variant_list (tree qual_union_type, VEC(subst,heap) *subst_list,
+		    tree gnu_list)
 {
   tree gnu_field;
 
@@ -7557,10 +7571,12 @@  build_variant_list (tree qual_union_type, tree subst_list, tree gnu_list)
        gnu_field;
        gnu_field = DECL_CHAIN (gnu_field))
     {
-      tree t, qual = DECL_QUALIFIER (gnu_field);
+      tree qual = DECL_QUALIFIER (gnu_field);
+      unsigned ix;
+      subst *s;
 
-      for (t = subst_list; t; t = TREE_CHAIN (t))
-	qual = SUBSTITUTE_IN_EXPR (qual, TREE_PURPOSE (t), TREE_VALUE (t));
+      FOR_EACH_VEC_ELT_REVERSE (subst, subst_list, ix, s)
+	qual = SUBSTITUTE_IN_EXPR (qual, s->discriminant, s->replacement);
 
       /* If the new qualifier is not unconditionally false, its variant may
 	 still be accessed.  */
@@ -8223,16 +8239,18 @@  intrin_profiles_compatible_p (intrin_binding_t * inb)
 
 static tree
 create_field_decl_from (tree old_field, tree field_type, tree record_type,
-			tree size, tree pos_list, tree subst_list)
+			tree size, tree pos_list, VEC(subst,heap) *subst_list)
 {
   tree t = TREE_VALUE (purpose_member (old_field, pos_list));
   tree pos = TREE_VEC_ELT (t, 0), bitpos = TREE_VEC_ELT (t, 2);
   unsigned int offset_align = tree_low_cst (TREE_VEC_ELT (t, 1), 1);
   tree new_pos, new_field;
+  unsigned ix;
+  subst *s;
 
   if (CONTAINS_PLACEHOLDER_P (pos))
-    for (t = subst_list; t; t = TREE_CHAIN (t))
-      pos = SUBSTITUTE_IN_EXPR (pos, TREE_PURPOSE (t), TREE_VALUE (t));
+    FOR_EACH_VEC_ELT_REVERSE (subst, subst_list, ix, s)
+      pos = SUBSTITUTE_IN_EXPR (pos, s->discriminant, s->replacement);
 
   /* If the position is now a constant, we can set it as the position of the
      field when we make it.  Otherwise, we need to deal with it specially.  */
@@ -8308,7 +8326,8 @@  get_variant_part (tree record_type)
 
 static tree
 create_variant_part_from (tree old_variant_part, tree variant_list,
-			  tree record_type, tree pos_list, tree subst_list)
+			  tree record_type, tree pos_list,
+			  VEC(subst,heap) *subst_list)
 {
   tree offset = DECL_FIELD_OFFSET (old_variant_part);
   tree old_union_type = TREE_TYPE (old_variant_part);
@@ -8421,9 +8440,11 @@  create_variant_part_from (tree old_variant_part, tree variant_list,
    in SUBST_LIST.  */
 
 static void
-copy_and_substitute_in_size (tree new_type, tree old_type, tree subst_list)
+copy_and_substitute_in_size (tree new_type, tree old_type,
+			     VEC(subst,heap) *subst_list)
 {
-  tree t;
+  unsigned ix;
+  subst *s;
 
   TYPE_SIZE (new_type) = TYPE_SIZE (old_type);
   TYPE_SIZE_UNIT (new_type) = TYPE_SIZE_UNIT (old_type);
@@ -8432,25 +8453,22 @@  copy_and_substitute_in_size (tree new_type, tree old_type, tree subst_list)
   relate_alias_sets (new_type, old_type, ALIAS_SET_COPY);
 
   if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (new_type)))
-    for (t = subst_list; t; t = TREE_CHAIN (t))
+    FOR_EACH_VEC_ELT_REVERSE (subst, subst_list, ix, s)
       TYPE_SIZE (new_type)
 	= SUBSTITUTE_IN_EXPR (TYPE_SIZE (new_type),
-			      TREE_PURPOSE (t),
-			      TREE_VALUE (t));
+			      s->discriminant, s->replacement);
 
   if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE_UNIT (new_type)))
-    for (t = subst_list; t; t = TREE_CHAIN (t))
+    FOR_EACH_VEC_ELT_REVERSE (subst, subst_list, ix, s)
       TYPE_SIZE_UNIT (new_type)
 	= SUBSTITUTE_IN_EXPR (TYPE_SIZE_UNIT (new_type),
-			      TREE_PURPOSE (t),
-			      TREE_VALUE (t));
+			      s->discriminant, s->replacement);
 
   if (CONTAINS_PLACEHOLDER_P (TYPE_ADA_SIZE (new_type)))
-    for (t = subst_list; t; t = TREE_CHAIN (t))
+    FOR_EACH_VEC_ELT_REVERSE (subst, subst_list, ix, s)
       SET_TYPE_ADA_SIZE
 	(new_type, SUBSTITUTE_IN_EXPR (TYPE_ADA_SIZE (new_type),
-				       TREE_PURPOSE (t),
-				       TREE_VALUE (t)));
+				       s->discriminant, s->replacement));
 
   /* Finalize the size.  */
   TYPE_SIZE (new_type) = variable_size (TYPE_SIZE (new_type));