diff mbox

Cleanup tree-ssa-uninit.c exports

Message ID 5231C76A.8050306@redhat.com
State New
Headers show

Commit Message

Andrew MacLeod Sept. 12, 2013, 1:53 p.m. UTC
It turns out that ssa_undefined_value_p() is also used in tree-complex.c 
and tree-ssa-pre.c.  doh.

That routine is *almost* pass independent...  only the last line uses 
'possibly_undefined_names'.  Since the late warning pass initializes and 
then clears that pointer_set when done, those other 2 passes obviously 
don't need that part.

So I moved the majority of  ssa_undefined_value_p() to tree-ssa.c and 
added a new local routine  'has_undefined_value_p()' to 
tree-ssa-uninit.c.   It first calls ssa_undefined_value_p() and then 
does the pass dependent check.

I also moved the early warning pass stuff from tree-ssa.c into 
tree-ssa-uninit.c where it belongs.

Now there is nothing exported from tree-ssa-uninit.c, and the one pass 
independent routine is now in tree-ssa.[ch].

Bootstrapped on x86_64-unknown-linux-gnu.  regression  testing 
underway.  Assuming no regressions, OK?

Andrew

Comments

Richard Biener Sept. 12, 2013, 2:09 p.m. UTC | #1
On Thu, Sep 12, 2013 at 3:53 PM, Andrew MacLeod <amacleod@redhat.com> wrote:
> It turns out that ssa_undefined_value_p() is also used in tree-complex.c and
> tree-ssa-pre.c.  doh.
>
> That routine is *almost* pass independent...  only the last line uses
> 'possibly_undefined_names'.  Since the late warning pass initializes and
> then clears that pointer_set when done, those other 2 passes obviously don't
> need that part.
>
> So I moved the majority of  ssa_undefined_value_p() to tree-ssa.c and added
> a new local routine  'has_undefined_value_p()' to tree-ssa-uninit.c.   It
> first calls ssa_undefined_value_p() and then does the pass dependent check.
>
> I also moved the early warning pass stuff from tree-ssa.c into
> tree-ssa-uninit.c where it belongs.
>
> Now there is nothing exported from tree-ssa-uninit.c, and the one pass
> independent routine is now in tree-ssa.[ch].
>
> Bootstrapped on x86_64-unknown-linux-gnu.  regression  testing underway.
> Assuming no regressions, OK?

Ok.

Thanks!
Richard.

> Andrew
diff mbox

Patch


	* tree-flow.h (ssa_undefined_value_p): Remove prototype.
	* tree-ssa.c (ssa_undefined_value_p): Move pass independent parts here.
	(warn_uninit, warn_uninitialized_vars, execute_early_warn_uninitialized,
	make_pass_early_warn_uninitialized): Move to tree-ssa-uninit.c.
	* tree-ssa-uninit.c (ssa_undefined_value_p): Move to tree-ssa.c
	(has_undefined_value_p): New.  Pass dependant parts of 
	ssa_undefined_value_p.
	(uninit_undefined_value_p): Use has_undefined_value_p.
	(warn_uninit, warn_uninitialized_vars, execute_early_warn_uninitialized,
	make_pass_early_warn_uninitialized): Move from tree-ssa.c
	* tree-ssa.h: Adjust prototypes

Index: tree-flow.h
===================================================================
*** tree-flow.h	(revision 202527)
--- tree-flow.h	(working copy)
*************** extern bool gimple_seq_may_fallthru (gim
*** 421,429 ****
  extern bool gimple_stmt_may_fallthru (gimple);
  extern bool gimple_check_call_matching_types (gimple, tree, bool);
  
- /* In tree-ssa-uninit.c  */
- extern bool ssa_undefined_value_p (tree);
- 
  /* In tree-into-ssa.c  */
  void update_ssa (unsigned);
  void delete_update_ssa (void);
--- 421,426 ----
Index: tree-ssa.c
===================================================================
*** tree-ssa.c	(revision 202525)
--- tree-ssa.c	(working copy)
*************** tree_ssa_strip_useless_type_conversions
*** 1182,1187 ****
--- 1182,1212 ----
  }
  
  
