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]

Use simplify_replace_rtx rather than wrap_constant


Combine and reload need to substitute into debug_insns.  They currently
do this by storing the "to" value at the location of the "from" value
while leaving the enclosing rtx as-is.  The one exception is that they
handle subregs of the "from" value specially.

However, doing a substitution this way can easily create an invalid rtx.
One particular case that we've already hit is that replacing a
register with a CONST_INT doesn't work inside unary operators
like ZERO_EXTEND and SIGN_EXTEND.  The VTA code gets around this
by using wrap_constant to convert the CONST_INT into a
(const (const_int ...)).

I've whined about that a few times recently.  One of the big advantages
of the VTA approach was that it used the same rvalue IR for both "debug"
insns and "real" insns.  I think using wrap_constant is a severe
deviation from that goal.  We're introducing hitherto invalid CONSTs at
arbitrary places within a var location (not just at the top level rtx),
and many generic rtx routines just aren't prepared to deal with that.
Jakub said that it should just be simplify-rtx.c, var-tracking.c and
consumers of cselib that need to handle them, but I think it goes much
wider than that.  E.g. if reload1.c replaces:

    (plus (reg x) (reg y))

with:

    (plus (reg x) (const (const_int C)))

(which it can easily do) then is that supposed to be rtx_equal_p to:

    (plus (reg x) (const_int C))

or not?  If not, when is the result of the reload1.c substitution
supposed to be canonicalised?  And why leave it in a non-canonical
state until then?

The same question goes if we end up making a substitution that
allows an enclosing rtx to be folded to a constant.  Obviously we
don't want that to happen too often (it would probably indicate
an earlier optimisation failure) but it is still possible.

Besides, losing modes is just one example of where this kind of
substitution can go wrong.  We could also end up creating other
kinds of invalid rtx (or at least non-canonical rtx, which IMO
amounts to the same thing).  E.g. the reload1.c substitution
can replace REGs with PLUS elimination targets, which could
lead to an enclosing commutative rtx having its operands
the wrong way around.

debug_insns can't rely on things like recog or constraints to help
detect some types of invalid change, so I think we should simply say that
any valid rvalue is also a valid var location.  We should then call the
generic function for doing a substitution on an arbitrary rvalue, namely
simplify_replace_rtx.  That's what this patch does.

The combine substitution is an interesting case because, on AUTO_INC_DEC
targets, it creates the "to" value lazily on the first substitution.
That seems like a reasonable thing to want to do, so I generalised
simplify_replace_rtx to allow it.

I made a couple of other changes to simplify_replace_rtx too:

  - It now copies the "to" rtx for each replacement.  All but one caller
    seemed to pass an already-used rtx as the "to" value, so current
    substitutions could create invalid sharing.  I've removed the
    now-redundant copy_rtx from the one caller that used it.

    (Doing the copy lazily seems better, and copes with cases where the
    value is used twice within the same expression.)

  - It now uses rtx_equal_p to check for equivalence.  Some callers seem
    to pass MEM rtxes, which can't be shared, so I think using rtx_equal_p
    is better than relying on pointer equivalence for everything except REGs.
    I scanned the current callers, and none of them seemed to be using
    the function in a way that genuinely required strict pointer
    equivalence.

    rtx_equal_p isn't cheap of course.  We could reduce the overhead
    by turning it into an inline wrapper that first checks whether the
    code and mode are the same (or maybe just the code) and only then
    calls an out-of-line function.

I did wonder about using a generic for_each_rtx-like callback that
could match the "from" rtx in other ways besides rtx_equal_p,
and provide an arbitrary "to" rtx.  However, making an indirect call
for every node carries a fair bit of overhead, so I think it'd be
better to leave things be until we find we need something so general.

