OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / var-tracking.c
index 557a2ca..d797c40 100644 (file)
@@ -555,7 +555,7 @@ static void dump_vars (htab_t);
 static void dump_dataflow_set (dataflow_set *);
 static void dump_dataflow_sets (void);
 
-static void set_dv_changed (decl_or_value, bool);
+static inline void set_dv_changed (decl_or_value, bool);
 static void variable_was_changed (variable, dataflow_set *);
 static void **set_slot_part (dataflow_set *, rtx, void **,
                             decl_or_value, HOST_WIDE_INT,
@@ -5298,6 +5298,7 @@ reverse_op (rtx val, const_rtx expr, rtx insn)
 {
   rtx src, arg, ret;
   cselib_val *v;
+  struct elt_loc_list *l;
   enum rtx_code code;
 
   if (GET_CODE (expr) != SET)
@@ -5333,6 +5334,18 @@ reverse_op (rtx val, const_rtx expr, rtx insn)
   if (!v || !cselib_preserved_value_p (v))
     return;
 
+  /* Use canonical V to avoid creating multiple redundant expressions
+     for different VALUES equivalent to V.  */
+  v = canonical_cselib_val (v);
+
+  /* Adding a reverse op isn't useful if V already has an always valid
+     location.  Ignore ENTRY_VALUE, while it is always constant, we should
+     prefer non-ENTRY_VALUE locations whenever possible.  */
+  for (l = v->locs; l; l = l->next)
+    if (CONSTANT_P (l->loc)
+       && (GET_CODE (l->loc) != CONST || !references_value_p (l->loc, 0)))
+      return;
+
   switch (GET_CODE (src))
     {
     case NOT:
@@ -8216,9 +8229,14 @@ emit_note_insn_var_location (void **varp, void *data)
       /* Make sure that the call related notes come first.  */
       while (NEXT_INSN (insn)
             && NOTE_P (insn)
-            && NOTE_DURING_CALL_P (insn))
+            && ((NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
+                 && NOTE_DURING_CALL_P (insn))
+                || NOTE_KIND (insn) == NOTE_INSN_CALL_ARG_LOCATION))
        insn = NEXT_INSN (insn);
-      if (NOTE_P (insn) && NOTE_DURING_CALL_P (insn))
+      if (NOTE_P (insn)
+         && ((NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
+              && NOTE_DURING_CALL_P (insn))
+             || NOTE_KIND (insn) == NOTE_INSN_CALL_ARG_LOCATION))
        note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
       else
        note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
@@ -8962,31 +8980,34 @@ vt_add_function_parameter (tree parm)
   /* DECL_INCOMING_RTL uses the INCOMING_REGNO of parameter registers.
      If the target machine has an explicit window save instruction, the
      actual entry value is the corresponding OUTGOING_REGNO instead.  */
-  if (REG_P (incoming)
-      && HARD_REGISTER_P (incoming)
-      && OUTGOING_REGNO (REGNO (incoming)) != REGNO (incoming))
-    {
-      parm_reg_t *p
-       = VEC_safe_push (parm_reg_t, gc, windowed_parm_regs, NULL);
-      p->incoming = incoming;
-      incoming
-       = gen_rtx_REG_offset (incoming, GET_MODE (incoming),
-                             OUTGOING_REGNO (REGNO (incoming)), 0);
-      p->outgoing = incoming;
-    }
-  else if (MEM_P (incoming)
-          && REG_P (XEXP (incoming, 0))
-          && HARD_REGISTER_P (XEXP (incoming, 0)))
+  if (HAVE_window_save && !current_function_uses_only_leaf_regs)
     {
-      rtx reg = XEXP (incoming, 0);
-      if (OUTGOING_REGNO (REGNO (reg)) != REGNO (reg))
+      if (REG_P (incoming)
+         && HARD_REGISTER_P (incoming)
+         && OUTGOING_REGNO (REGNO (incoming)) != REGNO (incoming))
        {
          parm_reg_t *p
            = VEC_safe_push (parm_reg_t, gc, windowed_parm_regs, NULL);
-         p->incoming = reg;
-         reg = gen_raw_REG (GET_MODE (reg), OUTGOING_REGNO (REGNO (reg)));
-         p->outgoing = reg;
-         incoming = replace_equiv_address_nv (incoming, reg);
+         p->incoming = incoming;
+         incoming
+           = gen_rtx_REG_offset (incoming, GET_MODE (incoming),
+                                 OUTGOING_REGNO (REGNO (incoming)), 0);
+         p->outgoing = incoming;
+       }
+      else if (MEM_P (incoming)
+              && REG_P (XEXP (incoming, 0))
+              && HARD_REGISTER_P (XEXP (incoming, 0)))
+       {
+         rtx reg = XEXP (incoming, 0);
+         if (OUTGOING_REGNO (REGNO (reg)) != REGNO (reg))
+           {
+             parm_reg_t *p
+               = VEC_safe_push (parm_reg_t, gc, windowed_parm_regs, NULL);
+             p->incoming = reg;
+             reg = gen_raw_REG (GET_MODE (reg), OUTGOING_REGNO (REGNO (reg)));
+             p->outgoing = reg;
+             incoming = replace_equiv_address_nv (incoming, reg);
+           }
        }
     }
 #endif