diff gcc/var-tracking.c @ 132:d34655255c78

update gcc-8.2
author mir3636
date Thu, 25 Oct 2018 10:21:07 +0900
parents 84e7813d76e9
children 1830386684a0
line wrap: on
line diff
--- a/gcc/var-tracking.c	Thu Oct 25 08:08:40 2018 +0900
+++ b/gcc/var-tracking.c	Thu Oct 25 10:21:07 2018 +0900
@@ -1,5 +1,5 @@
 /* Variable tracking routines for the GNU compiler.
-   Copyright (C) 2002-2017 Free Software Foundation, Inc.
+   Copyright (C) 2002-2018 Free Software Foundation, Inc.
 
    This file is part of GCC.
 
@@ -115,6 +115,7 @@
 #include "tree-pretty-print.h"
 #include "rtl-iter.h"
 #include "fibonacci_heap.h"
+#include "print-rtl.h"
 
 typedef fibonacci_heap <long, basic_block_def> bb_heap_t;
 typedef fibonacci_node <long, basic_block_def> bb_heap_node_t;
@@ -390,8 +391,16 @@
 /* Pointer to the BB's information specific to variable tracking pass.  */
 #define VTI(BB) ((variable_tracking_info *) (BB)->aux)
 
-/* Macro to access MEM_OFFSET as an HOST_WIDE_INT.  Evaluates MEM twice.  */
-#define INT_MEM_OFFSET(mem) (MEM_OFFSET_KNOWN_P (mem) ? MEM_OFFSET (mem) : 0)
+/* Return MEM_OFFSET (MEM) as a HOST_WIDE_INT, or 0 if we can't.  */
+
+static inline HOST_WIDE_INT
+int_mem_offset (const_rtx mem)
+{
+  HOST_WIDE_INT offset;
+  if (MEM_OFFSET_KNOWN_P (mem) && MEM_OFFSET (mem).is_constant (&offset))
+    return offset;
+  return 0;
+}
 
 #if CHECKING_P && (GCC_VERSION >= 2007)
 
@@ -666,7 +675,6 @@
 static void dataflow_set_destroy (dataflow_set *);
 
 static bool track_expr_p (tree, bool);
-static bool same_variable_part_p (rtx, tree, HOST_WIDE_INT);
 static void add_uses_1 (rtx *, void *);
 static void add_stores (rtx, const_rtx, void *);
 static bool compute_bb_dataflow (basic_block);
@@ -697,7 +705,6 @@
 static void emit_notes_in_bb (basic_block, dataflow_set *);
 static void vt_emit_notes (void);
 
-static bool vt_get_decl_and_offset (rtx, tree *, HOST_WIDE_INT *);
 static void vt_add_function_parameters (void);
 static bool vt_initialize (void);
 static void vt_finalize (void);
@@ -911,14 +918,14 @@
    or hard_frame_pointer_rtx.  */
 
 static inline rtx
-compute_cfa_pointer (HOST_WIDE_INT adjustment)
+compute_cfa_pointer (poly_int64 adjustment)
 {
   return plus_constant (Pmode, cfa_base_rtx, adjustment + cfa_base_offset);
 }
 
 /* Adjustment for hard_frame_pointer_rtx to cfa base reg,
    or -1 if the replacement shouldn't be done.  */
-static HOST_WIDE_INT hard_frame_pointer_adjustment = -1;
+static poly_int64 hard_frame_pointer_adjustment = -1;
 
 /* Data for adjust_mems callback.  */
 
@@ -958,6 +965,24 @@
 	  case MULT:
 	    break;
 	  case ASHIFT:
+	    if (GET_MODE (XEXP (x, 1)) != VOIDmode)
+	      {
+		enum machine_mode mode = GET_MODE (subreg);
+		rtx op1 = XEXP (x, 1);
+		enum machine_mode op1_mode = GET_MODE (op1);
+		if (GET_MODE_PRECISION (as_a <scalar_int_mode> (mode))
+		    < GET_MODE_PRECISION (as_a <scalar_int_mode> (op1_mode)))
+		  {
+		    poly_uint64 byte = subreg_lowpart_offset (mode, op1_mode);
+		    if (GET_CODE (op1) == SUBREG || GET_CODE (op1) == CONCAT)
+		      {
+			if (!simplify_subreg (mode, op1, op1_mode, byte))
+			  return false;
+		      }
+		    else if (!validate_subreg (mode, op1_mode, op1, byte))
+		      return false;
+		  }
+	      }
 	    iter.substitute (XEXP (x, 0));
 	    break;
 	  default:
@@ -1010,6 +1035,7 @@
   machine_mode mem_mode_save;
   bool store_save;
   scalar_int_mode tem_mode, tem_subreg_mode;
