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: [tree-ssa] Tail recursion improvement


On Fri, 2004-03-05 at 09:47, Zdenek Dvorak wrote:

> the problem seems to be that some of the ssa names do not lose the name
> tags, while the other (those that we rewrite out of ssa) do; to make it
> work as you suggest (or at least as I understand you suggest) would
> require get_stmt_operands to add also vdefs for type tags whenever
> it adds them for name tags, which somehow beats the purpose of name tags.
> 
The core of the problem was that we were not properly marking variables
that were modified nor pointers used in store or load operations.

At some point in the past we had added bit flags that would mark whether
a variable had been written to so that the alias pass would consider or
ignore it when computing aliases.  Since those flags were computed in
the variable discovery pass, we would miss things like call-clobbered
variables, or new variables added by other passes.

Since some variables were not being considered modified, the type based
alias pass was not creating alias sets for them, even though they were
necessary.  So, the fix involves moving the store discovery logic to the
alias analyzer proper.

This also allows us to remove these flags from var_ann_d that were a
pain to maintain, because passes like copy-prop needed to update them. 
This ultimately is more correct.  The additions do not affect compile
time in a significant way.

The patch also includes Zdenek's tail recursion reorg.

Bootstrapped and tested x86, x86-64 and ia64.


Diego.


	* tree-dfa.c (struct walk_state): Remove fields 'is_store' and
	'is_indirect_ref'.  Update all users.
	* tree-flow.h (struct var_ann_d): Remove fields 'is_stored',
	'is_dereferenced_store' and 'is_dereferenced_load'.  Update
	all users.
	* tree-simple.c (get_base_address): Handle BIT_FIELD_REF.
	* tree-ssa-alias.c (struct alias_info): Add fields
	'written_vars', 'dereferenced_ptrs_store' and
	'dereferenced_ptrs_load'.
	(init_alias_info): Initialize them.
	(delete_alias_info): Free them.
	(find_ptr_dereference): New.
	(ptr_is_dereferenced_by): Call it.
	Add new argument 'is_store'.  Set to true if the
	expression is an indirect store operation.
	(compute_points_to_and_addr_escape): If the statement
	makes a store, load or write operation, update the
	corresponding bitmap.
	(compute_flow_insensitive_aliasing): Test the
	'written_vars' bitmap to determine if alias sets should
	be computed.
	(setup_pointers_and_addressables): Always assume that
	volatile pointers and hidden pointers have been used in a
	memory store operation.
	* tree-ssa-operands.c (add_stmt_operand): Do add an
	operand for may-aliased variables before computing
	aliases.


2004-03-11  Zdenek Dvorak

	* tree-optimize.c (init_tree_optimization_passes): Move
	pass_tail_recursion and pass_ch after pass_may_alias.
	* tree-ssa-loop.c (mark_defs_for_rewrite): Mark type tags
	for rewriting.
	* tree-ssa.c (mark_def_sites): Process the operand of a
	VDEF before the result.

Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.219
diff -d -c -p -r1.1.4.219 tree-dfa.c
*** tree-dfa.c	11 Mar 2004 05:07:18 -0000	1.1.4.219
--- tree-dfa.c	12 Mar 2004 04:05:01 -0000
*************** struct dfa_stats_d
*** 67,78 ****
  /* State information for find_vars_r.  */
  struct walk_state
  {
-   /* Nonzero if the variables found under the current tree are written to.  */
-   int is_store : 1;
- 
-   /* Nonzero if the walker is inside an INDIRECT_REF node.  */
-   int is_indirect_ref : 1;
- 
    /* Hash table used to avoid adding the same variable more than once.  */
    htab_t vars_found;
  };
