From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 34586 invoked by alias); 21 Apr 2015 11:38:14 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 34574 invoked by uid 89); 21 Apr 2015 11:38:13 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.1 required=5.0 tests=AWL,BAYES_50,FREEMAIL_FROM,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=no version=3.3.2 X-HELO: mail-pa0-f52.google.com Received: from mail-pa0-f52.google.com (HELO mail-pa0-f52.google.com) (209.85.220.52) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 21 Apr 2015 11:38:12 +0000 Received: by paboj16 with SMTP id oj16so238646443pab.0 for ; Tue, 21 Apr 2015 04:38:10 -0700 (PDT) X-Received: by 10.68.198.36 with SMTP id iz4mr36921647pbc.167.1429616290252; Tue, 21 Apr 2015 04:38:10 -0700 (PDT) Received: from bubble.grove.modra.org (CPE-58-160-155-134.oycza5.sa.bigpond.net.au. [58.160.155.134]) by mx.google.com with ESMTPSA id a11sm1817538pdj.54.2015.04.21.04.38.08 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Apr 2015 04:38:09 -0700 (PDT) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 90996EACABB; Tue, 21 Apr 2015 21:08:04 +0930 (ACST) Date: Tue, 21 Apr 2015 11:38:00 -0000 From: Alan Modra To: Jakub Jelinek Cc: gcc-patches@gcc.gnu.org, Alexandre Oliva Subject: Re: [Patch] pr65779 - [5/6 Regression] undefined local symbol on powerpc Message-ID: <20150421113804.GH12627@bubble.grove.modra.org> Mail-Followup-To: Jakub Jelinek , gcc-patches@gcc.gnu.org, Alexandre Oliva References: <20150420031049.GB12627@bubble.grove.modra.org> <20150420073507.GA1725@tucnak.redhat.com> <20150420084226.GC12627@bubble.grove.modra.org> <20150420085556.GE1725@tucnak.redhat.com> <20150420130032.GD12627@bubble.grove.modra.org> <20150420131721.GH1725@tucnak.redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150420131721.GH1725@tucnak.redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes X-SW-Source: 2015-04/txt/msg01140.txt.bz2 On Mon, Apr 20, 2015 at 03:17:21PM +0200, Jakub Jelinek wrote: > On Mon, Apr 20, 2015 at 10:30:32PM +0930, Alan Modra wrote: > Zapping is conservatively correct, if you don't know where the var lives in > or how to compute it, you tell the debugger you don't know it. > Of course, it is a QoI issue, if there is an easy way how to reconstruct the > value otherwise, it is always better to do so. That's what this revised patch does, fix the easy cases. > > Of course, all this moving for shrink-wrap is senseless in a block > > that contains a call. > > Yeah, such blocks clearly aren't going to be shrink-wrapped, so there is no > point to move it that far, right? It's not where we're moving to, but from. The first block in the function has a call, but prepare_shrink_wrap goes ahead regardless, moving reg copies and initialization out of the block. Ideally none of the moves would be committed until we decide that we can shrink wrap. The tricky part is that we need to perform the moves in order to update dataflow info used to decide whether other moves can happen. So I think the only way to get back to the original insn stream is keep info around for an undo. Anyway, here's the current patch. The debug_loc info looks much better, so we should see fewer of those messages from gdb. Cures a dozen quality fails on powerpc64 too (all in one testcase). Bootstrapped and regression tested powerpc64-linux and x86_64-linux. gcc/ PR debug/65779 * shrink-wrap.c (insn_uses_reg): New function. (move_insn_for_shrink_wrap): Try to fix up debug insns related to the moved insn. gcc/testsuite/ * gcc.dg/pr65779.c: New. Index: shrink-wrap.c =================================================================== --- shrink-wrap.c (revision 222227) +++ shrink-wrap.c (working copy) @@ -182,6 +182,24 @@ live_edge_for_reg (basic_block bb, int regno, int return live_edge; } +/* Return true if INSN df shows a use of a reg in the range + [REGNO,END_REGNO). */ + +static bool +insn_uses_reg (rtx_insn *insn, unsigned int regno, unsigned int end_regno) +{ + df_ref use; + + FOR_EACH_INSN_USE (use, insn) + { + rtx reg = DF_REF_REG (use); + + if (REG_P (reg) && REGNO (reg) >= regno && REGNO (reg) < end_regno) + return true; + } + return false; +} + /* Try to move INSN from BB to a successor. Return true on success. USES and DEFS are the set of registers that are used and defined after INSN in BB. SPLIT_P indicates whether a live edge from BB @@ -342,8 +360,11 @@ move_insn_for_shrink_wrap (basic_block bb, rtx_ins /* At this point we are committed to moving INSN, but let's try to move it as far as we can. */ + auto_vec live_bbs; do { + if (MAY_HAVE_DEBUG_INSNS) + live_bbs.safe_push (bb); live_out = df_get_live_out (bb); live_in = df_get_live_in (next_block); bb = next_block; @@ -426,6 +447,54 @@ move_insn_for_shrink_wrap (basic_block bb, rtx_ins SET_REGNO_REG_SET (bb_uses, i); } + /* Try to fix up debug insns in the tail of the entry block and any + intervening blocks that use regs set by the insn we are moving. */ + if (MAY_HAVE_DEBUG_INSNS) + { + while (!live_bbs.is_empty ()) + { + rtx_insn *dinsn; + basic_block tmp_bb = live_bbs.pop (); + + FOR_BB_INSNS_REVERSE (tmp_bb, dinsn) + { + if (dinsn == insn) + break; + if (DEBUG_INSN_P (dinsn) + && insn_uses_reg (dinsn, dregno, end_dregno)) + { + if (live_bbs.is_empty ()) + /* Put debug info for the insn we'll be moving + into the destination block. */ + { + rtx_insn *newdinsn + = emit_debug_insn_after (copy_rtx (PATTERN (dinsn)), + bb_note (bb)); + df_insn_rescan (newdinsn); + } + + /* If the insn is a simple reg-reg copy, then reset + the debug insn to point to src. */ + if (REG_P (src) && GET_MODE (src) == GET_MODE (dest)) + { + INSN_VAR_LOCATION_LOC (dinsn) + = simplify_replace_rtx (INSN_VAR_LOCATION_LOC (dinsn), + dest, src); + df_insn_rescan (dinsn); + } + else + { + /* Otherwise remove anything about this variable. */ + INSN_VAR_LOCATION_LOC (dinsn) + = gen_rtx_UNKNOWN_VAR_LOC (); + df_insn_rescan_debug_internal (dinsn); + } + break; + } + } + } + } + emit_insn_after (PATTERN (insn), bb_note (bb)); delete_insn (insn); return true; Index: testsuite/gcc.dg/pr65779.c =================================================================== --- testsuite/gcc.dg/pr65779.c (revision 0) +++ testsuite/gcc.dg/pr65779.c (working copy) @@ -0,0 +1,64 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -g" } */ +/* { dg-additional-options "-mrelocatable" { target powerpc-*-rtems* } } */ + +unsigned long __attribute__ ((noinline)) +adler32 (unsigned long adler, unsigned char *buf, unsigned int len) +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == 0) + return 1L; + + while (len > 0) + { + k = len < 5552 ? len : 5552; + len -= k; + while (k >= 16) + { + s1 += *buf++; s2 += s1; + s1 += *buf++; s2 += s1; + s1 += *buf++; s2 += s1; + s1 += *buf++; s2 += s1; + s1 += *buf++; s2 += s1; + s1 += *buf++; s2 += s1; + s1 += *buf++; s2 += s1; + s1 += *buf++; s2 += s1; + s1 += *buf++; s2 += s1; + s1 += *buf++; s2 += s1; + s1 += *buf++; s2 += s1; + s1 += *buf++; s2 += s1; + s1 += *buf++; s2 += s1; + s1 += *buf++; s2 += s1; + s1 += *buf++; s2 += s1; + s1 += *buf++; s2 += s1; + k -= 16; + } + if (k != 0) + do + { + s1 += *buf++; s2 += s1; + } while (--k); + s1 &= 0xffffffffUL; + s2 &= 0xffffffffUL; + s1 %= 65521L; + s2 %= 65521L; + } + return (s2 << 16) | s1; +} + +unsigned char buf[] = { 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x55, 0xaa }; +int +main () +{ + unsigned long x = adler32 (0, buf, sizeof buf); + if (x != 0x640409efUL) + __builtin_abort (); + return 0; +} -- Alan Modra Australia Development Lab, IBM