+  poly_int64 size;
   switch (GET_CODE (loc))
     {
     case REG:
@@ -1023,7 +1049,7 @@
 	return compute_cfa_pointer (amd->stack_adjust);
       else if (loc == hard_frame_pointer_rtx
 	       && frame_pointer_needed
-	       && hard_frame_pointer_adjustment != -1
+	       && maybe_ne (hard_frame_pointer_adjustment, -1)
 	       && cfa_base_rtx)
 	return compute_cfa_pointer (hard_frame_pointer_adjustment);
       gcc_checking_assert (loc != virtual_incoming_args_rtx);
@@ -1054,11 +1080,9 @@
       return mem;
     case PRE_INC:
     case PRE_DEC:
-      addr = gen_rtx_PLUS (GET_MODE (loc), XEXP (loc, 0),
-			   gen_int_mode (GET_CODE (loc) == PRE_INC
-					 ? GET_MODE_SIZE (amd->mem_mode)
-					 : -GET_MODE_SIZE (amd->mem_mode),
-					 GET_MODE (loc)));
+      size = GET_MODE_SIZE (amd->mem_mode);
+      addr = plus_constant (GET_MODE (loc), XEXP (loc, 0),
+			    GET_CODE (loc) == PRE_INC ? size : -size);
       /* FALLTHRU */
     case POST_INC:
     case POST_DEC:
@@ -1066,12 +1090,10 @@
 	addr = XEXP (loc, 0);
       gcc_assert (amd->mem_mode != VOIDmode && amd->mem_mode != BLKmode);
       addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
-      tem = gen_rtx_PLUS (GET_MODE (loc), XEXP (loc, 0),
-			  gen_int_mode ((GET_CODE (loc) == PRE_INC
-					 || GET_CODE (loc) == POST_INC)
-					? GET_MODE_SIZE (amd->mem_mode)
-					: -GET_MODE_SIZE (amd->mem_mode),
-					GET_MODE (loc)));
+      size = GET_MODE_SIZE (amd->mem_mode);
+      tem = plus_constant (GET_MODE (loc), XEXP (loc, 0),
+			   (GET_CODE (loc) == PRE_INC
+			    || GET_CODE (loc) == POST_INC) ? size : -size);
       store_save = amd->store;
       amd->store = false;
       tem = simplify_replace_fn_rtx (tem, old_rtx, adjust_mems, data);
@@ -1118,7 +1140,7 @@
       if (tem == NULL_RTX)
 	tem = gen_rtx_raw_SUBREG (GET_MODE (loc), addr, SUBREG_BYTE (loc));
     finish_subreg:
-      if (MAY_HAVE_DEBUG_INSNS
+      if (MAY_HAVE_DEBUG_BIND_INSNS
 	  && GET_CODE (tem) == SUBREG
 	  && (GET_CODE (SUBREG_REG (tem)) == PLUS
 	      || GET_CODE (SUBREG_REG (tem)) == MINUS
@@ -1330,7 +1352,7 @@
 {
   tree decl;
 
-  if (!MAY_HAVE_DEBUG_INSNS)
+  if (!MAY_HAVE_DEBUG_BIND_INSNS)
     return NOT_ONEPART;
 
   if (dv_is_value_p (dv))
@@ -1843,6 +1865,32 @@
   set_variable_part (set, loc, dv, offset, initialized, set_src, iopt);
 }
 
+/* Return true if we should track a location that is OFFSET bytes from
+   a variable.  Store the constant offset in *OFFSET_OUT if so.  */
+
+static bool
+track_offset_p (poly_int64 offset, HOST_WIDE_INT *offset_out)
+{
+  HOST_WIDE_INT const_offset;
+  if (!offset.is_constant (&const_offset)
+      || !IN_RANGE (const_offset, 0, MAX_VAR_PARTS - 1))
+    return false;
+  *offset_out = const_offset;
+  return true;
+}
+
+/* Return the offset of a register that track_offset_p says we
+   should track.  */
+
+static HOST_WIDE_INT
+get_tracked_reg_offset (rtx loc)
+{
+  HOST_WIDE_INT offset;
+  if (!track_offset_p (REG_OFFSET (loc), &offset))
+    gcc_unreachable ();
+  return offset;
+}
+
 /* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  */
 
 static void
@@ -1850,7 +1898,7 @@
 	     rtx set_src)
 {
   tree decl = REG_EXPR (loc);
-  HOST_WIDE_INT offset = REG_OFFSET (loc);
+  HOST_WIDE_INT offset = get_tracked_reg_offset (loc);
 
   var_reg_decl_set (set, loc, initialized,
 		    dv_from_decl (decl), offset, set_src, INSERT);
@@ -1896,7 +1944,7 @@
 			enum var_init_status initialized, rtx set_src)
 {
   tree decl = REG_EXPR (loc);
-  HOST_WIDE_INT offset = REG_OFFSET (loc);
+  HOST_WIDE_INT offset = get_tracked_reg_offset (loc);
   attrs *node, *next;
   attrs **nextp;
 
@@ -1937,10 +1985,10 @@
   attrs **nextp = &set->regs[REGNO (loc)];
   attrs *node, *next;
 
-  if (clobber)
+  HOST_WIDE_INT offset;
+  if (clobber && track_offset_p (REG_OFFSET (loc), &offset))
     {
       tree decl = REG_EXPR (loc);
-      HOST_WIDE_INT offset = REG_OFFSET (loc);
 
       decl = var_debug_decl (decl);
 
@@ -2127,7 +2175,7 @@
 static rtx
 vt_canonicalize_addr (dataflow_set *set, rtx oloc)
 {
-  HOST_WIDE_INT ofst = 0;
+  poly_int64 ofst = 0, term;
   machine_mode mode = GET_MODE (oloc);
   rtx loc = oloc;
   rtx x;
@@ -2136,9 +2184,9 @@
   while (retry)
     {
       while (GET_CODE (loc) == PLUS
-	     && GET_CODE (XEXP (loc, 1)) == CONST_INT)
-	{
-	  ofst += INTVAL (XEXP (loc, 1));
+	     && poly_int_rtx_p (XEXP (loc, 1), &term))
+	{
+	  ofst += term;
 	  loc = XEXP (loc, 0);
 	}
 
@@ -2163,10 +2211,11 @@
 	    loc = get_addr_from_global_cache (loc);
 
 	  /* Consolidate plus_constants.  */
-	  while (ofst && GET_CODE (loc) == PLUS
-		 && GET_CODE (XEXP (loc, 1)) == CONST_INT)
+	  while (maybe_ne (ofst, 0)
+		 && GET_CODE (loc) == PLUS
+		 && poly_int_rtx_p (XEXP (loc, 1), &term))
 	    {
-	      ofst += INTVAL (XEXP (loc, 1));
+	      ofst += term;
 	      loc = XEXP (loc, 0);
 	    }
 
@@ -2182,12 +2231,10 @@
     }
 
   /* Add OFST back in.  */
-  if (ofst)
+  if (maybe_ne (ofst, 0))
     {
       /* Don't build new RTL if we can help it.  */
-      if (GET_CODE (oloc) == PLUS
-	  && XEXP (oloc, 0) == loc
-	  && INTVAL (XEXP (oloc, 1)) == ofst)
+      if (strip_offset (oloc, &term) == loc && known_eq (term, ofst))
 	return oloc;
 
       loc = plus_constant (mode, loc, ofst);
@@ -2336,7 +2383,7 @@
 	     rtx set_src)
 {
   tree decl = MEM_EXPR (loc);
-  HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
+  HOST_WIDE_INT offset = int_mem_offset (loc);
 
   var_mem_decl_set (set, loc, initialized,
 		    dv_from_decl (decl), offset, set_src, INSERT);
@@ -2354,7 +2401,7 @@
 			enum var_init_status initialized, rtx set_src)
 {
   tree decl = MEM_EXPR (loc);
-  HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
+  HOST_WIDE_INT offset = int_mem_offset (loc);
 
   clobber_overlapping_mems (set, loc);
   decl = var_debug_decl (decl);
@@ -2375,7 +2422,7 @@
 var_mem_delete (dataflow_set *set, rtx loc, bool clobber)
 {
   tree decl = MEM_EXPR (loc);
-  HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
+  HOST_WIDE_INT offset = int_mem_offset (loc);
 
   clobber_overlapping_mems (set, loc);
   decl = var_debug_decl (decl);
@@ -3490,6 +3537,12 @@
 	else
 	  return 1;
 
+      case 'p':
+	r = compare_sizes_for_sort (SUBREG_BYTE (x), SUBREG_BYTE (y));
+	if (r != 0)
+	  return r;
+	break;
+
       case 'V':
       case 'E':
 	/* Compare the vector length first.  */
@@ -4618,7 +4671,7 @@
   for (node = var->var_part[0].loc_chain; node; node = node->next)
     if (MEM_P (node->loc)
 	&& MEM_EXPR (node->loc) == expr
-	&& INT_MEM_OFFSET (node->loc) == 0)
+	&& int_mem_offset (node->loc) == 0)
       {
 	where = node;
 	break;
@@ -4683,7 +4736,7 @@
 	      /* We want to remove dying MEMs that don't refer to DECL.  */
 	      if (GET_CODE (loc->loc) == MEM
 		  && (MEM_EXPR (loc->loc) != decl
-		      || INT_MEM_OFFSET (loc->loc) != 0)
+		      || int_mem_offset (loc->loc) != 0)
 		  && mem_dies_at_call (loc->loc))
 		break;
 	      /* We want to move here MEMs that do refer to DECL.  */
@@ -4727,7 +4780,7 @@
 
 	  if (GET_CODE (loc->loc) != MEM
 	      || (MEM_EXPR (loc->loc) == decl
-		  && INT_MEM_OFFSET (loc->loc) == 0)
+		  && int_mem_offset (loc->loc) == 0)
 	      || !mem_dies_at_call (loc->loc))
 	    {
 	      if (old_loc != loc->loc && emit_notes)
@@ -4854,7 +4907,7 @@
   EXECUTE_IF_SET_IN_HARD_REG_SET (invalidated_regs, 0, r, hrsi)
     var_regno_delete (set, r);
 
-  if (MAY_HAVE_DEBUG_INSNS)
+  if (MAY_HAVE_DEBUG_BIND_INSNS)
     {
       set->traversed_vars = set->vars;
       shared_hash_htab (set->vars)
@@ -5170,20 +5223,20 @@
 	      || (TREE_CODE (realdecl) == MEM_REF
 		  && TREE_CODE (TREE_OPERAND (realdecl, 0)) == ADDR_EXPR))
 	    {
-	      HOST_WIDE_INT bitsize, bitpos, maxsize;
+	      HOST_WIDE_INT bitsize, bitpos;
 	      bool reverse;
 	      tree innerdecl
-		= get_ref_base_and_extent (realdecl, &bitpos, &bitsize,
-					   &maxsize, &reverse);
-	      if (!DECL_P (innerdecl)
+		= get_ref_base_and_extent_hwi (realdecl, &bitpos,
+					       &bitsize, &reverse);
+	      if (!innerdecl
+		  || !DECL_P (innerdecl)
 		  || DECL_IGNORED_P (innerdecl)
 		  /* Do not track declarations for parts of tracked record
 		     parameters since we want to track them as a whole.  */
 		  || tracked_record_parameter_p (innerdecl)
 		  || TREE_STATIC (innerdecl)
-		  || bitsize <= 0
-		  || bitpos + bitsize > 256
-		  || bitsize != maxsize)
+		  || bitsize == 0
+		  || bitpos + bitsize > 256)
 		return 0;
 	      else
 		realdecl = expr;
@@ -5225,7 +5278,7 @@
 	  && !tracked_record_parameter_p (realdecl))
 	return 0;
       if (MEM_SIZE_KNOWN_P (decl_rtl)
-	  && MEM_SIZE (decl_rtl) > MAX_VAR_PARTS)
+	  && maybe_gt (MEM_SIZE (decl_rtl), MAX_VAR_PARTS))
 	return 0;
     }
 
@@ -5238,10 +5291,10 @@
    EXPR+OFFSET.  */
 
 static bool
-same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset)
+same_variable_part_p (rtx loc, tree expr, poly_int64 offset)
 {
   tree expr2;
-  HOST_WIDE_INT offset2;
+  poly_int64 offset2;
 
   if (! DECL_P (expr))
     return false;
@@ -5254,7 +5307,7 @@
   else if (MEM_P (loc))
     {
       expr2 = MEM_EXPR (loc);
-      offset2 = INT_MEM_OFFSET (loc);
+      offset2 = int_mem_offset (loc);
     }
   else
     return false;
@@ -5265,7 +5318,7 @@
   expr = var_debug_decl (expr);
   expr2 = var_debug_decl (expr2);
 
-  return (expr == expr2 && offset == offset2);
+  return (expr == expr2 && known_eq (offset, offset2));
 }
 
 /* LOC is a REG or MEM that we would like to track if possible.
@@ -5279,7 +5332,7 @@
    from EXPR in *OFFSET_OUT (if nonnull).  */
 
 static bool
-track_loc_p (rtx loc, tree expr, HOST_WIDE_INT offset, bool store_reg_p,
+track_loc_p (rtx loc, tree expr, poly_int64 offset, bool store_reg_p,
 	     machine_mode *mode_out, HOST_WIDE_INT *offset_out)
 {
   machine_mode mode;
@@ -5313,19 +5366,20 @@
        || (store_reg_p
 	   && !COMPLEX_MODE_P (DECL_MODE (expr))
 	   && hard_regno_nregs (REGNO (loc), DECL_MODE (expr)) == 1))
-      && offset + byte_lowpart_offset (DECL_MODE (expr), mode) == 0)
+      && known_eq (offset + byte_lowpart_offset (DECL_MODE (expr), mode), 0))
     {
       mode = DECL_MODE (expr);
       offset = 0;
     }
 
-  if (offset < 0 || offset >= MAX_VAR_PARTS)
+  HOST_WIDE_INT const_offset;
+  if (!track_offset_p (offset, &const_offset))
     return false;
 
   if (mode_out)
     *mode_out = mode;
   if (offset_out)
-    *offset_out = offset;
+    *offset_out = const_offset;
   return true;
 }
 
@@ -5336,7 +5390,7 @@
 static rtx
 var_lowpart (machine_mode mode, rtx loc)
 {
-  unsigned int offset, reg_offset, regno;
+  unsigned int regno;
 
   if (GET_MODE (loc) == mode)
     return loc;
@@ -5344,12 +5398,12 @@
   if (!REG_P (loc) && !MEM_P (loc))
     return NULL;
 
-  offset = byte_lowpart_offset (mode, GET_MODE (loc));
+  poly_uint64 offset = byte_lowpart_offset (mode, GET_MODE (loc));
 
   if (MEM_P (loc))
     return adjust_address_nv (loc, mode, offset);
 
-  reg_offset = subreg_lowpart_offset (mode, GET_MODE (loc));
+  poly_uint64 reg_offset = subreg_lowpart_offset (mode, GET_MODE (loc));
   regno = REGNO (loc) + subreg_regno_offset (REGNO (loc), GET_MODE (loc),
 					     reg_offset, mode);
   return gen_rtx_REG_offset (loc, mode, regno, offset);
@@ -5522,13 +5576,13 @@
 	return MO_CLOBBER;
       else if (target_for_debug_bind (var_debug_decl (expr)))
 	return MO_CLOBBER;
-      else if (track_loc_p (loc, expr, INT_MEM_OFFSET (loc),
+      else if (track_loc_p (loc, expr, int_mem_offset (loc),
 			    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
+	       && (!MAY_HAVE_DEBUG_BIND_INSNS
 		   || !rtx_debug_expr_p (XEXP (loc, 0))))
 	return MO_USE;
       else
@@ -5926,7 +5980,9 @@
 	  mo.type = MO_CLOBBER;
 	  mo.u.loc = loc;
 	  if (GET_CODE (expr) == SET
-	      && SET_DEST (expr) == loc
+	      && (SET_DEST (expr) == loc
+		  || (GET_CODE (SET_DEST (expr)) == STRICT_LOW_PART
+		      && XEXP (SET_DEST (expr), 0) == loc))
 	      && !unsuitable_loc (SET_SRC (expr))
 	      && find_use_val (loc, mode, cui))
 	    {
@@ -6017,7 +6073,7 @@
 	      rtx xexpr = gen_rtx_SET (loc, src);
 	      if (same_variable_part_p (SET_SRC (xexpr),
 					MEM_EXPR (loc),
-					INT_MEM_OFFSET (loc)))
+					int_mem_offset (loc)))
 		mo.type = MO_COPY;
 	      else
 		mo.type = MO_SET;
@@ -6056,7 +6112,7 @@
     }
 
   if (loc == stack_pointer_rtx
-      && hard_frame_pointer_adjustment != -1
+      && maybe_ne (hard_frame_pointer_adjustment, -1)
       && preserve)
     cselib_set_value_sp_based (v);
 
@@ -6693,7 +6749,7 @@
   dataflow_set_copy (&old_out, out);
   dataflow_set_copy (out, in);
 
-  if (MAY_HAVE_DEBUG_INSNS)
+  if (MAY_HAVE_DEBUG_BIND_INSNS)
     local_get_addr_cache = new hash_map<rtx, rtx>;
 
   FOR_EACH_VEC_ELT (VTI (bb)->mos, i, mo)
@@ -6975,7 +7031,7 @@
 	}
     }
 
-  if (MAY_HAVE_DEBUG_INSNS)
+  if (MAY_HAVE_DEBUG_BIND_INSNS)
     {
       delete local_get_addr_cache;
       local_get_addr_cache = NULL;
@@ -7062,7 +7118,7 @@
 	      else
 		oldinsz = oldoutsz = 0;
 
-	      if (MAY_HAVE_DEBUG_INSNS)
+	      if (MAY_HAVE_DEBUG_BIND_INSNS)
 		{
 		  dataflow_set *in = &VTI (bb)->in, *first_out = NULL;
 		  bool first = true, adjust = false;
@@ -7123,7 +7179,7 @@
 
 	      if (htabmax && htabsz > htabmax)
 		{
-		  if (MAY_HAVE_DEBUG_INSNS)
+		  if (MAY_HAVE_DEBUG_BIND_INSNS)
 		    inform (DECL_SOURCE_LOCATION (cfun->decl),
 			    "variable tracking size limit exceeded with "
 			    "-fvar-tracking-assignments, retrying without");
@@ -7183,7 +7239,7 @@
 	}
     }
 
-  if (success && MAY_HAVE_DEBUG_INSNS)
+  if (success && MAY_HAVE_DEBUG_BIND_INSNS)
     FOR_EACH_BB_FN (bb, cfun)
       gcc_assert (VTI (bb)->flooded);
 
@@ -8572,7 +8628,7 @@
   struct expand_loc_callback_data data;
   rtx result;
 
-  if (!MAY_HAVE_DEBUG_INSNS)
+  if (!MAY_HAVE_DEBUG_BIND_INSNS)
     return loc;
 
   INIT_ELCD (data, vars);
@@ -8627,7 +8683,6 @@
   bool complete;
   enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED;
   HOST_WIDE_INT last_limit;
-  tree type_size_unit;
   HOST_WIDE_INT offsets[MAX_VAR_PARTS];
   rtx loc[MAX_VAR_PARTS];
   tree decl;
@@ -8649,7 +8704,7 @@
     {
       machine_mode mode, wider_mode;
       rtx loc2;
-      HOST_WIDE_INT offset;
+      HOST_WIDE_INT offset, size, wider_size;
 
       if (i == 0 && var->onepart)
 	{
@@ -8704,7 +8759,14 @@
       mode = GET_MODE (var->var_part[i].cur_loc);
       if (mode == VOIDmode && var->onepart)
 	mode = DECL_MODE (decl);
-      last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
+      /* We ony track subparts of constant-sized objects, since at present
+	 there's no representation for polynomial pieces.  */
+      if (!GET_MODE_SIZE (mode).is_constant (&size))
+	{
+	  complete = false;
+	  continue;
+	}
+      last_limit = offsets[n_var_parts] + size;
 
       /* Attempt to merge adjacent registers or memory.  */
       for (j = i + 1; j < var->n_var_parts; j++)
@@ -8712,6 +8774,7 @@
 	  break;
       if (j < var->n_var_parts
 	  && GET_MODE_WIDER_MODE (mode).exists (&wider_mode)
+	  && GET_MODE_SIZE (wider_mode).is_constant (&wider_size)
 	  && var->var_part[j].cur_loc
 	  && mode == GET_MODE (var->var_part[j].cur_loc)
 	  && (REG_P (loc[n_var_parts]) || MEM_P (loc[n_var_parts]))
@@ -8720,6 +8783,7 @@
 	  && GET_CODE (loc[n_var_parts]) == GET_CODE (loc2))
 	{
 	  rtx new_loc = NULL;
+	  poly_int64 offset2;
 
 	  if (REG_P (loc[n_var_parts])
 	      && hard_regno_nregs (REGNO (loc[n_var_parts]), mode) * 2
@@ -8744,20 +8808,13 @@
 	  else if (MEM_P (loc[n_var_parts])
 		   && GET_CODE (XEXP (loc2, 0)) == PLUS
 		   && REG_P (XEXP (XEXP (loc2, 0), 0))
-		   && CONST_INT_P (XEXP (XEXP (loc2, 0), 1)))
+		   && poly_int_rtx_p (XEXP (XEXP (loc2, 0), 1), &offset2))
 	    {
-	      if ((REG_P (XEXP (loc[n_var_parts], 0))
-		   && rtx_equal_p (XEXP (loc[n_var_parts], 0),
-				   XEXP (XEXP (loc2, 0), 0))
-		   && INTVAL (XEXP (XEXP (loc2, 0), 1))
-		      == GET_MODE_SIZE (mode))
-		  || (GET_CODE (XEXP (loc[n_var_parts], 0)) == PLUS
-		      && CONST_INT_P (XEXP (XEXP (loc[n_var_parts], 0), 1))
-		      && rtx_equal_p (XEXP (XEXP (loc[n_var_parts], 0), 0),
-				      XEXP (XEXP (loc2, 0), 0))
-		      && INTVAL (XEXP (XEXP (loc[n_var_parts], 0), 1))
-			 + GET_MODE_SIZE (mode)
-			 == INTVAL (XEXP (XEXP (loc2, 0), 1))))
+	      poly_int64 end1 = size;
+	      rtx base1 = strip_offset_and_add (XEXP (loc[n_var_parts], 0),
+						&end1);
+	      if (rtx_equal_p (base1, XEXP (XEXP (loc2, 0), 0))
+		  && known_eq (end1, offset2))
 		new_loc = adjust_address_nv (loc[n_var_parts],
 					     wider_mode, 0);
 	    }
@@ -8766,14 +8823,15 @@
 	    {
 	      loc[n_var_parts] = new_loc;
 	      mode = wider_mode;
-	      last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
+	      last_limit = offsets[n_var_parts] + wider_size;
 	      i = j;
 	    }
 	}
       ++n_var_parts;
     }
-  type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (decl));
-  if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
+  poly_uint64 type_size_unit
+    = tree_to_poly_uint64 (TYPE_SIZE_UNIT (TREE_TYPE (decl)));
+  if (maybe_lt (poly_uint64 (last_limit), type_size_unit))
     complete = false;
 
   if (! flag_var_tracking_uninit)
@@ -8818,14 +8876,12 @@
       /* Make sure that the call related notes come first.  */
       while (NEXT_INSN (insn)
 	     && NOTE_P (insn)
-	     && ((NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
-		  && NOTE_DURING_CALL_P (insn))
-		 || NOTE_KIND (insn) == NOTE_INSN_CALL_ARG_LOCATION))
+	     && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
+	     && NOTE_DURING_CALL_P (insn))
 	insn = NEXT_INSN (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_KIND (insn) == NOTE_INSN_VAR_LOCATION
+	  && NOTE_DURING_CALL_P (insn))
 	note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
       else
 	note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
@@ -9007,7 +9063,7 @@
   if (!changed_variables->elements ())
     return;
 
-  if (MAY_HAVE_DEBUG_INSNS)
+  if (MAY_HAVE_DEBUG_BIND_INSNS)
     process_changed_values (htab);
 
   data.insn = insn;
@@ -9168,7 +9224,6 @@
 	    emit_notes_for_changes (insn, EMIT_NOTE_AFTER_CALL_INSN, set->vars);
 	    {
 	      rtx arguments = mo->u.loc, *p = &arguments;
-	      rtx_note *note;
 	      while (*p)
 		{
 		  XEXP (XEXP (*p, 0), 1)
@@ -9176,7 +9231,11 @@
 				     shared_hash_htab (set->vars));
 		  /* If expansion is successful, keep it in the list.  */
 		  if (XEXP (XEXP (*p, 0), 1))
-		    p = &XEXP (*p, 1);
+		    {
+		      XEXP (XEXP (*p, 0), 1)
+			= copy_rtx_if_shared (XEXP (XEXP (*p, 0), 1));
+		      p = &XEXP (*p, 1);
+		    }
 		  /* Otherwise, if the following item is data_value for it,
 		     drop it too too.  */
 		  else if (XEXP (*p, 1)
@@ -9192,8 +9251,7 @@
 		  else
 		    *p = XEXP (*p, 1);
 		}
-	      note = emit_note_after (NOTE_INSN_CALL_ARG_LOCATION, insn);
-	      NOTE_VAR_LOCATION (note) = arguments;
+	      add_reg_note (insn, REG_CALL_ARG_LOCATION, arguments);
 	    }
 	    break;
 
@@ -9491,10 +9549,8 @@
      delete_variable_part).  */
   emit_notes = true;
 
-  if (MAY_HAVE_DEBUG_INSNS)
-    {
-      dropped_values = new variable_table_type (cselib_get_next_uid () * 2);
-    }
+  if (MAY_HAVE_DEBUG_BIND_INSNS)
+    dropped_values = new variable_table_type (cselib_get_next_uid () * 2);
 
   dataflow_set_init (&cur);
 
@@ -9504,13 +9560,13 @@
 	 subsequent basic blocks.  */
       emit_notes_for_differences (BB_HEAD (bb), &cur, &VTI (bb)->in);
 
-      if (MAY_HAVE_DEBUG_INSNS)
+      if (MAY_HAVE_DEBUG_BIND_INSNS)
 	local_get_addr_cache = new hash_map<rtx, rtx>;
 
       /* Emit the notes for the changes in the basic block itself.  */
       emit_notes_in_bb (bb, &cur);
 
-      if (MAY_HAVE_DEBUG_INSNS)
+      if (MAY_HAVE_DEBUG_BIND_INSNS)
 	delete local_get_addr_cache;
       local_get_addr_cache = NULL;
 
@@ -9526,7 +9582,7 @@
 
   dataflow_set_destroy (&cur);
 
-  if (MAY_HAVE_DEBUG_INSNS)
+  if (MAY_HAVE_DEBUG_BIND_INSNS)
     delete dropped_values;
   dropped_values = NULL;
 
@@ -9537,7 +9593,7 @@
    assign declaration to *DECLP and offset to *OFFSETP, and return true.  */
 
 static bool
-vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
+vt_get_decl_and_offset (rtx rtl, tree *declp, poly_int64 *offsetp)
 {
   if (REG_P (rtl))
     {
@@ -9563,8 +9619,10 @@
 	    decl = REG_EXPR (reg);
 	  if (REG_EXPR (reg) != decl)
 	    break;
-	  if (REG_OFFSET (reg) < offset)
-	    offset = REG_OFFSET (reg);
+	  HOST_WIDE_INT this_offset;
+	  if (!track_offset_p (REG_OFFSET (reg), &this_offset))
+	    break;
+	  offset = MIN (offset, this_offset);
 	}
 
       if (i == len)
@@ -9579,7 +9637,7 @@
       if (MEM_ATTRS (rtl))
 	{
 	  *declp = MEM_EXPR (rtl);
-	  *offsetp = INT_MEM_OFFSET (rtl);
+	  *offsetp = int_mem_offset (rtl);
 	  return true;
 	}
     }
@@ -9608,9 +9666,10 @@
   rtx incoming = DECL_INCOMING_RTL (parm);
   tree decl;
   machine_mode mode;
-  HOST_WIDE_INT offset;
+  poly_int64 offset;
   dataflow_set *out;
   decl_or_value dv;
+  bool incoming_ok = true;
 
   if (TREE_CODE (parm) != PARM_DECL)
     return;
@@ -9625,20 +9684,17 @@
      rewrite the incoming location of parameters passed on the stack
      into MEMs based on the argument pointer, so that incoming doesn't
      depend on a pseudo.  */
+  poly_int64 incoming_offset = 0;
   if (MEM_P (incoming)
-      && (XEXP (incoming, 0) == crtl->args.internal_arg_pointer
-	  || (GET_CODE (XEXP (incoming, 0)) == PLUS
-	      && XEXP (XEXP (incoming, 0), 0)
-		 == crtl->args.internal_arg_pointer
-	      && CONST_INT_P (XEXP (XEXP (incoming, 0), 1)))))
+      && (strip_offset (XEXP (incoming, 0), &incoming_offset)
+	  == crtl->args.internal_arg_pointer))
     {
       HOST_WIDE_INT off = -FIRST_PARM_OFFSET (current_function_decl);
-      if (GET_CODE (XEXP (incoming, 0)) == PLUS)
-	off += INTVAL (XEXP (XEXP (incoming, 0), 1));
       incoming
 	= replace_equiv_address_nv (incoming,
 				    plus_constant (Pmode,
-						   arg_pointer_rtx, off));
+						   arg_pointer_rtx,
+						   off + incoming_offset));
     }
 
 #ifdef HAVE_window_save