--- 67,72 ----
*************** varray_type referenced_vars;
*** 112,118 ****
  static void
  find_referenced_vars (void)
  {
!   static htab_t vars_found;
    basic_block bb;
    block_stmt_iterator si;
    struct walk_state walk_state;
--- 106,112 ----
  static void
  find_referenced_vars (void)
  {
!   htab_t vars_found;
    basic_block bb;
    block_stmt_iterator si;
    struct walk_state walk_state;
*************** dump_variable (FILE *file, tree var)
*** 562,576 ****
    if (is_call_clobbered (var))
      fprintf (file, ", call clobbered");
  
-   if (ann->is_stored)
-     fprintf (file, ", is written to");
- 
-   if (ann->is_dereferenced_store)
-     fprintf (file, ", is dereferenced to store");
- 
-   if (ann->is_dereferenced_load)
-     fprintf (file, ", is dereferenced to load");
- 
    if (ann->default_def)
      {
        fprintf (file, ", default def: ");
--- 556,561 ----
*************** find_vars_r (tree *tp, int *walk_subtree
*** 916,924 ****
        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 either side makes volatile references, mark the statement.  */
--- 901,907 ----
*************** find_vars_r (tree *tp, int *walk_subtree
*** 928,955 ****
  
        return t;
      }
-   else if (TREE_CODE (t) == ASM_EXPR)
-     {
-       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);
-       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;
-     }
  
    if (SSA_VAR_P (t))
      {
--- 911,916 ----
*************** find_vars_r (tree *tp, int *walk_subtree
*** 957,983 ****
        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)
-     {
-       tree op;
- 
-       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))
- 	      && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (arg))))
- 	    {
- 	      walk_state->is_indirect_ref = 1;
- 	      add_referenced_var (arg, walk_state);
- 	      walk_state->is_indirect_ref = 0;
- 	    }
- 	}
-     }
- 
    return NULL_TREE;
  }
  
--- 918,923 ----
*************** find_vars_r (tree *tp, int *walk_subtree
*** 987,996 ****
     tag, add it to the POINTERS array.  These two arrays are used for
     alias analysis (See compute_alias_sets).
  
!    WALK_STATE is an array with a hash table used to avoid adding the
!    same variable more than once to its corresponding set as well as flags
!    indicating if we're processing a load or store.  Note that this function
!    assumes that VAR is a valid SSA variable.  */
  
  static void
  add_referenced_var (tree var, struct walk_state *walk_state)
--- 927,936 ----
     tag, add it to the POINTERS array.  These two arrays are used for
     alias analysis (See compute_alias_sets).
  
!    WALK_STATE contains a hash table used to avoid adding the same
!    variable more than once to its corresponding set as well as flags
!    indicating if we're processing a load or store.  Note that this
!    function assumes that VAR is a valid SSA variable.  */
  
  static void
  add_referenced_var (tree var, struct walk_state *walk_state)
*************** add_referenced_var (tree var, struct wal
*** 1024,1051 ****
        if (DECL_NONLOCAL (var))
  	v_ann->used = 1;
      }
- 
-   /* Now, set attributes that depend on WALK_STATE.  */
-   if (walk_state == NULL)
-     return;
- 
-   /* Remember if the variable has been written to.  This is important for
-      alias analysis.  If a variable and its aliases are never modified, it
-      is not interesting for the optimizers because there are no aliased
-      stores to keep track of.  */
-   if (walk_state->is_store)
-     v_ann->is_stored = 1;
- 
-   /* If VAR is a pointer referenced in an INDIRECT_REF node, mark it so
-      that alias analysis creates a memory tag representing the location
-      pointed-to by pointer VAR.  */
-   if (walk_state->is_indirect_ref)
-     {
-       if (walk_state->is_store)
- 	v_ann->is_dereferenced_store = 1;
-       else
- 	v_ann->is_dereferenced_load = 1;
-     }
  }
  
  
