From patchwork Mon Oct 22 14:12:59 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Matz X-Patchwork-Id: 193161 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 25FFD2C00F8 for ; Tue, 23 Oct 2012 01:13:18 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1351519999; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Date: From:To:Subject:In-Reply-To:Message-ID:References:User-Agent: MIME-Version:Content-Type:Mailing-List:Precedence:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=6OM//zb0sbQ5SORnHFl0c6NPD4U=; b=dwS9tAIDXsgIJLG aX9E6PAVXiSNJh+Ol/vkL7UEX2dbt4dHyHiQIbSmJFwUDB9RtXt5+kjr/PN/cwgl TaCaWFWBn0KXP7CaxD/uMpji2p2hW+Tsl864ttbM1F8GygdIFNoCbM8Q384vGCHR Xybk5mdepio2osqEValY1UMwczDI= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Date:From:To:Subject:In-Reply-To:Message-ID:References:User-Agent:MIME-Version:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=wmfvPLPDRL8DeAJVk7uYwQchPaZCEt5LTzvcnMQA/eoNeozRwjDRt6R3ZicRfw pIu+Qavf05Wz8sOVOsWSvueI0lZD4My0GiNHnO0gXzUXIFSECZuJFEuCH3YKQNfn 41eTT/xNZS+dFT9Oarb2wnjp0CQ4sEG3LVQCqlO4jaULY=; Received: (qmail 24665 invoked by alias); 22 Oct 2012 14:13:13 -0000 Received: (qmail 24647 invoked by uid 22791); 22 Oct 2012 14:13:10 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_THREADED, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, TW_TM X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 22 Oct 2012 14:13:01 +0000 Received: from relay2.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 4BB32A30B9 for ; Mon, 22 Oct 2012 16:12:59 +0200 (CEST) Date: Mon, 22 Oct 2012 16:12:59 +0200 (CEST) From: Michael Matz To: gcc-patches@gcc.gnu.org Subject: Remove def operands cache, try 2 In-Reply-To: Message-ID: References: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 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 Hi, On Tue, 11 Sep 2012, Michael Matz wrote: > the operands cache is ugly. This patch removes it at least for the def > operands, saving three pointers for roughly each normal statement (the > pointer in gsbase, and two pointers from def_optype_d). This is > relatively easy to do, because all statements except ASMs have at most one > def (and one vdef), which themself aren't pointed to by something else, > unlike the use operands which have more structure for the SSA web. > > Performance wise the patch is a slight improvement (1% for some C++ > testcases, but relatively noisy, but at least not slower), bootstrap time > is unaffected. As the iterator is a bit larger code size increases by 1 > promille. > > The patch is regstrapped on x86_64-linux. If it's approved I'll adjust > the WORD count markers in gimple.h, I left it out in this submission as > it's just verbose noise in comments. So, 2nd try after some internal feedback. This version changes the operand order of asms to also have the defs at the beginning, which makes the iterators slightly nicer, and joins some more fields of the iterator, though not all that we could merge. Again, if approved I'll adjust the word count markers. Regstrapping on x86_64-linux in progress, speed similar as before. Okay for trunk? Ciao, Michael. Index: tree-ssa-operands.h =================================================================== --- tree-ssa-operands.h.orig 2012-09-24 15:24:52.000000000 +0200 +++ tree-ssa-operands.h 2012-10-22 15:12:30.000000000 +0200 @@ -34,14 +34,6 @@ typedef ssa_use_operand_t *use_operand_p #define NULL_USE_OPERAND_P ((use_operand_p)NULL) #define NULL_DEF_OPERAND_P ((def_operand_p)NULL) -/* This represents the DEF operands of a stmt. */ -struct def_optype_d -{ - struct def_optype_d *next; - tree *def_ptr; -}; -typedef struct def_optype_d *def_optype_p; - /* This represents the USE operands of a stmt. */ struct use_optype_d { @@ -68,7 +60,6 @@ struct GTY(()) ssa_operands { bool ops_active; - struct def_optype_d * GTY ((skip (""))) free_defs; struct use_optype_d * GTY ((skip (""))) free_uses; }; @@ -82,9 +73,6 @@ struct GTY(()) ssa_operands { #define USE_OP_PTR(OP) (&((OP)->use_ptr)) #define USE_OP(OP) (USE_FROM_PTR (USE_OP_PTR (OP))) -#define DEF_OP_PTR(OP) ((OP)->def_ptr) -#define DEF_OP(OP) (DEF_FROM_PTR (DEF_OP_PTR (OP))) - #define PHI_RESULT_PTR(PHI) gimple_phi_result_ptr (PHI) #define PHI_RESULT(PHI) DEF_FROM_PTR (PHI_RESULT_PTR (PHI)) #define SET_PHI_RESULT(PHI, V) SET_DEF (PHI_RESULT_PTR (PHI), (V)) @@ -133,13 +121,13 @@ enum ssa_op_iter_type { typedef struct ssa_operand_iterator_d { - bool done; enum ssa_op_iter_type iter_type; - def_optype_p defs; + bool done; + int flags; + unsigned i; + unsigned numops; use_optype_p uses; - int phi_i; - int num_phi; - gimple phi_stmt; + gimple stmt; } ssa_op_iter; /* These flags are used to determine which operands are returned during Index: gimple.h =================================================================== --- gimple.h.orig 2012-10-19 15:03:43.000000000 +0200 +++ gimple.h 2012-10-22 15:12:30.000000000 +0200 @@ -220,12 +222,12 @@ struct GTY(()) gimple_statement_with_ops /* [ WORD 1-6 ] */ struct gimple_statement_base gsbase; + /* XXX adjust word count */ /* [ WORD 7-8 ] SSA operand vectors. NOTE: It should be possible to amalgamate these vectors with the operand vector OP. However, the SSA operand vectors are organized differently and contain more information (like immediate use chaining). */ - struct def_optype_d GTY((skip (""))) *def_ops; struct use_optype_d GTY((skip (""))) *use_ops; }; @@ -1372,27 +1374,6 @@ gimple_has_mem_ops (const_gimple g) } -/* Return the set of DEF operands for statement G. */ - -static inline struct def_optype_d * -gimple_def_ops (const_gimple g) -{ - if (!gimple_has_ops (g)) - return NULL; - return g->gsops.opbase.def_ops; -} - - -/* Set DEF to be the set of DEF operands for statement G. */ - -static inline void -gimple_set_def_ops (gimple g, struct def_optype_d *def) -{ - gcc_gimple_checking_assert (gimple_has_ops (g)); - g->gsops.opbase.def_ops = def; -} - - /* Return the set of USE operands for statement G. */ static inline struct use_optype_d * @@ -1432,15 +1413,12 @@ gimple_vuse_op (const_gimple g) /* Return the set of VDEF operand for statement G. */ static inline def_operand_p -gimple_vdef_op (const_gimple g) +gimple_vdef_op (gimple g) { - struct def_optype_d *ops; if (!gimple_has_mem_ops (g)) return NULL_DEF_OPERAND_P; - ops = g->gsops.opbase.def_ops; - if (ops - && DEF_OP_PTR (ops) == &g->gsmembase.vdef) - return DEF_OP_PTR (ops); + if (g->gsmembase.vdef) + return &g->gsmembase.vdef; return NULL_DEF_OPERAND_P; } @@ -2941,8 +2919,8 @@ static inline tree gimple_asm_input_op (const_gimple gs, unsigned index) { GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index <= gs->gimple_asm.ni); - return gimple_op (gs, index); + gcc_gimple_checking_assert (index < gs->gimple_asm.ni); + return gimple_op (gs, index + gs->gimple_asm.no); } /* Return a pointer to input operand INDEX of GIMPLE_ASM GS. */ @@ -2951,8 +2929,8 @@ static inline tree * gimple_asm_input_op_ptr (const_gimple gs, unsigned index) { GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index <= gs->gimple_asm.ni); - return gimple_op_ptr (gs, index); + gcc_gimple_checking_assert (index < gs->gimple_asm.ni); + return gimple_op_ptr (gs, index + gs->gimple_asm.no); } @@ -2962,9 +2940,9 @@ static inline void gimple_asm_set_input_op (gimple gs, unsigned index, tree in_op) { GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index <= gs->gimple_asm.ni + gcc_gimple_checking_assert (index < gs->gimple_asm.ni && TREE_CODE (in_op) == TREE_LIST); - gimple_set_op (gs, index, in_op); + gimple_set_op (gs, index + gs->gimple_asm.no, in_op); } @@ -2974,8 +2952,8 @@ static inline tree gimple_asm_output_op (const_gimple gs, unsigned index) { GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index <= gs->gimple_asm.no); - return gimple_op (gs, index + gs->gimple_asm.ni); + gcc_gimple_checking_assert (index < gs->gimple_asm.no); + return gimple_op (gs, index); } /* Return a pointer to output operand INDEX of GIMPLE_ASM GS. */ @@ -2984,8 +2962,8 @@ static inline tree * gimple_asm_output_op_ptr (const_gimple gs, unsigned index) { GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index <= gs->gimple_asm.no); - return gimple_op_ptr (gs, index + gs->gimple_asm.ni); + gcc_gimple_checking_assert (index < gs->gimple_asm.no); + return gimple_op_ptr (gs, index); } @@ -2995,9 +2973,9 @@ static inline void gimple_asm_set_output_op (gimple gs, unsigned index, tree out_op) { GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index <= gs->gimple_asm.no + gcc_gimple_checking_assert (index < gs->gimple_asm.no && TREE_CODE (out_op) == TREE_LIST); - gimple_set_op (gs, index + gs->gimple_asm.ni, out_op); + gimple_set_op (gs, index, out_op); } @@ -3007,7 +2985,7 @@ static inline tree gimple_asm_clobber_op (const_gimple gs, unsigned index) { GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index <= gs->gimple_asm.nc); + gcc_gimple_checking_assert (index < gs->gimple_asm.nc); return gimple_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.no); } @@ -3018,7 +2996,7 @@ static inline void gimple_asm_set_clobber_op (gimple gs, unsigned index, tree clobber_op) { GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index <= gs->gimple_asm.nc + gcc_gimple_checking_assert (index < gs->gimple_asm.nc && TREE_CODE (clobber_op) == TREE_LIST); gimple_set_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.no, clobber_op); } @@ -3029,7 +3007,7 @@ static inline tree gimple_asm_label_op (const_gimple gs, unsigned index) { GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index <= gs->gimple_asm.nl); + gcc_gimple_checking_assert (index < gs->gimple_asm.nl); return gimple_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.nc); } @@ -3039,7 +3017,7 @@ static inline void gimple_asm_set_label_op (gimple gs, unsigned index, tree label_op) { GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index <= gs->gimple_asm.nl + gcc_gimple_checking_assert (index < gs->gimple_asm.nl && TREE_CODE (label_op) == TREE_LIST); gimple_set_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.nc, label_op); } Index: tree-flow-inline.h =================================================================== --- tree-flow-inline.h.orig 2012-09-24 15:26:16.000000000 +0200 +++ tree-flow-inline.h 2012-10-22 15:27:36.000000000 +0200 @@ -580,9 +580,9 @@ op_iter_next_use (ssa_op_iter *ptr) ptr->uses = ptr->uses->next; return use_p; } - if (ptr->phi_i < ptr->num_phi) + if (ptr->i < ptr->numops) { - return PHI_ARG_DEF_PTR (ptr->phi_stmt, (ptr->phi_i)++); + return PHI_ARG_DEF_PTR (ptr->stmt, (ptr->i)++); } ptr->done = true; return NULL_USE_OPERAND_P; @@ -592,14 +592,33 @@ op_iter_next_use (ssa_op_iter *ptr) static inline def_operand_p op_iter_next_def (ssa_op_iter *ptr) { - def_operand_p def_p; gcc_checking_assert (ptr->iter_type == ssa_op_iter_def); - if (ptr->defs) + if (ptr->flags & SSA_OP_VDEF) { - def_p = DEF_OP_PTR (ptr->defs); - ptr->defs = ptr->defs->next; - return def_p; + tree *p; + ptr->flags &= ~SSA_OP_VDEF; + p = gimple_vdef_ptr (ptr->stmt); + if (p && *p) + return p; } + if (ptr->flags & SSA_OP_DEF) + { + while (ptr->i < ptr->numops) + { + tree *val = gimple_op_ptr (ptr->stmt, ptr->i); + ptr->i++; + if (*val) + { + if (TREE_CODE (*val) == TREE_LIST) + val = &TREE_VALUE (*val); + if (TREE_CODE (*val) == SSA_NAME + || is_gimple_reg (*val)) + return val; + } + } + ptr->flags &= ~SSA_OP_DEF; + } + ptr->done = true; return NULL_DEF_OPERAND_P; } @@ -616,16 +635,32 @@ op_iter_next_tree (ssa_op_iter *ptr) ptr->uses = ptr->uses->next; return val; } - if (ptr->defs) + if (ptr->flags & SSA_OP_VDEF) { - val = DEF_OP (ptr->defs); - ptr->defs = ptr->defs->next; - return val; + ptr->flags &= ~SSA_OP_VDEF; + if ((val = gimple_vdef (ptr->stmt))) + return val; + } + if (ptr->flags & SSA_OP_DEF) + { + while (ptr->i < ptr->numops) + { + val = gimple_op (ptr->stmt, ptr->i); + ptr->i++; + if (val) + { + if (TREE_CODE (val) == TREE_LIST) + val = TREE_VALUE (val); + if (TREE_CODE (val) == SSA_NAME + || is_gimple_reg (val)) + return val; + } + } + ptr->flags &= ~SSA_OP_DEF; } ptr->done = true; return NULL_TREE; - } @@ -636,13 +671,13 @@ op_iter_next_tree (ssa_op_iter *ptr) static inline void clear_and_done_ssa_iter (ssa_op_iter *ptr) { - ptr->defs = NULL; + ptr->i = 0; + ptr->numops = 0; ptr->uses = NULL; ptr->iter_type = ssa_op_iter_none; - ptr->phi_i = 0; - ptr->num_phi = 0; - ptr->phi_stmt = NULL; + ptr->stmt = NULL; ptr->done = true; + ptr->flags = 0; } /* Initialize the iterator PTR to the virtual defs in STMT. */ @@ -655,21 +690,34 @@ op_iter_init (ssa_op_iter *ptr, gimple s gcc_checking_assert (gimple_code (stmt) != GIMPLE_PHI && (!(flags & SSA_OP_VDEF) || (flags & SSA_OP_DEF)) && (!(flags & SSA_OP_VUSE) || (flags & SSA_OP_USE))); - ptr->defs = (flags & (SSA_OP_DEF|SSA_OP_VDEF)) ? gimple_def_ops (stmt) : NULL; - if (!(flags & SSA_OP_VDEF) - && ptr->defs - && gimple_vdef (stmt) != NULL_TREE) - ptr->defs = ptr->defs->next; + ptr->numops = 0; + if (flags & (SSA_OP_DEF | SSA_OP_VDEF)) + { + switch (gimple_code (stmt)) + { + case GIMPLE_ASSIGN: + case GIMPLE_CALL: + ptr->numops = 1; + break; + case GIMPLE_ASM: + ptr->numops = gimple_asm_noutputs (stmt); + break; + default: + ptr->numops = 0; + flags &= ~(SSA_OP_DEF | SSA_OP_VDEF); + break; + } + } ptr->uses = (flags & (SSA_OP_USE|SSA_OP_VUSE)) ? gimple_use_ops (stmt) : NULL; if (!(flags & SSA_OP_VUSE) && ptr->uses && gimple_vuse (stmt) != NULL_TREE) ptr->uses = ptr->uses->next; ptr->done = false; + ptr->i = 0; - ptr->phi_i = 0; - ptr->num_phi = 0; - ptr->phi_stmt = NULL; + ptr->stmt = stmt; + ptr->flags = flags; } /* Initialize iterator PTR to the use operands in STMT based on FLAGS. Return @@ -839,9 +887,10 @@ op_iter_init_phiuse (ssa_op_iter *ptr, g return NULL_USE_OPERAND_P; } - ptr->phi_stmt = phi; - ptr->num_phi = gimple_phi_num_args (phi); + ptr->stmt = phi; + ptr->numops = gimple_phi_num_args (phi); ptr->iter_type = ssa_op_iter_use; + ptr->flags = flags; return op_iter_next_use (ptr); } Index: tree-ssa-operands.c =================================================================== --- tree-ssa-operands.c.orig 2012-09-24 15:26:38.000000000 +0200 +++ tree-ssa-operands.c 2012-10-22 15:12:30.000000000 +0200 @@ -106,9 +106,6 @@ along with GCC; see the file COPYING3. /* Operand is in a place where opf_non_addressable does not apply. */ #define opf_not_non_addressable (1 << 4) -/* Array for building all the def operands. */ -static VEC(tree,heap) *build_defs; - /* Array for building all the use operands. */ static VEC(tree,heap) *build_uses; @@ -185,7 +182,6 @@ init_ssa_operands (struct function *fn) { if (!n_initialized++) { - build_defs = VEC_alloc (tree, heap, 5); build_uses = VEC_alloc (tree, heap, 10); build_vuse = NULL_TREE; build_vdef = NULL_TREE; @@ -210,13 +206,11 @@ fini_ssa_operands (void) if (!--n_initialized) { - VEC_free (tree, heap, build_defs); VEC_free (tree, heap, build_uses); build_vdef = NULL_TREE; build_vuse = NULL_TREE; } - gimple_ssa_operands (cfun)->free_defs = NULL; gimple_ssa_operands (cfun)->free_uses = NULL; while ((ptr = gimple_ssa_operands (cfun)->operand_memory) != NULL) @@ -242,8 +236,7 @@ ssa_operand_alloc (unsigned size) { char *ptr; - gcc_assert (size == sizeof (struct use_optype_d) - || size == sizeof (struct def_optype_d)); + gcc_assert (size == sizeof (struct use_optype_d)); if (gimple_ssa_operands (cfun)->operand_memory_index + size >= gimple_ssa_operands (cfun)->ssa_operand_mem_size) @@ -282,25 +275,6 @@ ssa_operand_alloc (unsigned size) } -/* Allocate a DEF operand. */ - -static inline struct def_optype_d * -alloc_def (void) -{ - struct def_optype_d *ret; - if (gimple_ssa_operands (cfun)->free_defs) - { - ret = gimple_ssa_operands (cfun)->free_defs; - gimple_ssa_operands (cfun)->free_defs - = gimple_ssa_operands (cfun)->free_defs->next; - } - else - ret = (struct def_optype_d *) - ssa_operand_alloc (sizeof (struct def_optype_d)); - return ret; -} - - /* Allocate a USE operand. */ static inline struct use_optype_d * @@ -320,21 +294,6 @@ alloc_use (void) } -/* Adds OP to the list of defs after LAST. */ - -static inline def_optype_p -add_def_op (tree *op, def_optype_p last) -{ - def_optype_p new_def; - - new_def = alloc_def (); - DEF_OP_PTR (new_def) = op; - last->next = new_def; - new_def->next = NULL; - return new_def; -} - - /* Adds OP to the list of uses of statement STMT after LAST. */ static inline use_optype_p @@ -358,14 +317,6 @@ add_use_op (gimple stmt, tree *op, use_o static inline void finalize_ssa_defs (gimple stmt) { - unsigned new_i; - struct def_optype_d new_list; - def_optype_p old_ops, last; - unsigned int num = VEC_length (tree, build_defs); - - /* There should only be a single real definition per assignment. */ - gcc_assert ((stmt && gimple_code (stmt) != GIMPLE_ASSIGN) || num <= 1); - /* Pre-pend the vdef we may have built. */ if (build_vdef != NULL_TREE) { @@ -375,17 +326,8 @@ finalize_ssa_defs (gimple stmt) oldvdef = SSA_NAME_VAR (oldvdef); if (oldvdef != build_vdef) gimple_set_vdef (stmt, build_vdef); - VEC_safe_insert (tree, heap, build_defs, 0, (tree)gimple_vdef_ptr (stmt)); - ++num; } - new_list.next = NULL; - last = &new_list; - - old_ops = gimple_def_ops (stmt); - - new_i = 0; - /* Clear and unlink a no longer necessary VDEF. */ if (build_vdef == NULL_TREE && gimple_vdef (stmt) != NULL_TREE) @@ -405,30 +347,6 @@ finalize_ssa_defs (gimple stmt) cfun->gimple_df->rename_vops = 1; cfun->gimple_df->ssa_renaming_needed = 1; } - - /* Check for the common case of 1 def that hasn't changed. */ - if (old_ops && old_ops->next == NULL && num == 1 - && (tree *) VEC_index (tree, build_defs, 0) == DEF_OP_PTR (old_ops)) - return; - - /* If there is anything in the old list, free it. */ - if (old_ops) - { - old_ops->next = gimple_ssa_operands (cfun)->free_defs; - gimple_ssa_operands (cfun)->free_defs = old_ops; - } - - /* If there is anything remaining in the build_defs list, simply emit it. */ - for ( ; new_i < num; new_i++) - { - tree *op = (tree *) VEC_index (tree, build_defs, new_i); - if (DECL_P (*op)) - cfun->gimple_df->ssa_renaming_needed = 1; - last = add_def_op (op, last); - } - - /* Now set the stmt's operands. */ - gimple_set_def_ops (stmt, new_list.next); } @@ -488,8 +406,6 @@ finalize_ssa_uses (gimple stmt) for (new_i = 0; new_i < VEC_length (tree, build_uses); new_i++) { tree *op = (tree *) VEC_index (tree, build_uses, new_i); - if (DECL_P (*op)) - cfun->gimple_df->ssa_renaming_needed = 1; last = add_use_op (stmt, op, last); } @@ -506,7 +422,6 @@ cleanup_build_arrays (void) { build_vdef = NULL_TREE; build_vuse = NULL_TREE; - VEC_truncate (tree, build_defs, 0); VEC_truncate (tree, build_uses, 0); } @@ -527,22 +442,12 @@ finalize_ssa_stmt_operands (gimple stmt) static inline void start_ssa_stmt_operands (void) { - gcc_assert (VEC_length (tree, build_defs) == 0); gcc_assert (VEC_length (tree, build_uses) == 0); gcc_assert (build_vuse == NULL_TREE); gcc_assert (build_vdef == NULL_TREE); } -/* Add DEF_P to the list of pointers to operands. */ - -static inline void -append_def (tree *def_p) -{ - VEC_safe_push (tree, heap, build_defs, (tree) def_p); -} - - /* Add USE_P to the list of pointers to operands. */ static inline void @@ -620,9 +525,11 @@ add_stmt_operand (tree *var_p, gimple st { /* The variable is a GIMPLE register. Add it to real operands. */ if (flags & opf_def) - append_def (var_p); + ; else append_use (var_p); + if (DECL_P (*var_p)) + cfun->gimple_df->ssa_renaming_needed = 1; } else { @@ -669,15 +576,10 @@ mark_address_taken (tree ref) STMT is the statement being processed, EXPR is the MEM_REF that got us here. - FLAGS is as in get_expr_operands. - - RECURSE_ON_BASE should be set to true if we want to continue - calling get_expr_operands on the base pointer, and false if - something else will do it for us. */ + FLAGS is as in get_expr_operands. */ static void -get_indirect_ref_operands (gimple stmt, tree expr, int flags, - bool recurse_on_base) +get_indirect_ref_operands (gimple stmt, tree expr, int flags) { tree *pptr = &TREE_OPERAND (expr, 0); @@ -689,10 +591,9 @@ get_indirect_ref_operands (gimple stmt, add_virtual_operand (stmt, flags); /* If requested, add a USE operand for the base pointer. */ - if (recurse_on_base) - get_expr_operands (stmt, pptr, - opf_non_addressable | opf_use - | (flags & (opf_no_vops|opf_not_non_addressable))); + get_expr_operands (stmt, pptr, + opf_non_addressable | opf_use + | (flags & (opf_no_vops|opf_not_non_addressable))); } @@ -853,7 +754,7 @@ get_expr_operands (gimple stmt, tree *ex return; case MEM_REF: - get_indirect_ref_operands (stmt, expr, flags, true); + get_indirect_ref_operands (stmt, expr, flags); return; case TARGET_MEM_REF: @@ -1126,31 +1027,6 @@ verify_ssa_operands (gimple stmt) return true; } - FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF) - { - FOR_EACH_VEC_ELT (tree, build_defs, i, def) - { - if (def_p == (tree *)def) - { - VEC_replace (tree, build_defs, i, NULL_TREE); - break; - } - } - if (i == VEC_length (tree, build_defs)) - { - error ("excess def operand for stmt"); - debug_generic_expr (DEF_FROM_PTR (def_p)); - return true; - } - } - FOR_EACH_VEC_ELT (tree, build_defs, i, def) - if (def != NULL_TREE) - { - error ("def operand missing for stmt"); - debug_generic_expr (*(tree *)def); - return true; - } - if (gimple_has_volatile_ops (stmt) != volatile_p) { error ("stmt volatile flag not up-to-date"); @@ -1168,18 +1044,8 @@ verify_ssa_operands (gimple stmt) void free_stmt_operands (gimple stmt) { - def_optype_p defs = gimple_def_ops (stmt), last_def; use_optype_p uses = gimple_use_ops (stmt), last_use; - if (defs) - { - for (last_def = defs; last_def->next; last_def = last_def->next) - continue; - last_def->next = gimple_ssa_operands (cfun)->free_defs; - gimple_ssa_operands (cfun)->free_defs = defs; - gimple_set_def_ops (stmt, NULL); - } - if (uses) { for (last_use = uses; last_use->next; last_use = last_use->next) Index: gimple.c =================================================================== --- gimple.c.orig 2012-09-24 15:26:19.000000000 +0200 +++ gimple.c 2012-10-22 15:13:10.000000000 +0200 @@ -2345,7 +2345,6 @@ gimple_copy (gimple stmt) /* Clear out SSA operand vectors on COPY. */ if (gimple_has_ops (stmt)) { - gimple_set_def_ops (copy, NULL); gimple_set_use_ops (copy, NULL); /* SSA operands need to be updated. */