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] Tweak var-tracking to better handle x86-64 lea insns


Hi!

Usually when a lea pattern is used in x86-64 code we generate
suboptimial debug info when the target reg is clobbered.  The
problem is that cselib doesn't handle very well mixing modes on the same
register.  Such code usually uses SImode regs, but then a
(set (reg:SI) (subreg:SI (plus:DI (reg:DI) (const_int)) 0))
etc. lea pattern is used, when it really means
(set (reg:SI) (plus:SI (reg:SI) (const_int))).

The following patch transforms the first representation into the latter
if cselib doesn't track currently the used registers in the wider mode
for var-tracking purposes.  On i686-linux this obviously doesn't make
any changes, on x86_64-linux it fixes:
-FAIL: gcc.dg/guality/pr43177.c  -O1  line 24 x == 7
-FAIL: gcc.dg/guality/pr43177.c  -O2  line 24 x == 7
-FAIL: gcc.dg/guality/pr43177.c  -O3 -fomit-frame-pointer  line 24 x == 7
-FAIL: gcc.dg/guality/pr43177.c  -O3 -g  line 24 x == 7
-FAIL: gcc.dg/guality/pr43177.c  -Os  line 24 x == 7
-FAIL: gcc.dg/guality/pr43177.c  -O2 -flto  line 24 x == 7
-FAIL: gcc.dg/guality/pr43177.c  -O2 -fwhopr  line 24 x == 7
the number of DIEs with DW_AT_location in cc1plus grows from
313918 to 314685 and .debug_loc grows by 51KB.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2010-03-29  Jakub Jelinek  <jakub@redhat.com>

	* var-tracking.c (use_narrower_mode_p, use_narrower_mode): New
	functions.
	(adjust_mems): Replace narrowing SUBREG of expression containing
	just PLUS, MINUS, MULT and ASHIFT of registers and constants
	with operations in the narrower mode.

--- gcc/var-tracking.c.jj	2010-03-26 20:48:09.000000000 +0100
+++ gcc/var-tracking.c	2010-03-29 15:47:15.000000000 +0200
@@ -729,6 +729,65 @@ struct adjust_mem_data
   rtx side_effects;
 };
 
+/* Helper for adjust_mems.  Return 1 if *loc is unsuitable for
+   transformation of wider mode arithmetics to narrower mode,
+   -1 if it is suitable and subexpressions shouldn't be
+   traversed and 0 if it is suitable and subexpressions should
+   be traversed.  */
+
+static int
+use_narrower_mode_p (rtx *loc, void *data)
+{
+  rtx subreg = (rtx) data;
+
+  if (CONSTANT_P (*loc))
+    return -1;
+  switch (GET_CODE (*loc))
+    {
+    case REG:
+      if (cselib_lookup (*loc, GET_MODE (SUBREG_REG (subreg)), 0))
+	return 1;
+      return -1;
+    case PLUS:
+    case MINUS:
+    case MULT:
+      return 0;
+    case ASHIFT:
+      if (for_each_rtx (&XEXP (*loc, 0), use_narrower_mode_p, data))
+	return 1;
+      else
+	return -1;
+    default:
+      return 1;
+    }
+}
+
+/* Transform X into narrower mode MODE from wider mode WMODE.  */
+
+static rtx
+use_narrower_mode (rtx x, enum machine_mode mode, enum machine_mode wmode)
+{
+  rtx op0, op1;
+  if (CONSTANT_P (x))
+    return lowpart_subreg (mode, x, wmode);
+  switch (GET_CODE (x))
+    {
+    case REG:
+      return lowpart_subreg (mode, x, wmode);
+    case PLUS:
+    case MINUS:
+    case MULT:
+      op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
+      op1 = use_narrower_mode (XEXP (x, 1), mode, wmode);
+      return simplify_gen_binary (GET_CODE (x), mode, op0, op1);
+    case ASHIFT:
+      op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
+      return simplify_gen_binary (ASHIFT, mode, op0, XEXP (x, 1));
+    default:
+      gcc_unreachable ();
+    }
+}
+
 /* Helper function for adjusting used MEMs.  */
 
 static rtx
@@ -822,18 +879,36 @@ adjust_mems (rtx loc, const_rtx old_rtx,
       amd->store = store_save;
       mem = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
       if (mem == SUBREG_REG (loc))
-	return loc;
+	{
+	  tem = loc;
+	  goto finish_subreg;
+	}
       tem = simplify_gen_subreg (GET_MODE (loc), mem,
 				 GET_MODE (SUBREG_REG (loc)),
 				 SUBREG_BYTE (loc));
       if (tem)
-	return tem;
+	goto finish_subreg;
       tem = simplify_gen_subreg (GET_MODE (loc), addr,
 				 GET_MODE (SUBREG_REG (loc)),
 				 SUBREG_BYTE (loc));
-      if (tem)
-	return tem;
-      return gen_rtx_raw_SUBREG (GET_MODE (loc), addr, SUBREG_BYTE (loc));
+      if (tem == NULL_RTX)
+	tem = gen_rtx_raw_SUBREG (GET_MODE (loc), addr, SUBREG_BYTE (loc));
+    finish_subreg:
+      if (MAY_HAVE_DEBUG_INSNS
+	  && GET_CODE (tem) == SUBREG
+	  && (GET_CODE (SUBREG_REG (tem)) == PLUS
+	      || GET_CODE (SUBREG_REG (tem)) == MINUS
+	      || GET_CODE (SUBREG_REG (tem)) == MULT
+	      || GET_CODE (SUBREG_REG (tem)) == ASHIFT)
+	  && GET_MODE_CLASS (GET_MODE (tem)) == MODE_INT
+	  && GET_MODE_CLASS (GET_MODE (SUBREG_REG (tem))) == MODE_INT
+	  && GET_MODE_SIZE (GET_MODE (tem))
+	     < GET_MODE_SIZE (GET_MODE (SUBREG_REG (tem)))
+	  && subreg_lowpart_p (tem)
+	  && !for_each_rtx (&SUBREG_REG (tem), use_narrower_mode_p, tem))
+	return use_narrower_mode (SUBREG_REG (tem), GET_MODE (tem),
+				  GET_MODE (SUBREG_REG (tem)));
+      return tem;
     default:
       break;
     }

	Jakub


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