+ /* Return true if T, an SSA_NAME, has an undefined value.  */
+ 
+ bool
+ ssa_undefined_value_p (tree t)
+ {
+   tree var = SSA_NAME_VAR (t);
+ 
+   if (!var)
+     ;
+   /* Parameters get their initial value from the function entry.  */
+   else if (TREE_CODE (var) == PARM_DECL)
+     return false;
+   /* When returning by reference the return address is actually a hidden
+      parameter.  */
+   else if (TREE_CODE (var) == RESULT_DECL && DECL_BY_REFERENCE (var))
+     return false;
+   /* Hard register variables get their initial value from the ether.  */
+   else if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var))
+     return false;
+ 
+   /* The value is undefined iff its definition statement is empty.  */
+   return gimple_nop_p (SSA_NAME_DEF_STMT (t));
+ }
+ 
+ 
  /* Internal helper for walk_use_def_chains.  VAR, FN and DATA are as
     described in walk_use_def_chains.
  
*************** walk_use_def_chains (tree var, walk_use_
*** 1290,1504 ****
      }
  }
  
- 
- /* Emit warnings for uninitialized variables.  This is done in two passes.
- 
-    The first pass notices real uses of SSA names with undefined values.
-    Such uses are unconditionally uninitialized, and we can be certain that
-    such a use is a mistake.  This pass is run before most optimizations,
-    so that we catch as many as we can.
- 
-    The second pass follows PHI nodes to find uses that are potentially
-    uninitialized.  In this case we can't necessarily prove that the use
-    is really uninitialized.  This pass is run after most optimizations,
-    so that we thread as many jumps and possible, and delete as much dead
-    code as possible, in order to reduce false positives.  We also look
-    again for plain uninitialized variables, since optimization may have
-    changed conditionally uninitialized to unconditionally uninitialized.  */
- 
- /* Emit a warning for EXPR based on variable VAR at the point in the
-    program T, an SSA_NAME, is used being uninitialized.  The exact
-    warning text is in MSGID and LOCUS may contain a location or be null.
-    WC is the warning code.  */
- 
- void
- warn_uninit (enum opt_code wc, tree t,
- 	     tree expr, tree var, const char *gmsgid, void *data)
- {
-   gimple context = (gimple) data;
-   location_t location, cfun_loc;
-   expanded_location xloc, floc;
- 
-   if (!ssa_undefined_value_p (t))
-     return;
- 
-   /* TREE_NO_WARNING either means we already warned, or the front end
-      wishes to suppress the warning.  */
-   if ((context
-        && (gimple_no_warning_p (context)
- 	   || (gimple_assign_single_p (context)
- 	       && TREE_NO_WARNING (gimple_assign_rhs1 (context)))))
-       || TREE_NO_WARNING (expr))
-     return;
- 
-   location = (context != NULL && gimple_has_location (context))
- 	     ? gimple_location (context)
- 	     : DECL_SOURCE_LOCATION (var);
-   location = linemap_resolve_location (line_table, location,
- 				       LRK_SPELLING_LOCATION,
- 				       NULL);
-   cfun_loc = DECL_SOURCE_LOCATION (cfun->decl);
-   xloc = expand_location (location);
-   floc = expand_location (cfun_loc);
-   if (warning_at (location, wc, gmsgid, expr))
-     {
-       TREE_NO_WARNING (expr) = 1;
- 
-       if (location == DECL_SOURCE_LOCATION (var))
- 	return;
-       if (xloc.file != floc.file
- 	  || linemap_location_before_p (line_table,
- 					location, cfun_loc)
- 	  || linemap_location_before_p (line_table,
- 					cfun->function_end_locus,
- 					location))
- 	inform (DECL_SOURCE_LOCATION (var), "%qD was declared here", var);
-     }
- }
- 
- unsigned int
- warn_uninitialized_vars (bool warn_possibly_uninitialized)
- {
-   gimple_stmt_iterator gsi;
-   basic_block bb;
- 
-   FOR_EACH_BB (bb)
-     {
-       bool always_executed = dominated_by_p (CDI_POST_DOMINATORS,
- 					     single_succ (ENTRY_BLOCK_PTR), bb);
-       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- 	{
- 	  gimple stmt = gsi_stmt (gsi);
- 	  use_operand_p use_p;
- 	  ssa_op_iter op_iter;
- 	  tree use;
- 
- 	  if (is_gimple_debug (stmt))
- 	    continue;
- 
- 	  /* We only do data flow with SSA_NAMEs, so that's all we
- 	     can warn about.  */
- 	  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
- 	    {
- 	      use = USE_FROM_PTR (use_p);
- 	      if (always_executed)
- 		warn_uninit (OPT_Wuninitialized, use,
- 			     SSA_NAME_VAR (use), SSA_NAME_VAR (use),
- 			     "%qD is used uninitialized in this function",
- 			     stmt);
- 	      else if (warn_possibly_uninitialized)
- 		warn_uninit (OPT_Wmaybe_uninitialized, use,
- 			     SSA_NAME_VAR (use), SSA_NAME_VAR (use),
- 			     "%qD may be used uninitialized in this function",
- 			     stmt);
- 	    }
- 
- 	  /* For memory the only cheap thing we can do is see if we
- 	     have a use of the default def of the virtual operand.
- 	     ???  Note that at -O0 we do not have virtual operands.
- 	     ???  Not so cheap would be to use the alias oracle via
- 	     walk_aliased_vdefs, if we don't find any aliasing vdef
- 	     warn as is-used-uninitialized, if we don't find an aliasing
- 	     vdef that kills our use (stmt_kills_ref_p), warn as
- 	     may-be-used-uninitialized.  But this walk is quadratic and
- 	     so must be limited which means we would miss warning
- 	     opportunities.  */
- 	  use = gimple_vuse (stmt);
- 	  if (use
- 	      && gimple_assign_single_p (stmt)
- 	      && !gimple_vdef (stmt)
- 	      && SSA_NAME_IS_DEFAULT_DEF (use))
- 	    {
- 	      tree rhs = gimple_assign_rhs1 (stmt);
- 	      tree base = get_base_address (rhs);
- 
- 	      /* Do not warn if it can be initialized outside this function.  */
- 	      if (TREE_CODE (base) != VAR_DECL
- 		  || DECL_HARD_REGISTER (base)
- 		  || is_global_var (base))
- 		continue;
- 
- 	      if (always_executed)
- 		warn_uninit (OPT_Wuninitialized, use, 
- 			     gimple_assign_rhs1 (stmt), base,
- 			     "%qE is used uninitialized in this function",
- 			     stmt);
- 	      else if (warn_possibly_uninitialized)
- 		warn_uninit (OPT_Wmaybe_uninitialized, use,
- 			     gimple_assign_rhs1 (stmt), base,
- 			     "%qE may be used uninitialized in this function",
- 			     stmt);
- 	    }
- 	}
-     }
- 
-   return 0;
- }
- 
- static unsigned int
- execute_early_warn_uninitialized (void)
- {
-   /* Currently, this pass runs always but
-      execute_late_warn_uninitialized only runs with optimization. With
-      optimization we want to warn about possible uninitialized as late
-      as possible, thus don't do it here.  However, without
-      optimization we need to warn here about "may be uninitialized".
-   */
-   calculate_dominance_info (CDI_POST_DOMINATORS);
- 
-   warn_uninitialized_vars (/*warn_possibly_uninitialized=*/!optimize);
- 
-   /* Post-dominator information can not be reliably updated. Free it
-      after the use.  */
- 
-   free_dominance_info (CDI_POST_DOMINATORS);
-   return 0;
- }
- 
- static bool
- gate_warn_uninitialized (void)
- {
-   return warn_uninitialized != 0;
- }
- 
- namespace {
- 
- const pass_data pass_data_early_warn_uninitialized =
- {
-   GIMPLE_PASS, /* type */
-   "*early_warn_uninitialized", /* name */
-   OPTGROUP_NONE, /* optinfo_flags */
-   true, /* has_gate */
-   true, /* has_execute */
-   TV_TREE_UNINIT, /* tv_id */
-   PROP_ssa, /* properties_required */
-   0, /* properties_provided */
-   0, /* properties_destroyed */
-   0, /* todo_flags_start */
-   0, /* todo_flags_finish */
- };
- 
- class pass_early_warn_uninitialized : public gimple_opt_pass
- {
- public:
-   pass_early_warn_uninitialized(gcc::context *ctxt)
-     : gimple_opt_pass(pass_data_early_warn_uninitialized, ctxt)
-   {}
- 
-   /* opt_pass methods: */
-   bool gate () { return gate_warn_uninitialized (); }
-   unsigned int execute () { return execute_early_warn_uninitialized (); }
- 
- }; // class pass_early_warn_uninitialized
- 
- } // anon namespace
- 
- gimple_opt_pass *
- make_pass_early_warn_uninitialized (gcc::context *ctxt)
- {
-   return new pass_early_warn_uninitialized (ctxt);
- }
- 
  
  /* If necessary, rewrite the base of the reference tree *TP from
     a MEM_REF to a plain or converted symbol.  */
