public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH]: Track uninitialized variables
@ 2007-05-02  0:03 Caroline Tice
  2007-05-08 16:25 ` Ping! " Caroline Tice
                   ` (2 more replies)
  0 siblings, 3 replies; 25+ messages in thread
From: Caroline Tice @ 2007-05-02  0:03 UTC (permalink / raw)
  To: gcc-patches@gcc.gnu.org Patches; +Cc: Caroline Tice

[-- Attachment #1: Type: text/plain, Size: 7469 bytes --]


As part of some work I've been doing on improving debugging of  
optimized code, I
have developed the following patch which, while tracking the locations  
of variables,
also keeps track of whether the variables are initialized or not (it  
makes conservative
assumptions where it can't be sure).  For those places where it is  
sure the variables
are unintialized, it adds an annotation to the var_location_note,  
which the dwarf
writer later translates to a new DW_OP (an extension) that indicates a  
variable is uninitialized
(DW_OP_GNU_uninit).

Since this work requires that GDB be able to read and do something  
reasonable with
the new DW_OP, I have also created a GDB patch to deal with the new  
op, and to
inform the user that a particular value is unintialized when the user  
asks to see it.
As the two patches really go together, I am attaching both of them to  
this message.
(I will also be sending the GDB patch to the gdb patches list).

Because using the new DW_OP is sensitive to whether or not the user  
has a version of GDB
that can handle it, I have added a macro, TARGET_DWARF_UNINIT_VARS,  
which defaults
to 0, and which controls whether the uninitialized variable tracking  
is done.

I have bootstrapped and run the dejagnu testsuite on this patch, with  
no regressions, on
a ppc running apple-darwin, an x86 running apple-darwin, and an x86 64  
running 64-bit linux.

Is this patch okay to commit to mainline?

-- Caroline Tice
ctice@apple.com

2007-05-01  Caroline Tice  <ctice@apple.com>

         * defaults.h (TARGET_DWARF_UNINIT_VARS): New macro, to control
         tracking uninitialized variables.
         * rtl.def (VAR_LOCATION): Add a new integer subfield to  
VAR_LOCATION
         note definitions, to allow recording of initialization status  
in the
         notes.
         * dwarf2out.c (dwarf_stack_op_name): Add case for  
DW_OP_GNU_uninit.
         (add_var_loc_to_decl): Add comparison of  
NOTE_VAR_LOCATION_STATUS to
         determine if two note locations are equal.
         (output_loc_list): Don't output list entries whose start &  
end labels
         are the same.
         (reg_loc_descriptor): Add parameter for initialization  
status; pass it
         to other loc descriptor functions.
         (one_reg_loc_descriptor): Add parameter for initialization  
status;
         check its value and add DW_OP_GNU_uninit to returned loc  
descr if
         appropriate.
         (multiple_reg_loc_descriptor): Add parameter for  
initialization status;
         pass init status argument to other loc descriptor functions;  
check
         value of intialization parameter and add DW_OP_GNU_uninit to  
returned
         loc descr if appropriate.
         (based_loc_descr): Add parameter for initialization status;  
add new
         variable for return value; check value of initialization  
parameter and
         add DW_OP_GNU_uninit to returned loc descr if appropriate.
         (concatn_mem_loc_descriptor): Add parameter for  
initialization status;
         pass init status argument to other loc descriptor functions;  
check
         value of intialization parameter and add DW_OP_GNU_uninit to  
returned
         loc descr if appropriate.
         (mem_loc_descriptor): Likewise.
         (concat_loc_descriptor): Likewise.
         (concatn_loc_descriptor): Likewise.
         (loc_descriptor): Add parameter for initialization status;  
pass it as
         argument to other loc descriptor function calls.
         (loc_descriptor_from_tree_1): Add appropriate initialization  
status
         to loc descriptor function calls.
         (add_location_or_const_value_attribute): Get initialization  
status
         from VAR_LOCATION note; add initialization status to loc  
descriptor
         function calls.
         * dwarf2.h (enum dwarf_location_atom): New op,  
DW_OP_GNU_uninit.
         * print-rtl.c (print_rtx): When printing a VAR_LOCATION note,  
if status
         is uninitialized, add "[uninint]" to output.
         * rtl.h (NOTE_VAR_LOCATION_STATUS): New macro for accessing  
new field.
         (enum var_init_status): New type, for var initialization  
status field.
         * var-tracking.c (struct location_chain_def): Two new fields,  
init,
         for initialization status, and set_src for the assignment  
value expr.
         (unshare_variable): New parameter for initialization status;  
initialize
         new init and set_src fields.
         (var_reg_set): New parameters for initialization status and  
value;
         pass them to set_variable_part.
         (var_mem_set): Likewise.
         (get_init_value): New function.
         (var_reg_delete_and_set): New initialization status & value  
parameters;
         add call to get_init_value if status is unknown; pass new  
parameters
         to clobber_variable_part and var_reg_set.
         (var_mem_delete_and_set): Likewise.
         (var_reg_delete): Pass null set_src value to  
clobber_variable_part.
         (var_mem_delete): Likewise.
         (variable_union): Pass status to unshare_variable; initialize  
new init
         and set_src fields.  If target doesn't have correct gdb  
(tested by
         macro TARGET_DWARF_UNINIT_VARS), force status to initialized.
         (add_stores): Store insn, rather than NEXT_INSN(insn), so it  
can be
         used later to get the set_src value.
         (find_src_status): New function.
         (find_src_set_src): New function.
         (compute_bb_dataflow): Pass init status to calls to  
var_reg_set,
         var_mem_set, var_reg_delete_and_set and  
var_mem_delete_and_set; for
         MO_SET, get set_src value and pass it to   
var_reg_delete_and_set
         and var_mem_delete_and_set.
         (dump_variable):  Print out "[uninit]" if appropriate.
         (set_variable_part): Add new initialization and set_src  
parameters;
         pass status to unshare_variable; set node->init and node- 
 >set_src
         fields and modify slot in hash table appropriately; save the  
init and
         set_src values if appropriate and assign to the new node.
         (clobber_variable_part): New set_src parameter; if two nodes  
have
         same variable and same location but different set_src  
(assignment)
         values, clobber old node.
         (delete_variable_part): Pass init status to unshare_variable.
         (emit_note_insn_var_location): Add initialized var; assign  
var's init
         status to new 'initialized'; pass new init status field to  
calls to
         gen_rtx_VAR_LOCATION.  If target doesn't have correct gdb  
(tested by
         macro TARGET_DWARF_UNINIT_VARS), force status to initialized.
         (emit_notes_in_bb): Pass initialization status to calls to  
var_reg_set,
         var_mem_set, var_reg_delete_and_set and  
var_mem_delete_and_set; for
         MO_SET, get set_src value and pass it to  
var_reg_delete_and_set and
         var_mem_delete_and_set; call emit_notes_for_changes on  
NEXT_INSN(insn)
         rather than on insn, to make up for change in add_stores.
         (vt_add_function_parameters): Add status to calls to  
set_variable_part.
         * config/i386/linux.h (TARGET_DWARF_UNINIT_VARS): New macro  
definition
         to control tracking uninitialized variables.  Redefined from  
defaults.h
         * config/darwin.h (TARGET_DWARF_UNINIT_VARS): New macro  
definition to
         control tracking uninitialized variables.  Redefined from  
defaults.h.




[-- Attachment #2: fsf-gcc-patch.txt --]
[-- Type: text/plain, Size: 43215 bytes --]

Index: gcc/defaults.h
===================================================================
--- gcc/defaults.h	(revision 124192)
+++ gcc/defaults.h	(working copy)
@@ -796,6 +796,12 @@
 #define TARGET_C99_FUNCTIONS 0
 #endif
 
+/* Determine whether gcc should output DWARF information about
+   uninitialized variables or not.  */
+#ifndef TARGET_DWARF_UNINIT_VARS
+#define TARGET_DWARF_UNINIT_VARS 0
+#endif
+
 /* Determine whether the target runtime library has
    a sincos implementation following the GNU extension.  */
 #ifndef TARGET_HAS_SINCOS
Index: gcc/rtl.def
===================================================================
--- gcc/rtl.def	(revision 124192)
+++ gcc/rtl.def	(working copy)
@@ -670,7 +670,7 @@
 DEF_RTL_EXPR(US_TRUNCATE, "us_truncate", "e", RTX_UNARY)
 
 /* Information about the variable and its location.  */
-DEF_RTL_EXPR(VAR_LOCATION, "var_location", "te", RTX_EXTRA)
+DEF_RTL_EXPR(VAR_LOCATION, "var_location", "tei", RTX_EXTRA)
 
 /* All expressions from this point forward appear only in machine
    descriptions.  */
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 124192)
+++ gcc/dwarf2out.c	(working copy)
@@ -3116,6 +3116,8 @@
       return "DW_OP_call_ref";
     case DW_OP_GNU_push_tls_address:
       return "DW_OP_GNU_push_tls_address";
+    case DW_OP_GNU_uninit:
+      return "DW_OP_GNU_uninit";
     default:
       return "OP_<unknown>";
     }
@@ -4163,15 +4165,20 @@
 static int type_is_enum (tree);
 static unsigned int dbx_reg_number (rtx);
 static void add_loc_descr_op_piece (dw_loc_descr_ref *, int);
-static dw_loc_descr_ref reg_loc_descriptor (rtx);
-static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int);
-static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx);
+static dw_loc_descr_ref reg_loc_descriptor (rtx, enum var_init_status);
+static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int, 
+						enum var_init_status);
+static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx,
+						     enum var_init_status);
 static dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT);
-static dw_loc_descr_ref based_loc_descr (rtx, HOST_WIDE_INT);
+static dw_loc_descr_ref based_loc_descr (rtx, HOST_WIDE_INT,
+					 enum var_init_status);
 static int is_based_loc (rtx);
-static dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode);
-static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx);
-static dw_loc_descr_ref loc_descriptor (rtx);
+static dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode,
+					    enum var_init_status);
+static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx,
+					       enum var_init_status);
+static dw_loc_descr_ref loc_descriptor (rtx, enum var_init_status);
 static dw_loc_descr_ref loc_descriptor_from_tree_1 (tree, int);
 static dw_loc_descr_ref loc_descriptor_from_tree (tree);
 static HOST_WIDE_INT ceiling (HOST_WIDE_INT, unsigned int);
@@ -5727,9 +5734,16 @@
   if (temp->last)
     {
       /* If the current location is the same as the end of the list,
+	 and either both or neither of the locations is uninitialized,
 	 we have nothing to do.  */
-      if (!rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->last->var_loc_note),
-			NOTE_VAR_LOCATION_LOC (loc->var_loc_note)))
+      if ((!rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->last->var_loc_note),
+			 NOTE_VAR_LOCATION_LOC (loc->var_loc_note)))
+	  || ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note)
+	       != NOTE_VAR_LOCATION_STATUS (loc->var_loc_note))
+	      && ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note)
+		   == STATUS_UNINITIALIZED)
+		  || (NOTE_VAR_LOCATION_STATUS (loc->var_loc_note)
+		      == STATUS_UNINITIALIZED))))
 	{
 	  /* Add LOC to the end of list and update LAST.  */
 	  temp->last->next = loc;
@@ -7039,6 +7053,9 @@
   for (curr = list_head; curr != NULL; curr = curr->dw_loc_next)
     {
       unsigned long size;
+      /* Don't output an entry that starts and ends at the same address.  */
+      if (strcmp (curr->begin, curr->end) == 0)
+	continue;
       if (!have_multiple_function_sections)
 	{
 	  dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->begin, curr->section,
@@ -8648,7 +8665,7 @@
    zero if there is none.  */
 
 static dw_loc_descr_ref
-reg_loc_descriptor (rtx rtl)
+reg_loc_descriptor (rtx rtl, enum var_init_status initialized)
 {
   rtx regs;
 
@@ -8658,28 +8675,35 @@
   regs = targetm.dwarf_register_span (rtl);
 
   if (hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)] > 1 || regs)
-    return multiple_reg_loc_descriptor (rtl, regs);
+    return multiple_reg_loc_descriptor (rtl, regs, initialized);
   else
-    return one_reg_loc_descriptor (dbx_reg_number (rtl));
+    return one_reg_loc_descriptor (dbx_reg_number (rtl), initialized);
 }
 
 /* Return a location descriptor that designates a machine register for
    a given hard register number.  */
 
 static dw_loc_descr_ref
-one_reg_loc_descriptor (unsigned int regno)
+one_reg_loc_descriptor (unsigned int regno, enum var_init_status initialized)
 {
+  dw_loc_descr_ref reg_loc_descr;
   if (regno <= 31)
-    return new_loc_descr (DW_OP_reg0 + regno, 0, 0);
+    reg_loc_descr = new_loc_descr (DW_OP_reg0 + regno, 0, 0);
   else
-    return new_loc_descr (DW_OP_regx, regno, 0);
+    reg_loc_descr =  new_loc_descr (DW_OP_regx, regno, 0);
+
+  if (initialized == STATUS_UNINITIALIZED)
+    add_loc_descr (&reg_loc_descr, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+
+  return reg_loc_descr;
 }
 
 /* Given an RTL of a register, return a location descriptor that
    designates a value that spans more than one register.  */
 
 static dw_loc_descr_ref
-multiple_reg_loc_descriptor (rtx rtl, rtx regs)
+multiple_reg_loc_descriptor (rtx rtl, rtx regs, 
+			     enum var_init_status initialized)
 {
   int nregs, size, i;
   unsigned reg;
@@ -8707,7 +8731,8 @@
 	{
 	  dw_loc_descr_ref t;
 
-	  t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg));
+	  t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg),
+				      STATUS_UNINITIALIZED);
 	  add_loc_descr (&loc_result, t);
 	  add_loc_descr_op_piece (&loc_result, size);
 	  ++reg;
@@ -8726,11 +8751,15 @@
     {
       dw_loc_descr_ref t;
 
-      t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)));
+      t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)),
+				  STATUS_INITIALIZED);
       add_loc_descr (&loc_result, t);
       size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
       add_loc_descr_op_piece (&loc_result, size);
     }
+
+  if (loc_result && initialized == STATUS_UNINITIALIZED)
+    add_loc_descr (&loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
   return loc_result;
 }
 
@@ -8776,9 +8805,11 @@
 /* Return a location descriptor that designates a base+offset location.  */
 
 static dw_loc_descr_ref
-based_loc_descr (rtx reg, HOST_WIDE_INT offset)
+based_loc_descr (rtx reg, HOST_WIDE_INT offset,
+		 enum var_init_status initialized)
 {
   unsigned int regno;
+  dw_loc_descr_ref result;
 
   /* We only use "frame base" when we're sure we're talking about the
      post-prologue local stack frame.  We do this by *not* running
@@ -8805,9 +8836,14 @@
 
   regno = dbx_reg_number (reg);
   if (regno <= 31)
-    return new_loc_descr (DW_OP_breg0 + regno, offset, 0);
+    result = new_loc_descr (DW_OP_breg0 + regno, offset, 0);
   else
-    return new_loc_descr (DW_OP_bregx, regno, offset);
+    result = new_loc_descr (DW_OP_bregx, regno, offset);
+
+  if (initialized == STATUS_UNINITIALIZED)
+    add_loc_descr (&result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+
+  return result;
 }
 
 /* Return true if this RTL expression describes a base+offset calculation.  */
@@ -8825,7 +8861,8 @@
    used to form the address of a memory location.  */
 
 static dw_loc_descr_ref
-concatn_mem_loc_descriptor (rtx concatn, enum machine_mode mode)
+concatn_mem_loc_descriptor (rtx concatn, enum machine_mode mode,
+			    enum var_init_status initialized)
 {
   unsigned int i;
   dw_loc_descr_ref cc_loc_result = NULL;
@@ -8836,7 +8873,7 @@
       dw_loc_descr_ref ref;
       rtx x = XVECEXP (concatn, 0, i);
 
-      ref = mem_loc_descriptor (x, mode);
+      ref = mem_loc_descriptor (x, mode, STATUS_INITIALIZED);
       if (ref == NULL)
 	return NULL;
 
@@ -8844,6 +8881,9 @@
       add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x)));
     }
 
+  if (cc_loc_result && initialized == STATUS_UNINITIALIZED)
+    add_loc_descr (&cc_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+
   return cc_loc_result;
 }
 
@@ -8866,7 +8906,8 @@
    Return 0 if we can't represent the location.  */
 
 static dw_loc_descr_ref
-mem_loc_descriptor (rtx rtl, enum machine_mode mode)
+mem_loc_descriptor (rtx rtl, enum machine_mode mode,
+		    enum var_init_status initialized)
 {
   dw_loc_descr_ref mem_loc_result = NULL;
   enum dwarf_location_atom op;
@@ -8913,11 +8954,12 @@
 	 memory) so DWARF consumers need to be aware of the subtle
 	 distinction between OP_REG and OP_BASEREG.  */
       if (REGNO (rtl) < FIRST_PSEUDO_REGISTER)
-	mem_loc_result = based_loc_descr (rtl, 0);
+	mem_loc_result = based_loc_descr (rtl, 0, STATUS_INITIALIZED);
       break;
 
     case MEM:
-      mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl));
+      mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl),
+					   STATUS_INITIALIZED);
       if (mem_loc_result != 0)
 	add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
       break;
@@ -8984,10 +9026,12 @@
     plus:
       if (is_based_loc (rtl))
 	mem_loc_result = based_loc_descr (XEXP (rtl, 0),
-					  INTVAL (XEXP (rtl, 1)));
+					  INTVAL (XEXP (rtl, 1)),
+					  STATUS_INITIALIZED);
       else
 	{
-	  mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode);
+	  mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode,
+					       STATUS_INITIALIZED);
 	  if (mem_loc_result == 0)
 	    break;
 
@@ -8999,7 +9043,8 @@
 	  else
 	    {
 	      add_loc_descr (&mem_loc_result,
-			     mem_loc_descriptor (XEXP (rtl, 1), mode));
+			     mem_loc_descriptor (XEXP (rtl, 1), mode,
+						 STATUS_INITIALIZED));
 	      add_loc_descr (&mem_loc_result,
 			     new_loc_descr (DW_OP_plus, 0, 0));
 	    }
@@ -9026,8 +9071,10 @@
 
     do_binop:
       {
-	dw_loc_descr_ref op0 = mem_loc_descriptor (XEXP (rtl, 0), mode);
-	dw_loc_descr_ref op1 = mem_loc_descriptor (XEXP (rtl, 1), mode);
+	dw_loc_descr_ref op0 = mem_loc_descriptor (XEXP (rtl, 0), mode,
+						   STATUS_INITIALIZED);
+	dw_loc_descr_ref op1 = mem_loc_descriptor (XEXP (rtl, 1), mode,
+						   STATUS_INITIALIZED);
 
 	if (op0 == 0 || op1 == 0)
 	  break;
@@ -9043,13 +9090,17 @@
       break;
 
     case CONCATN:
-      mem_loc_result = concatn_mem_loc_descriptor (rtl, mode);
+      mem_loc_result = concatn_mem_loc_descriptor (rtl, mode, 
+						   STATUS_INITIALIZED);
       break;
 
     default:
       gcc_unreachable ();
     }
 
+  if (mem_loc_result && initialized == STATUS_UNINITIALIZED)
+    add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+
   return mem_loc_result;
 }
 
@@ -9057,11 +9108,11 @@
    This is typically a complex variable.  */
 
 static dw_loc_descr_ref
-concat_loc_descriptor (rtx x0, rtx x1)
+concat_loc_descriptor (rtx x0, rtx x1, enum var_init_status initialized)
 {
   dw_loc_descr_ref cc_loc_result = NULL;
-  dw_loc_descr_ref x0_ref = loc_descriptor (x0);
-  dw_loc_descr_ref x1_ref = loc_descriptor (x1);
+  dw_loc_descr_ref x0_ref = loc_descriptor (x0, STATUS_INITIALIZED);
+  dw_loc_descr_ref x1_ref = loc_descriptor (x1, STATUS_INITIALIZED);
 
   if (x0_ref == 0 || x1_ref == 0)
     return 0;
@@ -9072,6 +9123,9 @@
   add_loc_descr (&cc_loc_result, x1_ref);
   add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x1)));
 
+  if (initialized == STATUS_UNINITIALIZED)
+    add_loc_descr (&cc_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+
   return cc_loc_result;
 }
 
@@ -9079,7 +9133,7 @@
    locations.  */
 
 static dw_loc_descr_ref
-concatn_loc_descriptor (rtx concatn)
+concatn_loc_descriptor (rtx concatn, enum var_init_status initialized)
 {
   unsigned int i;
   dw_loc_descr_ref cc_loc_result = NULL;
@@ -9090,7 +9144,7 @@
       dw_loc_descr_ref ref;
       rtx x = XVECEXP (concatn, 0, i);
 
-      ref = loc_descriptor (x);
+      ref = loc_descriptor (x, STATUS_INITIALIZED);
       if (ref == NULL)
 	return NULL;
 
@@ -9098,6 +9152,9 @@
       add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x)));
     }
 
+  if (cc_loc_result && initialized == STATUS_UNINITIALIZED)
+    add_loc_descr (&cc_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+
   return cc_loc_result;
 }
 
@@ -9110,7 +9167,7 @@
    If we don't know how to describe it, return 0.  */
 
 static dw_loc_descr_ref
-loc_descriptor (rtx rtl)
+loc_descriptor (rtx rtl, enum var_init_status initialized)
 {
   dw_loc_descr_ref loc_result = NULL;
 
@@ -9127,26 +9184,28 @@
       /* ... fall through ...  */
 
     case REG:
-      loc_result = reg_loc_descriptor (rtl);
+      loc_result = reg_loc_descriptor (rtl, initialized);
       break;
 
     case MEM:
-      loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl));
+      loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl),
+				       initialized);
       break;
 
     case CONCAT:
-      loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1));
+      loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1),
+					  initialized);
       break;
 
     case CONCATN:
-      loc_result = concatn_loc_descriptor (rtl);
+      loc_result = concatn_loc_descriptor (rtl, initialized);
       break;
 
     case VAR_LOCATION:
       /* Single part.  */
       if (GET_CODE (XEXP (rtl, 1)) != PARALLEL)
 	{
-	  loc_result = loc_descriptor (XEXP (XEXP (rtl, 1), 0));
+	  loc_result = loc_descriptor (XEXP (XEXP (rtl, 1), 0), initialized);
 	  break;
 	}
 
@@ -9161,14 +9220,16 @@
 	int i;
 
 	/* Create the first one, so we have something to add to.  */
-	loc_result = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0));
+	loc_result = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0),
+				     initialized);
 	mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
 	add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
 	for (i = 1; i < num_elem; i++)
 	  {
 	    dw_loc_descr_ref temp;
 
-	    temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0));
+	    temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0),
+				   initialized);
 	    add_loc_descr (&loc_result, temp);
 	    mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
 	    add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
@@ -9300,7 +9361,7 @@
 
 	    /* Certain constructs can only be represented at top-level.  */
 	    if (want_address == 2)
-	      return loc_descriptor (rtl);
+	      return loc_descriptor (rtl, STATUS_INITIALIZED);
 
 	    mode = GET_MODE (rtl);
 	    if (MEM_P (rtl))
@@ -9308,7 +9369,7 @@
 		rtl = XEXP (rtl, 0);
 		have_address = 1;
 	      }
-	    ret = mem_loc_descriptor (rtl, mode);
+	    ret = mem_loc_descriptor (rtl, mode, STATUS_INITIALIZED);
 	  }
       }
       break;
@@ -9389,7 +9450,7 @@
 	  return 0;
 	mode = GET_MODE (rtl);
 	rtl = XEXP (rtl, 0);
-	ret = mem_loc_descriptor (rtl, mode);
+	ret = mem_loc_descriptor (rtl, mode, STATUS_INITIALIZED);
 	have_address = 1;
 	break;
       }
@@ -10475,6 +10536,7 @@
       const char *endname, *secname;
       dw_loc_list_ref list;
       rtx varloc;
+      enum var_init_status initialized;
 
       /* Now that we know what section we are using for a base,
 	 actually construct the list of locations.
@@ -10491,7 +10553,12 @@
       varloc = NOTE_VAR_LOCATION (node->var_loc_note);
       secname = secname_for_decl (decl);
 
-      list = new_loc_list (loc_descriptor (varloc),
+      if (NOTE_VAR_LOCATION_LOC (node->var_loc_note))
+	initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
+      else
+	initialized = STATUS_INITIALIZED;
+
+      list = new_loc_list (loc_descriptor (varloc, initialized),
 			   node->label, node->next->label, secname, 1);
       node = node->next;
 
@@ -10500,8 +10567,11 @@
 	  {
 	    /* The variable has a location between NODE->LABEL and
 	       NODE->NEXT->LABEL.  */
+	    enum var_init_status initialized =
+	      NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
 	    varloc = NOTE_VAR_LOCATION (node->var_loc_note);
-	    add_loc_descr_to_loc_list (&list, loc_descriptor (varloc),
+	    add_loc_descr_to_loc_list (&list, 
+				       loc_descriptor (varloc, initialized),
 				       node->label, node->next->label, secname);
 	  }
 
@@ -10510,6 +10580,8 @@
       if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX)
 	{
 	  char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
+	  enum var_init_status initialized =
+	    NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
 
 	  varloc = NOTE_VAR_LOCATION (node->var_loc_note);
 	  if (!current_function_decl)
@@ -10520,7 +10592,8 @@
 					   current_function_funcdef_no);
 	      endname = ggc_strdup (label_id);
 	    }
-	  add_loc_descr_to_loc_list (&list, loc_descriptor (varloc),
+	  add_loc_descr_to_loc_list (&list, 
+				     loc_descriptor (varloc, initialized),
 				     node->label, endname, secname);
 	}
 
@@ -10544,8 +10617,10 @@
      location list, try generating a location from that.  */
   if (loc_list && loc_list->first)
     {
+      enum var_init_status status;
       node = loc_list->first;
-      descr = loc_descriptor (NOTE_VAR_LOCATION (node->var_loc_note));
+      status = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
+      descr = loc_descriptor (NOTE_VAR_LOCATION (node->var_loc_note), status);
       if (descr)
 	{
 	  add_AT_location_description (die, attr, descr);
Index: gcc/dwarf2.h
===================================================================
--- gcc/dwarf2.h	(revision 124192)
+++ gcc/dwarf2.h	(working copy)
@@ -540,6 +540,7 @@
     DW_OP_bit_piece = 0x9d,
     /* GNU extensions.  */
     DW_OP_GNU_push_tls_address = 0xe0,
+    DW_OP_GNU_uninit     = 0xf0,
     /* HP extensions.  */
     DW_OP_HP_unknown     = 0xe0, /* Ouch, the same as GNU_push_tls_address.  */
     DW_OP_HP_is_value    = 0xe1,
Index: gcc/print-rtl.c
===================================================================
--- gcc/print-rtl.c	(revision 124192)
+++ gcc/print-rtl.c	(working copy)
@@ -325,6 +325,8 @@
 		print_mem_expr (outfile, NOTE_VAR_LOCATION_DECL (in_rtx));
 		fprintf (outfile, " ");
 		print_rtx (NOTE_VAR_LOCATION_LOC (in_rtx));
+		if (NOTE_VAR_LOCATION_STATUS (in_rtx) == STATUS_UNINITIALIZED)
+		  fprintf (outfile, " [uninit]");
 		fprintf (outfile, ")");
 #endif
 		break;
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h	(revision 124192)
+++ gcc/rtl.h	(working copy)
@@ -868,6 +868,16 @@
 #define NOTE_VAR_LOCATION_LOC(INSN)	(XCEXP (XCEXP (INSN, 4, NOTE),  \
 						1, VAR_LOCATION))
 
+#define NOTE_VAR_LOCATION_STATUS(INSN)  (XCINT (XCEXP (INSN, 4, NOTE), \
+						2, VAR_LOCATION))
+
+enum var_init_status
+{
+  STATUS_UNKNOWN,
+  STATUS_UNINITIALIZED,
+  STATUS_INITIALIZED
+};
+
 /* Codes that appear in the NOTE_LINE_NUMBER field for kinds of notes
    that are not line numbers.  These codes are all negative.
    
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c	(revision 124192)
+++ gcc/var-tracking.c	(working copy)
@@ -219,6 +219,12 @@
 
   /* The location (REG or MEM).  */
   rtx loc;
+
+  /* The "value" stored in this location.  */
+  rtx set_src;
+
+  /* Initialized? */
+  enum var_init_status init;
 } *location_chain;
 
 /* Structure describing one part of variable.  */
@@ -294,16 +300,19 @@
 static void attrs_list_union (attrs *, attrs);
 
 static void vars_clear (htab_t);
-static variable unshare_variable (dataflow_set *set, variable var);
+static variable unshare_variable (dataflow_set *set, variable var, 
+				  enum var_init_status);
 static int vars_copy_1 (void **, void *);
 static void vars_copy (htab_t, htab_t);
 static tree var_debug_decl (tree);
-static void var_reg_set (dataflow_set *, rtx);
-static void var_reg_delete_and_set (dataflow_set *, rtx, bool);
+static void var_reg_set (dataflow_set *, rtx, enum var_init_status, rtx);
+static void var_reg_delete_and_set (dataflow_set *, rtx, bool, 
+				    enum var_init_status, rtx);
 static void var_reg_delete (dataflow_set *, rtx, bool);
 static void var_regno_delete (dataflow_set *, int);
-static void var_mem_set (dataflow_set *, rtx);
-static void var_mem_delete_and_set (dataflow_set *, rtx, bool);
+static void var_mem_set (dataflow_set *, rtx, enum var_init_status, rtx);
+static void var_mem_delete_and_set (dataflow_set *, rtx, bool, 
+				    enum var_init_status, rtx);
 static void var_mem_delete (dataflow_set *, rtx, bool);
 
 static void dataflow_set_init (dataflow_set *, int);
@@ -338,8 +347,10 @@
 static void dump_dataflow_sets (void);
 
 static void variable_was_changed (variable, htab_t);
-static void set_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
-static void clobber_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
+static void set_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT, 
+			       enum var_init_status, rtx);
+static void clobber_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT, 
+				   rtx);
 static void delete_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
 static int emit_note_insn_var_location (void **, void *);
 static void emit_notes_for_changes (rtx, enum emit_note_where);
@@ -727,7 +738,8 @@
 /* Return a copy of a variable VAR and insert it to dataflow set SET.  */
 
 static variable
-unshare_variable (dataflow_set *set, variable var)
+unshare_variable (dataflow_set *set, variable var, 
+		  enum var_init_status initialized)
 {
   void **slot;
   variable new_var;
@@ -752,6 +764,14 @@
 
 	  new_lc = pool_alloc (loc_chain_pool);
 	  new_lc->next = NULL;
+	  if (node->init > initialized)
+	    new_lc->init = node->init;
+	  else
+	    new_lc->init = initialized;
+	  if (node->set_src && !(MEM_P (node->set_src)))
+	    new_lc->set_src = node->set_src;
+	  else
+	    new_lc->set_src = NULL;
 	  new_lc->loc = node->loc;
 
 	  *nextp = new_lc;
@@ -819,7 +839,8 @@
 /* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  */
 
 static void
-var_reg_set (dataflow_set *set, rtx loc)
+var_reg_set (dataflow_set *set, rtx loc, enum var_init_status initialized, 
+	     rtx set_src)
 {
   tree decl = REG_EXPR (loc);
   HOST_WIDE_INT offset = REG_OFFSET (loc);
@@ -832,9 +853,44 @@
       break;
   if (!node)
     attrs_list_insert (&set->regs[REGNO (loc)], decl, offset, loc);
-  set_variable_part (set, loc, decl, offset);
+  set_variable_part (set, loc, decl, offset, initialized, set_src);
 }
 
+
+/* Lookup the variable described by DECL in SET, and return its initialization
+   status for location LOC.  */
+
+static int
+get_init_value (dataflow_set *set, rtx loc, tree decl)
+{
+  void **slot;
+  variable var;
+  int i;
+  int ret_val = STATUS_UNKNOWN;
+
+  if (! TARGET_DWARF_UNINIT_VARS)
+    return STATUS_INITIALIZED;
+
+  slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl),
+				   NO_INSERT);
+  if (slot)
+    {
+      var = * (variable *) slot;
+      for (i = 0; i < var->n_var_parts && ret_val == STATUS_UNKNOWN; i++)
+	{
+	  location_chain nextp;
+	  for (nextp = var->var_part[i].loc_chain; nextp; nextp = nextp->next)
+	    if (rtx_equal_p (nextp->loc, loc))
+	      {
+		ret_val = nextp->init;
+		break;
+	      }
+	}
+    }
+
+  return ret_val;
+}
+
 /* Delete current content of register LOC in dataflow set SET and set
    the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  If
    MODIFY is true, any other live copies of the same variable part are
@@ -843,7 +899,8 @@
    part.  */
 
 static void
-var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify)
+var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify, 
+			enum var_init_status initialized, rtx set_src)
 {
   tree decl = REG_EXPR (loc);
   HOST_WIDE_INT offset = REG_OFFSET (loc);
@@ -852,6 +909,9 @@
 
   decl = var_debug_decl (decl);
 
+  if (initialized == STATUS_UNKNOWN)
+    initialized = get_init_value (set, loc, decl);
+
   nextp = &set->regs[REGNO (loc)];
   for (node = *nextp; node; node = next)
     {
@@ -869,8 +929,8 @@
 	}
     }
   if (modify)
-    clobber_variable_part (set, loc, decl, offset);
-  var_reg_set (set, loc);
+    clobber_variable_part (set, loc, decl, offset, set_src);
+  var_reg_set (set, loc, initialized, set_src);
 }
 
 /* Delete current content of register LOC in dataflow set SET.  If
@@ -890,7 +950,7 @@
 
       decl = var_debug_decl (decl);
 
-      clobber_variable_part (set, NULL, decl, offset);
+      clobber_variable_part (set, NULL, decl, offset, NULL);
     }
 
   for (node = *reg; node; node = next)
@@ -924,14 +984,15 @@
    Adjust the address first if it is stack pointer based.  */
 
 static void
-var_mem_set (dataflow_set *set, rtx loc)
+var_mem_set (dataflow_set *set, rtx loc, enum var_init_status initialized, 
+	     rtx set_src)
 {
   tree decl = MEM_EXPR (loc);
   HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
 
   decl = var_debug_decl (decl);
 
-  set_variable_part (set, loc, decl, offset);
+  set_variable_part (set, loc, decl, offset, initialized, set_src);
 }
 
 /* Delete and set the location part of variable MEM_EXPR (LOC) in
@@ -942,16 +1003,20 @@
    Adjust the address first if it is stack pointer based.  */
 
 static void