--- 964,969 ----
*************** find_hidden_use_vars_r (tree *tp, int *w
*** 1139,1147 ****
  /* Add a temporary variable to REFERENCED_VARS.  This is similar to
     add_referenced_var, but is used by passes that need to add new temps to
     the REFERENCED_VARS array after the program has been scanned for
!    variables.  In particular, none of the annotations that depend on struct
!    walk_state will be set.  The variable will just receive a new UID and be
!    added to the REFERENCED_VARS array without checking for duplicates.  */
  
  void
  add_referenced_tmp_var (tree var)
--- 1057,1064 ----
  /* Add a temporary variable to REFERENCED_VARS.  This is similar to
     add_referenced_var, but is used by passes that need to add new temps to
     the REFERENCED_VARS array after the program has been scanned for
!    variables.  The variable will just receive a new UID and be added
!    to the REFERENCED_VARS array without checking for duplicates.  */
  
  void
  add_referenced_tmp_var (tree var)
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.195
diff -d -c -p -r1.1.4.195 tree-flow.h
*** tree-flow.h	24 Feb 2004 21:09:26 -0000	1.1.4.195
--- tree-flow.h	12 Mar 2004 04:05:01 -0000
*************** struct var_ann_d GTY(())
*** 106,114 ****
  	   has been performed.  */
    unsigned has_hidden_use : 1;
  
-   /* Nonzero if this variable was stored/written in the function.  */
-   unsigned is_stored : 1;
- 
    /* Used by the out of SSA pass to determine whether this variable has
       been seen yet or not.  */
    unsigned out_of_ssa_tag : 1;
--- 106,111 ----
*************** struct var_ann_d GTY(())
*** 127,138 ****
    /* Nonzero if this variable was used after SSA optimizations were
       applied.  We set this when translating out of SSA form.  */
    unsigned used : 1;
- 
-   /* Nonzero if this variable is a pointer that has been dereferenced in a
-      store or a load operation.  Pointers that have been dereferenced are
-      the only ones that need to have memory tags associated to them.  */
-   unsigned is_dereferenced_store : 1;
-   unsigned is_dereferenced_load : 1;
  
    /* This field indicates whether or not the variable may need PHI nodes.
       See the enum's definition for more detailed information about the
--- 124,129 ----
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 1.1.4.132
diff -d -c -p -r1.1.4.132 tree-optimize.c
*** tree-optimize.c	2 Mar 2004 18:41:48 -0000	1.1.4.132
--- tree-optimize.c	12 Mar 2004 04:05:01 -0000
*************** init_tree_optimization_passes (void)
*** 287,294 ****
    NEXT_PASS (DUP_PASS (pass_dce));
    NEXT_PASS (pass_forwprop);
    NEXT_PASS (pass_phiopt);
-   NEXT_PASS (pass_ch);
    NEXT_PASS (pass_may_alias);
    NEXT_PASS (pass_del_pta);
    NEXT_PASS (pass_profile);
    NEXT_PASS (pass_lower_complex);
--- 287,295 ----
    NEXT_PASS (DUP_PASS (pass_dce));
    NEXT_PASS (pass_forwprop);
    NEXT_PASS (pass_phiopt);
    NEXT_PASS (pass_may_alias);
+   NEXT_PASS (pass_tail_recursion);
+   NEXT_PASS (pass_ch);
    NEXT_PASS (pass_del_pta);
    NEXT_PASS (pass_profile);
    NEXT_PASS (pass_lower_complex);
*************** init_tree_optimization_passes (void)
*** 300,306 ****
    NEXT_PASS (pass_dse);
    NEXT_PASS (DUP_PASS (pass_forwprop));
    NEXT_PASS (DUP_PASS (pass_phiopt));
-   NEXT_PASS (pass_tail_recursion);
    NEXT_PASS (pass_loop);
    NEXT_PASS (pass_ccp);
    NEXT_PASS (DUP_PASS (pass_redundant_phi));
--- 301,306 ----
Index: tree-simple.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-simple.c,v
retrieving revision 1.1.4.73
diff -d -c -p -r1.1.4.73 tree-simple.c
*** tree-simple.c	11 Mar 2004 05:07:18 -0000	1.1.4.73
--- tree-simple.c	12 Mar 2004 04:05:01 -0000
*************** get_base_address (tree t)
*** 607,612 ****
--- 607,613 ----
  	case COMPONENT_REF:
  	case REALPART_EXPR:
  	case IMAGPART_EXPR:
+ 	case BIT_FIELD_REF:
  	  t = TREE_OPERAND (t, 0);
  	  break;
  
Index: tree-ssa-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-alias.c,v
retrieving revision 1.1.2.10
diff -d -c -p -r1.1.2.10 tree-ssa-alias.c
*** tree-ssa-alias.c	11 Mar 2004 05:07:18 -0000	1.1.2.10
--- tree-ssa-alias.c	12 Mar 2004 04:05:01 -0000
*************** struct alias_info
*** 103,108 ****
--- 103,117 ----
    /* Total number of virtual operands that will be needed to represent
       all the aliases of all the pointers found in the program.  */
    long total_alias_vops;
+ 
+   /* Variables that have been written to.  */
+   bitmap written_vars;
+ 
+   /* Pointers that have been used in an indirect store operation.  */
+   bitmap dereferenced_ptrs_store;
+ 
+   /* Pointers that have been used in an indirect load operation.  */
+   bitmap dereferenced_ptrs_load;
  };
  
  
