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] Mark aliases that may reference global memory [patch]


- Allows transitivity of may-alias information.  If V1 may-alias
  V2 and V2 may-alias V3 then references to V3 may be references
  to V1 even though they do not alias directly.

- Detects aliasing to global variables.  When a variable may
  alias global storage, it is considered a global variable by
  DCE.

- Adds a hideous hack to prevent removing blocks with nonlocal
  labels.  I have another patch to fix this for real, but I
  didn't want to commit a non-bootstrapping patch. 

- Adds a new dump flag option (-alias) to show information about
  the alias computation pass.  This is independent from the
  points-to dump flag, which is only enabled when alias
  information is computed using points-to analysis.


With this patch we pass all the c-torture tests with CCP and DCE
enabled.  The only remaining failures are those tests that
declare VLAs.  For that, we need GIMPLE to expose the declaration
of variable length arrays.


Diego.

	* tree-cfg.c (make_goto_expr_edges): Temporary hack to prevent
	removing blocks with nonlocal labels.
	(is_nonlocal_label_block): Return true if DECL_NONLOCAL is set for
	the label.

	* tree-dfa.c (alias_leaders): New local array.
	(num_alias_leaders): New local variable.
	(find_alias_leader): New local function.
	(may_access_global_mem): New local function.
	(find_may_aliases_for): Call them.
	(compute_may_aliases): Allocate and deallocate alias_leaders.
	Show alias information if -fdump-tree-...-alias flag is given.
	(may_alias_p): Return true if both variables are the same.

	(find_refs_in_expr): Strip WFL and NOPs from the parent statement.
	If a pointer relocation is due to a function call, assignment from
	a global or a function argument, mark the pointer as a may-alias
	for global storage.
	(dump_referenced_vars): Reformat output.
	(dump_variable): Likewise.

	* tree-dump.c (dump_option_value_info): Add entry for TDF_ALIAS.
	* tree.h (TDF_ALIAS): Define.

	* tree-flow-inline.h (may_alias_global_mem_p): New function.
	* tree-flow.h (enum tree_flags): Add value TF_MAY_ALIAS_GLOBAL_MEM.
	(may_alias_global_mem_p): Declare.

	* tree-simple.c (get_base_symbol): Return NULL_TREE, not NULL.
	* tree-ssa-ccp.c (tree_ssa_ccp): Remove unused variable.
	* tree-ssa-dce.c (need_to_preserve_store): Call
	decl_function_context instead of DECL_CONTEXT.
	If the symbol may alias global memory, return nonzero.

	* tree-ssa.c (dump_reaching_defs): Reformat output.
	(set_currdef_for): Walk the alias leader chain, setting CURRDEF for
	all the alias sets that may be affected by the definition.

Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.36
diff -d -u -p -r1.1.4.36 tree-cfg.c
--- tree-cfg.c	3 Dec 2002 22:54:32 -0000	1.1.4.36
+++ tree-cfg.c	6 Dec 2002 19:48:00 -0000
@@ -674,13 +674,22 @@ make_goto_expr_edges (bb)
 	  && LABEL_EXPR_LABEL (target) == dest)
 	{
 	  make_edge (bb, target_bb, 0);
+
+	  /* FIXME.  This is stupid and unnecessary.  We should find
+	     out which labels can be the target of a nonlocal goto and make
+	     the abnormal edge from the blocks that call nested functions
+	     or setjmp.   */
+	  if (is_nonlocal_label_block (target_bb))
+	    make_edge (BASIC_BLOCK (0), target_bb, EDGE_ABNORMAL);
 	  break;
 	}
 
-      /* Computed GOTOs.  Make an edge to every label block.  */
+      /* Computed GOTOs.  Make an edge to every label block.  FIXME  it
+	 should be possible to trim down the number of labels we make the
+	 edges to.  See cfgbuild.c.  */
       else if (TREE_CODE (dest) != LABEL_DECL
 	       && TREE_CODE (target) == LABEL_EXPR)
