From patchwork Mon Jul 12 18:16:53 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 58638 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 4BAC2B6F10 for ; Tue, 13 Jul 2010 04:15:27 +1000 (EST) Received: (qmail 19200 invoked by alias); 12 Jul 2010 18:15:26 -0000 Received: (qmail 19188 invoked by uid 22791); 12 Jul 2010 18:15:25 -0000 X-SWARE-Spam-Status: No, hits=-6.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 12 Jul 2010 18:15:19 +0000 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o6CIFHH9016907 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 12 Jul 2010 14:15:17 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [10.16.42.4]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o6CIFGL7024433 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 12 Jul 2010 14:15:17 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [127.0.0.1]) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4) with ESMTP id o6CIGrON007407 for ; Mon, 12 Jul 2010 20:16:53 +0200 Received: (from jakub@localhost) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4/Submit) id o6CIGrEc007405 for gcc-patches@gcc.gnu.org; Mon, 12 Jul 2010 20:16:53 +0200 Date: Mon, 12 Jul 2010 20:16:53 +0200 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Subject: [PATCH] Preserve order in cfun->local_decls vector (PR debug/44901) Message-ID: <20100712181653.GY20208@tyan-ft48-01.lab.bos.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-12-10) 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! The recent change of cfun->local_decls representation from linked list to vector caused -fcompare-debug regressions. The problem is that expansion cares about the order of vars in cfun->local_decls (which determines in which order the vars will be expanded in some cases) and that some vars are only preserved when -g and not when -g0 (this isn't related to VTA btw, the failures are even with -m32 -O2 -fcompare-debug -fno-var-tracking). As the removal of vars from cfun->local_decls is done using VEC_unordered_remove, the relative order of vars gets out of sync in between -g and -g0 builds which leads into -fcompare-debug failures. Fixed by not doing unordered removals, instead moving the vector a single element at a time after first spot that needs element removal. We walk the whole vector anyways, this just adds writing of it. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2010-07-12 Jakub Jelinek PR debug/44901 * vec.h (VEC_block_remove): Fix comment. * tree-ssa-live.c (remove_unused_locals): Don't use VEC_unordered_remove on local_decls, instead replace a single vector element in each iteration if at least one element had to be removed and VEC_truncate at the end. * omp-low.c (expand_omp_taskreg): Likewise. Jakub --- gcc/vec.h.jj 2010-07-07 14:25:51.000000000 +0200 +++ gcc/vec.h 2010-07-12 16:41:27.000000000 +0200 @@ -424,7 +424,7 @@ along with GCC; see the file COPYING3. void VEC_T_block_remove (VEC(T) *v, unsigned ix, unsigned len); Remove LEN elements starting at the IXth. Ordering is retained. - This is an O(1) operation. */ + This is an O(N) operation due to memmove. */ #define VEC_block_remove(T,V,I,L) \ (VEC_OP(T,base,block_remove)(VEC_BASE(V),I,L VEC_CHECK_INFO)) --- gcc/tree-ssa-live.c.jj 2010-07-12 09:25:05.000000000 +0200 +++ gcc/tree-ssa-live.c 2010-07-12 17:03:32.000000000 +0200 @@ -689,7 +689,7 @@ remove_unused_locals (void) referenced_var_iterator rvi; var_ann_t ann; bitmap global_unused_vars = NULL; - unsigned ix; + unsigned srcidx, dstidx, num; /* Removing declarations from lexical blocks when not optimizing is not only a waste of time, it actually causes differences in stack @@ -756,8 +756,10 @@ remove_unused_locals (void) cfun->has_local_explicit_reg_vars = false; /* Remove unmarked local vars from local_decls. */ - for (ix = 0; VEC_iterate (tree, cfun->local_decls, ix, var); ) + num = VEC_length (tree, cfun->local_decls); + for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++) { + var = VEC_index (tree, cfun->local_decls, srcidx); if (TREE_CODE (var) != FUNCTION_DECL && (!(ann = var_ann (var)) || !ann->used)) @@ -769,18 +771,19 @@ remove_unused_locals (void) bitmap_set_bit (global_unused_vars, DECL_UID (var)); } else - { - VEC_unordered_remove (tree, cfun->local_decls, ix); - continue; - } + continue; } else if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var) && !is_global_var (var)) cfun->has_local_explicit_reg_vars = true; - ix++; + if (srcidx != dstidx) + VEC_replace (tree, cfun->local_decls, dstidx, var); + dstidx++; } + if (dstidx != num) + VEC_truncate (tree, cfun->local_decls, dstidx); /* Remove unmarked global vars from local_decls. */ if (global_unused_vars != NULL) @@ -794,13 +797,21 @@ remove_unused_locals (void) && ann->used) mark_all_vars_used (&DECL_INITIAL (var), global_unused_vars); - for (ix = 0; VEC_iterate (tree, cfun->local_decls, ix, var); ) - if (TREE_CODE (var) == VAR_DECL - && is_global_var (var) - && bitmap_bit_p (global_unused_vars, DECL_UID (var))) - VEC_unordered_remove (tree, cfun->local_decls, ix); - else - ix++; + num = VEC_length (tree, cfun->local_decls); + for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++) + { + var = VEC_index (tree, cfun->local_decls, srcidx); + if (TREE_CODE (var) == VAR_DECL + && is_global_var (var) + && bitmap_bit_p (global_unused_vars, DECL_UID (var))) + continue; + + if (srcidx != dstidx) + VEC_replace (tree, cfun->local_decls, dstidx, var); + dstidx++; + } + if (dstidx != num) + VEC_truncate (tree, cfun->local_decls, dstidx); BITMAP_FREE (global_unused_vars); } --- gcc/omp-low.c.jj 2010-07-07 14:25:51.000000000 +0200 +++ gcc/omp-low.c 2010-07-12 17:07:25.000000000 +0200 @@ -3378,7 +3378,7 @@ expand_omp_taskreg (struct omp_region *r } else { - unsigned ix; + unsigned srcidx, dstidx, num; /* If the parallel region needs data sent from the parent function, then the very first statement (except possible @@ -3515,11 +3515,18 @@ expand_omp_taskreg (struct omp_region *r single_succ_edge (new_bb)->flags = EDGE_FALLTHRU; /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */ - for (ix = 0; VEC_iterate (tree, child_cfun->local_decls, ix, t); ) - if (DECL_CONTEXT (t) != cfun->decl) - ix++; - else - VEC_unordered_remove (tree, child_cfun->local_decls, ix); + num = VEC_length (tree, child_cfun->local_decls); + for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++) + { + t = VEC_index (tree, child_cfun->local_decls, srcidx); + if (DECL_CONTEXT (t) == cfun->decl) + continue; + if (srcidx != dstidx) + VEC_replace (tree, child_cfun->local_decls, dstidx, t); + dstidx++; + } + if (dstidx != num) + VEC_truncate (tree, child_cfun->local_decls, dstidx); /* Inform the callgraph about the new function. */ DECL_STRUCT_FUNCTION (child_fn)->curr_properties