*************** static void add_pointed_to_var (struct a
*** 143,149 ****
  static void add_pointed_to_expr (tree, tree);
  static void create_global_var (void);
  static void collect_points_to_info_for (struct alias_info *, tree);
! static bool ptr_is_dereferenced_by (tree, tree);
  static void maybe_create_global_var (struct alias_info *ai);
  static void group_aliases (struct alias_info *);
  
--- 152,158 ----
  static void add_pointed_to_expr (tree, tree);
  static void create_global_var (void);
  static void collect_points_to_info_for (struct alias_info *, tree);
! static bool ptr_is_dereferenced_by (tree, tree, bool *);
  static void maybe_create_global_var (struct alias_info *ai);
  static void group_aliases (struct alias_info *);
  
*************** init_alias_info (void)
*** 367,372 ****
--- 376,384 ----
       created during alias analysis.  Since we can't create more than 2 tags
       per pointer, 3 times the number of referenced vars is enough.  */
    ai->num_references = xcalloc (3 * num_referenced_vars, sizeof (size_t));
+   ai->written_vars = BITMAP_XMALLOC ();
+   ai->dereferenced_ptrs_store = BITMAP_XMALLOC ();
+   ai->dereferenced_ptrs_load = BITMAP_XMALLOC ();
  
    return ai;
  }
*************** delete_alias_info (struct alias_info *ai
*** 398,403 ****
--- 410,419 ----
    free (ai->pointers);
  
    free (ai->num_references);
+   BITMAP_FREE (ai->written_vars);
+   BITMAP_FREE (ai->dereferenced_ptrs_store);
+   BITMAP_FREE (ai->dereferenced_ptrs_load);
+ 
    free (ai);
  }
  
*************** collect_points_to_info_for (struct alias
*** 434,447 ****
  }
  
  
! /* Return true if STMT contains INDIRECT_REF <PTR>.  */
  
  static bool