-	make_edge (bb, target_bb, 0);
+	make_edge (bb, target_bb, EDGE_ABNORMAL);
     }
 }
 
@@ -858,8 +867,9 @@ is_nonlocal_label_block (bb)
     return false;
 
   /* FIXME  We don't compute nonlocal labels until RTL expansion.  This
-	    returns false positives.  */
-  return (TREE_CODE (t) == LABEL_EXPR && DECL_NAME (LABEL_EXPR_LABEL (t)));
+     will always return true.  This will likely break programs with nested
+     functions and nonlocal gotos.  */
+  return (TREE_CODE (t) == LABEL_EXPR && DECL_NONLOCAL (LABEL_EXPR_LABEL (t)));
 }
 
 
@@ -1619,7 +1629,7 @@ is_ctrl_stmt (t)
 }
 
 
-/* Return true if T alters the flow of control (i.e., T is GOTO,
+/* Return true if T alters the flow of control (e.g., T is GOTO,
    RETURN or a call to a non-returning function)  */
 
 bool
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.57
diff -d -u -p -r1.1.4.57 tree-dfa.c
--- tree-dfa.c	6 Dec 2002 05:25:07 -0000	1.1.4.57
+++ tree-dfa.c	6 Dec 2002 19:48:00 -0000
@@ -73,6 +73,8 @@ struct dfa_stats_d
   unsigned long num_ekills;
 };
 
+static tree *alias_leaders;
+static unsigned long num_alias_leaders;
 
 /* Data and functions shared with tree-ssa.c.  */
 struct dfa_counts_d dfa_counts;
@@ -96,6 +98,8 @@ static void count_ref_list_nodes	PARAMS 
 static tree clobber_vars_r		PARAMS ((tree *, int *, void *));
 static void compute_may_aliases		PARAMS ((void));
 static void find_may_aliases_for	PARAMS ((tree));
+static tree find_alias_leader		PARAMS ((tree));
+static bool may_access_global_mem 	PARAMS ((tree));
 static size_t tree_ref_size		PARAMS ((enum tree_ref_type));
 static tree replace_ref_r		PARAMS ((tree *, int *, void *));
 static void remove_def			PARAMS ((tree_ref));
