This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: IPA merge part 1: localize SSA variables


Hi,
I started to execute our plot and this is WIP patch I have (no changelog
and sufficient testing yet).  I am sending it for further disucssion as
I slightly diverged from original idea.

The reason is that I don't think we should blindly have
gimple_/gimple_set accessors for everything in tree-flow.h as it would
just increase size of the header and give false feeling that all those
variables are public and shall be set by everyone.  For many of fields
we do have existing accessors and I think it makes sense to update them
directly to use the gimple_df structure.  Also it seems to me that there
is no need for gimple_set accessor for things wich are set/reset on one
place only and are designed to be so.

So I ended up with read only accessors to the fields shared across number of
modules and I also found that the gimple/gimple_set scheme does not work
too well with vectors since those do & operator on the vector parameter of
macro requiring it to be lvalue.

Luckilly I think writes to all vectors we have are sufficiently abstracted
(particularly it is ssa_names set inly in tree-ssa-names and
modified_noreturn_calls set once in mark_stmt_modified and once reset in
cfgcleanup.c)

What do you think?  I definitly have no problems with adding the missing
set_ accessors if it looks like preferred variant.

Also I would like to followup with few extra renaming and pushing in FUN
argument to the existing accessors that are now intermixed with new
gimple_* scheme (such as ssa_names/num_ssa_names macros that shall
become inline functions too IMO).  If the scheme works out, I would like
to do similar changes to cfg bits so we can ideally remove
push_cfun/pop_cfun stuff in tree-inline.c and turn it into cleaner IPA
pass.

I hope to do this incrementally in parallel with IPA branch merge to not
delay it significantly - there is enought additional fun to discuss on
this thread.

In longer run I am not sure how far we want to go with elliminating
global cfun accesses.  It definitly do make sense to keep them in local
passes - we don't want to add extra argument to every single function in
GCC. On the other hand it would be nice from IPA point of view to do,
for instance, cfgcleanup directly on specified function after some IP
transformation was performed.

Honza

Index: tree-into-ssa.c
===================================================================
*** tree-into-ssa.c	(revision 118887)
--- tree-into-ssa.c	(working copy)
*************** Boston, MA 02110-1301, USA.  */
*** 55,63 ****
     Graph. ACM Transactions on Programming Languages and Systems,
     13(4):451-490, October 1991.  */
  
- /* True if the code is in ssa form.  */
- bool in_ssa_p;
- 
  /* Structure to map a variable VAR to the set of blocks that contain
     definitions for VAR.  */
  struct def_blocks_d
--- 55,60 ----
*************** rewrite_into_ssa (void)
*** 2122,2128 ****
    sbitmap_free (interesting_blocks);
  
    timevar_pop (TV_TREE_SSA_OTHER);
!   in_ssa_p = true;
    return 0;
  }
  
--- 2119,2125 ----
    sbitmap_free (interesting_blocks);
  
    timevar_pop (TV_TREE_SSA_OTHER);
!   cfun->gimple_df->in_ssa_p = true;
    return 0;
  }
  
