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]

Move value numbering routines and add VALUE_HANDLE code


This is mostly mechanical.  It adds a new VALUE_HANDLE tree code that is
generated and consumed internally by GVN-PRE.  This ought to reduce
memory consumption somewhat (not tested, though) because we won't use
VAR_DECLs as value handles anymore.

The patch also moves all the value numbering routines to tree-vn.c.  I
also have changes to make value numbering incorporate virtual operands,
but that is still unstable, so I'm flushing the stable bits out to avoid
lugging around a huge patch.

Finally, the patch uncovered a subtle bug in tree-optimize.c.  The calls
to init_tree_ssa() and delete_tree_ssa() were sometimes not paired. 
When not optimizing, we would call delete_tree_ssa() but not
init_tree_ssa().  Since we are now removing the value numbering hash
table in delete_tree_ssa(), we were ICEing at -O0.

Bootstrapped and tested x86 and x86-64 with no regressions.  Dan and
Steven, could you folks take a look and make sure I haven't broken
anything subtle?  There should be no behavioural change in PRE.

I will commit later today after I update my local tree and re-run tests.


Diego.


2004-06-23  Diego Novillo  <dnovillo@redhat.com>

	* Makefile.in (tree-vn.o): New.
	(tree-ssa-pre.o): Don't depend on RTL_H.
	* tree-dfa.c (find_referenced_vars): Don't call init_tree_ssa.
	* tree-flow.h (struct var_ann_d): Remove field expr_set.
	(add_to_value, expressions_equal_p, get_value_handle, vn_compute,
	vn_lookup_or_add, vn_add, vn_lookup, vn_init, vn_delete): Declare.
	* tree-optimize.c (execute_init_datastructures): New local function.
	(pass_init_datastructures): New local variable.
	(init_tree_optimization_passes): Sequence pass_init_datastructures.
	* tree-pretty-print.c (MASK_POINTER): Remove.
	(dump_generic_node): Handle VALUE_HANDLE.
	* tree-ssa-pre.c: Move all value numbering routines to tree-vn.c.
	Update callers to use new function names.
	Use VALUE_HANDLE_ID and VALUE_HANDLE_EXPR_SET instead of
	variable annotations.
	* tree-ssa.c (init_tree_ssa): Call vn_init.
	(delete_tree_ssa): Call vn_delete.
	* tree-vn.c: New file.
	* tree.c (tree_size): Handle VALUE_HANDLE.
	(tree_node_structure): Likewise.
	(iterative_hash_expr): Likewise.
	* tree.def (VALUE_HANDLE): New code.
	* tree.h (struct tree_value_handle): New.
	(VALUE_HANDLE_ID): Define.
	(VALUE_HANDLE_EXPR_SET): Define.
	(enum tree_node_structure_enum): Add TS_VALUE_HANDLE.
	(union tree_node): Add struct tree_value_handle.

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.1304
diff -d -c -p -d -u -p -r1.1304 Makefile.in
--- Makefile.in	22 Jun 2004 03:18:15 -0000	1.1304
+++ Makefile.in	23 Jun 2004 02:50:56 -0000
@@ -887,7 +887,7 @@ C_OBJS = c-parse.o c-lang.o stub-objc.o 
 OBJS-common = \
  tree-cfg.o tree-dfa.o tree-eh.o tree-ssa.o tree-optimize.o tree-gimple.o  \
  tree-alias-type.o gimplify.o tree-pretty-print.o tree-into-ssa.o          \
- tree-outof-ssa.o tree-alias-common.o tree-ssa-ccp.o			   \
+ tree-outof-ssa.o tree-alias-common.o tree-ssa-ccp.o tree-vn.o             \
  @ANDER@ tree-ssa-dce.o  tree-ssa-copy.o tree-nrv.o tree-ssa-copyrename.o  \
  tree-ssa-pre.o tree-ssa-live.o tree-ssa-operands.o tree-ssa-alias.o       \
  tree-ssa-phiopt.o tree-ssa-forwprop.o tree-nested.o tree-ssa-dse.o	   \
@@ -1640,9 +1640,12 @@ tree-ssa-copyrename.o : tree-ssa-copyren
    diagnostic.h errors.h toplev.h function.h $(TIMEVAR_H) tree-pass.h \
    tree-alias-common.h $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_SSA_LIVE_H)
 tree-ssa-pre.o : tree-ssa-pre.c $(TREE_FLOW_H) $(CONFIG_H) \
-   $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) \
+   $(SYSTEM_H) $(TREE_H) $(TM_P_H) $(EXPR_H) \
    $(GGC_H) output.h diagnostic.h errors.h toplev.h $(TIMEVAR_H) \
    $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H)
+tree-vn.o : tree-vn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \
+   $(TREE_H) $(TREE_FLOW_H) $(HASHTAB_H) langhooks.h tree-pass.h \
+   $(TREE_DUMP_H) diagnostic.h
 tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
    $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \
    diagnostic.h errors.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-dfa.c,v
retrieving revision 2.12
diff -d -c -p -d -u -p -r2.12 tree-dfa.c
--- tree-dfa.c	22 Jun 2004 03:06:40 -0000	2.12
+++ tree-dfa.c	23 Jun 2004 02:50:56 -0000
@@ -111,10 +111,6 @@ find_referenced_vars (void)
   struct walk_state walk_state;
   tree block;
 
-  /* This is the very first pass in preparation for building the SSA
-     form of the function, so initialize internal data structures now.  */
-  init_tree_ssa ();
-
   /* Walk the lexical blocks in the function looking for variables that may
      have been used to declare VLAs and for nested functions.  Both
      constructs create hidden uses of variables. 
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-flow.h,v
retrieving revision 2.12
diff -d -c -p -d -u -p -r2.12 tree-flow.h
--- tree-flow.h	19 Jun 2004 15:33:06 -0000	2.12
+++ tree-flow.h	23 Jun 2004 02:50:56 -0000
@@ -167,11 +167,6 @@ struct var_ann_d GTY(())
      live at the same time and this can happen for each call to the
      dominator optimizer.  */
   tree current_def;
