From patchwork Thu Mar 1 16:53:53 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Oliva X-Patchwork-Id: 144073 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 2C5F81007D4 for ; Fri, 2 Mar 2012 03:54:24 +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=1331225665; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Received:From:To:Subject:Date:Message-ID: User-Agent:MIME-Version:Content-Type:Mailing-List:Precedence: List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=dVCvlU/hm+adkV3FNr1b8kBiybc=; b=CWNuMQAzyEXOtlP 59h9kScK9SjHwNPBkx8bsb/C/xtZSy58ltqGJfsijtRiknW+o0kaPCrkS0kV0EW1 QmuYzgbsQV0v2baV2c3Rmin2HlrFPQ3VAwoI8F0Y77rSysNGoBqVsjPA7l0sNIKV gbdQN/DzKbB5ySLgInclCfmamGkw= 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:Received:From:To:Subject:Date:Message-ID:User-Agent:MIME-Version:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=bKK/nVZM8J9tVZFmUKnQ21782DliIoKdx8kpqfZfuAlPJiHkdP/ly7rNjYXYW2 7A/SJjY4PDAwgG8tRkiX/rGntRjr87aAeeroRlYX0UUnWH2XacDVR6wXLA0rVuUi aWgoiB+8E8phL3bAIo0HKZ0AsoPQPJ/4AXOAXB3IELlPM=; Received: (qmail 23630 invoked by alias); 1 Mar 2012 16:54:19 -0000 Received: (qmail 23617 invoked by uid 22791); 1 Mar 2012 16:54:17 -0000 X-SWARE-Spam-Status: No, hits=-5.9 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD, T_TVD_MIME_NO_HEADERS 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; Thu, 01 Mar 2012 16:53:59 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q21GrvYE018587 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 1 Mar 2012 11:53:58 -0500 Received: from freie.oliva.athome.lsd.ic.unicamp.br (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q21GruID005256 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 1 Mar 2012 11:53:57 -0500 Received: from livre.localdomain (livre-to-gw.oliva.athome.lsd.ic.unicamp.br [172.31.160.19]) by freie.oliva.athome.lsd.ic.unicamp.br (8.14.5/8.14.5) with ESMTP id q21GrtMP013907 for ; Thu, 1 Mar 2012 13:53:55 -0300 Received: from livre.localdomain (aoliva@localhost.localdomain [127.0.0.1]) by livre.localdomain (8.14.3/8.14.3/Debian-5+lenny1) with ESMTP id q21Grsqs007567; Thu, 1 Mar 2012 13:53:54 -0300 Received: (from aoliva@localhost) by livre.localdomain (8.14.3/8.14.3/Submit) id q21GrrBb007565; Thu, 1 Mar 2012 13:53:53 -0300 From: Alexandre Oliva To: gcc-patches@gcc.gnu.org Subject: [PR52417] restore get_addr behavior for passes other than VT Date: Thu, 01 Mar 2012 13:53:53 -0300 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 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 The PR52001 alias.c patch meant to avoid infinite recursion among permanent equivalences within VTA introduced some relatively expensive behavior that showed up as (apparently?)-infinite recursion within dse on AVR for one gcc.c-torture/compile test. This patch reworks get_addr so that it behaves exactly as before when permanent equivalences are not in use (i.e., any pass other than var tracking) and retains the heuristics that avoids infinite recursion only when permanent equivalences are present, when needed. Regstrapped on x86_64-linux-gnu and i686-pc-linux-gnu, compile-time tested for the given AVR testcase, approved (minus the comment before the newly-added function) by Jakub in bugzilla, checking in. for gcc/ChangeLog from Alexandre Oliva PR debug/52001 PR rtl-optimization/52417 * cselib.c (cselib_any_perm_equivs): New variable. (cselib_reset_table): Check that it's not set when not preserving constants. (cselib_add_permanent_equiv): Set it. (cselib_have_permanent_equivalences): New. (cselib_init, cselib_finish): Reset it. * cselib.h (cselib_have_permanent_equivalences): Declare. * alias.c (get_addr): Restore earlier behavior when there aren't permanent equivalences. Index: gcc/alias.c =================================================================== --- gcc/alias.c.orig 2012-03-01 04:25:47.348625625 -0300 +++ gcc/alias.c 2012-03-01 07:49:11.000000000 -0300 @@ -1811,20 +1811,34 @@ get_addr (rtx x) v = CSELIB_VAL_PTR (x); if (v) { - v = canonical_cselib_val (v); + bool have_equivs = cselib_have_permanent_equivalences (); + if (have_equivs) + v = canonical_cselib_val (v); for (l = v->locs; l; l = l->next) if (CONSTANT_P (l->loc)) return l->loc; for (l = v->locs; l; l = l->next) - if (!REG_P (l->loc) && !MEM_P (l->loc) && GET_CODE (l->loc) != VALUE - && !refs_newer_value_p (l->loc, x)) + if (!REG_P (l->loc) && !MEM_P (l->loc) + /* Avoid infinite recursion when potentially dealing with + var-tracking artificial equivalences, by skipping the + equivalences themselves, and not choosing expressions + that refer to newer VALUEs. */ + && (!have_equivs + || (GET_CODE (l->loc) != VALUE + && !refs_newer_value_p (l->loc, x)))) return l->loc; - for (l = v->locs; l; l = l->next) - if (REG_P (l->loc) || (GET_CODE (l->loc) != VALUE - && !refs_newer_value_p (l->loc, x))) - return l->loc; - /* Return the canonical value. */ - return v->val_rtx; + if (have_equivs) + { + for (l = v->locs; l; l = l->next) + if (REG_P (l->loc) + || (GET_CODE (l->loc) != VALUE + && !refs_newer_value_p (l->loc, x))) + return l->loc; + /* Return the canonical value. */ + return v->val_rtx; + } + if (v->locs) + return v->locs->loc; } return x; } Index: gcc/cselib.c =================================================================== --- gcc/cselib.c.orig 2012-03-01 07:44:32.426668955 -0300 +++ gcc/cselib.c 2012-03-01 13:15:07.000000000 -0300 @@ -52,6 +52,7 @@ struct elt_list { static bool cselib_record_memory; static bool cselib_preserve_constants; +static bool cselib_any_perm_equivs; static int entry_and_rtx_equal_p (const void *, const void *); static hashval_t get_value_hash (const void *); static struct elt_list *new_elt_list (struct elt_list *, cselib_val *); @@ -477,7 +478,10 @@ cselib_reset_table (unsigned int num) if (cselib_preserve_constants) htab_traverse (cselib_hash_table, preserve_constants_and_equivs, NULL); else - htab_empty (cselib_hash_table); + { + htab_empty (cselib_hash_table); + gcc_checking_assert (!cselib_any_perm_equivs); + } n_useless_values = 0; n_useless_debug_values = 0; @@ -2388,6 +2392,8 @@ cselib_add_permanent_equiv (cselib_val * if (nelt != elt) { + cselib_any_perm_equivs = true; + if (!PRESERVED_VALUE_P (nelt->val_rtx)) cselib_preserve_value (nelt); @@ -2397,6 +2403,14 @@ cselib_add_permanent_equiv (cselib_val * cselib_current_insn = save_cselib_current_insn; } +/* Return TRUE if any permanent equivalences have been recorded since + the table was last initialized. */ +bool +cselib_have_permanent_equivalences (void) +{ + return cselib_any_perm_equivs; +} + /* There is no good way to determine how many elements there can be in a PARALLEL. Since it's fairly cheap, use a really large number. */ #define MAX_SETS (FIRST_PSEUDO_REGISTER * 2) @@ -2651,6 +2665,7 @@ cselib_init (int record_what) value_pool = create_alloc_pool ("value", RTX_CODE_SIZE (VALUE), 100); cselib_record_memory = record_what & CSELIB_RECORD_MEMORY; cselib_preserve_constants = record_what & CSELIB_PRESERVE_CONSTANTS; + cselib_any_perm_equivs = false; /* (mem:BLK (scratch)) is a special mechanism to conflict with everything, see canon_true_dependence. This is only created once. */ @@ -2684,6 +2699,7 @@ cselib_finish (void) { cselib_discard_hook = NULL; cselib_preserve_constants = false; + cselib_any_perm_equivs = false; cfa_base_preserved_val = NULL; cfa_base_preserved_regno = INVALID_REGNUM; free_alloc_pool (elt_list_pool); Index: gcc/cselib.h =================================================================== --- gcc/cselib.h.orig 2012-03-01 07:44:32.875663665 -0300 +++ gcc/cselib.h 2012-03-01 07:49:24.608222578 -0300 @@ -98,6 +98,7 @@ extern bool cselib_preserved_value_p (cs extern void cselib_preserve_only_values (void); extern void cselib_preserve_cfa_base_value (cselib_val *, unsigned int); extern void cselib_add_permanent_equiv (cselib_val *, rtx, rtx); +extern bool cselib_have_permanent_equivalences (void); extern void dump_cselib_table (FILE *);