@@ -264,6 +268,9 @@ find_refs_in_expr (expr_p, ref_type, ref
   if (parent_stmt && TREE_NOT_GIMPLE (parent_stmt))
     return;
 
+  STRIP_WFL (parent_stmt);
+  STRIP_NOPS (parent_stmt);
+
   /* If we found a _DECL node, create a reference to it and return.  */
   if (code == VAR_DECL || code == PARM_DECL)
     {
@@ -280,6 +287,13 @@ find_refs_in_expr (expr_p, ref_type, ref
 
 	  create_ref (indirect_var (expr), V_DEF, TRM_RELOCATE, bb,
 		      parent_stmt_p, 1);
+
+	  /* If the relocation of 'p' is due to a function call, an
+	     assignment from a global or an assignment from an argument,
+	     then mark '*p' as an alias for global memory.  */
+	  if (TREE_CODE (parent_stmt) == MODIFY_EXPR
+	      && may_access_global_mem (TREE_OPERAND (parent_stmt, 1)))
+	    set_tree_flag (indirect_var (expr), TF_MAY_ALIAS_GLOBAL_MEM);
 	}
 
       return;
@@ -1576,6 +1590,7 @@ dump_referenced_vars (file, details)
   for (i = 0; i < num_referenced_vars; i++)
     {
       tree var = referenced_var (i);
+      fprintf (file, "Variable: ");
       dump_variable (file, var);
       dump_ref_list (file, "", tree_refs (var), 2, details);
       fprintf (file, "\n");
@@ -1601,17 +1616,18 @@ dump_variable (file, var)
      FILE *file;
      tree var;
 {
-  fprintf (file, "Variable: ");
   print_generic_expr (file, var, 0);
   
   if (alias_leader (var))
     {
       fprintf (file, ", alias leader: ");
       print_generic_expr (file, alias_leader (var), 0);
-      fprintf (file, "\n");
     }
-  else
-    fprintf (file, "\n");
+
+  if (may_alias_global_mem_p (var))
+    fprintf (file, ", may alias global memory");
+
+  fprintf (file, "\n");
 }
 
 
@@ -2006,6 +2022,12 @@ compute_may_aliases ()
       create_alias_vars ();
       timevar_pop (TV_TREE_PTA);
     }
+
+  num_alias_leaders = 0;
+  alias_leaders = (tree *) xmalloc (num_referenced_vars * sizeof (tree));
+  if (alias_leaders == NULL)
+    abort ();
+  memset ((void *) alias_leaders, 0, num_referenced_vars * sizeof (tree));
   
   for (i = 0; i < num_referenced_vars; i++)
     {
@@ -2017,6 +2039,34 @@ compute_may_aliases ()
     }
 
   timevar_pop (TV_TREE_MAY_ALIAS);
+
+  /* Debugging dumps.  */
+  if (tree_ssa_dump_file && tree_ssa_dump_flags & TDF_ALIAS)
+    {
+      unsigned long i, j;
+
+      fprintf (tree_ssa_dump_file, "\nAlias information for %s: %ld sets\n\n",
+	       get_name (current_function_decl), num_alias_leaders);
+
+      for (i = 0; i < num_alias_leaders; i++)
+	{
+	  fprintf (tree_ssa_dump_file, "Alias set #%ld:\n", i);
+	  fprintf (tree_ssa_dump_file, "  Leader: ");
+	  dump_variable (tree_ssa_dump_file, alias_leaders[i]);
+	  fprintf (tree_ssa_dump_file, "  Aliases: { ");
+	  for (j = 0; j < num_referenced_vars; j++)
+	    if (alias_leader (referenced_var (j)) == alias_leaders[i])
+	      {
+		print_generic_expr (tree_ssa_dump_file, referenced_var (j), 0);
+		fprintf (tree_ssa_dump_file, " ");
+	      }
+	  fprintf (tree_ssa_dump_file, "}\n\n");
+	}
+    }
+
+  free (alias_leaders);
+  alias_leaders = NULL;
+  num_alias_leaders = 0;
 }
 
 
@@ -2030,16 +2080,17 @@ may_alias_p (v1, v2)
   tree ptr, var, ptr_sym, var_sym;
   HOST_WIDE_INT ptr_alias_set, var_alias_set;
 
+  if (v1 == v2)
+    return true;
+
   /* One of the two variables needs to be an INDIRECT_REF or GLOBAL_VAR,
      otherwise they can't possibly alias each other.  */
-  if (TREE_CODE (v1) == INDIRECT_REF
-      || v1 == global_var)
+  if (TREE_CODE (v1) == INDIRECT_REF || v1 == global_var)
     {
       ptr = v1;
       var = v2;
     }
-  else if (TREE_CODE (v2) == INDIRECT_REF
-           || v2 == global_var)
+  else if (TREE_CODE (v2) == INDIRECT_REF || v2 == global_var)
     {
       ptr = v2;
       var = v1;
@@ -2078,85 +2129,134 @@ may_alias_p (v1, v2)
 	}
     }
 
-  /* Obvious reasons why PTR_SYM and VAR_SYM can't possibly alias
-     each other.  */
-  if (var_sym == ptr_sym
-      || DECL_ARTIFICIAL (var_sym)
-      /* Only check for addressability on non-pointers.  Even if VAR is 
-	 a non-addressable pointer, it may still alias with ptr.  */
-      || (DECL_P (var) && !TREE_ADDRESSABLE (var)))
+  /* VAR_DECLs that have not had their address taken cannot be aliased.  */
+  if (DECL_P (var) && !TREE_ADDRESSABLE (var))
     return false;
 
