This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH,updated] PR35371 GCSE loses track of REG_POINTER attribute


This patch fixes PR35371, which really is two more issues related to PR28690.
The first was that gcse and loop invariant code motion were generating
pseudos to copy expressions into, but they were not copying over the
REG_POINTER/MEM_POINTER attribute to the new pseudo.  The second issue was
that SYMBOL_REF's were given the same precedence as other RTX_CONST_OBJ's
which is lower than registers.  The problem is that we eventually copy the
SYMBOL_REF into a register with REG_POINTER attribute, but by that time,
we're done swapping operands and so we lose.

This has bootstrapped and regtested with no errors on powerpc64-linux and
H.J. kindly SPEC tested this on x86_64 and saw no performance regressions.
Is this ok for mainline?  Is it appropriate for gcc4.3?

Peter

	PR rtl-optimization/35371
	* rtlanal.c: Update copyright years.
	(commutative_operand_precedence): Give SYMBOL_REF's the same precedence
	as REG_POINTER and MEM_POINTER operands.
	* emit-rtl.c (gen_reg_rtx_copy): New function.
	(set_reg_attrs_from_value): Call mark_reg_pointer as appropriate.
	* rtl.h (gen_reg_rtx_copy): Add prototype for new function.
	* gcse.c: Update copyright years.
	(pre_delete): Call gen_reg_rtx_copy.
	(hoist_code): Likewise.
	(build_store_vectors): Likewise.
	(delete_store): Likewise.
	* loop-invariant.c (move_invariant_reg): Likewise.
	Update copyright years.

Index: rtlanal.c
===================================================================
--- rtlanal.c	(revision 133772)
+++ rtlanal.c	(working copy)
@@ -1,6 +1,6 @@
 /* Analyze RTL for GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software
    Foundation, Inc.
 
 This file is part of GCC.
@@ -2898,6 +2898,8 @@ commutative_operand_precedence (rtx op)
   switch (GET_RTX_CLASS (code))
     {
     case RTX_CONST_OBJ:
+      if (code == SYMBOL_REF)
+	return -1;
       if (code == CONST_INT)
         return -6;
       if (code == CONST_DOUBLE)
Index: gcse.c
===================================================================
--- gcse.c	(revision 133772)
+++ gcse.c	(working copy)
@@ -1,7 +1,7 @@
 /* Global common subexpression elimination/Partial redundancy elimination
    and global constant/copy propagation for GNU compiler.
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007 Free Software Foundation, Inc.
+   2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -4463,8 +4463,7 @@ pre_delete (void)
 		   expressions into.  Get the mode for the new pseudo from
 		   the mode of the original destination pseudo.  */
 		if (expr->reaching_reg == NULL)
-		  expr->reaching_reg
-		    = gen_reg_rtx (GET_MODE (SET_DEST (set)));
+		  expr->reaching_reg = gen_reg_rtx_copy (SET_DEST (set));
 
 		gcse_emit_move_after (expr->reaching_reg, SET_DEST (set), insn);
 		delete_insn (insn);
@@ -4988,7 +4987,7 @@ hoist_code (void)
 			 from the mode of the original destination pseudo.  */
 		      if (expr->reaching_reg == NULL)
 			expr->reaching_reg
-			  = gen_reg_rtx (GET_MODE (SET_DEST (set)));
+			  = gen_reg_rtx_copy (SET_DEST (set));
 
 		      gcse_emit_move_after (expr->reaching_reg, SET_DEST (set), insn);
 		      delete_insn (insn);
@@ -6121,7 +6120,7 @@ build_store_vectors (void)
 	     are any side effects.  */
 	  if (TEST_BIT (ae_gen[bb->index], ptr->index))
 	    {
-	      rtx r = gen_reg_rtx (GET_MODE (ptr->pattern));
+	      rtx r = gen_reg_rtx_copy (ptr->pattern);
 	      if (dump_file)
 		fprintf (dump_file, "Removing redundant store:\n");
 	      replace_store_insn (r, XEXP (st, 0), bb, ptr);
@@ -6444,7 +6443,7 @@ delete_store (struct ls_expr * expr, bas
   rtx reg, i, del;
 
   if (expr->reaching_reg == NULL_RTX)
-    expr->reaching_reg = gen_reg_rtx (GET_MODE (expr->pattern));
+    expr->reaching_reg = gen_reg_rtx_copy (expr->pattern);
 
   reg = expr->reaching_reg;
 
Index: emit-rtl.c
===================================================================
--- emit-rtl.c	(revision 133772)
+++ emit-rtl.c	(working copy)
@@ -964,11 +964,32 @@ set_reg_attrs_from_value (rtx reg, rtx x
   int offset;
 
   offset = byte_lowpart_offset (GET_MODE (reg), GET_MODE (x));
-  if (MEM_P (x) && MEM_OFFSET (x) && GET_CODE (MEM_OFFSET (x)) == CONST_INT)
-    REG_ATTRS (reg)
-      = get_reg_attrs (MEM_EXPR (x), INTVAL (MEM_OFFSET (x)) + offset);
-  if (REG_P (x) && REG_ATTRS (x))
-    update_reg_offset (reg, x, offset);
+  if (MEM_P (x))
+    {
+      if (MEM_OFFSET (x) && GET_CODE (MEM_OFFSET (x)) == CONST_INT)
+	REG_ATTRS (reg)
+	  = get_reg_attrs (MEM_EXPR (x), INTVAL (MEM_OFFSET (x)) + offset);
+      if (MEM_POINTER (x))
+	mark_reg_pointer (reg, MEM_ALIGN (x));
+    }
+  else if (REG_P (x))
+    {
+      if (REG_ATTRS (x))
+	update_reg_offset (reg, x, offset);
+      if (REG_POINTER (x))
+	mark_reg_pointer (reg, REGNO_POINTER_ALIGN (REGNO (x)));
+    }
+}
+
+/* Generate a REG rtx for a new pseudo register, copying the mode
+   and attributes from X.  */
+
+rtx
+gen_reg_rtx_copy (rtx x)
+{
+  rtx reg = gen_reg_rtx (GET_MODE (x));
+  set_reg_attrs_from_value (reg, x);
+  return reg;
 }
 
 /* Set the register attributes for registers contained in PARM_RTX.
Index: loop-invariant.c
===================================================================
--- loop-invariant.c	(revision 133772)
+++ loop-invariant.c	(working copy)
@@ -1,5 +1,5 @@
 /* RTL-level loop invariant motion.
-   Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -1193,7 +1193,7 @@ move_invariant_reg (struct loop *loop, u
 	 need to create a temporary register.  */
       set = single_set (inv->insn);
       dest = SET_DEST (set);
-      reg = gen_reg_rtx (GET_MODE (dest));
+      reg = gen_reg_rtx_copy (dest);
 
       /* Try replacing the destination by a new pseudoregister.  */
       if (!validate_change (inv->insn, &SET_DEST (set), reg, false))
Index: rtl.h
===================================================================
--- rtl.h	(revision 133772)
+++ rtl.h	(working copy)
@@ -1502,6 +1502,7 @@ extern rtvec gen_rtvec_v (int, rtx *);
 extern rtx gen_reg_rtx (enum machine_mode);
 extern rtx gen_rtx_REG_offset (rtx, enum machine_mode, unsigned int, int);
 extern rtx gen_reg_rtx_offset (rtx, enum machine_mode, int);
+extern rtx gen_reg_rtx_copy (rtx);
 extern rtx gen_label_rtx (void);
 extern rtx gen_lowpart_common (enum machine_mode, rtx);
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]