-var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify)
+var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify, 
+			enum var_init_status initialized, rtx set_src)
 {
   tree decl = MEM_EXPR (loc);
   HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
 
   decl = var_debug_decl (decl);
 
+  if (initialized == STATUS_UNKNOWN)
+    initialized = get_init_value (set, loc, decl);
+
   if (modify)
-    clobber_variable_part (set, NULL, decl, offset);
-  var_mem_set (set, loc);
+    clobber_variable_part (set, NULL, decl, offset, set_src);
+  var_mem_set (set, loc, initialized, set_src);
 }
 
 /* Delete the location part LOC from dataflow set SET.  If CLOBBER is
@@ -966,7 +1031,7 @@
 
   decl = var_debug_decl (decl);
   if (clobber)
-    clobber_variable_part (set, NULL, decl, offset);
+    clobber_variable_part (set, NULL, decl, offset, NULL);
   delete_variable_part (set, loc, decl, offset);
 }
 
@@ -1078,7 +1143,14 @@
 	    }
 	}
       if (k < src->n_var_parts)
-	unshare_variable (set, src);
+	{
+	  enum var_init_status status = STATUS_UNKNOWN;
+	  
+	  if (! TARGET_DWARF_UNINIT_VARS)
+	    status = STATUS_INITIALIZED;
+
+	  unshare_variable (set, src, status);
+	}
       else
 	*dstp = src;
 
@@ -1112,7 +1184,13 @@
   gcc_assert (k <= MAX_VAR_PARTS);
 
   if (dst->refcount > 1 && dst->n_var_parts != k)
-    dst = unshare_variable (set, dst);
+    {
+      enum var_init_status status = STATUS_UNKNOWN;
+      
+      if (! TARGET_DWARF_UNINIT_VARS)
+	status = STATUS_INITIALIZED;
+      dst = unshare_variable (set, dst, status);
+    }
 
   i = src->n_var_parts - 1;
   j = dst->n_var_parts - 1;
@@ -1145,10 +1223,12 @@
 			 && REG_P (node->loc)
 			 && REGNO (node2->loc) == REGNO (node->loc))
 			|| rtx_equal_p (node2->loc, node->loc)))
+		    if (node2->init < node->init)
+		      node2->init = node->init;
 		    break;
 		}
 	      if (node || node2)
-		dst = unshare_variable (set, dst);
+		dst = unshare_variable (set, dst, STATUS_UNKNOWN);
 	    }
 
 	  src_l = 0;
@@ -1194,6 +1274,11 @@
 		  /* Copy the location from SRC.  */
 		  new_node = pool_alloc (loc_chain_pool);
 		  new_node->loc = node->loc;
+		  new_node->init = node->init;
+		  if (!node->set_src || MEM_P (node->set_src))
+		    new_node->set_src = NULL;
+		  else
+		    new_node->set_src = node->set_src;
 		  vui[n].lc = new_node;
 		  vui[n].pos_src = ii;
 		  vui[n].pos_dst = src_l + dst_l;
@@ -1240,6 +1325,11 @@
 
 	      new_lc = pool_alloc (loc_chain_pool);
 	      new_lc->next = NULL;
+	      new_lc->init = node->init;
+	      if (!node->set_src || MEM_P (node->set_src))
+		new_lc->set_src = NULL;
+	      else
+		new_lc->set_src = node->set_src;
 	      new_lc->loc = node->loc;
 
 	      *nextp = new_lc;
@@ -1258,6 +1348,18 @@
 	dst->var_part[k].cur_loc = NULL;
     }
 
+  for (i = 0; i < src->n_var_parts && i < dst->n_var_parts; i++)
+    {
+      location_chain node, node2;
+      for (node = src->var_part[i].loc_chain; node; node = node->next)
+	for (node2 = dst->var_part[i].loc_chain; node2; node2 = node2->next)
+	  if (rtx_equal_p (node->loc, node2->loc))
+	    {
+	      if (node->init > node2->init)
+		node2->init = node->init;
+	    }
+    }
+
   /* Continue traversing the hash table.  */
   return 1;
 }
@@ -1679,7 +1781,7 @@
       else
 	mo->type = MO_SET;
       mo->u.loc = loc;
-      mo->insn = NEXT_INSN ((rtx) insn);
+      mo->insn = (rtx) insn;
     }
   else if (MEM_P (loc)
 	   && MEM_EXPR (loc)
@@ -1700,10 +1802,109 @@
       else
 	mo->type = MO_SET;
       mo->u.loc = loc;
-      mo->insn = NEXT_INSN ((rtx) insn);
+      mo->insn = (rtx) insn;
     }
 }
 
+/* Given a dataflow_set IN, a location LOC, and an instruction INSN that
+   supposedly assigns a value to loc, find the piece of the instruction
+   that is being assigned to LOC, check to see if it's a variable (decl),
+   and if so, look up and return its initialization status.*/
+
+static enum var_init_status
+find_src_status (dataflow_set *in, rtx loc, rtx insn)
+{
+  rtx src = NULL_RTX;
+  tree decl = NULL_TREE;
+  enum var_init_status status = STATUS_UNINITIALIZED;
+
+  if (! TARGET_DWARF_UNINIT_VARS)
+    status = STATUS_INITIALIZED;
+
+  if (GET_CODE (PATTERN (insn)) == SET)
+    src = SET_SRC (PATTERN (insn));
+  else if (GET_CODE (PATTERN (insn)) == PARALLEL
+	   || GET_CODE (PATTERN (insn)) == SEQUENCE)
+    {
+      int i;
+      for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
+	if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
+	    && SET_DEST (XVECEXP (PATTERN (insn), 0, i)) == loc)
+	  src = SET_SRC (XVECEXP (PATTERN (insn), 0, i));
+    }
+
+  if (REG_P (src))
+    decl = var_debug_decl (REG_EXPR (src));
+  else if (MEM_P (src))
+    decl = var_debug_decl (MEM_EXPR (src));
+
+  if (src && decl)
+    status = get_init_value (in, src, decl);
+
+  return status;
+}
+
+/* Given an assignment instruction (INSN) and an assignment destination
+   (LOC), find the piece of INSN that is being assigned to LOC.  If it
+   corresponds to a variable (decl), look up the variable in SET and
+   return *its* set_src. 
+
+   In other words, (using 'set_src' as short hand for 'the value assigned
+   to'), look up and return the set_src of the variable being assigned 
+   to LOC. */
+
+static rtx
+find_src_set_src (dataflow_set *set, rtx loc, rtx insn)
+{
+  tree decl = NULL_TREE;   /* The variable being copied around.          */
+  rtx src = NULL_RTX;      /* The location "decl" is being copied from.  */
+  rtx set_src = NULL_RTX;  /* The value for "decl" stored in "src".      */
+  void **slot;
+  variable var;
+  location_chain nextp;
+  int i;
+  bool found;
+
+  if (GET_CODE (PATTERN (insn)) == SET)
+    src = SET_SRC (PATTERN (insn));
+  else if (GET_CODE (PATTERN (insn)) == PARALLEL
+	   || GET_CODE (PATTERN (insn)) == SEQUENCE)
+    {
+      for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
+	if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
+	    && SET_DEST (XVECEXP (PATTERN (insn), 0, i)) == loc)
+	  src = SET_SRC (XVECEXP (PATTERN (insn), 0, i));
+    }
+
+  if (REG_P (src))
+    decl = var_debug_decl (REG_EXPR (src));
+  else if (MEM_P (src))
+    decl = var_debug_decl (MEM_EXPR (src));
+
+  if (src && decl)
+    {
+      slot = htab_find_slot_with_hash (set->vars, decl, 
+				       VARIABLE_HASH_VAL (decl), NO_INSERT);
+
+      if (slot)
+	{
+	  var = *(variable *) slot;
+	  found = false;
+	  for (i = 0; i < var->n_var_parts && !found; i++)
+	    for (nextp = var->var_part[i].loc_chain; nextp && !found; 
+		 nextp = nextp->next)
+	      if (rtx_equal_p (nextp->loc, src))
+		{
+		  set_src = nextp->set_src;
+		  found = true;
+		}
+	      
+	}
+    }
+
+  return set_src;
+}
+
 /* Compute the changes of variable locations in the basic block BB.  */
 
 static bool
@@ -1733,33 +1934,65 @@
 	  case MO_USE:
 	    {
 	      rtx loc = VTI (bb)->mos[i].u.loc;
+	      enum var_init_status status = STATUS_UNINITIALIZED;
 
+	      if (! TARGET_DWARF_UNINIT_VARS)
+		status = STATUS_INITIALIZED;
+
 	      if (GET_CODE (loc) == REG)
-		var_reg_set (out, loc);
+		var_reg_set (out, loc, status, NULL);
 	      else if (GET_CODE (loc) == MEM)
-		var_mem_set (out, loc);
+		var_mem_set (out, loc, status, NULL);
 	    }
 	    break;
 
 	  case MO_SET:
 	    {
 	      rtx loc = VTI (bb)->mos[i].u.loc;
+	      rtx set_src =  NULL;
+	      rtx insn = VTI (bb)->mos[i].insn;
 
+	      if (GET_CODE (PATTERN (insn)) == SET)
+		set_src = SET_SRC (PATTERN (insn));
+	      else if (GET_CODE (PATTERN (insn)) == PARALLEL
+		       || GET_CODE (PATTERN (insn)) == SEQUENCE)
+		{
+		  int j;
+		  for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
+		    if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
+			&& SET_DEST (XVECEXP (PATTERN (insn), 0, j)) == loc)
+		      set_src = SET_SRC (XVECEXP (PATTERN (insn), 0, j));
+		}
+
 	      if (REG_P (loc))
-		var_reg_delete_and_set (out, loc, true);
+		var_reg_delete_and_set (out, loc, true, STATUS_INITIALIZED,
+					set_src);
 	      else if (MEM_P (loc))
-		var_mem_delete_and_set (out, loc, true);
+		var_mem_delete_and_set (out, loc, true, STATUS_INITIALIZED,
+					set_src);
 	    }
 	    break;
 
 	  case MO_COPY:
 	    {
 	      rtx loc = VTI (bb)->mos[i].u.loc;
+	      enum var_init_status src_status;
+	      rtx set_src;
 
+	      if (! TARGET_DWARF_UNINIT_VARS)
+		src_status = STATUS_INITIALIZED;
+	      else
+		src_status = find_src_status (in, loc, VTI (bb)->mos[i].insn);
+
+	      if (src_status == STATUS_UNKNOWN)
+		src_status = find_src_status (out, loc, VTI (bb)->mos[i].insn);
+
+	      set_src = find_src_set_src (in, loc, VTI (bb)->mos[i].insn);
+
 	      if (REG_P (loc))
-		var_reg_delete_and_set (out, loc, false);
+		var_reg_delete_and_set (out, loc, false, src_status, set_src);
 	      else if (MEM_P (loc))
-		var_mem_delete_and_set (out, loc, false);
+		var_mem_delete_and_set (out, loc, false, src_status, set_src);
 	    }
 	    break;
 
@@ -1932,6 +2165,8 @@
       for (node = var->var_part[i].loc_chain; node; node = node->next)
 	{
 	  fprintf (dump_file, "      ");
+	  if (node->init == STATUS_UNINITIALIZED)
+	    fprintf (dump_file, "[uninit]");
 	  print_rtl_single (dump_file, node->loc);
 	}
     }
@@ -2077,7 +2312,8 @@
    part's location by LOC.  */
 
 static void
-set_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset)
+set_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset,
+		   enum var_init_status initialized, rtx set_src)
 {
   int pos;
   location_chain node, next;
@@ -2119,13 +2355,19 @@
 	    {
 	      /* LOC is in the beginning of the chain so we have nothing
 		 to do.  */
+	      if (node->init < initialized)
+		node->init = initialized;
+	      if (set_src != NULL)
+		node->set_src = set_src;
+
+	      *slot = var;
 	      return;
 	    }
 	  else
 	    {
 	      /* We have to make a copy of a shared variable.  */
 	      if (var->refcount > 1)
-		var = unshare_variable (set, var);
+		var = unshare_variable (set, var, initialized);
 	    }
 	}
       else
@@ -2134,7 +2376,7 @@
 
 	  /* We have to make a copy of the shared variable.  */
 	  if (var->refcount > 1)
-	    var = unshare_variable (set, var);
+	    var = unshare_variable (set, var, initialized);
 
 	  /* We track only variables whose size is <= MAX_VAR_PARTS bytes
 	     thus there are at most MAX_VAR_PARTS different offsets.  */
@@ -2161,6 +2403,12 @@
 	   && REGNO (node->loc) == REGNO (loc))
 	  || rtx_equal_p (node->loc, loc))
 	{
+	  /* Save these values, to assign to the new node, before
+	     deleting this one.  */
+	  if (node->init > initialized)
+	    initialized = node->init;
+	  if (node->set_src != NULL && set_src == NULL)
+	    set_src = node->set_src;
 	  pool_free (loc_chain_pool, node);
 	  *nextp = next;
 	  break;
@@ -2172,6 +2420,8 @@
   /* Add the location to the beginning.  */
   node = pool_alloc (loc_chain_pool);
   node->loc = loc;
+  node->init = initialized;
+  node->set_src = set_src;
   node->next = var->var_part[pos].loc_chain;
   var->var_part[pos].loc_chain = node;
 
@@ -2190,7 +2440,7 @@
 
 static void
 clobber_variable_part (dataflow_set *set, rtx loc, tree decl,
-		      HOST_WIDE_INT offset)
+		       HOST_WIDE_INT offset, rtx set_src)
 {
   void **slot;
 
@@ -2213,7 +2463,11 @@
 	  for (node = next; node; node = next)
 	    {
 	      next = node->next;
-	      if (node->loc != loc)
+	      if (node->loc != loc 
+		  && (!(TARGET_DWARF_UNINIT_VARS)
+		      || !set_src 
+		      || MEM_P (set_src)
+		      || !rtx_equal_p (set_src, node->set_src)))
 		{
 		  if (REG_P (node->loc))
 		    {
@@ -2278,7 +2532,10 @@
 		       && REGNO (node->loc) == REGNO (loc))
 		      || rtx_equal_p (node->loc, loc))
 		    {
-		      var = unshare_variable (set, var);
+		      enum var_init_status status = STATUS_UNKNOWN;
+		      if (! TARGET_DWARF_UNINIT_VARS)
+			status = STATUS_INITIALIZED;
+		      var = unshare_variable (set, var, status);
 		      break;
 		    }
 		}
@@ -2345,6 +2602,7 @@
   rtx note;
   int i, j, n_var_parts;
   bool complete;
+  enum var_init_status initialized = STATUS_UNINITIALIZED;
   HOST_WIDE_INT last_limit;
   tree type_size_unit;
   HOST_WIDE_INT offsets[MAX_VAR_PARTS];
@@ -2352,6 +2610,9 @@
 
   gcc_assert (var->decl);
 
+  if (! TARGET_DWARF_UNINIT_VARS)
+    initialized = STATUS_INITIALIZED;
+
   complete = true;
   last_limit = 0;
   n_var_parts = 0;
@@ -2369,6 +2630,7 @@
       offsets[n_var_parts] = var->var_part[i].offset;
       loc[n_var_parts] = var->var_part[i].loc_chain->loc;
       mode = GET_MODE (loc[n_var_parts]);
+      initialized = var->var_part[i].loc_chain->init;
       last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
 
       /* Attempt to merge adjacent registers or memory.  */
@@ -2448,10 +2710,13 @@
   else
     note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
 
+  if (!(TARGET_DWARF_UNINIT_VARS))
+    initialized = STATUS_INITIALIZED;
+
   if (!complete)
     {
       NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
-						       NULL_RTX);
+						       NULL_RTX, 0);
     }
   else if (n_var_parts == 1)
     {
@@ -2459,7 +2724,8 @@
 	= gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
 
       NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
-						       expr_list);
+						       expr_list, 
+						       (int) initialized);
     }
   else if (n_var_parts)
     {
@@ -2472,9 +2738,12 @@
       parallel = gen_rtx_PARALLEL (VOIDmode,
 				   gen_rtvec_v (n_var_parts, loc));
       NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
-						       parallel);
+						       parallel, 
+						       (int) initialized);
     }
 
+  NOTE_VAR_LOCATION_STATUS (note) = (int) initialized;
+
   htab_clear_slot (changed_variables, varp);
 
   /* When there are no location parts the variable has been already
@@ -2603,11 +2872,14 @@
 	  case MO_USE:
 	    {
 	      rtx loc = VTI (bb)->mos[i].u.loc;
-
+      
+	      enum var_init_status status = STATUS_UNINITIALIZED;
+	      if (! TARGET_DWARF_UNINIT_VARS)
+		status = STATUS_INITIALIZED;
 	      if (GET_CODE (loc) == REG)
-		var_reg_set (&set, loc);
+		var_reg_set (&set, loc, status, NULL);
 	      else
-		var_mem_set (&set, loc);
+		var_mem_set (&set, loc, status, NULL);
 
 	      emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
 	    }
@@ -2616,26 +2888,46 @@
 	  case MO_SET:
 	    {
 	      rtx loc = VTI (bb)->mos[i].u.loc;
+	      rtx set_src =  NULL;
 
+	      if (GET_CODE (PATTERN (insn)) == SET)
+		set_src = SET_SRC (PATTERN (insn));
+	      else if (GET_CODE (PATTERN (insn)) == PARALLEL
+		       || GET_CODE (PATTERN (insn)) == SEQUENCE)
+		{
+		  int j;
+		  for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
+		    if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
+			&& SET_DEST (XVECEXP (PATTERN (insn), 0, j)) == loc)
+		      set_src = SET_SRC (XVECEXP (PATTERN (insn), 0, j));
+		}
+
 	      if (REG_P (loc))
-		var_reg_delete_and_set (&set, loc, true);
+		var_reg_delete_and_set (&set, loc, true, STATUS_INITIALIZED, 
+					set_src);
 	      else
-		var_mem_delete_and_set (&set, loc, true);
+		var_mem_delete_and_set (&set, loc, true, STATUS_INITIALIZED, 
+					set_src);
 
-	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
+	      emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN);
 	    }
 	    break;
 
 	  case MO_COPY:
 	    {
 	      rtx loc = VTI (bb)->mos[i].u.loc;
+	      enum var_init_status src_status;
+	      rtx set_src;
 
+	      src_status = find_src_status (&set, loc, VTI (bb)->mos[i].insn);
+	      set_src = find_src_set_src (&set, loc, VTI (bb)->mos[i].insn);
+
 	      if (REG_P (loc))
-		var_reg_delete_and_set (&set, loc, false);
+		var_reg_delete_and_set (&set, loc, false, src_status, set_src);
 	      else
-		var_mem_delete_and_set (&set, loc, false);
+		var_mem_delete_and_set (&set, loc, false, src_status, set_src);
 
-	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
+	      emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN);
 	    }
 	    break;
 
@@ -2661,7 +2953,7 @@
 	      else
 		var_mem_delete (&set, loc, true);
 
-	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
+	      emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN);
 	    }
 	    break;
 
@@ -2777,10 +3069,12 @@
 	  gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
 	  attrs_list_insert (&out->regs[REGNO (incoming)],
 			     parm, offset, incoming);
-	  set_variable_part (out, incoming, parm, offset);
+	  set_variable_part (out, incoming, parm, offset, STATUS_INITIALIZED, 
+			     NULL);
 	}
       else if (MEM_P (incoming))
-	set_variable_part (out, incoming, parm, offset);
+	set_variable_part (out, incoming, parm, offset, STATUS_INITIALIZED, 
+			   NULL);
     }
 }
 
Index: gcc/config/i386/linux.h
===================================================================
--- gcc/config/i386/linux.h	(revision 124192)
+++ gcc/config/i386/linux.h	(working copy)
@@ -195,3 +195,6 @@
 /* i386 glibc provides __stack_chk_guard in %gs:0x14.  */
 #define TARGET_THREAD_SSP_OFFSET	0x14
 #endif
+
+#undef  TARGET_DWARF_UNINIT_VARS
+#define TARGET_DWARF_UNINIT_VARS   1
Index: gcc/config/darwin.h
===================================================================
--- gcc/config/darwin.h	(revision 124192)
+++ gcc/config/darwin.h	(working copy)
@@ -984,4 +984,8 @@
 
 #define TARGET_HAS_TARGETCM 1
 
+#undef  TARGET_DWARF_UNINIT_VARS
+#define TARGET_DWARF_UNINIT_VARS   \
+  (strverscmp (darwin_macosx_version_min, "10.5") >= 0)
+
 #endif /* CONFIG_DARWIN_H */

