From patchwork Sat Aug 7 17:40:03 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Froyd X-Patchwork-Id: 61184 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id E633EB6EDD for ; Sun, 8 Aug 2010 03:40:14 +1000 (EST) Received: (qmail 15689 invoked by alias); 7 Aug 2010 17:40:12 -0000 Received: (qmail 15677 invoked by uid 22791); 7 Aug 2010 17:40:11 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 07 Aug 2010 17:40:06 +0000 Received: (qmail 22123 invoked from network); 7 Aug 2010 17:40:04 -0000 Received: from unknown (HELO localhost) (froydnj@127.0.0.2) by mail.codesourcery.com with ESMTPA; 7 Aug 2010 17:40:04 -0000 Date: Sat, 7 Aug 2010 10:40:03 -0700 From: Nathan Froyd To: Eric Botcazou Cc: gcc-patches@gcc.gnu.org Subject: Re: [PATCH] rewrite Ada's build_variant_list to build a VEC Message-ID: <20100807174003.GG17362@codesourcery.com> References: <20100716020846.GY12333@codesourcery.com> <201008041738.37745.ebotcazou@adacore.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <201008041738.37745.ebotcazou@adacore.com> User-Agent: Mutt/1.5.17+20080114 (2008-01-14) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org On Wed, Aug 04, 2010 at 05:38:37PM +0200, Eric Botcazou wrote: > > I don't know what a good name is for the structure; I was going to call > > it `variant', but that conflicts with bits in atree.h. Suggestions for > > a better name welcome. > > "variant_desc" would be fine. OK, thanks. > > * gcc-interface/decl.c (rec_variant). Declare. Declare a VEC of it. > > (build_variant_list): Return a VEC instead of a tree. Move most > > of the logic into... > > (build_variant_list_1): ...here. New function. > > (create_variant_part_from): Take a VEC instead of a tree for > > variant_list. Adjust accordingly. > > (gnat_to_gnu_entity): Adjust for changes to previous functions. > > Wouldn't it work to make build_variant_list take an existing vector, push > elements and return the new vector? Oh. Yes, yes it would. How about this version? Tested on x86_64-unknown-linux-gnu. -Nathan * gcc-interface/decl.c (rec_variant). Declare. Declare a VEC of it. (build_variant_list): Return a VEC instead of a tree. Take a VEC instead of a tree. (create_variant_part_from): Take a VEC instead of a tree for variant_list. Adjust accordingly. (gnat_to_gnu_entity): Adjust for changes to previous functions. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index a9e3358..405c3fe 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -112,6 +112,23 @@ typedef struct GTY(()) subst_pair_d { DEF_VEC_O(subst_pair); DEF_VEC_ALLOC_O(subst_pair,heap); +typedef struct GTY(()) variant_desc_d { + /* The type of the variant. */ + tree type; + + /* The associated field. */ + tree field; + + /* The value of the qualifier. */ + tree qual; + + /* The record associated with this variant. */ + tree record; +} variant_desc; + +DEF_VEC_O(variant_desc); +DEF_VEC_ALLOC_O(variant_desc,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; @@ -150,7 +167,9 @@ 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 VEC(subst_pair,heap) *build_subst_list (Entity_Id, Entity_Id, bool); -static tree build_variant_list (tree, VEC(subst_pair,heap) *, tree); +static VEC(variant_desc,heap) *build_variant_list (tree, + VEC(subst_pair,heap) *, + VEC(variant_desc,heap) *); 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); @@ -161,8 +180,8 @@ static tree create_field_decl_from (tree, tree, tree, tree, tree, VEC(subst_pair,heap) *); static tree get_rep_part (tree); static tree get_variant_part (tree); -static tree create_variant_part_from (tree, tree, tree, tree, - VEC(subst_pair,heap) *); +static tree create_variant_part_from (tree, VEC(variant_desc,heap) *, tree, + tree, VEC(subst_pair,heap) *); static void copy_and_substitute_in_size (tree, tree, VEC(subst_pair,heap) *); static void rest_of_type_decl_compilation_no_defer (tree); @@ -3045,9 +3064,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) VEC(subst_pair,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; + tree gnu_pos_list, gnu_field_list = NULL_TREE; bool selected_variant = false; Entity_Id gnat_field; + VEC(variant_desc,heap) *gnu_variant_list; gnu_type = make_node (RECORD_TYPE); TYPE_NAME (gnu_type) = gnu_entity_name; @@ -3075,15 +3095,19 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) union for the variants that are still relevant. */ if (gnu_variant_part) { + variant_desc *v; + unsigned ix; + gnu_variant_list = build_variant_list (TREE_TYPE (gnu_variant_part), - gnu_subst_list, NULL_TREE); + gnu_subst_list, NULL); /* If all the qualifiers are unconditionally true, the innermost variant is statically selected. */ selected_variant = true; - for (t = gnu_variant_list; t; t = TREE_CHAIN (t)) - if (!integer_onep (TREE_VEC_ELT (TREE_VALUE (t), 1))) + FOR_EACH_VEC_ELT_REVERSE (variant_desc, gnu_variant_list, + ix, v) + if (!integer_onep (v->qual)) { selected_variant = false; break; @@ -3091,20 +3115,21 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) /* Otherwise, create the new variants. */ if (!selected_variant) - for (t = gnu_variant_list; t; t = TREE_CHAIN (t)) + FOR_EACH_VEC_ELT_REVERSE (variant_desc, gnu_variant_list, + ix, v) { - tree old_variant = TREE_PURPOSE (t); + tree old_variant = v->type; tree new_variant = make_node (RECORD_TYPE); TYPE_NAME (new_variant) = DECL_NAME (TYPE_NAME (old_variant)); copy_and_substitute_in_size (new_variant, old_variant, gnu_subst_list); - TREE_VEC_ELT (TREE_VALUE (t), 2) = new_variant; + v->record = new_variant; } } else { - gnu_variant_list = NULL_TREE; + gnu_variant_list = NULL; selected_variant = false; } @@ -3187,13 +3212,23 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) gnu_cont_type = gnu_type; else { - t = purpose_member (gnu_context, gnu_variant_list); + variant_desc *v; + unsigned ix; + + t = NULL_TREE; + FOR_EACH_VEC_ELT_REVERSE (variant_desc, + gnu_variant_list, ix, v) + if (v->type == gnu_context) + { + t = v->type; + break; + } if (t) { if (selected_variant) gnu_cont_type = gnu_type; else - gnu_cont_type = TREE_VEC_ELT (TREE_VALUE (t), 2); + gnu_cont_type = v->record; } else /* The front-end may pass us "ghost" components if @@ -3319,6 +3354,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) gnat_entity); } + VEC_free (variant_desc, heap, gnu_variant_list); VEC_free (subst_pair, heap, gnu_subst_list); /* Now we can finalize it. */ @@ -7547,16 +7583,15 @@ build_subst_list (Entity_Id gnat_subtype, Entity_Id gnat_type, bool definition) return gnu_vec; } -/* Scan all fields in QUAL_UNION_TYPE and return a TREE_LIST describing the - variants of QUAL_UNION_TYPE that are still relevant after applying the - substitutions described in SUBST_LIST. TREE_PURPOSE is the type of the - variant and TREE_VALUE is a TREE_VEC containing the field, the new value - of the qualifier and NULL_TREE respectively. GNU_LIST is a pre-existing - list to be chained to the newly created entries. */ +/* Scan all fields in QUAL_UNION_TYPE and return a VEC describing the + variants of QUAL_UNION_TYPE that are still relevant after applying + the substitutions described in SUBST_LIST. VARIANT_LIST is a + pre-existing VEC onto which newly created entries should be + pushed. */ -static tree +static VEC(variant_desc,heap) * build_variant_list (tree qual_union_type, VEC(subst_pair,heap) *subst_list, - tree gnu_list) + VEC(variant_desc,heap) *variant_list) { tree gnu_field; @@ -7575,18 +7610,20 @@ build_variant_list (tree qual_union_type, VEC(subst_pair,heap) *subst_list, still be accessed. */ if (!integer_zerop (qual)) { + variant_desc *v; tree variant_type = TREE_TYPE (gnu_field), variant_subpart; - tree v = make_tree_vec (3); - TREE_VEC_ELT (v, 0) = gnu_field; - TREE_VEC_ELT (v, 1) = qual; - TREE_VEC_ELT (v, 2) = NULL_TREE; - gnu_list = tree_cons (variant_type, v, gnu_list); + + v = VEC_safe_push (variant_desc, heap, variant_list, NULL); + v->type = variant_type; + v->field = gnu_field; + v->qual = qual; + v->record = NULL_TREE; /* Recurse on the variant subpart of the variant, if any. */ variant_subpart = get_variant_part (variant_type); if (variant_subpart) - gnu_list = build_variant_list (TREE_TYPE (variant_subpart), - subst_list, gnu_list); + variant_list = build_variant_list (TREE_TYPE (variant_subpart), + subst_list, variant_list); /* If the new qualifier is unconditionally true, the subsequent variants cannot be accessed. */ @@ -7595,7 +7632,7 @@ build_variant_list (tree qual_union_type, VEC(subst_pair,heap) *subst_list, } } - return gnu_list; + return variant_list; } /* UINT_SIZE is a Uint giving the specified size for an object of GNU_TYPE @@ -8319,14 +8356,17 @@ get_variant_part (tree record_type) layout. */ static tree -create_variant_part_from (tree old_variant_part, tree variant_list, +create_variant_part_from (tree old_variant_part, + VEC(variant_desc,heap) *variant_list, tree record_type, tree pos_list, VEC(subst_pair,heap) *subst_list) { tree offset = DECL_FIELD_OFFSET (old_variant_part); tree old_union_type = TREE_TYPE (old_variant_part); - tree new_union_type, new_variant_part, t; + tree new_union_type, new_variant_part; tree union_field_list = NULL_TREE; + variant_desc *v; + unsigned ix; /* First create the type of the variant part from that of the old one. */ new_union_type = make_node (QUAL_UNION_TYPE); @@ -8354,9 +8394,9 @@ create_variant_part_from (tree old_variant_part, tree variant_list, copy_and_substitute_in_size (new_union_type, old_union_type, subst_list); /* Now finish up the new variants and populate the union type. */ - for (t = variant_list; t; t = TREE_CHAIN (t)) + FOR_EACH_VEC_ELT_REVERSE (variant_desc, variant_list, ix, v) { - tree old_field = TREE_VEC_ELT (TREE_VALUE (t), 0), new_field; + tree old_field = v->field, new_field; tree old_variant, old_variant_subpart, new_variant, field_list; /* Skip variants that don't belong to this nesting level. */ @@ -8364,12 +8404,12 @@ create_variant_part_from (tree old_variant_part, tree variant_list, continue; /* Retrieve the list of fields already added to the new variant. */ - new_variant = TREE_VEC_ELT (TREE_VALUE (t), 2); + new_variant = v->record; field_list = TYPE_FIELDS (new_variant); /* If the old variant had a variant subpart, we need to create a new variant subpart and add it to the field list. */ - old_variant = TREE_PURPOSE (t); + old_variant = v->type; old_variant_subpart = get_variant_part (old_variant); if (old_variant_subpart) { @@ -8391,7 +8431,7 @@ create_variant_part_from (tree old_variant_part, tree variant_list, = create_field_decl_from (old_field, new_variant, new_union_type, TYPE_SIZE (new_variant), pos_list, subst_list); - DECL_QUALIFIER (new_field) = TREE_VEC_ELT (TREE_VALUE (t), 1); + DECL_QUALIFIER (new_field) = v->qual; DECL_INTERNAL_P (new_field) = 1; DECL_CHAIN (new_field) = union_field_list; union_field_list = new_field;