-
-  /* The set of expressions represented by this variable if it is a
-     value handle.  This is used by GVN-PRE.  */
-  PTR GTY ((skip)) expr_set;
-  
 };
 
 
@@ -576,12 +571,23 @@ extern bool tree_can_throw_internal (tre
 extern bool tree_can_throw_external (tree);
 extern void add_stmt_to_eh_region (tree, int);
 
-/* In tree-ssa-pre.c */
-tree get_value_handle (tree);
-void set_value_handle (tree, tree);
+/* In tree-ssa-pre.c  */
+void add_to_value (tree, tree);
 void debug_value_expressions (tree);
 void print_value_expressions (FILE *, tree);
 
+
+/* In tree-vn.c  */
+bool expressions_equal_p (tree e1, tree e2);
+tree get_value_handle (tree);
+hashval_t vn_compute (tree, hashval_t);
+tree vn_lookup_or_add (tree);
+void vn_add (tree, tree);
+tree vn_lookup (tree);
+void vn_init (void);
+void vn_delete (void);
+
+
 /* In tree-sra.c  */
 void insert_edge_copies (tree stmt, basic_block bb);
 
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 2.20
diff -d -c -p -d -u -p -r2.20 tree-optimize.c
--- tree-optimize.c	19 Jun 2004 15:33:06 -0000	2.20
+++ tree-optimize.c	23 Jun 2004 02:50:56 -0000
@@ -153,6 +153,33 @@ static struct tree_opt_pass pass_free_da
   0					/* todo_flags_finish */
 };
 
+
+/* Do the actions required to initialize internal data structures used
+   in tree-ssa optimization passes.  */
+
+static void
+execute_init_datastructures (void)
+{
+  /* Allocate hash tables, arrays and other structures.  */
+  init_tree_ssa ();
+}
+
+static struct tree_opt_pass pass_init_datastructures =
+{
+  NULL,					/* name */
+  NULL,					/* gate */
+  execute_init_datastructures,		/* execute */
+  NULL,					/* sub */
+  NULL,					/* next */
+  0,					/* static_pass_number */
+  0,					/* tv_id */
+  PROP_cfg,				/* properties_required */
+  0,					/* properties_provided */
+  0,					/* properties_destroyed */
+  0,					/* todo_flags_start */
+  0					/* todo_flags_finish */
+};
+
 /* Iterate over the pass tree allocating dump file numbers.  We want
    to do this depth first, and independent of whether the pass is
    enabled or not.  */
@@ -253,6 +280,7 @@ init_tree_optimization_passes (void)
   NEXT_PASS (pass_lower_eh);
   NEXT_PASS (pass_build_cfg);
   NEXT_PASS (pass_tree_profile);
+  NEXT_PASS (pass_init_datastructures);
   NEXT_PASS (pass_all_optimizations);
   NEXT_PASS (pass_mudflap_2);
   NEXT_PASS (pass_free_datastructures);
Index: tree-pretty-print.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-pretty-print.c,v
retrieving revision 2.10
diff -d -c -p -d -u -p -r2.10 tree-pretty-print.c
--- tree-pretty-print.c	22 Jun 2004 03:06:41 -0000	2.10
+++ tree-pretty-print.c	23 Jun 2004 02:50:56 -0000
@@ -55,8 +55,6 @@ static void dump_generic_bb_buff (pretty
    lang_hooks.decl_printable_name (TREE_OPERAND (NODE, 0), 1) : \
    lang_hooks.decl_printable_name (NODE, 1))
 
-#define MASK_POINTER(P)	((unsigned)((unsigned long)(P) & 0xffff))
-
 static pretty_printer buffer;
 static int initialized = 0;
 static bool dumping_stmts;
@@ -1402,6 +1400,10 @@ dump_generic_node (pretty_printer *buffe
       pp_decimal_int (buffer, SSA_NAME_VERSION (node));
       break;
 
+    case VALUE_HANDLE:
+      pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
+      break;
+
     default:
       NIY;
     }
Index: tree-ssa-pre.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-pre.c,v
retrieving revision 2.16
diff -d -c -p -d -u -p -r2.16 tree-ssa-pre.c
--- tree-ssa-pre.c	21 Jun 2004 21:57:33 -0000	2.16
+++ tree-ssa-pre.c	23 Jun 2004 02:50:57 -0000
@@ -19,6 +19,7 @@ You should have received a copy of the G
 along with GCC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
+
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
@@ -26,11 +27,6 @@ Boston, MA 02111-1307, USA.  */
 #include "errors.h"
 #include "ggc.h"
 #include "tree.h"
-
-/* These RTL headers are needed for basic-block.h.  */
-#include "rtl.h"
-#include "tm_p.h"
-#include "hard-reg-set.h"
 #include "basic-block.h"
 #include "diagnostic.h"
 #include "tree-inline.h"
@@ -48,6 +44,7 @@ Boston, MA 02111-1307, USA.  */
 #include "splay-tree.h"
 #include "bitmap.h"
 #include "langhooks.h"
+
 /* TODO:
    
    1. Implement load value numbering.
@@ -279,10 +276,8 @@ static struct
 static tree find_leader (value_set_t, tree);
 static void value_insert_into_set (value_set_t, tree);
 static void insert_into_set (value_set_t, tree);
-static void add_to_value (tree, tree);
 static value_set_t set_new  (bool);
 static bool is_undefined_value (tree);
-static bool expressions_equal_p (tree, tree);
 static tree create_expression_by_pieces (basic_block, tree, tree);
 
 /* We can add and remove elements and entries to and from sets
@@ -293,117 +288,12 @@ static alloc_pool value_set_node_pool;
 static alloc_pool binary_node_pool;
 static alloc_pool unary_node_pool;
 
-/* The value table that maps expressions to values.  */
-
-static htab_t value_table;
 
 /* The phi_translate_table caches phi translations for a given
    expression and predecessor.  */
 
 static htab_t phi_translate_table;
 