[-- Attachment #3: Type: text/plain, Size: 1435 bytes --]



GDB PATCH:

2007-05-01  Caroline Tice  <ctice@apple.com>

         * c-valprint.c (c_value_print):  If the var_status field of the
         value struct is 0, print out "[uninitialized]" before the  
value.
         * dwarf2expr.c (add_piece): Make function non-static.
         (unsigned_address_type): Likewise.
         (signed_address_type): Likewise.
         (execute_stack_op): Initialize ctx->var_status field; allow
         DW_OP_GNU_uninit as legal op following a DW_OP_reg op or a
         DW_OP_regx op; add case for DW_OP_GNU_uninit and update
         ctx->var_status appropriately.
         * dwarf2expr.h (struct dwarf_expr_context): New field,  
var_status.
         (unsigned_address_type): Add extern declaration.
         (signed_address_type): Likewise.
         (add_piece): Likewise.
         * dwarf2loc.c (dwarf2_evaluate_loc_desc): Add call to
         set_var_status.
         * dwarf2read.c (dwarf_stack_op_name): Add case for  
DW_OP_GNU_uninit.
         (decode_locdesc): Add case for DW_OP_GNU_uninit.
         * value.c (struct value):  New field, var_status.
         (allocate_value): Initialize new field.
         (set_var_status): New function.
         (value_var_status): New function.
         * value.h (value_var_status): New extern declaration.
         (set_var_status): Likewise.
         * include/elf/dwarf2.h: (enum dwarf_location_atom): Add new  
DW_OP,
         DW_OP_GNU_uninit.



[-- Attachment #4: fsf-gdb-patch.txt --]
[-- Type: text/plain, Size: 9486 bytes --]

Index: gdb/c-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-valprint.c,v
retrieving revision 1.42
diff -c -3 -p -r1.42 c-valprint.c
*** gdb/c-valprint.c	26 Jan 2007 20:54:16 -0000	1.42
--- gdb/c-valprint.c	1 May 2007 22:10:43 -0000
*************** c_value_print (struct value *val, struct
*** 556,561 ****
--- 556,564 ----
  	}
      }
  
+   if (value_var_status (val) == 0)
+     fprintf_filtered (stream, " [uninitialized] ");
+ 
    if (objectprint && (TYPE_CODE (type) == TYPE_CODE_CLASS))
      {
        /* Attempt to determine real type of object */
Index: gdb/dwarf2expr.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2expr.c,v
retrieving revision 1.19
diff -c -3 -p -r1.19 dwarf2expr.c
*** gdb/dwarf2expr.c	9 Jan 2007 17:58:50 -0000	1.19
--- gdb/dwarf2expr.c	1 May 2007 22:10:43 -0000
*************** dwarf_expr_fetch (struct dwarf_expr_cont
*** 106,112 ****
  }
  
  /* Add a new piece to CTX's piece list.  */
! static void
  add_piece (struct dwarf_expr_context *ctx,
             int in_reg, CORE_ADDR value, ULONGEST size)
  {
--- 106,112 ----
  }
  
  /* Add a new piece to CTX's piece list.  */
! void
  add_piece (struct dwarf_expr_context *ctx,
             int in_reg, CORE_ADDR value, ULONGEST size)
  {
*************** dwarf2_read_address (gdb_byte *buf, gdb_
*** 213,219 ****
  
  /* Return the type of an address, for unsigned arithmetic.  */
  
! static struct type *
  unsigned_address_type (void)
  {
    switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
--- 213,219 ----
  
  /* Return the type of an address, for unsigned arithmetic.  */
  
! struct type *
  unsigned_address_type (void)
  {
    switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
*************** unsigned_address_type (void)
*** 232,238 ****
  
  /* Return the type of an address, for signed arithmetic.  */
  
! static struct type *
  signed_address_type (void)
  {
    switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
--- 232,238 ----
  
  /* Return the type of an address, for signed arithmetic.  */
  
! struct type *
  signed_address_type (void)
  {
    switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
*************** execute_stack_op (struct dwarf_expr_cont
*** 257,262 ****
--- 257,263 ----
  		  gdb_byte *op_ptr, gdb_byte *op_end)
  {
    ctx->in_reg = 0;
+   ctx->var_status = 1;  /* Default is initialized.  */
  
    while (op_ptr < op_end)
      {
*************** execute_stack_op (struct dwarf_expr_cont
*** 383,389 ****
  	case DW_OP_reg29:
  	case DW_OP_reg30:
  	case DW_OP_reg31:
! 	  if (op_ptr != op_end && *op_ptr != DW_OP_piece)
  	    error (_("DWARF-2 expression error: DW_OP_reg operations must be "
  		   "used either alone or in conjuction with DW_OP_piece."));
  
--- 384,392 ----
  	case DW_OP_reg29:
  	case DW_OP_reg30:
  	case DW_OP_reg31:
! 	  if (op_ptr != op_end 
! 	      && *op_ptr != DW_OP_piece
! 	      && *op_ptr != DW_OP_GNU_uninit)
  	    error (_("DWARF-2 expression error: DW_OP_reg operations must be "
  		   "used either alone or in conjuction with DW_OP_piece."));
  
*************** execute_stack_op (struct dwarf_expr_cont
*** 394,400 ****
  
  	case DW_OP_regx:
  	  op_ptr = read_uleb128 (op_ptr, op_end, &reg);
! 	  if (op_ptr != op_end && *op_ptr != DW_OP_piece)
  	    error (_("DWARF-2 expression error: DW_OP_reg operations must be "
  		   "used either alone or in conjuction with DW_OP_piece."));
  
--- 397,405 ----
  
  	case DW_OP_regx:
  	  op_ptr = read_uleb128 (op_ptr, op_end, &reg);
! 	  if (op_ptr != op_end 
! 	      && *op_ptr != DW_OP_piece
! 	      && *op_ptr != DW_OP_GNU_uninit)
  	    error (_("DWARF-2 expression error: DW_OP_reg operations must be "
  		   "used either alone or in conjuction with DW_OP_piece."));
  
*************** execute_stack_op (struct dwarf_expr_cont
*** 704,709 ****
--- 709,718 ----
            }
            goto no_push;
  
+ 	case DW_OP_GNU_uninit:
+ 	  ctx->var_status = 0;
+ 	  goto no_push;
+ 
  	default:
  	  error (_("Unhandled dwarf expression opcode 0x%x"), op);
  	}
Index: gdb/dwarf2expr.h
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2expr.h,v
retrieving revision 1.9
diff -c -3 -p -r1.9 dwarf2expr.h
*** gdb/dwarf2expr.h	9 Jan 2007 17:58:50 -0000	1.9
--- gdb/dwarf2expr.h	1 May 2007 22:10:43 -0000
*************** struct dwarf_expr_context
*** 76,81 ****
--- 76,84 ----
       will be on the expression stack.  */
    int in_reg;
  
+   /* Initialization status of variable.  */
+   int var_status;
+ 
    /* An array of pieces.  PIECES points to its first element;
       NUM_PIECES is its length.
  
*************** gdb_byte *read_sleb128 (gdb_byte *buf, g
*** 135,138 ****
--- 138,144 ----
  CORE_ADDR dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end,
  			       int *bytes_read);
  
+ extern struct type *unsigned_address_type (void);
+ extern struct type *signed_address_type (void);
+ extern void add_piece (struct dwarf_expr_context *, int, CORE_ADDR, ULONGEST);
  #endif /* dwarf2expr.h */
Index: gdb/dwarf2loc.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.c,v
retrieving revision 1.39
diff -c -3 -p -r1.39 dwarf2loc.c
*** gdb/dwarf2loc.c	24 Jan 2007 22:04:48 -0000	1.39
--- gdb/dwarf2loc.c	1 May 2007 22:10:43 -0000
*************** dwarf2_evaluate_loc_desc (struct symbol 
*** 256,261 ****
--- 256,263 ----
        VALUE_ADDRESS (retval) = address;
      }
  
+   set_var_status (retval, ctx->var_status);
+ 
    free_dwarf_expr_context (ctx);
  
    return retval;
Index: gdb/dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.218
diff -c -3 -p -r1.218 dwarf2read.c
*** gdb/dwarf2read.c	18 Apr 2007 13:25:04 -0000	1.218
--- gdb/dwarf2read.c	1 May 2007 22:10:44 -0000
*************** dwarf_stack_op_name (unsigned op)
*** 8629,8634 ****
--- 8629,8636 ----
        return "DW_OP_bit_piece";
      case DW_OP_GNU_push_tls_address:
        return "DW_OP_GNU_push_tls_address";
+     case DW_OP_GNU_uninit:
+       return "DW_OP_GNU_uninit";
      /* HP extensions. */ 
      case DW_OP_HP_is_value:
        return "DW_OP_HP_is_value";
*************** decode_locdesc (struct dwarf_block *blk,
*** 9204,9209 ****
--- 9206,9214 ----
  	    dwarf2_complex_location_expr_complaint ();
            break;
  
+ 	case DW_OP_GNU_uninit:
+ 	  break;
+ 
  	default:
  	  complaint (&symfile_complaints, _("unsupported stack op: '%s'"),
  		     dwarf_stack_op_name (op));
Index: gdb/value.c
===================================================================
RCS file: /cvs/src/src/gdb/value.c,v
retrieving revision 1.41
diff -c -3 -p -r1.41 value.c
*** gdb/value.c	13 Apr 2007 14:17:46 -0000	1.41
--- gdb/value.c	1 May 2007 22:10:44 -0000
*************** struct value
*** 157,162 ****
--- 157,165 ----
       actually exist in the program.  */
    char optimized_out;
  
+   /* If value is a variable, is it initialized or not.  */
+   int var_status;
+ 
    /* Actual contents of the value.  For use of this value; setting it
       uses the stuff above.  Not valid if lazy is nonzero.  Target
       byte-order.  We force it to be aligned properly for any possible
*************** allocate_value (struct type *type)
*** 232,237 ****
--- 235,241 ----
    val->embedded_offset = 0;
    val->pointed_to_offset = 0;
    val->modifiable = 1;
+   val->var_status = 1;  /* Default to initialized.  */
    return val;
  }
  
*************** using_struct_return (struct type *value_
*** 1691,1696 ****
--- 1695,1717 ----
  	  != RETURN_VALUE_REGISTER_CONVENTION);
  }
  
+ /* Set the var_status field in a value struct.  */
+ 
+ void
+ set_var_status (struct value *val, int status)
+ {
+   val->var_status = status;
+ }
+ 
+ 
+ /* Return the var_status field in a value struct.  */
+ 
+ int
+ value_var_status (struct value *val)
+ {
+   return val->var_status;
+ }
+ 
  void
  _initialize_values (void)
  {
Index: gdb/value.h
===================================================================
RCS file: /cvs/src/src/gdb/value.h,v
retrieving revision 1.96
diff -c -3 -p -r1.96 value.h
*** gdb/value.h	9 Jan 2007 17:58:59 -0000	1.96
--- gdb/value.h	1 May 2007 22:10:44 -0000
*************** extern int value_contents_equal (struct 
*** 193,198 ****
--- 193,202 ----
  extern int value_optimized_out (struct value *value);
  extern void set_value_optimized_out (struct value *value, int val);
  
+ /* */
+ extern int value_var_status (struct value *);
+ extern void set_var_status (struct value *, int);
+ 
  /* While the following fields are per- VALUE .CONTENT .PIECE (i.e., a
     single value might have multiple LVALs), this hacked interface is
     limited to just the first PIECE.  Expect further change.  */
Index: include/elf/dwarf2.h
===================================================================
RCS file: /cvs/src/src/include/elf/dwarf2.h,v
retrieving revision 1.19
diff -c -3 -p -r1.19 dwarf2.h
*** include/elf/dwarf2.h	2 Mar 2006 00:54:27 -0000	1.19
--- include/elf/dwarf2.h	1 May 2007 22:10:44 -0000
*************** enum dwarf_location_atom
*** 540,545 ****
--- 540,546 ----
      DW_OP_bit_piece = 0x9d,
      /* GNU extensions.  */
      DW_OP_GNU_push_tls_address = 0xe0,
+     DW_OP_GNU_uninit     = 0xf0,
      /* HP extensions.  */
      DW_OP_HP_unknown     = 0xe0, /* Ouch, the same as GNU_push_tls_address.  */
      DW_OP_HP_is_value    = 0xe1,

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Ping!  [PATCH]: Track uninitialized variables
  2007-05-02  0:03 [PATCH]: Track uninitialized variables Caroline Tice
@ 2007-05-08 16:25 ` Caroline Tice
  2007-05-09  0:28 ` Ian Lance Taylor
  2007-05-11 19:13 ` [PATCH, revised]: " Caroline Tice
  2 siblings, 0 replies; 25+ messages in thread
From: Caroline Tice @ 2007-05-08 16:25 UTC (permalink / raw)
  To: gcc-patches@gcc.gnu.org Patches; +Cc: Caroline Tice


On May 1, 2007, at 5:02 PM, Caroline Tice wrote:

>
> As part of some work I've been doing on improving debugging of  
> optimized code, I
> have developed the following patch which, while tracking the  
> locations of variables,
> also keeps track of whether the variables are initialized or not (it  
> makes conservative
> assumptions where it can't be sure).  For those places where it is  
> sure the variables
> are unintialized, it adds an annotation to the var_location_note,  
> which the dwarf
> writer later translates to a new DW_OP (an extension) that indicates  
> a variable is uninitialized
> (DW_OP_GNU_uninit).
>
> Since this work requires that GDB be able to read and do something  
> reasonable with
> the new DW_OP, I have also created a GDB patch to deal with the new  
> op, and to
> inform the user that a particular value is unintialized when the  
> user asks to see it.
> As the two patches really go together, I am attaching both of them  
> to this message.
> (I will also be sending the GDB patch to the gdb patches list).
>
> Because using the new DW_OP is sensitive to whether or not the user  
> has a version of GDB
> that can handle it, I have added a macro, TARGET_DWARF_UNINIT_VARS,  
> which defaults
> to 0, and which controls whether the uninitialized variable tracking  
> is done.
>
> I have bootstrapped and run the dejagnu testsuite on this patch,  
> with no regressions, on
> a ppc running apple-darwin, an x86 running apple-darwin, and an x86  
> 64 running 64-bit linux.
>
> Is this patch okay to commit to mainline?
>
> -- Caroline Tice
> ctice@apple.com
>
> 2007-05-01  Caroline Tice  <ctice@apple.com>
>
>        * defaults.h (TARGET_DWARF_UNINIT_VARS): New macro, to control
>        tracking uninitialized variables.
>        * rtl.def (VAR_LOCATION): Add a new integer subfield to  
> VAR_LOCATION
>        note definitions, to allow recording of initialization status  
> in the
>        notes.
>        * dwarf2out.c (dwarf_stack_op_name): Add case for  
> DW_OP_GNU_uninit.
>        (add_var_loc_to_decl): Add comparison of  
> NOTE_VAR_LOCATION_STATUS to
>        determine if two note locations are equal.
>        (output_loc_list): Don't output list entries whose start &  
> end labels
>        are the same.
>        (reg_loc_descriptor): Add parameter for initialization  
> status; pass it
>        to other loc descriptor functions.
>        (one_reg_loc_descriptor): Add parameter for initialization  
> status;
>        check its value and add DW_OP_GNU_uninit to returned loc  
> descr if
>        appropriate.
>        (multiple_reg_loc_descriptor): Add parameter for  
> initialization status;
>        pass init status argument to other loc descriptor functions;  
> check
>        value of intialization parameter and add DW_OP_GNU_uninit to  
> returned
>        loc descr if appropriate.
>        (based_loc_descr): Add parameter for initialization status;  
> add new
>        variable for return value; check value of initialization  
> parameter and
>        add DW_OP_GNU_uninit to returned loc descr if appropriate.
>        (concatn_mem_loc_descriptor): Add parameter for  
> initialization status;
>        pass init status argument to other loc descriptor functions;  
> check
>        value of intialization parameter and add DW_OP_GNU_uninit to  
> returned
>        loc descr if appropriate.
>        (mem_loc_descriptor): Likewise.
>        (concat_loc_descriptor): Likewise.
>        (concatn_loc_descriptor): Likewise.
>        (loc_descriptor): Add parameter for initialization status;  
> pass it as
>        argument to other loc descriptor function calls.
>        (loc_descriptor_from_tree_1): Add appropriate initialization  
> status
>        to loc descriptor function calls.
>        (add_location_or_const_value_attribute): Get initialization  
> status
>        from VAR_LOCATION note; add initialization status to loc  
> descriptor
>        function calls.
>        * dwarf2.h (enum dwarf_location_atom): New op,  
> DW_OP_GNU_uninit.
>        * print-rtl.c (print_rtx): When printing a VAR_LOCATION note,  
> if status
>        is uninitialized, add "[uninint]" to output.
>        * rtl.h (NOTE_VAR_LOCATION_STATUS): New macro for accessing  
> new field.
>        (enum var_init_status): New type, for var initialization  
> status field.
>        * var-tracking.c (struct location_chain_def): Two new fields,  
> init,
>        for initialization status, and set_src for the assignment  
> value expr.
>        (unshare_variable): New parameter for initialization status;  
> initialize
>        new init and set_src fields.
>        (var_reg_set): New parameters for initialization status and  
> value;
>        pass them to set_variable_part.
>        (var_mem_set): Likewise.
>        (get_init_value): New function.
>        (var_reg_delete_and_set): New initialization status & value  
> parameters;
>        add call to get_init_value if status is unknown; pass new  
> parameters
>        to clobber_variable_part and var_reg_set.
>        (var_mem_delete_and_set): Likewise.
>        (var_reg_delete): Pass null set_src value to  
> clobber_variable_part.
>        (var_mem_delete): Likewise.
>        (variable_union): Pass status to unshare_variable; initialize  
> new init
>        and set_src fields.  If target doesn't have correct gdb  
> (tested by
>        macro TARGET_DWARF_UNINIT_VARS), force status to initialized.
>        (add_stores): Store insn, rather than NEXT_INSN(insn), so it  
> can be
>        used later to get the set_src value.
>        (find_src_status): New function.
>        (find_src_set_src): New function.
>        (compute_bb_dataflow): Pass init status to calls to  
> var_reg_set,
>        var_mem_set, var_reg_delete_and_set and  
> var_mem_delete_and_set; for
>        MO_SET, get set_src value and pass it to   
> var_reg_delete_and_set
>        and var_mem_delete_and_set.
>        (dump_variable):  Print out "[uninit]" if appropriate.
>        (set_variable_part): Add new initialization and set_src  
> parameters;
>        pass status to unshare_variable; set node->init and node- 
> >set_src
>        fields and modify slot in hash table appropriately; save the  
> init and
>        set_src values if appropriate and assign to the new node.
>        (clobber_variable_part): New set_src parameter; if two nodes  
> have
>        same variable and same location but different set_src  
> (assignment)
>        values, clobber old node.
>        (delete_variable_part): Pass init status to unshare_variable.
>        (emit_note_insn_var_location): Add initialized var; assign  
> var's init
>        status to new 'initialized'; pass new init status field to  
> calls to
>        gen_rtx_VAR_LOCATION.  If target doesn't have correct gdb  
> (tested by
>        macro TARGET_DWARF_UNINIT_VARS), force status to initialized.
>        (emit_notes_in_bb): Pass initialization status to calls to  
> var_reg_set,
>        var_mem_set, var_reg_delete_and_set and  
> var_mem_delete_and_set; for
>        MO_SET, get set_src value and pass it to  
> var_reg_delete_and_set and
>        var_mem_delete_and_set; call emit_notes_for_changes on  
> NEXT_INSN(insn)
>        rather than on insn, to make up for change in add_stores.
>        (vt_add_function_parameters): Add status to calls to  
> set_variable_part.
>        * config/i386/linux.h (TARGET_DWARF_UNINIT_VARS): New macro  
> definition
>        to control tracking uninitialized variables.  Redefined from  
> defaults.h
>        * config/darwin.h (TARGET_DWARF_UNINIT_VARS): New macro  
> definition to
>        control tracking uninitialized variables.  Redefined from  
> defaults.h.
>
>
>
> <fsf-gcc-patch.txt>
>
> GDB PATCH:
>
> 2007-05-01  Caroline Tice  <ctice@apple.com>
>
>        * c-valprint.c (c_value_print):  If the var_status field of the
>        value struct is 0, print out "[uninitialized]" before the  
> value.
>        * dwarf2expr.c (add_piece): Make function non-static.
>        (unsigned_address_type): Likewise.
>        (signed_address_type): Likewise.
>        (execute_stack_op): Initialize ctx->var_status field; allow
>        DW_OP_GNU_uninit as legal op following a DW_OP_reg op or a
>        DW_OP_regx op; add case for DW_OP_GNU_uninit and update
>        ctx->var_status appropriately.
>        * dwarf2expr.h (struct dwarf_expr_context): New field,  
> var_status.
>        (unsigned_address_type): Add extern declaration.
>        (signed_address_type): Likewise.
>        (add_piece): Likewise.
>        * dwarf2loc.c (dwarf2_evaluate_loc_desc): Add call to
>        set_var_status.
>        * dwarf2read.c (dwarf_stack_op_name): Add case for  
> DW_OP_GNU_uninit.
>        (decode_locdesc): Add case for DW_OP_GNU_uninit.
>        * value.c (struct value):  New field, var_status.
>        (allocate_value): Initialize new field.
>        (set_var_status): New function.
>        (value_var_status): New function.
>        * value.h (value_var_status): New extern declaration.
>        (set_var_status): Likewise.
>        * include/elf/dwarf2.h: (enum dwarf_location_atom): Add new  
> DW_OP,
>        DW_OP_GNU_uninit.
>
>
> <fsf-gdb-patch.txt>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH]: Track uninitialized variables
  2007-05-02  0:03 [PATCH]: Track uninitialized variables Caroline Tice
  2007-05-08 16:25 ` Ping! " Caroline Tice
@ 2007-05-09  0:28 ` Ian Lance Taylor
  2007-05-09 16:48   ` Caroline Tice
  2007-05-11 19:13 ` [PATCH, revised]: " Caroline Tice
  2 siblings, 1 reply; 25+ messages in thread
From: Ian Lance Taylor @ 2007-05-09  0:28 UTC (permalink / raw)
  To: Caroline Tice; +Cc: gcc-patches@gcc.gnu.org Patches

Caroline Tice <ctice@apple.com> writes:

> As part of some work I've been doing on improving debugging of
> optimized code, I
> have developed the following patch which, while tracking the locations
> of variables,
> also keeps track of whether the variables are initialized or not (it
> makes conservative
> assumptions where it can't be sure).  For those places where it is
> sure the variables
> are unintialized, it adds an annotation to the var_location_note,
> which the dwarf
> writer later translates to a new DW_OP (an extension) that indicates a
> variable is uninitialized
> (DW_OP_GNU_uninit).

[ For some reason the line breaks in your e-mail message make it hard
  to read. ]


Can you explain why this is useful?

Your patch needs comments for the changes in rtl.def and dwarf2.h.

Using TARGET_DWARF_UNINIT_VARS doesn't make sense to me.  This is an
enhancement which depends on the version of gdb being used.  It is not
in any meaningful way target specific.  I would recommend controlling
this via an option.  For Darwin, you can make the option default to on
if you like.

Ian

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH]: Track uninitialized variables
  2007-05-09  0:28 ` Ian Lance Taylor
@ 2007-05-09 16:48   ` Caroline Tice
  2007-05-09 17:40     ` Caroline Tice
  2007-05-09 18:08     ` Ian Lance Taylor
  0 siblings, 2 replies; 25+ messages in thread
From: Caroline Tice @ 2007-05-09 16:48 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches@gcc.gnu.org Patches, gkeating


On May 8, 2007, at 5:28 PM, Ian Lance Taylor wrote:

> Caroline Tice <ctice@apple.com> writes:
>
>> As part of some work I've been doing on improving debugging of
>> optimized code, I
>> have developed the following patch which, while tracking the  
>> locations
>> of variables,
>> also keeps track of whether the variables are initialized or not (it
>> makes conservative
>> assumptions where it can't be sure).  For those places where it is
>> sure the variables
>> are unintialized, it adds an annotation to the var_location_note,
>> which the dwarf
>> writer later translates to a new DW_OP (an extension) that  
>> indicates a
>> variable is uninitialized
>> (DW_OP_GNU_uninit).
>
> [ For some reason the line breaks in your e-mail message make it hard
>   to read. ]
>


I'm sorry about that; I forgot that the our email system does this
sometimes.  I will try to be more careful with future messages.

>
> Can you explain why this is useful?
>

As I mentioned, this is mostly for help with debugging optimized
code.  Sometimes bugs that seem to "magically appear" when
optimizations get turned on are actually caused by uninitialized
variables having a different value when the optimizations change
the data layout.  In the unoptimized version the value happened
to be benign, but in the optimized version the value causes bad
things to happen.  Therefore it would help programmers quite
a bit, when attempting to debug their optimized code, if the
debugger could point out when a variable did not get optimized.

> Your patch needs comments for the changes in rtl.def and dwarf2.h.
>

Okay, will do.

> Using TARGET_DWARF_UNINIT_VARS doesn't make sense to me.  This is an
> enhancement which depends on the version of gdb being used.  It is not
> in any meaningful way target specific.  I would recommend controlling
> this via an option.  For Darwin, you can make the option default to on
> if you like.
>

I did it this way on the recommendation of Geoff Keating (we discussed
both approaches), but I am willing to change it if you really want me  
to.
Geoff's idea, I believe, was that doing it this way, individual people
maintaining their systems can turn this on as they install the correct
version of GDB, then never have to worry about it again, as opposed to
having to pass a flag/option every time you do a compilation.  But I may
have misunderstood his reasoning; perhaps he could explain it better.

> Ian

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH]: Track uninitialized variables
  2007-05-09 16:48   ` Caroline Tice
@ 2007-05-09 17:40     ` Caroline Tice
  2007-05-09 18:08     ` Ian Lance Taylor
  1 sibling, 0 replies; 25+ messages in thread
From: Caroline Tice @ 2007-05-09 17:40 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Caroline Tice, gcc-patches@gcc.gnu.org Patches, gkeating


On May 9, 2007, at 9:48 AM, Caroline Tice wrote:

>
> As I mentioned, this is mostly for help with debugging optimized
> code.  Sometimes bugs that seem to "magically appear" when
> optimizations get turned on are actually caused by uninitialized
> variables having a different value when the optimizations change
> the data layout.  In the unoptimized version the value happened
> to be benign, but in the optimized version the value causes bad
> things to happen.  Therefore it would help programmers quite
> a bit, when attempting to debug their optimized code, if the
> debugger could point out when a variable did not get optimized.
                                                                         
                 ^^^^^^^^^^^^^^^^
Typo:  That was supposed to say, "when a variable did not
get initialized".

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH]: Track uninitialized variables
  2007-05-09 16:48   ` Caroline Tice
  2007-05-09 17:40     ` Caroline Tice
@ 2007-05-09 18:08     ` Ian Lance Taylor
  2007-05-09 18:16       ` Daniel Jacobowitz
  1 sibling, 1 reply; 25+ messages in thread
From: Ian Lance Taylor @ 2007-05-09 18:08 UTC (permalink / raw)
  To: Caroline Tice; +Cc: gcc-patches@gcc.gnu.org Patches, gkeating

Caroline Tice <ctice@apple.com> writes:

> > Using TARGET_DWARF_UNINIT_VARS doesn't make sense to me.  This is an
> > enhancement which depends on the version of gdb being used.  It is not
> > in any meaningful way target specific.  I would recommend controlling
> > this via an option.  For Darwin, you can make the option default to on
> > if you like.
> >
> 
> I did it this way on the recommendation of Geoff Keating (we discussed
> both approaches), but I am willing to change it if you really want me
> to.
> Geoff's idea, I believe, was that doing it this way, individual people
> maintaining their systems can turn this on as they install the correct
> version of GDB, then never have to worry about it again, as opposed to
> having to pass a flag/option every time you do a compilation.  But I may
> have misunderstood his reasoning; perhaps he could explain it better.

In my view that makes sense if you are a distro maintainer, but it
does not make sense for anybody else.  If I build gcc myself, I won't
know to make this change.  And since most distro maintainers do not
track the minutia of gcc changes, they probably wouldn't change it
either (which is also a flaw with my suggestion above).

I'll expand my recommendation: provide a command line option, and use
a configure test to set the default value of the command line option.
Any other suggestions?

Ian

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH]: Track uninitialized variables
  2007-05-09 18:08     ` Ian Lance Taylor
@ 2007-05-09 18:16       ` Daniel Jacobowitz
  2007-05-10  3:29         ` Mark Mitchell
  0 siblings, 1 reply; 25+ messages in thread
From: Daniel Jacobowitz @ 2007-05-09 18:16 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Caroline Tice, gcc-patches@gcc.gnu.org Patches, gkeating

On Wed, May 09, 2007 at 11:07:28AM -0700, Ian Lance Taylor wrote:
> I'll expand my recommendation: provide a command line option, and use
> a configure test to set the default value of the command line option.
> Any other suggestions?

Trying to check at configure time for the features of a debugger seems
like a bad idea.  I'd recommend just defaulting it to off and
providing the option.  Darwin can wiggle it on by default if they
want.  It probably shouldn't be on by default on other platforms until
someone's approached the DWARF committee about it; it'll break all
other debuggers too.

If this goes in at all I'd like it on by default too, but not until it
won't be a compatibility headache.  It's a pity there's no graceful
way for a debugger to ignore unknown markers in the location
expressions.  It only affects printing values at points where they are
believed to be uninitialized, though, so maybe the collateral damage
is small.

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH]: Track uninitialized variables
  2007-05-09 18:16       ` Daniel Jacobowitz
@ 2007-05-10  3:29         ` Mark Mitchell
  0 siblings, 0 replies; 25+ messages in thread
From: Mark Mitchell @ 2007-05-10  3:29 UTC (permalink / raw)
  To: Ian Lance Taylor, Caroline Tice, gcc-patches@gcc.gnu.org Patches,
	gkeating

Daniel Jacobowitz wrote:
> On Wed, May 09, 2007 at 11:07:28AM -0700, Ian Lance Taylor wrote:
>> I'll expand my recommendation: provide a command line option, and use
>> a configure test to set the default value of the command line option.
>> Any other suggestions?
> 
> Trying to check at configure time for the features of a debugger seems
> like a bad idea. 

For one thing, you can't do it with a Canadian cross, so we're going to
break the invariant that a Canadian cross and an ordinary cross come out
exactly the same.  We should never have configure checks that require
running host programs -- although running build programs which are
assumed to be the same as host programs (such as a build->target
assembler instead of a host->target assembler) is OK.  I guess we could
say that you have to provide a build->target GDB, but that seems pretty
nasty.

I agree that, if we decide this patch should go in, it should just be a
command-line option, with, if we like, a configure-time option to enable it.

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH, revised]: Track uninitialized variables
  2007-05-02  0:03 [PATCH]: Track uninitialized variables Caroline Tice
  2007-05-08 16:25 ` Ping! " Caroline Tice
  2007-05-09  0:28 ` Ian Lance Taylor
@ 2007-05-11 19:13 ` Caroline Tice
  2007-05-18 19:48   ` Ping! " Caroline Tice
  2007-07-11 14:45   ` Ian Lance Taylor
  2 siblings, 2 replies; 25+ messages in thread
From: Caroline Tice @ 2007-05-11 19:13 UTC (permalink / raw)
  To: gcc-patches@gcc.gnu.org Patches; +Cc: Caroline Tice

[-- Attachment #1: Type: text/plain, Size: 8791 bytes --]

Here is a revised version of my patch for tracking uninitialized
variables (see description in original posting copied below).  I added
the comments Ian asked for, and I changed the way it is turned on/off.
Instead of the macro in my previous patch, it is now controlled by a
command line option, -fvar-tracking-uninit, which turns on
var-tracking, just like -fvar-tracking, but also turns on the
uninitialized variable tracking.  I added the same feasibility checks to
it that are used for -fvar-tracking.  I also turned it on by default
on darwin systems running 10.5 or later (when var-tracking is on).

I tested this patch by bootstrapping it and running the dejagnu
testsuite without any regressions, on a ppc running apple-darwin, an
x86 running apple-darwin, and an x86 64 running 64-bit linux.  I also
ran it on a small test case containing uninitialized variables, to
verify that it turns on when the command line option is passed, or
when running on the correct version of darwin, and is off at all other
times.

Is this patch okay to commit to mainline?

--Caroline Tice
ctice@apple.com


On May 1, 2007, at 5:02 PM, Caroline Tice wrote:

>
> As part of some work I've been doing on improving debugging of
> optimized code, I have developed the following patch which, while
> tracking the locations of variables, also keeps track of whether the
> variables are initialized or not (it makes conservative assumptions
> where it can't be sure).  For those places where it is sure the
> variables are unintialized, it adds an annotation to the
> var_location_note, which the dwarf writer later translates to a new
> DW_OP (an extension) that indicates a variable is uninitialized
> (DW_OP_GNU_uninit).

> Since this work requires that GDB be able to read and do something
> reasonable with the new DW_OP, I have also created a GDB patch to deal
> with the new op, and to inform the user that a particular value is
> unintialized when the user asks to see it.  As the two patches really
> go together, I am attaching both of them to this message.  (I will
> also be sending the GDB patch to the gdb patches list).

> Because using the new DW_OP is sensitive to whether or not the user
> has a version of GDB that can handle it, I have added a macro,
> TARGET_DWARF_UNINIT_VARS, which defaults to 0, and which controls
> whether the uninitialized variable tracking is done.

> I have bootstrapped and run the dejagnu testsuite on this patch, with
> no regressions, on a ppc running apple-darwin, an x86 running
> apple-darwin, and an x86 64 running 64-bit linux.

> Is this patch okay to commit to mainline?
> -- Caroline Tice
> ctice@apple.com
>

2007-05-11  Caroline Tice  <ctice@apple.com>

         * toplev.c (process_options): Turn flag_var_tracking_uninit  
off when
         flag_var_tracking is explicitly turned off (i.e. when variable
         tracking is not feasible); otherwise, turn flag_var_tracking  
on when
         flag_var_tracking_uninit is on.
         * rtl.def (VAR_LOCATION): Add a new integer subfield to  
VAR_LOCATION
         note definitions, to allow recording of initialization status  
in the
         notes.
         * dwarf2out.c (dwarf_stack_op_name): Add case for  
DW_OP_GNU_uninit.
         (add_var_loc_to_decl): Add comparison of  
NOTE_VAR_LOCATION_STATUS to
         determine if two note locations are equal.
         (output_loc_list): Don't output list entries whose start &  
end labels
         are the same.
         (reg_loc_descriptor): Add parameter for initialization  
status; pass it
         to other loc descriptor functions.
         (one_reg_loc_descriptor): Add parameter for initialization  
status;
         check its value and add DW_OP_GNU_uninit to returned loc  
descr if
         appropriate.
         (multiple_reg_loc_descriptor): Add parameter for initialization
         status;
         pass init status argument to other loc descriptor functions;  
check
         value of intialization parameter and add DW_OP_GNU_uninit to  
returned
         loc descr if appropriate.
         (based_loc_descr): Add parameter for initialization status;  
add new
         variable for return value; check value of initialization  
parameter and
         add DW_OP_GNU_uninit to returned loc descr if appropriate.
         (concatn_mem_loc_descriptor): Add parameter for  
initialization status;
         pass init status argument to other loc descriptor functions;  
check
         value of intialization parameter and add DW_OP_GNU_uninit to  
returned
         loc descr if appropriate.
         (mem_loc_descriptor): Likewise.
         (concat_loc_descriptor): Likewise.
         (concatn_loc_descriptor): Likewise.
         (loc_descriptor): Add parameter for initialization status;  
pass it as
         argument to other loc descriptor function calls.
         (loc_descriptor_from_tree_1): Add appropriate initialization  
status
         to loc descriptor function calls.
         (add_location_or_const_value_attribute): Get initialization  
status
         from VAR_LOCATION note; add initialization status to loc  
descriptor
         function calls.
         * dwarf2.h (enum dwarf_location_atom): New op,  
DW_OP_GNU_uninit.
         * print-rtl.c (print_rtx): When printing a VAR_LOCATION note,  
if
         status is uninitialized, add "[uninint]" to output.
         * common.opt (fvar-tracking-uninit): New option, similar to
         fvar-tracking, to turn on tracking of uninitialized  
variables; creates
         a new global flag, flag_var_tracking_uninit.
         * rtl.h (NOTE_VAR_LOCATION_STATUS): New macro for accessing  
new field.
         (enum var_init_status): New type, for var initialization  
status field.
         * var-tracking.c (struct location_chain_def): Two new fields,  
init,
         for initialization status, and set_src for the assignment  
value expr.
         (unshare_variable): New parameter for initialization status;
         initialize new init and set_src fields.
         (var_reg_set): New parameters for initialization status and  
value;
         pass them to set_variable_part.
         (var_mem_set): Likewise.
         (get_init_value): New function.
         (var_reg_delete_and_set): New initialization status & value
         parameters; add call to get_init_value if status is unknown;  
pass new
         parameters to clobber_variable_part and var_reg_set.
         (var_mem_delete_and_set): Likewise.
         (var_reg_delete): Pass null set_src value to  
clobber_variable_part.
         (var_mem_delete): Likewise.
         (variable_union): Pass status to unshare_variable; initialize  
new init
         and set_src fields.  If flag_var_tracking_uninit is not set,  
force
         status to initialized.
         (add_stores): Store insn, rather than NEXT_INSN(insn), so it  
can be
         used later to get the set_src value.
         (find_src_status): New function.
         (find_src_set_src): New function.
         (compute_bb_dataflow): Pass init status to calls to  
var_reg_set,
         var_mem_set, var_reg_delete_and_set and  
var_mem_delete_and_set; for
         MO_SET, get set_src value and pass it to   
var_reg_delete_and_set
         and var_mem_delete_and_set.
         (dump_variable):  Print out "[uninit]" if appropriate.
         (set_variable_part): Add new initialization and set_src  
parameters;
         pass status to unshare_variable; set node->init and node- 
 >set_src
         fields and modify slot in hash table appropriately; save the  
init and
         set_src values if appropriate and assign to the new node.
         (clobber_variable_part): New set_src parameter; if two nodes  
have
         same variable and same location but different set_src  
(assignment)
         values, clobber old node.
         (delete_variable_part): Pass init status to unshare_variable.
         (emit_note_insn_var_location): Add initialized var; assign  
var's init
         status to new 'initialized'; pass new init status field to  
calls to
         gen_rtx_VAR_LOCATION.  If flag_var_tracking_uninit is not  
set, force
         status to initialized.
         (emit_notes_in_bb): Pass initialization status to calls to
         var_reg_set, var_mem_set, var_reg_delete_and_set and
         var_mem_delete_and_set; for MO_SET, get set_src value and  
pass it to
         var_reg_delete_and_set and var_mem_delete_and_set; call
         emit_notes_for_changes on NEXT_INSN(insn) rather than on  
insn, to
         make up for change in add_stores.
         (vt_add_function_parameters): Add status to calls to
         set_variable_part.
         * config/darwin.c (darwin_override_options): Turn on  
uninitialized
         tracking automatically, if var_tracking is on and the system is
         10.5 or higher.



[-- Attachment #2: fsf-gcc-patch.v2.txt --]
[-- Type: text/plain, Size: 63265 bytes --]

Index: gcc/toplev.c
===================================================================
*** gcc/toplev.c	(revision 124599)
--- gcc/toplev.c	(working copy)
*************** process_options (void)
*** 1853,1859 ****
    if (debug_info_level < DINFO_LEVEL_NORMAL
        || debug_hooks->var_location == do_nothing_debug_hooks.var_location)
      {
!       if (flag_var_tracking == 1)
          {
  	  if (debug_info_level < DINFO_LEVEL_NORMAL)
  	    warning (0, "variable tracking requested, but useless unless "
--- 1853,1860 ----
    if (debug_info_level < DINFO_LEVEL_NORMAL
        || debug_hooks->var_location == do_nothing_debug_hooks.var_location)
      {
!       if (flag_var_tracking == 1
! 	  || flag_var_tracking_uninit == 1)
          {
  	  if (debug_info_level < DINFO_LEVEL_NORMAL)
  	    warning (0, "variable tracking requested, but useless unless "
*************** process_options (void)
*** 1863,1868 ****
--- 1864,1870 ----
  		     "by this debug format");
  	}
        flag_var_tracking = 0;
+       flag_var_tracking_uninit = 0;
      }
  
    if (flag_rename_registers == AUTODETECT_VALUE)
*************** process_options (void)
*** 1872,1877 ****
--- 1874,1885 ----
    if (flag_var_tracking == AUTODETECT_VALUE)
      flag_var_tracking = optimize >= 1;
  
+   /* If the user specifically requested variable tracking with tagging
+      uninitialized variables, we need to turn on variable tracking.
+      (We already determined above that variable tracking is feasible.)  */
+   if (flag_var_tracking_uninit)
+     flag_var_tracking = 1;
+ 
    /* If auxiliary info generation is desired, open the output file.
       This goes in the same directory as the source file--unlike
       all the other output files.  */
Index: gcc/rtl.def
===================================================================
*** gcc/rtl.def	(revision 124599)
--- gcc/rtl.def	(working copy)
*************** DEF_RTL_EXPR(SS_TRUNCATE, "ss_truncate",
*** 673,679 ****
  DEF_RTL_EXPR(US_TRUNCATE, "us_truncate", "e", RTX_UNARY)
  
  /* Information about the variable and its location.  */
! DEF_RTL_EXPR(VAR_LOCATION, "var_location", "te", RTX_EXTRA)
  
  /* All expressions from this point forward appear only in machine
     descriptions.  */
--- 673,681 ----
  DEF_RTL_EXPR(US_TRUNCATE, "us_truncate", "e", RTX_UNARY)
  
  /* Information about the variable and its location.  */
! /* Changed 'te' to 'tei'; the 'i' field is for recording
!    initialization status of variables.  */
! DEF_RTL_EXPR(VAR_LOCATION, "var_location", "tei", RTX_EXTRA)
  
  /* All expressions from this point forward appear only in machine
     descriptions.  */
Index: gcc/dwarf2out.c
===================================================================
*** gcc/dwarf2out.c	(revision 124599)
--- gcc/dwarf2out.c	(working copy)
*************** dwarf_stack_op_name (unsigned int op)
*** 3116,3121 ****
--- 3116,3123 ----
        return "DW_OP_call_ref";
      case DW_OP_GNU_push_tls_address:
        return "DW_OP_GNU_push_tls_address";
+     case DW_OP_GNU_uninit:
+       return "DW_OP_GNU_uninit";
      default:
        return "OP_<unknown>";
      }
*************** static dw_die_ref modified_type_die (tre
*** 4163,4177 ****
  static int type_is_enum (tree);
  static unsigned int dbx_reg_number (rtx);
  static void add_loc_descr_op_piece (dw_loc_descr_ref *, int);
! static dw_loc_descr_ref reg_loc_descriptor (rtx);
! static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int);
! static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx);
  static dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT);
! static dw_loc_descr_ref based_loc_descr (rtx, HOST_WIDE_INT);
  static int is_based_loc (rtx);
! static dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode);
! static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx);
! static dw_loc_descr_ref loc_descriptor (rtx);
  static dw_loc_descr_ref loc_descriptor_from_tree_1 (tree, int);
  static dw_loc_descr_ref loc_descriptor_from_tree (tree);
  static HOST_WIDE_INT ceiling (HOST_WIDE_INT, unsigned int);
--- 4165,4184 ----
  static int type_is_enum (tree);
  static unsigned int dbx_reg_number (rtx);
  static void add_loc_descr_op_piece (dw_loc_descr_ref *, int);
! static dw_loc_descr_ref reg_loc_descriptor (rtx, enum var_init_status);
! static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int, 
! 						enum var_init_status);
! static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx,
! 						     enum var_init_status);
  static dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT);
! static dw_loc_descr_ref based_loc_descr (rtx, HOST_WIDE_INT,
! 					 enum var_init_status);
  static int is_based_loc (rtx);
! static dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode,
! 					    enum var_init_status);
! static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx,
! 					       enum var_init_status);
! static dw_loc_descr_ref loc_descriptor (rtx, enum var_init_status);
  static dw_loc_descr_ref loc_descriptor_from_tree_1 (tree, int);
  static dw_loc_descr_ref loc_descriptor_from_tree (tree);
  static HOST_WIDE_INT ceiling (HOST_WIDE_INT, unsigned int);
*************** add_var_loc_to_decl (tree decl, struct v
*** 5727,5735 ****
    if (temp->last)
      {
        /* If the current location is the same as the end of the list,
  	 we have nothing to do.  */
!       if (!rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->last->var_loc_note),
! 			NOTE_VAR_LOCATION_LOC (loc->var_loc_note)))
  	{
  	  /* Add LOC to the end of list and update LAST.  */
  	  temp->last->next = loc;
--- 5734,5749 ----
    if (temp->last)
      {
        /* If the current location is the same as the end of the list,
+ 	 and either both or neither of the locations is uninitialized,
  	 we have nothing to do.  */
!       if ((!rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->last->var_loc_note),
! 			 NOTE_VAR_LOCATION_LOC (loc->var_loc_note)))
! 	  || ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note)
! 	       != NOTE_VAR_LOCATION_STATUS (loc->var_loc_note))
! 	      && ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note)
! 		   == STATUS_UNINITIALIZED)
! 		  || (NOTE_VAR_LOCATION_STATUS (loc->var_loc_note)
! 		      == STATUS_UNINITIALIZED))))
  	{
  	  /* Add LOC to the end of list and update LAST.  */
  	  temp->last->next = loc;
*************** output_loc_list (dw_loc_list_ref list_he
*** 7039,7044 ****
--- 7053,7061 ----
    for (curr = list_head; curr != NULL; curr = curr->dw_loc_next)
      {
        unsigned long size;
+       /* Don't output an entry that starts and ends at the same address.  */
+       if (strcmp (curr->begin, curr->end) == 0)
+ 	continue;
        if (!have_multiple_function_sections)
  	{
  	  dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->begin, curr->section,
*************** add_loc_descr_op_piece (dw_loc_descr_ref
*** 8648,8654 ****
     zero if there is none.  */
  
  static dw_loc_descr_ref
! reg_loc_descriptor (rtx rtl)
  {
    rtx regs;
  
--- 8665,8671 ----
     zero if there is none.  */
  
  static dw_loc_descr_ref
! reg_loc_descriptor (rtx rtl, enum var_init_status initialized)
  {
    rtx regs;
  
*************** reg_loc_descriptor (rtx rtl)
*** 8658,8685 ****
    regs = targetm.dwarf_register_span (rtl);
  
    if (hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)] > 1 || regs)
!     return multiple_reg_loc_descriptor (rtl, regs);
    else
!     return one_reg_loc_descriptor (dbx_reg_number (rtl));
  }
  
  /* Return a location descriptor that designates a machine register for
     a given hard register number.  */
  
  static dw_loc_descr_ref
! one_reg_loc_descriptor (unsigned int regno)
  {
    if (regno <= 31)
!     return new_loc_descr (DW_OP_reg0 + regno, 0, 0);
    else
!     return new_loc_descr (DW_OP_regx, regno, 0);
  }
  
  /* Given an RTL of a register, return a location descriptor that
     designates a value that spans more than one register.  */
  
  static dw_loc_descr_ref
! multiple_reg_loc_descriptor (rtx rtl, rtx regs)
  {
    int nregs, size, i;
    unsigned reg;
--- 8675,8709 ----
    regs = targetm.dwarf_register_span (rtl);
  
    if (hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)] > 1 || regs)
!     return multiple_reg_loc_descriptor (rtl, regs, initialized);
    else
!     return one_reg_loc_descriptor (dbx_reg_number (rtl), initialized);
  }
  
  /* Return a location descriptor that designates a machine register for
     a given hard register number.  */
  
  static dw_loc_descr_ref
! one_reg_loc_descriptor (unsigned int regno, enum var_init_status initialized)
  {
+   dw_loc_descr_ref reg_loc_descr;
    if (regno <= 31)
!     reg_loc_descr = new_loc_descr (DW_OP_reg0 + regno, 0, 0);
    else
!     reg_loc_descr =  new_loc_descr (DW_OP_regx, regno, 0);
! 
!   if (initialized == STATUS_UNINITIALIZED)
!     add_loc_descr (&reg_loc_descr, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
! 
!   return reg_loc_descr;
  }
  
  /* Given an RTL of a register, return a location descriptor that
     designates a value that spans more than one register.  */
  
  static dw_loc_descr_ref
! multiple_reg_loc_descriptor (rtx rtl, rtx regs, 
! 			     enum var_init_status initialized)
  {
    int nregs, size, i;
    unsigned reg;
*************** multiple_reg_loc_descriptor (rtx rtl, rt
*** 8707,8713 ****
  	{
  	  dw_loc_descr_ref t;
  
! 	  t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg));
  	  add_loc_descr (&loc_result, t);
  	  add_loc_descr_op_piece (&loc_result, size);
  	  ++reg;
--- 8731,8738 ----
  	{
  	  dw_loc_descr_ref t;
  
! 	  t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg),
! 				      STATUS_UNINITIALIZED);
  	  add_loc_descr (&loc_result, t);
  	  add_loc_descr_op_piece (&loc_result, size);
  	  ++reg;
*************** multiple_reg_loc_descriptor (rtx rtl, rt
*** 8726,8736 ****
      {
        dw_loc_descr_ref t;
  
!       t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)));
        add_loc_descr (&loc_result, t);
        size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
        add_loc_descr_op_piece (&loc_result, size);
      }
    return loc_result;
  }
  
--- 8751,8765 ----
      {
        dw_loc_descr_ref t;
  
!       t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)),
! 				  STATUS_INITIALIZED);
        add_loc_descr (&loc_result, t);
        size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
        add_loc_descr_op_piece (&loc_result, size);
      }
