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]

[tree-ssa] More fixes


Another collection of minor fixes.  This one does two main things:

      * Variables that are hidden in the IL (VLA initialization,
        non-gimple builtin calls) are never exposed to the optimizers.
      * Variables that are used in VA_ARG_EXPR are never used in real
        operands.  This is necessary because VA_ARG_EXPR both modifies
        and reads from its argument.  This is not something we can
        easily support in real operands.  Perhaps if VA_ARG_EXPR had two
        operands, instead of one.
      * In tree-ssa.c we were creating varrays of data structures that
        were not GC allocated, this was creating random failures on
        ia64.
      * Similarly, in tree-ssa-ccp.c, we were using a varray of edges,
        which are not GC allocated.  I created a new VARRAY for edges
        that use xmalloc instead.
      * I also moved the code to find variables outside of
        compute_may_aliases.  It doesn't make sense to have them both in
        the same place.

Bootstrapped and tested on x86, ia64, ppc and amd64.


Diego.

	* Makefile.in (GTFILES): Add tree-ssa.c, tree-dfa.c and
	tree-ssa-ccp.c.
	(gt-tree-ssa.h, gt-tree-dfa.h, gt-tree-ssa-ccp.h): Depend on
	s-gtype.
	* tree-dfa.c (struct clobber_data_d): Remove.  Update all users.
	(struct alias_map_d): Mark for garbage collection.
	(struct walk_state): Add fields 'is_not_gimple' and
	'is_va_arg_expr'.
	(clobber_vars_r): Remove.  Update all users.
	(get_stmt_operands): Abort if attempting to get operands from a
	non-GIMPLE statement.
	(get_expr_operands): Likewise.
	Do not force a virtual operand when scanning VA_ARG_EXPR.
	(add_stmt_operand): If the variable has hidden uses, mark the
	statement as having volatile operands and return.
	If the variable occurs inside a VA_ARG_EXPR, add it as a virtual
	operand.
	(add_immediate_use): Call VARRAY_TREE_INIT instead of
	VARRAY_GENERIC_PTR_INIT.
	(dump_variable): Check is_in_va_arg_expr flag.
	(compute_may_aliases): Move code to find variables ...
	(find_referenced_vars): ... here.
	(find_vars_r): Abort if we find a non-GIMPLE expression
	unexpectedly.
	Mark variables found inside a VA_ARG_EXPR.
	Do not scan arguments for non-GIMPLE CALL_EXPRs.
	Remove local variable saved_is_store.
	Reformat some code for readability.
	(add_referenced_var): If the variable is already marked as having
	hidden uses, ignore it.
	If the variable is found inside a non-GIMPLE expression, mark it.
	If the variable is found inside a VA_ARG_EXPR, mark it.

	* tree-flow.h (struct var_ann_d): Add field is_in_va_arg_expr.
	(find_referenced_vars): Declare.
	* tree-optimize.c (optimize_function_tree): Call
	find_referenced_vars before computing may aliases.

	* tree-ssa-dce.c (need_to_preserve_store): Do not check if the
	variable has hidden uses.
	* tree-ssa-live.c (type_var_init): Likewise.

	* tree-ssa-ccp.c (ssa_edges): Mark for garbage collection.
	(tree_ssa_ccp): Use VARRAY_.*_EDGE calls to manipulate the varray
	of CFG edges.
	(add_control_edge): Likewise.
	(initialize): Likewise.
	* tree-ssa.c (struct def_blocks_d): Mark for garbage collection.
	(struct var_value_d): Likewise.
	(def_blocks_free): Remove.  Update all users.
	(rewrite_into_ssa): Do not specify free function when creating
	def_blocks and currdefs.
	Call sbitmap_free instead of free.
	(mark_def_sites): Call sbitmap_free instead of free.
	(set_def_block): Use GC allocation.
	(set_livein_block): Likewise.
	(insert_phi_nodes): Adjust name of varray def_maps when creating it.
	(insert_phis_for_deferred_variables): Remove call to BITMAP_XFREE.
	(insert_phi_nodes_for): Use GC allocation for phi_insertion_points.
	(init_tree_ssa): Remove typecast in call to memset.
	(set_value_for): Use GC allocation.
	(get_def_blocks_for): Remove typecast in call to htab_find.
	* varray.c (element): Add entry for struct edge_def *.
	* varray.h (enum varray_data_enum): Add VARRAY_DATA_EDGE.
	(union varray_data_tag): Add field of type struct edge_def *.
	(VARRAY_EDGE_INIT): Define.
	(VARRAY_EDGE): Define.
	(VARRAY_PUSH_EDGE): Define.
	(VARRAY_TOP_EDGE): Define.


testsuite/ChangeLog.tree-ssa:

	* gcc.c-torture/execute/20030801-1.c: New test.

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.903.2.107
diff -d -u -p -c -r1.903.2.107 Makefile.in
*** Makefile.in	4 Aug 2003 17:22:41 -0000	1.903.2.107
--- Makefile.in	7 Aug 2003 18:51:15 -0000
*************** GTFILES = $(srcdir)/input.h $(srcdir)/co
*** 2147,2152 ****
--- 2147,2153 ----
    $(srcdir)/tree-mudflap.c $(srcdir)/tree-flow.h \
    $(srcdir)/c-objc-common.c $(srcdir)/c-common.c $(srcdir)/c-parse.in \
    $(srcdir)/stringpool.c $(srcdir)/tree.c $(srcdir)/varasm.c \
+   $(srcdir)/tree-ssa.c $(srcdir)/tree-dfa.c $(srcdir)/tree-ssa-ccp.c \
    $(out_file) \
    @all_gtfiles@
  
*************** gt-dwarf2out.h gt-ra-build.h gt-reg-stac
*** 2164,2170 ****
  gt-dbxout.h gt-c-common.h gt-c-decl.h gt-c-parse.h \
  gt-c-pragma.h gt-c-objc-common.h gtype-c.h gt-input.h gt-cfglayout.h \
  gt-stringpool.h gt-langhooks.h \
! gt-tree-alias-common.h gt-tree-mudflap.h gt-dependence.h: s-gtype ; @true
  
  gtyp-gen.h: Makefile
  	echo "/* This file is machine generated.  Do not edit.  */" > tmp-gtyp.h
--- 2165,2172 ----
  gt-dbxout.h gt-c-common.h gt-c-decl.h gt-c-parse.h \
  gt-c-pragma.h gt-c-objc-common.h gtype-c.h gt-input.h gt-cfglayout.h \
  gt-stringpool.h gt-langhooks.h \
! gt-tree-alias-common.h gt-tree-mudflap.h gt-dependence.h \
! gt-tree-ssa.h gt-tree-dfa.h gt-tree-ssa-ccp.h: s-gtype ; @true
  
  gtyp-gen.h: Makefile
  	echo "/* This file is machine generated.  Do not edit.  */" > tmp-gtyp.h
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.142
diff -d -u -p -c -r1.1.4.142 tree-dfa.c
*** tree-dfa.c	6 Aug 2003 19:55:38 -0000	1.1.4.142
--- tree-dfa.c	7 Aug 2003 18:51:16 -0000
*************** struct dfa_stats_d
*** 60,74 ****
    long num_vuses;
  };
  
- struct clobber_data_d
- {
-   tree stmt;
-   voperands_t prev_vops;
- };
- 
  /* Tuple to map a variable to its alias set.  Used to cache the results of
     calls to get_alias_set().  */
! struct alias_map_d
  {
    tree var;
    HOST_WIDE_INT set;
--- 60,68 ----
    long num_vuses;
  };
  
  /* Tuple to map a variable to its alias set.  Used to cache the results of
     calls to get_alias_set().  */