! ptr_is_dereferenced_by (tree ptr, tree stmt)
  {
    if (TREE_CODE (stmt) == MODIFY_EXPR
        || (TREE_CODE (stmt) == RETURN_EXPR
! 	&& TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR))
      {
        tree e, lhs, rhs;
  
--- 450,482 ----
  }
  
  
! /* Helper for ptr_is_dereferenced_by.  Called by walk_tree to look for
!    INDIRECT_REF nodes for the pointer passed in DATA.  */
! 
! static tree
! find_ptr_dereference (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
! {
!   tree ptr = (tree) data;
! 
!   if (TREE_CODE (*tp) == INDIRECT_REF
!       && TREE_OPERAND (*tp, 0) == ptr)
!     return *tp;
! 
!   return NULL_TREE;
! }
! 
! 
! /* Return true if STMT contains INDIRECT_REF <PTR>.  *IS_STORE is set
!    to 'true' if the dereference is on the LHS of an assignment.  */
  
  static bool
! ptr_is_dereferenced_by (tree ptr, tree stmt, bool *is_store)
  {
+   *is_store = false;
+ 
    if (TREE_CODE (stmt) == MODIFY_EXPR
        || (TREE_CODE (stmt) == RETURN_EXPR
! 	  && TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR))
      {
        tree e, lhs, rhs;
  
*************** ptr_is_dereferenced_by (tree ptr, tree s
*** 449,467 ****
        lhs = TREE_OPERAND (e, 0);
        rhs = TREE_OPERAND (e, 1);
  
!       if (TREE_CODE_CLASS (TREE_CODE (lhs)) == 'r')
  	{
! 	  lhs = get_base_address (lhs);
! 	  if (lhs && TREE_CODE (lhs) == INDIRECT_REF
! 	      && TREE_OPERAND (lhs, 0) == ptr)
! 	    return true;
  	}
!       if (TREE_CODE_CLASS (TREE_CODE (rhs)) == 'r')
  	{
! 	  rhs = get_base_address (rhs);
! 	  if (rhs && TREE_CODE (rhs) == INDIRECT_REF
! 	      && TREE_OPERAND (rhs, 0) == ptr)
! 	    return true;
  	}
      }
  
--- 484,512 ----
        lhs = TREE_OPERAND (e, 0);
        rhs = TREE_OPERAND (e, 1);
  
!       if (EXPR_P (lhs)
! 	  && walk_tree (&lhs, find_ptr_dereference, ptr, NULL))
  	{
! 	  *is_store = true;
! 	  return true;
  	}
!       else if (EXPR_P (rhs)
! 	       && walk_tree (&rhs, find_ptr_dereference, ptr, NULL))
  	{
! 	  return true;
! 	}
!     }
!   else if (TREE_CODE (stmt) == ASM_EXPR)
!     {
!       if (walk_tree (&ASM_OUTPUTS (stmt), find_ptr_dereference, ptr, NULL)
! 	  || walk_tree (&ASM_CLOBBERS (stmt), find_ptr_dereference, ptr, NULL))
! 	{
! 	  *is_store = true;
! 	  return true;
! 	}
!       else if (walk_tree (&ASM_INPUTS (stmt), find_ptr_dereference, ptr, NULL))
! 	{
! 	  return true;
  	}
      }
  
*************** compute_points_to_and_addr_escape (struc
*** 489,494 ****
--- 534,540 ----
  	{
  	  use_optype uses;
  	  def_optype defs;
+ 	  vdef_optype vdefs;
  	  stmt_ann_t ann;
  	  bitmap addr_taken;
  	  tree stmt = bsi_stmt (si);
*************** compute_points_to_and_addr_escape (struc
*** 534,539 ****
--- 580,586 ----
  	      tree op = USE_OP (uses, i);
  	      var_ann_t v_ann = var_ann (SSA_NAME_VAR (op));
  	      ssa_name_ann_t ptr_ann;
+ 	      bool is_store;
  
  	      if (may_be_aliased (SSA_NAME_VAR (op)))
  		ai->num_references[v_ann->uid]++;
*************** compute_points_to_and_addr_escape (struc
*** 544,550 ****
  	      collect_points_to_info_for (ai, op);
  
  	      ptr_ann = ssa_name_ann (op);
! 	      if (ptr_is_dereferenced_by (op, stmt))
  		{
  		  /* If we found OP to point to a set of variables or
  		     malloc, then create a name memory tag for it.  This
--- 591,597 ----
  	      collect_points_to_info_for (ai, op);
  
  	      ptr_ann = ssa_name_ann (op);
! 	      if (ptr_is_dereferenced_by (op, stmt, &is_store))
  		{
  		  /* If we found OP to point to a set of variables or
  		     malloc, then create a name memory tag for it.  This
*************** compute_points_to_and_addr_escape (struc
*** 560,565 ****
--- 607,620 ----
  		  /* Keep track of how many time we've dereferenced each
  		     pointer.  */
  		  ai->num_references[v_ann->uid]++;
+ 
+ 		  /* If this is a store operation, mark OP as being
+ 		     dereferenced to store, otherwise mark it as being
+ 		     dereferenced to load.  */
+ 		  if (is_store)
+ 		    bitmap_set_bit (ai->dereferenced_ptrs_store, v_ann->uid);
+ 		  else
+ 		    bitmap_set_bit (ai->dereferenced_ptrs_load, v_ann->uid);
  		}
  	      else if (stmt_escapes_p)
  		{
*************** compute_points_to_and_addr_escape (struc
*** 568,573 ****
--- 623,634 ----
  		     why we only check for escape points if OP is not
  		     dereferenced by STMT.  */
  		  ptr_ann->value_escapes_p = 1;
+ 
+ 		  /* If the statement makes a function call, assume
+ 		     that pointer OP will be dereferenced in a store
+ 		     operation inside the called function.  */
+ 		  if (get_call_expr_in (stmt))
+ 		    bitmap_set_bit (ai->dereferenced_ptrs_store, v_ann->uid);
  		}
  	    }
  
*************** compute_points_to_and_addr_escape (struc
*** 578,585 ****
  	  for (i = 0; i < NUM_DEFS (defs); i++)
  	    {
  	      tree op = DEF_OP (defs, i);
! 	      if (may_be_aliased (SSA_NAME_VAR (op)))
! 		ai->num_references[var_ann (SSA_NAME_VAR (op))->uid]++;
  	    }
  
  	  /* After promoting variables and computing aliasing we will
--- 639,659 ----
  	  for (i = 0; i < NUM_DEFS (defs); i++)
  	    {
  	      tree op = DEF_OP (defs, i);
! 	      tree var = SSA_NAME_VAR (op);
! 	      var_ann_t ann = var_ann (var);
! 	      bitmap_set_bit (ai->written_vars, ann->uid);
! 	      if (may_be_aliased (var))
! 		ai->num_references[ann->uid]++;
! 	    }
! 
! 	  /* Mark variables in VDEF operands as being written to.  */
! 	  vdefs = VDEF_OPS (ann);
! 	  for (i = 0; i < NUM_VDEFS (vdefs); i++)
! 	    {
! 	      tree op = VDEF_OP (vdefs, i);
! 	      tree var = SSA_NAME_VAR (op);
! 	      var_ann_t ann = var_ann (var);
! 	      bitmap_set_bit (ai->written_vars, ann->uid);
  	    }
  
  	  /* After promoting variables and computing aliasing we will
*************** compute_flow_insensitive_aliasing (struc
*** 706,722 ****
  	  struct alias_map_d *v_map;
  	  var_ann_t v_ann;
  	  tree var;
  	  
  	  v_map = ai->addressable_vars[j];
  	  var = v_map->var;
  	  v_ann = var_ann (var);
  
! 	  /* Skip memory tags and variables that have never been written to.  */
! 	  if (!tag_ann->is_stored && !v_ann->is_stored)
  	    continue;
  	     
  	  /* Skip memory tags which are written if the variable is readonly.  */
! 	  if (tag_ann->is_stored && TREE_READONLY (var))
  	    continue;
  
  	  if (may_alias_p (p_map->var, p_map->set, var, v_map->set))
--- 780,804 ----
  	  struct alias_map_d *v_map;
  	  var_ann_t v_ann;
  	  tree var;
+ 	  bool tag_stored_p, var_stored_p;
  	  
  	  v_map = ai->addressable_vars[j];
  	  var = v_map->var;
  	  v_ann = var_ann (var);
  
! 	  /* Skip memory tags and variables that have never been
! 	     written to.  We also need to check if the variables are
! 	     call-clobbered because they may be overwritten by
! 	     function calls.  */
! 	  tag_stored_p = bitmap_bit_p (ai->written_vars, tag_ann->uid)
! 			 || is_call_clobbered (tag);
! 	  var_stored_p = bitmap_bit_p (ai->written_vars, v_ann->uid)
! 			 || is_call_clobbered (var);
! 	  if (!tag_stored_p && !var_stored_p)
  	    continue;
  	     
  	  /* Skip memory tags which are written if the variable is readonly.  */
! 	  if (tag_stored_p && TREE_READONLY (var))
  	    continue;
  
  	  if (may_alias_p (p_map->var, p_map->set, var, v_map->set))
*************** setup_pointers_and_addressables (struct 
*** 1009,1015 ****
  	num_addressable_vars++;
  
        if (POINTER_TYPE_P (TREE_TYPE (var)))
! 	num_pointers++;
      }
  
    /* Create ADDRESSABLE_VARS and POINTERS.  Note that these arrays are
--- 1091,1106 ----
  	num_addressable_vars++;
  
        if (POINTER_TYPE_P (TREE_TYPE (var)))
! 	{
! 	  /* Since we don't keep track of volatile variables nor
! 	     variables with hidden uses, assume that these pointers
! 	     are used in indirect store operations.  */
! 	  var_ann_t ann = var_ann (var);
! 	  if (TREE_THIS_VOLATILE (var) || ann->has_hidden_use)
! 	    bitmap_set_bit (ai->dereferenced_ptrs_store, ann->uid);
! 
! 	  num_pointers++;
! 	}
      }
  
    /* Create ADDRESSABLE_VARS and POINTERS.  Note that these arrays are
*************** setup_pointers_and_addressables (struct 
*** 1081,1088 ****
        /* Add pointer variables that have been dereferenced to the POINTERS
           array and create a type memory tag for them.  */
        if (POINTER_TYPE_P (TREE_TYPE (var))
! 	  && (v_ann->is_dereferenced_store
! 	      || v_ann->is_dereferenced_load))
  	{
  	  tree tag = v_ann->type_mem_tag;
  	  var_ann_t t_ann;
--- 1172,1179 ----
        /* Add pointer variables that have been dereferenced to the POINTERS
           array and create a type memory tag for them.  */
        if (POINTER_TYPE_P (TREE_TYPE (var))
! 	  && (bitmap_bit_p (ai->dereferenced_ptrs_store, v_ann->uid)
! 	      || bitmap_bit_p (ai->dereferenced_ptrs_load, v_ann->uid)))
  	{
  	  tree tag = v_ann->type_mem_tag;
  	  var_ann_t t_ann;
*************** setup_pointers_and_addressables (struct 
*** 1097,1105 ****
  	  v_ann->type_mem_tag = tag;
  
  	  /* If pointer VAR has been used in a store operation, then its
! 	     memory tag must be marked as stored.  */
! 	  if (v_ann->is_dereferenced_store)
! 	    t_ann->is_stored = 1;
  
  	  /* If pointer VAR is a global variable or a PARM_DECL, then its
  	     memory tag should be considered a global variable.  */
--- 1188,1196 ----
  	  v_ann->type_mem_tag = tag;
  
  	  /* If pointer VAR has been used in a store operation, then its
! 	     memory tag must be marked as written-to.  */
! 	  if (bitmap_bit_p (ai->dereferenced_ptrs_store, v_ann->uid))
! 	    bitmap_set_bit (ai->written_vars, t_ann->uid);
  
  	  /* If pointer VAR is a global variable or a PARM_DECL, then its
  	     memory tag should be considered a global variable.  */
Index: tree-ssa-copy.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-copy.c,v
retrieving revision 1.1.2.3
diff -d -c -p -r1.1.2.3 tree-ssa-copy.c
*** tree-ssa-copy.c	25 Feb 2004 03:22:47 -0000	1.1.2.3
--- tree-ssa-copy.c	12 Mar 2004 04:05:01 -0000
*************** replace_ssa_names (tree *op_p,
*** 79,91 ****
        var_ann_t new_ann = var_ann (SSA_NAME_VAR (var));
        var_ann_t orig_ann = var_ann (SSA_NAME_VAR (*op_p));
  
-       /* Merge the dereferenced attributes for the replacement variable.
- 	 Note that we cannot just copy them.  Otherwise, we would mess
- 	 things up if the original variable wasn't dereferenced but the
- 	 replacement was.  */
-       new_ann->is_dereferenced_store |= orig_ann->is_dereferenced_store;
-       new_ann->is_dereferenced_load |= orig_ann->is_dereferenced_load;
- 
        if (new_ann->type_mem_tag == NULL_TREE)
  	new_ann->type_mem_tag = orig_ann->type_mem_tag;
        else if (orig_ann->type_mem_tag == NULL_TREE)
--- 79,84 ----
Index: tree-ssa-copyrename.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-copyrename.c,v
retrieving revision 1.1.2.2
diff -d -c -p -r1.1.2.2 tree-ssa-copyrename.c
*** tree-ssa-copyrename.c	3 Mar 2004 13:11:54 -0000	1.1.2.2
--- tree-ssa-copyrename.c	12 Mar 2004 04:05:01 -0000
*************** copy_rename_partition_coalesce (var_map 
*** 229,239 ****
  
    /* Update the various flag widgitry of the current base representative.  */
    ann3 = var_ann (SSA_NAME_VAR (partition_to_var (map, p3)));
-   ann3->is_stored = ann1->is_stored | ann2->is_stored;
-   ann3->is_dereferenced_store 
-     = (ann1->is_dereferenced_store | ann2->is_dereferenced_store);
-   ann3->is_dereferenced_load
-     = (ann1->is_dereferenced_load | ann2->is_dereferenced_load);
    if (ann1->type_mem_tag)
      ann3->type_mem_tag = ann1->type_mem_tag;
    else
--- 229,234 ----
Index: tree-ssa-loop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-loop.c,v
retrieving revision 1.1.2.10
diff -d -c -p -r1.1.2.10 tree-ssa-loop.c
*** tree-ssa-loop.c	25 Feb 2004 03:22:47 -0000	1.1.2.10
--- tree-ssa-loop.c	12 Mar 2004 04:05:01 -0000
*************** mark_defs_for_rewrite (basic_block bb)
*** 152,157 ****
--- 152,164 ----
      {
        var = SSA_NAME_VAR (PHI_RESULT (stmt));
        bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+ 
+       /* If we have a type_mem_tag, add it as well.  Due to rewriting the
+ 	 variable out of ssa, we lose its name tag, so we use type_mem_tag
+ 	 instead.  */
+       var = var_ann (var)->type_mem_tag;
+       if (var)
+ 	bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
      }
  
    for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
*************** mark_defs_for_rewrite (basic_block bb)
*** 165,170 ****
--- 172,184 ----
  	{
  	  var = SSA_NAME_VAR (DEF_OP (defs, i));
  	  bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+ 
+ 	  /* If we have a type_mem_tag, add it as well.  Due to rewriting the
+ 	     variable out of ssa, we lose its name tag, so we use type_mem_tag
+ 	     instead.  */
+ 	  var = var_ann (var)->type_mem_tag;
+ 	  if (var)
+ 	    bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
  	}
  
        vdefs = VDEF_OPS (ann);
Index: tree-ssa-operands.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-operands.c,v
retrieving revision 1.1.2.15
diff -d -c -p -r1.1.2.15 tree-ssa-operands.c
*** tree-ssa-operands.c	11 Mar 2004 05:07:18 -0000	1.1.2.15
--- tree-ssa-operands.c	12 Mar 2004 04:05:02 -0000
*************** add_stmt_operand (tree *var_p, tree stmt
*** 1199,1213 ****
  
        aliases = v_ann->may_aliases;
  
!       /* If alias information hasn't been computed yet, then addressable
! 	 variables will not be an alias tag nor will they have aliases.  In
! 	 this case, simply mark the statement as having volatile operands
! 	 and return.  */
        if (!aliases_computed_p && may_be_aliased (var))
! 	{
! 	  s_ann->has_volatile_ops = true;
! 	  return;
! 	}
  
        if (aliases == NULL)
  	{
--- 1199,1210 ----
  
        aliases = v_ann->may_aliases;
  
!       /* If alias information hasn't been computed yet, then
! 	 addressable variables will not be an alias tag nor will they
! 	 have aliases.  In this case, mark the statement as having
! 	 volatile operands.  */
        if (!aliases_computed_p && may_be_aliased (var))
! 	s_ann->has_volatile_ops = true;
  
        if (aliases == NULL)
  	{
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.210
diff -d -c -p -r1.1.4.210 tree-ssa.c
*** tree-ssa.c	12 Mar 2004 02:01:18 -0000	1.1.4.210
--- tree-ssa.c	12 Mar 2004 04:05:02 -0000
*************** mark_def_sites (struct dom_walk_data *wa
*** 622,630 ****
  	{
  	  VDEF_RESULT (vdefs, i) = VDEF_OP (vdefs, i);
  
- 	  set_def_block (VDEF_RESULT (vdefs, i), bb);
  	  if (!TEST_BIT (kills, uid))
  	    set_livein_block (VDEF_OP (vdefs, i), bb);
  	}
      }
  
--- 622,630 ----
  	{
  	  VDEF_RESULT (vdefs, i) = VDEF_OP (vdefs, i);
  
  	  if (!TEST_BIT (kills, uid))
  	    set_livein_block (VDEF_OP (vdefs, i), bb);
+ 	  set_def_block (VDEF_RESULT (vdefs, i), bb);
  	}
      }
  
*************** create_temp (tree t)
*** 973,983 ****
       of the flags in the annotation.  However, some flags we need to
       inherit from our original variable.  */
    var_ann (tmp)->type_mem_tag = var_ann (t)->type_mem_tag;
-   var_ann (tmp)->is_dereferenced_load = var_ann (t)->is_dereferenced_load;
-   var_ann (tmp)->is_dereferenced_store = var_ann (t)->is_dereferenced_store;
    if (is_call_clobbered (t))
      mark_call_clobbered (tmp);
-   var_ann (tmp)->is_stored = var_ann (t)->is_stored;
  
    return tmp;
  }
--- 973,980 ----



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