OSDN Git Service

PR debug/43299
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 Mar 2010 18:53:38 +0000 (18:53 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 Mar 2010 18:53:38 +0000 (18:53 +0000)
* var-tracking.c (adjust_sets): New function.
(count_with_sets, add_with_sets): Use it.
(get_adjusted_src): New inline function.
(add_stores): Use it.

* gcc.dg/pr43299.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@157316 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr43299.c [new file with mode: 0644]
gcc/var-tracking.c

index 4b68db5..105d366 100644 (file)
@@ -1,5 +1,11 @@
 2010-03-09  Jakub Jelinek  <jakub@redhat.com>
 
+       PR debug/43299
+       * var-tracking.c (adjust_sets): New function.
+       (count_with_sets, add_with_sets): Use it.
+       (get_adjusted_src): New inline function.
+       (add_stores): Use it.
+
        PR debug/43304
        * var-tracking.c (vt_expand_loc_callback) <case SUBREG>: If dummy,
        call cselib_dummy_expand_value_rtx_cb instead of
index a874977..6f37093 100644 (file)
@@ -1,5 +1,8 @@
 2010-03-09  Jakub Jelinek  <jakub@redhat.com>
 
+       PR debug/43299
+       * gcc.dg/pr43299.c: New test.
+
        PR debug/43290
        * g++.dg/eh/unwind2.C: New test.
 
diff --git a/gcc/testsuite/gcc.dg/pr43299.c b/gcc/testsuite/gcc.dg/pr43299.c
new file mode 100644 (file)
index 0000000..d71c896
--- /dev/null
@@ -0,0 +1,28 @@
+/* PR debug/43299 */
+/* { dg-do assemble } */
+/* { dg-options "-g -O2" } */
+
+extern void *emit_insn (void *);
+
+__attribute__((noinline))
+void *gen_load_locked_si (void *x, void *y)
+{
+  return x;
+}
+
+__attribute__((noinline))
+void *gen_load_locked_di (void *x, void *y)
+{
+  return x;
+}
+
+void
+emit_load_locked (int mode, void *reg, void *mem)
+{
+  void * (*fn) (void *, void *) = ((void *)0);
+  if (mode == 9)
+    fn = gen_load_locked_si;
+  else if (mode == 10)
+    fn = gen_load_locked_di;
+  emit_insn (fn (reg, mem));
+}
index 378bb75..ece7790 100644 (file)
@@ -4601,6 +4601,30 @@ count_stores (rtx loc, const_rtx expr ATTRIBUTE_UNUSED, void *cui)
   count_uses (&loc, cui);
 }
 
+/* Adjust sets if needed.  Currently this optimizes read-only MEM loads
+   if REG_EQUAL/REG_EQUIV note is present.  */
+
+static void
+adjust_sets (rtx insn, struct cselib_set *sets, int n_sets)
+{
+  if (n_sets == 1 && MEM_P (sets[0].src) && MEM_READONLY_P (sets[0].src))
+    {
+      /* For read-only MEMs containing some constant, prefer those
+        constants.  */
+      rtx note = find_reg_equal_equiv_note (insn), src;
+
+      if (note && CONSTANT_P (XEXP (note, 0)))
+       {
+         sets[0].src = src = XEXP (note, 0);
+         if (GET_CODE (PATTERN (insn)) == COND_EXEC)
+           src = gen_rtx_IF_THEN_ELSE (GET_MODE (sets[0].dest),
+                                       COND_EXEC_TEST (PATTERN (insn)),
+                                       src, sets[0].dest);
+         sets[0].src_elt = cselib_lookup (src, GET_MODE (sets[0].dest), 1);
+       }
+    }
+}
+
 /* Callback for cselib_record_sets_hook, that counts how many micro
    operations it takes for uses and stores in an insn after
    cselib_record_sets has analyzed the sets in an insn, but before it
@@ -4617,6 +4641,8 @@ count_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
 
   cselib_hook_called = true;
 
+  adjust_sets (insn, sets, n_sets);
+
   cui.insn = insn;
   cui.bb = bb;
   cui.sets = sets;
@@ -4934,6 +4960,21 @@ reverse_op (rtx val, const_rtx expr)
   return gen_rtx_CONCAT (GET_MODE (v->val_rtx), v->val_rtx, ret);
 }
 
+/* Return SRC, or, if it is a read-only MEM for which adjust_sets
+   replated it with a constant from REG_EQUIV/REG_EQUAL note,
+   that constant.  */
+
+static inline rtx
+get_adjusted_src (struct count_use_info *cui, rtx src)
+{
+  if (cui->n_sets == 1
+      && MEM_P (src)
+      && MEM_READONLY_P (src)
+      && CONSTANT_P (cui->sets[0].src))
+    return cui->sets[0].src;
+  return src;
+}
+
 /* Add stores (register and memory references) LOC which will be tracked
    to VTI (bb)->mos.  EXPR is the RTL expression containing the store.
    CUIP->insn is instruction which the LOC is part of.  */
@@ -4971,7 +5012,10 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
       else
        {
          if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
-           src = var_lowpart (mode2, SET_SRC (expr));
+           {
+             src = get_adjusted_src (cui, SET_SRC (expr));
+             src = var_lowpart (mode2, src);
+           }
          loc = var_lowpart (mode2, loc);
 
          if (src == NULL)
@@ -5030,7 +5074,10 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
       else
        {
          if (GET_CODE (expr) == SET && SET_DEST (expr) == loc)
-           src = var_lowpart (mode2, SET_SRC (expr));
+           {
+             src = get_adjusted_src (cui, SET_SRC (expr));
+             src = var_lowpart (mode2, src);
+           }
          loc = var_lowpart (mode2, loc);
 
          if (src == NULL)
@@ -5099,12 +5146,13 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
     }
   else if (resolve && GET_CODE (mo->u.loc) == SET)
     {
-      nloc = replace_expr_with_values (SET_SRC (expr));
+      src = get_adjusted_src (cui, SET_SRC (expr));
+      nloc = replace_expr_with_values (src);
 
       /* Avoid the mode mismatch between oexpr and expr.  */
       if (!nloc && mode != mode2)
        {
-         nloc = SET_SRC (expr);
+         nloc = src;
          gcc_assert (oloc == SET_DEST (expr));
        }
 
@@ -5201,6 +5249,8 @@ add_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
 
   cselib_hook_called = true;
 
+  adjust_sets (insn, sets, n_sets);
+
   cui.insn = insn;
   cui.bb = bb;
   cui.sets = sets;