+  /* Compute type-based alias information.  If the alias sets don't
+     conflict then PTR cannot alias VAR.  */
   ptr_alias_set = get_alias_set (ptr);
   var_alias_set = get_alias_set (var);
   if (!alias_sets_conflict_p (ptr_alias_set, var_alias_set))
     return false;
 
+  /* If -ftree-points-to is given, check if PTR may point to VAR.  */
   if (flag_tree_points_to)
     if (!ptr_may_alias_var (ptr_sym, var_sym))
       return false;
 
-
   return true;
 }
 
 
-/* Find variables that INDIRECT_PTR (an INDIRECT_REF node) may be aliasing.  */
+/* Find variables that V1 may be aliasing.  For every variable V2 that V1
+   may alias, add V2 to one of the alias sets in the array ALIAS_LEADERS.
+
+   Each entry I in ALIAS_LEADERS represents a set of all the variables that
+   are aliased by ALIAS_LEADERS[I].  In the absence of points-to
+   information, the ALIAS_LEADERS array will tend to have few entries, and
+   each entry will likely alias many program variables.
+   
+   This will negatively impact optimizations because variable uses will be
+   reached by many definitions that can't really reach them.  See the
+   documentation in tree-ssa.c.  */
 
 static void
-find_may_aliases_for (indirect_ptr)
-     tree indirect_ptr;
+find_may_aliases_for (v1)
+     tree v1;
 {
   unsigned long i;
 
-#if defined ENABLE_CHECKING
-  if (TREE_CODE (indirect_ptr) != INDIRECT_REF)
-    abort ();
-#endif
-
-  if (alias_leader (indirect_ptr) == NULL)
-    set_alias_leader (indirect_ptr, indirect_ptr);
+  if (may_access_global_mem (v1))
+    set_tree_flag (v1, TF_MAY_ALIAS_GLOBAL_MEM);
 
   for (i = 0; i < num_referenced_vars; i++)
     {
-      tree var = referenced_var (i);
+      tree v2 = referenced_var (i);
 
-      /* If INDIRECT_PTR may alias VAR, make INDIRECT_PTR the alias leader
-	 for VAR.  */
-      if (may_alias_p (indirect_ptr, var))
-	{
-	  /* Note that the alias leader of INDIRECT_PTR may not be
-	     INDIRECT_PTR if INDIRECT_PTR is in the alias set of some other
-	     pointer.  If the current alias leader for INDIRECT_PTR is not
-	     an alias for VAR, then INDIRECT_PTR must become its own alias
-	     leader.  This is to avoid the following problem:
+      if (v1 == v2)
+	continue;
 
-	     Assume that the following aliasing relations hold for
-	     variables V1, V2 and V3:
+      if (may_alias_p (v1, v2))
+	{
+	  tree al = find_alias_leader (v2);
+	  if (al == NULL_TREE)
+	    al = alias_leaders [num_alias_leaders++] = v1;
 
-	     	V1 may-alias V2
-		V2 may-alias V3
-		V1 may-not-alias V3
+	  set_alias_leader (v2, al);
 
-	     When processing V1 and V2 for the first time, this pass made
-	     V1 the alias leader for V2.  In the next iteration, it
-	     determines that V2 may alias V3 and so it sets V3's alias
-	     leader to be V1 (which is V2's alias leader).
-	     
-	     However, V1 and V3 do not alias each other, so making V1 the
-	     alias leader for V3 makes no sense.  In this case, we make V2
-	     the alias leader for itself and V3.  */
-	  if (alias_leader (indirect_ptr) != indirect_ptr
-	      && alias_leader (indirect_ptr) != var
-	      && !may_alias_p (alias_leader (indirect_ptr), var))
+	  /* If V2 may access global memory, mark both AL and V1 as aliases
+	     for global memory.  */
+	  if (may_access_global_mem (v2))
 	    {
-	      set_alias_leader (alias_leader (indirect_ptr), indirect_ptr);
-	      set_alias_leader (indirect_ptr, indirect_ptr);
+	      set_tree_flag (al, TF_MAY_ALIAS_GLOBAL_MEM);
+	      set_tree_flag (v1, TF_MAY_ALIAS_GLOBAL_MEM);
 	    }
-
-	  set_alias_leader (var, alias_leader (indirect_ptr));
 	}
     }
+}
+
+
+/* Traverse the ALIAS_LEADERS array looking for an alias leader that may
+   alias var.  If an alias leader AL is found, make AL be the alias leader
+   for VAR.  Otherwise return NULL_TREE so that the caller may create a new
+   entry in the ALIAS_LEADER array.  */
+
+static tree
+find_alias_leader (var)
+     tree var;
+{
+  unsigned long i;
+
+  for (i = 0; i < num_alias_leaders; i++)
+    if (may_alias_p (alias_leaders[i], var))
+      return alias_leaders[i];
+
+  return NULL_TREE;
+}
+
+
+/* Return true if EXPR may be a pointer to global memory.  */
+
+static bool
+may_access_global_mem (expr)
+     tree expr;
+{
+  char class;
+  tree sym;
+
+  if (expr == NULL_TREE)
+    return false;
+
+  /* Function arguments and global variables may reference global memory.  */
+  if ((sym = get_base_symbol (expr)) != NULL_TREE)
+    {
+      if (TREE_CODE (sym) == PARM_DECL
+	  || decl_function_context (sym) == NULL_TREE)
+	return true;
+    }
+
+  /* Otherwise, the expression must be of pointer type.  */
+  if (TREE_TYPE (expr) == NULL_TREE
+      || !POINTER_TYPE_P (TREE_TYPE (expr)))
+    return false;
+
+  /* Call expressions that return pointers may point to global memory.  */
+  if (TREE_CODE (expr) == CALL_EXPR)
+    return true;
+
+  /* Recursively check the expression's operands.  */
+  class = TREE_CODE_CLASS (TREE_CODE (expr));
+  if (IS_EXPR_CODE_CLASS (class) || class == 'r')
+    {
+      unsigned char i;
+
+      for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (expr)); i++)
+	if (may_access_global_mem (TREE_OPERAND (expr, i)))
+	  return true;
+    }
+
+  return false;
 }
 
 
