OSDN Git Service

PR tree-optimization/50693
[pf3gnuchains/gcc-fork.git] / gcc / var-tracking.c
index 8a64000..95bc02b 100644 (file)
@@ -4907,6 +4907,18 @@ replace_expr_with_values (rtx loc)
     return cselib_subst_to_values (loc, VOIDmode);
 }
 
+/* Return true if *X is a DEBUG_EXPR.  Usable as an argument to
+   for_each_rtx to tell whether there are any DEBUG_EXPRs within
+   RTX.  */
+
+static int
+rtx_debug_expr_p (rtx *x, void *data ATTRIBUTE_UNUSED)
+{
+  rtx loc = *x;
+
+  return GET_CODE (loc) == DEBUG_EXPR;
+}
+
 /* Determine what kind of micro operation to choose for a USE.  Return
    MO_CLOBBER if no micro operation is to be generated.  */
 
@@ -4988,7 +5000,13 @@ use_type (rtx loc, struct count_use_info *cui, enum machine_mode *modep)
       else if (target_for_debug_bind (var_debug_decl (expr)))
        return MO_CLOBBER;
       else if (track_loc_p (loc, expr, INT_MEM_OFFSET (loc),
-                           false, modep, NULL))
+                           false, modep, NULL)
+              /* Multi-part variables shouldn't refer to one-part
+                 variable names such as VALUEs (never happens) or
+                 DEBUG_EXPRs (only happens in the presence of debug
+                 insns).  */
+              && (!MAY_HAVE_DEBUG_INSNS
+                  || !for_each_rtx (&XEXP (loc, 0), rtx_debug_expr_p, NULL)))
        return MO_USE;
       else
        return MO_CLOBBER;
@@ -7746,7 +7764,7 @@ vt_expand_var_loc_chain (variable var, bitmap regs, void *data, bool *pendrecp)
   bool pending_recursion;
   rtx loc_from = NULL;
   struct elt_loc_list *cloc = NULL;
-  int depth, saved_depth = elcd->depth;
+  int depth = 0, saved_depth = elcd->depth;
 
   /* Clear all backlinks pointing at this, so that we're not notified
      while we're active.  */
@@ -7824,6 +7842,8 @@ vt_expand_var_loc_chain (variable var, bitmap regs, void *data, bool *pendrecp)
   VAR_LOC_FROM (var) = loc_from;
   VAR_LOC_DEPTH (var) = depth;
 
+  gcc_checking_assert (!depth == !result);
+
   elcd->depth = update_depth (saved_depth, depth);
 
   /* Indicate whether any of the dependencies are pending recursion
@@ -9497,6 +9517,12 @@ vt_initialize (void)
   return true;
 }
 
+/* This is *not* reset after each function.  It gives each
+   NOTE_INSN_DELETED_DEBUG_LABEL in the entire compilation
+   a unique label number.  */
+
+static int debug_label_num = 1;
+
 /* Get rid of all debug insns from the insn stream.  */
 
 static void
@@ -9512,7 +9538,22 @@ delete_debug_insns (void)
     {
       FOR_BB_INSNS_SAFE (bb, insn, next)
        if (DEBUG_INSN_P (insn))
-         delete_insn (insn);
+         {
+           tree decl = INSN_VAR_LOCATION_DECL (insn);
+           if (TREE_CODE (decl) == LABEL_DECL
+               && DECL_NAME (decl)
+               && !DECL_RTL_SET_P (decl))
+             {
+               PUT_CODE (insn, NOTE);
+               NOTE_KIND (insn) = NOTE_INSN_DELETED_DEBUG_LABEL;
+               NOTE_DELETED_LABEL_NAME (insn)
+                 = IDENTIFIER_POINTER (DECL_NAME (decl));
+               SET_DECL_RTL (decl, insn);
+               CODE_LABEL_NUMBER (insn) = debug_label_num++;
+             }
+           else
+             delete_insn (insn);
+         }
     }
 }