+ 
+   if (loc_result && initialized == STATUS_UNINITIALIZED)
+     add_loc_descr (&loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
    return loc_result;
  }
  
*************** int_loc_descriptor (HOST_WIDE_INT i)
*** 8776,8784 ****
  /* Return a location descriptor that designates a base+offset location.  */
  
  static dw_loc_descr_ref
! based_loc_descr (rtx reg, HOST_WIDE_INT offset)
  {
    unsigned int regno;
  
    /* We only use "frame base" when we're sure we're talking about the
       post-prologue local stack frame.  We do this by *not* running
--- 8805,8815 ----
  /* Return a location descriptor that designates a base+offset location.  */
  
  static dw_loc_descr_ref
! based_loc_descr (rtx reg, HOST_WIDE_INT offset,
! 		 enum var_init_status initialized)
  {
    unsigned int regno;
+   dw_loc_descr_ref result;
  
    /* We only use "frame base" when we're sure we're talking about the
       post-prologue local stack frame.  We do this by *not* running
*************** based_loc_descr (rtx reg, HOST_WIDE_INT 
*** 8805,8813 ****
  
    regno = dbx_reg_number (reg);
    if (regno <= 31)
!     return new_loc_descr (DW_OP_breg0 + regno, offset, 0);
    else
!     return new_loc_descr (DW_OP_bregx, regno, offset);
  }
  
  /* Return true if this RTL expression describes a base+offset calculation.  */
--- 8836,8849 ----
  
    regno = dbx_reg_number (reg);
    if (regno <= 31)
!     result = new_loc_descr (DW_OP_breg0 + regno, offset, 0);
    else
!     result = new_loc_descr (DW_OP_bregx, regno, offset);
! 
!   if (initialized == STATUS_UNINITIALIZED)
!     add_loc_descr (&result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
! 
!   return result;
  }
  
  /* Return true if this RTL expression describes a base+offset calculation.  */
*************** is_based_loc (rtx rtl)
*** 8825,8831 ****
     used to form the address of a memory location.  */
  
  static dw_loc_descr_ref
! concatn_mem_loc_descriptor (rtx concatn, enum machine_mode mode)
  {
    unsigned int i;
    dw_loc_descr_ref cc_loc_result = NULL;
--- 8861,8868 ----
     used to form the address of a memory location.  */
  
  static dw_loc_descr_ref
! concatn_mem_loc_descriptor (rtx concatn, enum machine_mode mode,
! 			    enum var_init_status initialized)
  {
    unsigned int i;
    dw_loc_descr_ref cc_loc_result = NULL;
*************** concatn_mem_loc_descriptor (rtx concatn,
*** 8836,8842 ****
        dw_loc_descr_ref ref;
        rtx x = XVECEXP (concatn, 0, i);
  
!       ref = mem_loc_descriptor (x, mode);
        if (ref == NULL)
  	return NULL;
  
--- 8873,8879 ----
        dw_loc_descr_ref ref;
        rtx x = XVECEXP (concatn, 0, i);
  
!       ref = mem_loc_descriptor (x, mode, STATUS_INITIALIZED);
        if (ref == NULL)
  	return NULL;
  
*************** concatn_mem_loc_descriptor (rtx concatn,
*** 8844,8849 ****
--- 8881,8889 ----
        add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x)));
      }
  
+   if (cc_loc_result && initialized == STATUS_UNINITIALIZED)
+     add_loc_descr (&cc_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+ 
    return cc_loc_result;
  }
  
*************** concatn_mem_loc_descriptor (rtx concatn,
*** 8866,8872 ****
     Return 0 if we can't represent the location.  */
  
  static dw_loc_descr_ref
! mem_loc_descriptor (rtx rtl, enum machine_mode mode)
  {
    dw_loc_descr_ref mem_loc_result = NULL;
    enum dwarf_location_atom op;
--- 8906,8913 ----
     Return 0 if we can't represent the location.  */
  
  static dw_loc_descr_ref
! mem_loc_descriptor (rtx rtl, enum machine_mode mode,
! 		    enum var_init_status initialized)
  {
    dw_loc_descr_ref mem_loc_result = NULL;
    enum dwarf_location_atom op;
*************** mem_loc_descriptor (rtx rtl, enum machin
*** 8913,8923 ****
  	 memory) so DWARF consumers need to be aware of the subtle
  	 distinction between OP_REG and OP_BASEREG.  */
        if (REGNO (rtl) < FIRST_PSEUDO_REGISTER)
! 	mem_loc_result = based_loc_descr (rtl, 0);
        break;
  
      case MEM:
!       mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl));
        if (mem_loc_result != 0)
  	add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
        break;
--- 8954,8965 ----
  	 memory) so DWARF consumers need to be aware of the subtle
  	 distinction between OP_REG and OP_BASEREG.  */
        if (REGNO (rtl) < FIRST_PSEUDO_REGISTER)
! 	mem_loc_result = based_loc_descr (rtl, 0, STATUS_INITIALIZED);
        break;
  
      case MEM:
!       mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl),
! 					   STATUS_INITIALIZED);
        if (mem_loc_result != 0)
  	add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
        break;
*************** mem_loc_descriptor (rtx rtl, enum machin
*** 8984,8993 ****
      plus:
        if (is_based_loc (rtl))
  	mem_loc_result = based_loc_descr (XEXP (rtl, 0),
! 					  INTVAL (XEXP (rtl, 1)));
        else
  	{
! 	  mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode);
  	  if (mem_loc_result == 0)
  	    break;
  
--- 9026,9037 ----
      plus:
        if (is_based_loc (rtl))
  	mem_loc_result = based_loc_descr (XEXP (rtl, 0),
! 					  INTVAL (XEXP (rtl, 1)),
! 					  STATUS_INITIALIZED);
        else
  	{
! 	  mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode,
! 					       STATUS_INITIALIZED);
  	  if (mem_loc_result == 0)
  	    break;
  
*************** mem_loc_descriptor (rtx rtl, enum machin
*** 8999,9005 ****
  	  else
  	    {
  	      add_loc_descr (&mem_loc_result,
! 			     mem_loc_descriptor (XEXP (rtl, 1), mode));
  	      add_loc_descr (&mem_loc_result,
  			     new_loc_descr (DW_OP_plus, 0, 0));
  	    }
--- 9043,9050 ----
  	  else
  	    {
  	      add_loc_descr (&mem_loc_result,
! 			     mem_loc_descriptor (XEXP (rtl, 1), mode,
! 						 STATUS_INITIALIZED));
  	      add_loc_descr (&mem_loc_result,
  			     new_loc_descr (DW_OP_plus, 0, 0));
  	    }
*************** mem_loc_descriptor (rtx rtl, enum machin
*** 9026,9033 ****
  
      do_binop:
        {
! 	dw_loc_descr_ref op0 = mem_loc_descriptor (XEXP (rtl, 0), mode);
! 	dw_loc_descr_ref op1 = mem_loc_descriptor (XEXP (rtl, 1), mode);
  
  	if (op0 == 0 || op1 == 0)
  	  break;
--- 9071,9080 ----
  
      do_binop:
        {
! 	dw_loc_descr_ref op0 = mem_loc_descriptor (XEXP (rtl, 0), mode,
! 						   STATUS_INITIALIZED);
! 	dw_loc_descr_ref op1 = mem_loc_descriptor (XEXP (rtl, 1), mode,
! 						   STATUS_INITIALIZED);
  
  	if (op0 == 0 || op1 == 0)
  	  break;
*************** mem_loc_descriptor (rtx rtl, enum machin
*** 9043,9055 ****
        break;
  
      case CONCATN:
!       mem_loc_result = concatn_mem_loc_descriptor (rtl, mode);
        break;
  
      default:
        gcc_unreachable ();
      }
  
    return mem_loc_result;
  }
  
--- 9090,9106 ----
        break;
  
      case CONCATN:
!       mem_loc_result = concatn_mem_loc_descriptor (rtl, mode, 
! 						   STATUS_INITIALIZED);
        break;
  
      default:
        gcc_unreachable ();
      }
  
+   if (mem_loc_result && initialized == STATUS_UNINITIALIZED)
+     add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+ 
    return mem_loc_result;
  }
  
*************** mem_loc_descriptor (rtx rtl, enum machin
*** 9057,9067 ****
     This is typically a complex variable.  */
  
  static dw_loc_descr_ref
! concat_loc_descriptor (rtx x0, rtx x1)
  {
    dw_loc_descr_ref cc_loc_result = NULL;
!   dw_loc_descr_ref x0_ref = loc_descriptor (x0);
!   dw_loc_descr_ref x1_ref = loc_descriptor (x1);
  
    if (x0_ref == 0 || x1_ref == 0)
      return 0;
--- 9108,9118 ----
     This is typically a complex variable.  */
  
  static dw_loc_descr_ref
! concat_loc_descriptor (rtx x0, rtx x1, enum var_init_status initialized)
  {
    dw_loc_descr_ref cc_loc_result = NULL;
!   dw_loc_descr_ref x0_ref = loc_descriptor (x0, STATUS_INITIALIZED);
!   dw_loc_descr_ref x1_ref = loc_descriptor (x1, STATUS_INITIALIZED);
  
    if (x0_ref == 0 || x1_ref == 0)
      return 0;
*************** concat_loc_descriptor (rtx x0, rtx x1)
*** 9072,9077 ****
--- 9123,9131 ----
    add_loc_descr (&cc_loc_result, x1_ref);
    add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x1)));
  
+   if (initialized == STATUS_UNINITIALIZED)
+     add_loc_descr (&cc_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+ 
    return cc_loc_result;
  }
  
*************** concat_loc_descriptor (rtx x0, rtx x1)
*** 9079,9085 ****
     locations.  */
  
  static dw_loc_descr_ref
! concatn_loc_descriptor (rtx concatn)
  {
    unsigned int i;
    dw_loc_descr_ref cc_loc_result = NULL;
--- 9133,9139 ----
     locations.  */
  
  static dw_loc_descr_ref
! concatn_loc_descriptor (rtx concatn, enum var_init_status initialized)
  {
    unsigned int i;
    dw_loc_descr_ref cc_loc_result = NULL;
*************** concatn_loc_descriptor (rtx concatn)
*** 9090,9096 ****
        dw_loc_descr_ref ref;
        rtx x = XVECEXP (concatn, 0, i);
  
!       ref = loc_descriptor (x);
        if (ref == NULL)
  	return NULL;
  
--- 9144,9150 ----
        dw_loc_descr_ref ref;
        rtx x = XVECEXP (concatn, 0, i);
  
!       ref = loc_descriptor (x, STATUS_INITIALIZED);
        if (ref == NULL)
  	return NULL;
  
*************** concatn_loc_descriptor (rtx concatn)
*** 9098,9103 ****
--- 9152,9160 ----
        add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x)));
      }
  
+   if (cc_loc_result && initialized == STATUS_UNINITIALIZED)
+     add_loc_descr (&cc_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+ 
    return cc_loc_result;
  }
  
*************** concatn_loc_descriptor (rtx concatn)
*** 9110,9116 ****
     If we don't know how to describe it, return 0.  */
  
  static dw_loc_descr_ref
! loc_descriptor (rtx rtl)
  {
    dw_loc_descr_ref loc_result = NULL;
  
--- 9167,9173 ----
     If we don't know how to describe it, return 0.  */
  
  static dw_loc_descr_ref
! loc_descriptor (rtx rtl, enum var_init_status initialized)
  {
    dw_loc_descr_ref loc_result = NULL;
  
*************** loc_descriptor (rtx rtl)
*** 9127,9152 ****
        /* ... fall through ...  */
  
      case REG:
!       loc_result = reg_loc_descriptor (rtl);
        break;
  
      case MEM:
!       loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl));
        break;
  
      case CONCAT:
!       loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1));
        break;
  
      case CONCATN:
!       loc_result = concatn_loc_descriptor (rtl);
        break;
  
      case VAR_LOCATION:
        /* Single part.  */
        if (GET_CODE (XEXP (rtl, 1)) != PARALLEL)
  	{
! 	  loc_result = loc_descriptor (XEXP (XEXP (rtl, 1), 0));
  	  break;
  	}
  
--- 9184,9211 ----
        /* ... fall through ...  */
  
      case REG:
!       loc_result = reg_loc_descriptor (rtl, initialized);
        break;
  
      case MEM:
!       loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl),
! 				       initialized);
        break;
  
      case CONCAT:
!       loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1),
! 					  initialized);
        break;
  
      case CONCATN:
!       loc_result = concatn_loc_descriptor (rtl, initialized);
        break;
  
      case VAR_LOCATION:
        /* Single part.  */
        if (GET_CODE (XEXP (rtl, 1)) != PARALLEL)
  	{
! 	  loc_result = loc_descriptor (XEXP (XEXP (rtl, 1), 0), initialized);
  	  break;
  	}
  
*************** loc_descriptor (rtx rtl)
*** 9161,9174 ****
  	int i;
  
  	/* Create the first one, so we have something to add to.  */
! 	loc_result = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0));
  	mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
  	add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
  	for (i = 1; i < num_elem; i++)
  	  {
  	    dw_loc_descr_ref temp;
  
! 	    temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0));
  	    add_loc_descr (&loc_result, temp);
  	    mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
  	    add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
--- 9220,9235 ----
  	int i;
  
  	/* Create the first one, so we have something to add to.  */
! 	loc_result = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0),
! 				     initialized);
  	mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
  	add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
  	for (i = 1; i < num_elem; i++)
  	  {
  	    dw_loc_descr_ref temp;
  
! 	    temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0),
! 				   initialized);
  	    add_loc_descr (&loc_result, temp);
  	    mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
  	    add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
*************** loc_descriptor_from_tree_1 (tree loc, in
*** 9300,9306 ****
  
  	    /* Certain constructs can only be represented at top-level.  */
  	    if (want_address == 2)
! 	      return loc_descriptor (rtl);
  
  	    mode = GET_MODE (rtl);
  	    if (MEM_P (rtl))
--- 9361,9367 ----
  
  	    /* Certain constructs can only be represented at top-level.  */
  	    if (want_address == 2)
! 	      return loc_descriptor (rtl, STATUS_INITIALIZED);
  
  	    mode = GET_MODE (rtl);
  	    if (MEM_P (rtl))
*************** loc_descriptor_from_tree_1 (tree loc, in
*** 9308,9314 ****
  		rtl = XEXP (rtl, 0);
  		have_address = 1;
  	      }
! 	    ret = mem_loc_descriptor (rtl, mode);
  	  }
        }
        break;
--- 9369,9375 ----
  		rtl = XEXP (rtl, 0);
  		have_address = 1;
  	      }
! 	    ret = mem_loc_descriptor (rtl, mode, STATUS_INITIALIZED);
  	  }
        }
        break;
*************** loc_descriptor_from_tree_1 (tree loc, in
*** 9389,9395 ****
  	  return 0;
  	mode = GET_MODE (rtl);
  	rtl = XEXP (rtl, 0);
! 	ret = mem_loc_descriptor (rtl, mode);
  	have_address = 1;
  	break;
        }
--- 9450,9456 ----
  	  return 0;
  	mode = GET_MODE (rtl);
  	rtl = XEXP (rtl, 0);
! 	ret = mem_loc_descriptor (rtl, mode, STATUS_INITIALIZED);
  	have_address = 1;
  	break;
        }
*************** add_location_or_const_value_attribute (d
*** 10475,10480 ****
--- 10536,10542 ----
        const char *endname, *secname;
        dw_loc_list_ref list;
        rtx varloc;
+       enum var_init_status initialized;
  
        /* Now that we know what section we are using for a base,
  	 actually construct the list of locations.
*************** add_location_or_const_value_attribute (d
*** 10491,10497 ****
        varloc = NOTE_VAR_LOCATION (node->var_loc_note);
        secname = secname_for_decl (decl);
  
!       list = new_loc_list (loc_descriptor (varloc),
  			   node->label, node->next->label, secname, 1);
        node = node->next;
  
--- 10553,10564 ----
        varloc = NOTE_VAR_LOCATION (node->var_loc_note);
        secname = secname_for_decl (decl);
  
!       if (NOTE_VAR_LOCATION_LOC (node->var_loc_note))
! 	initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
!       else
! 	initialized = STATUS_INITIALIZED;
! 
!       list = new_loc_list (loc_descriptor (varloc, initialized),
  			   node->label, node->next->label, secname, 1);
        node = node->next;
  
*************** add_location_or_const_value_attribute (d
*** 10500,10507 ****
  	  {
  	    /* The variable has a location between NODE->LABEL and
  	       NODE->NEXT->LABEL.  */
  	    varloc = NOTE_VAR_LOCATION (node->var_loc_note);
! 	    add_loc_descr_to_loc_list (&list, loc_descriptor (varloc),
  				       node->label, node->next->label, secname);
  	  }
  
--- 10567,10577 ----
  	  {
  	    /* The variable has a location between NODE->LABEL and
  	       NODE->NEXT->LABEL.  */
+ 	    enum var_init_status initialized =
+ 	      NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
  	    varloc = NOTE_VAR_LOCATION (node->var_loc_note);
! 	    add_loc_descr_to_loc_list (&list, 
! 				       loc_descriptor (varloc, initialized),
  				       node->label, node->next->label, secname);
  	  }
  
*************** add_location_or_const_value_attribute (d
*** 10510,10515 ****
--- 10580,10587 ----
        if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX)
  	{
  	  char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
+ 	  enum var_init_status initialized =
+ 	    NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
  
  	  varloc = NOTE_VAR_LOCATION (node->var_loc_note);
  	  if (!current_function_decl)
*************** add_location_or_const_value_attribute (d
*** 10520,10526 ****
  					   current_function_funcdef_no);
  	      endname = ggc_strdup (label_id);
  	    }
! 	  add_loc_descr_to_loc_list (&list, loc_descriptor (varloc),
  				     node->label, endname, secname);
  	}
  
--- 10592,10599 ----
  					   current_function_funcdef_no);
  	      endname = ggc_strdup (label_id);
  	    }
! 	  add_loc_descr_to_loc_list (&list, 
! 				     loc_descriptor (varloc, initialized),
  				     node->label, endname, secname);
  	}
  
*************** add_location_or_const_value_attribute (d
*** 10544,10551 ****
       location list, try generating a location from that.  */
    if (loc_list && loc_list->first)
      {
        node = loc_list->first;
!       descr = loc_descriptor (NOTE_VAR_LOCATION (node->var_loc_note));
        if (descr)
  	{
  	  add_AT_location_description (die, attr, descr);
--- 10617,10626 ----
       location list, try generating a location from that.  */
    if (loc_list && loc_list->first)
      {
+       enum var_init_status status;
        node = loc_list->first;
!       status = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
!       descr = loc_descriptor (NOTE_VAR_LOCATION (node->var_loc_note), status);
        if (descr)
  	{
  	  add_AT_location_description (die, attr, descr);
Index: gcc/dwarf2.h
===================================================================
*** gcc/dwarf2.h	(revision 124599)
--- gcc/dwarf2.h	(working copy)
*************** enum dwarf_location_atom
*** 540,545 ****
--- 540,547 ----
      DW_OP_bit_piece = 0x9d,
      /* GNU extensions.  */
      DW_OP_GNU_push_tls_address = 0xe0,
+     /* The following is for marking variables that are uninitialized.  */
+     DW_OP_GNU_uninit     = 0xf0,
      /* HP extensions.  */
      DW_OP_HP_unknown     = 0xe0, /* Ouch, the same as GNU_push_tls_address.  */
      DW_OP_HP_is_value    = 0xe1,
Index: gcc/print-rtl.c
===================================================================
*** gcc/print-rtl.c	(revision 124599)
--- gcc/print-rtl.c	(working copy)
*************** print_rtx (rtx in_rtx)
*** 325,330 ****
--- 325,332 ----
  		print_mem_expr (outfile, NOTE_VAR_LOCATION_DECL (in_rtx));
  		fprintf (outfile, " ");
  		print_rtx (NOTE_VAR_LOCATION_LOC (in_rtx));
+ 		if (NOTE_VAR_LOCATION_STATUS (in_rtx) == STATUS_UNINITIALIZED)
+ 		  fprintf (outfile, " [uninit]");
  		fprintf (outfile, ")");
  #endif
  		break;
Index: gcc/common.opt
===================================================================
*** gcc/common.opt	(revision 124599)
--- gcc/common.opt	(working copy)
*************** fvar-tracking
*** 1097,1102 ****
--- 1097,1106 ----
  Common Report Var(flag_var_tracking) VarExists Optimization
  Perform variable tracking
  
+ fvar-tracking-uninit
+ Common Report Var(flag_var_tracking_uninit) Optimization
+ Perform variable tracking and also tag variables that are uninitialized
+ 
  ftree-vectorize
  Common Report Var(flag_tree_vectorize) Optimization
  Enable loop vectorization on trees
Index: gcc/rtl.h
===================================================================
*** gcc/rtl.h	(revision 124599)
--- gcc/rtl.h	(working copy)
*************** extern const char * const reg_note_name[
*** 868,873 ****
--- 868,889 ----
  #define NOTE_VAR_LOCATION_LOC(INSN)	(XCEXP (XCEXP (INSN, 4, NOTE),  \
  						1, VAR_LOCATION))
  
+ /* Initialization status of the variable in the location.  Status
+    can be unknown, uninitialized or initialized.  See enumeration
+    type below.  */
+ #define NOTE_VAR_LOCATION_STATUS(INSN)  (XCINT (XCEXP (INSN, 4, NOTE), \
+ 						2, VAR_LOCATION))
+ 
+ /* Possible initialization status of a variable.   When requested
+    by the user, this information is tracked and recorded in the DWARF
+    debug information, along with the variable's location.  */
+ enum var_init_status
+ {
+   STATUS_UNKNOWN,
+   STATUS_UNINITIALIZED,
+   STATUS_INITIALIZED
+ };
+ 
  /* Codes that appear in the NOTE_LINE_NUMBER field for kinds of notes
     that are not line numbers.  These codes are all negative.
     
Index: gcc/var-tracking.c
===================================================================
*** gcc/var-tracking.c	(revision 124599)
--- gcc/var-tracking.c	(working copy)
*************** typedef struct location_chain_def
*** 219,224 ****
--- 219,230 ----
  
    /* The location (REG or MEM).  */
    rtx loc;
+ 
+   /* The "value" stored in this location.  */
+   rtx set_src;
+ 
+   /* Initialized? */
+   enum var_init_status init;
  } *location_chain;
  
  /* Structure describing one part of variable.  */
*************** static void attrs_list_copy (attrs *, at
*** 294,309 ****
  static void attrs_list_union (attrs *, attrs);
  
  static void vars_clear (htab_t);
! static variable unshare_variable (dataflow_set *set, variable var);
  static int vars_copy_1 (void **, void *);
  static void vars_copy (htab_t, htab_t);
  static tree var_debug_decl (tree);
! static void var_reg_set (dataflow_set *, rtx);
! static void var_reg_delete_and_set (dataflow_set *, rtx, bool);
  static void var_reg_delete (dataflow_set *, rtx, bool);
  static void var_regno_delete (dataflow_set *, int);
! static void var_mem_set (dataflow_set *, rtx);
! static void var_mem_delete_and_set (dataflow_set *, rtx, bool);
  static void var_mem_delete (dataflow_set *, rtx, bool);
  
  static void dataflow_set_init (dataflow_set *, int);
--- 300,318 ----
  static void attrs_list_union (attrs *, attrs);
  
  static void vars_clear (htab_t);
! static variable unshare_variable (dataflow_set *set, variable var, 
! 				  enum var_init_status);
  static int vars_copy_1 (void **, void *);
  static void vars_copy (htab_t, htab_t);
  static tree var_debug_decl (tree);
! static void var_reg_set (dataflow_set *, rtx, enum var_init_status, rtx);
! static void var_reg_delete_and_set (dataflow_set *, rtx, bool, 
! 				    enum var_init_status, rtx);
  static void var_reg_delete (dataflow_set *, rtx, bool);
  static void var_regno_delete (dataflow_set *, int);
! static void var_mem_set (dataflow_set *, rtx, enum var_init_status, rtx);
! static void var_mem_delete_and_set (dataflow_set *, rtx, bool, 
! 				    enum var_init_status, rtx);
  static void var_mem_delete (dataflow_set *, rtx, bool);
  
  static void dataflow_set_init (dataflow_set *, int);
*************** static void dump_dataflow_set (dataflow_
*** 338,345 ****
  static void dump_dataflow_sets (void);
  
  static void variable_was_changed (variable, htab_t);
! static void set_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
! static void clobber_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
  static void delete_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
  static int emit_note_insn_var_location (void **, void *);
  static void emit_notes_for_changes (rtx, enum emit_note_where);
--- 347,356 ----
  static void dump_dataflow_sets (void);
  
  static void variable_was_changed (variable, htab_t);
! static void set_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT, 
! 			       enum var_init_status, rtx);
! static void clobber_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT, 
! 				   rtx);
  static void delete_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
  static int emit_note_insn_var_location (void **, void *);
  static void emit_notes_for_changes (rtx, enum emit_note_where);
*************** vars_clear (htab_t vars)
*** 727,733 ****
  /* Return a copy of a variable VAR and insert it to dataflow set SET.  */
  
  static variable
! unshare_variable (dataflow_set *set, variable var)
  {
    void **slot;
    variable new_var;
--- 738,745 ----
  /* Return a copy of a variable VAR and insert it to dataflow set SET.  */
  
  static variable
! unshare_variable (dataflow_set *set, variable var, 
! 		  enum var_init_status initialized)
  {
    void **slot;
    variable new_var;
*************** unshare_variable (dataflow_set *set, var
*** 752,757 ****
--- 764,777 ----
  
  	  new_lc = pool_alloc (loc_chain_pool);
  	  new_lc->next = NULL;
+ 	  if (node->init > initialized)
+ 	    new_lc->init = node->init;
+ 	  else
+ 	    new_lc->init = initialized;
+ 	  if (node->set_src && !(MEM_P (node->set_src)))
+ 	    new_lc->set_src = node->set_src;
+ 	  else
+ 	    new_lc->set_src = NULL;
  	  new_lc->loc = node->loc;
  
  	  *nextp = new_lc;
*************** var_debug_decl (tree decl)
*** 819,825 ****
  /* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  */
  
  static void
! var_reg_set (dataflow_set *set, rtx loc)
  {
    tree decl = REG_EXPR (loc);
    HOST_WIDE_INT offset = REG_OFFSET (loc);
--- 839,846 ----
  /* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  */
  
  static void
! var_reg_set (dataflow_set *set, rtx loc, enum var_init_status initialized, 
! 	     rtx set_src)
  {
    tree decl = REG_EXPR (loc);
    HOST_WIDE_INT offset = REG_OFFSET (loc);
*************** var_reg_set (dataflow_set *set, rtx loc)
*** 832,838 ****
        break;
    if (!node)
      attrs_list_insert (&set->regs[REGNO (loc)], decl, offset, loc);
!   set_variable_part (set, loc, decl, offset);
  }
  
  /* Delete current content of register LOC in dataflow set SET and set
--- 853,890 ----
        break;
    if (!node)
      attrs_list_insert (&set->regs[REGNO (loc)], decl, offset, loc);
!   set_variable_part (set, loc, decl, offset, initialized, set_src);
! }
! 
! static int
! get_init_value (dataflow_set *set, rtx loc, tree decl)
! {
!   void **slot;
!   variable var;
!   int i;
!   int ret_val = STATUS_UNKNOWN;
! 
!   if (! flag_var_tracking_uninit)
!     return STATUS_INITIALIZED;
! 
!   slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl),
! 				   NO_INSERT);
!   if (slot)
!     {
!       var = * (variable *) slot;
!       for (i = 0; i < var->n_var_parts && ret_val == STATUS_UNKNOWN; i++)
! 	{
! 	  location_chain nextp;
! 	  for (nextp = var->var_part[i].loc_chain; nextp; nextp = nextp->next)
! 	    if (rtx_equal_p (nextp->loc, loc))
! 	      {
! 		ret_val = nextp->init;
! 		break;
! 	      }
! 	}
!     }
! 
!   return ret_val;
  }
  
  /* Delete current content of register LOC in dataflow set SET and set
*************** var_reg_set (dataflow_set *set, rtx loc)
*** 843,849 ****
     part.  */
  
  static void
! var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify)
  {
    tree decl = REG_EXPR (loc);
    HOST_WIDE_INT offset = REG_OFFSET (loc);
--- 895,902 ----
     part.  */
  
  static void
! var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify, 
! 			enum var_init_status initialized, rtx set_src)
  {
    tree decl = REG_EXPR (loc);
    HOST_WIDE_INT offset = REG_OFFSET (loc);
*************** var_reg_delete_and_set (dataflow_set *se
*** 852,857 ****
--- 905,913 ----
  
    decl = var_debug_decl (decl);
  
+   if (initialized == STATUS_UNKNOWN)
+     initialized = get_init_value (set, loc, decl);
+ 
    nextp = &set->regs[REGNO (loc)];
    for (node = *nextp; node; node = next)
      {
*************** var_reg_delete_and_set (dataflow_set *se
*** 869,876 ****
  	}
      }
    if (modify)
!     clobber_variable_part (set, loc, decl, offset);
!   var_reg_set (set, loc);
  }
  
  /* Delete current content of register LOC in dataflow set SET.  If
--- 925,932 ----
  	}
      }
    if (modify)
!     clobber_variable_part (set, loc, decl, offset, set_src);
!   var_reg_set (set, loc, initialized, set_src);
  }
  
  /* Delete current content of register LOC in dataflow set SET.  If
*************** var_reg_delete (dataflow_set *set, rtx l
*** 890,896 ****
  
        decl = var_debug_decl (decl);
  
!       clobber_variable_part (set, NULL, decl, offset);
      }
  
    for (node = *reg; node; node = next)
--- 946,952 ----
  
        decl = var_debug_decl (decl);
  
!       clobber_variable_part (set, NULL, decl, offset, NULL);
      }
  
    for (node = *reg; node; node = next)
*************** var_regno_delete (dataflow_set *set, int
*** 924,937 ****
     Adjust the address first if it is stack pointer based.  */
  
  static void
! var_mem_set (dataflow_set *set, rtx loc)
  {
    tree decl = MEM_EXPR (loc);
    HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
  
    decl = var_debug_decl (decl);
  
!   set_variable_part (set, loc, decl, offset);
  }
  
  /* Delete and set the location part of variable MEM_EXPR (LOC) in
--- 980,994 ----
     Adjust the address first if it is stack pointer based.  */
  
  static void
! var_mem_set (dataflow_set *set, rtx loc, enum var_init_status initialized, 
! 	     rtx set_src)
  {
    tree decl = MEM_EXPR (loc);
    HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
  
    decl = var_debug_decl (decl);
  
!   set_variable_part (set, loc, decl, offset, initialized, set_src);
  }
  
  /* Delete and set the location part of variable MEM_EXPR (LOC) in
*************** var_mem_set (dataflow_set *set, rtx loc)
*** 942,957 ****
     Adjust the address first if it is stack pointer based.  */
  
  static void
! var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify)
  {
    tree decl = MEM_EXPR (loc);
    HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
  
    decl = var_debug_decl (decl);
  
    if (modify)
!     clobber_variable_part (set, NULL, decl, offset);
!   var_mem_set (set, loc);
  }
  
  /* Delete the location part LOC from dataflow set SET.  If CLOBBER is
--- 999,1018 ----
     Adjust the address first if it is stack pointer based.  */
  
  static void
! var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify, 
! 			enum var_init_status initialized, rtx set_src)
  {
    tree decl = MEM_EXPR (loc);
    HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
  
    decl = var_debug_decl (decl);
  
+   if (initialized == STATUS_UNKNOWN)
+     initialized = get_init_value (set, loc, decl);
+ 
    if (modify)
!     clobber_variable_part (set, NULL, decl, offset, set_src);
!   var_mem_set (set, loc, initialized, set_src);
  }
  
  /* Delete the location part LOC from dataflow set SET.  If CLOBBER is
*************** var_mem_delete (dataflow_set *set, rtx l
*** 966,972 ****
  
    decl = var_debug_decl (decl);
    if (clobber)
!     clobber_variable_part (set, NULL, decl, offset);
    delete_variable_part (set, loc, decl, offset);
  }
  
--- 1027,1033 ----
  
    decl = var_debug_decl (decl);
    if (clobber)
!     clobber_variable_part (set, NULL, decl, offset, NULL);
    delete_variable_part (set, loc, decl, offset);
  }
  
*************** variable_union (void **slot, void *data)
*** 1078,1084 ****
  	    }
  	}
        if (k < src->n_var_parts)
! 	unshare_variable (set, src);
        else
  	*dstp = src;
  
--- 1139,1152 ----
  	    }
  	}
        if (k < src->n_var_parts)
! 	{
! 	  enum var_init_status status = STATUS_UNKNOWN;
! 	  
! 	  if (! flag_var_tracking_uninit)
! 	    status = STATUS_INITIALIZED;
! 
! 	  unshare_variable (set, src, status);
! 	}
        else
  	*dstp = src;
  
*************** variable_union (void **slot, void *data)
*** 1112,1118 ****
    gcc_assert (k <= MAX_VAR_PARTS);
  
    if (dst->refcount > 1 && dst->n_var_parts != k)
!     dst = unshare_variable (set, dst);
  
    i = src->n_var_parts - 1;
    j = dst->n_var_parts - 1;
--- 1180,1192 ----
    gcc_assert (k <= MAX_VAR_PARTS);
  
    if (dst->refcount > 1 && dst->n_var_parts != k)
!     {
!       enum var_init_status status = STATUS_UNKNOWN;
!       
!       if (! flag_var_tracking_uninit)
! 	status = STATUS_INITIALIZED;
!       dst = unshare_variable (set, dst, status);
!     }
  
    i = src->n_var_parts - 1;
    j = dst->n_var_parts - 1;
*************** variable_union (void **slot, void *data)
*** 1145,1154 ****
  			 && REG_P (node->loc)
  			 && REGNO (node2->loc) == REGNO (node->loc))
  			|| rtx_equal_p (node2->loc, node->loc)))
  		    break;
  		}
  	      if (node || node2)
! 		dst = unshare_variable (set, dst);
  	    }
  
  	  src_l = 0;
--- 1219,1230 ----
  			 && REG_P (node->loc)
  			 && REGNO (node2->loc) == REGNO (node->loc))
  			|| rtx_equal_p (node2->loc, node->loc)))
+ 		    if (node2->init < node->init)
+ 		      node2->init = node->init;
  		    break;
  		}
  	      if (node || node2)
! 		dst = unshare_variable (set, dst, STATUS_UNKNOWN);
  	    }
  
  	  src_l = 0;
*************** variable_union (void **slot, void *data)
*** 1194,1199 ****
--- 1270,1280 ----
  		  /* Copy the location from SRC.  */
  		  new_node = pool_alloc (loc_chain_pool);
  		  new_node->loc = node->loc;
+ 		  new_node->init = node->init;
+ 		  if (!node->set_src || MEM_P (node->set_src))
+ 		    new_node->set_src = NULL;
+ 		  else
+ 		    new_node->set_src = node->set_src;
  		  vui[n].lc = new_node;
  		  vui[n].pos_src = ii;
  		  vui[n].pos_dst = src_l + dst_l;
*************** variable_union (void **slot, void *data)
*** 1240,1245 ****
--- 1321,1331 ----
  
  	      new_lc = pool_alloc (loc_chain_pool);
  	      new_lc->next = NULL;
+ 	      new_lc->init = node->init;
+ 	      if (!node->set_src || MEM_P (node->set_src))
+ 		new_lc->set_src = NULL;
+ 	      else
+ 		new_lc->set_src = node->set_src;
  	      new_lc->loc = node->loc;
  
  	      *nextp = new_lc;
*************** variable_union (void **slot, void *data)
*** 1258,1263 ****
--- 1344,1361 ----
  	dst->var_part[k].cur_loc = NULL;
      }
  
+   for (i = 0; i < src->n_var_parts && i < dst->n_var_parts; i++)
+     {
+       location_chain node, node2;
+       for (node = src->var_part[i].loc_chain; node; node = node->next)
+ 	for (node2 = dst->var_part[i].loc_chain; node2; node2 = node2->next)
+ 	  if (rtx_equal_p (node->loc, node2->loc))
+ 	    {
+ 	      if (node->init > node2->init)
+ 		node2->init = node->init;
+ 	    }
+     }
+ 
    /* Continue traversing the hash table.  */
    return 1;
  }
*************** add_stores (rtx loc, rtx expr, void *ins
*** 1679,1685 ****
        else
  	mo->type = MO_SET;
        mo->u.loc = loc;
!       mo->insn = NEXT_INSN ((rtx) insn);
      }
    else if (MEM_P (loc)
  	   && MEM_EXPR (loc)
--- 1777,1783 ----
        else
  	mo->type = MO_SET;
        mo->u.loc = loc;
!       mo->insn = (rtx) insn;
      }
    else if (MEM_P (loc)
  	   && MEM_EXPR (loc)
*************** add_stores (rtx loc, rtx expr, void *ins
*** 1700,1707 ****
        else
  	mo->type = MO_SET;
        mo->u.loc = loc;
!       mo->insn = NEXT_INSN ((rtx) insn);
      }
  }
  
  /* Compute the changes of variable locations in the basic block BB.  */
--- 1798,1894 ----
        else
  	mo->type = MO_SET;
        mo->u.loc = loc;
!       mo->insn = (rtx) insn;
!     }
! }
! 
! static enum var_init_status
! find_src_status (dataflow_set *in, rtx loc, rtx insn)
! {
!   rtx src = NULL_RTX;
!   tree decl = NULL_TREE;
!   enum var_init_status status = STATUS_UNINITIALIZED;
! 
!   if (! flag_var_tracking_uninit)
!     status = STATUS_INITIALIZED;
! 
!   if (GET_CODE (PATTERN (insn)) == SET)
!     src = SET_SRC (PATTERN (insn));
!   else if (GET_CODE (PATTERN (insn)) == PARALLEL
! 	   || GET_CODE (PATTERN (insn)) == SEQUENCE)
!     {
!       int i;
!       for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
! 	if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
! 	    && SET_DEST (XVECEXP (PATTERN (insn), 0, i)) == loc)
! 	  src = SET_SRC (XVECEXP (PATTERN (insn), 0, i));
      }
