From patchwork Thu Jul 22 18:00:57 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Bosscher X-Patchwork-Id: 59620 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 CE2BBB70BE for ; Fri, 23 Jul 2010 04:01:11 +1000 (EST) Received: (qmail 21122 invoked by alias); 22 Jul 2010 18:01:09 -0000 Received: (qmail 20960 invoked by uid 22791); 22 Jul 2010 18:01:07 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Received: from mail-bw0-f47.google.com (HELO mail-bw0-f47.google.com) (209.85.214.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 22 Jul 2010 18:01:01 +0000 Received: by bwz10 with SMTP id 10so1370760bwz.20 for ; Thu, 22 Jul 2010 11:00:58 -0700 (PDT) MIME-Version: 1.0 Received: by 10.239.160.19 with SMTP id a19mr216640hbd.56.1279821657948; Thu, 22 Jul 2010 11:00:57 -0700 (PDT) Received: by 10.239.140.201 with HTTP; Thu, 22 Jul 2010 11:00:57 -0700 (PDT) Date: Thu, 22 Jul 2010 20:00:57 +0200 Message-ID: Subject: [patch] merge true_dependence and canon_true_dependence From: Steven Bosscher To: GCC Patches 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, These two functions are almost the same, so let's merge them. This also uncovered that canon_true_dependence was missing one check that true_dependence checked for (the case when base is a constant pool address). Just shows that merging these two functions is a Good Thing. Bootstrapped&tested on x86_64-unknown-linux-gnu. OK for trunk? Ciao! Steven * alias.c (true_dependence_1): New function, merged version of true_dependence and canon_true_dependence. (true_dependence): Simplify. (canon_true_dependence): Simplify. Index: alias.c =================================================================== --- alias.c (revision 162421) +++ alias.c (working copy) @@ -2317,16 +2317,30 @@ nonoverlapping_memrefs_p (const_rtx x, c return sizex >= 0 && offsety >= offsetx + sizex; } -/* True dependence: X is read after store in MEM takes place. */ +/* Helper for true_dependence and canon_true_dependence. + Checks for true dependence: X is read after store in MEM takes place. -int -true_dependence (const_rtx mem, enum machine_mode mem_mode, const_rtx x, - bool (*varies) (const_rtx, bool)) + VARIES is the function that should be used as rtx_varies function. + + If MEM_CANONICALIZED is FALSE, then X_ADDR and MEM_ADDR should be + NULL_RTX, and the canonical addresses of MEM and X are both computed + here. If MEM_CANONICALIZED, then MEM must be already canonicalized. + + If X_ADDR is non-NULL, it is used in preference of XEXP (x, 0). + + Returns 1 if there is a true dependence, 0 otherwise. */ + +static int +true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr, + const_rtx x, rtx x_addr, bool (*varies) (const_rtx, bool), + bool mem_canonicalized) { - rtx x_addr, mem_addr; rtx base; int ret; + gcc_checking_assert (mem_canonicalized ? (mem_addr != NULL_RTX) + : (mem_addr == NULL_RTX && x_addr == NULL_RTX)); + if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) return 1; @@ -2352,11 +2366,16 @@ true_dependence (const_rtx mem, enum mac if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) return 1; - if (mem_mode == VOIDmode) - mem_mode = GET_MODE (mem); + if (! mem_addr) + { + mem_addr = XEXP (mem, 0); + if (mem_mode == VOIDmode) + mem_mode = GET_MODE (mem); + } + + if (! x_addr) + x_addr = XEXP (x, 0); - x_addr = XEXP (x, 0); - mem_addr = XEXP (mem, 0); if (!((GET_CODE (x_addr) == VALUE && GET_CODE (mem_addr) != VALUE && reg_mentioned_p (x_addr, mem_addr)) @@ -2365,7 +2384,8 @@ true_dependence (const_rtx mem, enum mac && reg_mentioned_p (mem_addr, x_addr)))) { x_addr = get_addr (x_addr); - mem_addr = get_addr (mem_addr); + if (!mem_canonicalized) + mem_addr = get_addr (mem_addr); } base = find_base_term (x_addr); @@ -2378,7 +2398,8 @@ true_dependence (const_rtx mem, enum mac return 0; x_addr = canon_rtx (x_addr); - mem_addr = canon_rtx (mem_addr); + if (!mem_canonicalized) + mem_addr = canon_rtx (mem_addr); if ((ret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr, SIZE_FOR_MODE (x), x_addr, 0)) != -1) @@ -2394,11 +2415,11 @@ true_dependence (const_rtx mem, enum mac return 1; /* We cannot use aliases_everything_p to test MEM, since we must look - at MEM_MODE, rather than GET_MODE (MEM). */ + at MEM_ADDR, rather than XEXP (mem, 0). */ if (mem_mode == QImode || GET_CODE (mem_addr) == AND) return 1; - /* In true_dependence we also allow BLKmode to alias anything. Why + /* ??? In true_dependence we also allow BLKmode to alias anything. Why don't we do this in anti_dependence and output_dependence? */ if (mem_mode == BLKmode || GET_MODE (x) == BLKmode) return 1; @@ -2409,87 +2430,30 @@ true_dependence (const_rtx mem, enum mac return rtx_refs_may_alias_p (x, mem, true); } +/* True dependence: X is read after store in MEM takes place. */ + +int +true_dependence (const_rtx mem, enum machine_mode mem_mode, const_rtx x, + bool (*varies) (const_rtx, bool)) +{ + return true_dependence_1 (mem, mem_mode, NULL_RTX, + x, NULL_RTX, varies, + /*mem_canonicalized=*/false); +} + /* Canonical true dependence: X is read after store in MEM takes place. Variant of true_dependence which assumes MEM has already been canonicalized (hence we no longer do that here). - The mem_addr argument has been added, since true_dependence computed - this value prior to canonicalizing. - If x_addr is non-NULL, it is used in preference of XEXP (x, 0). */ + The mem_addr argument has been added, since true_dependence_1 computed + this value prior to canonicalizing. */ int canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr, const_rtx x, rtx x_addr, bool (*varies) (const_rtx, bool)) { - int ret; - - if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) - return 1; - - /* (mem:BLK (scratch)) is a special mechanism to conflict with everything. - This is used in epilogue deallocation functions. */ - if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH) - return 1; - if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH) - return 1; - if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER - || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER) - return 1; - - /* Read-only memory is by definition never modified, and therefore can't - conflict with anything. We don't expect to find read-only set on MEM, - but stupid user tricks can produce them, so don't die. */ - if (MEM_READONLY_P (x)) - return 0; - - /* If we have MEMs refering to different address spaces (which can - potentially overlap), we cannot easily tell from the addresses - whether the references overlap. */ - if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) - return 1; - - if (! x_addr) - { - x_addr = XEXP (x, 0); - if (!((GET_CODE (x_addr) == VALUE - && GET_CODE (mem_addr) != VALUE - && reg_mentioned_p (x_addr, mem_addr)) - || (GET_CODE (x_addr) != VALUE - && GET_CODE (mem_addr) == VALUE - && reg_mentioned_p (mem_addr, x_addr)))) - x_addr = get_addr (x_addr); - } - - if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode)) - return 0; - - x_addr = canon_rtx (x_addr); - if ((ret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr, - SIZE_FOR_MODE (x), x_addr, 0)) != -1) - return ret; - - if (DIFFERENT_ALIAS_SETS_P (x, mem)) - return 0; - - if (nonoverlapping_memrefs_p (x, mem)) - return 0; - - if (aliases_everything_p (x)) - return 1; - - /* We cannot use aliases_everything_p to test MEM, since we must look - at MEM_MODE, rather than GET_MODE (MEM). */ - if (mem_mode == QImode || GET_CODE (mem_addr) == AND) - return 1; - - /* In true_dependence we also allow BLKmode to alias anything. Why - don't we do this in anti_dependence and output_dependence? */ - if (mem_mode == BLKmode || GET_MODE (x) == BLKmode) - return 1; - - if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, varies)) - return 0; - - return rtx_refs_may_alias_p (x, mem, true); + return true_dependence_1 (mem, mem_mode, mem_addr, + x, x_addr, varies, + /*mem_canonicalized=*/true); } /* Returns nonzero if a write to X might alias a previous read from