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] Eliminate eliminable regs even in DEBUG_INSNs


Hi!

int bar (unsigned long *, unsigned long *);

int
foo (void)
{
  unsigned long a = 0, b = 0, c = 0;
  a = bar (&b, &c);
  unsigned long vara = a;
  unsigned long varb = b;
  unsigned long varc = c;
  __asm__ volatile ("" : : "g" (vara), "g" (varb), "g" (varc));
  return a;
}

doesn't get location info for varb and varc, eventhough those clearly have
to be live at the start of the inline asm.  On the trunk there is a problem
in SSA expansion that I'll file a bug about shortly, on the
redhat/gcc-4_4-branch the problem is that we don't eliminate eliminable regs
in DEBUG_INSNs.  So in *.asmcons we have:
(debug_insn 14 13 15 2 Y.ii:7 (var_location:DI D.4294967295 (zero_extend:DI (reg:SI 58 [ D.1605 ]))) -1 (nil))
(debug_insn 15 14 16 2 Y.ii:7 (var_location:DI a (debug_expr:DI D#1)) -1 (nil))
(debug_insn 16 15 17 2 Y.ii:8 (var_location:DI vara (debug_expr:DI D#1)) -1 (nil))
(debug_insn 17 16 18 2 Y.ii:9 (var_location:DI D.4294967294 (mem/c/i:DI (plus:DI (reg/f:DI 20 frame) (const_int -8 [0xfffffffffffffff8])) [2 b+0 S8 A64])) -1 (nil))
(debug_insn 18 17 19 2 Y.ii:9 (var_location:DI varb (debug_expr:DI D#2)) -1 (nil))
(debug_insn 19 18 20 2 Y.ii:10 (var_location:DI D.4294967293 (mem/c/i:DI (plus:DI (reg/f:DI 20 frame) (const_int -16 [0xfffffffffffffff0])) [2 c+0 S8 A64])) -1 (nil))
(debug_insn 20 19 21 2 Y.ii:10 (var_location:DI varc (debug_expr:DI D#3)) -1 (nil))
which matches the inputs of the asm, but in *.ira dump the debug_insns
remain the same, but in asm inputs reg 20 is eliminated to sp + 16.  Then
during DSE2 the debug insns get cleared.

The attached patch fixes this, and on the trunk fixes on i686-linux also
-FAIL: gcc.dg/guality/pr41353-1.c  -O1  line 28 i1 == 2 * 37
-FAIL: gcc.dg/guality/pr41353-1.c  -O1  line 28 i2 == 3 * 37
-FAIL: gcc.dg/guality/pr41353-1.c  -O2  line 28 i1 == 2 * 37
-FAIL: gcc.dg/guality/pr41353-1.c  -O2  line 28 i2 == 3 * 37
-FAIL: gcc.dg/guality/pr41353-1.c  -O3 -fomit-frame-pointer  line 28 i1 == 2 * 37
-FAIL: gcc.dg/guality/pr41353-1.c  -O3 -fomit-frame-pointer  line 28 i2 == 3 * 37
-FAIL: gcc.dg/guality/pr41353-1.c  -O3 -g  line 28 i1 == 2 * 37
-FAIL: gcc.dg/guality/pr41353-1.c  -O3 -g  line 28 i2 == 3 * 37
-FAIL: gcc.dg/guality/pr41353-1.c  -Os  line 28 i1 == 2 * 37
-FAIL: gcc.dg/guality/pr41353-1.c  -Os  line 28 i2 == 3 * 37
In i686-linux cc1 with the patch there are roughly 1500 (0.7%) more DIEs
with DW_AT_location attribute.  In x86_64-linux cc1 it is roughtly 1000 more
such DIEs.

The eliminate_regs_1 changes are to avoid -fcompare-debug differences and
not to crash on (clobber (const_int 0)) that is used in DEBUG_INSNs when no
location is available.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2010-02-10  Jakub Jelinek  <jakub@redhat.com>

	* reload1.c (eliminate_regs_1): If insn is DEBUG_INSN, avoid any
	modifications outside of the DEBUG_INSN.  Accept CLOBBERs inside
	of DEBUG_INSNs.
	(eliminate_regs_in_insn): Eliminate regs even in DEBUG_INSNs.

--- gcc/reload1.c.jj	2010-01-18 17:14:18.000000000 +0100
+++ gcc/reload1.c	2010-02-10 20:48:24.000000000 +0100
@@ -2570,7 +2570,7 @@ eliminate_regs_1 (rtx x, enum machine_mo
       else if (reg_renumber && reg_renumber[regno] < 0
 	       && reg_equiv_invariant && reg_equiv_invariant[regno])
 	{
-	  if (may_use_invariant)
+	  if (may_use_invariant || (insn && DEBUG_INSN_P (insn)))
 	    return eliminate_regs_1 (copy_rtx (reg_equiv_invariant[regno]),
 			             mem_mode, insn, true);
 	  /* There exists at least one use of REGNO that cannot be
@@ -2685,9 +2685,11 @@ eliminate_regs_1 (rtx x, enum machine_mo
 	  if (ep->from_rtx == XEXP (x, 0) && ep->can_eliminate)
 	    {
 	      if (! mem_mode
-		  /* Refs inside notes don't count for this purpose.  */
+		  /* Refs inside notes or in DEBUG_INSNs don't count for
+		     this purpose.  */
 		  && ! (insn != 0 && (GET_CODE (insn) == EXPR_LIST
-				      || GET_CODE (insn) == INSN_LIST)))
+				      || GET_CODE (insn) == INSN_LIST
+				      || DEBUG_INSN_P (insn))))
 		ep->ref_outside_mem = 1;
 
 	      return
@@ -2863,6 +2865,9 @@ eliminate_regs_1 (rtx x, enum machine_mo
       return x;
 
     case CLOBBER:
+      gcc_assert (insn && DEBUG_INSN_P (insn));
+      break;
+
     case ASM_OPERANDS:
     case SET:
       gcc_unreachable ();
@@ -3199,6 +3204,9 @@ eliminate_regs_in_insn (rtx insn, int re
 		  || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
 		  || GET_CODE (PATTERN (insn)) == ASM_INPUT
 		  || DEBUG_INSN_P (insn));
+      if (DEBUG_INSN_P (insn))
+	INSN_VAR_LOCATION_LOC (insn)
+	  = eliminate_regs (INSN_VAR_LOCATION_LOC (insn), VOIDmode, insn);
       return 0;
     }
 


	Jakub


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