The reload1.c loop was structured like this:

 	  for (use = DF_REG_USE_CHAIN (i); use; use = next)
 	    {
              ...
 	      insn = DF_REF_INSN (use);
 	      next = DF_REF_NEXT_REG (use);

which was presumably to cope with the case where we replace the location
with an UNKNOWN_VAR_LOC and call df_insn_rescan_debug_internal.  But if
that's the case, then we should skip all consecutive uses of the register
in INSN, not just the current one.  Doing this in the new code also
avoids a redundant substitution in cases where the insn uses the
register more than once.

TBH, I'm not sure why we needed the other new calls to wrap_constant.
There are no comments to justify them, and no-one's explained them
on the list.  I also couldn't get anything to regress when I removed them.
As mentioned before, things based around cselib_expand_value_rtx
(and similar functions) should always know the mode of the value they're
dealing with; the convention is to pass the mode separately if it isn't
obvious.  So if there are cases where we're losing track of the mode somehow,
I think that needs to be fixed.  And if these calls are instead due to
substitutions like the combine.c and reload1.c ones, then I think we
should be doing the substitution differently.

The patch reinstates cselib's original static wrap_constant, so that
we don't accidentally introduce more uses.  Since the wrapped constants
are entirely local to the hash-table lookup, and aren't even entered
into the hash table, I'm tempted to pass the lookup function an
(on-stack) "rtx, enum machine_mode" pair instead of a plain rtx,
and thus avoid the need to create a throw-away CONST.  I'll send a
follow-on patch for that if this one is OK, and if no-one tells me
it's a bad idea.

I've also removed unwrap_constant, which was added by VTA,
but isn't used.

Finally, I've removed the CONST handling in simplify_unary, even though
it predated VTA.  The code is at odds with the other simplification
routines and isn't explained.  I can't see any reason why we'd want
to lose the knowledge that a constant is a constant.

Bootstrapped & regression-tested on x86_64-linux-gnu.  Also
regression-tested on arm-eabi (for the AUTO_INC_DEC stuff)
and tested against GDB on x86_64-linux-gnu.  OK to install?

I wouldn't be entirely surprised if this patch introduces some post-VTA
regressions that weren't picked up by the usual testing.  But if it does,
I think that's actually a useful thing, because we'll then be able to
pinpoint the places that are doing invalid substitutions, losing the mode,
or whatever.  And if it doesn't introduce any regressions, well, even better!

Richard


gcc/
	* rtl.h (simplify_replace_fn_rtx): Declare.
	(wrap_constant, unwrap_constant): Delete.
	* cfgexpand.c (unwrap_constant, wrap_constant): Delete.
	(expand_debug_expr): Don't call wrap_constant.
	* combine.c (rtx_subst_pair): Only define for AUTO_INC_DEC.
	(auto_adjust_pair): Fold into...
	(propagate_for_debug_subst): ...here.  Only define for AUTO_INC_DEC.
	Just return a new value.
	(propagate_for_debug): Use simplify_replace_fn_rtx for AUTO_INC_DEC,
	otherwise use simplify_replace_rtx.
	* cselib.c (wrap_constant): Reinstate old definition.
	(cselib_expand_value_rtx_1): Don't wrap constants.
	* reload1.c (reload): Skip all uses for an insn before adjusting it.
	Use simplify_replace_rtx.
	* simplify-rtx.c (simplify_replace_fn_rtx): New function, adapted from...
	(simplify_replace_rtx): ...here.  Turn into a wrapper for
	simplify_replace_fn_rtx.
	(simplify_unary_operation): Don't unwrap CONSTs.
	* var-tracking.c (check_wrap_constant): Delete.
	(vt_expand_loc_callback): Don't call it.
	(vt_expand_loc): Likewise.

Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h	2009-09-26 10:43:09.000000000 +0100
+++ gcc/rtl.h	2009-09-26 12:12:29.000000000 +0100
@@ -1765,6 +1765,8 @@ extern rtx simplify_subreg (enum machine
 			    unsigned int);
 extern rtx simplify_gen_subreg (enum machine_mode, rtx, enum machine_mode,
 				unsigned int);
+extern rtx simplify_replace_fn_rtx (rtx, const_rtx,
+				    rtx (*fn) (void *), void *);
 extern rtx simplify_replace_rtx (rtx, const_rtx, rtx);
 extern rtx simplify_rtx (const_rtx);
 extern rtx avoid_constant_pool_reference (rtx);
@@ -2404,8 +2406,6 @@ extern void invert_br_probabilities (rtx
 extern bool expensive_function_p (int);
 /* In cfgexpand.c */
 extern void add_reg_br_prob_note (rtx last, int probability);
-extern rtx wrap_constant (enum machine_mode, rtx);
-extern rtx unwrap_constant (rtx);
 
 /* In var-tracking.c */
 extern unsigned int variable_tracking_main (void);
Index: gcc/cfgexpand.c
===================================================================
--- gcc/cfgexpand.c	2009-09-26 10:43:09.000000000 +0100
+++ gcc/cfgexpand.c	2009-09-26 12:12:29.000000000 +0100
@@ -2194,46 +2194,6 @@ round_udiv_adjust (enum machine_mode mod
      const1_rtx, const0_rtx);
 }
 
-/* Wrap modeless constants in CONST:MODE.  */
-rtx
-wrap_constant (enum machine_mode mode, rtx x)
-{
-  if (GET_MODE (x) != VOIDmode)
-    return x;
-
-  if (CONST_INT_P (x)
-      || GET_CODE (x) == CONST_FIXED
-      || GET_CODE (x) == CONST_DOUBLE
-      || GET_CODE (x) == LABEL_REF)
-    {
-      gcc_assert (mode != VOIDmode);
-
-      x = gen_rtx_CONST (mode, x);
-    }
-
-  return x;
-}
-
-/* Remove CONST wrapper added by wrap_constant().  */
-rtx
-unwrap_constant (rtx x)
-{
-  rtx ret = x;
-
-  if (GET_CODE (x) != CONST)
-    return x;
-
-  x = XEXP (x, 0);
-
-  if (CONST_INT_P (x)
-      || GET_CODE (x) == CONST_FIXED
-      || GET_CODE (x) == CONST_DOUBLE
-      || GET_CODE (x) == LABEL_REF)
-    ret = x;
-
-  return ret;
-}
-
 /* Convert X to MODE, that must be Pmode or ptr_mode, without emitting
    any rtl.  */
 
@@ -2353,9 +2313,7 @@ expand_debug_expr (tree exp)
     case COMPLEX_CST:
       gcc_assert (COMPLEX_MODE_P (mode));
       op0 = expand_debug_expr (TREE_REALPART (exp));
-      op0 = wrap_constant (GET_MODE_INNER (mode), op0);
       op1 = expand_debug_expr (TREE_IMAGPART (exp));
-      op1 = wrap_constant (GET_MODE_INNER (mode), op1);
       return gen_rtx_CONCAT (mode, op0, op1);
 
     case VAR_DECL:
Index: gcc/combine.c
===================================================================
--- gcc/combine.c	2009-09-26 10:43:09.000000000 +0100
+++ gcc/combine.c	2009-09-26 12:12:29.000000000 +0100
@@ -2257,68 +2257,33 @@ cleanup_auto_inc_dec (rtx src, bool afte
 
   return x;
 }
-#endif
 
 /* Auxiliary data structure for propagate_for_debug_stmt.  */
 
 struct rtx_subst_pair
 {
-  rtx from, to;
-  bool changed;
-#ifdef AUTO_INC_DEC
+  rtx to;
   bool adjusted;
   bool after;
-#endif
 };
 
-/* Clean up any auto-updates in PAIR->to the first time it is called
-   for a PAIR.  PAIR->adjusted is used to tell whether we've cleaned
-   up before.  */
+/* DATA points to an rtx_subst_pair.  Return the value that should be
+   substituted.  */
 
-static void
-auto_adjust_pair (struct rtx_subst_pair *pair ATTRIBUTE_UNUSED)
+static rtx
+propagate_for_debug_subst (void *data)
 {
-#ifdef AUTO_INC_DEC
+  struct rtx_subst_pair *pair = (struct rtx_subst_pair *)data;
+
   if (!pair->adjusted)
     {
       pair->adjusted = true;
       pair->to = cleanup_auto_inc_dec (pair->to, pair->after, VOIDmode);
+      return pair->to;
     }
-#endif
-}
-
-/* If *LOC is the same as FROM in the struct rtx_subst_pair passed as
-   DATA, replace it with a copy of TO.  Handle SUBREGs of *LOC as
-   well.  */
-
-static int
-propagate_for_debug_subst (rtx *loc, void *data)
-{
-  struct rtx_subst_pair *pair = (struct rtx_subst_pair *)data;
-  rtx from = pair->from, to = pair->to;
-  rtx x = *loc, s = x;
-
-  if (rtx_equal_p (x, from)
-      || (GET_CODE (x) == SUBREG && rtx_equal_p ((s = SUBREG_REG (x)), from)))
-    {
-      auto_adjust_pair (pair);
-      if (pair->to != to)
-	to = pair->to;
-      else
-	to = copy_rtx (to);
-      if (s != x)
-	{
-	  gcc_assert (GET_CODE (x) == SUBREG && SUBREG_REG (x) == s);
-	  to = simplify_gen_subreg (GET_MODE (x), to,
-				    GET_MODE (from), SUBREG_BYTE (x));
-	}
-      *loc = wrap_constant (GET_MODE (x), to);
-      pair->changed = true;
-      return -1;
-    }
-
-  return 0;
+  return copy_rtx (pair->to);
 }
+#endif
 
 /* Replace occurrences of DEST with SRC in DEBUG_INSNs between INSN
    and LAST.  If MOVE holds, debug insns must also be moved past
@@ -2327,14 +2292,11 @@ propagate_for_debug_subst (rtx *loc, voi
 static void
 propagate_for_debug (rtx insn, rtx last, rtx dest, rtx src, bool move)
 {
-  struct rtx_subst_pair p;
-  rtx next, move_pos = move ? last : NULL_RTX;
-
-  p.from = dest;
-  p.to = src;
-  p.changed = false;
+  rtx next, move_pos = move ? last : NULL_RTX, loc;
 
 #ifdef AUTO_INC_DEC
+  struct rtx_subst_pair p;
+  p.to = src;
   p.adjusted = false;
   p.after = move;
 #endif
@@ -2346,11 +2308,15 @@ propagate_for_debug (rtx insn, rtx last,
       next = NEXT_INSN (insn);
       if (DEBUG_INSN_P (insn))
 	{
-	  for_each_rtx (&INSN_VAR_LOCATION_LOC (insn),
-			propagate_for_debug_subst, &p);
-	  if (!p.changed)
+#ifdef AUTO_INC_DEC
+	  loc = simplify_replace_fn_rtx (INSN_VAR_LOCATION_LOC (insn),
+					 dest, propagate_for_debug_subst, &p);
+#else
+	  loc = simplify_replace_rtx (INSN_VAR_LOCATION_LOC (insn), dest, src);
+#endif
+	  if (loc == INSN_VAR_LOCATION_LOC (insn))
 	    continue;
-	  p.changed = false;
+	  INSN_VAR_LOCATION_LOC (insn) = loc;
 	  if (move_pos)
 	    {
 	      remove_insn (insn);
Index: gcc/cselib.c
===================================================================
--- gcc/cselib.c	2009-09-26 10:43:09.000000000 +0100
+++ gcc/cselib.c	2009-09-26 12:12:29.000000000 +0100
@@ -661,6 +661,19 @@ rtx_equal_for_cselib_p (rtx x, rtx y)
   return 1;
 }
 
+/* We need to pass down the mode of constants through the hash table
+   functions.  For that purpose, wrap them in a CONST of the appropriate
+   mode.  */
+static rtx
+wrap_constant (enum machine_mode mode, rtx x)
+{
+  if (!CONST_INT_P (x) && GET_CODE (x) != CONST_FIXED
+      && (GET_CODE (x) != CONST_DOUBLE || GET_MODE (x) != VOIDmode))
+    return x;
+  gcc_assert (mode != VOIDmode);
+  return gen_rtx_CONST (mode, x);
+}
+
 /* Hash an rtx.  Return 0 if we couldn't hash the rtx.
    For registers and memory locations, we look up their cselib_val structure
    and return its VALUE element.
@@ -1327,21 +1340,9 @@ cselib_expand_value_rtx_1 (rtx orig, str
     default:
       break;
     }
-  if (scopy == NULL_RTX)
-    {
-      XEXP (copy, 0)
-	= gen_rtx_CONST (GET_MODE (XEXP (orig, 0)), XEXP (copy, 0));
-      if (dump_file && (dump_flags & TDF_DETAILS))
-	fprintf (dump_file, "  wrapping const_int result in const to preserve mode %s\n",
-		 GET_MODE_NAME (GET_MODE (XEXP (copy, 0))));
-    }
   scopy = simplify_rtx (copy);
   if (scopy)
-    {
-      if (GET_MODE (copy) != GET_MODE (scopy))
-	scopy = wrap_constant (GET_MODE (copy), scopy);
-      return scopy;
-    }
+    return scopy;
   return copy;
 }
 
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c	2009-09-26 10:43:09.000000000 +0100
+++ gcc/reload1.c	2009-09-26 12:12:29.000000000 +0100
@@ -1257,36 +1257,25 @@ reload (rtx first, int global)
 
 	  for (use = DF_REG_USE_CHAIN (i); use; use = next)
 	    {
-	      rtx *loc = DF_REF_LOC (use);
-	      rtx x = *loc;
-
 	      insn = DF_REF_INSN (use);
+
+	      /* Make sure the next ref is for a different instruction,
+		 so that we're not affected by the rescan.  */
 	      next = DF_REF_NEXT_REG (use);
+	      while (next && DF_REF_INSN (next) == insn)
+		next = DF_REF_NEXT_REG (next);
 
 	      if (DEBUG_INSN_P (insn))
 		{
-		  gcc_assert (x == reg
-			      || (GET_CODE (x) == SUBREG
-				  && SUBREG_REG (x) == reg));
-
 		  if (!equiv)
 		    {
 		      INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
 		      df_insn_rescan_debug_internal (insn);
 		    }
 		  else
-		    {
-		      if (x == reg)
-			*loc = copy_rtx (equiv);
-		      else if (GET_CODE (x) == SUBREG
-			       && SUBREG_REG (x) == reg)
-			*loc = simplify_gen_subreg (GET_MODE (x), equiv,
-						    GET_MODE (reg),
-						    SUBREG_BYTE (x));
-		      else
-			gcc_unreachable ();
-		    *loc = wrap_constant (GET_MODE (x), *loc);
-		    }
+		    INSN_VAR_LOCATION_LOC (insn)
+		      = simplify_replace_rtx (INSN_VAR_LOCATION_LOC (insn),
+					      reg, equiv);
 		}
 	    }
 	}