Index: tree-dump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-dump.c,v
retrieving revision 1.6.2.16
diff -d -u -p -r1.6.2.16 tree-dump.c
--- tree-dump.c	3 Dec 2002 22:54:33 -0000	1.6.2.16
+++ tree-dump.c	6 Dec 2002 19:48:01 -0000
@@ -693,6 +693,7 @@ static const struct dump_option_value_in
   {"details", TDF_DETAILS},
   {"stats", TDF_STATS},
   {"block", TDF_BLOCK},
+  {"alias", TDF_ALIAS},
   {"all", ~0},
   {NULL, 0}
 };
Index: tree-flow-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow-inline.h,v
retrieving revision 1.1.2.16
diff -d -u -p -r1.1.2.16 tree-flow-inline.h
--- tree-flow-inline.h	2 Dec 2002 20:42:50 -0000	1.1.2.16
+++ tree-flow-inline.h	6 Dec 2002 19:48:01 -0000
@@ -208,7 +208,8 @@ static inline tree
 alias_leader (var)
      tree var;
 {
-  return tree_annotation (var) ? tree_annotation (var)->alias_leader : NULL;
+  return tree_annotation (var) ? tree_annotation (var)->alias_leader
+                               : NULL_TREE;
 }
 
 static inline void
@@ -225,7 +226,14 @@ static inline bool
 is_aliased (var)
      tree var;
 {
-  return alias_leader (var) != NULL;
+  return alias_leader (var) != NULL_TREE;
+}
+
+static inline bool
+may_alias_global_mem_p (var)
+     tree var;
+{
+  return (tree_flags (var) & TF_MAY_ALIAS_GLOBAL_MEM) != 0;
 }
 
 static inline int
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.39
diff -d -u -p -r1.1.4.39 tree-flow.h
--- tree-flow.h	2 Dec 2002 20:42:50 -0000	1.1.4.39
+++ tree-flow.h	6 Dec 2002 19:48:01 -0000
@@ -489,13 +489,16 @@ typedef struct tree_ann_d *tree_ann;
 enum tree_flags
 {
   /* Expression tree should be folded.  */
-  TF_FOLDED		= 1 << 0,
+  TF_FOLDED			= 1 << 0,
 
   /* This _DECL node has already been referenced in this function.  */
-  TF_REFERENCED		= 1 << 1,
+  TF_REFERENCED			= 1 << 1,
 
   /* This expression is necessary (not dead code).  */
-  TF_NECESSARY		= 1 << 2
+  TF_NECESSARY			= 1 << 2,
+
+  /* This variable may alias global memory.  */
+  TF_MAY_ALIAS_GLOBAL_MEM	= 1 << 3
 };
 
 static inline tree_ann tree_annotation	PARAMS ((tree));