+ 
+   if (REG_P (src))
+     decl = var_debug_decl (REG_EXPR (src));
+   else if (MEM_P (src))
+     decl = var_debug_decl (MEM_EXPR (src));
+ 
+   if (src && decl)
+     status = get_init_value (in, src, decl);
+ 
+   return status;
+ }
+ 
+ /* LOC is the destination the variable is being copied to.  INSN 
+    contains the copy instruction.  SET is the dataflow set containing
+    the variable in LOC.  */
+ 
+ static rtx
+ find_src_set_src (dataflow_set *set, rtx loc, rtx insn)
+ {
+   tree decl = NULL_TREE;   /* The variable being copied around.          */
+   rtx src = NULL_RTX;      /* The location "decl" is being copied from.  */
+   rtx set_src = NULL_RTX;  /* The value for "decl" stored in "src".      */
+   void **slot;
+   variable var;
+   location_chain nextp;
+   int i;
+   bool found;
+ 
+   if (GET_CODE (PATTERN (insn)) == SET)
+     src = SET_SRC (PATTERN (insn));
+   else if (GET_CODE (PATTERN (insn)) == PARALLEL
+ 	   || GET_CODE (PATTERN (insn)) == SEQUENCE)
+     {
+       for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
+ 	if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
+ 	    && SET_DEST (XVECEXP (PATTERN (insn), 0, i)) == loc)
+ 	  src = SET_SRC (XVECEXP (PATTERN (insn), 0, i));
+     }
+ 
+   if (REG_P (src))
+     decl = var_debug_decl (REG_EXPR (src));
+   else if (MEM_P (src))
+     decl = var_debug_decl (MEM_EXPR (src));
+ 
+   if (src && decl)
+     {
+       slot = htab_find_slot_with_hash (set->vars, decl, 
+ 				       VARIABLE_HASH_VAL (decl), NO_INSERT);
+ 
+       if (slot)
+ 	{
+ 	  var = *(variable *) slot;
+ 	  found = false;
+ 	  for (i = 0; i < var->n_var_parts && !found; i++)
+ 	    for (nextp = var->var_part[i].loc_chain; nextp && !found; 
+ 		 nextp = nextp->next)
+ 	      if (rtx_equal_p (nextp->loc, src))
+ 		{
+ 		  set_src = nextp->set_src;
+ 		  found = true;
+ 		}
+ 	      
+ 	}
+     }
+ 
+   return set_src;
  }
  
  /* Compute the changes of variable locations in the basic block BB.  */
*************** compute_bb_dataflow (basic_block bb)
*** 1733,1765 ****
  	  case MO_USE:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
  
  	      if (GET_CODE (loc) == REG)
! 		var_reg_set (out, loc);
  	      else if (GET_CODE (loc) == MEM)
! 		var_mem_set (out, loc);
  	    }
  	    break;
  
  	  case MO_SET:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
  
  	      if (REG_P (loc))
! 		var_reg_delete_and_set (out, loc, true);
  	      else if (MEM_P (loc))
! 		var_mem_delete_and_set (out, loc, true);
  	    }
  	    break;
  
  	  case MO_COPY:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
  
  	      if (REG_P (loc))
! 		var_reg_delete_and_set (out, loc, false);
  	      else if (MEM_P (loc))
! 		var_mem_delete_and_set (out, loc, false);
  	    }
  	    break;
  
--- 1920,1984 ----
  	  case MO_USE:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
+ 	      enum var_init_status status = STATUS_UNINITIALIZED;
+ 
+ 	      if (! flag_var_tracking_uninit)
+ 		status = STATUS_INITIALIZED;
  
  	      if (GET_CODE (loc) == REG)
! 		var_reg_set (out, loc, status, NULL);
  	      else if (GET_CODE (loc) == MEM)
! 		var_mem_set (out, loc, status, NULL);
  	    }
  	    break;
  
  	  case MO_SET:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
+ 	      rtx set_src =  NULL;
+ 	      rtx insn = VTI (bb)->mos[i].insn;
+ 
+ 	      if (GET_CODE (PATTERN (insn)) == SET)
+ 		set_src = SET_SRC (PATTERN (insn));
+ 	      else if (GET_CODE (PATTERN (insn)) == PARALLEL
+ 		       || GET_CODE (PATTERN (insn)) == SEQUENCE)
+ 		{
+ 		  int j;
+ 		  for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
+ 		    if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
+ 			&& SET_DEST (XVECEXP (PATTERN (insn), 0, j)) == loc)
+ 		      set_src = SET_SRC (XVECEXP (PATTERN (insn), 0, j));
+ 		}
  
  	      if (REG_P (loc))
! 		var_reg_delete_and_set (out, loc, true, STATUS_INITIALIZED,
! 					set_src);
  	      else if (MEM_P (loc))
! 		var_mem_delete_and_set (out, loc, true, STATUS_INITIALIZED,
! 					set_src);
  	    }
  	    break;
  
  	  case MO_COPY:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
+ 	      enum var_init_status src_status;
+ 	      rtx set_src;
+ 
+ 	      if (! flag_var_tracking_uninit)
+ 		src_status = STATUS_INITIALIZED;
+ 	      else
+ 		src_status = find_src_status (in, loc, VTI (bb)->mos[i].insn);
+ 
+ 	      if (src_status == STATUS_UNKNOWN)
+ 		src_status = find_src_status (out, loc, VTI (bb)->mos[i].insn);
+ 
+ 	      set_src = find_src_set_src (in, loc, VTI (bb)->mos[i].insn);
  
  	      if (REG_P (loc))
! 		var_reg_delete_and_set (out, loc, false, src_status, set_src);
  	      else if (MEM_P (loc))
! 		var_mem_delete_and_set (out, loc, false, src_status, set_src);
  	    }
  	    break;
  
*************** dump_variable (void **slot, void *data A
*** 1932,1937 ****
--- 2151,2158 ----
        for (node = var->var_part[i].loc_chain; node; node = node->next)
  	{
  	  fprintf (dump_file, "      ");
+ 	  if (node->init == STATUS_UNINITIALIZED)
+ 	    fprintf (dump_file, "[uninit]");
  	  print_rtl_single (dump_file, node->loc);
  	}
      }
*************** find_variable_location_part (variable va
*** 2077,2083 ****
     part's location by LOC.  */
  
  static void
! set_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset)
  {
    int pos;
    location_chain node, next;
--- 2298,2305 ----
     part's location by LOC.  */
  
  static void
! set_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset,
! 		   enum var_init_status initialized, rtx set_src)
  {
    int pos;
    location_chain node, next;
*************** set_variable_part (dataflow_set *set, rt
*** 2119,2131 ****
  	    {
  	      /* LOC is in the beginning of the chain so we have nothing
  		 to do.  */
  	      return;
  	    }
  	  else
  	    {
  	      /* We have to make a copy of a shared variable.  */
  	      if (var->refcount > 1)
! 		var = unshare_variable (set, var);
  	    }
  	}
        else
--- 2341,2359 ----
  	    {
  	      /* LOC is in the beginning of the chain so we have nothing
  		 to do.  */
+ 	      if (node->init < initialized)
+ 		node->init = initialized;
+ 	      if (set_src != NULL)
+ 		node->set_src = set_src;
+ 
+ 	      *slot = var;
  	      return;
  	    }
  	  else
  	    {
  	      /* We have to make a copy of a shared variable.  */
  	      if (var->refcount > 1)
! 		var = unshare_variable (set, var, initialized);
  	    }
  	}
        else
