Patchwork [ia64] Patch for PR36898 & PR43760, predicated reg conflict warning

login
register
mail settings
Submitter Steve Ellcey
Date Oct. 4, 2010, 9:37 p.m.
Message ID <201010042137.o94LbsH28988@lucas.cup.hp.com>
Download mbox | patch
Permalink /patch/66741/
State New
Headers show

Comments

Steve Ellcey - Oct. 4, 2010, 9:37 p.m.
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  <sje@cup.hp.com>

	PR target/36898
	PR middle-end/43760
	* config/ia64/ia64.c (rws_access_regno): Remove predicate check.
Jim Wilson - Oct. 23, 2010, 8:12 p.m.
On Mon, 2010-10-04 at 14:37 -0700, Steve Ellcey wrote:
> 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.

It seems like a reasonable short term workaround, though it would be
better if the comments actually explained why we are doing the wrong
thing here.  It isn't a good idea to disable an optimization without
documenting why it has been disabled.

FYI I have left CodeSourcery and am Cisco now, so you will have to use
my tuliptree.org email address for now.  I probably won't be able to do
much until I am settle in at Cisco.  I'm busy dealing with the job
change and related activities.

Jim

Patch

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  <sje@cup.hp.com>

	* 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;