@@ -514,6 +517,7 @@ static inline tree create_indirect_ref	P
 static inline tree alias_leader		PARAMS ((tree));
 static inline void set_alias_leader	PARAMS ((tree, tree));
 static inline bool is_aliased		PARAMS ((tree));
+static inline bool may_alias_global_mem_p PARAMS ((tree));
 static inline int get_lineno		PARAMS ((tree));
 static inline const char *get_filename	PARAMS ((tree));
 static inline bool is_exec_stmt		PARAMS ((tree));
Index: tree-simple.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-simple.c,v
retrieving revision 1.1.4.21
diff -d -u -p -r1.1.4.21 tree-simple.c
--- tree-simple.c	3 Dec 2002 22:54:34 -0000	1.1.4.21
+++ tree-simple.c	6 Dec 2002 19:48:01 -0000
@@ -956,7 +956,7 @@ get_base_symbol (t)
       return get_base_symbol (TREE_OPERAND (t, 0));
 
     default:
-      return NULL;
+      return NULL_TREE;
     }
 }
 
Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-ccp.c,v
retrieving revision 1.1.2.37
diff -d -u -p -r1.1.2.37 tree-ssa-ccp.c
--- tree-ssa-ccp.c	3 Dec 2002 22:54:34 -0000	1.1.2.37
+++ tree-ssa-ccp.c	6 Dec 2002 19:48:01 -0000
@@ -130,8 +130,6 @@ void
 tree_ssa_ccp (fndecl)
      tree fndecl;
 {
-  tree fnbody = DECL_SAVED_TREE (fndecl);
-
   timevar_push (TV_TREE_CCP);
 
   initialize ();
Index: tree-ssa-dce.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dce.c,v
retrieving revision 1.1.2.17
diff -d -u -p -r1.1.2.17 tree-ssa-dce.c
--- tree-ssa-dce.c	3 Dec 2002 22:54:34 -0000	1.1.2.17
+++ tree-ssa-dce.c	6 Dec 2002 19:48:01 -0000
@@ -186,19 +186,24 @@ need_to_preserve_store (sym)
     return 0;
 
   base_symbol = get_base_symbol (sym);
+
   /* File scope variables must be preserved.  */
-  if (DECL_CONTEXT (base_symbol) == NULL)
+  if (decl_function_context (base_symbol) == NULL)
     return 1;
   
   /* Stores through parameter pointers must be perserved.  */
-  if (TREE_CODE (sym) == INDIRECT_REF)
-      if (TREE_CODE (base_symbol) == PARM_DECL)
-	return 1;
+  if (TREE_CODE (sym) == INDIRECT_REF
+      && TREE_CODE (base_symbol) == PARM_DECL)
+    return 1;
 
   /* Static locals must be preserved as well.  */
   if (TREE_STATIC (base_symbol))
     return 1;
 
+  /* If SYM may alias global memory, we also need to preserve the store.  */
+  if (may_alias_global_mem_p (sym))
+    return 1;
+
   return 0;
 }
 