*************** set_variable_part (dataflow_set *set, rt
*** 2134,2140 ****
  
  	  /* We have to make a copy of the shared variable.  */
  	  if (var->refcount > 1)
! 	    var = unshare_variable (set, var);
  
  	  /* We track only variables whose size is <= MAX_VAR_PARTS bytes
  	     thus there are at most MAX_VAR_PARTS different offsets.  */
--- 2362,2368 ----
  
  	  /* We have to make a copy of the shared variable.  */
  	  if (var->refcount > 1)
! 	    var = unshare_variable (set, var, initialized);
  
  	  /* We track only variables whose size is <= MAX_VAR_PARTS bytes
  	     thus there are at most MAX_VAR_PARTS different offsets.  */
*************** set_variable_part (dataflow_set *set, rt
*** 2161,2166 ****
--- 2389,2400 ----
  	   && REGNO (node->loc) == REGNO (loc))
  	  || rtx_equal_p (node->loc, loc))
  	{
+ 	  /* Save these values, to assign to the new node, before
+ 	     deleting this one.  */
+ 	  if (node->init > initialized)
+ 	    initialized = node->init;
+ 	  if (node->set_src != NULL && set_src == NULL)
+ 	    set_src = node->set_src;
  	  pool_free (loc_chain_pool, node);
  	  *nextp = next;
  	  break;
*************** set_variable_part (dataflow_set *set, rt
*** 2172,2177 ****
--- 2406,2413 ----
    /* Add the location to the beginning.  */
    node = pool_alloc (loc_chain_pool);
    node->loc = loc;
+   node->init = initialized;
+   node->set_src = set_src;
    node->next = var->var_part[pos].loc_chain;
    var->var_part[pos].loc_chain = node;
  
*************** set_variable_part (dataflow_set *set, rt
*** 2190,2196 ****
  
  static void
  clobber_variable_part (dataflow_set *set, rtx loc, tree decl,
! 		      HOST_WIDE_INT offset)
  {
    void **slot;
  
--- 2426,2432 ----
  
  static void
  clobber_variable_part (dataflow_set *set, rtx loc, tree decl,
! 		       HOST_WIDE_INT offset, rtx set_src)
  {
    void **slot;
  
*************** clobber_variable_part (dataflow_set *set
*** 2213,2219 ****
  	  for (node = next; node; node = next)
  	    {
  	      next = node->next;
! 	      if (node->loc != loc)
  		{
  		  if (REG_P (node->loc))
  		    {
--- 2449,2459 ----
  	  for (node = next; node; node = next)
  	    {
  	      next = node->next;
! 	      if (node->loc != loc 
! 		  && (!(flag_var_tracking_uninit)
! 		      || !set_src 
! 		      || MEM_P (set_src)
! 		      || !rtx_equal_p (set_src, node->set_src)))
  		{
  		  if (REG_P (node->loc))
  		    {
*************** delete_variable_part (dataflow_set *set,
*** 2278,2284 ****
  		       && REGNO (node->loc) == REGNO (loc))
  		      || rtx_equal_p (node->loc, loc))
  		    {
! 		      var = unshare_variable (set, var);
  		      break;
  		    }
  		}
--- 2518,2527 ----
  		       && REGNO (node->loc) == REGNO (loc))
  		      || rtx_equal_p (node->loc, loc))
  		    {
! 		      enum var_init_status status = STATUS_UNKNOWN;
! 		      if (! flag_var_tracking_uninit)
! 			status = STATUS_INITIALIZED;
! 		      var = unshare_variable (set, var, status);
  		      break;
  		    }
  		}
*************** emit_note_insn_var_location (void **varp
*** 2345,2350 ****
--- 2588,2594 ----
    rtx note;
    int i, j, n_var_parts;
    bool complete;
+   enum var_init_status initialized = STATUS_UNINITIALIZED;
    HOST_WIDE_INT last_limit;
    tree type_size_unit;
    HOST_WIDE_INT offsets[MAX_VAR_PARTS];
*************** emit_note_insn_var_location (void **varp
*** 2352,2357 ****
--- 2596,2604 ----
  
    gcc_assert (var->decl);
  
+   if (! flag_var_tracking_uninit)
+     initialized = STATUS_INITIALIZED;
+ 
    complete = true;
    last_limit = 0;
    n_var_parts = 0;
*************** emit_note_insn_var_location (void **varp
*** 2369,2374 ****
--- 2616,2622 ----
        offsets[n_var_parts] = var->var_part[i].offset;
        loc[n_var_parts] = var->var_part[i].loc_chain->loc;
        mode = GET_MODE (loc[n_var_parts]);
+       initialized = var->var_part[i].loc_chain->init;
        last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
  
        /* Attempt to merge adjacent registers or memory.  */
*************** emit_note_insn_var_location (void **varp
*** 2448,2457 ****
    else
      note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
  
    if (!complete)
      {
        NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
! 						       NULL_RTX);
      }
    else if (n_var_parts == 1)
      {
--- 2696,2708 ----
    else
      note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
  
+   if (!(flag_var_tracking_uninit))
+     initialized = STATUS_INITIALIZED;
+ 
    if (!complete)
      {
        NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
! 						       NULL_RTX, 0);
      }
    else if (n_var_parts == 1)
      {
*************** emit_note_insn_var_location (void **varp
*** 2459,2465 ****
  	= gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
  
        NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
! 						       expr_list);
      }
    else if (n_var_parts)
      {
--- 2710,2717 ----
  	= gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
  
        NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
! 						       expr_list, 
! 						       (int) initialized);
      }
    else if (n_var_parts)
      {
*************** emit_note_insn_var_location (void **varp
*** 2472,2480 ****
        parallel = gen_rtx_PARALLEL (VOIDmode,
  				   gen_rtvec_v (n_var_parts, loc));
        NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
! 						       parallel);
      }
  
    htab_clear_slot (changed_variables, varp);
  
    /* When there are no location parts the variable has been already
--- 2724,2735 ----
        parallel = gen_rtx_PARALLEL (VOIDmode,
  				   gen_rtvec_v (n_var_parts, loc));
        NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
! 						       parallel, 
! 						       (int) initialized);
      }
  
+   NOTE_VAR_LOCATION_STATUS (note) = (int) initialized;
+ 
    htab_clear_slot (changed_variables, varp);
  
    /* When there are no location parts the variable has been already
*************** emit_notes_in_bb (basic_block bb)
*** 2603,2613 ****
  	  case MO_USE:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
! 
  	      if (GET_CODE (loc) == REG)
! 		var_reg_set (&set, loc);
  	      else
! 		var_mem_set (&set, loc);
  
  	      emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
  	    }
--- 2858,2871 ----
  	  case MO_USE:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
!       
! 	      enum var_init_status status = STATUS_UNINITIALIZED;
! 	      if (! flag_var_tracking_uninit)
! 		status = STATUS_INITIALIZED;
  	      if (GET_CODE (loc) == REG)
! 		var_reg_set (&set, loc, status, NULL);
  	      else
! 		var_mem_set (&set, loc, status, NULL);
  
  	      emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
  	    }
*************** emit_notes_in_bb (basic_block bb)
*** 2616,2641 ****
  	  case MO_SET:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
  
  	      if (REG_P (loc))
! 		var_reg_delete_and_set (&set, loc, true);
  	      else
! 		var_mem_delete_and_set (&set, loc, true);
  
! 	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
  	    }
  	    break;
  
  	  case MO_COPY:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
  
  	      if (REG_P (loc))
! 		var_reg_delete_and_set (&set, loc, false);
  	      else
! 		var_mem_delete_and_set (&set, loc, false);
  
! 	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
  	    }
  	    break;
  
--- 2874,2919 ----
  	  case MO_SET:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
+ 	      rtx set_src =  NULL;
+ 
+ 	      if (GET_CODE (PATTERN (insn)) == SET)
+ 		set_src = SET_SRC (PATTERN (insn));
+ 	      else if (GET_CODE (PATTERN (insn)) == PARALLEL
+ 		       || GET_CODE (PATTERN (insn)) == SEQUENCE)
+ 		{
+ 		  int j;
+ 		  for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
+ 		    if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
+ 			&& SET_DEST (XVECEXP (PATTERN (insn), 0, j)) == loc)
+ 		      set_src = SET_SRC (XVECEXP (PATTERN (insn), 0, j));
+ 		}
  
  	      if (REG_P (loc))
! 		var_reg_delete_and_set (&set, loc, true, STATUS_INITIALIZED, 
! 					set_src);
  	      else
! 		var_mem_delete_and_set (&set, loc, true, STATUS_INITIALIZED, 
! 					set_src);
  
! 	      emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN);
  	    }
  	    break;
  
  	  case MO_COPY:
  	    {
  	      rtx loc = VTI (bb)->mos[i].u.loc;
+ 	      enum var_init_status src_status;
+ 	      rtx set_src;
+ 
+ 	      src_status = find_src_status (&set, loc, VTI (bb)->mos[i].insn);
+ 	      set_src = find_src_set_src (&set, loc, VTI (bb)->mos[i].insn);
  
  	      if (REG_P (loc))
! 		var_reg_delete_and_set (&set, loc, false, src_status, set_src);
  	      else
! 		var_mem_delete_and_set (&set, loc, false, src_status, set_src);
  
! 	      emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN);
  	    }
  	    break;
  
*************** emit_notes_in_bb (basic_block bb)
*** 2661,2667 ****
  	      else
  		var_mem_delete (&set, loc, true);
  
! 	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
  	    }
  	    break;
  
--- 2939,2945 ----
  	      else
  		var_mem_delete (&set, loc, true);
  
! 	      emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN);
  	    }
  	    break;
  
*************** vt_add_function_parameters (void)
*** 2777,2786 ****
  	  gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
  	  attrs_list_insert (&out->regs[REGNO (incoming)],
  			     parm, offset, incoming);
! 	  set_variable_part (out, incoming, parm, offset);
  	}
        else if (MEM_P (incoming))
! 	set_variable_part (out, incoming, parm, offset);
      }
  }
  
--- 3055,3066 ----
  	  gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
  	  attrs_list_insert (&out->regs[REGNO (incoming)],
  			     parm, offset, incoming);
! 	  set_variable_part (out, incoming, parm, offset, STATUS_INITIALIZED, 
! 			     NULL);
  	}
        else if (MEM_P (incoming))
! 	set_variable_part (out, incoming, parm, offset, STATUS_INITIALIZED, 
! 			   NULL);
      }
  }
  
Index: gcc/config/darwin.c
===================================================================
*** gcc/config/darwin.c	(revision 124599)
--- gcc/config/darwin.c	(working copy)
*************** darwin_override_options (void)
*** 1721,1726 ****
--- 1721,1729 ----
        /* No -fnon-call-exceptions data in kexts.  */
        flag_non_call_exceptions = 0;
      }
+   if (flag_var_tracking
+       && strverscmp (darwin_macosx_version_min, "10.5") >= 0)
+     flag_var_tracking_uninit = 1;
  }
  
  #include "gt-darwin.h"

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Ping!  [PATCH, revised]: Track uninitialized variables
  2007-05-11 19:13 ` [PATCH, revised]: " Caroline Tice
@ 2007-05-18 19:48   ` Caroline Tice
  2007-05-25 21:26     ` Ping2! " Caroline Tice
  2007-07-11 14:45   ` Ian Lance Taylor
  1 sibling, 1 reply; 25+ messages in thread
From: Caroline Tice @ 2007-05-18 19:48 UTC (permalink / raw)
  To: gcc-patches@gcc.gnu.org Patches; +Cc: Caroline Tice

As a point of interest:  The GDB side of this patch has been accepted  
and
committed to FSF GDB.

-- Caroline

On May 11, 2007, at 12:13 PM, Caroline Tice wrote:

> Here is a revised version of my patch for tracking uninitialized
> variables (see description in original posting copied below).  I added
> the comments Ian asked for, and I changed the way it is turned on/off.
> Instead of the macro in my previous patch, it is now controlled by a
> command line option, -fvar-tracking-uninit, which turns on
> var-tracking, just like -fvar-tracking, but also turns on the
> uninitialized variable tracking.  I added the same feasibility  
> checks to
> it that are used for -fvar-tracking.  I also turned it on by default
> on darwin systems running 10.5 or later (when var-tracking is on).
>
> I tested this patch by bootstrapping it and running the dejagnu
> testsuite without any regressions, on a ppc running apple-darwin, an
> x86 running apple-darwin, and an x86 64 running 64-bit linux.  I also
> ran it on a small test case containing uninitialized variables, to
> verify that it turns on when the command line option is passed, or
> when running on the correct version of darwin, and is off at all other
> times.
>
> Is this patch okay to commit to mainline?
>
> --Caroline Tice
> ctice@apple.com
>
>
> On May 1, 2007, at 5:02 PM, Caroline Tice wrote:
>
>>
>> As part of some work I've been doing on improving debugging of
>> optimized code, I have developed the following patch which, while
>> tracking the locations of variables, also keeps track of whether the
>> variables are initialized or not (it makes conservative assumptions
>> where it can't be sure).  For those places where it is sure the
>> variables are unintialized, it adds an annotation to the
>> var_location_note, which the dwarf writer later translates to a new
>> DW_OP (an extension) that indicates a variable is uninitialized
>> (DW_OP_GNU_uninit).
>
>> Since this work requires that GDB be able to read and do something
>> reasonable with the new DW_OP, I have also created a GDB patch to  
>> deal
>> with the new op, and to inform the user that a particular value is
>> unintialized when the user asks to see it.  As the two patches really
>> go together, I am attaching both of them to this message.  (I will
>> also be sending the GDB patch to the gdb patches list).
>
>> Because using the new DW_OP is sensitive to whether or not the user
>> has a version of GDB that can handle it, I have added a macro,
>> TARGET_DWARF_UNINIT_VARS, which defaults to 0, and which controls
>> whether the uninitialized variable tracking is done.
>
>> I have bootstrapped and run the dejagnu testsuite on this patch, with
>> no regressions, on a ppc running apple-darwin, an x86 running
>> apple-darwin, and an x86 64 running 64-bit linux.
>
>> Is this patch okay to commit to mainline?
>> -- Caroline Tice
>> ctice@apple.com
>>
>
> 2007-05-11  Caroline Tice  <ctice@apple.com>
>
>        * toplev.c (process_options): Turn flag_var_tracking_uninit  
> off when
>        flag_var_tracking is explicitly turned off (i.e. when variable
>        tracking is not feasible); otherwise, turn flag_var_tracking  
> on when
>        flag_var_tracking_uninit is on.
>        * rtl.def (VAR_LOCATION): Add a new integer subfield to  
> VAR_LOCATION
>        note definitions, to allow recording of initialization status  
> in the
>        notes.
>        * dwarf2out.c (dwarf_stack_op_name): Add case for  
> DW_OP_GNU_uninit.
>        (add_var_loc_to_decl): Add comparison of  
> NOTE_VAR_LOCATION_STATUS to
>        determine if two note locations are equal.
>        (output_loc_list): Don't output list entries whose start &  
> end labels
>        are the same.
>        (reg_loc_descriptor): Add parameter for initialization  
> status; pass it
>        to other loc descriptor functions.
>        (one_reg_loc_descriptor): Add parameter for initialization  
> status;
>        check its value and add DW_OP_GNU_uninit to returned loc  
> descr if
>        appropriate.
>        (multiple_reg_loc_descriptor): Add parameter for initialization
>        status;
>        pass init status argument to other loc descriptor functions;  
> check
>        value of intialization parameter and add DW_OP_GNU_uninit to  
> returned
>        loc descr if appropriate.
>        (based_loc_descr): Add parameter for initialization status;  
> add new
>        variable for return value; check value of initialization  
> parameter and
>        add DW_OP_GNU_uninit to returned loc descr if appropriate.
>        (concatn_mem_loc_descriptor): Add parameter for  
> initialization status;
>        pass init status argument to other loc descriptor functions;  
> check
>        value of intialization parameter and add DW_OP_GNU_uninit to  
> returned
>        loc descr if appropriate.
>        (mem_loc_descriptor): Likewise.
>        (concat_loc_descriptor): Likewise.
>        (concatn_loc_descriptor): Likewise.
>        (loc_descriptor): Add parameter for initialization status;  
> pass it as
>        argument to other loc descriptor function calls.
>        (loc_descriptor_from_tree_1): Add appropriate initialization  
> status
>        to loc descriptor function calls.
>        (add_location_or_const_value_attribute): Get initialization  
> status
>        from VAR_LOCATION note; add initialization status to loc  
> descriptor
>        function calls.
>        * dwarf2.h (enum dwarf_location_atom): New op,  
> DW_OP_GNU_uninit.
>        * print-rtl.c (print_rtx): When printing a VAR_LOCATION note,  
> if
>        status is uninitialized, add "[uninint]" to output.
>        * common.opt (fvar-tracking-uninit): New option, similar to
>        fvar-tracking, to turn on tracking of uninitialized  
> variables; creates
>        a new global flag, flag_var_tracking_uninit.
>        * rtl.h (NOTE_VAR_LOCATION_STATUS): New macro for accessing  
> new field.
>        (enum var_init_status): New type, for var initialization  
> status field.
>        * var-tracking.c (struct location_chain_def): Two new fields,  
> init,
>        for initialization status, and set_src for the assignment  
> value expr.
>        (unshare_variable): New parameter for initialization status;
>        initialize new init and set_src fields.
>        (var_reg_set): New parameters for initialization status and  
> value;
>        pass them to set_variable_part.
>        (var_mem_set): Likewise.
>        (get_init_value): New function.
>        (var_reg_delete_and_set): New initialization status & value
>        parameters; add call to get_init_value if status is unknown;  
> pass new
>        parameters to clobber_variable_part and var_reg_set.
>        (var_mem_delete_and_set): Likewise.
>        (var_reg_delete): Pass null set_src value to  
> clobber_variable_part.
>        (var_mem_delete): Likewise.
>        (variable_union): Pass status to unshare_variable; initialize  
> new init
>        and set_src fields.  If flag_var_tracking_uninit is not set,  
> force
>        status to initialized.
>        (add_stores): Store insn, rather than NEXT_INSN(insn), so it  
> can be
>        used later to get the set_src value.
>        (find_src_status): New function.
>        (find_src_set_src): New function.
>        (compute_bb_dataflow): Pass init status to calls to  
> var_reg_set,
>        var_mem_set, var_reg_delete_and_set and  
> var_mem_delete_and_set; for
>        MO_SET, get set_src value and pass it to   
> var_reg_delete_and_set
>        and var_mem_delete_and_set.
>        (dump_variable):  Print out "[uninit]" if appropriate.
>        (set_variable_part): Add new initialization and set_src  
> parameters;
>        pass status to unshare_variable; set node->init and node- 
> >set_src
>        fields and modify slot in hash table appropriately; save the  
> init and
>        set_src values if appropriate and assign to the new node.
>        (clobber_variable_part): New set_src parameter; if two nodes  
> have
>        same variable and same location but different set_src  
> (assignment)
>        values, clobber old node.
>        (delete_variable_part): Pass init status to unshare_variable.
>        (emit_note_insn_var_location): Add initialized var; assign  
> var's init
>        status to new 'initialized'; pass new init status field to  
> calls to
>        gen_rtx_VAR_LOCATION.  If flag_var_tracking_uninit is not  
> set, force
>        status to initialized.
>        (emit_notes_in_bb): Pass initialization status to calls to
>        var_reg_set, var_mem_set, var_reg_delete_and_set and
>        var_mem_delete_and_set; for MO_SET, get set_src value and  
> pass it to
>        var_reg_delete_and_set and var_mem_delete_and_set; call
>        emit_notes_for_changes on NEXT_INSN(insn) rather than on  
> insn, to
>        make up for change in add_stores.
>        (vt_add_function_parameters): Add status to calls to
>        set_variable_part.
>        * config/darwin.c (darwin_override_options): Turn on  
> uninitialized
>        tracking automatically, if var_tracking is on and the system is
>        10.5 or higher.
>
>
> <fsf-gcc-patch.v2.txt>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Ping2!  [PATCH, revised]: Track uninitialized variables
  2007-05-18 19:48   ` Ping! " Caroline Tice
@ 2007-05-25 21:26     ` Caroline Tice
  2007-06-01 16:59       ` Ping3! " Caroline Tice
  0 siblings, 1 reply; 25+ messages in thread
From: Caroline Tice @ 2007-05-25 21:26 UTC (permalink / raw)
  To: gcc-patches@gcc.gnu.org Patches; +Cc: Caroline Tice


On May 18, 2007, at 12:48 PM, Caroline Tice wrote:

> As a point of interest:  The GDB side of this patch has been  
> accepted and
> committed to FSF GDB.
>
> -- Caroline
>
> On May 11, 2007, at 12:13 PM, Caroline Tice wrote:
>
>> Here is a revised version of my patch for tracking uninitialized
>> variables (see description in original posting copied below).  I  
>> added
>> the comments Ian asked for, and I changed the way it is turned on/ 
>> off.
>> Instead of the macro in my previous patch, it is now controlled by a
>> command line option, -fvar-tracking-uninit, which turns on
>> var-tracking, just like -fvar-tracking, but also turns on the
>> uninitialized variable tracking.  I added the same feasibility  
>> checks to
>> it that are used for -fvar-tracking.  I also turned it on by default
>> on darwin systems running 10.5 or later (when var-tracking is on).
>>
>> I tested this patch by bootstrapping it and running the dejagnu
>> testsuite without any regressions, on a ppc running apple-darwin, an
>> x86 running apple-darwin, and an x86 64 running 64-bit linux.  I also
>> ran it on a small test case containing uninitialized variables, to
>> verify that it turns on when the command line option is passed, or
>> when running on the correct version of darwin, and is off at all  
>> other
>> times.
>>
>> Is this patch okay to commit to mainline?
>>
>> --Caroline Tice
>> ctice@apple.com
>>
>>
>> On May 1, 2007, at 5:02 PM, Caroline Tice wrote:
>>
>>>
>>> As part of some work I've been doing on improving debugging of
>>> optimized code, I have developed the following patch which, while
>>> tracking the locations of variables, also keeps track of whether the
>>> variables are initialized or not (it makes conservative assumptions
>>> where it can't be sure).  For those places where it is sure the
>>> variables are unintialized, it adds an annotation to the
>>> var_location_note, which the dwarf writer later translates to a new
>>> DW_OP (an extension) that indicates a variable is uninitialized
>>> (DW_OP_GNU_uninit).
>>
>>> Since this work requires that GDB be able to read and do something
>>> reasonable with the new DW_OP, I have also created a GDB patch to  
>>> deal
>>> with the new op, and to inform the user that a particular value is
>>> unintialized when the user asks to see it.  As the two patches  
>>> really
>>> go together, I am attaching both of them to this message.  (I will
>>> also be sending the GDB patch to the gdb patches list).
>>
>>> Because using the new DW_OP is sensitive to whether or not the user
>>> has a version of GDB that can handle it, I have added a macro,
>>> TARGET_DWARF_UNINIT_VARS, which defaults to 0, and which controls
>>> whether the uninitialized variable tracking is done.
>>
>>> I have bootstrapped and run the dejagnu testsuite on this patch,  
>>> with
>>> no regressions, on a ppc running apple-darwin, an x86 running
>>> apple-darwin, and an x86 64 running 64-bit linux.
>>
>>> Is this patch okay to commit to mainline?
>>> -- Caroline Tice
>>> ctice@apple.com
>>>
>>
>> 2007-05-11  Caroline Tice  <ctice@apple.com>
>>
>>       * toplev.c (process_options): Turn flag_var_tracking_uninit  
>> off when
>>       flag_var_tracking is explicitly turned off (i.e. when variable
>>       tracking is not feasible); otherwise, turn flag_var_tracking  
>> on when
>>       flag_var_tracking_uninit is on.
>>       * rtl.def (VAR_LOCATION): Add a new integer subfield to  
>> VAR_LOCATION
>>       note definitions, to allow recording of initialization status  
>> in the
>>       notes.
>>       * dwarf2out.c (dwarf_stack_op_name): Add case for  
>> DW_OP_GNU_uninit.
>>       (add_var_loc_to_decl): Add comparison of  
>> NOTE_VAR_LOCATION_STATUS to
>>       determine if two note locations are equal.
>>       (output_loc_list): Don't output list entries whose start &  
>> end labels
>>       are the same.
>>       (reg_loc_descriptor): Add parameter for initialization  
>> status; pass it
>>       to other loc descriptor functions.
>>       (one_reg_loc_descriptor): Add parameter for initialization  
>> status;
>>       check its value and add DW_OP_GNU_uninit to returned loc  
>> descr if
>>       appropriate.
>>       (multiple_reg_loc_descriptor): Add parameter for initialization
>>       status;
>>       pass init status argument to other loc descriptor functions;  
>> check
>>       value of intialization parameter and add DW_OP_GNU_uninit to  
>> returned
>>       loc descr if appropriate.
>>       (based_loc_descr): Add parameter for initialization status;  
>> add new
>>       variable for return value; check value of initialization  
>> parameter and
>>       add DW_OP_GNU_uninit to returned loc descr if appropriate.
>>       (concatn_mem_loc_descriptor): Add parameter for  
>> initialization status;
>>       pass init status argument to other loc descriptor functions;  
>> check
>>       value of intialization parameter and add DW_OP_GNU_uninit to  
>> returned
>>       loc descr if appropriate.
>>       (mem_loc_descriptor): Likewise.
>>       (concat_loc_descriptor): Likewise.
>>       (concatn_loc_descriptor): Likewise.
>>       (loc_descriptor): Add parameter for initialization status;  
>> pass it as
>>       argument to other loc descriptor function calls.
>>       (loc_descriptor_from_tree_1): Add appropriate initialization  
>> status
>>       to loc descriptor function calls.
>>       (add_location_or_const_value_attribute): Get initialization  
>> status
>>       from VAR_LOCATION note; add initialization status to loc  
>> descriptor
>>       function calls.
>>       * dwarf2.h (enum dwarf_location_atom): New op,  
>> DW_OP_GNU_uninit.
>>       * print-rtl.c (print_rtx): When printing a VAR_LOCATION note,  
>> if
>>       status is uninitialized, add "[uninint]" to output.
>>       * common.opt (fvar-tracking-uninit): New option, similar to
>>       fvar-tracking, to turn on tracking of uninitialized  
>> variables; creates
>>       a new global flag, flag_var_tracking_uninit.
>>       * rtl.h (NOTE_VAR_LOCATION_STATUS): New macro for accessing  
>> new field.
>>       (enum var_init_status): New type, for var initialization  
>> status field.
>>       * var-tracking.c (struct location_chain_def): Two new fields,  
>> init,
>>       for initialization status, and set_src for the assignment  
>> value expr.
>>       (unshare_variable): New parameter for initialization status;
>>       initialize new init and set_src fields.
>>       (var_reg_set): New parameters for initialization status and  
>> value;
>>       pass them to set_variable_part.
>>       (var_mem_set): Likewise.
>>       (get_init_value): New function.
>>       (var_reg_delete_and_set): New initialization status & value
>>       parameters; add call to get_init_value if status is unknown;  
>> pass new
>>       parameters to clobber_variable_part and var_reg_set.
>>       (var_mem_delete_and_set): Likewise.
>>       (var_reg_delete): Pass null set_src value to  
>> clobber_variable_part.
>>       (var_mem_delete): Likewise.
>>       (variable_union): Pass status to unshare_variable; initialize  
>> new init
>>       and set_src fields.  If flag_var_tracking_uninit is not set,  
>> force
>>       status to initialized.
>>       (add_stores): Store insn, rather than NEXT_INSN(insn), so it  
>> can be
>>       used later to get the set_src value.
>>       (find_src_status): New function.
>>       (find_src_set_src): New function.
>>       (compute_bb_dataflow): Pass init status to calls to  
>> var_reg_set,
>>       var_mem_set, var_reg_delete_and_set and  
>> var_mem_delete_and_set; for
>>       MO_SET, get set_src value and pass it to   
>> var_reg_delete_and_set
>>       and var_mem_delete_and_set.
>>       (dump_variable):  Print out "[uninit]" if appropriate.
>>       (set_variable_part): Add new initialization and set_src  
>> parameters;
>>       pass status to unshare_variable; set node->init and node- 
>> >set_src
>>       fields and modify slot in hash table appropriately; save the  
>> init and
>>       set_src values if appropriate and assign to the new node.
>>       (clobber_variable_part): New set_src parameter; if two nodes  
>> have
>>       same variable and same location but different set_src  
>> (assignment)
>>       values, clobber old node.
>>       (delete_variable_part): Pass init status to unshare_variable.
>>       (emit_note_insn_var_location): Add initialized var; assign  
>> var's init
>>       status to new 'initialized'; pass new init status field to  
>> calls to
>>       gen_rtx_VAR_LOCATION.  If flag_var_tracking_uninit is not  
>> set, force
>>       status to initialized.
>>       (emit_notes_in_bb): Pass initialization status to calls to
>>       var_reg_set, var_mem_set, var_reg_delete_and_set and
>>       var_mem_delete_and_set; for MO_SET, get set_src value and  
>> pass it to
>>       var_reg_delete_and_set and var_mem_delete_and_set; call
>>       emit_notes_for_changes on NEXT_INSN(insn) rather than on  
>> insn, to
>>       make up for change in add_stores.
>>       (vt_add_function_parameters): Add status to calls to
>>       set_variable_part.
>>       * config/darwin.c (darwin_override_options): Turn on  
>> uninitialized
>>       tracking automatically, if var_tracking is on and the system is
>>       10.5 or higher.
>>
>>
>> <fsf-gcc-patch.v2.txt>
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Ping3!  [PATCH, revised]: Track uninitialized variables
  2007-05-25 21:26     ` Ping2! " Caroline Tice
@ 2007-06-01 16:59       ` Caroline Tice
  2007-06-01 17:13         ` Manuel López-Ibáñez
  0 siblings, 1 reply; 25+ messages in thread
From: Caroline Tice @ 2007-06-01 16:59 UTC (permalink / raw)
  To: gcc-patches@gcc.gnu.org Patches; +Cc: Caroline Tice


Still waiting to be reviewed...

On May 25, 2007, at 1:53 PM, Caroline Tice wrote:

>
> On May 18, 2007, at 12:48 PM, Caroline Tice wrote:
>
>> As a point of interest:  The GDB side of this patch has been  
>> accepted and
>> committed to FSF GDB.
>>
>> -- Caroline
>>
>> On May 11, 2007, at 12:13 PM, Caroline Tice wrote:
>>
>>> Here is a revised version of my patch for tracking uninitialized
>>> variables (see description in original posting copied below).  I  
>>> added
>>> the comments Ian asked for, and I changed the way it is turned on/ 
>>> off.
>>> Instead of the macro in my previous patch, it is now controlled by a
>>> command line option, -fvar-tracking-uninit, which turns on
>>> var-tracking, just like -fvar-tracking, but also turns on the
>>> uninitialized variable tracking.  I added the same feasibility  
>>> checks to
>>> it that are used for -fvar-tracking.  I also turned it on by default
>>> on darwin systems running 10.5 or later (when var-tracking is on).
>>>
>>> I tested this patch by bootstrapping it and running the dejagnu
>>> testsuite without any regressions, on a ppc running apple-darwin, an
>>> x86 running apple-darwin, and an x86 64 running 64-bit linux.  I  
>>> also
>>> ran it on a small test case containing uninitialized variables, to
>>> verify that it turns on when the command line option is passed, or
>>> when running on the correct version of darwin, and is off at all  
>>> other
>>> times.
>>>
>>> Is this patch okay to commit to mainline?
>>>
>>> --Caroline Tice
>>> ctice@apple.com
>>>
>>>
>>> On May 1, 2007, at 5:02 PM, Caroline Tice wrote:
>>>
>>>>
>>>> As part of some work I've been doing on improving debugging of
>>>> optimized code, I have developed the following patch which, while
>>>> tracking the locations of variables, also keeps track of whether  
>>>> the
>>>> variables are initialized or not (it makes conservative assumptions
>>>> where it can't be sure).  For those places where it is sure the
>>>> variables are unintialized, it adds an annotation to the
>>>> var_location_note, which the dwarf writer later translates to a new
>>>> DW_OP (an extension) that indicates a variable is uninitialized
>>>> (DW_OP_GNU_uninit).
>>>
>>>> Since this work requires that GDB be able to read and do something
>>>> reasonable with the new DW_OP, I have also created a GDB patch to  
>>>> deal
>>>> with the new op, and to inform the user that a particular value is
>>>> unintialized when the user asks to see it.  As the two patches  
>>>> really
>>>> go together, I am attaching both of them to this message.  (I will
>>>> also be sending the GDB patch to the gdb patches list).
>>>
>>>> Because using the new DW_OP is sensitive to whether or not the user
>>>> has a version of GDB that can handle it, I have added a macro,
>>>> TARGET_DWARF_UNINIT_VARS, which defaults to 0, and which controls
>>>> whether the uninitialized variable tracking is done.
>>>
>>>> I have bootstrapped and run the dejagnu testsuite on this patch,  
>>>> with
>>>> no regressions, on a ppc running apple-darwin, an x86 running
>>>> apple-darwin, and an x86 64 running 64-bit linux.
>>>
>>>> Is this patch okay to commit to mainline?
>>>> -- Caroline Tice
>>>> ctice@apple.com
>>>>
>>>
>>> 2007-05-11  Caroline Tice  <ctice@apple.com>
>>>
>>>      * toplev.c (process_options): Turn flag_var_tracking_uninit  
>>> off when
>>>      flag_var_tracking is explicitly turned off (i.e. when variable
>>>      tracking is not feasible); otherwise, turn flag_var_tracking  
>>> on when
>>>      flag_var_tracking_uninit is on.
>>>      * rtl.def (VAR_LOCATION): Add a new integer subfield to  
>>> VAR_LOCATION
>>>      note definitions, to allow recording of initialization status  
>>> in the
>>>      notes.
>>>      * dwarf2out.c (dwarf_stack_op_name): Add case for  
>>> DW_OP_GNU_uninit.
>>>      (add_var_loc_to_decl): Add comparison of  
>>> NOTE_VAR_LOCATION_STATUS to
>>>      determine if two note locations are equal.
>>>      (output_loc_list): Don't output list entries whose start &  
>>> end labels
>>>      are the same.
>>>      (reg_loc_descriptor): Add parameter for initialization  
>>> status; pass it
>>>      to other loc descriptor functions.
>>>      (one_reg_loc_descriptor): Add parameter for initialization  
>>> status;
>>>      check its value and add DW_OP_GNU_uninit to returned loc  
>>> descr if
>>>      appropriate.
>>>      (multiple_reg_loc_descriptor): Add parameter for initialization
>>>      status;
>>>      pass init status argument to other loc descriptor functions;  
>>> check
>>>      value of intialization parameter and add DW_OP_GNU_uninit to  
>>> returned
>>>      loc descr if appropriate.
>>>      (based_loc_descr): Add parameter for initialization status;  
>>> add new
>>>      variable for return value; check value of initialization  
>>> parameter and
>>>      add DW_OP_GNU_uninit to returned loc descr if appropriate.
>>>      (concatn_mem_loc_descriptor): Add parameter for  
>>> initialization status;
>>>      pass init status argument to other loc descriptor functions;  
>>> check
>>>      value of intialization parameter and add DW_OP_GNU_uninit to  
>>> returned
>>>      loc descr if appropriate.
>>>      (mem_loc_descriptor): Likewise.
>>>      (concat_loc_descriptor): Likewise.
>>>      (concatn_loc_descriptor): Likewise.
>>>      (loc_descriptor): Add parameter for initialization status;  
>>> pass it as
>>>      argument to other loc descriptor function calls.
>>>      (loc_descriptor_from_tree_1): Add appropriate initialization  
>>> status
>>>      to loc descriptor function calls.
>>>      (add_location_or_const_value_attribute): Get initialization  
>>> status
>>>      from VAR_LOCATION note; add initialization status to loc  
>>> descriptor
>>>      function calls.
>>>      * dwarf2.h (enum dwarf_location_atom): New op,  
>>> DW_OP_GNU_uninit.
>>>      * print-rtl.c (print_rtx): When printing a VAR_LOCATION note,  
>>> if
>>>      status is uninitialized, add "[uninint]" to output.
>>>      * common.opt (fvar-tracking-uninit): New option, similar to
>>>      fvar-tracking, to turn on tracking of uninitialized  
>>> variables; creates
>>>      a new global flag, flag_var_tracking_uninit.
>>>      * rtl.h (NOTE_VAR_LOCATION_STATUS): New macro for accessing  
>>> new field.
>>>      (enum var_init_status): New type, for var initialization  
>>> status field.
>>>      * var-tracking.c (struct location_chain_def): Two new fields,  
>>> init,
>>>      for initialization status, and set_src for the assignment  
>>> value expr.
>>>      (unshare_variable): New parameter for initialization status;
>>>      initialize new init and set_src fields.
>>>      (var_reg_set): New parameters for initialization status and  
>>> value;
>>>      pass them to set_variable_part.
>>>      (var_mem_set): Likewise.
>>>      (get_init_value): New function.
>>>      (var_reg_delete_and_set): New initialization status & value
>>>      parameters; add call to get_init_value if status is unknown;  
>>> pass new
>>>      parameters to clobber_variable_part and var_reg_set.
>>>      (var_mem_delete_and_set): Likewise.
>>>      (var_reg_delete): Pass null set_src value to  
>>> clobber_variable_part.
>>>      (var_mem_delete): Likewise.
>>>      (variable_union): Pass status to unshare_variable; initialize  
>>> new init
>>>      and set_src fields.  If flag_var_tracking_uninit is not set,  
>>> force
>>>      status to initialized.
>>>      (add_stores): Store insn, rather than NEXT_INSN(insn), so it  
>>> can be
>>>      used later to get the set_src value.
>>>      (find_src_status): New function.
>>>      (find_src_set_src): New function.
>>>      (compute_bb_dataflow): Pass init status to calls to  
>>> var_reg_set,
>>>      var_mem_set, var_reg_delete_and_set and  
>>> var_mem_delete_and_set; for
>>>      MO_SET, get set_src value and pass it to   
>>> var_reg_delete_and_set
>>>      and var_mem_delete_and_set.
>>>      (dump_variable):  Print out "[uninit]" if appropriate.
>>>      (set_variable_part): Add new initialization and set_src  
>>> parameters;
>>>      pass status to unshare_variable; set node->init and node- 
>>> >set_src
>>>      fields and modify slot in hash table appropriately; save the  
>>> init and
>>>      set_src values if appropriate and assign to the new node.
>>>      (clobber_variable_part): New set_src parameter; if two nodes  
>>> have
>>>      same variable and same location but different set_src  
>>> (assignment)
>>>      values, clobber old node.
>>>      (delete_variable_part): Pass init status to unshare_variable.
>>>      (emit_note_insn_var_location): Add initialized var; assign  
>>> var's init
>>>      status to new 'initialized'; pass new init status field to  
>>> calls to
>>>      gen_rtx_VAR_LOCATION.  If flag_var_tracking_uninit is not  
>>> set, force
>>>      status to initialized.
>>>      (emit_notes_in_bb): Pass initialization status to calls to
>>>      var_reg_set, var_mem_set, var_reg_delete_and_set and
>>>      var_mem_delete_and_set; for MO_SET, get set_src value and  
>>> pass it to
>>>      var_reg_delete_and_set and var_mem_delete_and_set; call
>>>      emit_notes_for_changes on NEXT_INSN(insn) rather than on  
>>> insn, to
>>>      make up for change in add_stores.
>>>      (vt_add_function_parameters): Add status to calls to
>>>      set_variable_part.
>>>      * config/darwin.c (darwin_override_options): Turn on  
>>> uninitialized
>>>      tracking automatically, if var_tracking is on and the system is
>>>      10.5 or higher.
>>>
>>>
>>> <fsf-gcc-patch.v2.txt>
>>
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Ping3! [PATCH, revised]: Track uninitialized variables
  2007-06-01 16:59       ` Ping3! " Caroline Tice
@ 2007-06-01 17:13         ` Manuel López-Ibáñez
  2007-06-01 17:24           ` Caroline Tice
  0 siblings, 1 reply; 25+ messages in thread
From: Manuel López-Ibáñez @ 2007-06-01 17:13 UTC (permalink / raw)
  To: Caroline Tice; +Cc: GCC Patches

Hi Caroline,

I think that giving a link to the original mail in the archives will
increase the chances of getting a reviewer. And as a rule of thumb,
anything that makes easier the life of a reviewer will increase the
chances of getting a patch reviewed.

Cheers,

Manuel.

On 01/06/07, Caroline Tice <ctice@apple.com> wrote:
>
> Still waiting to be reviewed...
>
> On May 25, 2007, at 1:53 PM, Caroline Tice wrote:
>
> >
> > On May 18, 2007, at 12:48 PM, Caroline Tice wrote:
> >
> >> As a point of interest:  The GDB side of this patch has been
> >> accepted and
> >> committed to FSF GDB.
> >>
> >> -- Caroline
> >>
> >> On May 11, 2007, at 12:13 PM, Caroline Tice wrote:
> >>
> >>> Here is a revised version of my patch for tracking uninitialized
> >>> variables (see description in original posting copied below).  I
> >>> added
> >>> the comments Ian asked for, and I changed the way it is turned on/
> >>> off.
> >>> Instead of the macro in my previous patch, it is now controlled by a
> >>> command line option, -fvar-tracking-uninit, which turns on
> >>> var-tracking, just like -fvar-tracking, but also turns on the
> >>> uninitialized variable tracking.  I added the same feasibility
> >>> checks to
> >>> it that are used for -fvar-tracking.  I also turned it on by default
> >>> on darwin systems running 10.5 or later (when var-tracking is on).
> >>>
> >>> I tested this patch by bootstrapping it and running the dejagnu
> >>> testsuite without any regressions, on a ppc running apple-darwin, an
> >>> x86 running apple-darwin, and an x86 64 running 64-bit linux.  I
> >>> also
> >>> ran it on a small test case containing uninitialized variables, to
> >>> verify that it turns on when the command line option is passed, or
> >>> when running on the correct version of darwin, and is off at all
> >>> other
> >>> times.
> >>>
> >>> Is this patch okay to commit to mainline?
> >>>
> >>> --Caroline Tice
> >>> ctice@apple.com
> >>>
> >>>
> >>> On May 1, 2007, at 5:02 PM, Caroline Tice wrote:
> >>>
> >>>>
> >>>> As part of some work I've been doing on improving debugging of
> >>>> optimized code, I have developed the following patch which, while
> >>>> tracking the locations of variables, also keeps track of whether
> >>>> the
> >>>> variables are initialized or not (it makes conservative assumptions
> >>>> where it can't be sure).  For those places where it is sure the
> >>>> variables are unintialized, it adds an annotation to the
> >>>> var_location_note, which the dwarf writer later translates to a new
> >>>> DW_OP (an extension) that indicates a variable is uninitialized
> >>>> (DW_OP_GNU_uninit).
> >>>
> >>>> Since this work requires that GDB be able to read and do something
> >>>> reasonable with the new DW_OP, I have also created a GDB patch to
> >>>> deal
> >>>> with the new op, and to inform the user that a particular value is
> >>>> unintialized when the user asks to see it.  As the two patches
> >>>> really
> >>>> go together, I am attaching both of them to this message.  (I will
> >>>> also be sending the GDB patch to the gdb patches list).
> >>>
> >>>> Because using the new DW_OP is sensitive to whether or not the user
> >>>> has a version of GDB that can handle it, I have added a macro,
> >>>> TARGET_DWARF_UNINIT_VARS, which defaults to 0, and which controls
> >>>> whether the uninitialized variable tracking is done.
> >>>
> >>>> I have bootstrapped and run the dejagnu testsuite on this patch,
> >>>> with
> >>>> no regressions, on a ppc running apple-darwin, an x86 running
> >>>> apple-darwin, and an x86 64 running 64-bit linux.
> >>>
> >>>> Is this patch okay to commit to mainline?
> >>>> -- Caroline Tice
> >>>> ctice@apple.com
> >>>>
> >>>
> >>> 2007-05-11  Caroline Tice  <ctice@apple.com>
> >>>
> >>>      * toplev.c (process_options): Turn flag_var_tracking_uninit
> >>> off when
> >>>      flag_var_tracking is explicitly turned off (i.e. when variable
> >>>      tracking is not feasible); otherwise, turn flag_var_tracking
> >>> on when
> >>>      flag_var_tracking_uninit is on.
> >>>      * rtl.def (VAR_LOCATION): Add a new integer subfield to
> >>> VAR_LOCATION
> >>>      note definitions, to allow recording of initialization status
> >>> in the
> >>>      notes.
> >>>      * dwarf2out.c (dwarf_stack_op_name): Add case for
> >>> DW_OP_GNU_uninit.
> >>>      (add_var_loc_to_decl): Add comparison of
> >>> NOTE_VAR_LOCATION_STATUS to
> >>>      determine if two note locations are equal.
> >>>      (output_loc_list): Don't output list entries whose start &
> >>> end labels
> >>>      are the same.
> >>>      (reg_loc_descriptor): Add parameter for initialization
> >>> status; pass it
> >>>      to other loc descriptor functions.
> >>>      (one_reg_loc_descriptor): Add parameter for initialization
> >>> status;
> >>>      check its value and add DW_OP_GNU_uninit to returned loc
> >>> descr if
> >>>      appropriate.
> >>>      (multiple_reg_loc_descriptor): Add parameter for initialization
> >>>      status;
> >>>      pass init status argument to other loc descriptor functions;
> >>> check
> >>>      value of intialization parameter and add DW_OP_GNU_uninit to
> >>> returned
> >>>      loc descr if appropriate.
> >>>      (based_loc_descr): Add parameter for initialization status;
> >>> add new
> >>>      variable for return value; check value of initialization
> >>> parameter and
> >>>      add DW_OP_GNU_uninit to returned loc descr if appropriate.
> >>>      (concatn_mem_loc_descriptor): Add parameter for
> >>> initialization status;
> >>>      pass init status argument to other loc descriptor functions;
> >>> check
> >>>      value of intialization parameter and add DW_OP_GNU_uninit to
> >>> returned
> >>>      loc descr if appropriate.
> >>>      (mem_loc_descriptor): Likewise.
> >>>      (concat_loc_descriptor): Likewise.
> >>>      (concatn_loc_descriptor): Likewise.
> >>>      (loc_descriptor): Add parameter for initialization status;
> >>> pass it as
> >>>      argument to other loc descriptor function calls.
> >>>      (loc_descriptor_from_tree_1): Add appropriate initialization
> >>> status
> >>>      to loc descriptor function calls.
> >>>      (add_location_or_const_value_attribute): Get initialization
> >>> status
> >>>      from VAR_LOCATION note; add initialization status to loc
> >>> descriptor
> >>>      function calls.
> >>>      * dwarf2.h (enum dwarf_location_atom): New op,
> >>> DW_OP_GNU_uninit.
> >>>      * print-rtl.c (print_rtx): When printing a VAR_LOCATION note,
> >>> if
> >>>      status is uninitialized, add "[uninint]" to output.
> >>>      * common.opt (fvar-tracking-uninit): New option, similar to
> >>>      fvar-tracking, to turn on tracking of uninitialized
> >>> variables; creates
> >>>      a new global flag, flag_var_tracking_uninit.
> >>>      * rtl.h (NOTE_VAR_LOCATION_STATUS): New macro for accessing
> >>> new field.
> >>>      (enum var_init_status): New type, for var initialization
> >>> status field.
> >>>      * var-tracking.c (struct location_chain_def): Two new fields,
> >>> init,
> >>>      for initialization status, and set_src for the assignment
> >>> value expr.
> >>>      (unshare_variable): New parameter for initialization status;
> >>>      initialize new init and set_src fields.
> >>>      (var_reg_set): New parameters for initialization status and
> >>> value;
> >>>      pass them to set_variable_part.
> >>>      (var_mem_set): Likewise.
> >>>      (get_init_value): New function.
> >>>      (var_reg_delete_and_set): New initialization status & value
> >>>      parameters; add call to get_init_value if status is unknown;
> >>> pass new
> >>>      parameters to clobber_variable_part and var_reg_set.
> >>>      (var_mem_delete_and_set): Likewise.
> >>>      (var_reg_delete): Pass null set_src value to
> >>> clobber_variable_part.
> >>>      (var_mem_delete): Likewise.
> >>>      (variable_union): Pass status to unshare_variable; initialize
> >>> new init
> >>>      and set_src fields.  If flag_var_tracking_uninit is not set,
> >>> force
> >>>      status to initialized.
> >>>      (add_stores): Store insn, rather than NEXT_INSN(insn), so it
> >>> can be
> >>>      used later to get the set_src value.
> >>>      (find_src_status): New function.
> >>>      (find_src_set_src): New function.
> >>>      (compute_bb_dataflow): Pass init status to calls to
> >>> var_reg_set,
> >>>      var_mem_set, var_reg_delete_and_set and
> >>> var_mem_delete_and_set; for
> >>>      MO_SET, get set_src value and pass it to
> >>> var_reg_delete_and_set
> >>>      and var_mem_delete_and_set.
> >>>      (dump_variable):  Print out "[uninit]" if appropriate.
> >>>      (set_variable_part): Add new initialization and set_src
> >>> parameters;
> >>>      pass status to unshare_variable; set node->init and node-
> >>> >set_src
> >>>      fields and modify slot in hash table appropriately; save the
> >>> init and
> >>>      set_src values if appropriate and assign to the new node.
> >>>      (clobber_variable_part): New set_src parameter; if two nodes
> >>> have
> >>>      same variable and same location but different set_src
> >>> (assignment)
> >>>      values, clobber old node.
> >>>      (delete_variable_part): Pass init status to unshare_variable.
> >>>      (emit_note_insn_var_location): Add initialized var; assign
> >>> var's init
> >>>      status to new 'initialized'; pass new init status field to
> >>> calls to
> >>>      gen_rtx_VAR_LOCATION.  If flag_var_tracking_uninit is not
> >>> set, force
> >>>      status to initialized.
> >>>      (emit_notes_in_bb): Pass initialization status to calls to
> >>>      var_reg_set, var_mem_set, var_reg_delete_and_set and
> >>>      var_mem_delete_and_set; for MO_SET, get set_src value and
> >>> pass it to
> >>>      var_reg_delete_and_set and var_mem_delete_and_set; call
> >>>      emit_notes_for_changes on NEXT_INSN(insn) rather than on
> >>> insn, to
> >>>      make up for change in add_stores.
> >>>      (vt_add_function_parameters): Add status to calls to
> >>>      set_variable_part.
> >>>      * config/darwin.c (darwin_override_options): Turn on
> >>> uninitialized
> >>>      tracking automatically, if var_tracking is on and the system is
> >>>      10.5 or higher.
> >>>
> >>>
> >>> <fsf-gcc-patch.v2.txt>
> >>
> >
>
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Ping3! [PATCH, revised]: Track uninitialized variables
  2007-06-01 17:13         ` Manuel López-Ibáñez
@ 2007-06-01 17:24           ` Caroline Tice
  2007-06-08 17:52             ` Ping 4! " Caroline Tice
  0 siblings, 1 reply; 25+ messages in thread
From: Caroline Tice @ 2007-06-01 17:24 UTC (permalink / raw)
  To: GCC Patches; +Cc: Caroline Tice

Thank you for the suggestion.  The link to the original
posting for this unreviewed patch is:

http://gcc.gnu.org/ml/gcc-patches/2007-05/msg01240.html

On Jun 1, 2007, at 10:13 AM, Manuel López-Ibáñez wrote:

> Hi Caroline,
>
> I think that giving a link to the original mail in the archives will
> increase the chances of getting a reviewer. And as a rule of thumb,
> anything that makes easier the life of a reviewer will increase the
> chances of getting a patch reviewed.
>
> Cheers,
>
> Manuel.
>
> On 01/06/07, Caroline Tice <ctice@apple.com> wrote:
>>
>> Still waiting to be reviewed...
>>
>> On May 25, 2007, at 1:53 PM, Caroline Tice wrote:
>>
>> >
>> > On May 18, 2007, at 12:48 PM, Caroline Tice wrote:
>> >
>> >> As a point of interest:  The GDB side of this patch has been
>> >> accepted and
>> >> committed to FSF GDB.
>> >>
>> >> -- Caroline
>> >>
>> >> On May 11, 2007, at 12:13 PM, Caroline Tice wrote:
>> >>
>> >>> Here is a revised version of my patch for tracking uninitialized
>> >>> variables (see description in original posting copied below).  I
>> >>> added
>> >>> the comments Ian asked for, and I changed the way it is turned  
>> on/
>> >>> off.
>> >>> Instead of the macro in my previous patch, it is now controlled  
>> by a
>> >>> command line option, -fvar-tracking-uninit, which turns on
>> >>> var-tracking, just like -fvar-tracking, but also turns on the
>> >>> uninitialized variable tracking.  I added the same feasibility
>> >>> checks to
>> >>> it that are used for -fvar-tracking.  I also turned it on by  
>> default
>> >>> on darwin systems running 10.5 or later (when var-tracking is  
>> on).
>> >>>
>> >>> I tested this patch by bootstrapping it and running the dejagnu
>> >>> testsuite without any regressions, on a ppc running apple- 
>> darwin, an
>> >>> x86 running apple-darwin, and an x86 64 running 64-bit linux.  I
>> >>> also
>> >>> ran it on a small test case containing uninitialized variables,  
>> to
>> >>> verify that it turns on when the command line option is passed,  
>> or
>> >>> when running on the correct version of darwin, and is off at all
>> >>> other
>> >>> times.
>> >>>
>> >>> Is this patch okay to commit to mainline?
>> >>>
>> >>> --Caroline Tice
>> >>> ctice@apple.com
>> >>>
>> >>>
>> >>> On May 1, 2007, at 5:02 PM, Caroline Tice wrote:
>> >>>
>> >>>>
>> >>>> As part of some work I've been doing on improving debugging of
>> >>>> optimized code, I have developed the following patch which,  
>> while
>> >>>> tracking the locations of variables, also keeps track of whether
>> >>>> the
>> >>>> variables are initialized or not (it makes conservative  
>> assumptions
>> >>>> where it can't be sure).  For those places where it is sure the
>> >>>> variables are unintialized, it adds an annotation to the
>> >>>> var_location_note, which the dwarf writer later translates to  
>> a new
>> >>>> DW_OP (an extension) that indicates a variable is uninitialized
>> >>>> (DW_OP_GNU_uninit).
>> >>>
>> >>>> Since this work requires that GDB be able to read and do  
>> something
>> >>>> reasonable with the new DW_OP, I have also created a GDB patch  
>> to
>> >>>> deal
>> >>>> with the new op, and to inform the user that a particular  
>> value is
>> >>>> unintialized when the user asks to see it.  As the two patches
>> >>>> really
>> >>>> go together, I am attaching both of them to this message.  (I  
>> will
>> >>>> also be sending the GDB patch to the gdb patches list).
>> >>>
>> >>>> Because using the new DW_OP is sensitive to whether or not the  
>> user
>> >>>> has a version of GDB that can handle it, I have added a macro,
>> >>>> TARGET_DWARF_UNINIT_VARS, which defaults to 0, and which  
>> controls
>> >>>> whether the uninitialized variable tracking is done.
>> >>>
>> >>>> I have bootstrapped and run the dejagnu testsuite on this patch,
>> >>>> with
>> >>>> no regressions, on a ppc running apple-darwin, an x86 running
>> >>>> apple-darwin, and an x86 64 running 64-bit linux.
>> >>>
>> >>>> Is this patch okay to commit to mainline?
>> >>>> -- Caroline Tice
>> >>>> ctice@apple.com
>> >>>>
>> >>>
>> >>> 2007-05-11  Caroline Tice  <ctice@apple.com>
>> >>>
>> >>>      * toplev.c (process_options): Turn flag_var_tracking_uninit
>> >>> off when
>> >>>      flag_var_tracking is explicitly turned off (i.e. when  
>> variable
>> >>>      tracking is not feasible); otherwise, turn flag_var_tracking
>> >>> on when
>> >>>      flag_var_tracking_uninit is on.
>> >>>      * rtl.def (VAR_LOCATION): Add a new integer subfield to
>> >>> VAR_LOCATION
>> >>>      note definitions, to allow recording of initialization  
>> status
>> >>> in the
>> >>>      notes.
>> >>>      * dwarf2out.c (dwarf_stack_op_name): Add case for
>> >>> DW_OP_GNU_uninit.
>> >>>      (add_var_loc_to_decl): Add comparison of
>> >>> NOTE_VAR_LOCATION_STATUS to
>> >>>      determine if two note locations are equal.
>> >>>      (output_loc_list): Don't output list entries whose start &
>> >>> end labels
>> >>>      are the same.
>> >>>      (reg_loc_descriptor): Add parameter for initialization
>> >>> status; pass it
>> >>>      to other loc descriptor functions.
>> >>>      (one_reg_loc_descriptor): Add parameter for initialization
>> >>> status;
>> >>>      check its value and add DW_OP_GNU_uninit to returned loc
>> >>> descr if
>> >>>      appropriate.
>> >>>      (multiple_reg_loc_descriptor): Add parameter for  
>> initialization
>> >>>      status;
>> >>>      pass init status argument to other loc descriptor functions;
>> >>> check
>> >>>      value of intialization parameter and add DW_OP_GNU_uninit to
>> >>> returned
>> >>>      loc descr if appropriate.
>> >>>      (based_loc_descr): Add parameter for initialization status;
>> >>> add new
>> >>>      variable for return value; check value of initialization
>> >>> parameter and
>> >>>      add DW_OP_GNU_uninit to returned loc descr if appropriate.
>> >>>      (concatn_mem_loc_descriptor): Add parameter for
>> >>> initialization status;
>> >>>      pass init status argument to other loc descriptor functions;
>> >>> check
>> >>>      value of intialization parameter and add DW_OP_GNU_uninit to
>> >>> returned
>> >>>      loc descr if appropriate.
>> >>>      (mem_loc_descriptor): Likewise.
>> >>>      (concat_loc_descriptor): Likewise.
>> >>>      (concatn_loc_descriptor): Likewise.
>> >>>      (loc_descriptor): Add parameter for initialization status;
>> >>> pass it as
>> >>>      argument to other loc descriptor function calls.
>> >>>      (loc_descriptor_from_tree_1): Add appropriate initialization
>> >>> status
>> >>>      to loc descriptor function calls.
>> >>>      (add_location_or_const_value_attribute): Get initialization
>> >>> status
>> >>>      from VAR_LOCATION note; add initialization status to loc
>> >>> descriptor
>> >>>      function calls.
>> >>>      * dwarf2.h (enum dwarf_location_atom): New op,
>> >>> DW_OP_GNU_uninit.
>> >>>      * print-rtl.c (print_rtx): When printing a VAR_LOCATION  
>> note,
>> >>> if
>> >>>      status is uninitialized, add "[uninint]" to output.
>> >>>      * common.opt (fvar-tracking-uninit): New option, similar to
>> >>>      fvar-tracking, to turn on tracking of uninitialized
>> >>> variables; creates
>> >>>      a new global flag, flag_var_tracking_uninit.
>> >>>      * rtl.h (NOTE_VAR_LOCATION_STATUS): New macro for accessing
>> >>> new field.
>> >>>      (enum var_init_status): New type, for var initialization
>> >>> status field.
>> >>>      * var-tracking.c (struct location_chain_def): Two new  
>> fields,
>> >>> init,
>> >>>      for initialization status, and set_src for the assignment
>> >>> value expr.
>> >>>      (unshare_variable): New parameter for initialization status;
>> >>>      initialize new init and set_src fields.
>> >>>      (var_reg_set): New parameters for initialization status and
>> >>> value;
>> >>>      pass them to set_variable_part.
>> >>>      (var_mem_set): Likewise.
>> >>>      (get_init_value): New function.
>> >>>      (var_reg_delete_and_set): New initialization status & value
>> >>>      parameters; add call to get_init_value if status is unknown;
>> >>> pass new
>> >>>      parameters to clobber_variable_part and var_reg_set.
>> >>>      (var_mem_delete_and_set): Likewise.
>> >>>      (var_reg_delete): Pass null set_src value to
>> >>> clobber_variable_part.
>> >>>      (var_mem_delete): Likewise.
>> >>>      (variable_union): Pass status to unshare_variable;  
>> initialize
>> >>> new init
>> >>>      and set_src fields.  If flag_var_tracking_uninit is not set,
>> >>> force
>> >>>      status to initialized.
>> >>>      (add_stores): Store insn, rather than NEXT_INSN(insn), so it
>> >>> can be
>> >>>      used later to get the set_src value.
>> >>>      (find_src_status): New function.
>> >>>      (find_src_set_src): New function.
>> >>>      (compute_bb_dataflow): Pass init status to calls to
>> >>> var_reg_set,
>> >>>      var_mem_set, var_reg_delete_and_set and
>> >>> var_mem_delete_and_set; for
>> >>>      MO_SET, get set_src value and pass it to
>> >>> var_reg_delete_and_set
>> >>>      and var_mem_delete_and_set.
>> >>>      (dump_variable):  Print out "[uninit]" if appropriate.
>> >>>      (set_variable_part): Add new initialization and set_src
>> >>> parameters;
>> >>>      pass status to unshare_variable; set node->init and node-
>> >>> >set_src
>> >>>      fields and modify slot in hash table appropriately; save the
>> >>> init and
>> >>>      set_src values if appropriate and assign to the new node.
>> >>>      (clobber_variable_part): New set_src parameter; if two nodes
>> >>> have
>> >>>      same variable and same location but different set_src
>> >>> (assignment)
>> >>>      values, clobber old node.
>> >>>      (delete_variable_part): Pass init status to  
>> unshare_variable.
>> >>>      (emit_note_insn_var_location): Add initialized var; assign
>> >>> var's init
>> >>>      status to new 'initialized'; pass new init status field to
>> >>> calls to
>> >>>      gen_rtx_VAR_LOCATION.  If flag_var_tracking_uninit is not
>> >>> set, force
>> >>>      status to initialized.
>> >>>      (emit_notes_in_bb): Pass initialization status to calls to
>> >>>      var_reg_set, var_mem_set, var_reg_delete_and_set and
>> >>>      var_mem_delete_and_set; for MO_SET, get set_src value and
>> >>> pass it to
>> >>>      var_reg_delete_and_set and var_mem_delete_and_set; call
>> >>>      emit_notes_for_changes on NEXT_INSN(insn) rather than on
>> >>> insn, to
>> >>>      make up for change in add_stores.
>> >>>      (vt_add_function_parameters): Add status to calls to
>> >>>      set_variable_part.
>> >>>      * config/darwin.c (darwin_override_options): Turn on
>> >>> uninitialized
>> >>>      tracking automatically, if var_tracking is on and the  
>> system is
>> >>>      10.5 or higher.
>> >>>
>> >>>
>> >>> <fsf-gcc-patch.v2.txt>
>> >>
>> >
>>
>>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Ping 4! [PATCH, revised]: Track uninitialized variables
  2007-06-01 17:24           ` Caroline Tice
@ 2007-06-08 17:52             ` Caroline Tice
  2007-06-21 17:02               ` Ping 5! " Caroline Tice
  0 siblings, 1 reply; 25+ messages in thread
From: Caroline Tice @ 2007-06-08 17:52 UTC (permalink / raw)
  To: GCC Patches; +Cc: Caroline Tice


On Jun 1, 2007, at 10:24 AM, Caroline Tice wrote:

> Thank you for the suggestion.  The link to the original
> posting for this unreviewed patch is:
>
> http://gcc.gnu.org/ml/gcc-patches/2007-05/msg01240.html
>
> On Jun 1, 2007, at 10:13 AM, Manuel López-Ibáñez wrote:
>
>> Hi Caroline,
>>
>> I think that giving a link to the original mail in the archives will
>> increase the chances of getting a reviewer. And as a rule of thumb,
>> anything that makes easier the life of a reviewer will increase the
>> chances of getting a patch reviewed.
>>
>> Cheers,
>>
>> Manuel.
>>
>> On 01/06/07, Caroline Tice <ctice@apple.com> wrote:
>>>
>>> Still waiting to be reviewed...
>>>
>>> On May 25, 2007, at 1:53 PM, Caroline Tice wrote:
>>>
>>> >
>>> > On May 18, 2007, at 12:48 PM, Caroline Tice wrote:
>>> >
>>> >> As a point of interest:  The GDB side of this patch has been
>>> >> accepted and
>>> >> committed to FSF GDB.
>>> >>
>>> >> -- Caroline
>>> >>
>>> >> On May 11, 2007, at 12:13 PM, Caroline Tice wrote:
>>> >>
>>> >>> Here is a revised version of my patch for tracking uninitialized
>>> >>> variables (see description in original posting copied below).  I
>>> >>> added
>>> >>> the comments Ian asked for, and I changed the way it is turned  
>>> on/
>>> >>> off.
>>> >>> Instead of the macro in my previous patch, it is now  
>>> controlled by a
>>> >>> command line option, -fvar-tracking-uninit, which turns on
>>> >>> var-tracking, just like -fvar-tracking, but also turns on the
>>> >>> uninitialized variable tracking.  I added the same feasibility
>>> >>> checks to
>>> >>> it that are used for -fvar-tracking.  I also turned it on by  
>>> default
>>> >>> on darwin systems running 10.5 or later (when var-tracking is  
>>> on).
>>> >>>
>>> >>> I tested this patch by bootstrapping it and running the dejagnu
>>> >>> testsuite without any regressions, on a ppc running apple- 
>>> darwin, an
>>> >>> x86 running apple-darwin, and an x86 64 running 64-bit linux.  I
>>> >>> also
>>> >>> ran it on a small test case containing uninitialized  
>>> variables, to
>>> >>> verify that it turns on when the command line option is  
>>> passed, or
>>> >>> when running on the correct version of darwin, and is off at all
>>> >>> other
>>> >>> times.
>>> >>>
>>> >>> Is this patch okay to commit to mainline?
>>> >>>
>>> >>> --Caroline Tice
>>> >>> ctice@apple.com
>>> >>>
>>> >>>
>>> >>> On May 1, 2007, at 5:02 PM, Caroline Tice wrote:
>>> >>>
>>> >>>>
>>> >>>> As part of some work I've been doing on improving debugging of
>>> >>>> optimized code, I have developed the following patch which,  
>>> while
>>> >>>> tracking the locations of variables, also keeps track of  
>>> whether
>>> >>>> the
>>> >>>> variables are initialized or not (it makes conservative  
>>> assumptions
>>> >>>> where it can't be sure).  For those places where it is sure the
>>> >>>> variables are unintialized, it adds an annotation to the
>>> >>>> var_location_note, which the dwarf writer later translates to  
>>> a new
>>> >>>> DW_OP (an extension) that indicates a variable is uninitialized
>>> >>>> (DW_OP_GNU_uninit).
>>> >>>
>>> >>>> Since this work requires that GDB be able to read and do  
>>> something
>>> >>>> reasonable with the new DW_OP, I have also created a GDB  
>>> patch to
>>> >>>> deal
>>> >>>> with the new op, and to inform the user that a particular  
>>> value is
>>> >>>> unintialized when the user asks to see it.  As the two patches
>>> >>>> really
>>> >>>> go together, I am attaching both of them to this message.  (I  
>>> will
>>> >>>> also be sending the GDB patch to the gdb patches list).
>>> >>>
>>> >>>> Because using the new DW_OP is sensitive to whether or not  
>>> the user
>>> >>>> has a version of GDB that can handle it, I have added a macro,
>>> >>>> TARGET_DWARF_UNINIT_VARS, which defaults to 0, and which  
>>> controls
>>> >>>> whether the uninitialized variable tracking is done.
>>> >>>
>>> >>>> I have bootstrapped and run the dejagnu testsuite on this  
>>> patch,
>>> >>>> with
>>> >>>> no regressions, on a ppc running apple-darwin, an x86 running
>>> >>>> apple-darwin, and an x86 64 running 64-bit linux.
>>> >>>
>>> >>>> Is this patch okay to commit to mainline?
>>> >>>> -- Caroline Tice
>>> >>>> ctice@apple.com
>>> >>>>
>>> >>>
>>> >>> 2007-05-11  Caroline Tice  <ctice@apple.com>
>>> >>>
>>> >>>      * toplev.c (process_options): Turn flag_var_tracking_uninit
>>> >>> off when
>>> >>>      flag_var_tracking is explicitly turned off (i.e. when  
>>> variable
>>> >>>      tracking is not feasible); otherwise, turn  
>>> flag_var_tracking
>>> >>> on when
>>> >>>      flag_var_tracking_uninit is on.
>>> >>>      * rtl.def (VAR_LOCATION): Add a new integer subfield to
>>> >>> VAR_LOCATION
>>> >>>      note definitions, to allow recording of initialization  
>>> status
>>> >>> in the
>>> >>>      notes.
>>> >>>      * dwarf2out.c (dwarf_stack_op_name): Add case for
>>> >>> DW_OP_GNU_uninit.
>>> >>>      (add_var_loc_to_decl): Add comparison of
>>> >>> NOTE_VAR_LOCATION_STATUS to
>>> >>>      determine if two note locations are equal.
>>> >>>      (output_loc_list): Don't output list entries whose start &
>>> >>> end labels
>>> >>>      are the same.
>>> >>>      (reg_loc_descriptor): Add parameter for initialization
>>> >>> status; pass it
>>> >>>      to other loc descriptor functions.
>>> >>>      (one_reg_loc_descriptor): Add parameter for initialization
>>> >>> status;
>>> >>>      check its value and add DW_OP_GNU_uninit to returned loc
>>> >>> descr if
>>> >>>      appropriate.
>>> >>>      (multiple_reg_loc_descriptor): Add parameter for  
>>> initialization
>>> >>>      status;
>>> >>>      pass init status argument to other loc descriptor  
>>> functions;
>>> >>> check
>>> >>>      value of intialization parameter and add DW_OP_GNU_uninit  
>>> to
>>> >>> returned
>>> >>>      loc descr if appropriate.
>>> >>>      (based_loc_descr): Add parameter for initialization status;
>>> >>> add new
>>> >>>      variable for return value; check value of initialization
>>> >>> parameter and
>>> >>>      add DW_OP_GNU_uninit to returned loc descr if appropriate.
>>> >>>      (concatn_mem_loc_descriptor): Add parameter for
>>> >>> initialization status;
>>> >>>      pass init status argument to other loc descriptor  
>>> functions;
>>> >>> check
>>> >>>      value of intialization parameter and add DW_OP_GNU_uninit  
>>> to
>>> >>> returned
>>> >>>      loc descr if appropriate.
>>> >>>      (mem_loc_descriptor): Likewise.
>>> >>>      (concat_loc_descriptor): Likewise.
>>> >>>      (concatn_loc_descriptor): Likewise.
>>> >>>      (loc_descriptor): Add parameter for initialization status;
>>> >>> pass it as
>>> >>>      argument to other loc descriptor function calls.
>>> >>>      (loc_descriptor_from_tree_1): Add appropriate  
>>> initialization
>>> >>> status
>>> >>>      to loc descriptor function calls.
>>> >>>      (add_location_or_const_value_attribute): Get initialization
>>> >>> status
>>> >>>      from VAR_LOCATION note; add initialization status to loc
>>> >>> descriptor
>>> >>>      function calls.
>>> >>>      * dwarf2.h (enum dwarf_location_atom): New op,
>>> >>> DW_OP_GNU_uninit.
>>> >>>      * print-rtl.c (print_rtx): When printing a VAR_LOCATION  
>>> note,
>>> >>> if
>>> >>>      status is uninitialized, add "[uninint]" to output.
>>> >>>      * common.opt (fvar-tracking-uninit): New option, similar to
>>> >>>      fvar-tracking, to turn on tracking of uninitialized
>>> >>> variables; creates
>>> >>>      a new global flag, flag_var_tracking_uninit.
>>> >>>      * rtl.h (NOTE_VAR_LOCATION_STATUS): New macro for accessing
>>> >>> new field.
>>> >>>      (enum var_init_status): New type, for var initialization
>>> >>> status field.
>>> >>>      * var-tracking.c (struct location_chain_def): Two new  
>>> fields,
>>> >>> init,
>>> >>>      for initialization status, and set_src for the assignment
>>> >>> value expr.
>>> >>>      (unshare_variable): New parameter for initialization  
>>> status;
>>> >>>      initialize new init and set_src fields.
>>> >>>      (var_reg_set): New parameters for initialization status and
>>> >>> value;
>>> >>>      pass them to set_variable_part.
>>> >>>      (var_mem_set): Likewise.
>>> >>>      (get_init_value): New function.
>>> >>>      (var_reg_delete_and_set): New initialization status & value
>>> >>>      parameters; add call to get_init_value if status is  
>>> unknown;
>>> >>> pass new
>>> >>>      parameters to clobber_variable_part and var_reg_set.
>>> >>>      (var_mem_delete_and_set): Likewise.
>>> >>>      (var_reg_delete): Pass null set_src value to
>>> >>> clobber_variable_part.
>>> >>>      (var_mem_delete): Likewise.
>>> >>>      (variable_union): Pass status to unshare_variable;  
>>> initialize
>>> >>> new init
>>> >>>      and set_src fields.  If flag_var_tracking_uninit is not  
>>> set,
>>> >>> force
>>> >>>      status to initialized.
>>> >>>      (add_stores): Store insn, rather than NEXT_INSN(insn), so  
>>> it
>>> >>> can be
>>> >>>      used later to get the set_src value.
>>> >>>      (find_src_status): New function.
>>> >>>      (find_src_set_src): New function.
>>> >>>      (compute_bb_dataflow): Pass init status to calls to
>>> >>> var_reg_set,
>>> >>>      var_mem_set, var_reg_delete_and_set and
>>> >>> var_mem_delete_and_set; for
>>> >>>      MO_SET, get set_src value and pass it to
>>> >>> var_reg_delete_and_set
>>> >>>      and var_mem_delete_and_set.
>>> >>>      (dump_variable):  Print out "[uninit]" if appropriate.
>>> >>>      (set_variable_part): Add new initialization and set_src
>>> >>> parameters;
>>> >>>      pass status to unshare_variable; set node->init and node-
>>> >>> >set_src
>>> >>>      fields and modify slot in hash table appropriately; save  
>>> the
>>> >>> init and
>>> >>>      set_src values if appropriate and assign to the new node.
>>> >>>      (clobber_variable_part): New set_src parameter; if two  
>>> nodes
>>> >>> have
>>> >>>      same variable and same location but different set_src
>>> >>> (assignment)
>>> >>>      values, clobber old node.
>>> >>>      (delete_variable_part): Pass init status to  
>>> unshare_variable.
>>> >>>      (emit_note_insn_var_location): Add initialized var; assign
>>> >>> var's init
>>> >>>      status to new 'initialized'; pass new init status field to
>>> >>> calls to
>>> >>>      gen_rtx_VAR_LOCATION.  If flag_var_tracking_uninit is not
>>> >>> set, force
>>> >>>      status to initialized.
>>> >>>      (emit_notes_in_bb): Pass initialization status to calls to
>>> >>>      var_reg_set, var_mem_set, var_reg_delete_and_set and
>>> >>>      var_mem_delete_and_set; for MO_SET, get set_src value and
>>> >>> pass it to
>>> >>>      var_reg_delete_and_set and var_mem_delete_and_set; call
>>> >>>      emit_notes_for_changes on NEXT_INSN(insn) rather than on
>>> >>> insn, to
>>> >>>      make up for change in add_stores.
>>> >>>      (vt_add_function_parameters): Add status to calls to
>>> >>>      set_variable_part.
>>> >>>      * config/darwin.c (darwin_override_options): Turn on
>>> >>> uninitialized
>>> >>>      tracking automatically, if var_tracking is on and the  
>>> system is
>>> >>>      10.5 or higher.
>>> >>>
>>> >>>
>>> >>> <fsf-gcc-patch.v2.txt>
>>> >>
>>> >
>>>
>>>
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Ping 5! [PATCH, revised]: Track uninitialized variables
  2007-06-08 17:52             ` Ping 4! " Caroline Tice
@ 2007-06-21 17:02               ` Caroline Tice
  2007-06-23 18:54                 ` Mark Mitchell
  2007-07-12 17:24                 ` Ping 6! " Caroline Tice
  0 siblings, 2 replies; 25+ messages in thread
From: Caroline Tice @ 2007-06-21 17:02 UTC (permalink / raw)
  To: GCC Patches; +Cc: Caroline Tice, Geoffrey Keating, Eric Christopher


On Jun 8, 2007, at 10:07 AM, Caroline Tice wrote:

>
> On Jun 1, 2007, at 10:24 AM, Caroline Tice wrote:
>
>> Thank you for the suggestion.  The link to the original
>> posting for this unreviewed patch is:
>>
>> http://gcc.gnu.org/ml/gcc-patches/2007-05/msg01240.html
>>
>> On Jun 1, 2007, at 10:13 AM, Manuel López-Ibáñez wrote:
>>
>>> Hi Caroline,
>>>
>>> I think that giving a link to the original mail in the archives will
>>> increase the chances of getting a reviewer. And as a rule of thumb,
>>> anything that makes easier the life of a reviewer will increase the
>>> chances of getting a patch reviewed.
>>>
>>> Cheers,
>>>
>>> Manuel.
>>>
>>> On 01/06/07, Caroline Tice <ctice@apple.com> wrote:
>>>>
>>>> Still waiting to be reviewed...
>>>>
>>>> On May 25, 2007, at 1:53 PM, Caroline Tice wrote:
>>>>
>>>> >
>>>> > On May 18, 2007, at 12:48 PM, Caroline Tice wrote:
>>>> >
>>>> >> As a point of interest:  The GDB side of this patch has been
>>>> >> accepted and
>>>> >> committed to FSF GDB.
>>>> >>
>>>> >> -- Caroline
>>>> >>
>>>> >> On May 11, 2007, at 12:13 PM, Caroline Tice wrote:
>>>> >>
>>>> >>> Here is a revised version of my patch for tracking  
>>>> uninitialized
>>>> >>> variables (see description in original posting copied  
>>>> below).  I
>>>> >>> added
>>>> >>> the comments Ian asked for, and I changed the way it is  
>>>> turned on/
>>>> >>> off.
>>>> >>> Instead of the macro in my previous patch, it is now  
>>>> controlled by a
>>>> >>> command line option, -fvar-tracking-uninit, which turns on
>>>> >>> var-tracking, just like -fvar-tracking, but also turns on the
>>>> >>> uninitialized variable tracking.  I added the same feasibility
>>>> >>> checks to
>>>> >>> it that are used for -fvar-tracking.  I also turned it on by  
>>>> default
>>>> >>> on darwin systems running 10.5 or later (when var-tracking is  
>>>> on).
>>>> >>>
>>>> >>> I tested this patch by bootstrapping it and running the dejagnu
>>>> >>> testsuite without any regressions, on a ppc running apple- 
>>>> darwin, an
>>>> >>> x86 running apple-darwin, and an x86 64 running 64-bit  
>>>> linux.  I
>>>> >>> also
>>>> >>> ran it on a small test case containing uninitialized  
>>>> variables, to
>>>> >>> verify that it turns on when the command line option is  
>>>> passed, or
>>>> >>> when running on the correct version of darwin, and is off at  
>>>> all
>>>> >>> other
>>>> >>> times.
>>>> >>>
>>>> >>> Is this patch okay to commit to mainline?
>>>> >>>
>>>> >>> --Caroline Tice
>>>> >>> ctice@apple.com
>>>> >>>
>>>> >>>
>>>> >>> On May 1, 2007, at 5:02 PM, Caroline Tice wrote:
>>>> >>>
>>>> >>>>
>>>> >>>> As part of some work I've been doing on improving debugging of
>>>> >>>> optimized code, I have developed the following patch which,  
>>>> while
>>>> >>>> tracking the locations of variables, also keeps track of  
>>>> whether
>>>> >>>> the
>>>> >>>> variables are initialized or not (it makes conservative  
>>>> assumptions
>>>> >>>> where it can't be sure).  For those places where it is sure  
>>>> the
>>>> >>>> variables are unintialized, it adds an annotation to the
>>>> >>>> var_location_note, which the dwarf writer later translates  
>>>> to a new
>>>> >>>> DW_OP (an extension) that indicates a variable is  
>>>> uninitialized
>>>> >>>> (DW_OP_GNU_uninit).
>>>> >>>
>>>> >>>> Since this work requires that GDB be able to read and do  
>>>> something
>>>> >>>> reasonable with the new DW_OP, I have also created a GDB  
>>>> patch to
>>>> >>>> deal
>>>> >>>> with the new op, and to inform the user that a particular  
>>>> value is
>>>> >>>> unintialized when the user asks to see it.  As the two patches
>>>> >>>> really
>>>> >>>> go together, I am attaching both of them to this message.   
>>>> (I will
>>>> >>>> also be sending the GDB patch to the gdb patches list).
>>>> >>>
>>>> >>>> Because using the new DW_OP is sensitive to whether or not  
>>>> the user
>>>> >>>> has a version of GDB that can handle it, I have added a macro,
>>>> >>>> TARGET_DWARF_UNINIT_VARS, which defaults to 0, and which  
>>>> controls
>>>> >>>> whether the uninitialized variable tracking is done.
>>>> >>>
>>>> >>>> I have bootstrapped and run the dejagnu testsuite on this  
>>>> patch,
>>>> >>>> with
>>>> >>>> no regressions, on a ppc running apple-darwin, an x86 running
>>>> >>>> apple-darwin, and an x86 64 running 64-bit linux.
>>>> >>>
>>>> >>>> Is this patch okay to commit to mainline?
>>>> >>>> -- Caroline Tice
>>>> >>>> ctice@apple.com
>>>> >>>>
>>>> >>>
>>>> >>> 2007-05-11  Caroline Tice  <ctice@apple.com>
>>>> >>>
>>>> >>>      * toplev.c (process_options): Turn  
>>>> flag_var_tracking_uninit
>>>> >>> off when
>>>> >>>      flag_var_tracking is explicitly turned off (i.e. when  
>>>> variable
>>>> >>>      tracking is not feasible); otherwise, turn  
>>>> flag_var_tracking
>>>> >>> on when
>>>> >>>      flag_var_tracking_uninit is on.
>>>> >>>      * rtl.def (VAR_LOCATION): Add a new integer subfield to
>>>> >>> VAR_LOCATION
>>>> >>>      note definitions, to allow recording of initialization  
>>>> status
>>>> >>> in the
>>>> >>>      notes.
>>>> >>>      * dwarf2out.c (dwarf_stack_op_name): Add case for
>>>> >>> DW_OP_GNU_uninit.
>>>> >>>      (add_var_loc_to_decl): Add comparison of
>>>> >>> NOTE_VAR_LOCATION_STATUS to
>>>> >>>      determine if two note locations are equal.
>>>> >>>      (output_loc_list): Don't output list entries whose start &
>>>> >>> end labels
>>>> >>>      are the same.
>>>> >>>      (reg_loc_descriptor): Add parameter for initialization
>>>> >>> status; pass it
>>>> >>>      to other loc descriptor functions.
>>>> >>>      (one_reg_loc_descriptor): Add parameter for initialization
>>>> >>> status;
>>>> >>>      check its value and add DW_OP_GNU_uninit to returned loc
>>>> >>> descr if
>>>> >>>      appropriate.
>>>> >>>      (multiple_reg_loc_descriptor): Add parameter for  
>>>> initialization
>>>> >>>      status;
>>>> >>>      pass init status argument to other loc descriptor  
>>>> functions;
>>>> >>> check
>>>> >>>      value of intialization parameter and add  
>>>> DW_OP_GNU_uninit to
>>>> >>> returned
>>>> >>>      loc descr if appropriate.
>>>> >>>      (based_loc_descr): Add parameter for initialization  
>>>> status;
>>>> >>> add new
>>>> >>>      variable for return value; check value of initialization
>>>> >>> parameter and
>>>> >>>      add DW_OP_GNU_uninit to returned loc descr if appropriate.
>>>> >>>      (concatn_mem_loc_descriptor): Add parameter for
>>>> >>> initialization status;
>>>> >>>      pass init status argument to other loc descriptor  
>>>> functions;
>>>> >>> check
>>>> >>>      value of intialization parameter and add  
>>>> DW_OP_GNU_uninit to
>>>> >>> returned
>>>> >>>      loc descr if appropriate.
>>>> >>>      (mem_loc_descriptor): Likewise.
>>>> >>>      (concat_loc_descriptor): Likewise.
>>>> >>>      (concatn_loc_descriptor): Likewise.
>>>> >>>      (loc_descriptor): Add parameter for initialization status;
>>>> >>> pass it as
>>>> >>>      argument to other loc descriptor function calls.
>>>> >>>      (loc_descriptor_from_tree_1): Add appropriate  
>>>> initialization
>>>> >>> status
>>>> >>>      to loc descriptor function calls.
>>>> >>>      (add_location_or_const_value_attribute): Get  
>>>> initialization
>>>> >>> status
>>>> >>>      from VAR_LOCATION note; add initialization status to loc
>>>> >>> descriptor
>>>> >>>      function calls.
>>>> >>>      * dwarf2.h (enum dwarf_location_atom): New op,
>>>> >>> DW_OP_GNU_uninit.
>>>> >>>      * print-rtl.c (print_rtx): When printing a VAR_LOCATION  
>>>> note,
>>>> >>> if
>>>> >>>      status is uninitialized, add "[uninint]" to output.
>>>> >>>      * common.opt (fvar-tracking-uninit): New option, similar  
>>>> to
>>>> >>>      fvar-tracking, to turn on tracking of uninitialized
>>>> >>> variables; creates
>>>> >>>      a new global flag, flag_var_tracking_uninit.
>>>> >>>      * rtl.h (NOTE_VAR_LOCATION_STATUS): New macro for  
>>>> accessing
>>>> >>> new field.
>>>> >>>      (enum var_init_status): New type, for var initialization
>>>> >>> status field.
>>>> >>>      * var-tracking.c (struct location_chain_def): Two new  
>>>> fields,
>>>> >>> init,
>>>> >>>      for initialization status, and set_src for the assignment
>>>> >>> value expr.
>>>> >>>      (unshare_variable): New parameter for initialization  
>>>> status;
>>>> >>>      initialize new init and set_src fields.
>>>> >>>      (var_reg_set): New parameters for initialization status  
>>>> and
>>>> >>> value;
>>>> >>>      pass them to set_variable_part.
>>>> >>>      (var_mem_set): Likewise.
>>>> >>>      (get_init_value): New function.
>>>> >>>      (var_reg_delete_and_set): New initialization status &  
>>>> value
>>>> >>>      parameters; add call to get_init_value if status is  
>>>> unknown;
>>>> >>> pass new
>>>> >>>      parameters to clobber_variable_part and var_reg_set.
>>>> >>>      (var_mem_delete_and_set): Likewise.
>>>> >>>      (var_reg_delete): Pass null set_src value to
>>>> >>> clobber_variable_part.
>>>> >>>      (var_mem_delete): Likewise.
>>>> >>>      (variable_union): Pass status to unshare_variable;  
>>>> initialize
>>>> >>> new init
>>>> >>>      and set_src fields.  If flag_var_tracking_uninit is not  
>>>> set,
>>>> >>> force
>>>> >>>      status to initialized.
>>>> >>>      (add_stores): Store insn, rather than NEXT_INSN(insn),  
>>>> so it
>>>> >>> can be
>>>> >>>      used later to get the set_src value.
>>>> >>>      (find_src_status): New function.
>>>> >>>      (find_src_set_src): New function.
>>>> >>>      (compute_bb_dataflow): Pass init status to calls to
>>>> >>> var_reg_set,
>>>> >>>      var_mem_set, var_reg_delete_and_set and
>>>> >>> var_mem_delete_and_set; for
>>>> >>>      MO_SET, get set_src value and pass it to
>>>> >>> var_reg_delete_and_set
>>>> >>>      and var_mem_delete_and_set.
>>>> >>>      (dump_variable):  Print out "[uninit]" if appropriate.
>>>> >>>      (set_variable_part): Add new initialization and set_src
>>>> >>> parameters;
>>>> >>>      pass status to unshare_variable; set node->init and node-
>>>> >>> >set_src
>>>> >>>      fields and modify slot in hash table appropriately; save  
>>>> the
>>>> >>> init and
>>>> >>>      set_src values if appropriate and assign to the new node.
>>>> >>>      (clobber_variable_part): New set_src parameter; if two  
>>>> nodes
>>>> >>> have
>>>> >>>      same variable and same location but different set_src
>>>> >>> (assignment)
>>>> >>>      values, clobber old node.
>>>> >>>      (delete_variable_part): Pass init status to  
>>>> unshare_variable.
>>>> >>>      (emit_note_insn_var_location): Add initialized var; assign
>>>> >>> var's init
>>>> >>>      status to new 'initialized'; pass new init status field to
>>>> >>> calls to
>>>> >>>      gen_rtx_VAR_LOCATION.  If flag_var_tracking_uninit is not
>>>> >>> set, force
>>>> >>>      status to initialized.
>>>> >>>      (emit_notes_in_bb): Pass initialization status to calls to
>>>> >>>      var_reg_set, var_mem_set, var_reg_delete_and_set and
>>>> >>>      var_mem_delete_and_set; for MO_SET, get set_src value and
>>>> >>> pass it to
>>>> >>>      var_reg_delete_and_set and var_mem_delete_and_set; call
>>>> >>>      emit_notes_for_changes on NEXT_INSN(insn) rather than on
>>>> >>> insn, to
>>>> >>>      make up for change in add_stores.
>>>> >>>      (vt_add_function_parameters): Add status to calls to
>>>> >>>      set_variable_part.
>>>> >>>      * config/darwin.c (darwin_override_options): Turn on
>>>> >>> uninitialized
>>>> >>>      tracking automatically, if var_tracking is on and the  
>>>> system is
>>>> >>>      10.5 or higher.
>>>> >>>
>>>> >>>
>>>> >>> <fsf-gcc-patch.v2.txt>
>>>> >>
>>>> >
>>>>
>>>>
>>
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Ping 5! [PATCH, revised]: Track uninitialized variables
  2007-06-21 17:02               ` Ping 5! " Caroline Tice
@ 2007-06-23 18:54                 ` Mark Mitchell
  2007-07-12 17:24                 ` Ping 6! " Caroline Tice
  1 sibling, 0 replies; 25+ messages in thread
From: Mark Mitchell @ 2007-06-23 18:54 UTC (permalink / raw)
  To: Caroline Tice; +Cc: GCC Patches, Geoffrey Keating, Eric Christopher

Caroline Tice wrote:

>>>> I think that giving a link to the original mail in the archives will
>>>> increase the chances of getting a reviewer. And as a rule of thumb,
>>>> anything that makes easier the life of a reviewer will increase the
>>>> chances of getting a patch reviewed.

I've looked at this patch a few times.  To be honest, the reasons I've
never tried to review it is that (a) it's big, and (b) I'm not sure
*why* we want it, (c), the archives and (c) I was secretly hoping Ian
would review it since he'd had some comments before.

Would you please address (b)?  What does having this information in the
debugger allow you to do?  Is it that it helps you debug because you can
tell "uninitialized" from "random weird value"?

Also, what's the memory impact of this patch, given that it makes
VAR_LOCATION bigger?

Why is this target specific?  Do non-GNU debuggers do something bad if
they see DW_OP_GNU_uninit?  If so, do we have to worry about older
versions of GDB?

Does the new dataflow machinery give us any way to get the information
more easily?  Like, can we just ask it about a REG from
one_reg_loc_descriptor, rather than having to pass information around
through multiple functions?

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH, revised]: Track uninitialized variables
  2007-05-11 19:13 ` [PATCH, revised]: " Caroline Tice
  2007-05-18 19:48   ` Ping! " Caroline Tice
@ 2007-07-11 14:45   ` Ian Lance Taylor
  2007-07-16 13:37     ` Richard Guenther
  1 sibling, 1 reply; 25+ messages in thread
From: Ian Lance Taylor @ 2007-07-11 14:45 UTC (permalink / raw)
  To: Caroline Tice; +Cc: gcc-patches@gcc.gnu.org Patches

Caroline Tice <ctice@apple.com> writes:

>   static dw_loc_descr_ref
> ! one_reg_loc_descriptor (unsigned int regno, enum var_init_status initialized)
>   {
> +   dw_loc_descr_ref reg_loc_descr;
>     if (regno <= 31)
> !     reg_loc_descr = new_loc_descr (DW_OP_reg0 + regno, 0, 0);
>     else
> !     reg_loc_descr =  new_loc_descr (DW_OP_regx, regno, 0);

Extraneous space after '='.


> *************** multiple_reg_loc_descriptor (rtx rtl, rt
> *** 8707,8713 ****
>   	{
>   	  dw_loc_descr_ref t;
>   
> ! 	  t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg));
>   	  add_loc_descr (&loc_result, t);
>   	  add_loc_descr_op_piece (&loc_result, size);
>   	  ++reg;
> --- 8731,8738 ----
>   	{
>   	  dw_loc_descr_ref t;
>   
> ! 	  t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg),
> ! 				      STATUS_UNINITIALIZED);
>   	  add_loc_descr (&loc_result, t);
>   	  add_loc_descr_op_piece (&loc_result, size);
>   	  ++reg;

You should be passing STATUS_INITIALIZED here, not
STATUS_UNINITIALIZED.


> + /* Possible initialization status of a variable.   When requested
> +    by the user, this information is tracked and recorded in the DWARF
> +    debug information, along with the variable's location.  */
> + enum var_init_status
> + {
> +   STATUS_UNKNOWN,
> +   STATUS_UNINITIALIZED,
> +   STATUS_INITIALIZED
> + };

I'm sorry to do this to you, but these enum constant names are too
generic.  Please use something like VAR_INIT_STATUS_UNKNOWN, etc.


> +   if (!(flag_var_tracking_uninit))
> +     initialized = STATUS_INITIALIZED;

Remove the extraneous parentheses.


> *************** emit_note_insn_var_location (void **varp
> *** 2472,2480 ****
>         parallel = gen_rtx_PARALLEL (VOIDmode,
>   				   gen_rtvec_v (n_var_parts, loc));
>         NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
> ! 						       parallel);
>       }
>   
>     htab_clear_slot (changed_variables, varp);
>   
>     /* When there are no location parts the variable has been already
> --- 2724,2735 ----
>         parallel = gen_rtx_PARALLEL (VOIDmode,
>   				   gen_rtvec_v (n_var_parts, loc));
>         NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
> ! 						       parallel, 
> ! 						       (int) initialized);
>       }
>   
> +   NOTE_VAR_LOCATION_STATUS (note) = (int) initialized;

Setting NOTE_VAR_LOCATION_STATUS here is redundant with passing
initialized to gen_rtx_VAR_LOCATION.  You should either remove this
and fix the one case of gen_rtx_VAR_LOCATION to which you pass 0
rather than (int) initialized, or you should pass 0 in all cases to
gen_rtx_VAR_LOCATION.


The patch is OK with those changes.

Thanks, and sorry for the slow review.

Ian

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Ping 6! [PATCH, revised]: Track uninitialized variables
  2007-06-21 17:02               ` Ping 5! " Caroline Tice
  2007-06-23 18:54                 ` Mark Mitchell
@ 2007-07-12 17:24                 ` Caroline Tice
  2007-07-12 20:11                   ` Eric Christopher
  1 sibling, 1 reply; 25+ messages in thread
From: Caroline Tice @ 2007-07-12 17:24 UTC (permalink / raw)
  To: GCC Patches; +Cc: Geoffrey Keating, Eric Christopher, Caroline Tice

Ping again.  The link to the unreviewed patch is:

http://gcc.gnu.org/ml/gcc-patches/2007-05/msg01240.html

I believe I have answered everybody's questions so far. Please
let me know if you have any more questions about this patch.

-- Caroline Tice
ctice@apple.com

On Jun 21, 2007, at 9:27 AM, Caroline Tice wrote:

>
> On Jun 8, 2007, at 10:07 AM, Caroline Tice wrote:
>
>>
>> On Jun 1, 2007, at 10:24 AM, Caroline Tice wrote:
>>
>>> Thank you for the suggestion.  The link to the original
>>> posting for this unreviewed patch is:
>>>
>>> http://gcc.gnu.org/ml/gcc-patches/2007-05/msg01240.html
>>>
>>> On Jun 1, 2007, at 10:13 AM, Manuel López-Ibáñez wrote:
>>>
>>>> Hi Caroline,
>>>>
>>>> I think that giving a link to the original mail in the archives  
>>>> will
>>>> increase the chances of getting a reviewer. And as a rule of thumb,
>>>> anything that makes easier the life of a reviewer will increase the
>>>> chances of getting a patch reviewed.
>>>>
>>>> Cheers,
>>>>
>>>> Manuel.
>>>>
>>>> On 01/06/07, Caroline Tice <ctice@apple.com> wrote:
>>>>>
>>>>> Still waiting to be reviewed...
>>>>>
>>>>> On May 25, 2007, at 1:53 PM, Caroline Tice wrote:
>>>>>
>>>>> >
>>>>> > On May 18, 2007, at 12:48 PM, Caroline Tice wrote:
>>>>> >
>>>>> >> As a point of interest:  The GDB side of this patch has been
>>>>> >> accepted and
>>>>> >> committed to FSF GDB.
>>>>> >>
>>>>> >> -- Caroline
>>>>> >>
>>>>> >> On May 11, 2007, at 12:13 PM, Caroline Tice wrote:
>>>>> >>
>>>>> >>> Here is a revised version of my patch for tracking  
>>>>> uninitialized
>>>>> >>> variables (see description in original posting copied  
>>>>> below).  I
>>>>> >>> added
>>>>> >>> the comments Ian asked for, and I changed the way it is  
>>>>> turned on/
>>>>> >>> off.
>>>>> >>> Instead of the macro in my previous patch, it is now  
>>>>> controlled by a
>>>>> >>> command line option, -fvar-tracking-uninit, which turns on
>>>>> >>> var-tracking, just like -fvar-tracking, but also turns on the
>>>>> >>> uninitialized variable tracking.  I added the same feasibility
>>>>> >>> checks to
>>>>> >>> it that are used for -fvar-tracking.  I also turned it on by  
>>>>> default
>>>>> >>> on darwin systems running 10.5 or later (when var-tracking  
>>>>> is on).
>>>>> >>>
>>>>> >>> I tested this patch by bootstrapping it and running the  
>>>>> dejagnu
>>>>> >>> testsuite without any regressions, on a ppc running apple- 
>>>>> darwin, an
>>>>> >>> x86 running apple-darwin, and an x86 64 running 64-bit  
>>>>> linux.  I
>>>>> >>> also
>>>>> >>> ran it on a small test case containing uninitialized  
>>>>> variables, to
>>>>> >>> verify that it turns on when the command line option is  
>>>>> passed, or
>>>>> >>> when running on the correct version of darwin, and is off at  
>>>>> all
>>>>> >>> other
>>>>> >>> times.
>>>>> >>>
>>>>> >>> Is this patch okay to commit to mainline?
>>>>> >>>
>>>>> >>> --Caroline Tice
>>>>> >>> ctice@apple.com
>>>>> >>>
>>>>> >>>
>>>>> >>> On May 1, 2007, at 5:02 PM, Caroline Tice wrote:
>>>>> >>>
>>>>> >>>>
>>>>> >>>> As part of some work I've been doing on improving debugging  
>>>>> of
>>>>> >>>> optimized code, I have developed the following patch which,  
>>>>> while
>>>>> >>>> tracking the locations of variables, also keeps track of  
>>>>> whether
>>>>> >>>> the
>>>>> >>>> variables are initialized or not (it makes conservative  
>>>>> assumptions
>>>>> >>>> where it can't be sure).  For those places where it is sure  
>>>>> the
>>>>> >>>> variables are unintialized, it adds an annotation to the
>>>>> >>>> var_location_note, which the dwarf writer later translates  
>>>>> to a new
>>>>> >>>> DW_OP (an extension) that indicates a variable is  
>>>>> uninitialized
>>>>> >>>> (DW_OP_GNU_uninit).
>>>>> >>>
>>>>> >>>> Since this work requires that GDB be able to read and do  
>>>>> something
>>>>> >>>> reasonable with the new DW_OP, I have also created a GDB  
>>>>> patch to
>>>>> >>>> deal
>>>>> >>>> with the new op, and to inform the user that a particular  
>>>>> value is
>>>>> >>>> unintialized when the user asks to see it.  As the two  
>>>>> patches
>>>>> >>>> really
>>>>> >>>> go together, I am attaching both of them to this message.   
>>>>> (I will
>>>>> >>>> also be sending the GDB patch to the gdb patches list).
>>>>> >>>
>>>>> >>>> Because using the new DW_OP is sensitive to whether or not  
>>>>> the user
>>>>> >>>> has a version of GDB that can handle it, I have added a  
>>>>> macro,
>>>>> >>>> TARGET_DWARF_UNINIT_VARS, which defaults to 0, and which  
>>>>> controls
>>>>> >>>> whether the uninitialized variable tracking is done.
>>>>> >>>
>>>>> >>>> I have bootstrapped and run the dejagnu testsuite on this  
>>>>> patch,
>>>>> >>>> with
>>>>> >>>> no regressions, on a ppc running apple-darwin, an x86 running
>>>>> >>>> apple-darwin, and an x86 64 running 64-bit linux.
>>>>> >>>
>>>>> >>>> Is this patch okay to commit to mainline?
>>>>> >>>> -- Caroline Tice
>>>>> >>>> ctice@apple.com
>>>>> >>>>
>>>>> >>>
>>>>> >>> 2007-05-11  Caroline Tice  <ctice@apple.com>
>>>>> >>>
>>>>> >>>      * toplev.c (process_options): Turn  
>>>>> flag_var_tracking_uninit
>>>>> >>> off when
>>>>> >>>      flag_var_tracking is explicitly turned off (i.e. when  
>>>>> variable
>>>>> >>>      tracking is not feasible); otherwise, turn  
>>>>> flag_var_tracking
>>>>> >>> on when
>>>>> >>>      flag_var_tracking_uninit is on.
>>>>> >>>      * rtl.def (VAR_LOCATION): Add a new integer subfield to
>>>>> >>> VAR_LOCATION
>>>>> >>>      note definitions, to allow recording of initialization  
>>>>> status
>>>>> >>> in the
>>>>> >>>      notes.
>>>>> >>>      * dwarf2out.c (dwarf_stack_op_name): Add case for
>>>>> >>> DW_OP_GNU_uninit.
>>>>> >>>      (add_var_loc_to_decl): Add comparison of
>>>>> >>> NOTE_VAR_LOCATION_STATUS to
>>>>> >>>      determine if two note locations are equal.
>>>>> >>>      (output_loc_list): Don't output list entries whose  
>>>>> start &
>>>>> >>> end labels
>>>>> >>>      are the same.
>>>>> >>>      (reg_loc_descriptor): Add parameter for initialization
>>>>> >>> status; pass it
>>>>> >>>      to other loc descriptor functions.
>>>>> >>>      (one_reg_loc_descriptor): Add parameter for  
>>>>> initialization
>>>>> >>> status;
>>>>> >>>      check its value and add DW_OP_GNU_uninit to returned loc
>>>>> >>> descr if
>>>>> >>>      appropriate.
>>>>> >>>      (multiple_reg_loc_descriptor): Add parameter for  
>>>>> initialization
>>>>> >>>      status;
>>>>> >>>      pass init status argument to other loc descriptor  
>>>>> functions;
>>>>> >>> check
>>>>> >>>      value of intialization parameter and add  
>>>>> DW_OP_GNU_uninit to
>>>>> >>> returned
>>>>> >>>      loc descr if appropriate.
>>>>> >>>      (based_loc_descr): Add parameter for initialization  
>>>>> status;
>>>>> >>> add new
>>>>> >>>      variable for return value; check value of initialization
>>>>> >>> parameter and
>>>>> >>>      add DW_OP_GNU_uninit to returned loc descr if  
>>>>> appropriate.
>>>>> >>>      (concatn_mem_loc_descriptor): Add parameter for
>>>>> >>> initialization status;
>>>>> >>>      pass init status argument to other loc descriptor  
>>>>> functions;
>>>>> >>> check
>>>>> >>>      value of intialization parameter and add  
>>>>> DW_OP_GNU_uninit to
>>>>> >>> returned
>>>>> >>>      loc descr if appropriate.
>>>>> >>>      (mem_loc_descriptor): Likewise.
>>>>> >>>      (concat_loc_descriptor): Likewise.
>>>>> >>>      (concatn_loc_descriptor): Likewise.
>>>>> >>>      (loc_descriptor): Add parameter for initialization  
>>>>> status;
>>>>> >>> pass it as
>>>>> >>>      argument to other loc descriptor function calls.
>>>>> >>>      (loc_descriptor_from_tree_1): Add appropriate  
>>>>> initialization
>>>>> >>> status
>>>>> >>>      to loc descriptor function calls.
>>>>> >>>      (add_location_or_const_value_attribute): Get  
>>>>> initialization
>>>>> >>> status
>>>>> >>>      from VAR_LOCATION note; add initialization status to loc
>>>>> >>> descriptor
>>>>> >>>      function calls.
>>>>> >>>      * dwarf2.h (enum dwarf_location_atom): New op,
>>>>> >>> DW_OP_GNU_uninit.
>>>>> >>>      * print-rtl.c (print_rtx): When printing a VAR_LOCATION  
>>>>> note,
>>>>> >>> if
>>>>> >>>      status is uninitialized, add "[uninint]" to output.
>>>>> >>>      * common.opt (fvar-tracking-uninit): New option,  
>>>>> similar to
>>>>> >>>      fvar-tracking, to turn on tracking of uninitialized
>>>>> >>> variables; creates
>>>>> >>>      a new global flag, flag_var_tracking_uninit.
>>>>> >>>      * rtl.h (NOTE_VAR_LOCATION_STATUS): New macro for  
>>>>> accessing
>>>>> >>> new field.
>>>>> >>>      (enum var_init_status): New type, for var initialization
>>>>> >>> status field.
>>>>> >>>      * var-tracking.c (struct location_chain_def): Two new  
>>>>> fields,
>>>>> >>> init,
>>>>> >>>      for initialization status, and set_src for the assignment
>>>>> >>> value expr.
>>>>> >>>      (unshare_variable): New parameter for initialization  
>>>>> status;
>>>>> >>>      initialize new init and set_src fields.
>>>>> >>>      (var_reg_set): New parameters for initialization status  
>>>>> and
>>>>> >>> value;
>>>>> >>>      pass them to set_variable_part.
>>>>> >>>      (var_mem_set): Likewise.
>>>>> >>>      (get_init_value): New function.
>>>>> >>>      (var_reg_delete_and_set): New initialization status &  
>>>>> value
>>>>> >>>      parameters; add call to get_init_value if status is  
>>>>> unknown;
>>>>> >>> pass new
>>>>> >>>      parameters to clobber_variable_part and var_reg_set.
>>>>> >>>      (var_mem_delete_and_set): Likewise.
>>>>> >>>      (var_reg_delete): Pass null set_src value to
>>>>> >>> clobber_variable_part.
>>>>> >>>      (var_mem_delete): Likewise.
>>>>> >>>      (variable_union): Pass status to unshare_variable;  
>>>>> initialize
>>>>> >>> new init
>>>>> >>>      and set_src fields.  If flag_var_tracking_uninit is not  
>>>>> set,
>>>>> >>> force
>>>>> >>>      status to initialized.
>>>>> >>>      (add_stores): Store insn, rather than NEXT_INSN(insn),  
>>>>> so it
>>>>> >>> can be
>>>>> >>>      used later to get the set_src value.
>>>>> >>>      (find_src_status): New function.
>>>>> >>>      (find_src_set_src): New function.
>>>>> >>>      (compute_bb_dataflow): Pass init status to calls to
>>>>> >>> var_reg_set,
>>>>> >>>      var_mem_set, var_reg_delete_and_set and
>>>>> >>> var_mem_delete_and_set; for
>>>>> >>>      MO_SET, get set_src value and pass it to
>>>>> >>> var_reg_delete_and_set
>>>>> >>>      and var_mem_delete_and_set.
>>>>> >>>      (dump_variable):  Print out "[uninit]" if appropriate.
>>>>> >>>      (set_variable_part): Add new initialization and set_src
>>>>> >>> parameters;
>>>>> >>>      pass status to unshare_variable; set node->init and node-
>>>>> >>> >set_src
>>>>> >>>      fields and modify slot in hash table appropriately;  
>>>>> save the
>>>>> >>> init and
>>>>> >>>      set_src values if appropriate and assign to the new node.
>>>>> >>>      (clobber_variable_part): New set_src parameter; if two  
>>>>> nodes
>>>>> >>> have
>>>>> >>>      same variable and same location but different set_src
>>>>> >>> (assignment)
>>>>> >>>      values, clobber old node.
>>>>> >>>      (delete_variable_part): Pass init status to  
>>>>> unshare_variable.
>>>>> >>>      (emit_note_insn_var_location): Add initialized var;  
>>>>> assign
>>>>> >>> var's init
>>>>> >>>      status to new 'initialized'; pass new init status field  
>>>>> to
>>>>> >>> calls to
>>>>> >>>      gen_rtx_VAR_LOCATION.  If flag_var_tracking_uninit is not
>>>>> >>> set, force
>>>>> >>>      status to initialized.
>>>>> >>>      (emit_notes_in_bb): Pass initialization status to calls  
>>>>> to
>>>>> >>>      var_reg_set, var_mem_set, var_reg_delete_and_set and
>>>>> >>>      var_mem_delete_and_set; for MO_SET, get set_src value and
>>>>> >>> pass it to
>>>>> >>>      var_reg_delete_and_set and var_mem_delete_and_set; call
>>>>> >>>      emit_notes_for_changes on NEXT_INSN(insn) rather than on
>>>>> >>> insn, to
>>>>> >>>      make up for change in add_stores.
>>>>> >>>      (vt_add_function_parameters): Add status to calls to
>>>>> >>>      set_variable_part.
>>>>> >>>      * config/darwin.c (darwin_override_options): Turn on
>>>>> >>> uninitialized
>>>>> >>>      tracking automatically, if var_tracking is on and the  
>>>>> system is
>>>>> >>>      10.5 or higher.
>>>>> >>>
>>>>> >>>
>>>>> >>> <fsf-gcc-patch.v2.txt>
>>>>> >>
>>>>> >
>>>>>
>>>>>
>>>
>>
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Ping 6! [PATCH, revised]: Track uninitialized variables
  2007-07-12 17:24                 ` Ping 6! " Caroline Tice
@ 2007-07-12 20:11                   ` Eric Christopher
  2007-07-12 21:04                     ` Caroline Tice
  0 siblings, 1 reply; 25+ messages in thread
From: Eric Christopher @ 2007-07-12 20:11 UTC (permalink / raw)
  To: Caroline Tice; +Cc: GCC Patches, Geoffrey Keating


On Jul 12, 2007, at 10:04 AM, Caroline Tice wrote:

> Ping again.  The link to the unreviewed patch is:
>
> http://gcc.gnu.org/ml/gcc-patches/2007-05/msg01240.html
>
> I believe I have answered everybody's questions so far. Please
> let me know if you have any more questions about this patch.
>

I think Ian's ok was enough?

http://gcc.gnu.org/ml/gcc-patches/2007-07/msg01065.html

-eric

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Ping 6! [PATCH, revised]: Track uninitialized variables
  2007-07-12 20:11                   ` Eric Christopher
@ 2007-07-12 21:04                     ` Caroline Tice
  0 siblings, 0 replies; 25+ messages in thread
From: Caroline Tice @ 2007-07-12 21:04 UTC (permalink / raw)
  To: Eric Christopher; +Cc: GCC Patches, Geoffrey Keating, Caroline Tice

Whoops!  Sorry I didn't see that (and I  *was* scanning the
list for an approval!);   time to get my eyes checked I guess... :-)

I will make the requested changes and commit the patch.

-- Caroline Tice
ctice@apple.com

On Jul 12, 2007, at 12:31 PM, Eric Christopher wrote:

>
> On Jul 12, 2007, at 10:04 AM, Caroline Tice wrote:
>
>> Ping again.  The link to the unreviewed patch is:
>>
>> http://gcc.gnu.org/ml/gcc-patches/2007-05/msg01240.html
>>
>> I believe I have answered everybody's questions so far. Please
>> let me know if you have any more questions about this patch.
>>
>
> I think Ian's ok was enough?
>
> http://gcc.gnu.org/ml/gcc-patches/2007-07/msg01065.html
>
> -eric
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH, revised]: Track uninitialized variables
  2007-07-11 14:45   ` Ian Lance Taylor
@ 2007-07-16 13:37     ` Richard Guenther
  2007-07-16 16:40       ` Caroline Tice
  0 siblings, 1 reply; 25+ messages in thread
From: Richard Guenther @ 2007-07-16 13:37 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Caroline Tice, gcc-patches@gcc.gnu.org Patches

On 11 Jul 2007 07:43:28 -0700, Ian Lance Taylor <iant@google.com> wrote:
> Caroline Tice <ctice@apple.com> writes:
>
> >   static dw_loc_descr_ref
> > ! one_reg_loc_descriptor (unsigned int regno, enum var_init_status initialized)
> >   {
> > +   dw_loc_descr_ref reg_loc_descr;
> >     if (regno <= 31)
> > !     reg_loc_descr = new_loc_descr (DW_OP_reg0 + regno, 0, 0);
> >     else
> > !     reg_loc_descr =  new_loc_descr (DW_OP_regx, regno, 0);
>
> Extraneous space after '='.
>
>
> > *************** multiple_reg_loc_descriptor (rtx rtl, rt
> > *** 8707,8713 ****
> >       {
> >         dw_loc_descr_ref t;
> >
> > !       t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg));
> >         add_loc_descr (&loc_result, t);
> >         add_loc_descr_op_piece (&loc_result, size);
> >         ++reg;
> > --- 8731,8738 ----
> >       {
> >         dw_loc_descr_ref t;
> >
> > !       t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg),
> > !                                   STATUS_UNINITIALIZED);
> >         add_loc_descr (&loc_result, t);
> >         add_loc_descr_op_piece (&loc_result, size);
> >         ++reg;
>
> You should be passing STATUS_INITIALIZED here, not
> STATUS_UNINITIALIZED.
>
>
> > + /* Possible initialization status of a variable.   When requested
> > +    by the user, this information is tracked and recorded in the DWARF
> > +    debug information, along with the variable's location.  */
> > + enum var_init_status
> > + {
> > +   STATUS_UNKNOWN,
> > +   STATUS_UNINITIALIZED,
> > +   STATUS_INITIALIZED
> > + };
>
> I'm sorry to do this to you, but these enum constant names are too
> generic.  Please use something like VAR_INIT_STATUS_UNKNOWN, etc.
>
>
> > +   if (!(flag_var_tracking_uninit))
> > +     initialized = STATUS_INITIALIZED;
>
> Remove the extraneous parentheses.
>
>
> > *************** emit_note_insn_var_location (void **varp
> > *** 2472,2480 ****
> >         parallel = gen_rtx_PARALLEL (VOIDmode,
> >                                  gen_rtvec_v (n_var_parts, loc));
> >         NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
> > !                                                    parallel);
> >       }
> >
> >     htab_clear_slot (changed_variables, varp);
> >
> >     /* When there are no location parts the variable has been already
> > --- 2724,2735 ----
> >         parallel = gen_rtx_PARALLEL (VOIDmode,
> >                                  gen_rtvec_v (n_var_parts, loc));
> >         NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
> > !                                                    parallel,
> > !                                                    (int) initialized);
> >       }
> >
> > +   NOTE_VAR_LOCATION_STATUS (note) = (int) initialized;
>
> Setting NOTE_VAR_LOCATION_STATUS here is redundant with passing
> initialized to gen_rtx_VAR_LOCATION.  You should either remove this
> and fix the one case of gen_rtx_VAR_LOCATION to which you pass 0
> rather than (int) initialized, or you should pass 0 in all cases to
> gen_rtx_VAR_LOCATION.
>
>
> The patch is OK with those changes.
>
> Thanks, and sorry for the slow review.

This patch breaks bootstrap on ia64.  See PR32746.

Richard.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH, revised]: Track uninitialized variables
  2007-07-16 13:37     ` Richard Guenther
@ 2007-07-16 16:40       ` Caroline Tice
  2007-07-16 17:19         ` Caroline Tice
  0 siblings, 1 reply; 25+ messages in thread
From: Caroline Tice @ 2007-07-16 16:40 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Ian Lance Taylor, gcc-patches@gcc.gnu.org Patches

I am working on this and will try to have a fix soon.

-- Caroline Tice
ctice@apple.com

On Jul 16, 2007, at 6:26 AM, Richard Guenther wrote:

> On 11 Jul 2007 07:43:28 -0700, Ian Lance Taylor <iant@google.com>  
> wrote:
>> Caroline Tice <ctice@apple.com> writes:
>>
>> >   static dw_loc_descr_ref
>> > ! one_reg_loc_descriptor (unsigned int regno, enum  
>> var_init_status initialized)
>> >   {
>> > +   dw_loc_descr_ref reg_loc_descr;
>> >     if (regno <= 31)
>> > !     reg_loc_descr = new_loc_descr (DW_OP_reg0 + regno, 0, 0);
>> >     else
>> > !     reg_loc_descr =  new_loc_descr (DW_OP_regx, regno, 0);
>>
>> Extraneous space after '='.
>>
>>
>> > *************** multiple_reg_loc_descriptor (rtx rtl, rt
>> > *** 8707,8713 ****
>> >       {
>> >         dw_loc_descr_ref t;
>> >
>> > !       t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg));
>> >         add_loc_descr (&loc_result, t);
>> >         add_loc_descr_op_piece (&loc_result, size);
>> >         ++reg;
>> > --- 8731,8738 ----
>> >       {
>> >         dw_loc_descr_ref t;
>> >
>> > !       t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg),
>> > !                                   STATUS_UNINITIALIZED);
>> >         add_loc_descr (&loc_result, t);
>> >         add_loc_descr_op_piece (&loc_result, size);
>> >         ++reg;
>>
>> You should be passing STATUS_INITIALIZED here, not
>> STATUS_UNINITIALIZED.
>>
>>
>> > + /* Possible initialization status of a variable.   When requested
>> > +    by the user, this information is tracked and recorded in the  
>> DWARF
>> > +    debug information, along with the variable's location.  */
>> > + enum var_init_status
>> > + {
>> > +   STATUS_UNKNOWN,
>> > +   STATUS_UNINITIALIZED,
>> > +   STATUS_INITIALIZED
>> > + };
>>
>> I'm sorry to do this to you, but these enum constant names are too
>> generic.  Please use something like VAR_INIT_STATUS_UNKNOWN, etc.
>>
>>
>> > +   if (!(flag_var_tracking_uninit))
>> > +     initialized = STATUS_INITIALIZED;
>>
>> Remove the extraneous parentheses.
>>
>>
>> > *************** emit_note_insn_var_location (void **varp
>> > *** 2472,2480 ****
>> >         parallel = gen_rtx_PARALLEL (VOIDmode,
>> >                                  gen_rtvec_v (n_var_parts, loc));
>> >         NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION  
>> (VOIDmode, var->decl,
>> > !                                                    parallel);
>> >       }
>> >
>> >     htab_clear_slot (changed_variables, varp);
>> >
>> >     /* When there are no location parts the variable has been  
>> already
>> > --- 2724,2735 ----
>> >         parallel = gen_rtx_PARALLEL (VOIDmode,
>> >                                  gen_rtvec_v (n_var_parts, loc));
>> >         NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION  
>> (VOIDmode, var->decl,
>> > !                                                    parallel,
>> > !                                                    (int)  
>> initialized);
>> >       }
>> >
>> > +   NOTE_VAR_LOCATION_STATUS (note) = (int) initialized;
>>
>> Setting NOTE_VAR_LOCATION_STATUS here is redundant with passing
>> initialized to gen_rtx_VAR_LOCATION.  You should either remove this
>> and fix the one case of gen_rtx_VAR_LOCATION to which you pass 0
>> rather than (int) initialized, or you should pass 0 in all cases to
>> gen_rtx_VAR_LOCATION.
>>
>>
>> The patch is OK with those changes.
>>
>> Thanks, and sorry for the slow review.
>
> This patch breaks bootstrap on ia64.  See PR32746.
>
> Richard.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH, revised]: Track uninitialized variables
  2007-07-16 16:40       ` Caroline Tice
@ 2007-07-16 17:19         ` Caroline Tice
  2007-07-16 17:33           ` H.J. Lu
  0 siblings, 1 reply; 25+ messages in thread
From: Caroline Tice @ 2007-07-16 17:19 UTC (permalink / raw)
  To: gcc-patches@gcc.gnu.org Patches, Richard Guenther; +Cc: Caroline Tice


I have a tentative patch to fix this problem, but I don't have an ia64  
box
to test it with.  I will try to do the cross-platform build/testing  
stuff, but if
anybody out there with an ia64 machine would like to help me test my
patch it would probably get done a lot faster.  Any volunteers to help?

-- Caroline Tice
ctice@apple.com

On Jul 16, 2007, at 9:22 AM, Caroline Tice wrote:

> I am working on this and will try to have a fix soon.
>
> -- Caroline Tice
> ctice@apple.com
>
> On Jul 16, 2007, at 6:26 AM, Richard Guenther wrote:
>
>> On 11 Jul 2007 07:43:28 -0700, Ian Lance Taylor <iant@google.com>  
>> wrote:
>>> Caroline Tice <ctice@apple.com> writes:
>>>
>>> >   static dw_loc_descr_ref
>>> > ! one_reg_loc_descriptor (unsigned int regno, enum  
>>> var_init_status initialized)
>>> >   {
>>> > +   dw_loc_descr_ref reg_loc_descr;
>>> >     if (regno <= 31)
>>> > !     reg_loc_descr = new_loc_descr (DW_OP_reg0 + regno, 0, 0);
>>> >     else
>>> > !     reg_loc_descr =  new_loc_descr (DW_OP_regx, regno, 0);
>>>
>>> Extraneous space after '='.
>>>
>>>
>>> > *************** multiple_reg_loc_descriptor (rtx rtl, rt
>>> > *** 8707,8713 ****
>>> >       {
>>> >         dw_loc_descr_ref t;
>>> >
>>> > !       t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg));
>>> >         add_loc_descr (&loc_result, t);
>>> >         add_loc_descr_op_piece (&loc_result, size);
>>> >         ++reg;
>>> > --- 8731,8738 ----
>>> >       {
>>> >         dw_loc_descr_ref t;
>>> >
>>> > !       t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg),
>>> > !                                   STATUS_UNINITIALIZED);
>>> >         add_loc_descr (&loc_result, t);
>>> >         add_loc_descr_op_piece (&loc_result, size);
>>> >         ++reg;
>>>
>>> You should be passing STATUS_INITIALIZED here, not
>>> STATUS_UNINITIALIZED.
>>>
>>>
>>> > + /* Possible initialization status of a variable.   When  
>>> requested
>>> > +    by the user, this information is tracked and recorded in  
>>> the DWARF
>>> > +    debug information, along with the variable's location.  */
>>> > + enum var_init_status
>>> > + {
>>> > +   STATUS_UNKNOWN,
>>> > +   STATUS_UNINITIALIZED,
>>> > +   STATUS_INITIALIZED
>>> > + };
>>>
>>> I'm sorry to do this to you, but these enum constant names are too
>>> generic.  Please use something like VAR_INIT_STATUS_UNKNOWN, etc.
>>>
>>>
>>> > +   if (!(flag_var_tracking_uninit))
>>> > +     initialized = STATUS_INITIALIZED;
>>>
>>> Remove the extraneous parentheses.
>>>
>>>
>>> > *************** emit_note_insn_var_location (void **varp
>>> > *** 2472,2480 ****
>>> >         parallel = gen_rtx_PARALLEL (VOIDmode,
>>> >                                  gen_rtvec_v (n_var_parts, loc));
>>> >         NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION  
>>> (VOIDmode, var->decl,
>>> > !                                                    parallel);
>>> >       }
>>> >
>>> >     htab_clear_slot (changed_variables, varp);
>>> >
>>> >     /* When there are no location parts the variable has been  
>>> already
>>> > --- 2724,2735 ----
>>> >         parallel = gen_rtx_PARALLEL (VOIDmode,
>>> >                                  gen_rtvec_v (n_var_parts, loc));
>>> >         NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION  
>>> (VOIDmode, var->decl,
>>> > !                                                    parallel,
>>> > !                                                    (int)  
>>> initialized);
>>> >       }
>>> >
>>> > +   NOTE_VAR_LOCATION_STATUS (note) = (int) initialized;
>>>
>>> Setting NOTE_VAR_LOCATION_STATUS here is redundant with passing
>>> initialized to gen_rtx_VAR_LOCATION.  You should either remove this
>>> and fix the one case of gen_rtx_VAR_LOCATION to which you pass 0
>>> rather than (int) initialized, or you should pass 0 in all cases to
>>> gen_rtx_VAR_LOCATION.
>>>
>>>
>>> The patch is OK with those changes.
>>>
>>> Thanks, and sorry for the slow review.
>>
>> This patch breaks bootstrap on ia64.  See PR32746.
>>
>> Richard.
>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH, revised]: Track uninitialized variables
  2007-07-16 17:19         ` Caroline Tice
@ 2007-07-16 17:33           ` H.J. Lu
  0 siblings, 0 replies; 25+ messages in thread
From: H.J. Lu @ 2007-07-16 17:33 UTC (permalink / raw)
  To: Caroline Tice; +Cc: gcc-patches@gcc.gnu.org Patches, Richard Guenther

On Mon, Jul 16, 2007 at 09:50:02AM -0700, Caroline Tice wrote:
> 
> I have a tentative patch to fix this problem, but I don't have an ia64  
> box
> to test it with.  I will try to do the cross-platform build/testing  
> stuff, but if
> anybody out there with an ia64 machine would like to help me test my
> patch it would probably get done a lot faster.  Any volunteers to help?
> 

You only need to build a partial cross compiler to Linux/ia64 since
the build may not finish due to lack of glibc. However, it should
be good enough to test the testcase in

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32764

If it passes, I will test gcc on Linux/ia64 with your fix.

Thanks.


H.J.

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2007-07-16 17:26 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-05-02  0:03 [PATCH]: Track uninitialized variables Caroline Tice
2007-05-08 16:25 ` Ping! " Caroline Tice
2007-05-09  0:28 ` Ian Lance Taylor
2007-05-09 16:48   ` Caroline Tice
2007-05-09 17:40     ` Caroline Tice
2007-05-09 18:08     ` Ian Lance Taylor
2007-05-09 18:16       ` Daniel Jacobowitz
2007-05-10  3:29         ` Mark Mitchell
2007-05-11 19:13 ` [PATCH, revised]: " Caroline Tice
2007-05-18 19:48   ` Ping! " Caroline Tice
2007-05-25 21:26     ` Ping2! " Caroline Tice
2007-06-01 16:59       ` Ping3! " Caroline Tice
2007-06-01 17:13         ` Manuel López-Ibáñez
2007-06-01 17:24           ` Caroline Tice
2007-06-08 17:52             ` Ping 4! " Caroline Tice
2007-06-21 17:02               ` Ping 5! " Caroline Tice
2007-06-23 18:54                 ` Mark Mitchell
2007-07-12 17:24                 ` Ping 6! " Caroline Tice
2007-07-12 20:11                   ` Eric Christopher
2007-07-12 21:04                     ` Caroline Tice
2007-07-11 14:45   ` Ian Lance Taylor
2007-07-16 13:37     ` Richard Guenther
2007-07-16 16:40       ` Caroline Tice
2007-07-16 17:19         ` Caroline Tice
2007-07-16 17:33           ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).