Index: gcc/simplify-rtx.c
===================================================================
--- gcc/simplify-rtx.c	2009-09-26 10:43:09.000000000 +0100
+++ gcc/simplify-rtx.c	2009-09-26 13:17:07.000000000 +0100
@@ -350,38 +350,45 @@ simplify_gen_relational (enum rtx_code c
   return gen_rtx_fmt_ee (code, mode, op0, op1);
 }
 
-/* Replace all occurrences of OLD_RTX in X with NEW_RTX and try to simplify the
-   resulting RTX.  Return a new RTX which is as simplified as possible.  */
+/* Replace all occurrences of OLD_RTX in X with FN (DATA).  Treat FN as
+   copy_rtx if it is null.  Canonicalize and simplify the result.  */
 
 rtx
-simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
+simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
+			 rtx (*fn) (void *), void *data)
 {
   enum rtx_code code = GET_CODE (x);
   enum machine_mode mode = GET_MODE (x);
   enum machine_mode op_mode;
   rtx op0, op1, op2;
 
-  /* If X is OLD_RTX, return NEW_RTX.  Otherwise, if this is an expression, try
-     to build a new expression substituting recursively.  If we can't do
-     anything, return our input.  */
+  /* If X is OLD_RTX, return FN (DATA), with a null FN equating to
+     copy_rtx.  Otherwise, if this is an expression, try to build a
+     new expression, substituting recursively.  If we can't do anything,
+     return our input.  */
 
-  if (x == old_rtx)
-    return new_rtx;
+  if (rtx_equal_p (x, old_rtx))
+    {
+      if (fn)
+	return fn (data);
+      else
+	return copy_rtx ((rtx) data);
+    }
 
   switch (GET_RTX_CLASS (code))
     {
     case RTX_UNARY:
       op0 = XEXP (x, 0);
       op_mode = GET_MODE (op0);
-      op0 = simplify_replace_rtx (op0, old_rtx, new_rtx);
+      op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
       if (op0 == XEXP (x, 0))
 	return x;
       return simplify_gen_unary (code, mode, op0, op_mode);
 
     case RTX_BIN_ARITH:
     case RTX_COMM_ARITH:
-      op0 = simplify_replace_rtx (XEXP (x, 0), old_rtx, new_rtx);
-      op1 = simplify_replace_rtx (XEXP (x, 1), old_rtx, new_rtx);
+      op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
+      op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
 	return x;
       return simplify_gen_binary (code, mode, op0, op1);
@@ -391,8 +398,8 @@ simplify_replace_rtx (rtx x, const_rtx o
       op0 = XEXP (x, 0);
       op1 = XEXP (x, 1);
       op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
-      op0 = simplify_replace_rtx (op0, old_rtx, new_rtx);
-      op1 = simplify_replace_rtx (op1, old_rtx, new_rtx);
+      op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
+      op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
 	return x;
       return simplify_gen_relational (code, mode, op_mode, op0, op1);
@@ -401,9 +408,9 @@ simplify_replace_rtx (rtx x, const_rtx o
     case RTX_BITFIELD_OPS:
       op0 = XEXP (x, 0);
       op_mode = GET_MODE (op0);
-      op0 = simplify_replace_rtx (op0, old_rtx, new_rtx);
-      op1 = simplify_replace_rtx (XEXP (x, 1), old_rtx, new_rtx);
-      op2 = simplify_replace_rtx (XEXP (x, 2), old_rtx, new_rtx);
+      op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
+      op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
+      op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
 	return x;
       if (op_mode == VOIDmode)
@@ -414,7 +421,7 @@ simplify_replace_rtx (rtx x, const_rtx o
       /* The only case we try to handle is a SUBREG.  */
       if (code == SUBREG)
 	{
-	  op0 = simplify_replace_rtx (SUBREG_REG (x), old_rtx, new_rtx);
+	  op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
 	  if (op0 == SUBREG_REG (x))
 	    return x;
 	  op0 = simplify_gen_subreg (GET_MODE (x), op0,
@@ -427,15 +434,15 @@ simplify_replace_rtx (rtx x, const_rtx o
     case RTX_OBJ:
       if (code == MEM)
 	{
-	  op0 = simplify_replace_rtx (XEXP (x, 0), old_rtx, new_rtx);
+	  op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
 	  if (op0 == XEXP (x, 0))
 	    return x;
 	  return replace_equiv_address_nv (x, op0);
 	}
       else if (code == LO_SUM)
 	{
-	  op0 = simplify_replace_rtx (XEXP (x, 0), old_rtx, new_rtx);
-	  op1 = simplify_replace_rtx (XEXP (x, 1), old_rtx, new_rtx);
+	  op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
+	  op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
 
 	  /* (lo_sum (high x) x) -> x  */
 	  if (GET_CODE (op0) == HIGH && rtx_equal_p (XEXP (op0, 0), op1))
@@ -445,11 +452,6 @@ simplify_replace_rtx (rtx x, const_rtx o
 	    return x;
 	  return gen_rtx_LO_SUM (mode, op0, op1);
 	}
-      else if (code == REG)
-	{
-	  if (rtx_equal_p (x, old_rtx))
-	    return new_rtx;
-	}
       break;
 
     default:
@@ -457,6 +459,15 @@ simplify_replace_rtx (rtx x, const_rtx o
     }
   return x;
 }
+
+/* Replace all occurrences of OLD_RTX in X with NEW_RTX and try to simplify the
+   resulting RTX.  Return a new RTX which is as simplified as possible.  */
+
+rtx
+simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
+{
+  return simplify_replace_fn_rtx (x, old_rtx, 0, new_rtx);
+}
 
 /* Try to simplify a unary operation CODE whose output mode is to be
    MODE with input operand OP whose mode was originally OP_MODE.
@@ -467,9 +478,6 @@ simplify_unary_operation (enum rtx_code 
 {
   rtx trueop, tem;
 
-  if (GET_CODE (op) == CONST)
-    op = XEXP (op, 0);
-
   trueop = avoid_constant_pool_reference (op);
 
   tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c	2009-09-26 10:43:09.000000000 +0100
+++ gcc/var-tracking.c	2009-09-26 12:12:29.000000000 +0100
@@ -6242,24 +6242,6 @@ delete_variable_part (dataflow_set *set,
   slot = delete_slot_part (set, loc, slot, offset);
 }
 
-/* Wrap result in CONST:MODE if needed to preserve the mode.  */
-
-static rtx
-check_wrap_constant (enum machine_mode mode, rtx result)
-{
-  if (!result || GET_MODE (result) == mode)
-    return result;
-
-  if (dump_file && (dump_flags & TDF_DETAILS))
-    fprintf (dump_file, "  wrapping result in const to preserve mode %s\n",
-	     GET_MODE_NAME (mode));
-
-  result = wrap_constant (mode, result);
-  gcc_assert (GET_MODE (result) == mode);
-
-  return result;
-}
-
 /* Callback for cselib_expand_value, that looks for expressions
    holding the value in the var-tracking hash tables.  Return X for
    standard processing, anything else is to be used as-is.  */
@@ -6323,7 +6305,6 @@ vt_expand_loc_callback (rtx x, bitmap re
     {
       result = cselib_expand_value_rtx_cb (loc->loc, regs, max_depth,
 					   vt_expand_loc_callback, vars);
-      result = check_wrap_constant (GET_MODE (loc->loc), result);
       if (result)
 	break;
     }
@@ -6341,14 +6322,11 @@ vt_expand_loc_callback (rtx x, bitmap re
 static rtx
 vt_expand_loc (rtx loc, htab_t vars)
 {
-  rtx newloc;
-
   if (!MAY_HAVE_DEBUG_INSNS)
     return loc;
 
-  newloc = cselib_expand_value_rtx_cb (loc, scratch_regs, 5,
-				       vt_expand_loc_callback, vars);
-  loc = check_wrap_constant (GET_MODE (loc), newloc);
+  loc = cselib_expand_value_rtx_cb (loc, scratch_regs, 5,
+				    vt_expand_loc_callback, vars);
 
   if (loc && MEM_P (loc))
     loc = targetm.delegitimize_address (loc);


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