-/* Compare two expressions E1 and E2 and return true if they are
-   equal.  */
-
-static bool
-expressions_equal_p (tree e1, tree e2)
-{
-  tree te1, te2;
-  
-  if (e1 == e2)
-    return true;
-  
-  te1 = TREE_TYPE (e1);
-  te2 = TREE_TYPE (e2);
-
-  if (TREE_CODE (e1) == TREE_CODE (e2) 
-      && (te1 == te2 || lang_hooks.types_compatible_p (te1, te2))
-      && operand_equal_p (e1, e2, 0))
-    return true;
-  return false;
-}
-
-/* Map expressions to values.  These are simple pairs of expressions
-   and the values they represent.  To find the value represented by
-   an expression, we use a hash table where the elements are {e,v}
-   pairs, and the expression is the key.  */
-
-typedef struct val_expr_pair_d
-{
-  tree v, e;
-  hashval_t hashcode;
-} *val_expr_pair_t;
-
-
-/* Hash a {v,e} pair that is pointed to by P.
-   The hashcode is cached in the val_expr_pair, so we just return
-   that.  */
-
-static hashval_t
-val_expr_pair_hash (const void *p)
-{
-  const val_expr_pair_t ve = (val_expr_pair_t) p;
-  return ve->hashcode;
-}
-
-
-/* Given two val_expr_pair_t's, return true if they represent the same
-   expression, false otherwise.
-   P1 and P2 should point to the val_expr_pair_t's to be compared.  */
-
-static int
-val_expr_pair_expr_eq (const void *p1, const void *p2)
-{
-  const val_expr_pair_t ve1 = (val_expr_pair_t) p1;
-  const val_expr_pair_t ve2 = (val_expr_pair_t) p2;
-
-  if (expressions_equal_p (ve1->e, ve2->e))
-    return true;
-  
-  return false;
-}
-
-
-/* Get the value handle of EXPR.  This is the only correct way to get
-   the value handle for a "thing". 
-   Returns NULL if the value handle does not exist.  */
-
-tree
-get_value_handle (tree expr)
-{
-  /* We should never see these.  */
-  if (DECL_P (expr))
-    abort ();
-  else if (TREE_CODE (expr) == SSA_NAME)
-    {
-      return SSA_NAME_VALUE (expr);
-    }
-  else if (TREE_CODE_CLASS (TREE_CODE (expr)) == 'c')
-    return expr;
-  else if (EXPR_P (expr))
-    {
-      tree_ann_t ann = tree_ann (expr);  
-      if (ann)
-	return ann->common.value_handle;
-      return NULL;
-    }
-  abort ();
-}
-
-
-/* Set the value handle for expression E to value V */
-   
-void
-set_value_handle (tree e, tree v)
-{
-  if (DECL_P (e))
-    abort ();
-  else if (TREE_CODE (e) == SSA_NAME)
-    SSA_NAME_VALUE (e) = v;
-  else if (EXPR_P (e))
-    get_tree_ann (e)->common.value_handle = v;
-}
-
 /* A three tuple {e, pred, v} used to cache phi translations in the
    phi_translate_table.  */
 