--- 1315,1320 ----
Index: tree-ssa-uninit.c
===================================================================
*** tree-ssa-uninit.c	(revision 202525)
--- tree-ssa-uninit.c	(working copy)
*************** get_mask_first_set_bit (unsigned mask)
*** 74,119 ****
  }
  #define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask)
  
- 
  /* Return true if T, an SSA_NAME, has an undefined value.  */
! 
! bool
! ssa_undefined_value_p (tree t)
  {
!   tree var = SSA_NAME_VAR (t);
! 
!   if (!var)
!     ;
!   /* Parameters get their initial value from the function entry.  */
!   else if (TREE_CODE (var) == PARM_DECL)
!     return false;
!   /* When returning by reference the return address is actually a hidden
!      parameter.  */
!   else if (TREE_CODE (var) == RESULT_DECL && DECL_BY_REFERENCE (var))
!     return false;
!   /* Hard register variables get their initial value from the ether.  */
!   else if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var))
!     return false;
! 
!   /* The value is undefined iff its definition statement is empty.  */
!   return (gimple_nop_p (SSA_NAME_DEF_STMT (t))
            || (possibly_undefined_names
                && pointer_set_contains (possibly_undefined_names, t)));
  }
  
! /* Like ssa_undefined_value_p, but don't return true if TREE_NO_WARNING
     is set on SSA_NAME_VAR.  */
  
  static inline bool