! struct GTY(()) alias_map_d
  {
    tree var;
    HOST_WIDE_INT set;
*************** static GTY(()) varray_type pointers;
*** 85,93 ****
  /* State information for find_vars_r.  */
  struct walk_state
  {
-   /* Hash table used to avoid adding the same variable more than once.  */
-   htab_t vars_found;
- 
    /* Nonzero if the variables found under the current tree are written to.  */
    int is_store : 1;
  
--- 79,84 ----
*************** struct walk_state
*** 96,101 ****
--- 87,101 ----
  
    /* Nonzero if the walker is inside an ASM_EXPR node.  */
    int is_asm_expr : 1;
+ 
+   /* Nonzero if the walker is inside a non-GIMPLE expression.  */
+   int is_not_gimple : 1;
+ 
+   /* Nonzero if the walker is inside a VA_ARG_EXPR node.  */
+   int is_va_arg_expr : 1;
+ 
+   /* Hash table used to avoid adding the same variable more than once.  */
+   htab_t vars_found;
  };
  
  
*************** static void cleanup_operand_arrays (stmt
*** 123,129 ****
  static void get_expr_operands (tree, tree *, int, voperands_t);
  static void collect_dfa_stats (struct dfa_stats_d *);
  static tree collect_dfa_stats_r (tree *, int *, void *);
- static tree clobber_vars_r (tree *, int *, void *);
  static void compute_alias_sets (void);
  static bool may_alias_p (tree, HOST_WIDE_INT, tree, HOST_WIDE_INT);
  static bool may_access_global_mem_p (tree);
--- 123,128 ----
*************** static void add_may_alias (tree, tree);
*** 140,146 ****
  static int get_call_flags (tree);
  static void find_hidden_use_vars (tree);
  static tree find_hidden_use_vars_r (tree *, int *, void *);
! 
  
  /* Global declarations.  */
  
--- 139,147 ----
  static int get_call_flags (tree);
  static void find_hidden_use_vars (tree);
  static tree find_hidden_use_vars_r (tree *, int *, void *);
! #if 0
! static void remove_hidden_vars_from (varray_type, bool);
! #endif
  
  /* Global declarations.  */
  
*************** get_stmt_operands (tree stmt)
*** 176,188 ****
      abort ();
  #endif
  
!   if (IS_EMPTY_STMT (stmt) || stmt == error_mark_node)
      return;
  
    /* If the statement has not been modified, the operands are still valid.  */
    if (!stmt_modified_p (stmt))
      return;
  
    ann = get_stmt_ann (stmt);
  
    /* Remove any existing operands as they will be scanned again.  */
--- 177,196 ----
      abort ();
  #endif
  
!   /* Ignore empty and error statements.  */
!   if (IS_EMPTY_STMT (stmt) || TREE_CODE (stmt) == ERROR_MARK)
      return;
  
    /* If the statement has not been modified, the operands are still valid.  */
    if (!stmt_modified_p (stmt))
      return;
  
+ #if defined ENABLE_CHECKING
+   /* non-GIMPLE statements should not appear here.  */
+   if (TREE_NOT_GIMPLE (stmt))
+     abort ();
+ #endif
+ 
    ann = get_stmt_ann (stmt);
  
    /* Remove any existing operands as they will be scanned again.  */
*************** get_expr_operands (tree stmt, tree *expr
*** 272,277 ****
--- 280,291 ----
    if (expr == NULL || expr == error_mark_node)
      return;
  
+ #if defined ENABLE_CHECKING
+   /* non-GIMPLE expressions should not appear here.  */
+   if (TREE_NOT_GIMPLE (expr))
+     abort ();
+ #endif
+ 
    code = TREE_CODE (expr);
    class = TREE_CODE_CLASS (code);
  
*************** get_expr_operands (tree stmt, tree *expr
*** 314,339 ****
        expr = *expr_p;
      }
  
-   /* If this reference is associated with a non GIMPLE expression, then we
-      mark the statement non GIMPLE and recursively clobber every
-      variable referenced by STMT.  FIXME: TREE_NOT_GIMPLE must die.  */
-   if (stmt && TREE_NOT_GIMPLE (expr))
-     {
-       struct clobber_data_d cd;
-       mark_not_gimple (&stmt);
-       cd.stmt = stmt;
-       cd.prev_vops = prev_vops;
-       walk_tree (&stmt, clobber_vars_r, (void *) &cd, NULL);
-       return;
-     }
- 
-   /* If the parent statement is marked not-gimple, don't do anything.  This
-      means that in a previous iteration we encountered a non-gimple
-      sub-expression which already clobbered all the variables in the
-      statement.  FIXME: TREE_NOT_GIMPLE must die.  */
-   if (stmt && TREE_NOT_GIMPLE (stmt))
-     return;
- 
    /* If we found a variable, add it to DEFS or USES depending on the
       operand flags.  */
    if (SSA_VAR_P (expr))
--- 328,333 ----
*************** get_expr_operands (tree stmt, tree *expr
*** 491,498 ****
       VOPS to avoid optimizations messing it up.  */
    if (code == VA_ARG_EXPR)
      {
!       add_stmt_operand (&TREE_OPERAND (expr, 0), stmt, opf_is_def|opf_force_vop,
! 			prev_vops);
        return;
      }
  
--- 485,491 ----
       VOPS to avoid optimizations messing it up.  */
    if (code == VA_ARG_EXPR)
      {
!       add_stmt_operand (&TREE_OPERAND (expr, 0), stmt, opf_is_def, prev_vops);
        return;
      }
  
*************** static void
*** 546,552 ****
  add_stmt_operand (tree *var_p, tree stmt, int flags, voperands_t prev_vops)
  {
    bool is_scalar;
!   tree var;
    varray_type aliases;
    size_t i;
    stmt_ann_t s_ann;
--- 539,545 ----
  add_stmt_operand (tree *var_p, tree stmt, int flags, voperands_t prev_vops)
  {
    bool is_scalar;
!   tree var, sym;
    varray_type aliases;
    size_t i;
    stmt_ann_t s_ann;
*************** add_stmt_operand (tree *var_p, tree stmt
*** 580,595 ****
    if (!is_scalar && !DECL_P (var))
      var = get_virtual_var (var);
  
!   /* If VAR is not a variable, do nothing.  */
    if (var == NULL_TREE || !SSA_VAR_P (var))
      return;
  
!   v_ann = var_ann (TREE_CODE (var) == SSA_NAME ? SSA_NAME_VAR (var) : var);
  
!   /* FIXME: Currently, objects in static storage are always treated as
!      virtual operands.  */
!   if (decl_function_context (!DECL_P (var) ? get_base_symbol (var) : var) == 0
!       || TREE_STATIC ((!DECL_P (var) ? get_base_symbol (var) : var)))
      flags |= opf_force_vop;
  
    /* If the variable is an alias tag, it means that its address has been
--- 573,602 ----
    if (!is_scalar && !DECL_P (var))
      var = get_virtual_var (var);
  
!   /* If VAR is not a variable that we care to optimize, do nothing.  */
    if (var == NULL_TREE || !SSA_VAR_P (var))
      return;
  
!   sym = get_base_symbol (var);
!   v_ann = var_ann (sym);
  
!   /* FIXME: We currently refuse to optimize variables that have hidden uses
!      (variables used in VLA declarations, MD builtin calls and variables
!      from the parent function in nested functions).  This is because not
!      all uses of these variables are exposed in the IL or the statements
!      that reference them are not in GIMPLE form.  If that's the case, mark
!      the statement as having volatile operands and return.  */
!   if (v_ann->has_hidden_use)
!     {
!       s_ann->has_volatile_ops = 1;
!       return;
!     }
! 
!   /* Globals, local statics and variables referenced in VA_ARG_EXPR are
!      always accessed using virtual operands.  */
!   if (decl_function_context (sym) == 0
!       || TREE_STATIC (sym)
!       || v_ann->is_in_va_arg_expr)
      flags |= opf_force_vop;
  
    /* If the variable is an alias tag, it means that its address has been
*************** add_immediate_use (tree stmt, tree use_s
*** 1159,1165 ****
      }
  
    if (ann->df->immediate_uses == NULL)
!     VARRAY_GENERIC_PTR_INIT (ann->df->immediate_uses, 10, "immediate_uses");
  
    VARRAY_PUSH_TREE (ann->df->immediate_uses, use_stmt);
  }
--- 1166,1172 ----
      }
  
    if (ann->df->immediate_uses == NULL)
!     VARRAY_TREE_INIT (ann->df->immediate_uses, 10, "immediate_uses");
  
    VARRAY_PUSH_TREE (ann->df->immediate_uses, use_stmt);
  }
*************** dump_variable (FILE *file, tree var)
*** 1381,1386 ****
--- 1388,1396 ----
    if (ann->is_stored)
      fprintf (file, ", is stored");
  
+   if (ann->is_in_va_arg_expr)
+     fprintf (file, ", is used in va_arg");
+ 
    if (ann->may_aliases)
      {
        fprintf (file, ", may aliases: ");
*************** collect_dfa_stats_r (tree *tp, int *walk
*** 1697,1733 ****
  }
  
  
! /* Callback for walk_tree, create may-def/may-use references for every
!    declaration node and compound reference found under a given tree node
!    TP.  */
  
! static tree
! clobber_vars_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
! 		void *data)
  {
!   enum tree_code code = TREE_CODE (*tp);
  
!   /* Add every *_DECL node to VDEFS and VUSES.  */
!   if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
      {
!       struct clobber_data_d *cd = (struct clobber_data_d *) data;
!       add_vuse (*tp, cd->stmt, cd->prev_vops);
!       add_vdef (*tp, cd->stmt, cd->prev_vops);
      }
  
!   return NULL;
  }
  
  
! /*---------------------------------------------------------------------------
! 				    Aliasing
! ---------------------------------------------------------------------------*/
! /* Compute may-alias information for every variable referenced in the
!    program.  Note that in the absence of points-to analysis
!    (-ftree-points-to), this may compute a much bigger set than necessary.  */
  
  void
! compute_may_aliases (tree fndecl)
  {
    static htab_t vars_found;
    basic_block bb;
--- 1707,1761 ----
  }
  
  
! /*---------------------------------------------------------------------------
! 				    Aliasing
! ---------------------------------------------------------------------------*/
! /* Compute may-alias information for every variable referenced in function
!    FNDECL.  Note that in the absence of points-to analysis
!    (-ftree-points-to), this may compute a much bigger set than necessary.  */
  
! void
! compute_may_aliases (tree fndecl ATTRIBUTE_UNUSED)
  {
!   timevar_push (TV_TREE_MAY_ALIAS);
  
!   if (flag_tree_points_to != PTA_NONE)
      {
!       timevar_push (TV_TREE_PTA);
!       create_alias_vars (fndecl);
!       timevar_pop (TV_TREE_PTA);
      }
  
!   /* Compute alias sets.  */
!   compute_alias_sets ();
!   
!   if (flag_tree_points_to != PTA_NONE)
!     {
!       timevar_push (TV_TREE_PTA);
!       delete_alias_vars ();
!       timevar_pop (TV_TREE_PTA);
!     }
! 
!   /* Deallocate memory used by aliasing data structures.  */
!   addressable_vars = NULL;
!   pointers = NULL;
! 
!   timevar_pop (TV_TREE_MAY_ALIAS);
  }
  
  
! /* Find all the variables referenced in function FNDECL.  This function
!    builds the global arrays REFERENCED_VARS and CALL_CLOBBERED_VARS.  It
!    also builds the local arrays ADDRESSABLE_VARS and POINTERS used for
!    alias analysis.
! 
!    Note that this function does not look for statement operands, it simply
!    determines what variables are referenced in the program and detects
!    various attributes for each variable used by alias analysis and the
!    optimizer.  */
  
  void
! find_referenced_vars (tree fndecl)
  {
    static htab_t vars_found;
    basic_block bb;
*************** compute_may_aliases (tree fndecl)
*** 1735,1741 ****
    struct walk_state walk_state;
    tree block;
  
!   timevar_push (TV_TREE_MAY_ALIAS);
  
    /* Walk the lexical blocks in the function looking for variables that may
       have been used to declare VLAs and for nested functions.  Both
--- 1763,1770 ----
    struct walk_state walk_state;
    tree block;
  
!   VARRAY_GENERIC_PTR_INIT (addressable_vars, 20, "addressable_vars");
!   VARRAY_GENERIC_PTR_INIT (pointers, 20, "pointers");
  
    /* Walk the lexical blocks in the function looking for variables that may
       have been used to declare VLAs and for nested functions.  Both
*************** compute_may_aliases (tree fndecl)
*** 1751,1795 ****
        block = BLOCK_CHAIN (block);
      }
  
-   VARRAY_GENERIC_PTR_INIT (addressable_vars, 20, "addressable_vars");
-   VARRAY_GENERIC_PTR_INIT (pointers, 20, "pointers");
- 
-   /* Hash table of all the objects the SSA builder needs to be aware of.  */
    vars_found = htab_create (50, htab_hash_pointer, htab_eq_pointer, NULL);
! 
!   if (flag_tree_points_to != PTA_NONE)
!     {
!       timevar_push (TV_TREE_PTA);
!       create_alias_vars (fndecl);
!       timevar_pop (TV_TREE_PTA);
!     }
! 
    walk_state.vars_found = vars_found;
-   walk_state.is_store = 0;
-   walk_state.is_indirect_ref = 0;
-   walk_state.is_asm_expr = 0;
  
-   /* Find all the variables referenced in the function.  */
    FOR_EACH_BB (bb)
      for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
!       walk_tree (bsi_stmt_ptr (si), find_vars_r, &walk_state, NULL);
  
!   htab_delete (vars_found);
  
!   compute_alias_sets ();
!   
!   if (flag_tree_points_to != PTA_NONE)
!     {
!       timevar_push (TV_TREE_PTA);
!       delete_alias_vars ();
!       timevar_pop (TV_TREE_PTA);
!     }
  
!   /* Deallocate memory used by aliasing data structures.  */
!   addressable_vars = NULL;
!   pointers = NULL;
  
!   timevar_pop (TV_TREE_MAY_ALIAS);
  }
  
  
--- 1780,1844 ----
        block = BLOCK_CHAIN (block);
      }
  
    vars_found = htab_create (50, htab_hash_pointer, htab_eq_pointer, NULL);
!   memset (&walk_state, 0, sizeof (walk_state));
    walk_state.vars_found = vars_found;
  
    FOR_EACH_BB (bb)
      for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
!       {
! 	tree *stmt_p = bsi_stmt_ptr (si);
  
! 	/* Propagate non-GIMPLE attribute into the statement.  FIXME:
! 	   The only statements that are not in GIMPLE form are calls to MD
! 	   builtins.  Propagate the non-GIMPLE attribute from the RHS of
! 	   assignments into the statement, if needed.  */
! 	if (TREE_CODE (*stmt_p) == MODIFY_EXPR
! 	    && TREE_CODE (TREE_OPERAND (*stmt_p, 1)) == CALL_EXPR
! 	    && TREE_NOT_GIMPLE (TREE_OPERAND (*stmt_p, 1)))
! 	  {
! 	    mark_not_gimple (stmt_p);
! 	    /* Prevent get_stmt_operands() from ever dealing with this
! 	       statement.  */
! 	    unmodify_stmt (*stmt_p);
! 	  }
  
! 	/* A CALL_EXPR may also appear inside a RETURN_EXPR.  */
! 	if (TREE_CODE (*stmt_p) == RETURN_EXPR)
! 	  {
! 	    tree expr = TREE_OPERAND (*stmt_p, 0);
! 	    if (expr
! 		&& TREE_CODE (expr) == MODIFY_EXPR
! 		&& TREE_CODE (TREE_OPERAND (expr, 1)) == CALL_EXPR
! 		&& TREE_NOT_GIMPLE (TREE_OPERAND (expr, 1)))
! 	      {
! 		mark_not_gimple (stmt_p);
! 		/* Prevent get_stmt_operands() from ever dealing with this
! 		   statement.  */
! 		unmodify_stmt (*stmt_p);
! 	      }
! 	  }
  
! 	if (TREE_NOT_GIMPLE (*stmt_p))
! 	  walk_state.is_not_gimple = 1;
  
! 	walk_tree (stmt_p, find_vars_r, &walk_state, NULL);
! 	walk_state.is_not_gimple = 0;
!       }
! 
!   htab_delete (vars_found);
! 
! #if 0
!   /* Purge the arrays of variables.  Variables that have hidden uses must
!      be removed so that the optimizers don't do anything with them.  Note
!      that this can't be done while looking for variables because it may not
!      be obvious that a variable has hidden uses until it's found inside a
!      VLA declaration or an MD built-in call.  */
!   remove_hidden_vars_from (referenced_vars, false);
!   remove_hidden_vars_from (call_clobbered_vars, false);
!   remove_hidden_vars_from (addressable_vars, true);
!   remove_hidden_vars_from (pointers, true);
! #endif
  }
  
  
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2216,2222 ****
  {
    tree t = *tp;
    struct walk_state *walk_state = (struct walk_state *)data;
!   int saved_is_store = walk_state->is_store;
  
    /* Type and constant nodes have no interesting children.  Ignore them.  */
    if (TYPE_P (t) || TREE_CODE_CLASS (TREE_CODE (t)) == 'c')
--- 2265,2275 ----
  {
    tree t = *tp;
    struct walk_state *walk_state = (struct walk_state *)data;
! 
! #if defined ENABLE_CHECKING
!   if (TREE_NOT_GIMPLE (*tp) && walk_state->is_not_gimple == 0)
!     abort ();
! #endif
  
    /* Type and constant nodes have no interesting children.  Ignore them.  */
    if (TYPE_P (t) || TREE_CODE_CLASS (TREE_CODE (t)) == 'c')
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2238,2261 ****
  
    if (TREE_CODE (t) == MODIFY_EXPR)
      {
        walk_state->is_store = 1;
!       walk_tree (&TREE_OPERAND (t, 0), find_vars_r, data, NULL);
        walk_state->is_store = 0;
!       walk_tree (&TREE_OPERAND (t, 1), find_vars_r, data, NULL);
!       walk_state->is_store = saved_is_store;
  
        /* If this is an assignment to a pointer and the RHS may point to
! 	 global memory, mark the pointer on the LHS.  FIXME: This causes a
! 	 second traversal of the RHS of the assignment, we should set a bit
! 	 in WALK_STATE as we walk the RHS.  */
!       if (SSA_VAR_P (TREE_OPERAND (t, 0))
! 	  && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0)))
! 	  && may_access_global_mem_p (TREE_OPERAND (t, 1)))
! 	set_may_point_to_global_mem (TREE_OPERAND (t, 0));
  
        /* If either side makes volatile references, mark the statement.  */
!       if (TREE_THIS_VOLATILE (TREE_OPERAND (t, 0))
! 	  || TREE_THIS_VOLATILE (TREE_OPERAND (t, 1)))
  	get_stmt_ann (t)->has_volatile_ops = 1;
  
        return t;
--- 2291,2314 ----
  
    if (TREE_CODE (t) == MODIFY_EXPR)
      {
+       tree *lhs_p = &TREE_OPERAND (t, 0);
+       tree *rhs_p = &TREE_OPERAND (t, 1);
+ 
        walk_state->is_store = 1;
!       walk_tree (lhs_p, find_vars_r, walk_state, NULL);
        walk_state->is_store = 0;
!       walk_tree (rhs_p, find_vars_r, walk_state, NULL);
  
        /* If this is an assignment to a pointer and the RHS may point to
! 	 global memory, mark the pointer on the LHS.  */
!       if (SSA_VAR_P (*lhs_p)
! 	  && POINTER_TYPE_P (TREE_TYPE (*lhs_p))
! 	  && may_access_global_mem_p (*rhs_p))
! 	set_may_point_to_global_mem (*lhs_p);
  
        /* If either side makes volatile references, mark the statement.  */
!       if (TREE_THIS_VOLATILE (*lhs_p)
! 	  || TREE_THIS_VOLATILE (*rhs_p))
  	get_stmt_ann (t)->has_volatile_ops = 1;
  
        return t;
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2264,2302 ****
      {
        walk_state->is_asm_expr = 1;
        walk_state->is_store = 1;
!       walk_tree (&ASM_OUTPUTS (t), find_vars_r, data, NULL);
!       walk_tree (&ASM_CLOBBERS (t), find_vars_r, data, NULL);
        walk_state->is_store = 0;
!       walk_tree (&ASM_INPUTS (t), find_vars_r, data, NULL);
!       walk_state->is_store = saved_is_store;
        walk_state->is_asm_expr = 0;
        return t;
      }
    else if (TREE_CODE (t) == INDIRECT_REF)
      {
        walk_state->is_indirect_ref = 1;
!       walk_tree (&TREE_OPERAND (t, 0), find_vars_r, data, NULL);
        /* INDIRECT_REF nodes cannot be nested in GIMPLE, so there is no need
  	 of saving/restoring the state.  */
        walk_state->is_indirect_ref = 0;
        return NULL_TREE;
      }
  
!   if (SSA_VAR_P (*tp))
      {
!       add_referenced_var (*tp, walk_state);
        return NULL_TREE;
      }
  
    /* A function call that receives pointer arguments may dereference them.
       For every pointer 'p' in the argument to the function call, add a
       reference to '*p'.  */
!   if (TREE_CODE (*tp) == CALL_EXPR)
      {
        tree op;
!       int call_flags = get_call_flags (*tp);
  
!       for (op = TREE_OPERAND (*tp, 1); op; op = TREE_CHAIN (op))
  	{
  	  tree arg = TREE_VALUE (op);
  	  if (SSA_VAR_P (arg) && POINTER_TYPE_P (TREE_TYPE (arg)))
--- 2317,2365 ----
      {
        walk_state->is_asm_expr = 1;
        walk_state->is_store = 1;
!       walk_tree (&ASM_OUTPUTS (t), find_vars_r, walk_state, NULL);
!       walk_tree (&ASM_CLOBBERS (t), find_vars_r, walk_state, NULL);
        walk_state->is_store = 0;
!       walk_tree (&ASM_INPUTS (t), find_vars_r, walk_state, NULL);
        walk_state->is_asm_expr = 0;
        return t;
      }
    else if (TREE_CODE (t) == INDIRECT_REF)
      {
        walk_state->is_indirect_ref = 1;
!       walk_tree (&TREE_OPERAND (t, 0), find_vars_r, walk_state, NULL);
! 
        /* INDIRECT_REF nodes cannot be nested in GIMPLE, so there is no need
  	 of saving/restoring the state.  */
        walk_state->is_indirect_ref = 0;
+ 
+       /* Keep iterating, because an INDIRECT_REF node may have more
+ 	 references inside (structures and arrays).  */
        return NULL_TREE;
      }
+   else if (TREE_CODE (t) == VA_ARG_EXPR)
+     {
+       walk_state->is_va_arg_expr = 1;
+       walk_tree (&TREE_OPERAND (t, 0), find_vars_r, walk_state, NULL);
+       walk_state->is_va_arg_expr = 0;
+       return t;
+     }
  
!   if (SSA_VAR_P (t))
      {
!       add_referenced_var (t, walk_state);
        return NULL_TREE;
      }
  
    /* A function call that receives pointer arguments may dereference them.
       For every pointer 'p' in the argument to the function call, add a
       reference to '*p'.  */
!   if (TREE_CODE (t) == CALL_EXPR && walk_state->is_not_gimple == 0)
      {
        tree op;
!       int call_flags = get_call_flags (t);
  
!       for (op = TREE_OPERAND (t, 1); op; op = TREE_CHAIN (op))
  	{
  	  tree arg = TREE_VALUE (op);
  	  if (SSA_VAR_P (arg) && POINTER_TYPE_P (TREE_TYPE (arg)))
*************** find_vars_r (tree *tp, int *walk_subtree
*** 2314,2322 ****
  	 consider this call as a store operation to .GLOBAL_VAR.  */
        if (!(call_flags & (ECF_CONST | ECF_PURE | ECF_NORETURN)))
  	walk_state->is_store = 1;
- 
        add_referenced_var (global_var, walk_state);
!       walk_state->is_store = saved_is_store;
      }
  
    return NULL_TREE;
--- 2377,2384 ----
  	 consider this call as a store operation to .GLOBAL_VAR.  */
        if (!(call_flags & (ECF_CONST | ECF_PURE | ECF_NORETURN)))
  	walk_state->is_store = 1;
        add_referenced_var (global_var, walk_state);
!       walk_state->is_store = 0;
      }
  
    return NULL_TREE;
*************** add_referenced_var (tree var, struct wal
*** 2342,2347 ****
--- 2404,2414 ----
  
    v_ann = get_var_ann (var);
  
+   /* If the variable has already been flagged as having hidden uses,
+      ignore it.  */
+   if (v_ann->has_hidden_use)
+     return;
+ 
    slot = htab_find_slot (vars_found, (void *) var, INSERT);
    if (*slot == NULL)
      {
*************** add_referenced_var (tree var, struct wal
*** 2378,2384 ****
  	  alias_map = ggc_alloc (sizeof (*alias_map));
  	  alias_map->var = var;
  	  alias_map->set = get_alias_set (var);
! 	  VARRAY_PUSH_GENERIC_PTR (addressable_vars, (void *) alias_map);
  	}
  
        /* Addressable variables, memory tags and static locals may be used
--- 2445,2451 ----
  	  alias_map = ggc_alloc (sizeof (*alias_map));
  	  alias_map->var = var;
  	  alias_map->set = get_alias_set (var);
! 	  VARRAY_PUSH_GENERIC_PTR (addressable_vars, alias_map);
  	}
  
        /* Addressable variables, memory tags and static locals may be used
*************** add_referenced_var (tree var, struct wal
*** 2401,2406 ****
--- 2468,2485 ----
    if (walk_state->is_store)
      v_ann->is_stored = 1;
  
+   /* If VAR is being referenced inside a non-GIMPLE tree, mark it as having
+      hidden uses.  Currently, this is used for MD built-ins, which are not
+      gimplified and cannot be optimized.  FIXME: long term all trees must
+      be in GIMPLE form.  */
+   if (walk_state->is_not_gimple)
+     v_ann->has_hidden_use = 1;
+ 
+   /* If VAR is being referenced inside a VA_ARG_EXPR, mark it so that all
+      operands to VAR are always virtual.  */
+   if (walk_state->is_va_arg_expr)
+     v_ann->is_in_va_arg_expr = 1;
+ 
    /* If the variable is a pointer being clobbered by an ASM_EXPR, the
       pointer may end up pointing to global memory.  */
    if (POINTER_TYPE_P (TREE_TYPE (var))
*************** get_memory_tag_for (tree ptr)
*** 2483,2489 ****
        alias_map = ggc_alloc (sizeof (*alias_map));
        alias_map->var = ptr;
        alias_map->set = tag_set;
!       VARRAY_PUSH_GENERIC_PTR (pointers, (void *) alias_map);
      }
  
    return tag;
--- 2562,2568 ----
        alias_map = ggc_alloc (sizeof (*alias_map));
        alias_map->var = ptr;
        alias_map->set = tag_set;
!       VARRAY_PUSH_GENERIC_PTR (pointers, alias_map);
      }
  
    return tag;
*************** create_global_var (void)
*** 2623,2625 ****
--- 2702,2746 ----
    TREE_THIS_VOLATILE (global_var) = 1;
    TREE_ADDRESSABLE (global_var) = 0;
  }
+ 
+ #if 0
+ /* Remove all the variables marked with the has_hidden_use attribute from
+    ARRAY.  IS_ALIAS_MAP is true when ARRAY is an array of struct
+    alias_map_d objects.  */
+ 
+ static void
+ remove_hidden_vars_from (varray_type array, bool is_alias_map)
+ {
+   size_t i;
+ 
+   for (i = 0; i < VARRAY_ACTIVE_SIZE (array); i++)
+     {
+       tree var = (is_alias_map)
+ 		 ? ((struct alias_map_d *) VARRAY_GENERIC_PTR (array, i))->var
+ 		 : VARRAY_TREE (array, i);
+ 
+       if (0)
+ 	{
+ 	  size_t len = VARRAY_ACTIVE_SIZE (array);
+ 	  if (i < len - 1)
+ 	    {
+ 	      if (is_alias_map)
+ 		VARRAY_GENERIC_PTR (array, i) = VARRAY_GENERIC_PTR (array,
+ 		                                                    len - 1);
+ 	      else
+ 		VARRAY_TREE (array, i) = VARRAY_TREE (array, len - 1);
+ 
+ 	      /* Make sure we visit the element we just moved from the end
+ 		 of the array.  */
+ 	      i--;
+ 	    }
+ 
+ 	  fprintf (stderr, "%s(%d): Removed variable %s from array %s\n",
+ 	           input_filename, input_line, get_name (var), array->name);
+ 	  VARRAY_POP (array);
+ 	}
+     }
+ }
+ #endif
+ 
+ #include "gt-tree-dfa.h"
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.100
diff -d -u -p -c -r1.1.4.100 tree-flow.h
*** tree-flow.h	5 Aug 2003 15:17:57 -0000	1.1.4.100
--- tree-flow.h	7 Aug 2003 18:51:16 -0000
*************** struct var_ann_d GTY(())
*** 95,100 ****
--- 95,106 ----
       applied.  We set this when translating out of SSA form.  */
    unsigned used : 1;
  
+   /* Nonzero if this variable is used as the argument to VA_ARG_EXPR.  This
+      forces all operands to this variable to always be virtual, because
+      VA_ARG_EXPR both reads and modifies its argument and it can't be
+      modified by optimizations.  */
+   unsigned is_in_va_arg_expr;
+ 
    /* A VAR_DECL used to associated pointers with the memory location that
       they are pointing to.  If IS_MEM_TAG is nonzero, then MEM_TAG is the
       pointer associated to this memory tag.  If IS_MEM_TAG is zero, then
*************** extern int could_trap_p (tree);
*** 412,417 ****
--- 418,424 ----
  extern basic_block tree_split_edge (edge);
  
  /* In tree-dfa.c  */
+ void find_referenced_vars (tree);
  extern void get_stmt_operands (tree);
  extern var_ann_t create_var_ann (tree);
  extern stmt_ann_t create_stmt_ann (tree);
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-optimize.c,v
retrieving revision 1.1.4.42
diff -d -u -p -c -r1.1.4.42 tree-optimize.c
*** tree-optimize.c	5 Aug 2003 16:10:53 -0000	1.1.4.42
--- tree-optimize.c	7 Aug 2003 18:51:16 -0000
*************** optimize_function_tree (tree fndecl)
*** 69,74 ****
--- 69,77 ----
        /* Initialize common SSA structures.  */
        init_tree_ssa ();
  
+       /* Find all the variables referenced in the function.  */
+       find_referenced_vars (fndecl);
+ 
        /* Compute aliasing information for all the variables referenced in
  	 the function.  */
        compute_may_aliases (fndecl);
Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-ccp.c,v
retrieving revision 1.1.2.82
diff -d -u -p -c -r1.1.2.82 tree-ssa-ccp.c
*** tree-ssa-ccp.c	5 Aug 2003 13:14:30 -0000	1.1.2.82
--- tree-ssa-ccp.c	7 Aug 2003 18:51:17 -0000
*************** static varray_type cfg_edges;
*** 98,104 ****
     has changed.  SSA edges are def-use edges in the SSA web.  For each
     edge, we store the definition statement or PHI node D.  The destination
     nodes that need to be visited are accessed using immediate_uses (D).  */
! static varray_type ssa_edges;
  
  static void initialize (void);
  static void finalize (void);
--- 98,104 ----
     has changed.  SSA edges are def-use edges in the SSA web.  For each
     edge, we store the definition statement or PHI node D.  The destination
     nodes that need to be visited are accessed using immediate_uses (D).  */
! static GTY(()) varray_type ssa_edges;
  
  static void initialize (void);
  static void finalize (void);
*************** tree_ssa_ccp (tree fndecl)
*** 154,161 ****
        if (VARRAY_ACTIVE_SIZE (cfg_edges) > 0)
  	{
  	  /* Pull the next block to simulate off the worklist.  */
! 	  basic_block dest_block;
! 	  dest_block = ((edge)VARRAY_TOP_GENERIC_PTR (cfg_edges))->dest;
  	  VARRAY_POP (cfg_edges);
  	  simulate_block (dest_block);
  	}
--- 154,160 ----
        if (VARRAY_ACTIVE_SIZE (cfg_edges) > 0)
  	{
  	  /* Pull the next block to simulate off the worklist.  */
! 	  basic_block dest_block = VARRAY_TOP_EDGE (cfg_edges)->dest;
  	  VARRAY_POP (cfg_edges);
  	  simulate_block (dest_block);
  	}
*************** add_control_edge (edge e)
*** 697,703 ****
      return;
  
    e->flags |= EDGE_EXECUTABLE;
!   VARRAY_PUSH_GENERIC_PTR (cfg_edges, e);
  
    if (dump_file && (dump_flags & TDF_DETAILS))
      fprintf (dump_file, "Adding edge (%d -> %d) to worklist\n\n",
--- 696,702 ----
      return;
  
    e->flags |= EDGE_EXECUTABLE;
!   VARRAY_PUSH_EDGE (cfg_edges, e);
  
    if (dump_file && (dump_flags & TDF_DETAILS))
      fprintf (dump_file, "Adding edge (%d -> %d) to worklist\n\n",
*************** initialize (void)
*** 1032,1045 ****
      }
  
  
!   VARRAY_GENERIC_PTR_INIT (cfg_edges, 20, "cfg_edges");
  
    /* Seed the algorithm by adding the successors of the entry block to the
       edge worklist.  */
    for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
      {
        e->flags |= EDGE_EXECUTABLE;
!       VARRAY_PUSH_GENERIC_PTR (cfg_edges, e);
      }
  }
  
--- 1031,1044 ----
      }
  
  
!   VARRAY_EDGE_INIT (cfg_edges, 20, "cfg_edges");
  
    /* Seed the algorithm by adding the successors of the entry block to the
       edge worklist.  */
    for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
      {
        e->flags |= EDGE_EXECUTABLE;
!       VARRAY_PUSH_EDGE (cfg_edges, e);
      }
  }
  
*************** get_strlen (tree arg)
*** 1585,1587 ****
--- 1584,1588 ----
  
    return NULL_TREE;
  }
+ 
+ #include "gt-tree-ssa-ccp.h"
Index: tree-ssa-dce.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dce.c,v
retrieving revision 1.1.2.51
diff -d -u -p -c -r1.1.2.51 tree-ssa-dce.c
*** tree-ssa-dce.c	5 Aug 2003 19:20:49 -0000	1.1.2.51
--- tree-ssa-dce.c	7 Aug 2003 18:51:17 -0000
*************** need_to_preserve_store (tree var)
*** 201,210 ****
    if (may_alias_global_mem_p (sym))
      return true;
  
    /* If SYM is used in some way that we can not readily see in the IL, then
       we need to preserve it.  FIXME: Long term this needs to go away.  */
    if (has_hidden_use (sym))
!     return true;
  
    return false;
  }
--- 201,212 ----
    if (may_alias_global_mem_p (sym))
      return true;
  
+ #if 1
    /* If SYM is used in some way that we can not readily see in the IL, then
       we need to preserve it.  FIXME: Long term this needs to go away.  */
    if (has_hidden_use (sym))
!     abort ();
! #endif
  
    return false;
  }
Index: tree-ssa-live.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-live.c,v
retrieving revision 1.1.2.14
diff -d -u -p -c -r1.1.2.14 tree-ssa-live.c
*** tree-ssa-live.c	31 Jul 2003 12:10:46 -0000	1.1.2.14
--- tree-ssa-live.c	7 Aug 2003 18:51:17 -0000
*************** type_var_init (var_map map)
*** 878,888 ****
    for (x = num_partitions - 1; x >= 0; x--)
      {
        t = partition_to_var (map, x);
        /* Disallow coalescing of these types of variables.  */
!       if (!t || TREE_THIS_VOLATILE (t) || TREE_CODE (t) == RESULT_DECL
        	  || TREE_CODE (t) == PARM_DECL 
! 	  || (DECL_P (t) && (DECL_REGISTER (t) || !DECL_ARTIFICIAL (t)
! 			     || DECL_RTL_SET_P (t) || has_hidden_use (t))))
          continue;
  
        p = var_to_partition (map, t);
--- 878,895 ----
    for (x = num_partitions - 1; x >= 0; x--)
      {
        t = partition_to_var (map, x);
+       if (has_hidden_use (t))
+ 	abort ();
+ 
        /* Disallow coalescing of these types of variables.  */
!       if (!t
! 	  || TREE_THIS_VOLATILE (t)
! 	  || TREE_CODE (t) == RESULT_DECL
        	  || TREE_CODE (t) == PARM_DECL 
! 	  || (DECL_P (t)
! 	      && (DECL_REGISTER (t)
! 		  || !DECL_ARTIFICIAL (t)
! 		  || DECL_RTL_SET_P (t))))
          continue;
  
        p = var_to_partition (map, t);
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.114
diff -d -u -p -c -r1.1.4.114 tree-ssa.c
*** tree-ssa.c	5 Aug 2003 15:17:58 -0000	1.1.4.114
--- tree-ssa.c	7 Aug 2003 18:51:17 -0000
*************** static htab_t def_blocks;
*** 77,83 ****
  
  /* Structure to map a variable VAR to the set of blocks that contain
     definitions for VAR.  */
! struct def_blocks_d
  {
    tree var;
    bitmap def_blocks;
--- 77,83 ----
  
  /* Structure to map a variable VAR to the set of blocks that contain
     definitions for VAR.  */
! struct GTY(()) def_blocks_d
  {
    tree var;
    bitmap def_blocks;
*************** static htab_t currdefs;
*** 93,99 ****
  /* Structure to map variables to values.  It's used to keep track of the
     current reaching definition, constant values and variable copies while
     renaming.  */
! struct var_value_d
  {
    tree var;
    tree value;
--- 93,99 ----
  /* Structure to map variables to values.  It's used to keep track of the
     current reaching definition, constant values and variable copies while
     renaming.  */
! struct GTY(()) var_value_d
  {
    tree var;
    tree value;
*************** static hashval_t def_blocks_hash (const 
*** 161,167 ****
  static int def_blocks_eq (const void *, const void *);
  static hashval_t var_value_hash (const void *);
  static int var_value_eq (const void *, const void *);
- static void def_blocks_free (void *);
  static int debug_def_blocks_r (void **, void *);
  static struct def_blocks_d *get_def_blocks_for (tree);
  static void htab_statistics (FILE *, htab_t);
--- 161,166 ----
*************** rewrite_into_ssa (tree fndecl, sbitmap v
*** 297,307 ****
  
    /* Allocate memory for the DEF_BLOCKS hash table.  */
    def_blocks = htab_create (VARRAY_ACTIVE_SIZE (referenced_vars),
! 			    def_blocks_hash, def_blocks_eq, def_blocks_free);
  
    /* Allocate memory for the CURRDEFS hash table.  */
    currdefs = htab_create (VARRAY_ACTIVE_SIZE (referenced_vars),
! 			  var_value_hash, var_value_eq, free);
  
    /* Allocate memory for the GLOBALS bitmap which will indicate which
       variables are live across basic block boundaries.  Note that this
--- 296,306 ----
  
    /* Allocate memory for the DEF_BLOCKS hash table.  */
    def_blocks = htab_create (VARRAY_ACTIVE_SIZE (referenced_vars),
! 			    def_blocks_hash, def_blocks_eq, NULL);
  
    /* Allocate memory for the CURRDEFS hash table.  */
    currdefs = htab_create (VARRAY_ACTIVE_SIZE (referenced_vars),
! 			  var_value_hash, var_value_eq, NULL);
  
    /* Allocate memory for the GLOBALS bitmap which will indicate which
       variables are live across basic block boundaries.  Note that this
*************** rewrite_into_ssa (tree fndecl, sbitmap v
*** 393,399 ****
    for (i = 0; i < n_basic_blocks; i++)
      BITMAP_XFREE (dfs[i]);
    free (dfs);
!   free (globals);
    htab_delete (def_blocks);
    htab_delete (currdefs);
    if (vars == NULL)
--- 392,398 ----
    for (i = 0; i < n_basic_blocks; i++)
      BITMAP_XFREE (dfs[i]);
    free (dfs);
!   sbitmap_free (globals);
    htab_delete (def_blocks);
    htab_delete (currdefs);
    if (vars == NULL)
*************** mark_def_sites (sbitmap globals)
*** 626,632 ****
  	}
      }
  
!   free (kills);
  }
  
  /* Mark block BB as the definition site for variable VAR.  */
--- 625,631 ----
  	}
      }
  
!   sbitmap_free (kills);
  }
  
  /* Mark block BB as the definition site for variable VAR.  */
*************** set_def_block (tree var, basic_block bb)
*** 642,651 ****
    slot = htab_find_slot (def_blocks, (void *) &db, INSERT);
    if (*slot == NULL)
      {
!       db_p = xmalloc (sizeof (*db_p));
        db_p->var = var;
!       db_p->def_blocks = BITMAP_XMALLOC ();
!       db_p->livein_blocks = BITMAP_XMALLOC ();
        *slot = (void *) db_p;
      }
    else
--- 641,650 ----
    slot = htab_find_slot (def_blocks, (void *) &db, INSERT);
    if (*slot == NULL)
      {
!       db_p = ggc_alloc (sizeof (*db_p));
        db_p->var = var;
!       db_p->def_blocks = BITMAP_GGC_ALLOC ();
!       db_p->livein_blocks = BITMAP_GGC_ALLOC ();
        *slot = (void *) db_p;
      }
    else
*************** set_livein_block (tree var, basic_block 
*** 668,677 ****
    slot = htab_find_slot (def_blocks, (void *) &db, INSERT);
    if (*slot == NULL)
      {
!       db_p = xmalloc (sizeof (*db_p));
        db_p->var = var;
!       db_p->def_blocks = BITMAP_XMALLOC ();
!       db_p->livein_blocks = BITMAP_XMALLOC ();
        *slot = (void *) db_p;
      }
    else
--- 667,676 ----
    slot = htab_find_slot (def_blocks, (void *) &db, INSERT);
    if (*slot == NULL)
      {
!       db_p = ggc_alloc (sizeof (*db_p));
        db_p->var = var;
!       db_p->def_blocks = BITMAP_GGC_ALLOC ();
!       db_p->livein_blocks = BITMAP_GGC_ALLOC ();
        *slot = (void *) db_p;
      }
    else
*************** insert_phi_nodes (bitmap *dfs, sbitmap g
*** 698,704 ****
  
    timevar_push (TV_TREE_INSERT_PHI_NODES);
  
!   VARRAY_GENERIC_PTR_INIT (def_maps, HOST_BITS_PER_WIDE_INT, "deferred_vars");
  
    /* Array WORK_STACK is a stack of CFG blocks.  Each block that contains
       an assignment or PHI node will be pushed to this stack.  */
--- 697,703 ----
  
    timevar_push (TV_TREE_INSERT_PHI_NODES);
  
!   VARRAY_GENERIC_PTR_INIT (def_maps, HOST_BITS_PER_WIDE_INT, "def_maps");
  
    /* Array WORK_STACK is a stack of CFG blocks.  Each block that contains
       an assignment or PHI node will be pushed to this stack.  */
*************** insert_phis_for_deferred_variables (varr
*** 1889,1895 ****
  	    create_phi_node (var, BASIC_BLOCK (bb_index));
  	});
  
-       BITMAP_XFREE (phi_insertion_points);
        def_map->phi_insertion_points = NULL;
      }
  }
--- 1888,1893 ----
*************** insert_phi_nodes_for (tree var, bitmap *
*** 1908,1914 ****
    if (def_map == NULL)
      return;
  
!   phi_insertion_points = BITMAP_XMALLOC ();
  
    EXECUTE_IF_SET_IN_BITMAP (def_map->def_blocks, 0, bb_index,
      {
--- 1906,1912 ----
    if (def_map == NULL)
      return;
  
!   phi_insertion_points = BITMAP_GGC_ALLOC ();
  
    EXECUTE_IF_SET_IN_BITMAP (def_map->def_blocks, 0, bb_index,
      {
*************** insert_phi_nodes_for (tree var, bitmap *
*** 1981,1987 ****
        create_phi_node (var, BASIC_BLOCK (bb_index));
      });
  
!   BITMAP_XFREE (phi_insertion_points);
  }
  
  /* Scan all the statements looking for symbols not in SSA form.  If any are
--- 1979,1985 ----
        create_phi_node (var, BASIC_BLOCK (bb_index));
      });
  
!   phi_insertion_points = NULL;
  }
  
  /* Scan all the statements looking for symbols not in SSA form.  If any are
*************** register_new_def (tree var, tree def, va
*** 2181,2187 ****
  /*---------------------------------------------------------------------------
  			     Various helpers.
  ---------------------------------------------------------------------------*/
! /* Initialize DFA/SSA structures.  */
  
  void
  init_tree_ssa (void)
--- 2179,2185 ----
  /*---------------------------------------------------------------------------
  			     Various helpers.
  ---------------------------------------------------------------------------*/
! /* Initialize global DFA and SSA structures.  */
  
  void
  init_tree_ssa (void)
*************** init_tree_ssa (void)
*** 2189,2195 ****
    next_ssa_version = 1;
    VARRAY_TREE_INIT (referenced_vars, 20, "referenced_vars");
    VARRAY_TREE_INIT (call_clobbered_vars, 20, "call_clobbered_vars");
!   memset ((void *) &ssa_stats, 0, sizeof (ssa_stats));
    global_var = NULL_TREE;
  }
  
--- 2187,2193 ----
    next_ssa_version = 1;
    VARRAY_TREE_INIT (referenced_vars, 20, "referenced_vars");
    VARRAY_TREE_INIT (call_clobbered_vars, 20, "call_clobbered_vars");
!   memset (&ssa_stats, 0, sizeof (ssa_stats));
    global_var = NULL_TREE;
  }
  
*************** get_reaching_def (tree var)
*** 2273,2290 ****
  }
  
  
- /* Free memory allocated for a <def, def_blocks> tuple.  */
- 
- static void
- def_blocks_free (void *p)
- {
-   struct def_blocks_d *db_p = (struct def_blocks_d *) p;
-   BITMAP_XFREE (db_p->def_blocks);
-   BITMAP_XFREE (db_p->livein_blocks);
-   free (p);
- }
- 
- 
  /* Hashing and equality functions for DEF_BLOCKS.  */
  
  static hashval_t
--- 2271,2276 ----
*************** set_value_for (tree var, tree value, hta
*** 2385,2391 ****
    slot = htab_find_slot (table, (void *) &vm, INSERT);
    if (*slot == NULL)
      {
!       vm_p = xmalloc (sizeof *vm_p);
        vm_p->var = var;
        *slot = (void *) vm_p;
      }
--- 2371,2377 ----
    slot = htab_find_slot (table, (void *) &vm, INSERT);
    if (*slot == NULL)
      {
!       vm_p = ggc_alloc (sizeof *vm_p);
        vm_p->var = var;
        *slot = (void *) vm_p;
      }
*************** get_def_blocks_for (tree var)
*** 2404,2408 ****
    struct def_blocks_d dm;
  
    dm.var = var;
!   return (struct def_blocks_d *) htab_find (def_blocks, (void *) &dm);
  }
--- 2390,2396 ----
    struct def_blocks_d dm;
  
    dm.var = var;
!   return (struct def_blocks_d *) htab_find (def_blocks, &dm);
  }
+ 
+ #include "gt-tree-ssa.h"
Index: varray.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varray.c,v
retrieving revision 1.15.2.4
diff -d -u -p -c -r1.15.2.4 varray.c
*** varray.c	23 Jul 2003 17:00:02 -0000	1.15.2.4
--- varray.c	7 Aug 2003 18:51:17 -0000
*************** static const struct {
*** 57,62 ****
--- 57,63 ----
    { sizeof (struct const_equiv_data), 0 },
    { sizeof (struct basic_block_def *), 0 },
    { sizeof (struct elt_list *), 1 },
+   { sizeof (struct edge_def *), 0 },
  };
  
  /* Allocate a virtual array with NUM_ELEMENT elements, each of which is
Index: varray.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varray.h,v
retrieving revision 1.28.2.3
diff -d -u -p -c -r1.28.2.3 varray.h
*** varray.h	23 Jul 2003 17:00:02 -0000	1.28.2.3
--- varray.h	7 Aug 2003 18:51:17 -0000
*************** enum varray_data_enum {
*** 81,86 ****
--- 81,87 ----
    VARRAY_DATA_CONST_EQUIV,
    VARRAY_DATA_BB,
    VARRAY_DATA_TE,
+   VARRAY_DATA_EDGE,
    NUM_VARRAY_DATA
  };
  
*************** typedef union varray_data_tag GTY (()) {
*** 126,131 ****
--- 127,134 ----
  				tag ("VARRAY_DATA_BB")))	bb[1];
    struct elt_list	 *GTY ((length ("%0.num_elements"),
  				tag ("VARRAY_DATA_TE")))	te[1];
+   struct edge_def        *GTY ((length ("%0.num_elements"), skip (""),
+ 	                        tag ("VARRAY_DATA_EDGE")))	e[1];
  } varray_data;
  
  /* Virtual array of pointers header.  */
*************** extern varray_type varray_init (size_t, 
*** 204,209 ****
--- 207,215 ----
  #define VARRAY_ELT_LIST_INIT(va, num, name) \
    va = varray_init (num, VARRAY_DATA_TE, name)
  
+ #define VARRAY_EDGE_INIT(va, num, name) \
+   va = varray_init (num, VARRAY_DATA_EDGE, name)
+ 
  /* Free up memory allocated by the virtual array, but do not free any of the
     elements involved.  */
  #define VARRAY_FREE(vp) \
*************** extern void varray_check_failed (varray_
*** 276,281 ****
--- 282,288 ----
  #define VARRAY_CONST_EQUIV(VA, N)	VARRAY_CHECK (VA, N, const_equiv)
  #define VARRAY_BB(VA, N)		VARRAY_CHECK (VA, N, bb)
  #define VARRAY_ELT_LIST(VA, N)		VARRAY_CHECK (VA, N, te)
+ #define VARRAY_EDGE(VA, N)		VARRAY_CHECK (VA, N, e)
  
  /* Push a new element on the end of VA, extending it if necessary.  */
  #define VARRAY_PUSH_CHAR(VA, X)		VARRAY_PUSH (VA, c, X)
*************** extern void varray_check_failed (varray_
*** 297,302 ****
--- 304,310 ----
  #define VARRAY_PUSH_REG(VA, X)		VARRAY_PUSH (VA, reg, X)
  #define VARRAY_PUSH_CONST_EQUIV(VA, X)	VARRAY_PUSH (VA, const_equiv, X)
  #define VARRAY_PUSH_BB(VA, X)		VARRAY_PUSH (VA, bb, X)
+ #define VARRAY_PUSH_EDGE(VA, X)		VARRAY_PUSH (VA, e, X)
  
  /* Return the last element of VA.  */
  #define VARRAY_TOP_CHAR(VA)		VARRAY_TOP (VA, c)
*************** extern void varray_check_failed (varray_
*** 318,322 ****
--- 326,331 ----
  #define VARRAY_TOP_REG(VA)		VARRAY_TOP (VA, reg)
  #define VARRAY_TOP_CONST_EQUIV(VA)	VARRAY_TOP (VA, const_equiv)
  #define VARRAY_TOP_BB(VA)		VARRAY_TOP (VA, bb)
+ #define VARRAY_TOP_EDGE(VA)		VARRAY_TOP (VA, e)
  
  #endif /* ! GCC_VARRAY_H */


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