@@ -468,7 +358,7 @@ phi_trans_lookup (tree e, basic_block pr
   struct expr_pred_trans_d ept;
   ept.e = e;
   ept.pred = pred;
-  ept.hashcode = iterative_hash_expr (e, (unsigned long) pred);
+  ept.hashcode = vn_compute (e, (unsigned long) pred);
   slot = htab_find_slot_with_hash (phi_translate_table, &ept, ept.hashcode,
 				   NO_INSERT);
   if (!slot)
@@ -489,7 +379,7 @@ phi_trans_add (tree e, tree v, basic_blo
   new_pair->e = e;
   new_pair->pred = pred;
   new_pair->v = v;
-  new_pair->hashcode = iterative_hash_expr (e, (unsigned long) pred);
+  new_pair->hashcode = vn_compute (e, (unsigned long) pred);
   slot = htab_find_slot_with_hash (phi_translate_table, new_pair,
 				   new_pair->hashcode, INSERT);
   if (*slot)
@@ -497,31 +387,11 @@ phi_trans_add (tree e, tree v, basic_blo
   *slot = (void *) new_pair;
 }
 
-/* Search in TABLE for an existing instance of expression E,
-   and return its value, or NULL if none has been set.  */
-
-static inline tree
-lookup (htab_t table, tree e)
-{
-  void **slot;
-  struct val_expr_pair_d vep = {NULL, NULL, 0};
-  if (TREE_CODE_CLASS (TREE_CODE (e)) == 'c')
-    return e;
-  vep.e = e;
-  vep.hashcode = iterative_hash_expr (e,0); 
-  slot = htab_find_slot_with_hash (table, &vep, vep.hashcode, NO_INSERT);
-  if (!slot)
-    return NULL_TREE;
-  else
-    return ((val_expr_pair_t) *slot)->v;
-}
-
 /* Add expression E to the expression set of value V.  */
 
-static inline void
+void
 add_to_value (tree v, tree e)
 {
-  var_ann_t va;
   /* For values representing non-CST nodes, but still function
      invariant things we mark TREE_CONSTANT as true and set the tree
      chain to the actual constant.  This is because unlike values
@@ -536,106 +406,40 @@ add_to_value (tree v, tree e)
       TREE_CHAIN (v) = e;
       return;
     }
-  va = var_ann (v);
-  if (va->expr_set == NULL)
-    va->expr_set = set_new (false);
-  insert_into_set (va->expr_set, e);
-}
-
-/* Insert E into TABLE with value V, and add expression E to the value
-   set for value V.  */
-
-static inline void
-add (htab_t table, tree e, tree v)
-{
-
-  void **slot;
-  val_expr_pair_t new_pair = xmalloc (sizeof (struct val_expr_pair_d));
-  new_pair->e = e;
-  new_pair->v = v;
-  new_pair->hashcode = iterative_hash_expr (e, 0);
-  slot = htab_find_slot_with_hash (table, new_pair, new_pair->hashcode,
-				   INSERT);
-  if (*slot)
-    free (*slot);
-  *slot = (void *) new_pair;
-  set_value_handle (e, v);
-
-  add_to_value (v, e);
- 
-}
-
-/* A unique counter that is incremented every time we create a new
-   value.  */
-static int pre_uid;
 
-/* Create a new value handle for expression EXPR.  */
-
-static tree
-create_new_value (tree expr)
-{
-  tree a = create_tmp_var_raw (TREE_TYPE (expr), "value");
-  create_var_ann (a);
-  var_ann (a)->uid = pre_uid++;
+  if (VALUE_HANDLE_EXPR_SET (v) == NULL)
+    VALUE_HANDLE_EXPR_SET (v) = set_new (false);
 
-  if (dump_file && (dump_flags & TDF_DETAILS))
-    {     
-      fprintf (dump_file, "Created value ");
-      print_generic_expr (dump_file, a, dump_flags);
-      fprintf (dump_file, " for ");
-      print_generic_expr (dump_file, expr, dump_flags);
-      fprintf (dump_file, "\n");
-    }
-  return a;
+  insert_into_set (VALUE_HANDLE_EXPR_SET (v), e);
 }
 
-/* Like lookup, but creates a new value for expression E if E doesn't
-   already have a value.
-   Return the existing/created value for E.  */
 
-static inline tree
-lookup_or_add (htab_t table, tree e)
-{
-  tree x = lookup (table, e);
-  if (x == NULL_TREE)
-    {
-      tree v;
-      v = create_new_value (e);
-      add (table, e, v);
-      x = v;
-    }
-  set_value_handle (e, x);
-  return x;
-}
-
-  
 /* Return true if value V exists in the bitmap for SET.  */
 
 static inline bool
 value_exists_in_set_bitmap (value_set_t set, tree v)
 {
-  if (TREE_CODE (v) != VAR_DECL)
-    abort ();
-
   if (!set->values)
     return false;
-  return bitmap_bit_p (set->values, get_var_ann (v)->uid);
+
+  return bitmap_bit_p (set->values, VALUE_HANDLE_ID (v));
 }
 
+
 /* Remove value V from the bitmap for SET.  */
 
 static void
 value_remove_from_set_bitmap (value_set_t set, tree v)
 {
-  if (TREE_CODE (v) != VAR_DECL)
-    abort ();
 #ifdef ENABLE_CHECKING
   if (!set->indexed)
     abort ();
 #endif
+
   if (!set->values)
     return;
-  bitmap_clear_bit (set->values, get_var_ann (v)->uid);
+
+  bitmap_clear_bit (set->values, VALUE_HANDLE_ID (v));
 }
 
 
@@ -645,20 +449,21 @@ value_remove_from_set_bitmap (value_set_
 static inline void
 value_insert_into_set_bitmap (value_set_t set, tree v)
 {
-  if (TREE_CODE (v) != VAR_DECL)
-    abort ();  
 #ifdef ENABLE_CHECKING
   if (!set->indexed)
     abort ();
 #endif
+
   if (set->values == NULL)
     {
       set->values = BITMAP_GGC_ALLOC ();
       bitmap_clear (set->values);
     }
-  bitmap_set_bit (set->values, get_var_ann (v)->uid);
+
+  bitmap_set_bit (set->values, VALUE_HANDLE_ID (v));
 }
 
+
 /* Create a new set.  */
 
 static value_set_t
@@ -681,8 +486,6 @@ insert_into_set (value_set_t set, tree e
 {
   value_set_node_t newnode = pool_alloc (value_set_node_pool);
   tree val = get_value_handle (expr);
-  if (DECL_P (expr))
-    abort ();
   
   if (val == NULL)
     abort ();
@@ -873,7 +676,6 @@ value_insert_into_set (value_set_t set, 
 {
   tree val = get_value_handle (expr);
 
-
   /* Constant and invariant values exist everywhere, and thus,
      actually keeping them in the sets is pointless.  */
   if (TREE_CONSTANT (val))
@@ -913,13 +715,16 @@ print_value_set (FILE *outfile, value_se
 }
 
 /* Print out the expressions that have VAL to OUTFILE.  */
+
 void
 print_value_expressions (FILE *outfile, tree val)
 {
-  var_ann_t va = var_ann (val);
-  if (va && va->expr_set)
-    print_value_set (outfile, va->expr_set, 
-		     IDENTIFIER_POINTER (DECL_NAME (val)), 0);
+  if (VALUE_HANDLE_EXPR_SET (val))
+    {
+      char s[10];
+      sprintf (s, "VH.%04d", VALUE_HANDLE_ID (val));
+      print_value_set (outfile, VALUE_HANDLE_EXPR_SET (val), s, 0);
+    }
 }
 
 
@@ -983,7 +788,7 @@ phi_translate (tree expr, value_set_t se
 	    create_tree_ann (newexpr);
 	    TREE_OPERAND (newexpr, 0) = newop1 == oldop1 ? oldop1 : get_value_handle (newop1);
 	    TREE_OPERAND (newexpr, 1) = newop2 == oldop2 ? oldop2 : get_value_handle (newop2);
-	    lookup_or_add (value_table, newexpr);
+	    vn_lookup_or_add (newexpr);
 	    expr = newexpr;
 	    phi_trans_add (oldexpr, newexpr, pred);	    
 	  }
@@ -1010,7 +815,7 @@ phi_translate (tree expr, value_set_t se
 	    memcpy (newexpr, expr, tree_size (expr));
 	    create_tree_ann (newexpr);	 
 	    TREE_OPERAND (newexpr, 0) = get_value_handle (newop1);
-	    lookup_or_add (value_table, newexpr);
+	    vn_lookup_or_add (newexpr);
 	    expr = newexpr;
 	    phi_trans_add (oldexpr, newexpr, pred);
 	  }
@@ -1035,7 +840,7 @@ phi_translate (tree expr, value_set_t se
 	      tree val;
 	      if (is_undefined_value (PHI_ARG_DEF (phi, i)))
 		return NULL;
-	      val = lookup_or_add (value_table, PHI_ARG_DEF (phi, i));
+	      val = vn_lookup_or_add (PHI_ARG_DEF (phi, i));
 	      return PHI_ARG_DEF (phi, i);
 	    }
       }
@@ -1328,15 +1133,6 @@ compute_antic (void)
     fprintf (dump_file, "compute_antic required %d iterations\n", num_iterations);
 }
 
-/* Get the expressions represented by value VAL.  */
-
-static value_set_t
-get_expr_set (tree val)
-{
-  var_ann_t va = var_ann (val);
-  return va->expr_set;
-}
-
 
 /* Find a leader for an expression, or generate one using
    create_expression_by_pieces if it's ANTIC but
@@ -1364,7 +1160,7 @@ find_or_generate_expression (basic_block
      not really .  */
   if (genop == NULL)
     {
-      genop = get_expr_set (expr)->head->expr;
+      genop = VALUE_HANDLE_EXPR_SET (expr)->head->expr;
       if (TREE_CODE_CLASS (TREE_CODE (genop)) != '1'
 	  && TREE_CODE_CLASS (TREE_CODE (genop)) != '2')
 	abort ();
@@ -1445,7 +1241,7 @@ create_expression_by_pieces (basic_block
       
     }
   v = get_value_handle (expr);
-  add (value_table, name, v);
+  vn_add (name, v);
   insert_into_set (NEW_SETS (block), name);
   value_insert_into_set (AVAIL_OUT (block), name);
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -1610,7 +1406,7 @@ insert_aux (basic_block block)
 			  temp = create_tmp_var (type, "prephitmp");
 			  add_referenced_tmp_var (temp);
 			  temp = create_phi_node (temp, block);
-			  add (value_table, PHI_RESULT (temp), val);
+			  vn_add (PHI_RESULT (temp), val);
 
 #if 0
 			  if (!set_contains_value (AVAIL_OUT (block), val))
@@ -1679,17 +1475,19 @@ insert (void)
     fprintf (dump_file, "insert required %d iterations\n", num_iterations);
 }
 
+
 /* Return true if EXPR has no defining statement in this procedure,
    *AND* isn't a live-on-entry parameter.  */
+
 static bool
 is_undefined_value (tree expr)
 {  
-  
 #ifdef ENABLE_CHECKING
   /* We should never be handed DECL's  */
   if (DECL_P (expr))
     abort ();
 #endif
+
   if (TREE_CODE (expr) == SSA_NAME)
     {
       /* XXX: Is this the correct test?  */
@@ -1698,6 +1496,7 @@ is_undefined_value (tree expr)
       if (IS_EMPTY_STMT (SSA_NAME_DEF_STMT (expr)))
 	return true;
     }
+
   return false;
 }
 
@@ -1731,7 +1530,7 @@ compute_avail (basic_block block)
 	    {
 	      tree val;
 	      tree def = default_def (param);
-	      val = lookup_or_add (value_table, def);
+	      val = vn_lookup_or_add (def);
 	      insert_into_set (TMP_GEN (block), def);
 	      value_insert_into_set (AVAIL_OUT (block), def);
 	    }
@@ -1746,6 +1545,7 @@ compute_avail (basic_block block)
       dom = get_immediate_dominator (CDI_DOMINATORS, block);
       if (dom)
 	set_copy (AVAIL_OUT (block), AVAIL_OUT (dom));
+
       for (phi = phi_nodes (block); phi; phi = PHI_CHAIN (phi))
 	{
 	  /* Ignore virtual PHIs until we can do PRE on expressions
@@ -1753,7 +1553,7 @@ compute_avail (basic_block block)
 	  if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
 	    continue;
 
-	  lookup_or_add (value_table, PHI_RESULT (phi));
+	  vn_lookup_or_add (PHI_RESULT (phi));
 	  value_insert_into_set (AVAIL_OUT (block), PHI_RESULT (phi));
 	  insert_into_set (PHI_GEN (block), PHI_RESULT (phi));
 	}
@@ -1773,7 +1573,7 @@ compute_avail (basic_block block)
 	      for (j = 0; j < NUM_DEFS (STMT_DEF_OPS (stmt)); j++)
 		{
 		  tree def = DEF_OP (STMT_DEF_OPS (stmt), j);
-		  lookup_or_add (value_table, def);
+		  vn_lookup_or_add (def);
 		  insert_into_set (TMP_GEN (block), def);
 		  value_insert_into_set (AVAIL_OUT (block), def);
 		}
@@ -1782,7 +1582,7 @@ compute_avail (basic_block block)
 		  tree use = USE_OP (STMT_USE_OPS (stmt), j);
 		  if (TREE_CODE (use) == SSA_NAME)
 		    {
-		      lookup_or_add (value_table, use);
+		      vn_lookup_or_add (use);
 		      insert_into_set (TMP_GEN (block), use);
 		      value_insert_into_set (AVAIL_OUT (block), use);
 		    }
@@ -1801,7 +1601,7 @@ compute_avail (basic_block block)
 	      STRIP_USELESS_TYPE_CONVERSION (op1);
 	      if (is_gimple_min_invariant (op1))
 		{
-		  add (value_table, op0, lookup_or_add (value_table, op1));
+		  vn_add (op0, vn_lookup_or_add (op1));
 		  insert_into_set (TMP_GEN (block), op0);
 		  value_insert_into_set (AVAIL_OUT (block), op0);
 		}
@@ -1812,15 +1612,15 @@ compute_avail (basic_block block)
 		  tree newt;
 		  bop1 = TREE_OPERAND (op1, 0);
 		  bop2 = TREE_OPERAND (op1, 1);
-		  val1 = lookup_or_add (value_table, bop1);
-		  val2 = lookup_or_add (value_table, bop2);
+		  val1 = vn_lookup_or_add (bop1);
+		  val2 = vn_lookup_or_add (bop2);
  
 		  newt = pool_alloc (binary_node_pool);
 		  memcpy (newt, op1, tree_size (op1));
 		  TREE_OPERAND (newt, 0) = val1;
 		  TREE_OPERAND (newt, 1) = val2;
-		  val = lookup_or_add (value_table, newt);
-		  add (value_table, op0, val);
+		  val = vn_lookup_or_add (newt);
+		  vn_add (op0, val);
 		  if (!is_undefined_value (bop1))
 		    value_insert_into_set (EXP_GEN (block), bop1);
 		  if (!is_undefined_value (bop2))
@@ -1836,12 +1636,12 @@ compute_avail (basic_block block)
 		  tree val, val1;
 		  tree newt;
 		  uop = TREE_OPERAND (op1, 0);
-		  val1 = lookup_or_add (value_table, uop);
+		  val1 = vn_lookup_or_add (uop);
 		  newt = pool_alloc (unary_node_pool);
 		  memcpy (newt, op1, tree_size (op1));
 		  TREE_OPERAND (newt, 0) = val1;
-		  val = lookup_or_add (value_table, newt);
-		  add (value_table, op0, val);
+		  val = vn_lookup_or_add (newt);
+		  vn_add (op0, val);
 		  if (!is_undefined_value (uop))
 		    value_insert_into_set (EXP_GEN (block), uop);
 		  value_insert_into_set (EXP_GEN (block), newt);
@@ -1850,8 +1650,8 @@ compute_avail (basic_block block)
 		}
 	      else if (TREE_CODE (op1) == SSA_NAME)
 		{
-		  tree val = lookup_or_add (value_table, op1);
-		  add (value_table, op0, val);
+		  tree val = vn_lookup_or_add (op1);
+		  vn_add (op0, val);
 		  if (!is_undefined_value (op1))
 		    value_insert_into_set (EXP_GEN (block), op1);
 		  insert_into_set (TMP_GEN (block), op0);
@@ -1863,7 +1663,7 @@ compute_avail (basic_block block)
 		  for (j = 0; j < NUM_DEFS (STMT_DEF_OPS (stmt)); j++)
 		    {
 		      tree def = DEF_OP (STMT_DEF_OPS (stmt), j);
-		      lookup_or_add (value_table, def);
+		      vn_lookup_or_add (def);
 		      insert_into_set (TMP_GEN (block), def);
 		      value_insert_into_set (AVAIL_OUT (block), def);
 		      if (def != op0)
@@ -1874,7 +1674,7 @@ compute_avail (basic_block block)
 		      tree use = USE_OP (STMT_USE_OPS (stmt), j);
 		      if (TREE_CODE (use) == SSA_NAME)
 			{
-			  lookup_or_add (value_table, use);
+			  vn_lookup_or_add (use);
 			  insert_into_set (TMP_GEN (block), use);
 			  value_insert_into_set (AVAIL_OUT (block), use);
 			}
@@ -1887,7 +1687,7 @@ compute_avail (basic_block block)
 	      for (j = 0; j < NUM_DEFS (STMT_DEF_OPS (stmt)); j++)
 		{
 		  tree def = DEF_OP (STMT_DEF_OPS (stmt), j);
-		  lookup_or_add (value_table, def);
+		  vn_lookup_or_add (def);
 		  insert_into_set (TMP_GEN (block), def);
 		  value_insert_into_set (AVAIL_OUT (block), def);
 		}
@@ -1896,7 +1696,7 @@ compute_avail (basic_block block)
 		  tree use = USE_OP (STMT_USE_OPS (stmt), j);
 		  if (TREE_CODE (use) == SSA_NAME)
 		    {
-		      lookup_or_add (value_table, use);
+		      vn_lookup_or_add (use);
 		      insert_into_set (TMP_GEN (block), use);
 		      value_insert_into_set (AVAIL_OUT (block), use);
 		    }
@@ -1904,13 +1704,14 @@ compute_avail (basic_block block)
 	    }
 	}
     }
+
   for (son = first_dom_son (CDI_DOMINATORS, block);
        son;
        son = next_dom_son (CDI_DOMINATORS, son))
     compute_avail (son);
-
 }
 
+
 /* Eliminate fully redundant computations.  */
 
 static void
@@ -1931,6 +1732,7 @@ eliminate (void)
 	      || NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt))
 	      || stmt_ann (stmt)->has_volatile_ops)
             continue;
+
           /* Lookup the RHS of the expression, see if we have an
 	     available computation for it. If so, replace the RHS with
 	     the available computation.  */
@@ -1945,8 +1747,8 @@ eliminate (void)
 		  || (TREE_CODE_CLASS (TREE_CODE (expr)) != '2' 
 		   && TREE_CODE_CLASS (TREE_CODE (expr)) != '1'))
 		continue;
-	      sprime = find_leader (AVAIL_OUT (b),
-				    lookup (value_table, t));
+
+	      sprime = find_leader (AVAIL_OUT (b), vn_lookup (t));
               if (sprime 
 		  && sprime != t 
 		  && may_propagate_copy (sprime, TREE_OPERAND (stmt, 1)))
@@ -1965,11 +1767,11 @@ eliminate (void)
                   modify_stmt (stmt);
                 }
             }
-
         }
     }
 }
 
