From patchwork Mon Oct 4 21:37:54 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Ellcey X-Patchwork-Id: 66741 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 7C04BB70D3 for ; Tue, 5 Oct 2010 08:38:15 +1100 (EST) Received: (qmail 18665 invoked by alias); 4 Oct 2010 21:38:11 -0000 Received: (qmail 18565 invoked by uid 22791); 4 Oct 2010 21:38:10 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL, BAYES_00, TW_RW, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from g5t0007.atlanta.hp.com (HELO g5t0007.atlanta.hp.com) (15.192.0.44) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 04 Oct 2010 21:38:03 +0000 Received: from g5t0029.atlanta.hp.com (g5t0029.atlanta.hp.com [16.228.8.141]) by g5t0007.atlanta.hp.com (Postfix) with ESMTP id E204814033; Mon, 4 Oct 2010 21:38:01 +0000 (UTC) Received: from lucas.cup.hp.com (lucas.cup.hp.com [15.244.97.116]) by g5t0029.atlanta.hp.com (Postfix) with ESMTP id 6A78620176; Mon, 4 Oct 2010 21:37:56 +0000 (UTC) Received: (from sje@localhost) by lucas.cup.hp.com (8.11.1 (PHNE_35485)/8.11.1) id o94LbsH28988; Mon, 4 Oct 2010 14:37:54 -0700 (PDT) Date: Mon, 4 Oct 2010 14:37:54 -0700 (PDT) From: Steve Ellcey Message-Id: <201010042137.o94LbsH28988@lucas.cup.hp.com> To: gcc-patches@gcc.gnu.org, wilson@codesourcery.com Subject: [patch, ia64] Patch for PR36898 & PR43760, predicated reg conflict warning Reply-to: sje@cup.hp.com 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 In looking at PR36898 and PR43760, where the GNU assembler on IA64 is putting out messages about possibly conflicting register usages, the problem is that the usages aren't conflicting because the usages are predicated and the predicate registers used are never both true but the assembler doesn't know this because GCC isn't putting out enough .pred.mutex psuedo-ops. After trying to fix this by having GCC put out better '.pred.mutex' psuedo-ops to tell the assembler that the usages aren't conflicting and not having much success, I wondered if it would be easier to just not use (possibly) conflicting registers in the same instruction bundle and make GCC more conservative in it's instruction bundling. I made the change in my local build tree and ran the SPEC2006 tests to see what the performance impact would be. For SPECint the slowdown averaged around 0.5% (between .02% and .79% depending on the options) and in SPECfp it was around 0.15% (between .06% and .24%). The tests were run under HP-UX in 32 and 64 bit modes and with -O2 and -O3. I think the slowdown is small enough that this is a reasonable fix for the problem. So I would like to check in this change to IA64 to simply not do multiple predicated loads or stores in a single bundle (using the same register). Any comments? If I don't hear any objections I will check it in. Steve Ellcey sje@cup.hp.com 2010-10-04 Steve Ellcey PR target/36898 PR middle-end/43760 * config/ia64/ia64.c (rws_access_regno): Remove predicate check. Index: config/ia64/ia64.c =================================================================== --- config/ia64/ia64.c (revision 164824) +++ config/ia64/ia64.c (working copy) @@ -5874,15 +5874,14 @@ rws_access_regno (int regno, struct reg_ break; case 1: - /* The register has been written via a predicate. If this is - not a complementary predicate, then we need a barrier. */ - /* ??? This assumes that P and P+1 are always complementary - predicates for P even. */ + /* The register has been written via a predicate. Treat + it like a unconditional write and do not try to check + for complementary pred reg in earlier write. */ if (flags.is_and && rws_sum[regno].written_by_and) ; else if (flags.is_or && rws_sum[regno].written_by_or) ; - else if ((rws_sum[regno].first_pred ^ 1) != pred) + else need_barrier = 1; if (!in_safe_group_barrier) rws_update (regno, flags, pred); @@ -5943,12 +5942,9 @@ rws_access_regno (int regno, struct reg_ break; case 1: - /* The register has been written via a predicate. If this is - not a complementary predicate, then we need a barrier. */ - /* ??? This assumes that P and P+1 are always complementary - predicates for P even. */ - if ((rws_sum[regno].first_pred ^ 1) != pred) - need_barrier = 1; + /* The register has been written via a predicate, assume we + need a barrier (don't check for complementary regs). */ + need_barrier = 1; break; case 2: ========= Test case change: 2010-10-04 Steve Ellcey * gcc.c-torture/compile/920625-1.c: Remove dg-prune-output lines. Index: gcc.c-torture/compile/920625-1.c =================================================================== --- gcc.c-torture/compile/920625-1.c (revision 164824) +++ gcc.c-torture/compile/920625-1.c (working copy) @@ -1,22 +1,3 @@ -/* The problem on IA-64 is that if-conversion creates a sequence - - (p17) cmp.geu p6, p7 = r48, r15 - (p16) cmp.gtu p6, p7 = r48, r15 - - where p16 and p17 are complemenary, but the assembler DV validation - code doesn't recognize that p6 and p7 are complimentary, and so - we end up warning for a later use - - (p6) addl r14 = 1, r0 - (p7) mov r14 = r0 - - that appears to be a WAW violation. */ - -/* { dg-prune-output "Assembler messages" } */ -/* { dg-prune-output "violate\[^\n\]*dependency" } */ -/* { dg-prune-output "first path encountering" } */ -/* { dg-prune-output "location of the conflicting" } */ - typedef unsigned long int unsigned_word; typedef signed long int signed_word; typedef unsigned_word word;