@@ -279,12 +284,15 @@ find_useful_stmts ()
 			if (is_aliased (symbol))
 			  {
 			    for (x = 0; x < num_referenced_vars; x++)
-			      if (alias_leader (referenced_var (x)) == alias_leader (symbol)
-				  && need_to_preserve_store (referenced_var (x)))
-				{
-				  need = 1;
-				  break;
-				}
+			      {
+				tree var = referenced_var (x);
+				if (alias_leader (var) == alias_leader (symbol)
+				    && need_to_preserve_store (var))
+				  {
+				    need = 1;
+				    break;
+				  }
+			      }
 			  }
 
 		      if (need)
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.38
diff -d -u -p -r1.1.4.38 tree-ssa.c
--- tree-ssa.c	4 Dec 2002 00:16:04 -0000	1.1.4.38
+++ tree-ssa.c	6 Dec 2002 19:48:01 -0000
@@ -581,6 +581,7 @@ dump_reaching_defs (file)
       tree var = referenced_var (i);
       ref_list_iterator j;
 
+      fprintf (file, "Variable: ");
       dump_variable (file, var);
 
       for (j = rli_start (tree_refs (var)); !rli_after_end (j); rli_step (&j))
@@ -902,7 +903,7 @@ static inline tree_ref
 currdef_for (v)
      tree v;
 {
-  if (alias_leader (v))
+  if (is_aliased (v))
     v = alias_leader (v);
 
   return tree_annotation (v) ? tree_annotation (v)->currdef : NULL;
@@ -919,6 +920,7 @@ set_currdef_for (v, def)
      tree_ref def;
 {
   tree_ann ann;
+
 #if defined ENABLE_CHECKING
   if (TREE_CODE_CLASS (TREE_CODE (v)) != 'd'
       && TREE_CODE (v) != INDIRECT_REF)
@@ -928,9 +930,23 @@ set_currdef_for (v, def)
     abort ();
 #endif
 
-  if (alias_leader (v))
-    v = alias_leader (v);
-
   ann = tree_annotation (v) ? tree_annotation (v) : create_tree_ann (v);
   ann->currdef = def;
+
+  /* If V is aliased then CURRDEF also represents a definition for V's
+     alias leader.  Similarly, if V's alias leader has an alias leader of
+     its own, then CURRDEF represents a definition for it.  Therefore, we
+     walk the alias leader chain, which is guaranteed to be a cycle-free
+     graph (see tree-dfa.c:compute_may_aliases).  */
+  if (is_aliased (v))
+    {
+      v = alias_leader (v);
+      do
+	{
+	  ann = tree_annotation (v) ? tree_annotation (v) : create_tree_ann (v);
+	  ann->currdef = def;
+	  v = alias_leader (v);
+	}
+      while (v && v != alias_leader (v));
+    }
 }
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.30
diff -d -u -p -r1.342.2.30 tree.h
--- tree.h	3 Dec 2002 22:54:35 -0000	1.342.2.30
+++ tree.h	6 Dec 2002 19:48:01 -0000
@@ -3269,6 +3269,7 @@ enum tree_dump_index
 #define TDF_STATS	(1 << 4)	/* dump various statistics about
 					   each pass */
 #define TDF_BLOCK	(1 << 5)	/* display basic block boundaries */
+#define TDF_ALIAS	(1 << 6)	/* display aliasing information */
 
 
 typedef struct dump_info *dump_info_p;


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