+
 /* Main entry point to the SSA-PRE pass.
 
    PHASE indicates which dump file from the DUMP_FILES array to use when
@@ -1980,7 +1782,6 @@ execute_pre (void)
 {
   size_t tsize;
   basic_block bb;
-  pre_uid = num_referenced_vars;
   memset (&pre_stats, 0, sizeof (pre_stats));
   FOR_ALL_BB (bb)
     {
@@ -1989,8 +1790,6 @@ execute_pre (void)
   phi_translate_table = htab_create (511, expr_pred_trans_hash,
 				     expr_pred_trans_eq,
 				     free);
-  value_table = htab_create (511, val_expr_pair_hash,
-			     val_expr_pair_expr_eq, free);
   value_set_pool = create_alloc_pool ("Value sets",
 				      sizeof (struct value_set), 30);
   value_set_node_pool = create_alloc_pool ("Value set nodes",
@@ -2048,7 +1847,6 @@ execute_pre (void)
   free_alloc_pool (value_set_node_pool);
   free_alloc_pool (binary_node_pool);
   free_alloc_pool (unary_node_pool);
-  htab_delete (value_table);
   htab_delete (phi_translate_table);
   
   FOR_ALL_BB (bb)
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa.c,v
retrieving revision 2.14
diff -d -c -p -d -u -p -r2.14 tree-ssa.c
--- tree-ssa.c	22 Jun 2004 06:08:37 -0000	2.14
+++ tree-ssa.c	23 Jun 2004 02:50:57 -0000
@@ -497,6 +497,7 @@ init_tree_ssa (void)
   init_ssa_operands ();
   init_ssanames ();
   init_phinodes ();
+  vn_init ();
   global_var = NULL_TREE;
   aliases_computed_p = false;
 }
@@ -527,6 +528,7 @@ delete_tree_ssa (void)
   fini_ssanames ();
   fini_phinodes ();
   fini_ssa_operands ();
+  vn_delete ();
 
   global_var = NULL_TREE;
   BITMAP_XFREE (call_clobbered_vars);
Index: tree-vn.c
===================================================================
RCS file: tree-vn.c
diff -N tree-vn.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tree-vn.c	23 Jun 2004 02:50:57 -0000
@@ -0,0 +1,257 @@
+/* Value Numbering routines for tree expressions.
+   Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Contributed by Daniel Berlin <dan@dberlin.org>, Steven Bosscher
+   <stevenb@suse.de> and Diego Novillo <dnovillo@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "ggc.h"
+#include "tree.h"
+#include "tree-flow.h"
+#include "hashtab.h"
+#include "langhooks.h"
+#include "tree-pass.h"
+#include "tree-dump.h"
+#include "diagnostic.h"
+
+/* The value table that maps expressions to values.  */
+static htab_t value_table;
+
+/* Map expressions to values.  These are simple pairs of expressions
+   and the values they represent.  To find the value represented by
+   an expression, we use a hash table where the elements are {e,v}
+   pairs, and the expression is the key.  */
+typedef struct val_expr_pair_d
+{
+  tree v, e;
+  hashval_t hashcode;
+} *val_expr_pair_t;
+
+static void set_value_handle (tree e, tree v);
+
+
+/* Create and return a new value handle node of type TYPE.  */
+
+static tree
+make_value_handle (tree type)
+{
+  static unsigned int id = 0;
+  tree vh;
+
+  vh = build0 (VALUE_HANDLE, type);
+  VALUE_HANDLE_ID (vh) = id++;
+  return vh;
+}
+
+
+/* Given an expression or statement P, compute a hash value number using the
+   code of the expression and its real operands.  */
+
+hashval_t
+vn_compute (tree expr, hashval_t val)
+{
+  val = iterative_hash_expr (expr, val);
+  return val;
+}
+
+
+/* Compare two expressions E1 and E2 and return true if they are
+   equal.  */
+
+bool
+expressions_equal_p (tree e1, tree e2)
+{
+  tree te1, te2;
+  
+  if (e1 == e2)
+    return true;
+
+  te1 = TREE_TYPE (e1);
+  te2 = TREE_TYPE (e2);
+
+  if (TREE_CODE (e1) == TREE_CODE (e2) 
+      && (te1 == te2 || lang_hooks.types_compatible_p (te1, te2))
+      && operand_equal_p (e1, e2, 0))
+    return true;
+
+  return false;
+}
+
+
+/* Hash a {v,e} pair that is pointed to by P.
+   The hashcode is cached in the val_expr_pair, so we just return
+   that.  */
+
+static hashval_t
+val_expr_pair_hash (const void *p)
+{
+  const val_expr_pair_t ve = (val_expr_pair_t) p;
+  return ve->hashcode;
+}
+
+
+/* Given two val_expr_pair_t's, return true if they represent the same
+   expression, false otherwise.
+   P1 and P2 should point to the val_expr_pair_t's to be compared.  */
+
+static int
+val_expr_pair_expr_eq (const void *p1, const void *p2)
+{
+  const val_expr_pair_t ve1 = (val_expr_pair_t) p1;
+  const val_expr_pair_t ve2 = (val_expr_pair_t) p2;
+
+  if (expressions_equal_p (ve1->e, ve2->e))
+    return true;
+  
+  return false;
+}
+
+
+/* Set the value handle for expression E to value V */
+   
+static void
+set_value_handle (tree e, tree v)
+{
+  if (TREE_CODE (e) == SSA_NAME)
+    SSA_NAME_VALUE (e) = v;
+  else if (EXPR_P (e) || DECL_P (e))
+    get_tree_ann (e)->common.value_handle = v;
+  else if (TREE_CODE_CLASS (TREE_CODE (e)) == 'c')
+    /* Do nothing.  Constants are their own value handles.  */
+    ;
+  else
+    abort ();
+}
+
+
+/* Insert E into VALUE_TABLE with value V, and add expression E to the
+   value set for value V.  */
+
+void
+vn_add (tree e, tree v)
+{
+  void **slot;
+  val_expr_pair_t new_pair = xmalloc (sizeof (struct val_expr_pair_d));
+  new_pair->e = e;
+  new_pair->v = v;
+  new_pair->hashcode = vn_compute (e, 0);
+  slot = htab_find_slot_with_hash (value_table, new_pair, new_pair->hashcode,
+				   INSERT);
+  if (*slot)
+    free (*slot);
+  *slot = (void *) new_pair;
+  set_value_handle (e, v);
+
+  add_to_value (v, e);
+}
+
+
+/* Search in VALUE_TABLE for an existing instance of expression E, and
+   return its value, or NULL if none has been set.  */
+
+tree
+vn_lookup (tree e)
+{
+  void **slot;
+  struct val_expr_pair_d vep = {NULL, NULL, 0};
+
+  if (TREE_CODE_CLASS (TREE_CODE (e)) == 'c')
+    return e;
+  vep.e = e;
+  vep.hashcode = vn_compute (e, 0); 
+  slot = htab_find_slot_with_hash (value_table, &vep, vep.hashcode, NO_INSERT);
+  if (!slot)
+    return NULL_TREE;
+  else
+    return ((val_expr_pair_t) *slot)->v;
+}
+
+
+/* Like vn_lookup, but creates a new value for expression E if E doesn't
+   already have a value.  Return the existing/created value for E.  */
+
+tree
+vn_lookup_or_add (tree e)
+{
+  tree x = vn_lookup (e);
+  if (x == NULL_TREE)
+    {
+      tree v = make_value_handle (TREE_TYPE (e));
+
+      if (dump_file && (dump_flags & TDF_DETAILS))
+	{     
+	  fprintf (dump_file, "Created value ");
+	  print_generic_expr (dump_file, v, dump_flags);
+	  fprintf (dump_file, " for ");
+	  print_generic_expr (dump_file, e, dump_flags);
+	  fprintf (dump_file, "\n");
+	}
+
+      vn_add (e, v);
+      x = v;
+    }
+
+  set_value_handle (e, x);
+
+  return x;
+}
+
+
+/* Get the value handle of EXPR.  This is the only correct way to get
+   the value handle for a "thing".  If EXPR does not have a value
+   handle associated, it generates and returns a new one.  */
+
+tree
+get_value_handle (tree expr)
+{
+  if (TREE_CODE (expr) == SSA_NAME)
+    return SSA_NAME_VALUE (expr);
+  else if (TREE_CODE_CLASS (TREE_CODE (expr)) == 'c')
+    return expr;
+  else if (EXPR_P (expr) || DECL_P (expr))
+    {
+      tree_ann_t ann = tree_ann (expr);
+      return ((ann) ? ann->common.value_handle : NULL_TREE);
+    }
+
+  abort ();
+}
+
+
+/* Initialize data structures used in value numbering.  */
+
+void
+vn_init (void)
+{
+  value_table = htab_create (511, val_expr_pair_hash,
+			     val_expr_pair_expr_eq, free);
+}
+
+
+/* Delete data used for value numbering.  */
+
+void
+vn_delete (void)
+{
+  htab_delete (value_table);
+  value_table = NULL;
+}
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.378
diff -d -c -p -d -u -p -r1.378 tree.c
--- tree.c	22 Jun 2004 03:06:42 -0000	1.378
+++ tree.c	23 Jun 2004 02:50:58 -0000
@@ -196,6 +196,7 @@ tree_size (tree node)
 
 	case STATEMENT_LIST:	return sizeof (struct tree_statement_list);
 	case BLOCK:		return sizeof (struct tree_block);
