From patchwork Fri Sep 16 10:45:18 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Jambor X-Patchwork-Id: 114917 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 A292FB6F83 for ; Fri, 16 Sep 2011 20:45:45 +1000 (EST) Received: (qmail 10456 invoked by alias); 16 Sep 2011 10:45:42 -0000 Received: (qmail 10448 invoked by uid 22791); 16 Sep 2011 10:45:40 -0000 X-SWARE-Spam-Status: No, hits=-3.3 required=5.0 tests=AWL,BAYES_00,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; Fri, 16 Sep 2011 10:45:20 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 4D8138B013 for ; Fri, 16 Sep 2011 12:45:19 +0200 (CEST) Date: Fri, 16 Sep 2011 12:45:18 +0200 From: Martin Jambor To: GCC Patches Subject: [PATCH, 4.4] Backport of the fix for PR 49886 (again) Message-ID: <20110916104518.GA12695@virgil.arch.suse.de> Mail-Followup-To: GCC Patches MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) 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 patch below is a backport of the fix for PR 49886 as it is now in trunk except that we check for type attributes in ipa-split instead of in ipa-inline-analysis which does not exist in the 4.6 branch. The fix is almost the same as the one I have previously reverted but the !is_gimple_reg path was added to address the fallout of the first patch. I have checked that the testcase from PR 50295 does not trigger with this patch and added the testcase from PR 50287 (which is essentially the same bug but the testcase is simpler). Also bootstrapped and tested on x86_64-linux. Since the difference from the previously approved patch is exactly what has been approved for trunk (and finally seems to work), I will commit this on Monday unless someone objects. Thanks, Martin 2011-09-15 Martin Jambor PR middle-end/49886 * ipa-split.c (split_function): Do not change signature if it is not possible or there are attribute types. * testsuite/gcc.dg/torture/pr49886.c: Remove XFAILs. * testsuite/gcc.dg/torture/pr50287.c: New test. Index: gcc/testsuite/gcc.dg/torture/pr49886.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr49886.c (revision 178885) +++ gcc/testsuite/gcc.dg/torture/pr49886.c (working copy) @@ -1,5 +1,4 @@ /* { dg-do run } */ -/* { dg-xfail-run-if "" { "*-*-*" } { "-O2" "-O3" "-Os" } } */ struct PMC { unsigned flags; Index: gcc/testsuite/gcc.dg/torture/pr50287.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr50287.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr50287.c (revision 0) @@ -0,0 +1,109 @@ +/* { dg-do compile } */ + +struct PMC { + unsigned flags; +}; + +struct PVC { + unsigned flags, other_stuff; +}; + + +typedef struct Pcc_cell +{ + struct PMC *p; + long bla; + long type; +} Pcc_cell; + +int gi; +int cond; + +struct PVC g_pvc; + +extern void abort (); +extern void never_ever(int interp, struct PMC *pmc) + __attribute__((noinline,noclone)); + +void never_ever (int interp, struct PMC *pmc) +{ + abort (); +} + +static void mark_cell(int * interp, Pcc_cell *c, struct PVC pvc) + __attribute__((__nonnull__(1))); + +static void +mark_cell(int * interp, Pcc_cell *c, struct PVC pvc) +{ + if (!cond) + return; + + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<8))) + never_ever(gi + 1, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<7))) + never_ever(gi + 2, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<6))) + never_ever(gi + 3, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<5))) + never_ever(gi + 4, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<4))) + never_ever(gi + 5, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<3))) + never_ever(gi + 6, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<2))) + never_ever(gi + 7, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<1))) + never_ever(gi + 8, c->p); + if (c && c->type == 4 && c->p + && !(c->p->flags & (1<<9))) + never_ever(gi + 9, c->p); +} + +static void +foo(int * interp, Pcc_cell *c) +{ + mark_cell(interp, c, g_pvc); +} + +static struct Pcc_cell * +__attribute__((noinline,noclone)) +getnull(void) +{ + return (struct Pcc_cell *) 0; +} + + +int main() +{ + int i; + + cond = 1; + for (i = 0; i < 100; i++) + foo (&gi, getnull ()); + return 0; +} + + +void +bar_1 (int * interp, Pcc_cell *c) +{ + c->bla += 1; + mark_cell(interp, c, g_pvc); +} + +void +bar_2 (int * interp, Pcc_cell *c, struct PVC pvc) +{ + c->bla += 2; + mark_cell(interp, c, pvc); +} + Index: gcc/ipa-split.c =================================================================== --- gcc/ipa-split.c (revision 178885) +++ gcc/ipa-split.c (working copy) @@ -946,7 +946,7 @@ split_function (struct split_point *spli bitmap args_to_skip = BITMAP_ALLOC (NULL); tree parm; int num = 0; - struct cgraph_node *node; + struct cgraph_node *node, *cur_node = cgraph_node (current_function_decl); basic_block return_bb = find_return_bb (); basic_block call_bb; gimple_stmt_iterator gsi; @@ -966,17 +966,39 @@ split_function (struct split_point *spli dump_split_point (dump_file, split_point); } + if (cur_node->local.can_change_signature + && !TYPE_ATTRIBUTES (TREE_TYPE (cur_node->decl))) + args_to_skip = BITMAP_ALLOC (NULL); + else + args_to_skip = NULL; + /* Collect the parameters of new function and args_to_skip bitmap. */ for (parm = DECL_ARGUMENTS (current_function_decl); parm; parm = DECL_CHAIN (parm), num++) - if (!is_gimple_reg (parm) - || !gimple_default_def (cfun, parm) - || !bitmap_bit_p (split_point->ssa_names_to_pass, - SSA_NAME_VERSION (gimple_default_def (cfun, parm)))) + if (args_to_skip + && (!is_gimple_reg (parm) + || !gimple_default_def (cfun, parm) + || !bitmap_bit_p (split_point->ssa_names_to_pass, + SSA_NAME_VERSION (gimple_default_def (cfun, + parm))))) bitmap_set_bit (args_to_skip, num); else { - arg = gimple_default_def (cfun, parm); + /* This parm might not have been used up to now, but is going to be + used, hence register it. */ + add_referenced_var (parm); + if (is_gimple_reg (parm)) + { + arg = gimple_default_def (cfun, parm); + if (!arg) + { + arg = make_ssa_name (parm, gimple_build_nop ()); + set_default_def (parm, arg); + } + } + else + arg = parm; + if (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)) != TYPE_MAIN_VARIANT (TREE_TYPE (arg))) { @@ -1057,9 +1079,7 @@ split_function (struct split_point *spli /* Now create the actual clone. */ rebuild_cgraph_edges (); - node = cgraph_function_versioning (cgraph_node (current_function_decl), - NULL, NULL, - args_to_skip, + node = cgraph_function_versioning (cur_node, NULL, NULL, args_to_skip, split_point->split_bbs, split_point->entry_bb, "part"); /* For usual cloning it is enough to clear builtin only when signature @@ -1070,7 +1090,7 @@ split_function (struct split_point *spli DECL_BUILT_IN_CLASS (node->decl) = NOT_BUILT_IN; DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0; } - cgraph_node_remove_callees (cgraph_node (current_function_decl)); + cgraph_node_remove_callees (cur_node); if (!split_part_return_p) TREE_THIS_VOLATILE (node->decl) = 1; if (dump_file)