! uninit_undefined_value_p (tree t)
! {
!   if (!ssa_undefined_value_p (t))
      return false;
    if (SSA_NAME_VAR (t) && TREE_NO_WARNING (SSA_NAME_VAR (t)))
      return false;
    return true;
  }
  
  /* Checks if the operand OPND of PHI is defined by 
     another phi with one operand defined by this PHI, 
     but the rest operands are all defined. If yes, 
--- 74,246 ----
  }
  #define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask)
  
  /* Return true if T, an SSA_NAME, has an undefined value.  */
! static bool
! has_undefined_value_p (tree t)
  {
!   return (ssa_undefined_value_p (t)
            || (possibly_undefined_names
                && pointer_set_contains (possibly_undefined_names, t)));
  }
  
! 
! 
! /* Like has_undefined_value_p, but don't return true if TREE_NO_WARNING
     is set on SSA_NAME_VAR.  */
  
  static inline bool
! uninit_undefined_value_p (tree t) {
!   if (!has_undefined_value_p (t))
      return false;
    if (SSA_NAME_VAR (t) && TREE_NO_WARNING (SSA_NAME_VAR (t)))
      return false;
    return true;
  }
  
+ /* Emit warnings for uninitialized variables.  This is done in two passes.
+ 
+    The first pass notices real uses of SSA names with undefined values.
+    Such uses are unconditionally uninitialized, and we can be certain that
+    such a use is a mistake.  This pass is run before most optimizations,
+    so that we catch as many as we can.
+ 
+    The second pass follows PHI nodes to find uses that are potentially
+    uninitialized.  In this case we can't necessarily prove that the use
+    is really uninitialized.  This pass is run after most optimizations,
+    so that we thread as many jumps and possible, and delete as much dead
+    code as possible, in order to reduce false positives.  We also look
+    again for plain uninitialized variables, since optimization may have
+    changed conditionally uninitialized to unconditionally uninitialized.  */
+ 
+ /* Emit a warning for EXPR based on variable VAR at the point in the
+    program T, an SSA_NAME, is used being uninitialized.  The exact
+    warning text is in MSGID and LOCUS may contain a location or be null.
+    WC is the warning code.  */
+ 
+ static void
+ warn_uninit (enum opt_code wc, tree t,
+ 	     tree expr, tree var, const char *gmsgid, void *data)
+ {
+   gimple context = (gimple) data;
+   location_t location, cfun_loc;
+   expanded_location xloc, floc;
+ 
+   if (!has_undefined_value_p (t))
+     return;
+ 
+   /* TREE_NO_WARNING either means we already warned, or the front end
+      wishes to suppress the warning.  */
+   if ((context
+        && (gimple_no_warning_p (context)
+ 	   || (gimple_assign_single_p (context)
+ 	       && TREE_NO_WARNING (gimple_assign_rhs1 (context)))))
+       || TREE_NO_WARNING (expr))
+     return;
+ 
+   location = (context != NULL && gimple_has_location (context))
+ 	     ? gimple_location (context)
+ 	     : DECL_SOURCE_LOCATION (var);
+   location = linemap_resolve_location (line_table, location,
+ 				       LRK_SPELLING_LOCATION,
+ 				       NULL);
+   cfun_loc = DECL_SOURCE_LOCATION (cfun->decl);
+   xloc = expand_location (location);
+   floc = expand_location (cfun_loc);
+   if (warning_at (location, wc, gmsgid, expr))
+     {
+       TREE_NO_WARNING (expr) = 1;
+ 
+       if (location == DECL_SOURCE_LOCATION (var))
+ 	return;
+       if (xloc.file != floc.file
+ 	  || linemap_location_before_p (line_table,
+ 					location, cfun_loc)
+ 	  || linemap_location_before_p (line_table,
+ 					cfun->function_end_locus,
+ 					location))
+ 	inform (DECL_SOURCE_LOCATION (var), "%qD was declared here", var);
+     }
+ }
+ 
+ static unsigned int
+ warn_uninitialized_vars (bool warn_possibly_uninitialized)
+ {
+   gimple_stmt_iterator gsi;
+   basic_block bb;
+ 
+   FOR_EACH_BB (bb)
+     {
+       bool always_executed = dominated_by_p (CDI_POST_DOMINATORS,
+ 					     single_succ (ENTRY_BLOCK_PTR), bb);
+       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ 	{
+ 	  gimple stmt = gsi_stmt (gsi);
+ 	  use_operand_p use_p;
+ 	  ssa_op_iter op_iter;
+ 	  tree use;
+ 
+ 	  if (is_gimple_debug (stmt))
+ 	    continue;
+ 
+ 	  /* We only do data flow with SSA_NAMEs, so that's all we
+ 	     can warn about.  */
+ 	  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
+ 	    {
+ 	      use = USE_FROM_PTR (use_p);
+ 	      if (always_executed)
+ 		warn_uninit (OPT_Wuninitialized, use,
+ 			     SSA_NAME_VAR (use), SSA_NAME_VAR (use),
+ 			     "%qD is used uninitialized in this function",
+ 			     stmt);
+ 	      else if (warn_possibly_uninitialized)
+ 		warn_uninit (OPT_Wmaybe_uninitialized, use,
+ 			     SSA_NAME_VAR (use), SSA_NAME_VAR (use),
+ 			     "%qD may be used uninitialized in this function",
+ 			     stmt);
+ 	    }
+ 
+ 	  /* For memory the only cheap thing we can do is see if we
+ 	     have a use of the default def of the virtual operand.
+ 	     ???  Note that at -O0 we do not have virtual operands.
+ 	     ???  Not so cheap would be to use the alias oracle via
+ 	     walk_aliased_vdefs, if we don't find any aliasing vdef
+ 	     warn as is-used-uninitialized, if we don't find an aliasing
+ 	     vdef that kills our use (stmt_kills_ref_p), warn as
+ 	     may-be-used-uninitialized.  But this walk is quadratic and
+ 	     so must be limited which means we would miss warning
+ 	     opportunities.  */
+ 	  use = gimple_vuse (stmt);
+ 	  if (use
+ 	      && gimple_assign_single_p (stmt)
+ 	      && !gimple_vdef (stmt)
+ 	      && SSA_NAME_IS_DEFAULT_DEF (use))
+ 	    {
+ 	      tree rhs = gimple_assign_rhs1 (stmt);
+ 	      tree base = get_base_address (rhs);
+ 
+ 	      /* Do not warn if it can be initialized outside this function.  */
+ 	      if (TREE_CODE (base) != VAR_DECL
+ 		  || DECL_HARD_REGISTER (base)
+ 		  || is_global_var (base))
+ 		continue;
+ 
+ 	      if (always_executed)
+ 		warn_uninit (OPT_Wuninitialized, use, 
+ 			     gimple_assign_rhs1 (stmt), base,
+ 			     "%qE is used uninitialized in this function",
+ 			     stmt);
+ 	      else if (warn_possibly_uninitialized)
+ 		warn_uninit (OPT_Wmaybe_uninitialized, use,
+ 			     gimple_assign_rhs1 (stmt), base,
+ 			     "%qE may be used uninitialized in this function",
+ 			     stmt);
+ 	    }
+ 	}
+     }
+ 
+   return 0;
+ }
+ 
  /* Checks if the operand OPND of PHI is defined by 
     another phi with one operand defined by this PHI, 
     but the rest operands are all defined. If yes, 
*************** make_pass_late_warn_uninitialized (gcc::
*** 2084,2086 ****
--- 2211,2275 ----
  {
    return new pass_late_warn_uninitialized (ctxt);
  }
+ 
+ 
+ static unsigned int
+ execute_early_warn_uninitialized (void)
+ {
+   /* Currently, this pass runs always but
+      execute_late_warn_uninitialized only runs with optimization. With
+      optimization we want to warn about possible uninitialized as late
+      as possible, thus don't do it here.  However, without
+      optimization we need to warn here about "may be uninitialized".
+   */
+   calculate_dominance_info (CDI_POST_DOMINATORS);
+ 
+   warn_uninitialized_vars (/*warn_possibly_uninitialized=*/!optimize);
+ 
+   /* Post-dominator information can not be reliably updated. Free it
+      after the use.  */
+ 
+   free_dominance_info (CDI_POST_DOMINATORS);
+   return 0;
+ }
+ 
+ 
+ namespace {
+ 
+ const pass_data pass_data_early_warn_uninitialized =
+ {
+   GIMPLE_PASS, /* type */
+   "*early_warn_uninitialized", /* name */
+   OPTGROUP_NONE, /* optinfo_flags */
+   true, /* has_gate */
+   true, /* has_execute */
+   TV_TREE_UNINIT, /* tv_id */
+   PROP_ssa, /* properties_required */
+   0, /* properties_provided */
+   0, /* properties_destroyed */
+   0, /* todo_flags_start */
+   0, /* todo_flags_finish */
+ };
+ 
+ class pass_early_warn_uninitialized : public gimple_opt_pass
+ {
+ public:
+   pass_early_warn_uninitialized(gcc::context *ctxt)
+     : gimple_opt_pass(pass_data_early_warn_uninitialized, ctxt)
+   {}
+ 
+   /* opt_pass methods: */
+   bool gate () { return gate_warn_uninitialized (); }
+   unsigned int execute () { return execute_early_warn_uninitialized (); }
+ 
+ }; // class pass_early_warn_uninitialized
+ 
+ } // anon namespace
+ 
+ gimple_opt_pass *
+ make_pass_early_warn_uninitialized (gcc::context *ctxt)
+ {
+   return new pass_early_warn_uninitialized (ctxt);
+ }
+ 
+ 
Index: tree-ssa.h
===================================================================
*** tree-ssa.h	(revision 202527)
--- tree-ssa.h	(working copy)
*************** extern tree tree_ssa_strip_useless_type_
*** 58,65 ****
  typedef bool (*walk_use_def_chains_fn) (tree, gimple, void *);
  extern void walk_use_def_chains (tree, walk_use_def_chains_fn, void *, bool);
  
! extern void warn_uninit (enum opt_code, tree, tree, tree, const char *, void *);
! extern unsigned int warn_uninitialized_vars (bool);
  extern void execute_update_addresses_taken (void);
  
  /* Given an edge_var_map V, return the PHI arg definition.  */
--- 58,64 ----
  typedef bool (*walk_use_def_chains_fn) (tree, gimple, void *);
  extern void walk_use_def_chains (tree, walk_use_def_chains_fn, void *, bool);
  
! extern bool ssa_undefined_value_p (tree);
  extern void execute_update_addresses_taken (void);
  
  /* Given an edge_var_map V, return the PHI arg definition.  */