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]

Re: [vta->trunk] VTA merge


On Aug 31, 2009, Richard Henderson <rth@redhat.com> wrote:

>> +	  if (!id->debug_stmts)
>> +	    id->debug_stmts = VEC_alloc (gimple, heap, 1);
>> +	  VEC_safe_push (gimple, heap, id->debug_stmts, copy);

> Note that VEC_safe_push will also handle the initial
> allocation of the VEC from NULL.  It's quite handy.

Aah, indeed, this makes room for a few simplifications.  Even more so
because id is zero initialized.

Here's the revised patch I'm testing now, with a few additional
adjustments.  It has already completed bootstrap on i686-pc-linux-gnu.

Removed:
	* fwprop.c (try_fwprop_subst): Deal with NULL set.

Index: gcc/cse.c
===================================================================
--- gcc/cse.c.orig	2009-08-31 21:28:48.000000000 -0300
+++ gcc/cse.c	2009-08-31 21:28:57.000000000 -0300
@@ -6246,8 +6246,7 @@ cse_extended_basic_block (struct cse_bas
 
 	     FIXME: This is a real kludge and needs to be done some other
 		    way.  */
-	  if (INSN_P (insn)
-	      && !DEBUG_INSN_P (insn)
+	  if (NONDEBUG_INSN_P (insn)
 	      && num_insns++ > PARAM_VALUE (PARAM_MAX_CSE_INSNS))
 	    {
 	      flush_hash_table ();
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in.orig	2009-08-31 21:28:51.000000000 -0300
+++ gcc/Makefile.in	2009-08-31 21:28:57.000000000 -0300
@@ -911,7 +911,7 @@ SCEV_H = tree-scalar-evolution.h $(GGC_H
 LAMBDA_H = lambda.h $(TREE_H) vec.h $(GGC_H)
 TREE_DATA_REF_H = tree-data-ref.h $(LAMBDA_H) omega.h graphds.h $(SCEV_H)
 VARRAY_H = varray.h $(MACHMODE_H) $(SYSTEM_H) coretypes.h $(TM_H)
-TREE_INLINE_H = tree-inline.h pointer-set.h
+TREE_INLINE_H = tree-inline.h $(GIMPLE_H)
 REAL_H = real.h $(MACHMODE_H)
 IRA_INT_H = ira.h ira-int.h $(CFGLOOP_H) alloc-pool.h
 DBGCNT_H = dbgcnt.h dbgcnt.def
Index: gcc/tree-inline.c
===================================================================
--- gcc/tree-inline.c.orig	2009-08-31 21:28:51.000000000 -0300
+++ gcc/tree-inline.c	2009-08-31 22:53:15.000000000 -0300
@@ -1335,7 +1335,7 @@ remap_gimple_stmt (gimple stmt, copy_bod
 	  copy = gimple_build_debug_bind (gimple_debug_bind_get_var (stmt),
 					  gimple_debug_bind_get_value (stmt),
 					  stmt);
-	  VARRAY_PUSH_GENERIC_PTR (id->debug_stmts, copy);
+	  VEC_safe_push (gimple, heap, id->debug_stmts, copy);
 	  return copy;
 	}
       else
@@ -2122,20 +2122,22 @@ copy_debug_stmt (gimple stmt, copy_body_
 
 /* Process deferred debug stmts.  In order to give values better odds
    of being successfully remapped, we delay the processing of debug
-   stmts.  */
+   stmts until all other stmts that might require remapping are
+   processed.  */
 
 static void
 copy_debug_stmts (copy_body_data *id)
 {
-  size_t i, e;
+  size_t i;
+  gimple stmt;
 
   if (!id->debug_stmts)
     return;
 
-  for (i = 0, e = VARRAY_ACTIVE_SIZE (id->debug_stmts); i < e; i++)
-    copy_debug_stmt ((gimple) VARRAY_GENERIC_PTR (id->debug_stmts, i), id);
+  for (i = 0; VEC_iterate (gimple, id->debug_stmts, i, stmt); i++)
+    copy_debug_stmt (stmt, id);
 
-  VARRAY_POP_ALL (id->debug_stmts);
+  VEC_free (gimple, heap, id->debug_stmts);
 }
 
 /* Make a copy of the body of SRC_FN so that it can be inserted inline in
@@ -2226,8 +2228,6 @@ insert_init_debug_bind (copy_body_data *
 	gsi_insert_before (&gsi, note, GSI_SAME_STMT);
     }
 
-  mark_symbols_for_renaming (note);
-
   return note;
 }
 
@@ -3882,8 +3882,6 @@ optimize_inline_calls (tree fn)
   id.transform_return_to_modify = true;
   id.transform_lang_insert_block = NULL;
   id.statements_to_fold = pointer_set_create ();
-  if (MAY_HAVE_DEBUG_STMTS)
-    VARRAY_GENERIC_PTR_INIT (id.debug_stmts, 8, "debug_stmt");
 
   push_gimplify_context (&gctx);
 
@@ -3921,6 +3919,8 @@ optimize_inline_calls (tree fn)
   fold_marked_statements (last, id.statements_to_fold);
   pointer_set_destroy (id.statements_to_fold);
   
+  gcc_assert (!id.debug_stmts);
+
   /* Renumber the (code) basic_blocks consecutively.  */
   compact_blocks ();
   /* Renumber the lexical scoping (non-code) blocks consecutively.  */
@@ -4736,9 +4736,6 @@ tree_function_versioning (tree old_decl,
   /* Generate a new name for the new version. */
   id.statements_to_fold = pointer_set_create ();
 
-  if (MAY_HAVE_DEBUG_STMTS)
-    VARRAY_GENERIC_PTR_INIT (id.debug_stmts, 8, "debug_stmt");
-  
   id.decl_map = pointer_map_create ();
   id.debug_map = NULL;
   id.src_fn = old_decl;
@@ -4875,6 +4872,7 @@ tree_function_versioning (tree old_decl,
   free_dominance_info (CDI_DOMINATORS);
   free_dominance_info (CDI_POST_DOMINATORS);
 
+  gcc_assert (!id.debug_stmts);
   VEC_free (gimple, heap, init_stmts);
   pop_cfun ();
   current_function_decl = old_current_function_decl;
Index: gcc/tree-inline.h
===================================================================
--- gcc/tree-inline.h.orig	2009-08-31 21:28:52.000000000 -0300
+++ gcc/tree-inline.h	2009-08-31 21:28:57.000000000 -0300
@@ -22,8 +22,7 @@ along with GCC; see the file COPYING3.  
 #ifndef GCC_TREE_INLINE_H
 #define GCC_TREE_INLINE_H
 
-#include "varray.h"
-#include "pointer-set.h"
+#include "gimple.h"
 
 struct cgraph_edge;
 
@@ -120,7 +119,7 @@ typedef struct copy_body_data
   struct basic_block_def *entry_bb;
 
   /* Debug statements that need processing.  */
-  varray_type debug_stmts;
+  VEC(gimple,heap) *debug_stmts;
 
   /* A map from local declarations in the inlined function to
      equivalents in the function into which it is being inlined, where
Index: gcc/cfgexpand.c
===================================================================
--- gcc/cfgexpand.c.orig	2009-08-31 21:28:54.000000000 -0300
+++ gcc/cfgexpand.c	2009-08-31 21:28:57.000000000 -0300
@@ -3055,7 +3055,7 @@ expand_gimple_basic_block (basic_block b
 	  if (new_bb)
 	    return new_bb;
 	}
-      else if (is_gimple_debug (stmt))
+      else if (gimple_debug_bind_p (stmt))
 	{
 	  location_t sloc = get_curr_insn_source_location ();
 	  tree sblock = get_curr_insn_block ();
@@ -3102,7 +3102,7 @@ expand_gimple_basic_block (basic_block b
 	      if (gsi_end_p (nsi))
 		break;
 	      stmt = gsi_stmt (nsi);
-	      if (!is_gimple_debug (stmt))
+	      if (!gimple_debug_bind_p (stmt))
 		break;
 	    }
 
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c.orig	2009-08-31 21:28:49.000000000 -0300
+++ gcc/dwarf2out.c	2009-08-31 21:28:57.000000000 -0300
@@ -11541,7 +11541,7 @@ loc_descriptor (rtx rtl, enum machine_mo
       break;
 
     case CONST_INT:
-      if (mode != VOIDmode && mode != BLKmode)
+      if (mode != VOIDmode && mode != BLKmode && dwarf_version >= 4)
         {
           HOST_WIDE_INT i = INTVAL (rtl);
           int litsize;
@@ -11595,7 +11595,7 @@ loc_descriptor (rtx rtl, enum machine_mo
       break;
 
     case CONST_DOUBLE:
-      if (mode != VOIDmode)
+      if (mode != VOIDmode && dwarf_version >= 4)
 	{
 	  /* Note that a CONST_DOUBLE rtx could represent either an integer
 	     or a floating-point constant.  A CONST_DOUBLE is used whenever
@@ -11626,7 +11626,7 @@ loc_descriptor (rtx rtl, enum machine_mo
       break;
 
     case CONST_VECTOR:
-      if (mode != VOIDmode)
+      if (mode != VOIDmode && dwarf_version >= 4)
 	{
 	  unsigned int elt_size = GET_MODE_UNIT_SIZE (GET_MODE (rtl));
 	  unsigned int length = CONST_VECTOR_NUNITS (rtl);
@@ -11714,7 +11714,8 @@ loc_descriptor (rtx rtl, enum machine_mo
 	  && SYMBOL_REF_TLS_MODEL (rtl) != TLS_MODEL_NONE)
 	break;
     case LABEL_REF:
-      if (mode != VOIDmode && GET_MODE_SIZE (mode) == DWARF2_ADDR_SIZE)
+      if (mode != VOIDmode && GET_MODE_SIZE (mode) == DWARF2_ADDR_SIZE
+	  && dwarf_version >= 4)
 	{
 	  loc_result = new_loc_descr (DW_OP_implicit_value,
 				      DWARF2_ADDR_SIZE, 0);
@@ -11726,7 +11727,8 @@ loc_descriptor (rtx rtl, enum machine_mo
 
     default:
       if (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE (rtl) == mode
-	  && GET_MODE_SIZE (GET_MODE (rtl)) <= DWARF2_ADDR_SIZE)
+	  && GET_MODE_SIZE (GET_MODE (rtl)) <= DWARF2_ADDR_SIZE
+	  && dwarf_version >= 4)
 	{
 	  /* Value expression.  */
 	  loc_result = mem_loc_descriptor (rtl, VOIDmode, initialized);
Index: gcc/expr.c
===================================================================
--- gcc/expr.c.orig	2009-08-31 21:28:51.000000000 -0300
+++ gcc/expr.c	2009-08-31 21:28:58.000000000 -0300
@@ -6002,7 +6002,7 @@ get_inner_reference (tree exp, HOST_WIDE
 
   /* Compute cumulative bit-offset for nested component-refs and array-refs,
      and find the ultimate containing object.  */
-  do
+  while (1)
     {
       switch (TREE_CODE (exp))
 	{
@@ -6081,7 +6081,6 @@ get_inner_reference (tree exp, HOST_WIDE
 
       exp = TREE_OPERAND (exp, 0);
     }
-  while (exp);
  done:
 
   /* If OFFSET is constant, see if we can return the whole thing as a
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c.orig	2009-08-31 21:28:51.000000000 -0300
+++ gcc/var-tracking.c	2009-08-31 21:28:58.000000000 -0300
@@ -2742,25 +2742,8 @@ canonicalize_values_mark (void **slot, v
 	    decl_or_value odv = dv_from_value (node->loc);
 	    void **oslot = shared_hash_find_slot_noinsert (set->vars, odv);
 
-#if 0 && ENABLE_CHECKING
-	    variable ovar;
-	    location_chain onode;
-
-	    gcc_assert (oslot);
-	    ovar = (variable)*oslot;
-	    gcc_assert (ovar->n_var_parts == 1);
-	    for (onode = ovar->var_part[0].loc_chain; onode;
-		 onode = onode->next)
-	      if (onode->loc == val)
-		break;
-
-	    gcc_assert (onode);
-
-	    /* ??? Remove this in case the assertion above never fails.  */
-	    if (!onode)
-#endif
-	      oslot = set_slot_part (set, val, oslot, odv, 0,
-				     node->init, NULL_RTX);
+	    oslot = set_slot_part (set, val, oslot, odv, 0,
+				   node->init, NULL_RTX);
 
 	    VALUE_RECURSED_INTO (node->loc) = true;
 	  }
@@ -2971,23 +2954,8 @@ canonicalize_values_star (void **slot, v
       }
 
   if (val)
-    {
-#if 0 && ENABLE_CHECKING
-      variable cvar = (variable)*cslot;
-
-      gcc_assert (cvar->n_var_parts == 1);
-      for (node = cvar->var_part[0].loc_chain; node; node = node->next)
-	if (node->loc == val)
-	  break;
-
-      gcc_assert (node);
-
-      /* ??? Remove this in case the assertion above never fails.  */
-      if (!node)
-#endif
-	cslot = set_slot_part (set, val, cslot, cdv, 0,
-			       VAR_INIT_STATUS_INITIALIZED, NULL_RTX);
-    }
+    cslot = set_slot_part (set, val, cslot, cdv, 0,
+			   VAR_INIT_STATUS_INITIALIZED, NULL_RTX);
 
   slot = clobber_slot_part (set, cval, slot, 0, NULL);
 
@@ -3582,65 +3550,6 @@ variable_post_merge_new_vals (void **slo
 	      *curp = att->next;
 	      pool_free (attrs_pool, att);
 	    }
-#if 0 /* Don't push constants to values.  If you remove this, adjust
-	 the corresponding comment containing 'push constants to
-	 values' below.  */
-	  else if (GET_CODE (node->loc) == CONST_INT
-		   || GET_CODE (node->loc) == CONST_FIXED
-		   || GET_CODE (node->loc) == CONST_DOUBLE
-		   || GET_CODE (node->loc) == SYMBOL_REF)
-	    {
-	      decl_or_value cdv;
-	      rtx cval;
-	      cselib_val *v;
-	      void **oslot;
-
-	      if (var->refcount != 1)
-		{
-		  slot = unshare_variable (set, slot, var,
-					   VAR_INIT_STATUS_INITIALIZED);
-		  var = (variable)*slot;
-		  goto restart;
-		}
-
-	      v = cselib_lookup (node->loc,
-				 TYPE_MODE (TREE_TYPE (dv_as_decl (var->dv))),
-				 1);
-
-	      if (dump_file)
-		{
-		  fprintf (dump_file, "%s new value %i for ",
-			   cselib_preserved_value_p (v)
-			   ? "Reused" : "Created", v->value);
-		  print_rtl_single (dump_file, node->loc);
-		  fputc ('\n', dump_file);
-		}
-
-	      cselib_preserve_value (v);
-	      cval = v->val_rtx;
-	      cdv = dv_from_value (cval);
-
-	      oslot = shared_hash_find_slot_noinsert (set->vars, cdv);
-	      if (oslot)
-		oslot = set_slot_part (set, node->loc, oslot, cdv, 0,
-				       VAR_INIT_STATUS_INITIALIZED,
-				       NULL_RTX);
-	      else
-		{
-		  if (!*dfpm->permp)
-		    {
-		      *dfpm->permp = XNEW (dataflow_set);
-		      dataflow_set_init (*dfpm->permp);
-		    }
-
-		  set_variable_part (*dfpm->permp, node->loc, cdv, 0,
-				     VAR_INIT_STATUS_INITIALIZED, NULL,
-				     NO_INSERT);
-		}
-	      node->loc = cval;
-	      check_dupes = true;
-	    }
-#endif
 	}
 
       if (check_dupes)
@@ -7079,14 +6988,13 @@ vt_emit_notes (void)
   htab_traverse (shared_hash_htab (cur.vars),
 		 emit_notes_for_differences_1,
 		 shared_hash_htab (empty_shared_hash));
+  if (MAY_HAVE_DEBUG_INSNS)
+    gcc_assert (htab_elements (value_chains) == 0);
 #endif
   dataflow_set_destroy (&cur);
 
   if (MAY_HAVE_DEBUG_INSNS)
-    {
-      gcc_assert (htab_elements (value_chains) == 0);
-      VEC_free (variable, heap, changed_variables_stack);
-    }
+    VEC_free (variable, heap, changed_variables_stack);
 
   emit_notes = false;
 }
Index: gcc/gimple.h
===================================================================
--- gcc/gimple.h.orig	2009-08-31 21:28:48.000000000 -0300
+++ gcc/gimple.h	2009-08-31 21:28:58.000000000 -0300
@@ -114,9 +114,15 @@ enum gf_mask {
     GF_OMP_RETURN_NOWAIT	= 1 << 0,
 
     GF_OMP_SECTION_LAST		= 1 << 0,
-    GF_PREDICT_TAKEN		= 1 << 15,
+    GF_PREDICT_TAKEN		= 1 << 15
+};
 
-    GIMPLE_DEBUG_BIND		= 0
+/* Currently, there's only one type of gimple debug stmt.  Others are
+   envisioned, for example, to enable the generation of is_stmt notes
+   in line number information, to mark sequence points, etc.  This
+   subcode is to be used to tell them apart.  */
+enum gimple_debug_subcode {
+  GIMPLE_DEBUG_BIND = 0
 };
 
 /* Masks for selecting a pass local flag (PLF) to work on.  These
Index: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c.orig	2009-08-31 21:28:49.000000000 -0300
+++ gcc/tree-cfg.c	2009-08-31 21:28:58.000000000 -0300
@@ -1395,6 +1395,49 @@ gimple_can_merge_blocks_p (basic_block a
   return true;
 }
 
+/* Return true if the var whose chain of uses starts at PTR has no
+   nondebug uses.  */
+bool
+has_zero_uses_1 (const ssa_use_operand_t *head)
+{
+  const ssa_use_operand_t *ptr;
+
+  for (ptr = head->next; ptr != head; ptr = ptr->next)
+    if (!is_gimple_debug (USE_STMT (ptr)))
+      return false;
+
+  return true;
+}
+
+/* Return true if the var whose chain of uses starts at PTR has a
+   single nondebug use.  Set USE_P and STMT to that single nondebug
+   use, if so, or to NULL otherwise.  */
+bool
+single_imm_use_1 (const ssa_use_operand_t *head,
+		  use_operand_p *use_p, gimple *stmt)
+{
+  ssa_use_operand_t *ptr, *single_use = 0;
+
+  for (ptr = head->next; ptr != head; ptr = ptr->next)
+    if (!is_gimple_debug (USE_STMT (ptr)))
+      {
+	if (single_use)
+	  {
+	    single_use = NULL;
+	    break;
+	  }
+	single_use = ptr;
+      }
+
+  if (use_p)
+    *use_p = single_use;
+
+  if (stmt)
+    *stmt = single_use ? single_use->loc.stmt : NULL;
+
+  return !!single_use;
+}
+
 /* Replaces all uses of NAME by VAL.  */
 
 void
@@ -4137,7 +4180,12 @@ verify_gimple_phi (gimple stmt)
 static bool
 verify_gimple_debug (gimple stmt ATTRIBUTE_UNUSED)
 {
-  /* ??? FIXME.  */
+  /* There isn't much that could be wrong in a gimple debug stmt.  A
+     gimple debug bind stmt, for example, maps a tree, that's usually
+     a VAR_DECL or a PARM_DECL, but that could also be some scalarized
+     component or member of an aggregate type, to another tree, that
+     can be an arbitrary expression.  These stmts expand into debug
+     insns, and are converted to debug notes by var-tracking.c.  */
   return false;
 }
 
Index: gcc/tree-flow-inline.h
===================================================================
--- gcc/tree-flow-inline.h.orig	2009-08-31 21:28:50.000000000 -0300
+++ gcc/tree-flow-inline.h	2009-08-31 21:28:58.000000000 -0300
@@ -358,100 +358,88 @@ next_readonly_imm_use (imm_use_iterator 
   return imm->imm_use;
 }
 
-/* Return true if VAR has no uses.  */
+/* tree-cfg.c */
+extern bool has_zero_uses_1 (const ssa_use_operand_t *head);
+extern bool single_imm_use_1 (const ssa_use_operand_t *head,
+			      use_operand_p *use_p, gimple *stmt);
+
+/* Return true if VAR has no nondebug uses.  */
 static inline bool
 has_zero_uses (const_tree var)
 {
-  const ssa_use_operand_t *ptr, *start;
-  bool ret;
+  const ssa_use_operand_t *const ptr = &(SSA_NAME_IMM_USE_NODE (var));
 
-  ptr = &(SSA_NAME_IMM_USE_NODE (var));
-  /* A single use means there is no items in the list.  */
-  ret = (ptr == ptr->next);
-
-  if (ret || !MAY_HAVE_DEBUG_STMTS)
-    return ret;
-
-  start = ptr;
-  for (ptr = start->next; ptr != start; ptr = ptr->next)
-    if (!is_gimple_debug (USE_STMT (ptr)))
-      return false;
-  return true;
+  /* A single use_operand means there is no items in the list.  */
+  if (ptr == ptr->next)
+    return true;
+
+  /* If there are debug stmts, we have to look at each use and see
+     whether there are any nondebug uses.  */
+  if (!MAY_HAVE_DEBUG_STMTS)
+    return false;
+
+  return has_zero_uses_1 (ptr);
 }
 
-/* Return true if VAR has a single use.  */
+/* Return true if VAR has a single nondebug use.  */
 static inline bool
 has_single_use (const_tree var)
 {
-  const ssa_use_operand_t *ptr, *start;
-  bool ret;
+  const ssa_use_operand_t *const ptr = &(SSA_NAME_IMM_USE_NODE (var));
 
-  ptr = &(SSA_NAME_IMM_USE_NODE (var));
-  /* A single use means there is one item in the list.  */
-  ret = (ptr != ptr->next && ptr == ptr->next->next);
+  /* If there aren't any uses whatsoever, we're done.  */
+  if (ptr == ptr->next)
+    return false;
 
-  if (ret)
+  /* If there's a single use, check that it's not a debug stmt.  */
+  if (ptr == ptr->next->next)
     return !is_gimple_debug (USE_STMT (ptr->next));
-  else if (!MAY_HAVE_DEBUG_STMTS)
-    return ret;
 
-  start = ptr;
-  for (ptr = start->next; ptr != start; ptr = ptr->next)
-    if (!is_gimple_debug (USE_STMT (ptr)))
-      {
-	if (ret)
-	  return false;
-	ret = true;
-      }
-  return ret;
+  /* If there are debug stmts, we have to look at each of them.  */
+  if (!MAY_HAVE_DEBUG_STMTS)
+    return false;
+
+  return single_imm_use_1 (ptr, NULL, NULL);
 }
 
 
-/* If VAR has only a single immediate use, return true, and set USE_P and STMT
-   to the use pointer and stmt of occurrence.  */
+/* If VAR has only a single immediate nondebug use, return true, and
+   set USE_P and STMT to the use pointer and stmt of occurrence.  */
 static inline bool
 single_imm_use (const_tree var, use_operand_p *use_p, gimple *stmt)
 {
-  const ssa_use_operand_t *ptr;
-  bool ret;
-
-  ptr = &(SSA_NAME_IMM_USE_NODE (var));
-
-  ret = ptr != ptr->next && ptr == ptr->next->next;
+  const ssa_use_operand_t *const ptr = &(SSA_NAME_IMM_USE_NODE (var));
 
-  if (ret)
-    ret = !is_gimple_debug (USE_STMT (ptr->next));
-  else if (MAY_HAVE_DEBUG_STMTS)
+  /* If there aren't any uses whatsoever, we're done.  */
+  if (ptr == ptr->next)
     {
-      const ssa_use_operand_t *start = ptr, *prev = ptr, *single_use_prev = 0;
-
-      for (ptr = start->next; ptr != start; prev = ptr, ptr = ptr->next)
-	if (!is_gimple_debug (USE_STMT (ptr)))
-	  {
-	    if (ret)
-	      {
-		ret = false;
-		break;
-	      }
-	    ret = true;
-	    single_use_prev = prev;
-	  }
-
-      ptr = single_use_prev;
+    return_false:
+      *use_p = NULL_USE_OPERAND_P;
+      *stmt = NULL;
+      return false;
     }
 
-  if (ret)
+  /* If there's a single use, check that it's not a debug stmt.  */
+  if (ptr == ptr->next->next)
     {
-      *use_p = ptr->next;
-      *stmt = ptr->next->loc.stmt;
-      return true;
+      if (!is_gimple_debug (USE_STMT (ptr->next)))
+	{
+	  *use_p = ptr->next;
+	  *stmt = ptr->next->loc.stmt;
+	  return true;
+	}
+      else
+	goto return_false;
     }
-  *use_p = NULL_USE_OPERAND_P;
-  *stmt = NULL;
-  return false;
+
+  /* If there are debug stmts, we have to look at each of them.  */
+  if (!MAY_HAVE_DEBUG_STMTS)
+    goto return_false;
+
+  return single_imm_use_1 (ptr, use_p, stmt);
 }
 
-/* Return the number of immediate uses of VAR.  */
+/* Return the number of nondebug immediate uses of VAR.  */
 static inline unsigned int
 num_imm_uses (const_tree var)
 {
Index: gcc/tree-ssa-loop-ivopts.c
===================================================================
--- gcc/tree-ssa-loop-ivopts.c.orig	2009-08-31 21:28:51.000000000 -0300
+++ gcc/tree-ssa-loop-ivopts.c	2009-08-31 21:28:58.000000000 -0300
@@ -1850,7 +1850,7 @@ find_interesting_uses (struct ivopts_dat
 	find_interesting_uses_stmt (data, gsi_stmt (bsi));
       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
 	if (!is_gimple_debug (gsi_stmt (bsi)))
-	find_interesting_uses_stmt (data, gsi_stmt (bsi));
+	  find_interesting_uses_stmt (data, gsi_stmt (bsi));
     }
 
   if (dump_file && (dump_flags & TDF_DETAILS))
Index: gcc/tree-ssa.c
===================================================================
--- gcc/tree-ssa.c.orig	2009-08-31 21:28:49.000000000 -0300
+++ gcc/tree-ssa.c	2009-08-31 21:28:58.000000000 -0300
@@ -262,12 +262,6 @@ target_for_debug_bind (tree var)
   if (DECL_HAS_VALUE_EXPR_P (var))
     return target_for_debug_bind (DECL_VALUE_EXPR (var));
 
-#if 0
-  /* Should we deal with DECL_DEBUG_EXPR_IS_FROM as well?  */
-  if (DECL_DEBUG_EXPR_IS_FROM (var))
-    return target_for_debug_bind (DECL_DEBUG_EXPR (var));
-#endif
-
   if (DECL_IGNORED_P (var))
     return NULL_TREE;
 
@@ -439,7 +433,7 @@ propagate_defs_into_debug_stmts (gimple 
   if (!MAY_HAVE_DEBUG_STMTS)
     return;
 
-  FOR_EACH_SSA_DEF_OPERAND (def_p, def, op_iter, SSA_OP_ALL_DEFS)
+  FOR_EACH_SSA_DEF_OPERAND (def_p, def, op_iter, SSA_OP_DEF)
     {
       tree var = DEF_FROM_PTR (def_p);
 
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi.orig	2009-08-31 21:28:50.000000000 -0300
+++ gcc/doc/invoke.texi	2009-08-31 21:28:58.000000000 -0300
@@ -4398,11 +4398,14 @@ assembler (GAS) to fail with an error.
 @opindex gdwarf-@var{version}
 Produce debugging information in DWARF format (if that is
 supported).  This is the format used by DBX on IRIX 6.  The value
-of @var{version} may be either 2 or 3; the default version is 2.
+of @var{version} may be either 2, 3 or 4; the default version is 2.
 
 Note that with DWARF version 2 some ports require, and will always
 use, some non-conflicting DWARF 3 extensions in the unwind tables.
 
+Version 4 may require GDB 7.0 and @option{-fvar-tracking-assignments}
+for maximum benefit.
+
 @item -gvms
 @opindex gvms
 Produce debugging information in VMS debug format (if that is
@@ -5456,7 +5459,7 @@ the debug info format supports it.
 Annotate assignments to user variables early in the compilation and
 attempt to carry the annotations over throughout the compilation all the
 way to the end, in an attempt to improve debug information while
-optimizing.
+optimizing.  Use of @option{-gdwarf-4} is recommended along with it.
 
 It can be enabled even if var-tracking is disabled, in which case
 annotations will be created and maintained, but discarded at the end.
Index: gcc/opts.c
===================================================================
--- gcc/opts.c.orig	2009-08-31 21:28:50.000000000 -0300
+++ gcc/opts.c	2009-08-31 21:28:58.000000000 -0300
@@ -2054,7 +2054,7 @@ common_handle_option (size_t scode, cons
       break;
 
     case OPT_gdwarf_:
-      if (value < 2 || value > 3)
+      if (value < 2 || value > 4)
 	error ("dwarf version %d is not supported", value);
       else
 	dwarf_version = value;
-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist      Red Hat Brazil Compiler Engineer

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