From patchwork Tue Mar 5 16:30:23 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 225084 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 635672C02BF for ; Wed, 6 Mar 2013 03:31:41 +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=1363105903; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Date:From:To:Cc:Subject:Message-ID:Reply-To: MIME-Version:Content-Type:Content-Disposition:User-Agent: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=RU+nAGTAuQU6xr7FIMM+ JWP+B6Q=; b=QhJlAiZdzpLZrFtsbJXd++BGTdoT0jHPZM/K0aXXhCP04iTAVgAE JKRmLma/A7YFrnBEt3OK+0o75y8OztiJ+JGrXaztc3o//sG4PIgwmRuBqfUPKRAc LydwbEGEYfCK5AcUMGG4NG430UJA+nobQBltECO+iHWSBlz9jswPWmQ= 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:Received:Received:Received:Date:From:To:Cc:Subject:Message-ID:Reply-To:MIME-Version:Content-Type:Content-Disposition:User-Agent:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=NWSZM+dW5RS3JbHr+Wxtdg1nz3RmrNV9Pqfgw1ZjOHKkdD8uxprLpnTXWpPzBd I7uzbZXDDIM/i7x+U58FZv/YMNPJarDN922NIz53z2AYY2kaEdo8aIM/+gF1F3Ki G3ny8Eb7GO+z2Mc9r3bVd82jsmh6J2l3WDuyjomNwFjUs=; Received: (qmail 25132 invoked by alias); 5 Mar 2013 16:31:32 -0000 Received: (qmail 25115 invoked by uid 22791); 5 Mar 2013 16:31:29 -0000 X-SWARE-Spam-Status: No, hits=-6.6 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_SPAMHAUS_DROP, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, RP_MATCHES_RCVD, SPF_HELO_PASS, TW_TM 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; Tue, 05 Mar 2013 16:31:20 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r25GVKmb008657 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 5 Mar 2013 11:31:20 -0500 Received: from zalov.cz (vpn1-7-250.ams2.redhat.com [10.36.7.250]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r25GVIcY003839 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 5 Mar 2013 11:31:19 -0500 Received: from zalov.cz (localhost [127.0.0.1]) by zalov.cz (8.14.5/8.14.5) with ESMTP id r25GVHfE013847; Tue, 5 Mar 2013 17:31:17 +0100 Received: (from jakub@localhost) by zalov.cz (8.14.5/8.14.5/Submit) id r25GUNe7013660; Tue, 5 Mar 2013 17:30:23 +0100 Date: Tue, 5 Mar 2013 17:30:23 +0100 From: Jakub Jelinek To: Alexandre Oliva , Richard Biener Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Avoid too complex debug insns during expansion (PR debug/56510) Message-ID: <20130305163023.GK12913@tucnak.redhat.com> Reply-To: Jakub Jelinek 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! cselib (probably among others) isn't prepared to handle arbitrarily complex debug insns. The debug insns are usually created from debug stmts which shouldn't have unbound complexity, but with TER we can actually end up with arbitrarily large debug insns. This patch fixes that up during expansion, by splitting subexpressions of too large debug insn expressions into their own debug temporaries. So far bootstrapped/regtested on x86_64-linux and i686-linux without the first two hunks (it caused one failure on the latter because of invalid RTL sharing), I'm going to bootstrap/regtest it again, ok for trunk if it passes? 2013-03-05 Jakub Jelinek PR debug/56510 * cfgexpand.c (expand_debug_parm_decl): Call copy_rtx on incoming. (avoid_complex_debug_insns): New function. (expand_debug_locations): Call it. * gcc.dg/pr56510.c: New test. Jakub --- gcc/cfgexpand.c.jj 2013-03-05 15:12:15.071565689 +0100 +++ gcc/cfgexpand.c 2013-03-05 17:21:55.683602432 +0100 @@ -2622,6 +2622,8 @@ expand_debug_parm_decl (tree decl) reg = gen_raw_REG (GET_MODE (reg), OUTGOING_REGNO (REGNO (reg))); incoming = replace_equiv_address_nv (incoming, reg); } + else + incoming = copy_rtx (incoming); } #endif @@ -2637,7 +2639,7 @@ expand_debug_parm_decl (tree decl) || (GET_CODE (XEXP (incoming, 0)) == PLUS && XEXP (XEXP (incoming, 0), 0) == virtual_incoming_args_rtx && CONST_INT_P (XEXP (XEXP (incoming, 0), 1))))) - return incoming; + return copy_rtx (incoming); return NULL_RTX; } @@ -3704,6 +3706,54 @@ expand_debug_source_expr (tree exp) return op0; } +/* Ensure INSN_VAR_LOCATION_LOC (insn) doesn't have unbound complexity. + Allow 4 levels of rtl nesting for most rtl codes, and if we see anything + deeper than that, create DEBUG_EXPRs and emit DEBUG_INSNs before INSN. */ + +static void +avoid_complex_debug_insns (rtx insn, rtx *exp_p, int depth) +{ + rtx exp = *exp_p; + if (exp == NULL_RTX) + return; + if ((OBJECT_P (exp) && !MEM_P (exp)) || GET_CODE (exp) == CLOBBER) + return; + + if (depth == 4) + { + /* Create DEBUG_EXPR (and DEBUG_EXPR_DECL). */ + rtx dval = make_debug_expr_from_rtl (exp); + + /* Emit a debug bind insn before INSN. */ + rtx bind = gen_rtx_VAR_LOCATION (GET_MODE (exp), + DEBUG_EXPR_TREE_DECL (dval), exp, + VAR_INIT_STATUS_INITIALIZED); + + emit_debug_insn_before (bind, insn); + *exp_p = dval; + return; + } + + const char *format_ptr = GET_RTX_FORMAT (GET_CODE (exp)); + int i, j; + for (i = 0; i < GET_RTX_LENGTH (GET_CODE (exp)); i++) + switch (*format_ptr++) + { + case 'e': + avoid_complex_debug_insns (insn, &XEXP (exp, i), depth + 1); + break; + + case 'E': + case 'V': + for (j = 0; j < XVECLEN (exp, i); j++) + avoid_complex_debug_insns (insn, &XVECEXP (exp, i, j), depth + 1); + break; + + default: + break; + } +} + /* Expand the _LOCs in debug insns. We run this after expanding all regular insns, so that any variables referenced in the function will have their DECL_RTLs set. */ @@ -3724,7 +3774,7 @@ expand_debug_locations (void) if (DEBUG_INSN_P (insn)) { tree value = (tree)INSN_VAR_LOCATION_LOC (insn); - rtx val; + rtx val, prev_insn, insn2; enum machine_mode mode; if (value == NULL_TREE) @@ -3753,6 +3803,9 @@ expand_debug_locations (void) } INSN_VAR_LOCATION_LOC (insn) = val; + prev_insn = PREV_INSN (insn); + for (insn2 = insn; insn2 != prev_insn; insn2 = PREV_INSN (insn2)) + avoid_complex_debug_insns (insn2, &INSN_VAR_LOCATION_LOC (insn2), 0); } flag_strict_aliasing = save_strict_alias; --- gcc/testsuite/gcc.dg/pr56510.c.jj 2013-03-05 16:57:54.498939220 +0100 +++ gcc/testsuite/gcc.dg/pr56510.c 2013-03-05 16:57:54.499939214 +0100 @@ -0,0 +1,37 @@ +/* PR debug/56510 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g" } */ + +struct S { unsigned long s1; void **s2[0]; }; +void **a, **b, **c, **d, **e, **f; + +static void ** +baz (long x, long y) +{ + void **s = f; + *f = (void **) (y << 8 | (x & 0xff)); + f += y + 1; + return s; +} + +void bar (void); +void +foo (void) +{ + void **g = b[4]; + a = b[2]; + b = b[1]; + g[2] = e; + void **h + = ((void **************************) + a)[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][66]; + void **i = ((struct S *) h)->s2[4]; + d = baz (4, 3); + d[1] = b; + d[2] = a; + d[3] = bar; + b = d; + g[1] = i[2]; + a = g; + ((void (*) (void)) (i[1])) (); +}