From patchwork Thu Mar 10 09:18:08 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 595657 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 9994D1401CD for ; Thu, 10 Mar 2016 20:18:32 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=Z+KarijY; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; q=dns; s=default; b=V5hyUjbDwKGBjqhdP f8TJUeNyyWE51H7fxZTL4PWKi3qV8A4XyaHHqqHslE38gg8jP0GVDJijHSLzCGky 0PhzG7PeCqLWxPS1MBRpDBmtEOhM+Qnuua0dFqh8CJwyDqMVoLnEJHCU1/hC2fmV Muc6YTqvyArBWHonlb25Q4VhKI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=default; bh=OohndUYaag2vl1tkPgnQiHf h37c=; b=Z+KarijY/EgWdHvZm6ut+Ck9hGJBsAcZtD17GKczNu6/S8gNiAz+2W2 LcP998PQ8w00+hLpZKkYb71DNf2Khv6HWXyuhd+1dnguTGS5FgNkA54h0h/bvvtl +7P5xOguz9UJHJXUNe4SiwrjGS7QRdoPEBYY/w3QYJT+TDZpKWCw= Received: (qmail 31319 invoked by alias); 10 Mar 2016 09:18:21 -0000 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 Received: (qmail 31217 invoked by uid 89); 10 Mar 2016 09:18:20 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=REGNO, regno, bitmap, sk:adjust_ X-HELO: mail-pa0-f53.google.com Received: from mail-pa0-f53.google.com (HELO mail-pa0-f53.google.com) (209.85.220.53) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 10 Mar 2016 09:18:17 +0000 Received: by mail-pa0-f53.google.com with SMTP id tt10so62837821pab.3 for ; Thu, 10 Mar 2016 01:18:17 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=3wcBmd2AY7Akpl3k4fm0CNbY9OxXv21xwcer2SsuT7c=; b=LGoL1MEEj6t+UXk/POOkkbnqMjV+SoNdOr5yEY5ZVFlnqLIAd11cl+F5SFy9IXtQct pYe+iW5a2UUQtHlPbZO+EjhtmA0q06H5wgOYtzL8HA+nq9A99c+mCIAziCn6R1J5JMvo 5riItYy66XJStPPS98sKBy4pO8SfXwOK6pYgEQJCrSTx5022mlJxZmlgBDn4wen5zlai uNor5Yl1Pkp4hHsXdouQczLlhbZhwetJa8Nko5zJr8jPZHJT7UlBQyeujhj1yhWvwBoK 0LBiIzPfvzuCGBnxhg8YNkYvW0hfrYwLGLAYBoeo68il5rIKeRVpSXWv2GdZpkl4iZzS NnEA== X-Gm-Message-State: AD7BkJJdvG4SA8dotee9IF5ea/XOFl3GxZioBMAKxhsT9390xhArqZF704V4jYp8bmyQkw== X-Received: by 10.66.225.177 with SMTP id rl17mr3462729pac.46.1457601494550; Thu, 10 Mar 2016 01:18:14 -0800 (PST) Received: from bubble.grove.modra.org (CPE-58-160-146-233.sa.bigpond.net.au. [58.160.146.233]) by smtp.gmail.com with ESMTPSA id i1sm3958626pfj.17.2016.03.10.01.18.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 10 Mar 2016 01:18:13 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id E71FEEA0157; Thu, 10 Mar 2016 19:48:08 +1030 (ACDT) Date: Thu, 10 Mar 2016 19:48:08 +1030 From: Alan Modra To: Bernd Schmidt Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] PR69195, Reload confused by invalid reg equivs Message-ID: <20160310091808.GO9617@bubble.grove.modra.org> References: <20160304145430.GD9617@bubble.grove.modra.org> <56D9C86A.8050302@redhat.com> <20160307144656.GF9617@bubble.grove.modra.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20160307144656.GF9617@bubble.grove.modra.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes Doing the indirect jump optimization turned out to be quite easy. Bootstrapped and regression tested powerpc64le-linux, gcc-6, gcc-5 and gcc-4.9. Bootstrap and regression test x86_64-linux still running. OK to apply? gcc/ PR rtl-optimization/69195 PR rtl-optimization/47992 * ira.c (recorded_label_ref): Delete. (update_equiv_regs): Return void. (indirect_jump_optimize): New function. (ira): Call indirect_jump_optimize and delete_trivially_dead_insns before regstat_compute_ri. Don't rebuild_jump_labels here. Delete update_regstat. gcc/testsuite/ * gcc.dg/pr69195.c: New. * gcc.dg/pr69238.c: New. diff --git a/gcc/ira.c b/gcc/ira.c index 0973258..5e7a2ed 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -3319,9 +3319,6 @@ adjust_cleared_regs (rtx loc, const_rtx old_rtx ATTRIBUTE_UNUSED, void *data) return NULL_RTX; } -/* Nonzero if we recorded an equivalence for a LABEL_REF. */ -static int recorded_label_ref; - /* Find registers that are equivalent to a single value throughout the compilation (either because they can be referenced in memory or are set once from a single constant). Lower their priority for a @@ -3331,10 +3328,8 @@ static int recorded_label_ref; value into the using insn. If it succeeds, we can eliminate the register completely. - Initialize init_insns in ira_reg_equiv array. - - Return non-zero if jump label rebuilding should be done. */ -static int + Initialize init_insns in ira_reg_equiv array. */ +static void update_equiv_regs (void) { rtx_insn *insn; @@ -3343,10 +3338,6 @@ update_equiv_regs (void) bitmap cleared_regs; bool *pdx_subregs; - /* We need to keep track of whether or not we recorded a LABEL_REF so - that we know if the jump optimizer needs to be rerun. */ - recorded_label_ref = 0; - /* Use pdx_subregs to show whether a reg is used in a paradoxical subreg. */ pdx_subregs = XCNEWVEC (bool, max_regno); @@ -3578,17 +3569,6 @@ update_equiv_regs (void) = gen_rtx_INSN_LIST (VOIDmode, insn, ira_reg_equiv[regno].init_insns); - /* Record whether or not we created a REG_EQUIV note for a LABEL_REF. - We might end up substituting the LABEL_REF for uses of the - pseudo here or later. That kind of transformation may turn an - indirect jump into a direct jump, in which case we must rerun the - jump optimizer to ensure that the JUMP_LABEL fields are valid. */ - if (GET_CODE (x) == LABEL_REF - || (GET_CODE (x) == CONST - && GET_CODE (XEXP (x, 0)) == PLUS - && (GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF))) - recorded_label_ref = 1; - reg_equiv[regno].replacement = x; reg_equiv[regno].src_p = &SET_SRC (set); reg_equiv[regno].loop_depth = (short) loop_depth; @@ -3706,9 +3686,9 @@ update_equiv_regs (void) if (! INSN_P (insn)) continue; - /* Don't substitute into a non-local goto, this confuses CFG. */ - if (JUMP_P (insn) - && find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX)) + /* Don't substitute into jumps. indirect_jump_optimize does + this for anything we are prepared to handle. */ + if (JUMP_P (insn)) continue; for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) @@ -3860,11 +3840,50 @@ update_equiv_regs (void) end_alias_analysis (); free (reg_equiv); free (pdx_subregs); - return recorded_label_ref; } - +/* A pass over indirect jumps, converting simple cases to direct jumps. */ +static void +indirect_jump_optimize (void) +{ + basic_block bb; + bool rebuild_p = false; + FOR_EACH_BB_REVERSE_FN (bb, cfun) + { + rtx_insn *insn = BB_END (bb); + if (!JUMP_P (insn)) + continue; + + rtx x = pc_set (insn); + if (!x || !REG_P (SET_SRC (x))) + continue; + + int regno = REGNO (SET_SRC (x)); + if (DF_REG_DEF_COUNT (regno) == 1) + { + rtx_insn *def_insn = DF_REF_INSN (DF_REG_DEF_CHAIN (regno)); + rtx note = find_reg_note (def_insn, REG_LABEL_OPERAND, NULL_RTX); + + if (note) + { + rtx lab = gen_rtx_LABEL_REF (Pmode, XEXP (note, 0)); + if (validate_replace_rtx (SET_SRC (x), lab, insn)) + rebuild_p = true; + } + } + } + + if (rebuild_p) + { + timevar_push (TV_JUMP); + rebuild_jump_labels (get_insns ()); + if (purge_all_dead_edges ()) + delete_unreachable_blocks (); + timevar_pop (TV_JUMP); + } +} + /* Set up fields memory, constant, and invariant from init_insns in the structures of array ira_reg_equiv. */ static void @@ -5090,7 +5109,6 @@ ira (FILE *f) { bool loops_p; int ira_max_point_before_emit; - int rebuild_p; bool saved_flag_caller_saves = flag_caller_saves; enum ira_region saved_flag_ira_region = flag_ira_region; @@ -5167,6 +5185,10 @@ ira (FILE *f) df_clear_flags (DF_NO_INSN_RESCAN); + indirect_jump_optimize (); + if (delete_trivially_dead_insns (get_insns (), max_reg_num ())) + df_analyze (); + regstat_init_n_sets_and_refs (); regstat_compute_ri (); @@ -5184,32 +5206,12 @@ ira (FILE *f) if (resize_reg_info () && flag_ira_loop_pressure) ira_set_pseudo_classes (true, ira_dump_file); - rebuild_p = update_equiv_regs (); + update_equiv_regs (); setup_reg_equiv (); setup_reg_equiv_init (); - bool update_regstat = false; - - if (optimize && rebuild_p) - { - timevar_push (TV_JUMP); - rebuild_jump_labels (get_insns ()); - if (purge_all_dead_edges ()) - { - delete_unreachable_blocks (); - update_regstat = true; - } - timevar_pop (TV_JUMP); - } - allocated_reg_info_size = max_reg_num (); - if (delete_trivially_dead_insns (get_insns (), max_reg_num ())) - { - df_analyze (); - update_regstat = true; - } - /* It is not worth to do such improvement when we use a simple allocation because of -O0 usage or because the function is too big. */ @@ -5319,7 +5321,7 @@ ira (FILE *f) check_allocation (); #endif - if (update_regstat || max_regno != max_regno_before_ira) + if (max_regno != max_regno_before_ira) { regstat_free_n_sets_and_refs (); regstat_free_ri (); diff --git a/gcc/testsuite/gcc.dg/pr69195.c b/gcc/testsuite/gcc.dg/pr69195.c new file mode 100644 index 0000000..af373a1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr69195.c @@ -0,0 +1,27 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-dce -fno-forward-propagate" } */ + +void __attribute__ ((noinline, noclone)) +foo (int *a, int n) +{ + int *lasta = a + n; + for (; a != lasta; a++) + { + *a *= 2; + a[1] = a[-1] + a[-2]; + } +} + +int +main () +{ + int a[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + int r[16] = { 1, 2, 6, 6, 16, 24, 44, 80, + 136, 248, 432, 768, 1360, 2400, 4256, 3760 }; + unsigned i; + foo (&a[2], 13); + for (i = 0; i < 8; ++i) + if (a[i] != r[i]) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr69238.c b/gcc/testsuite/gcc.dg/pr69238.c new file mode 100644 index 0000000..3538e63 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr69238.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-dce -fno-forward-propagate -fno-rerun-cse-after-loop -funroll-loops" } */ + + +#define N 32 + +short sa[N]; +short sb[N]; +int ia[N]; +int ib[N]; + +int __attribute__ ((noinline, noclone)) +main1 (int n) +{ + int i; + for (i = 0; i < n; i++) + { + sa[i+7] = sb[i]; + ia[i+3] = ib[i+1]; + } + return 0; +} + +int +main (void) +{ + return main1 (N-7); +}