@@ -9701,6 +9757,7 @@
 
   if (!vt_get_decl_and_offset (incoming, &decl, &offset))
     {
+      incoming_ok = false;
       if (MEM_P (incoming))
 	{
 	  /* This means argument is passed by invisible reference.  */
@@ -9731,7 +9788,8 @@
       offset = 0;
     }
 
-  if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
+  HOST_WIDE_INT const_offset;
+  if (!track_loc_p (incoming, parm, offset, false, &mode, &const_offset))
     return;
 
   out = &VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun))->out;
@@ -9752,7 +9810,7 @@
 	 arguments passed by invisible reference aren't dealt with
 	 above: incoming-rtl will have Pmode rather than the
 	 expected mode for the type.  */
-      if (offset)
+      if (const_offset)
 	return;
 
       lowpart = var_lowpart (mode, incoming);
@@ -9767,7 +9825,7 @@
       if (val)
 	{
 	  preserve_value (val);
-	  set_variable_part (out, val->val_rtx, dv, offset,
+	  set_variable_part (out, val->val_rtx, dv, const_offset,
 			     VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
 	  dv = dv_from_value (val->val_rtx);
 	}
@@ -9788,9 +9846,9 @@
     {
       incoming = var_lowpart (mode, incoming);
       gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
-      attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
+      attrs_list_insert (&out->regs[REGNO (incoming)], dv, const_offset,
 			 incoming);
-      set_variable_part (out, incoming, dv, offset,
+      set_variable_part (out, incoming, dv, const_offset,
 			 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
       if (dv_is_value_p (dv))
 	{
@@ -9818,20 +9876,26 @@
     {
       int i;
 
+      /* The following code relies on vt_get_decl_and_offset returning true for
+	 incoming, which might not be always the case.  */
+      if (!incoming_ok)
+	return;
       for (i = 0; i < XVECLEN (incoming, 0); i++)
 	{
 	  rtx reg = XEXP (XVECEXP (incoming, 0, i), 0);
-	  offset = REG_OFFSET (reg);
+	  /* vt_get_decl_and_offset has already checked that the offset
+	     is a valid variable part.  */
+	  const_offset = get_tracked_reg_offset (reg);
 	  gcc_assert (REGNO (reg) < FIRST_PSEUDO_REGISTER);
-	  attrs_list_insert (&out->regs[REGNO (reg)], dv, offset, reg);
-	  set_variable_part (out, reg, dv, offset,
+	  attrs_list_insert (&out->regs[REGNO (reg)], dv, const_offset, reg);
+	  set_variable_part (out, reg, dv, const_offset,
 			     VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
 	}
     }
   else if (MEM_P (incoming))
     {
       incoming = var_lowpart (mode, incoming);
-      set_variable_part (out, incoming, dv, offset,
+      set_variable_part (out, incoming, dv, const_offset,
 			 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
     }
 }
@@ -9845,8 +9909,7 @@
 
   for (parm = DECL_ARGUMENTS (current_function_decl);
        parm; parm = DECL_CHAIN (parm))
-    if (!POINTER_BOUNDS_P (parm))
-      vt_add_function_parameter (parm);
+    vt_add_function_parameter (parm);
 
   if (DECL_HAS_VALUE_EXPR_P (DECL_RESULT (current_function_decl)))
     {
@@ -9886,7 +9949,7 @@
       cfa_base_rtx = NULL_RTX;
       return;
     }
-  if (!MAY_HAVE_DEBUG_INSNS)
+  if (!MAY_HAVE_DEBUG_BIND_INSNS)
     return;
 
   /* Tell alias analysis that cfa_base_rtx should share
@@ -9902,6 +9965,35 @@
   cselib_preserve_cfa_base_value (val, REGNO (cfa_base_rtx));
 }
 
+/* Reemit INSN, a MARKER_DEBUG_INSN, as a note.  */
+
+static rtx_insn *
+reemit_marker_as_note (rtx_insn *insn)
+{
+  gcc_checking_assert (DEBUG_MARKER_INSN_P (insn));
+
+  enum insn_note kind = INSN_DEBUG_MARKER_KIND (insn);
+
+  switch (kind)
+    {
+    case NOTE_INSN_BEGIN_STMT:
+    case NOTE_INSN_INLINE_ENTRY:
+      {
+	rtx_insn *note = NULL;
+	if (cfun->debug_nonbind_markers)
+	  {
+	    note = emit_note_before (kind, insn);
+	    NOTE_MARKER_LOCATION (note) = INSN_LOCATION (insn);
+	  }
+	delete_insn (insn);
+	return note;
+      }
+
+    default:
+      gcc_unreachable ();
+    }
+}
+
 /* Allocate and initialize the data structures for variable tracking
    and parse the RTL to get the micro operations.  */
 
@@ -9909,7 +10001,7 @@
 vt_initialize (void)
 {
   basic_block bb;
-  HOST_WIDE_INT fp_cfa_offset = -1;
+  poly_int64 fp_cfa_offset = -1;
 
   alloc_aux_for_blocks (sizeof (variable_tracking_info));
 
@@ -9928,7 +10020,7 @@
       VTI (bb)->permp = NULL;
     }
 
-  if (MAY_HAVE_DEBUG_INSNS)
+  if (MAY_HAVE_DEBUG_BIND_INSNS)
     {
       cselib_init (CSELIB_RECORD_MEMORY | CSELIB_PRESERVE_CONSTANTS);
       scratch_regs = BITMAP_ALLOC (NULL);
@@ -9941,7 +10033,7 @@
       global_get_addr_cache = NULL;
     }
 
-  if (MAY_HAVE_DEBUG_INSNS)
+  if (MAY_HAVE_DEBUG_BIND_INSNS)
     {
       rtx reg, expr;
       int ofst;
@@ -10024,7 +10116,7 @@
 	{
 	  if (GET_CODE (elim) == PLUS)
 	    {
-	      fp_cfa_offset -= INTVAL (XEXP (elim, 1));
+	      fp_cfa_offset -= rtx_to_poly_int64 (XEXP (elim, 1));
 	      elim = XEXP (elim, 0);
 	    }
 	  if (elim != hard_frame_pointer_rtx)
@@ -10071,7 +10163,7 @@
       HOST_WIDE_INT pre, post = 0;
       basic_block first_bb, last_bb;
 
-      if (MAY_HAVE_DEBUG_INSNS)
+      if (MAY_HAVE_DEBUG_BIND_INSNS)
 	{
 	  cselib_record_sets_hook = add_with_sets;
 	  if (dump_file && (dump_flags & TDF_DETAILS))
@@ -10098,8 +10190,9 @@
 	{
 	  HOST_WIDE_INT offset = VTI (bb)->out.stack_adjust;
 	  VTI (bb)->out.stack_adjust = VTI (bb)->in.stack_adjust;
-	  for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
-	       insn = NEXT_INSN (insn))
+
+	  rtx_insn *next;
+	  FOR_BB_INSNS_SAFE (bb, insn, next)
 	    {
 	      if (INSN_P (insn))
 		{
@@ -10116,20 +10209,32 @@
 			    log_op_type (PATTERN (insn), bb, insn,
 					 MO_ADJUST, dump_file);
 			  VTI (bb)->mos.safe_push (mo);
-			  VTI (bb)->out.stack_adjust += pre;
 			}
 		    }
 
 		  cselib_hook_called = false;
 		  adjust_insn (bb, insn);
-		  if (MAY_HAVE_DEBUG_INSNS)
+
+		  if (!frame_pointer_needed && pre)
+		    VTI (bb)->out.stack_adjust += pre;
+
+		  if (DEBUG_MARKER_INSN_P (insn))
+		    {
+		      reemit_marker_as_note (insn);
+		      continue;
+		    }
+
+		  if (MAY_HAVE_DEBUG_BIND_INSNS)
 		    {
 		      if (CALL_P (insn))
 			prepare_call_arguments (bb, insn);
 		      cselib_process_insn (insn);
 		      if (dump_file && (dump_flags & TDF_DETAILS))
 			{
-			  print_rtl_single (dump_file, insn);
+			  if (dump_flags & TDF_SLIM)
+			    dump_insn_slim (dump_file, insn);
+			  else
+			    print_rtl_single (dump_file, insn);
 			  dump_cselib_table (dump_file);
 			}
 		    }
@@ -10150,14 +10255,14 @@
 		      VTI (bb)->out.stack_adjust += post;
 		    }
 
-		  if (fp_cfa_offset != -1
-		      && hard_frame_pointer_adjustment == -1
+		  if (maybe_ne (fp_cfa_offset, -1)
+		      && known_eq (hard_frame_pointer_adjustment, -1)
 		      && fp_setter_insn (insn))
 		    {
 		      vt_init_cfa_base ();
 		      hard_frame_pointer_adjustment = fp_cfa_offset;
 		      /* Disassociate sp from fp now.  */
-		      if (MAY_HAVE_DEBUG_INSNS)
+		      if (MAY_HAVE_DEBUG_BIND_INSNS)
 			{
 			  cselib_val *v;
 			  cselib_invalidate_rtx (stack_pointer_rtx);
@@ -10177,7 +10282,7 @@
 
       bb = last_bb;
 
-      if (MAY_HAVE_DEBUG_INSNS)
+      if (MAY_HAVE_DEBUG_BIND_INSNS)
 	{
 	  cselib_preserve_only_values ();
 	  cselib_reset_table (cselib_get_next_uid ());
@@ -10197,10 +10302,40 @@
 
 static int debug_label_num = 1;
 
-/* Get rid of all debug insns from the insn stream.  */
-
-static void
-delete_debug_insns (void)
+/* Remove from the insn stream a single debug insn used for
+   variable tracking at assignments.  */
+
+static inline void
+delete_vta_debug_insn (rtx_insn *insn)
+{
+  if (DEBUG_MARKER_INSN_P (insn))
+    {
+      reemit_marker_as_note (insn);
+      return;
+    }
+
+  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);
+}
+
+/* Remove from the insn stream all debug insns used for variable
+   tracking at assignments.  USE_CFG should be false if the cfg is no
+   longer usable.  */
+
+void
+delete_vta_debug_insns (bool use_cfg)
 {
   basic_block bb;
   rtx_insn *insn, *next;
@@ -10208,27 +10343,20 @@
   if (!MAY_HAVE_DEBUG_INSNS)
     return;
 
-  FOR_EACH_BB_FN (bb, cfun)
-    {
-      FOR_BB_INSNS_SAFE (bb, insn, next)
+  if (use_cfg)
+    FOR_EACH_BB_FN (bb, cfun)
+      {
+	FOR_BB_INSNS_SAFE (bb, insn, next)
+	  if (DEBUG_INSN_P (insn))
+	    delete_vta_debug_insn (insn);
+      }
+  else
+    for (insn = get_insns (); insn; insn = next)
+      {
+	next = NEXT_INSN (insn);
 	if (DEBUG_INSN_P (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);
-	  }
-    }
+	  delete_vta_debug_insn (insn);
+      }
 }
 
 /* Run a fast, BB-local only version of var tracking, to take care of
@@ -10241,7 +10369,7 @@
 vt_debug_insns_local (bool skipped ATTRIBUTE_UNUSED)
 {
   /* ??? Just skip it all for now.  */
-  delete_debug_insns ();
+  delete_vta_debug_insns (true);
 }
 
 /* Free the data structures needed for variable tracking.  */
@@ -10276,7 +10404,7 @@
   location_chain_pool.release ();
   shared_hash_pool.release ();
 
-  if (MAY_HAVE_DEBUG_INSNS)
+  if (MAY_HAVE_DEBUG_BIND_INSNS)
     {
       if (global_get_addr_cache)
 	delete global_get_addr_cache;
@@ -10306,17 +10434,23 @@
 {
   bool success;
 
-  if (flag_var_tracking_assignments < 0
+  /* We won't be called as a separate pass if flag_var_tracking is not
+     set, but final may call us to turn debug markers into notes.  */
+  if ((!flag_var_tracking && MAY_HAVE_DEBUG_INSNS)
+      || flag_var_tracking_assignments < 0
       /* Var-tracking right now assumes the IR doesn't contain
 	 any pseudos at this point.  */
       || targetm.no_register_allocation)
     {
-      delete_debug_insns ();
+      delete_vta_debug_insns (true);
       return 0;
     }
 
-  if (n_basic_blocks_for_fn (cfun) > 500 &&
-      n_edges_for_fn (cfun) / n_basic_blocks_for_fn (cfun) >= 20)
+  if (!flag_var_tracking)
+    return 0;
+
+  if (n_basic_blocks_for_fn (cfun) > 500
+      && n_edges_for_fn (cfun) / n_basic_blocks_for_fn (cfun) >= 20)
     {
       vt_debug_insns_local (true);
       return 0;
@@ -10336,7 +10470,7 @@
     {
       vt_finalize ();
 
-      delete_debug_insns ();
+      delete_vta_debug_insns (true);
 
       /* This is later restored by our caller.  */
       flag_var_tracking_assignments = 0;