+	case VALUE_HANDLE:	return sizeof (struct tree_value_handle);
 
 	default:
 	  return lang_hooks.tree_size (code);
@@ -1497,6 +1498,7 @@ tree_node_structure (tree t)
     case PLACEHOLDER_EXPR:	return TS_COMMON;
     case STATEMENT_LIST:	return TS_STATEMENT_LIST;
     case BLOCK:			return TS_BLOCK;
+    case VALUE_HANDLE:		return TS_VALUE_HANDLE;
 
     default:
       abort ();
@@ -3851,7 +3853,8 @@ iterative_hash_expr (tree t, hashval_t v
   code = TREE_CODE (t);
   class = TREE_CODE_CLASS (code);
 
-  if (class == 'd')
+  if (class == 'd'
+      || TREE_CODE (t) == VALUE_HANDLE)
     {
       /* Decls we can just compare by pointer.  */
       val = iterative_hash_object (t, val);
Index: tree.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.def,v
retrieving revision 1.81
diff -d -c -p -d -u -p -r1.81 tree.def
--- tree.def	22 Jun 2004 03:06:43 -0000	1.81
+++ tree.def	23 Jun 2004 02:50:58 -0000
@@ -894,6 +894,12 @@ DEFTREECODE (EH_FILTER_EXPR, "eh_filter_
    Use the interface in tree-iterator.h to access this node.  */
 DEFTREECODE (STATEMENT_LIST, "statement_list", 'x', 0)
 
+/* Value handles.  Artificial nodes to represent expressions in
+   partial redundancy elimination (tree-ssa-pre.c).  These nodes are
+   used for expression canonicalization.  If two expressions compute
+   the same value, they will be assigned the same value handle.  */
+DEFTREECODE (VALUE_HANDLE, "value_handle", 'x', 0)
+
 /*
 Local variables:
 mode:c
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.525
diff -d -c -p -d -u -p -r1.525 tree.h
--- tree.h	22 Jun 2004 03:06:43 -0000	1.525
+++ tree.h	23 Jun 2004 02:50:59 -0000
@@ -2229,6 +2229,28 @@ struct tree_statement_list
   struct tree_statement_list_node *head;
   struct tree_statement_list_node *tail;
 };
+
+#define VALUE_HANDLE_ID(NODE)		\
+  (VALUE_HANDLE_CHECK (NODE)->value_handle.id)
+
+#define VALUE_HANDLE_EXPR_SET(NODE)	\
+  (VALUE_HANDLE_CHECK (NODE)->value_handle.expr_set)
+
+/* Defined and used in tree-ssa-pre.c.  */
+struct value_set;
+
+struct tree_value_handle GTY(())
+{
+  struct tree_common common;
+
+  /* The set of expressions represented by this handle.  */
+  struct value_set * GTY ((skip)) expr_set;
+
+  /* Unique ID for this value handle.  IDs are handed out in a
+     conveniently dense form starting at 0, so that we can make
+     bitmaps of value handles. */
+  unsigned int id;
+};
 
 enum tree_node_structure_enum {
   TS_COMMON,
@@ -2247,6 +2269,7 @@ enum tree_node_structure_enum {
   TS_PHI_NODE,
   TS_BLOCK,
   TS_STATEMENT_LIST,
+  TS_VALUE_HANDLE,
   LAST_TS_ENUM
 };
 
@@ -2273,6 +2296,7 @@ union tree_node GTY ((ptr_alias (union l
   struct tree_phi_node GTY ((tag ("TS_PHI_NODE"))) phi;
   struct tree_block GTY ((tag ("TS_BLOCK"))) block;
   struct tree_statement_list GTY ((tag ("TS_STATEMENT_LIST"))) stmt_list;
+  struct tree_value_handle GTY ((tag ("TS_VALUE_HANDLE"))) value_handle;
 };
 
 /* Standard named or nameless data types of the C compiler.  */



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