Index: tree-complex.c
===================================================================
*** tree-complex.c	(revision 118887)
--- tree-complex.c	(working copy)
*************** update_complex_assignment (block_stmt_it
*** 625,631 ****
    mod = stmt = bsi_stmt (*bsi);
    if (TREE_CODE (stmt) == RETURN_EXPR)
      mod = TREE_OPERAND (mod, 0);
!   else if (in_ssa_p)
      update_complex_components (bsi, stmt, r, i);
    
    type = TREE_TYPE (TREE_OPERAND (mod, 1));
--- 625,631 ----
    mod = stmt = bsi_stmt (*bsi);
    if (TREE_CODE (stmt) == RETURN_EXPR)
      mod = TREE_OPERAND (mod, 0);
!   else if (gimple_in_ssa_p (cfun))
      update_complex_components (bsi, stmt, r, i);
    
    type = TREE_TYPE (TREE_OPERAND (mod, 1));
*************** expand_complex_libcall (block_stmt_itera
*** 910,916 ****
      = build3 (CALL_EXPR, type, build_fold_addr_expr (fn), args, NULL);
    update_stmt (stmt);
  
!   if (in_ssa_p)
      {
        tree lhs = TREE_OPERAND (stmt, 0);
        type = TREE_TYPE (type);
--- 910,916 ----
      = build3 (CALL_EXPR, type, build_fold_addr_expr (fn), args, NULL);
    update_stmt (stmt);
  
!   if (gimple_in_ssa_p (cfun))
      {
        tree lhs = TREE_OPERAND (stmt, 0);
        type = TREE_TYPE (type);
*************** expand_complex_operations_1 (block_stmt_
*** 1422,1428 ****
  	}
      }
  
!   if (in_ssa_p)
      {
        al = find_lattice_value (ac);
        if (al == UNINITIALIZED)
--- 1422,1428 ----
  	}
      }
  
!   if (gimple_in_ssa_p (cfun))
      {
        al = find_lattice_value (ac);
        if (al == UNINITIALIZED)
Index: tree-ssa-propagate.c
===================================================================
*** tree-ssa-propagate.c	(revision 118887)
--- tree-ssa-propagate.c	(working copy)
*************** set_rhs (tree *stmt_p, tree expr)
*** 688,694 ****
        *stmt_p = TREE_SIDE_EFFECTS (expr) ? expr : build_empty_stmt ();
        (*stmt_p)->common.ann = (tree_ann_t) ann;
  
!       if (in_ssa_p
  	  && TREE_SIDE_EFFECTS (expr))
  	{
  	  /* Fix all the SSA_NAMEs created by *STMT_P to point to its new
--- 688,694 ----
        *stmt_p = TREE_SIDE_EFFECTS (expr) ? expr : build_empty_stmt ();
        (*stmt_p)->common.ann = (tree_ann_t) ann;
  
!       if (gimple_in_ssa_p (cfun)
  	  && TREE_SIDE_EFFECTS (expr))
  	{
  	  /* Fix all the SSA_NAMEs created by *STMT_P to point to its new
Index: tree-ssa-alias.c
===================================================================
*** tree-ssa-alias.c	(revision 118887)
--- tree-ssa-alias.c	(working copy)
*************** Boston, MA 02110-1301, USA.  */
*** 46,60 ****
  #include "ipa-type-escape.h"
  #include "vec.h"
  #include "bitmap.h"
  #include "vecprim.h"
  
  /* Obstack used to hold grouping bitmaps and other temporary bitmaps used by
     aliasing  */
  static bitmap_obstack alias_obstack;
  
- /* 'true' after aliases have been computed (see compute_may_aliases).  */
- bool aliases_computed_p;
- 
  /* Structure to map a variable to its alias set and keep track of the
     virtual operands that will be needed to represent it.  */
  struct alias_map_d
--- 46,58 ----
  #include "ipa-type-escape.h"
  #include "vec.h"
  #include "bitmap.h"
+ #include "ipa-prop.h"
  #include "vecprim.h"
  
  /* Obstack used to hold grouping bitmaps and other temporary bitmaps used by
     aliasing  */
  static bitmap_obstack alias_obstack;
  
  /* Structure to map a variable to its alias set and keep track of the
     virtual operands that will be needed to represent it.  */
  struct alias_map_d
*************** static void set_pt_anything (tree ptr);
*** 117,142 ****
  
  /* Global declarations.  */
  
- /* Call clobbered variables in the function.  If bit I is set, then
-    REFERENCED_VARS (I) is call-clobbered.  */
- bitmap call_clobbered_vars;
- 
- /* Addressable variables in the function.  If bit I is set, then
-    REFERENCED_VARS (I) has had its address taken.  Note that
-    CALL_CLOBBERED_VARS and ADDRESSABLE_VARS are not related.  An
-    addressable variable is not necessarily call-clobbered (e.g., a
-    local addressable whose address does not escape) and not all
-    call-clobbered variables are addressable (e.g., a local static
-    variable).  */
- bitmap addressable_vars;
- 
- /* When the program has too many call-clobbered variables and call-sites,
-    this variable is used to represent the clobbering effects of function
-    calls.  In these cases, all the call clobbered variables in the program
-    are forced to alias this variable.  This reduces compile times by not
-    having to keep track of too many V_MAY_DEF expressions at call sites.  */
- tree global_var;
- 
  /* qsort comparison function to sort type/name tags by DECL_UID.  */
  
  static int
--- 115,120 ----
*************** init_alias_info (void)
*** 883,896 ****
    ai->dereferenced_ptrs_load = BITMAP_ALLOC (&alias_obstack);
  
    /* If aliases have been computed before, clear existing information.  */
!   if (aliases_computed_p)
      {
        unsigned i;
    
        /* Similarly, clear the set of addressable variables.  In this
  	 case, we can just clear the set because addressability is
  	 only computed here.  */
!       bitmap_clear (addressable_vars);
  
        /* Clear flow-insensitive alias information from each symbol.  */
        FOR_EACH_REFERENCED_VAR (var, rvi)
--- 861,874 ----
    ai->dereferenced_ptrs_load = BITMAP_ALLOC (&alias_obstack);
  
    /* If aliases have been computed before, clear existing information.  */
!   if (gimple_aliases_computed_p (cfun))
      {
        unsigned i;
    
        /* Similarly, clear the set of addressable variables.  In this
  	 case, we can just clear the set because addressability is
  	 only computed here.  */
!       bitmap_clear (gimple_addressable_vars (cfun));
  
        /* Clear flow-insensitive alias information from each symbol.  */
        FOR_EACH_REFERENCED_VAR (var, rvi)
*************** init_alias_info (void)
*** 945,951 ****
      }
  
    /* Next time, we will need to reset alias information.  */
!   aliases_computed_p = true;
  
    return ai;
  }
--- 923,929 ----
      }
  
    /* Next time, we will need to reset alias information.  */
!   cfun->gimple_df->aliases_computed_p = true;
  
    return ai;
  }
*************** finalize_ref_all_pointers (struct alias_
*** 1341,1348 ****
  {
    size_t i;
  
!   if (global_var)
!     add_may_alias (ai->ref_all_symbol_mem_tag, global_var);
    else
      {
        /* First add the real call-clobbered variables.  */
--- 1319,1326 ----
  {
    size_t i;
  
!   if (gimple_global_var (cfun))
!     add_may_alias (ai->ref_all_symbol_mem_tag, gimple_global_var (cfun));
    else
      {
        /* First add the real call-clobbered variables.  */
*************** setup_pointers_and_addressables (struct 
*** 1692,1698 ****
           cleanup passes.  */
        if (TREE_ADDRESSABLE (var))
  	{
! 	  if (!bitmap_bit_p (addressable_vars, DECL_UID (var))
  	      && TREE_CODE (var) != RESULT_DECL
  	      && !is_global_var (var))
  	    {
--- 1670,1676 ----
           cleanup passes.  */
        if (TREE_ADDRESSABLE (var))
  	{
! 	  if (!bitmap_bit_p (gimple_addressable_vars (cfun), DECL_UID (var))
  	      && TREE_CODE (var) != RESULT_DECL
  	      && !is_global_var (var))
  	    {
*************** setup_pointers_and_addressables (struct 
*** 1712,1718 ****
  
  		  for (sv = svars; sv; sv = sv->next)
  		    {	      
! 		      if (bitmap_bit_p (addressable_vars, DECL_UID (sv->var)))
  			okay_to_mark = false;
  		      mark_sym_for_renaming (sv->var);
  		    }
--- 1690,1697 ----
  
  		  for (sv = svars; sv; sv = sv->next)
  		    {	      
! 		      if (bitmap_bit_p (gimple_addressable_vars (cfun),
! 					DECL_UID (sv->var)))
  			okay_to_mark = false;
  		      mark_sym_for_renaming (sv->var);
  		    }
*************** maybe_create_global_var (struct alias_in
*** 1833,1843 ****
    bitmap_iterator bi;
    
    /* No need to create it, if we have one already.  */
!   if (global_var == NULL_TREE)
      {
        /* Count all the call-clobbered variables.  */
        n_clobbered = 0;
!       EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
  	{
  	  n_clobbered++;
  	}
--- 1812,1822 ----
    bitmap_iterator bi;
    
    /* No need to create it, if we have one already.  */
!   if (gimple_global_var (cfun) == NULL_TREE)
      {
        /* Count all the call-clobbered variables.  */
        n_clobbered = 0;
!       EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, i, bi)
  	{
  	  n_clobbered++;
  	}
*************** maybe_create_global_var (struct alias_in
*** 1880,1895 ****
    /* Mark all call-clobbered symbols for renaming.  Since the initial
       rewrite into SSA ignored all call sites, we may need to rename
       .GLOBAL_VAR and the call-clobbered variables.   */
!   EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
      {
        tree var = referenced_var (i);
  
        /* If the function has calls to clobbering functions and
  	 .GLOBAL_VAR has been created, make it an alias for all
  	 call-clobbered variables.  */
!       if (global_var && var != global_var)
  	{
! 	  add_may_alias (var, global_var);
  	  gcc_assert (!get_subvars_for_var (var));
  	}
        
--- 1859,1874 ----
    /* Mark all call-clobbered symbols for renaming.  Since the initial
       rewrite into SSA ignored all call sites, we may need to rename
       .GLOBAL_VAR and the call-clobbered variables.   */
!   EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, i, bi)
      {
        tree var = referenced_var (i);
  
        /* If the function has calls to clobbering functions and
  	 .GLOBAL_VAR has been created, make it an alias for all
  	 call-clobbered variables.  */
!       if (gimple_global_var (cfun) && var != gimple_global_var (cfun))
  	{
! 	  add_may_alias (var, gimple_global_var (cfun));
  	  gcc_assert (!get_subvars_for_var (var));
  	}
        
*************** get_tmt_for (tree ptr, struct alias_info
*** 2329,2336 ****
  static void
  create_global_var (void)
  {
!   global_var = build_decl (VAR_DECL, get_identifier (".GLOBAL_VAR"),
!                            void_type_node);
    DECL_ARTIFICIAL (global_var) = 1;
    TREE_READONLY (global_var) = 0;
    DECL_EXTERNAL (global_var) = 1;
--- 2308,2315 ----
  static void
  create_global_var (void)
  {
!   tree global_var = build_decl (VAR_DECL, get_identifier (".GLOBAL_VAR"),
!                                 void_type_node);
    DECL_ARTIFICIAL (global_var) = 1;
    TREE_READONLY (global_var) = 0;
    DECL_EXTERNAL (global_var) = 1;
*************** create_global_var (void)
*** 2344,2349 ****
--- 2323,2329 ----
    mark_call_clobbered (global_var, ESCAPE_UNKNOWN);
    add_referenced_var (global_var);
    mark_sym_for_renaming (global_var);
+   cfun->gimple_df->global_var = global_var;
  }
  
  
Index: function.h
===================================================================
*** function.h	(revision 118887)
--- function.h	(working copy)
*************** struct expr_status GTY(())
*** 159,164 ****
--- 159,165 ----
  #define forced_labels (cfun->expr->x_forced_labels)
  #define stack_pointer_delta (cfun->expr->x_stack_pointer_delta)
  
+ struct gimple_df;
  struct temp_slot;
  typedef struct temp_slot *temp_slot_p;
  
*************** struct function GTY(())
*** 188,193 ****
--- 189,196 ----
  
    /* The control flow graph for this function.  */
    struct control_flow_graph *cfg;
+   /* SSA and dataflow information.  */
+   struct gimple_df *gimple_df;
  
    /* For function.c.  */
  
*************** extern bool pass_by_reference (CUMULATIV
*** 577,582 ****
--- 580,586 ----
  extern bool reference_callee_copied (CUMULATIVE_ARGS *, enum machine_mode,
  				     tree, bool);
  
+ extern int get_last_funcdef_no (void);
  extern void used_types_insert (tree);
  
  #endif  /* GCC_FUNCTION_H */
Index: tree-flow-inline.h
===================================================================
*** tree-flow-inline.h	(revision 118887)
--- tree-flow-inline.h	(working copy)
*************** Boston, MA 02110-1301, USA.  */
*** 25,30 ****
--- 25,96 ----
  /* Inline functions for manipulating various data structures defined in
     tree-flow.h.  See tree-flow.h for documentation.  */
  
+ /* Return true when gimple SSA form was built.
+    gimple_in_ssa_p is queried by gimplifier in various early stages before SSA
+    infrastructure is initialized.  Check for presence of the datastructures
+    at first place.  */
+ static inline bool
+ gimple_in_ssa_p (struct function *fun)
+ {
+   return fun && fun->gimple_df && fun->gimple_df->in_ssa_p;
+ }
+ 
+ /* 'true' after aliases have been computed (see compute_may_aliases).  */
+ static inline bool
+ gimple_aliases_computed_p (struct function *fun)
+ {
+   gcc_assert (fun && fun->gimple_df);
+   return fun->gimple_df->aliases_computed_p;
+ }
+ 
+ /* Addressable variables in the function.  If bit I is set, then
+    REFERENCED_VARS (I) has had its address taken.  Note that
+    CALL_CLOBBERED_VARS and ADDRESSABLE_VARS are not related.  An
+    addressable variable is not necessarily call-clobbered (e.g., a
+    local addressable whose address does not escape) and not all
+    call-clobbered variables are addressable (e.g., a local static
+    variable).  */
+ static inline bitmap
+ gimple_addressable_vars (struct function *fun)
+ {
+   gcc_assert (fun && fun->gimple_df);
+   return fun->gimple_df->addressable_vars;
+ }
+ 
+ /* Call clobbered variables in the function.  If bit I is set, then
+    REFERENCED_VARS (I) is call-clobbered.  */
+ static inline bitmap
+ gimple_call_clobbered_vars (struct function *fun)
+ {
+   gcc_assert (fun && fun->gimple_df);
+   return fun->gimple_df->call_clobbered_vars;
+ }
+ 
+ /* Array of all variables referenced in the function.  */
+ static inline htab_t
+ gimple_referenced_vars (struct function *fun)
+ {
+   if (!fun->gimple_df)
+     return NULL;
+   return fun->gimple_df->referenced_vars;
+ }
+ 
+ /* Artificial variable used to model the effects of function calls.  */
+ static inline tree
+ gimple_global_var (struct function *fun)
+ {
+   gcc_assert (fun && fun->gimple_df);
+   return fun->gimple_df->global_var;
+ }
+ 
+ /* Artificial variable used to model the effects of nonlocal
+    variables.  */
+ static inline tree
+ gimple_nonlocal_all (struct function *fun)
+ {
+   gcc_assert (fun && fun->gimple_df);
+   return fun->gimple_df->nonlocal_all;
+ }
  /* Initialize the hashtable iterator HTI to point to hashtable TABLE */
  
  static inline void *
*************** first_referenced_var (referenced_var_ite
*** 79,85 ****
  {
    struct int_tree_map *itm;
    itm = (struct int_tree_map *) first_htab_element (&iter->hti,
!                                                     referenced_vars);
    if (!itm) 
      return NULL;
    return itm->to;
--- 145,152 ----
  {
    struct int_tree_map *itm;
    itm = (struct int_tree_map *) first_htab_element (&iter->hti,
!                                                     gimple_referenced_vars
! 						    (cfun));
    if (!itm) 
      return NULL;
    return itm->to;
*************** mark_stmt_modified (tree t)
*** 278,285 ****
    ann = stmt_ann (t);
    if (ann == NULL)
      ann = create_stmt_ann (t);
!   else if (noreturn_call_p (t))
!     VEC_safe_push (tree, gc, modified_noreturn_calls, t);
    ann->modified = 1;
  }
  
--- 345,352 ----
    ann = stmt_ann (t);
    if (ann == NULL)
      ann = create_stmt_ann (t);
!   else if (noreturn_call_p (t) && cfun->gimple_df)
!     VEC_safe_push (tree, gc, cfun->gimple_df->modified_noreturn_calls, t);
    ann->modified = 1;
  }
  
*************** is_call_clobbered (tree var)
*** 760,766 ****
    if (!MTAG_P (var))
      return DECL_CALL_CLOBBERED (var);
    else
!     return bitmap_bit_p (call_clobbered_vars, DECL_UID (var)); 
  }
  
  /* Mark variable VAR as being clobbered by function calls.  */
--- 827,833 ----
    if (!MTAG_P (var))
      return DECL_CALL_CLOBBERED (var);
    else
!     return bitmap_bit_p (gimple_call_clobbered_vars (cfun), DECL_UID (var)); 
  }
  
  /* Mark variable VAR as being clobbered by function calls.  */
*************** mark_call_clobbered (tree var, unsigned 
*** 770,776 ****
    var_ann (var)->escape_mask |= escape_type;
    if (!MTAG_P (var))
      DECL_CALL_CLOBBERED (var) = true;
!   bitmap_set_bit (call_clobbered_vars, DECL_UID (var));
  }
  
  /* Clear the call-clobbered attribute from variable VAR.  */
--- 837,843 ----
    var_ann (var)->escape_mask |= escape_type;
    if (!MTAG_P (var))
      DECL_CALL_CLOBBERED (var) = true;
!   bitmap_set_bit (gimple_call_clobbered_vars (cfun), DECL_UID (var));
  }
  
  /* Clear the call-clobbered attribute from variable VAR.  */
*************** clear_call_clobbered (tree var)
*** 783,789 ****
      MTAG_GLOBAL (var) = 0;
    if (!MTAG_P (var))
      DECL_CALL_CLOBBERED (var) = false;
!   bitmap_clear_bit (call_clobbered_vars, DECL_UID (var));
  }
  
  /* Mark variable VAR as being non-addressable.  */
--- 850,856 ----
      MTAG_GLOBAL (var) = 0;
    if (!MTAG_P (var))
      DECL_CALL_CLOBBERED (var) = false;
!   bitmap_clear_bit (gimple_call_clobbered_vars (cfun), DECL_UID (var));
  }
  
  /* Mark variable VAR as being non-addressable.  */
*************** mark_non_addressable (tree var)
*** 792,798 ****
  {
    if (!MTAG_P (var))
      DECL_CALL_CLOBBERED (var) = false;
!   bitmap_clear_bit (call_clobbered_vars, DECL_UID (var));
    TREE_ADDRESSABLE (var) = 0;
  }
  
--- 859,865 ----
  {
    if (!MTAG_P (var))
      DECL_CALL_CLOBBERED (var) = false;
!   bitmap_clear_bit (gimple_call_clobbered_vars (cfun), DECL_UID (var));
    TREE_ADDRESSABLE (var) = 0;
  }
  
Index: gimplify.c
===================================================================
*** gimplify.c	(revision 118887)
--- gimplify.c	(working copy)
*************** force_gimple_operand (tree expr, tree *s
*** 6360,6366 ****
    gimple_test_f = simple ? is_gimple_val : is_gimple_reg_rhs;
  
    push_gimplify_context ();
!   gimplify_ctxp->into_ssa = in_ssa_p;
  
    if (var)
      expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
--- 6360,6366 ----
    gimple_test_f = simple ? is_gimple_val : is_gimple_reg_rhs;
  
    push_gimplify_context ();
!   gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun);
  
    if (var)
      expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
*************** force_gimple_operand (tree expr, tree *s
*** 6369,6375 ****
  		       gimple_test_f, fb_rvalue);
    gcc_assert (ret != GS_ERROR);
  
!   if (referenced_vars)
      {
        for (t = gimplify_ctxp->temps; t ; t = TREE_CHAIN (t))
  	add_referenced_var (t);
--- 6369,6375 ----
  		       gimple_test_f, fb_rvalue);
    gcc_assert (ret != GS_ERROR);
  
!   if (gimple_referenced_vars (cfun))
      {
        for (t = gimplify_ctxp->temps; t ; t = TREE_CHAIN (t))
  	add_referenced_var (t);
Index: tree-dfa.c
===================================================================
*** tree-dfa.c	(revision 118887)
--- tree-dfa.c	(working copy)
*************** static tree collect_dfa_stats_r (tree *,
*** 71,88 ****
  static tree find_vars_r (tree *, int *, void *);
  
  
- /* Global declarations.  */
- 
- /* Array of all variables referenced in the function.  */
- htab_t referenced_vars;
- 
- /* Default definition for this symbols.  If set for symbol, it
-    means that the first reference to this variable in the function is a
-    USE or a VUSE.  In those cases, the SSA renamer creates an SSA name
-    for this variable with an empty defining statement.  */
- htab_t default_defs;
- 
- 
  /*---------------------------------------------------------------------------
  			Dataflow analysis (DFA) routines
  ---------------------------------------------------------------------------*/
--- 71,76 ----
*************** make_rename_temp (tree type, const char 
*** 222,228 ****
    if (TREE_CODE (type) == COMPLEX_TYPE)
      DECL_COMPLEX_GIMPLE_REG_P (t) = 1;
  
!   if (referenced_vars)
      {
        add_referenced_var (t);
        mark_sym_for_renaming (t);
--- 210,216 ----
    if (TREE_CODE (type) == COMPLEX_TYPE)
      DECL_COMPLEX_GIMPLE_REG_P (t) = 1;
  
!   if (gimple_referenced_vars (cfun))
      {
        add_referenced_var (t);
        mark_sym_for_renaming (t);
*************** referenced_var_lookup (unsigned int uid)
*** 611,617 ****
  {
    struct int_tree_map *h, in;
    in.uid = uid;
!   h = (struct int_tree_map *) htab_find_with_hash (referenced_vars, &in, uid);
    gcc_assert (h || uid == 0);
    if (h)
      return h->to;
--- 599,606 ----
  {
    struct int_tree_map *h, in;
    in.uid = uid;
!   h = (struct int_tree_map *) htab_find_with_hash (gimple_referenced_vars (cfun),
! 						   &in, uid);
    gcc_assert (h || uid == 0);
    if (h)
      return h->to;
*************** referenced_var_check_and_insert (tree to
*** 630,636 ****
  
    in.uid = uid;
    in.to = to;
!   h = (struct int_tree_map *) htab_find_with_hash (referenced_vars, &in, uid);
  
    if (h)
      {
--- 619,626 ----
  
    in.uid = uid;
    in.to = to;
!   h = (struct int_tree_map *) htab_find_with_hash (gimple_referenced_vars (cfun),
! 						   &in, uid);
  
    if (h)
      {
*************** referenced_var_check_and_insert (tree to
*** 643,649 ****
    h = GGC_NEW (struct int_tree_map);
    h->uid = uid;
    h->to = to;
!   loc = htab_find_slot_with_hash (referenced_vars, h, uid, INSERT);
    *(struct int_tree_map **)  loc = h;
    return true;
  }
--- 633,640 ----
    h = GGC_NEW (struct int_tree_map);
    h->uid = uid;
    h->to = to;
!   loc = htab_find_slot_with_hash (gimple_referenced_vars (cfun),
! 				  h, uid, INSERT);
    *(struct int_tree_map **)  loc = h;
    return true;
  }
*************** referenced_var_check_and_insert (tree to
*** 652,669 ****
     variable.  */
  
  tree 
! default_def (tree var)
  {
    struct int_tree_map *h, in;
    gcc_assert (SSA_VAR_P (var));
    in.uid = DECL_UID (var);
!   h = (struct int_tree_map *) htab_find_with_hash (default_defs, &in,
                                                     DECL_UID (var));
    if (h)
      return h->to;
    return NULL_TREE;
  }
  
  /* Insert the pair VAR's UID, DEF into the default_defs hashtable.  */
  
  void
--- 643,667 ----
     variable.  */
  
  tree 
! default_def_fn (struct function *fn, tree var)
  {
    struct int_tree_map *h, in;
    gcc_assert (SSA_VAR_P (var));
    in.uid = DECL_UID (var);
!   h = (struct int_tree_map *) htab_find_with_hash (fn->gimple_df->default_defs,
! 						   &in,
                                                     DECL_UID (var));
    if (h)
      return h->to;
    return NULL_TREE;
  }
  
+ tree 
+ default_def (tree var)
+ {
+   return default_def_fn (cfun, var);
+ }
+ 
  /* Insert the pair VAR's UID, DEF into the default_defs hashtable.  */
  
  void
*************** set_default_def (tree var, tree def)
*** 677,688 ****
    in.uid = DECL_UID (var);
    if (!def && default_def (var))
      {
!       loc = htab_find_slot_with_hash (default_defs, &in, DECL_UID (var), INSERT);
!       htab_remove_elt (default_defs, *loc);
        return;
      }
    gcc_assert (TREE_CODE (def) == SSA_NAME);
!   loc = htab_find_slot_with_hash (default_defs, &in, DECL_UID (var), INSERT);
    /* Default definition might be changed by tail call optimization.  */
    if (!*loc)
      {
--- 675,688 ----
    in.uid = DECL_UID (var);
    if (!def && default_def (var))
      {
!       loc = htab_find_slot_with_hash (cfun->gimple_df->default_defs, &in,
!             DECL_UID (var), INSERT);
!       htab_remove_elt (cfun->gimple_df->default_defs, *loc);
        return;
      }
    gcc_assert (TREE_CODE (def) == SSA_NAME);
!   loc = htab_find_slot_with_hash (cfun->gimple_df->default_defs, &in,
!                                   DECL_UID (var), INSERT);
    /* Default definition might be changed by tail call optimization.  */
    if (!*loc)
      {
Index: tree-cfgcleanup.c
===================================================================
*** tree-cfgcleanup.c	(revision 118887)
--- tree-cfgcleanup.c	(working copy)
*************** cleanup_control_expr_graph (basic_block 
*** 127,140 ****
    return retval;
  }
  
- /* A list of all the noreturn calls passed to modify_stmt.
-    cleanup_control_flow uses it to detect cases where a mid-block
-    indirect call has been turned into a noreturn call.  When this
-    happens, all the instructions after the call are no longer
-    reachable and must be deleted as dead.  */
- 
- VEC(tree,gc) *modified_noreturn_calls;
- 
  /* Try to remove superfluous control structures.  */
  
  static bool
--- 127,132 ----
*************** cleanup_control_flow (void)
*** 146,158 ****
    tree stmt;
  
    /* Detect cases where a mid-block call is now known not to return.  */
!   while (VEC_length (tree, modified_noreturn_calls))
!     {
!       stmt = VEC_pop (tree, modified_noreturn_calls);
!       bb = bb_for_stmt (stmt);
!       if (bb != NULL && last_stmt (bb) != stmt && noreturn_call_p (stmt))
! 	split_block (bb, stmt);
!     }
  
    FOR_EACH_BB (bb)
      {
--- 138,151 ----
    tree stmt;
  
    /* Detect cases where a mid-block call is now known not to return.  */
!   if (cfun->gimple_df)
!     while (VEC_length (tree, cfun->gimple_df->modified_noreturn_calls))
!       {
! 	stmt = VEC_pop (tree, cfun->gimple_df->modified_noreturn_calls);
! 	bb = bb_for_stmt (stmt);
! 	if (bb != NULL && last_stmt (bb) != stmt && noreturn_call_p (stmt))
! 	  split_block (bb, stmt);
!       }
  
    FOR_EACH_BB (bb)
      {
Index: tree-ssa.c
===================================================================
*** tree-ssa.c	(revision 118887)
--- tree-ssa.c	(working copy)
*************** verify_call_clobbering (void)
*** 627,633 ****
       that everything in call_clobbered_vars is marked
       DECL_CALL_CLOBBERED, and that everything marked
       DECL_CALL_CLOBBERED is in call_clobbered_vars.  */
!   EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
      {
        var = referenced_var (i);
        if (!MTAG_P (var) && !DECL_CALL_CLOBBERED (var))
--- 627,633 ----
       that everything in call_clobbered_vars is marked
       DECL_CALL_CLOBBERED, and that everything marked
       DECL_CALL_CLOBBERED is in call_clobbered_vars.  */
!   EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, i, bi)
      {
        var = referenced_var (i);
        if (!MTAG_P (var) && !DECL_CALL_CLOBBERED (var))
*************** verify_call_clobbering (void)
*** 640,646 ****
    FOR_EACH_REFERENCED_VAR (var, rvi)
      {
        if (!MTAG_P (var) && DECL_CALL_CLOBBERED (var)
! 	  && !bitmap_bit_p (call_clobbered_vars, DECL_UID (var)))
  	{
  	  error ("variable marked DECL_CALL_CLOBBERED but not in call_clobbered_vars bitmap.");
  	  debug_variable (var);
--- 640,646 ----
    FOR_EACH_REFERENCED_VAR (var, rvi)
      {
        if (!MTAG_P (var) && DECL_CALL_CLOBBERED (var)
! 	  && !bitmap_bit_p (gimple_call_clobbered_vars (cfun), DECL_UID (var)))
  	{
  	  error ("variable marked DECL_CALL_CLOBBERED but not in call_clobbered_vars bitmap.");
  	  debug_variable (var);
*************** int_tree_map_hash (const void *item)
*** 830,845 ****
  void
  init_tree_ssa (void)
  {
!   referenced_vars = htab_create_ggc (20, int_tree_map_hash, 
! 				     int_tree_map_eq, NULL);
!   default_defs = htab_create_ggc (20, int_tree_map_hash, int_tree_map_eq, NULL);
!   call_clobbered_vars = BITMAP_ALLOC (NULL);
!   addressable_vars = BITMAP_ALLOC (NULL);
    init_alias_heapvars ();
    init_ssanames ();
    init_phinodes ();
-   global_var = NULL_TREE;
-   aliases_computed_p = false;
  }
  
  
--- 830,845 ----
  void
  init_tree_ssa (void)
  {
!   cfun->gimple_df = ggc_alloc_cleared (sizeof (struct gimple_df));
!   cfun->gimple_df->referenced_vars = htab_create_ggc (20, int_tree_map_hash, 
! 				     		      int_tree_map_eq, NULL);
!   cfun->gimple_df->default_defs = htab_create_ggc (20, int_tree_map_hash, 
! 				                   int_tree_map_eq, NULL);
!   cfun->gimple_df->call_clobbered_vars = BITMAP_GGC_ALLOC ();
!   cfun->gimple_df->addressable_vars = BITMAP_GGC_ALLOC ();
    init_alias_heapvars ();
    init_ssanames ();
    init_phinodes ();
  }
  
  
*************** delete_tree_ssa (void)
*** 887,907 ****
        ggc_free (var->common.ann);
        var->common.ann = NULL;
      }
!   htab_delete (referenced_vars);
!   referenced_vars = NULL;
  
    fini_ssanames ();
    fini_phinodes ();
  
!   global_var = NULL_TREE;
    
!   htab_delete (default_defs);
!   BITMAP_FREE (call_clobbered_vars);
!   call_clobbered_vars = NULL;
!   BITMAP_FREE (addressable_vars);
!   addressable_vars = NULL;
!   modified_noreturn_calls = NULL;
!   aliases_computed_p = false;
    delete_alias_heapvars ();
    gcc_assert (!need_ssa_update_p ());
  }
--- 887,905 ----
        ggc_free (var->common.ann);
        var->common.ann = NULL;
      }
!   htab_delete (gimple_referenced_vars (cfun));
!   cfun->gimple_df->referenced_vars = NULL;
  
    fini_ssanames ();
    fini_phinodes ();
  
!   cfun->gimple_df->global_var = NULL_TREE;
    
!   htab_delete (cfun->gimple_df->default_defs);
!   cfun->gimple_df->call_clobbered_vars = NULL;
!   cfun->gimple_df->addressable_vars = NULL;
!   cfun->gimple_df->modified_noreturn_calls = NULL;
!   cfun->gimple_df->aliases_computed_p = false;
    delete_alias_heapvars ();
    gcc_assert (!need_ssa_update_p ());
  }
Index: tree-outof-ssa.c
===================================================================
*** tree-outof-ssa.c	(revision 118887)
--- tree-outof-ssa.c	(working copy)
*************** rewrite_out_of_ssa (void)
*** 2546,2552 ****
    /* Flush out flow graph and SSA data.  */
    delete_var_map (map);
  
!   in_ssa_p = false;
    return 0;
  }
  
--- 2546,2552 ----
    /* Flush out flow graph and SSA data.  */
    delete_var_map (map);
  
!   cfun->gimple_df->in_ssa_p = false;
    return 0;
  }
  
Index: tree-flow.h
===================================================================
*** tree-flow.h	(revision 118887)
--- tree-flow.h	(working copy)
*************** Boston, MA 02110-1301, USA.  */
*** 30,35 ****
--- 30,36 ----
  #include "tree-ssa-operands.h"
  #include "cgraph.h"
  #include "ipa-reference.h"
+ #include "ipa-prop.h"
  
  /* Forward declare structures for the garbage collector GTY markers.  */
  #ifndef GCC_BASIC_BLOCK_H
*************** struct basic_block_def;
*** 39,44 ****
--- 40,96 ----
  typedef struct basic_block_def *basic_block;
  #endif
  
+ /* Gimple dataflow datastructure. All publically available fields shall have
+    gimple_ accessor defined in tree-flow-inline.h, all publically modifiable
+    fields should have gimple_set accessor.  */
+ struct gimple_df GTY(()) {
+   /* Array of all variables referenced in the function.  */
+   htab_t GTY((param_is (struct int_tree_map))) referenced_vars;
+   /* A list of all the noreturn calls passed to modify_stmt.
+      cleanup_control_flow uses it to detect cases where a mid-block
+      indirect call has been turned into a noreturn call.  When this
+      happens, all the instructions after the call are no longer
+      reachable and must be deleted as dead.  */
+   VEC(tree,gc) *modified_noreturn_calls;
+   /* Array of all SSA_NAMEs used in the function.  */
+   VEC(tree,gc) *ssa_names;
+ 
+   /* Artificial variable used to model the effects of function calls.  */
+   tree global_var;
+ 
+   /* Artificial variable used to model the effects of nonlocal
+      variables.  */
+   tree nonlocal_all;
+ 
+   /* Call clobbered variables in the function.  If bit I is set, then
+      REFERENCED_VARS (I) is call-clobbered.  */
+   bitmap call_clobbered_vars;
+ 
+   /* Addressable variables in the function.  If bit I is set, then
+      REFERENCED_VARS (I) has had its address taken.  Note that
+      CALL_CLOBBERED_VARS and ADDRESSABLE_VARS are not related.  An
+      addressable variable is not necessarily call-clobbered (e.g., a
+      local addressable whose address does not escape) and not all
+      call-clobbered variables are addressable (e.g., a local static
+      variable).  */
+   bitmap addressable_vars;
+ 
+   /* Free list of SSA_NAMEs.  */
+   tree free_ssanames;
+ 
+   /* Hashtable holding definition for symbol.  If this field is not NULL, it
+      means that the first reference to this variable in the function is a
+      USE or a VUSE.  In those cases, the SSA renamer creates an SSA name
+      for this variable with an empty defining statement.  */
+   htab_t GTY((param_is (struct int_tree_map))) default_defs;
+ 
+   /* 'true' after aliases have been computed (see compute_may_aliases).  */
+   unsigned int aliases_computed_p : 1;
+ 
+   /* True if the code is in ssa form.  */
+   unsigned int in_ssa_p : 1;
+ };
+ 
  /* True if the code is in ssa form.  */
  extern bool in_ssa_p;
  
*************** struct var_ann_d GTY(())
*** 206,212 ****
    /* During into-ssa and the dominator optimizer, this field holds the
       current version of this variable (an SSA_NAME).  */
    tree current_def;
!   
    /* If this variable is a structure, this fields holds a list of
       symbols representing each of the fields of the structure.  */
    subvar_t subvars;
--- 258,264 ----
    /* During into-ssa and the dominator optimizer, this field holds the
       current version of this variable (an SSA_NAME).  */
    tree current_def;
! 
    /* If this variable is a structure, this fields holds a list of
       symbols representing each of the fields of the structure.  */
    subvar_t subvars;
*************** union tree_ann_d GTY((desc ("ann_type ((
*** 329,336 ****
    struct stmt_ann_d GTY((tag ("STMT_ANN"))) stmt;
  };
  
- extern GTY(()) VEC(tree,gc) *modified_noreturn_calls;
- 
  typedef union tree_ann_d *tree_ann_t;
  typedef struct var_ann_d *var_ann_t;
  typedef struct function_ann_d *function_ann_t;
--- 381,386 ----
*************** typedef struct
*** 422,461 ****
         VEC_iterate (tree, (VEC), (ITER).i, (VAR)); \
         (ITER).i++)
  
- /* Array of all variables referenced in the function.  */
- extern GTY((param_is (struct int_tree_map))) htab_t referenced_vars;
- 
- /* Default defs for undefined symbols. */
- extern GTY((param_is (struct int_tree_map))) htab_t default_defs;
- 
  extern tree referenced_var_lookup (unsigned int);
  extern bool referenced_var_check_and_insert (tree);
! #define num_referenced_vars htab_elements (referenced_vars)
  #define referenced_var(i) referenced_var_lookup (i)
  
! /* Array of all SSA_NAMEs used in the function.  */
! extern GTY(()) VEC(tree,gc) *ssa_names;
! 
! #define num_ssa_names (VEC_length (tree, ssa_names))
! #define ssa_name(i) (VEC_index (tree, ssa_names, (i)))
! 
! /* Artificial variable used to model the effects of function calls.  */
! extern GTY(()) tree global_var;
! 
! /* Artificial variable used to model the effects of nonlocal
!    variables.  */
! extern GTY(()) tree nonlocal_all;
! 
! /* Call clobbered variables in the function.  If bit I is set, then
!    REFERENCED_VARS (I) is call-clobbered.  */
! extern bitmap call_clobbered_vars;
! 
! /* Addressable variables in the function.  If bit I is set, then
!    REFERENCED_VARS (I) has had its address taken.  */
! extern bitmap addressable_vars;
! 
! /* 'true' after aliases have been computed (see compute_may_aliases).  */
! extern bool aliases_computed_p;
  
  /* Macros for showing usage statistics.  */
  #define SCALE(x) ((unsigned long) ((x) < 1024*10	\
--- 472,484 ----
         VEC_iterate (tree, (VEC), (ITER).i, (VAR)); \
         (ITER).i++)
  
  extern tree referenced_var_lookup (unsigned int);
  extern bool referenced_var_check_and_insert (tree);
! #define num_referenced_vars htab_elements (gimple_referenced_vars (cfun))
  #define referenced_var(i) referenced_var_lookup (i)
  
! #define num_ssa_names (VEC_length (tree, cfun->gimple_df->ssa_names))
! #define ssa_name(i) (VEC_index (tree, cfun->gimple_df->ssa_names, (i)))
  
  /* Macros for showing usage statistics.  */
  #define SCALE(x) ((unsigned long) ((x) < 1024*10	\
Index: tree-ssa-structalias.c
===================================================================
*** tree-ssa-structalias.c	(revision 118887)
--- tree-ssa-structalias.c	(working copy)
*************** Foundation, Inc., 51 Franklin Street, Fi
*** 164,172 ****
  static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) 
  htab_t heapvar_for_stmt;
  
- /* One variable to represent all non-local accesses.  */
- tree nonlocal_all;
- 
  static bool use_field_sensitive = true;
  static int in_ipa_mode = 0;
  static bitmap_obstack predbitmap_obstack;
--- 164,169 ----
*************** create_nonlocal_var (tree type)
*** 2521,2527 ****
  {
    tree nonlocal = create_tmp_var_raw (type, "NONLOCAL");
    
!   if (referenced_vars)
      add_referenced_var (nonlocal);
  
    DECL_EXTERNAL (nonlocal) = 1;
--- 2518,2524 ----
  {
    tree nonlocal = create_tmp_var_raw (type, "NONLOCAL");
    
!   if (gimple_referenced_vars (cfun))
      add_referenced_var (nonlocal);
  
    DECL_EXTERNAL (nonlocal) = 1;
*************** get_constraint_for (tree t, VEC (ce_s, h
*** 2644,2650 ****
  		    heapvar = create_tmp_var_raw (ptr_type_node, "HEAP");
  		    DECL_EXTERNAL (heapvar) = 1;
  		    get_var_ann (heapvar)->is_heapvar = 1;
! 		    if (referenced_vars)
  		      add_referenced_var (heapvar);
  		    heapvar_insert (t, heapvar);
  		  }
--- 2641,2647 ----
  		    heapvar = create_tmp_var_raw (ptr_type_node, "HEAP");
  		    DECL_EXTERNAL (heapvar) = 1;
  		    get_var_ann (heapvar)->is_heapvar = 1;
! 		    if (gimple_referenced_vars (cfun))
  		      add_referenced_var (heapvar);
  		    heapvar_insert (t, heapvar);
  		  }
*************** update_alias_info (tree stmt, struct ali
*** 3079,3085 ****
    addr_taken = addresses_taken (stmt);
    if (addr_taken)
      {
!       bitmap_ior_into (addressable_vars, addr_taken);
  
        /* If STMT is an escape point, all the addresses taken by it are
  	 call-clobbered.  */
--- 3076,3082 ----
    addr_taken = addresses_taken (stmt);
    if (addr_taken)
      {
!       bitmap_ior_into (gimple_addressable_vars (cfun), addr_taken);
  
        /* If STMT is an escape point, all the addresses taken by it are
  	 call-clobbered.  */
*************** update_alias_info (tree stmt, struct ali
*** 3115,3121 ****
--- 3112,3121 ----
  	 to the set of addressable variables.  */
        if (TREE_CODE (op) == ADDR_EXPR)
  	{
+ 	  bitmap addressable_vars = gimple_addressable_vars (cfun);
+ 
  	  gcc_assert (TREE_CODE (stmt) == PHI_NODE);
+ 	  gcc_assert (addressable_vars);
  
  	  /* PHI nodes don't have annotations for pinning the set
  	     of addresses taken, so we collect them here.
*************** update_alias_info (tree stmt, struct ali
*** 3124,3130 ****
  	     so that they can be treated like regular statements?
  	     Currently, they are treated as second-class
  	     statements.  */
! 	  add_to_addressable_set (TREE_OPERAND (op, 0), &addressable_vars);
  	  continue;
  	}
  
--- 3124,3131 ----
  	     so that they can be treated like regular statements?
  	     Currently, they are treated as second-class
  	     statements.  */
! 	  add_to_addressable_set (TREE_OPERAND (op, 0),
!                                   &addressable_vars);
  	  continue;
  	}
  
*************** find_global_initializers (tree *tp, int 
*** 4028,4034 ****
      case VAR_DECL:
        /* We might not have walked this because we skip
  	 DECL_EXTERNALs during the initial scan.  */
!       if (referenced_vars)
  	{
  	  get_var_ann (t);
  	  if (referenced_var_check_and_insert (t))
--- 4029,4035 ----
      case VAR_DECL:
        /* We might not have walked this because we skip
  	 DECL_EXTERNALs during the initial scan.  */
!       if (gimple_referenced_vars (cfun))
  	{
  	  get_var_ann (t);
  	  if (referenced_var_check_and_insert (t))
*************** intra_create_variable_infos (void)
*** 4287,4293 ****
  					    "PARM_NOALIAS");
  	      get_var_ann (heapvar)->is_heapvar = 1;
  	      DECL_EXTERNAL (heapvar) = 1;
! 	      if (referenced_vars)
  		add_referenced_var (heapvar);
  	      heapvar_insert (t, heapvar);
  	    }
--- 4288,4294 ----
  					    "PARM_NOALIAS");
  	      get_var_ann (heapvar)->is_heapvar = 1;
  	      DECL_EXTERNAL (heapvar) = 1;
! 	      if (gimple_referenced_vars (cfun))
  		add_referenced_var (heapvar);
  	      heapvar_insert (t, heapvar);
  	    }
*************** intra_create_variable_infos (void)
*** 4311,4323 ****
  	    make_constraint_from_escaped (p);
  	}
      }
!   if (!nonlocal_all)
!     nonlocal_all = create_nonlocal_var (void_type_node);
  
    /* Create variable info for the nonlocal var if it does not
       exist.  */
!   nonlocal_vars_id = create_variable_info_for (nonlocal_all,
! 					       get_name (nonlocal_all));
    nonlocal_vi = get_varinfo (nonlocal_vars_id);
    nonlocal_vi->is_artificial_var = 1;
    nonlocal_vi->is_heap_var = 1; 
--- 4312,4325 ----
  	    make_constraint_from_escaped (p);
  	}
      }
!   if (!gimple_nonlocal_all (cfun))
!     cfun->gimple_df->nonlocal_all = create_nonlocal_var (void_type_node);
  
    /* Create variable info for the nonlocal var if it does not
       exist.  */
!   nonlocal_vars_id = create_variable_info_for (gimple_nonlocal_all (cfun),
! 					       get_name (gimple_nonlocal_all
! 							 (cfun)));
    nonlocal_vi = get_varinfo (nonlocal_vars_id);
    nonlocal_vi->is_artificial_var = 1;
    nonlocal_vi->is_heap_var = 1; 
*************** init_alias_heapvars (void)
*** 5020,5032 ****
  {
    heapvar_for_stmt = htab_create_ggc (11, tree_map_hash, tree_map_eq,
  				      NULL);
!   nonlocal_all = NULL_TREE;
  }
  
  void
  delete_alias_heapvars (void)
  {
!   nonlocal_all = NULL_TREE;
    htab_delete (heapvar_for_stmt);
  }
  
--- 5022,5034 ----
  {
    heapvar_for_stmt = htab_create_ggc (11, tree_map_hash, tree_map_eq,
  				      NULL);
!   cfun->gimple_df->nonlocal_all = NULL_TREE;
  }
  
  void
  delete_alias_heapvars (void)
  {
!   cfun->gimple_df->nonlocal_all = NULL_TREE;
    htab_delete (heapvar_for_stmt);
  }
  
Index: tree-cfg.c
===================================================================
*** tree-cfg.c	(revision 118887)
--- tree-cfg.c	(working copy)
*************** remove_bb (basic_block bb)
*** 2049,2055 ****
  	     may be called when not in SSA.  For example,
  	     final_cleanup calls this function via
  	     cleanup_tree_cfg.  */
! 	  if (in_ssa_p)
  	    release_defs (stmt);
  
  	  bsi_remove (&i, true);
--- 2049,2055 ----
  	     may be called when not in SSA.  For example,
  	     final_cleanup calls this function via
  	     cleanup_tree_cfg.  */
! 	  if (gimple_in_ssa_p (cfun))
  	    release_defs (stmt);
  
  	  bsi_remove (&i, true);
*************** gimplify_val (block_stmt_iterator *bsi, 
*** 5654,5660 ****
    TREE_BLOCK (new_stmt) = TREE_BLOCK (orig_stmt);
  
    bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
!   if (in_ssa_p)
      mark_new_vars_to_rename (new_stmt);
  
    return t;
--- 5654,5660 ----
    TREE_BLOCK (new_stmt) = TREE_BLOCK (orig_stmt);
  
    bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
!   if (gimple_in_ssa_p (cfun))
      mark_new_vars_to_rename (new_stmt);
  
    return t;
Index: tree-ssanames.c
===================================================================
*** tree-ssanames.c	(revision 118887)
--- tree-ssanames.c	(working copy)
*************** Boston, MA 02110-1301, USA.  */
*** 57,69 ****
     We could also use a zone allocator for these objects since they have
     a very well defined lifetime.  If someone wants to experiment with that
     this is the place to try it.  */
-    
- /* Array of all SSA_NAMEs used in the function.  */
- VEC(tree,gc) *ssa_names;
- 
- /* Free list of SSA_NAMEs.  This list is wiped at the end of each function
-    after we leave SSA form.  */
- static GTY (()) tree free_ssanames;
  
  /* Version numbers with special meanings.  We start allocating new version
     numbers after the special ones.  */
--- 57,62 ----
*************** unsigned int ssa_name_nodes_created;
*** 79,85 ****
  void
  init_ssanames (void)
  {
!   ssa_names = VEC_alloc (tree, gc, 50);
  
    /* Version 0 is special, so reserve the first slot in the table.  Though
       currently unused, we may use version 0 in alias analysis as part of
--- 72,78 ----
  void
  init_ssanames (void)
  {
!   cfun->gimple_df->ssa_names = VEC_alloc (tree, gc, 50);
  
    /* Version 0 is special, so reserve the first slot in the table.  Though
       currently unused, we may use version 0 in alias analysis as part of
*************** init_ssanames (void)
*** 88,95 ****
  
       We use VEC_quick_push here because we know that SSA_NAMES has at
       least 50 elements reserved in it.  */
!   VEC_quick_push (tree, ssa_names, NULL_TREE);
!   free_ssanames = NULL;
  }
  
  /* Finalize management of SSA_NAMEs.  */
--- 81,88 ----
  
       We use VEC_quick_push here because we know that SSA_NAMES has at
       least 50 elements reserved in it.  */
!   VEC_quick_push (tree, cfun->gimple_df->ssa_names, NULL_TREE);
!   cfun->gimple_df->free_ssanames = NULL;
  }
  
  /* Finalize management of SSA_NAMEs.  */
*************** init_ssanames (void)
*** 97,104 ****
  void
  fini_ssanames (void)
  {
!   VEC_free (tree, gc, ssa_names);
!   free_ssanames = NULL;
  }
  
  /* Dump some simple statistics regarding the re-use of SSA_NAME nodes.  */
--- 90,97 ----
  void
  fini_ssanames (void)
  {
!   VEC_free (tree, gc, cfun->gimple_df->ssa_names);
!   cfun->gimple_df->free_ssanames = NULL;
  }
  
  /* Dump some simple statistics regarding the re-use of SSA_NAME nodes.  */
*************** make_ssa_name (tree var, tree stmt)
*** 129,138 ****
    gcc_assert (!stmt || EXPR_P (stmt) || TREE_CODE (stmt) == PHI_NODE);
  
    /* If our free list has an element, then use it.  */
!   if (free_ssanames)
      {
!       t = free_ssanames;
!       free_ssanames = TREE_CHAIN (free_ssanames);
  #ifdef GATHER_STATISTICS
        ssa_name_nodes_reused++;
  #endif
--- 122,132 ----
    gcc_assert (!stmt || EXPR_P (stmt) || TREE_CODE (stmt) == PHI_NODE);
  
    /* If our free list has an element, then use it.  */
!   if (cfun->gimple_df->free_ssanames)
      {
!       t = cfun->gimple_df->free_ssanames;
!       cfun->gimple_df->free_ssanames
! 	= TREE_CHAIN (cfun->gimple_df->free_ssanames);
  #ifdef GATHER_STATISTICS
        ssa_name_nodes_reused++;
  #endif
*************** make_ssa_name (tree var, tree stmt)
*** 140,152 ****
        /* The node was cleared out when we put it on the free list, so
  	 there is no need to do so again here.  */
        gcc_assert (ssa_name (SSA_NAME_VERSION (t)) == NULL);
!       VEC_replace (tree, ssa_names, SSA_NAME_VERSION (t), t);
      }
    else
      {
        t = make_node (SSA_NAME);
        SSA_NAME_VERSION (t) = num_ssa_names;
!       VEC_safe_push (tree, gc, ssa_names, t);
  #ifdef GATHER_STATISTICS
        ssa_name_nodes_created++;
  #endif
--- 134,146 ----
        /* The node was cleared out when we put it on the free list, so
  	 there is no need to do so again here.  */
        gcc_assert (ssa_name (SSA_NAME_VERSION (t)) == NULL);
!       VEC_replace (tree, cfun->gimple_df->ssa_names, SSA_NAME_VERSION (t), t);
      }
    else
      {
        t = make_node (SSA_NAME);
        SSA_NAME_VERSION (t) = num_ssa_names;
!       VEC_safe_push (tree, gc, cfun->gimple_df->ssa_names, t);
  #ifdef GATHER_STATISTICS
        ssa_name_nodes_created++;
  #endif
*************** release_ssa_name (tree var)
*** 213,219 ****
        while (imm->next != imm)
  	delink_imm_use (imm->next);
  
!       VEC_replace (tree, ssa_names, SSA_NAME_VERSION (var), NULL_TREE);
        memset (var, 0, tree_size (var));
  
        imm->prev = imm;
--- 207,214 ----
        while (imm->next != imm)
  	delink_imm_use (imm->next);
  
!       VEC_replace (tree, cfun->gimple_df->ssa_names,
! 		   SSA_NAME_VERSION (var), NULL_TREE);
        memset (var, 0, tree_size (var));
  
        imm->prev = imm;
*************** release_ssa_name (tree var)
*** 234,241 ****
        SSA_NAME_IN_FREE_LIST (var) = 1;
  
        /* And finally link it into the free list.  */
!       TREE_CHAIN (var) = free_ssanames;
!       free_ssanames = var;
      }
  }
  
--- 229,236 ----
        SSA_NAME_IN_FREE_LIST (var) = 1;
  
        /* And finally link it into the free list.  */
!       TREE_CHAIN (var) = cfun->gimple_df->free_ssanames;
!       cfun->gimple_df->free_ssanames = var;
      }
  }
  
*************** release_defs (tree stmt)
*** 291,297 ****
  
    /* Make sure that we are in SSA.  Otherwise, operand cache may point
       to garbage.  */
!   gcc_assert (in_ssa_p);
  
    FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
      if (TREE_CODE (def) == SSA_NAME)
--- 286,292 ----
  
    /* Make sure that we are in SSA.  Otherwise, operand cache may point
       to garbage.  */
!   gcc_assert (gimple_in_ssa_p (cfun));
  
    FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
      if (TREE_CODE (def) == SSA_NAME)
*************** replace_ssa_name_symbol (tree ssa_name, 
*** 307,311 ****
    SSA_NAME_VAR (ssa_name) = sym;
    TREE_TYPE (ssa_name) = TREE_TYPE (sym);
  }
- 
- #include "gt-tree-ssanames.h"
--- 302,304 ----
Index: tree-ssa-operands.c
===================================================================
*** tree-ssa-operands.c	(revision 118887)
--- tree-ssa-operands.c	(working copy)
*************** access_can_touch_variable (tree ref, tre
*** 1050,1061 ****
    /* If ALIAS is .GLOBAL_VAR then the memory reference REF must be
       using a call-clobbered memory tag.  By definition, call-clobbered
       memory tags can always touch .GLOBAL_VAR.  */
!   if (alias == global_var)
      return true;
  
    /* We cannot prune nonlocal aliases because they are not type
       specific.  */
!   if (alias == nonlocal_all)
      return true;
  
    /* If ALIAS is an SFT, it can't be touched if the offset     
--- 1050,1061 ----
    /* If ALIAS is .GLOBAL_VAR then the memory reference REF must be
       using a call-clobbered memory tag.  By definition, call-clobbered
       memory tags can always touch .GLOBAL_VAR.  */
!   if (alias == gimple_global_var (cfun))
      return true;
  
    /* We cannot prune nonlocal aliases because they are not type
       specific.  */
!   if (alias == gimple_nonlocal_all (cfun))
      return true;
  
    /* If ALIAS is an SFT, it can't be touched if the offset     
*************** add_virtual_operand (tree var, stmt_ann_
*** 1317,1323 ****
  		 set on it, or else we will get the wrong answer on
  		 clobbers.  */
  	      if (none_added
! 		  && !updating_used_alone && aliases_computed_p
  		  && TREE_CODE (var) == SYMBOL_MEMORY_TAG)
  		gcc_assert (SMT_USED_ALONE (var));
  
--- 1317,1323 ----
  		 set on it, or else we will get the wrong answer on
  		 clobbers.  */
  	      if (none_added
! 		  && !updating_used_alone && gimple_aliases_computed_p (cfun)
  		  && TREE_CODE (var) == SYMBOL_MEMORY_TAG)
  		gcc_assert (SMT_USED_ALONE (var));
  
*************** add_call_clobber_ops (tree stmt, tree ca
*** 1552,1560 ****
  
    /* If we created .GLOBAL_VAR earlier, just use it.  See compute_may_aliases 
       for the heuristic used to decide whether to create .GLOBAL_VAR or not.  */
!   if (global_var)
      {
!       add_stmt_operand (&global_var, s_ann, opf_is_def);
        return;
      }
  
--- 1552,1560 ----
  
    /* If we created .GLOBAL_VAR earlier, just use it.  See compute_may_aliases 
       for the heuristic used to decide whether to create .GLOBAL_VAR or not.  */
!   if (gimple_global_var (cfun))
      {
!       add_stmt_operand (&cfun->gimple_df->global_var, s_ann, opf_is_def);
        return;
      }
  
*************** add_call_clobber_ops (tree stmt, tree ca
*** 1564,1570 ****
    not_read_b = callee ? ipa_reference_get_not_read_global (callee) : NULL; 
    not_written_b = callee ? ipa_reference_get_not_written_global (callee) : NULL; 
    /* Add a V_MAY_DEF operand for every call clobbered variable.  */
!   EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, u, bi)
      {
        tree var = referenced_var_lookup (u);
        unsigned int escape_mask = var_ann (var)->escape_mask;
--- 1564,1570 ----
    not_read_b = callee ? ipa_reference_get_not_read_global (callee) : NULL; 
    not_written_b = callee ? ipa_reference_get_not_written_global (callee) : NULL; 
    /* Add a V_MAY_DEF operand for every call clobbered variable.  */
!   EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, u, bi)
      {
        tree var = referenced_var_lookup (u);
        unsigned int escape_mask = var_ann (var)->escape_mask;
*************** add_call_read_ops (tree stmt, tree calle
*** 1633,1648 ****
    /* if the function is not pure, it may reference memory.  Add
       a VUSE for .GLOBAL_VAR if it has been created.  See add_referenced_var
       for the heuristic used to decide whether to create .GLOBAL_VAR.  */
!   if (global_var)
      {
!       add_stmt_operand (&global_var, s_ann, opf_none);
        return;
      }
    
    not_read_b = callee ? ipa_reference_get_not_read_global (callee) : NULL; 
  
    /* Add a VUSE for each call-clobbered variable.  */
!   EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, u, bi)
      {
        tree var = referenced_var (u);
        tree real_var = var;
--- 1633,1648 ----
    /* if the function is not pure, it may reference memory.  Add
       a VUSE for .GLOBAL_VAR if it has been created.  See add_referenced_var
       for the heuristic used to decide whether to create .GLOBAL_VAR.  */
!   if (gimple_global_var (cfun))
      {
!       add_stmt_operand (&cfun->gimple_df->global_var, s_ann, opf_none);
        return;
      }
    
    not_read_b = callee ? ipa_reference_get_not_read_global (callee) : NULL; 
  
    /* Add a VUSE for each call-clobbered variable.  */
!   EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, u, bi)
      {
        tree var = referenced_var (u);
        tree real_var = var;
*************** get_call_expr_operands (tree stmt, tree 
*** 1688,1695 ****
       computed.  By not bothering with virtual operands for CALL_EXPRs
       we avoid adding superfluous virtual operands, which can be a
       significant compile time sink (See PR 15855).  */
!   if (aliases_computed_p
!       && !bitmap_empty_p (call_clobbered_vars)
        && !(call_flags & ECF_NOVOPS))
      {
        /* A 'pure' or a 'const' function never call-clobbers anything. 
--- 1688,1695 ----
       computed.  By not bothering with virtual operands for CALL_EXPRs
       we avoid adding superfluous virtual operands, which can be a
       significant compile time sink (See PR 15855).  */
!   if (gimple_aliases_computed_p (cfun)
!       && !bitmap_empty_p (gimple_call_clobbered_vars (cfun))
        && !(call_flags & ECF_NOVOPS))
      {
        /* A 'pure' or a 'const' function never call-clobbers anything. 
*************** get_asm_expr_operands (tree stmt)
*** 1776,1792 ****
  
  	/* Clobber all call-clobbered variables (or .GLOBAL_VAR if we
  	   decided to group them).  */
! 	if (global_var)
! 	  add_stmt_operand (&global_var, s_ann, opf_is_def);
  	else
! 	  EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
  	    {
  	      tree var = referenced_var (i);
  	      add_stmt_operand (&var, s_ann, opf_is_def | opf_non_specific);
  	    }
  
  	/* Now clobber all addressables.  */
! 	EXECUTE_IF_SET_IN_BITMAP (addressable_vars, 0, i, bi)
  	    {
  	      tree var = referenced_var (i);
  
--- 1776,1792 ----
  
  	/* Clobber all call-clobbered variables (or .GLOBAL_VAR if we
  	   decided to group them).  */
! 	if (gimple_global_var (cfun))
! 	  add_stmt_operand (&cfun->gimple_df->global_var, s_ann, opf_is_def);
  	else
! 	  EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, i, bi)
  	    {
  	      tree var = referenced_var (i);
  	      add_stmt_operand (&var, s_ann, opf_is_def | opf_non_specific);
  	    }
  
  	/* Now clobber all addressables.  */
! 	EXECUTE_IF_SET_IN_BITMAP (gimple_addressable_vars (cfun), 0, i, bi)
  	    {
  	      tree var = referenced_var (i);
  


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