[PATCH][alias-improvements] Simplify SCCVN implementation

Richard Guenther rguenther@suse.de
Mon Dec 8 15:47:00 GMT 2008


This simplifies SCCVN implementation now that we only have a single
VUSE/VDEF per statement.  Next step is to "fix" the oracle use of it.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to the
branch.

Richard.

2008-12-08  Richard Guenther  <rguenther@suse.de>

	* gimple.h (gimple_vuse): New function.
	(gimple_vdef): Likewise.
	* tree-ssa-sccvn.c (SSA_VAL): Check for NULL.
	(vn_constant_eq): Bail out if hashes are different.
	(vn_reference_compute_hash): Simplify.
	(vn_reference_eq): Likewise.
	(vuses_to_vec, copy_vuses_from_stmt, vdefs_to_vec,
	copy_vdefs_from_stmt, shared_lookup_vops, shared_vuses_from_stmt,
	valueize_vuses): Remove.
	(get_def_ref_stmt_vuses): Simplify.  Rename to ...
	(get_def_ref_stmt_vuse): ... this.
	(vn_reference_lookup_pieces): Simplify.
	(vn_reference_lookup): Likewise.
	(vn_reference_insert): Likewise.
	(vn_reference_insert_pieces): Likewise.
	(vn_nary_op_eq): Bail out if hashes are different.
	(vn_phi_eq): Likewise.
	(set_ssa_val_to): Do not use SSA_VAL as lvalue.
	(visit_reference_op_call): Simplify.
	(visit_reference_op_load): Likewise.
	(visit_reference_op_store): Likewise.
	(init_scc_vn): Remove shared_lookup_vuses initialization.
	(free_scc_vn): Remove shared_lookup_vuses freeing.
	(run_scc_vn): Do not use SSA_VAL as lvalue.
	(sort_vuses, sort_vuses_heap): Remove.
	* tree-ssa-sccvn.h (struct vn_reference_s): Replace vuses
	vector with single vuse pointer.
	(vn_reference_lookup_pieces, vn_reference_lookup,
	vn_reference_insert, vn_reference_insert_pieces): Adjust prototypes.
	(shared_vuses_from_stmt): Remove.
	* tree-dfa.c (get_single_def_stmt): Simplify.
	(get_single_def_stmt_with_phi): Likewise.
	* tree-ssa-pre.c (translate_vuses_through_block): Simplify.  Rename to
	(translate_vuse_through_block): ... this.
	(phi_translate_1): Simplify.
	(value_dies_in_block_x): Likewise.
	(compute_avail): Simplify.

Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c	(revision 142546)
--- gcc/tree-ssa-sccvn.c	(working copy)
*************** static vn_tables_t current_info;
*** 140,146 ****
  
  static int *rpo_numbers;
  
! #define SSA_VAL(x) (VN_INFO ((x))->valnum)
  
  /* This represents the top of the VN lattice, which is the universal
     value.  */
--- 140,146 ----
  
  static int *rpo_numbers;
  
! #define SSA_VAL(x) (x ? VN_INFO ((x))->valnum : NULL_TREE)
  
  /* This represents the top of the VN lattice, which is the universal
     value.  */
*************** vn_constant_eq (const void *p1, const vo
*** 316,321 ****
--- 316,325 ----
    const struct vn_constant_s *vc1 = (const struct vn_constant_s *) p1;
    const struct vn_constant_s *vc2 = (const struct vn_constant_s *) p2;
  
+   /* Early out if this is not a hash collision.  */
+   if (vc1->hashcode != vc2->hashcode)
+     return false;
+ 
    return vn_constant_eq_with_type (vc1->constant, vc2->constant);
  }
  
*************** vn_reference_hash (const void *p1)
*** 417,429 ****
  hashval_t
  vn_reference_compute_hash (const vn_reference_t vr1)
  {
!   hashval_t result = 0;
!   tree v;
    int i;
    vn_reference_op_t vro;
  
!   for (i = 0; VEC_iterate (tree, vr1->vuses, i, v); i++)
!     result += iterative_hash_expr (v, 0);
    for (i = 0; VEC_iterate (vn_reference_op_s, vr1->operands, i, vro); i++)
      result += vn_reference_op_compute_hash (vro);
  
--- 421,431 ----
  hashval_t
  vn_reference_compute_hash (const vn_reference_t vr1)
  {
!   hashval_t result;
    int i;
    vn_reference_op_t vro;
  
!   result = iterative_hash_expr (vr1->vuse, 0);
    for (i = 0; VEC_iterate (vn_reference_op_s, vr1->operands, i, vro); i++)
      result += vn_reference_op_compute_hash (vro);
  
*************** vn_reference_compute_hash (const vn_refe
*** 436,457 ****
  int
  vn_reference_eq (const void *p1, const void *p2)
  {
-   tree v;
    int i;
    vn_reference_op_t vro;
  
    const_vn_reference_t const vr1 = (const_vn_reference_t) p1;
    const_vn_reference_t const vr2 = (const_vn_reference_t) p2;
  
!   if (vr1->vuses == vr2->vuses
!       && vr1->operands == vr2->operands)
!     return true;
  
!   /* Impossible for them to be equivalent if they have different
!      number of vuses.  */
!   if (VEC_length (tree, vr1->vuses) != VEC_length (tree, vr2->vuses))
      return false;
  
    /* We require that address operands be canonicalized in a way that
       two memory references will have the same operands if they are
       equivalent.  */
--- 438,461 ----
  int
  vn_reference_eq (const void *p1, const void *p2)
  {
    int i;
    vn_reference_op_t vro;
  
    const_vn_reference_t const vr1 = (const_vn_reference_t) p1;
    const_vn_reference_t const vr2 = (const_vn_reference_t) p2;
  
!   /* Early out if this is not a hash collision.  */
!   if (vr1->hashcode != vr2->hashcode)
!     return false;
  
!   /* The VOP needs to be the same.  */
!   if (vr1->vuse != vr2->vuse)
      return false;
  
+   /* If the operands are the same we are done.  */
+   if (vr1->operands == vr2->operands)
+     return true;
+ 
    /* We require that address operands be canonicalized in a way that
       two memory references will have the same operands if they are
       equivalent.  */
*************** vn_reference_eq (const void *p1, const v
*** 459,557 ****
        != VEC_length (vn_reference_op_s, vr2->operands))
      return false;
  
-   /* The memory state is more often different than the address of the
-      store/load, so check it first.  */
-   for (i = 0; VEC_iterate (tree, vr1->vuses, i, v); i++)
-     {
-       if (VEC_index (tree, vr2->vuses, i) != v)
- 	return false;
-     }
- 
    for (i = 0; VEC_iterate (vn_reference_op_s, vr1->operands, i, vro); i++)
!     {
!       if (!vn_reference_op_eq (VEC_index (vn_reference_op_s, vr2->operands, i),
! 			       vro))
! 	return false;
!     }
!   return true;
! }
! 
! /* Place the vuses from STMT into *result.  */
! 
! static inline void
! vuses_to_vec (gimple stmt, VEC (tree, gc) **result)
! {
!   ssa_op_iter iter;
!   tree vuse;
! 
!   if (!stmt)
!     return;
! 
!   VEC_reserve_exact (tree, gc, *result,
! 		     num_ssa_operands (stmt, SSA_OP_VIRTUAL_USES));
! 
!   FOR_EACH_SSA_TREE_OPERAND (vuse, stmt, iter, SSA_OP_VIRTUAL_USES)
!     VEC_quick_push (tree, *result, vuse);
! }
! 
! 
! /* Copy the VUSE names in STMT into a vector, and return
!    the vector.  */
! 
! static VEC (tree, gc) *
! copy_vuses_from_stmt (gimple stmt)
! {
!   VEC (tree, gc) *vuses = NULL;
! 
!   vuses_to_vec (stmt, &vuses);
! 
!   return vuses;
! }
! 
! /* Place the vdefs from STMT into *result.  */
! 
! static inline void
! vdefs_to_vec (gimple stmt, VEC (tree, gc) **result)
! {
!   ssa_op_iter iter;
!   tree vdef;
! 
!   if (!stmt)
!     return;
! 
!   *result = VEC_alloc (tree, gc, num_ssa_operands (stmt, SSA_OP_VIRTUAL_DEFS));
! 
!   FOR_EACH_SSA_TREE_OPERAND (vdef, stmt, iter, SSA_OP_VIRTUAL_DEFS)
!     VEC_quick_push (tree, *result, vdef);
! }
! 
! /* Copy the names of vdef results in STMT into a vector, and return
!    the vector.  */
! 
! static VEC (tree, gc) *
! copy_vdefs_from_stmt (gimple stmt)
! {
!   VEC (tree, gc) *vdefs = NULL;
! 
!   vdefs_to_vec (stmt, &vdefs);
! 
!   return vdefs;
! }
! 
! /* Place for shared_v{uses/defs}_from_stmt to shove vuses/vdefs.  */
! static VEC (tree, gc) *shared_lookup_vops;
! 
! /* Copy the virtual uses from STMT into SHARED_LOOKUP_VOPS.
!    This function will overwrite the current SHARED_LOOKUP_VOPS
!    variable.  */
! 
! VEC (tree, gc) *
! shared_vuses_from_stmt (gimple stmt)
! {
!   VEC_truncate (tree, shared_lookup_vops, 0);
!   vuses_to_vec (stmt, &shared_lookup_vops);
  
!   return shared_lookup_vops;
  }
  
  /* Copy the operations present in load/store REF into RESULT, a vector of
--- 463,474 ----
        != VEC_length (vn_reference_op_s, vr2->operands))
      return false;
  
    for (i = 0; VEC_iterate (vn_reference_op_s, vr1->operands, i, vro); i++)
!     if (!vn_reference_op_eq (VEC_index (vn_reference_op_s, vr2->operands, i),
! 			     vro))
!       return false;
  
!   return true;
  }
  
  /* Copy the operations present in load/store REF into RESULT, a vector of
*************** valueize_refs (VEC (vn_reference_op_s, h
*** 876,945 ****
    return orig;
  }
  
- /* Transform any SSA_NAME's in ORIG, a vector of vuse trees, into
-    their value numbers. This is done in-place, and the vector passed
-    in is returned.  */
- 
- static VEC (tree, gc) *
- valueize_vuses (VEC (tree, gc) *orig)
- {
-   bool made_replacement = false;
-   tree vuse;
-   int i;
- 
-   for (i = 0; VEC_iterate (tree, orig, i, vuse); i++)
-     {
-       if (vuse != SSA_VAL (vuse))
- 	{
- 	  made_replacement = true;
- 	  VEC_replace (tree, orig, i, SSA_VAL (vuse));
- 	}
-     }
- 
-   if (made_replacement && VEC_length (tree, orig) > 1)
-     sort_vuses (orig);
- 
-   return orig;
- }
- 
  /* Return the single reference statement defining all virtual uses
     in VUSES or NULL_TREE, if there are multiple defining statements.
     Take into account only definitions that alias REF if following
     back-edges.  */
  
  static gimple
! get_def_ref_stmt_vuses (tree ref, VEC (tree, gc) *vuses)
  {
    gimple def_stmt;
-   tree vuse;
-   unsigned int i;
  
!   gcc_assert (VEC_length (tree, vuses) >= 1);
  
!   def_stmt = SSA_NAME_DEF_STMT (VEC_index (tree, vuses, 0));
    if (gimple_code (def_stmt) == GIMPLE_PHI)
!     {
!       /* We can only handle lookups over PHI nodes for a single
! 	 virtual operand.  */
!       if (VEC_length (tree, vuses) == 1)
! 	{
! 	  def_stmt = get_single_def_stmt_from_phi (ref, def_stmt);
! 	  goto cont;
! 	}
!       else
! 	return NULL;
!     }
! 
!   /* Verify each VUSE reaches the same defining stmt.  */
!   for (i = 1; VEC_iterate (tree, vuses, i, vuse); ++i)
!     {
!       gimple tmp = SSA_NAME_DEF_STMT (vuse);
!       if (tmp != def_stmt)
! 	return NULL;
!     }
  
    /* Now see if the definition aliases ref, and loop until it does.  */
- cont:
    while (def_stmt
  	 && is_gimple_assign (def_stmt)
  	 && !refs_may_alias_p (ref, gimple_get_lhs (def_stmt)))
--- 793,815 ----
    return orig;
  }
  
  /* Return the single reference statement defining all virtual uses
     in VUSES or NULL_TREE, if there are multiple defining statements.
     Take into account only definitions that alias REF if following
     back-edges.  */
  
  static gimple
! get_def_ref_stmt_vuse (tree ref, tree vuse)
  {
    gimple def_stmt;
  
!   gcc_assert (vuse != NULL_TREE);
  
!   def_stmt = SSA_NAME_DEF_STMT (vuse);
    if (gimple_code (def_stmt) == GIMPLE_PHI)
!     def_stmt = get_single_def_stmt_from_phi (ref, def_stmt);
  
    /* Now see if the definition aliases ref, and loop until it does.  */
    while (def_stmt
  	 && is_gimple_assign (def_stmt)
  	 && !refs_may_alias_p (ref, gimple_get_lhs (def_stmt)))
*************** vn_reference_lookup_1 (vn_reference_t vr
*** 982,988 ****
     vn_reference_t stored in the hashtable if something is found.  */
  
  tree
! vn_reference_lookup_pieces (VEC (tree, gc) *vuses,
  			    VEC (vn_reference_op_s, heap) *operands,
  			    vn_reference_t *vnresult, bool maywalk)
  {
--- 852,858 ----
     vn_reference_t stored in the hashtable if something is found.  */
  
  tree
! vn_reference_lookup_pieces (tree vuse,
  			    VEC (vn_reference_op_s, heap) *operands,
  			    vn_reference_t *vnresult, bool maywalk)
  {
*************** vn_reference_lookup_pieces (VEC (tree, g
*** 991,997 ****
    if (vnresult)
      *vnresult = NULL;
    
!   vr1.vuses = valueize_vuses (vuses);
    vr1.operands = valueize_refs (operands);
    vr1.hashcode = vn_reference_compute_hash (&vr1);
    result = vn_reference_lookup_1 (&vr1, vnresult);
--- 861,867 ----
    if (vnresult)
      *vnresult = NULL;
    
!   vr1.vuse = SSA_VAL (vuse);
    vr1.operands = valueize_refs (operands);
    vr1.hashcode = vn_reference_compute_hash (&vr1);
    result = vn_reference_lookup_1 (&vr1, vnresult);
*************** vn_reference_lookup_pieces (VEC (tree, g
*** 1000,1018 ****
       use that, following virtual use-def chains.  */
    if (!result
        && maywalk
!       && vr1.vuses
!       && VEC_length (tree, vr1.vuses) >= 1)
      {
        tree ref = get_ref_from_reference_ops (operands);
        gimple def_stmt;
        if (ref
! 	  && (def_stmt = get_def_ref_stmt_vuses (ref, vr1.vuses))
  	  && is_gimple_assign (def_stmt))
  	{
! 	  /* We are now at an aliasing definition for the vuses we want to
! 	     look up.  Re-do the lookup with the vdefs for this stmt.  */
! 	  vdefs_to_vec (def_stmt, &vuses);
! 	  vr1.vuses = valueize_vuses (vuses);
  	  vr1.hashcode = vn_reference_compute_hash (&vr1);
  	  result = vn_reference_lookup_1 (&vr1, vnresult);
  	}
--- 870,886 ----
       use that, following virtual use-def chains.  */
    if (!result
        && maywalk
!       && vr1.vuse)
      {
        tree ref = get_ref_from_reference_ops (operands);
        gimple def_stmt;
        if (ref
! 	  && (def_stmt = get_def_ref_stmt_vuse (ref, vr1.vuse))
  	  && is_gimple_assign (def_stmt))
  	{
! 	  /* We are now at an aliasing definition for the vuse we want to
! 	     look up.  Re-do the lookup with the vdef for this stmt.  */
! 	  vr1.vuse = SSA_VAL (gimple_vdef (def_stmt));
  	  vr1.hashcode = vn_reference_compute_hash (&vr1);
  	  result = vn_reference_lookup_1 (&vr1, vnresult);
  	}
*************** vn_reference_lookup_pieces (VEC (tree, g
*** 1028,1034 ****
     stored in the hashtable if one exists.  */
  
  tree
! vn_reference_lookup (tree op, VEC (tree, gc) *vuses, bool maywalk,
  		     vn_reference_t *vnresult)
  {
    struct vn_reference_s vr1;
--- 896,902 ----
     stored in the hashtable if one exists.  */
  
  tree
! vn_reference_lookup (tree op, tree vuse, bool maywalk,
  		     vn_reference_t *vnresult)
  {
    struct vn_reference_s vr1;
*************** vn_reference_lookup (tree op, VEC (tree,
*** 1037,1043 ****
    if (vnresult)
      *vnresult = NULL;
  
!   vr1.vuses = valueize_vuses (vuses);
    vr1.operands = valueize_refs (shared_reference_ops_from_ref (op));
    vr1.hashcode = vn_reference_compute_hash (&vr1);
    result = vn_reference_lookup_1 (&vr1, vnresult);
--- 905,911 ----
    if (vnresult)
      *vnresult = NULL;
  
!   vr1.vuse = SSA_VAL (vuse);
    vr1.operands = valueize_refs (shared_reference_ops_from_ref (op));
    vr1.hashcode = vn_reference_compute_hash (&vr1);
    result = vn_reference_lookup_1 (&vr1, vnresult);
*************** vn_reference_lookup (tree op, VEC (tree,
*** 1046,1060 ****
       use that, following virtual use-def chains.  */
    if (!result
        && maywalk
!       && vr1.vuses
!       && VEC_length (tree, vr1.vuses) >= 1
!       && (def_stmt = get_def_ref_stmt_vuses (op, vr1.vuses))
        && is_gimple_assign (def_stmt))
      {
!       /* We are now at an aliasing definition for the vuses we want to
! 	 look up.  Re-do the lookup with the vdefs for this stmt.  */
!       vdefs_to_vec (def_stmt, &vuses);
!       vr1.vuses = valueize_vuses (vuses);
        vr1.hashcode = vn_reference_compute_hash (&vr1);
        result = vn_reference_lookup_1 (&vr1, vnresult);
      }
--- 914,926 ----
       use that, following virtual use-def chains.  */
    if (!result
        && maywalk
!       && vr1.vuse
!       && (def_stmt = get_def_ref_stmt_vuse (op, vr1.vuse))
        && is_gimple_assign (def_stmt))
      {
!       /* We are now at an aliasing definition for the vuse we want to
! 	 look up.  Re-do the lookup with the vdef for this stmt.  */
!       vr1.vuse = SSA_VAL (gimple_vdef (def_stmt));
        vr1.hashcode = vn_reference_compute_hash (&vr1);
        result = vn_reference_lookup_1 (&vr1, vnresult);
      }
*************** vn_reference_lookup (tree op, VEC (tree,
*** 1067,1073 ****
     RESULT, and return the resulting reference structure we created.  */
  
  vn_reference_t
! vn_reference_insert (tree op, tree result, VEC (tree, gc) *vuses)
  {
    void **slot;
    vn_reference_t vr1;
--- 933,939 ----
     RESULT, and return the resulting reference structure we created.  */
  
  vn_reference_t
! vn_reference_insert (tree op, tree result, tree vuse)
  {
    void **slot;
    vn_reference_t vr1;
*************** vn_reference_insert (tree op, tree resul
*** 1077,1083 ****
      vr1->value_id = VN_INFO (result)->value_id;
    else
      vr1->value_id = get_or_alloc_constant_value_id (result);
!   vr1->vuses = valueize_vuses (vuses);
    vr1->operands = valueize_refs (create_reference_ops_from_ref (op));
    vr1->hashcode = vn_reference_compute_hash (vr1);
    vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result;
--- 943,949 ----
      vr1->value_id = VN_INFO (result)->value_id;
    else
      vr1->value_id = get_or_alloc_constant_value_id (result);
!   vr1->vuse = SSA_VAL (vuse);
    vr1->operands = valueize_refs (create_reference_ops_from_ref (op));
    vr1->hashcode = vn_reference_compute_hash (vr1);
    vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result;
*************** vn_reference_insert (tree op, tree resul
*** 1106,1112 ****
     structure we created.  */
  
  vn_reference_t
! vn_reference_insert_pieces (VEC (tree, gc) *vuses,
  			    VEC (vn_reference_op_s, heap) *operands,
  			    tree result, unsigned int value_id)
  
--- 972,978 ----
     structure we created.  */
  
  vn_reference_t
! vn_reference_insert_pieces (tree vuse,
  			    VEC (vn_reference_op_s, heap) *operands,
  			    tree result, unsigned int value_id)
  
*************** vn_reference_insert_pieces (VEC (tree, g
*** 1116,1122 ****
  
    vr1 = (vn_reference_t) pool_alloc (current_info->references_pool);
    vr1->value_id =  value_id;
!   vr1->vuses = valueize_vuses (vuses);
    vr1->operands = valueize_refs (operands);
    vr1->hashcode = vn_reference_compute_hash (vr1);
    if (result && TREE_CODE (result) == SSA_NAME)
--- 982,988 ----
  
    vr1 = (vn_reference_t) pool_alloc (current_info->references_pool);
    vr1->value_id =  value_id;
!   vr1->vuse = SSA_VAL (vuse);
    vr1->operands = valueize_refs (operands);
    vr1->hashcode = vn_reference_compute_hash (vr1);
    if (result && TREE_CODE (result) == SSA_NAME)
*************** vn_reference_insert_pieces (VEC (tree, g
*** 1127,1134 ****
  				   INSERT);
    
    /* At this point we should have all the things inserted that we have
!   seen before, and we should never try inserting something that
!   already exists.  */
    gcc_assert (!*slot);
    if (*slot)
      free_reference (*slot);
--- 993,1000 ----
  				   INSERT);
    
    /* At this point we should have all the things inserted that we have
!      seen before, and we should never try inserting something that
!      already exists.  */
    gcc_assert (!*slot);
    if (*slot)
      free_reference (*slot);
*************** vn_nary_op_eq (const void *p1, const voi
*** 1183,1188 ****
--- 1049,1058 ----
    const_vn_nary_op_t const vno2 = (const_vn_nary_op_t) p2;
    unsigned i;
  
+   /* Early out if this is not a hash collision.  */
+   if (vno1->hashcode != vno2->hashcode)
+     return false;
+ 
    if (vno1->opcode != vno2->opcode
        || !types_compatible_p (vno1->type, vno2->type))
      return false;
*************** vn_phi_eq (const void *p1, const void *p
*** 1449,1454 ****
--- 1319,1328 ----
    const_vn_phi_t const vp1 = (const_vn_phi_t) p1;
    const_vn_phi_t const vp2 = (const_vn_phi_t) p2;
  
+   /* Early out if this is not a hash collision.  */
+   if (vp1->hashcode != vp2->hashcode)
+     return false;
+ 
    if (vp1->block == vp2->block)
      {
        int i;
*************** set_ssa_val_to (tree from, tree to)
*** 1593,1599 ****
  
    if (currval != to  && !operand_equal_p (currval, to, OEP_PURE_SAME))
      {
!       SSA_VAL (from) = to;
        if (dump_file && (dump_flags & TDF_DETAILS))
  	fprintf (dump_file, " (changed)\n");
        return true;
--- 1467,1473 ----
  
    if (currval != to  && !operand_equal_p (currval, to, OEP_PURE_SAME))
      {
!       VN_INFO (from)->valnum = to;
        if (dump_file && (dump_flags & TDF_DETAILS))
  	fprintf (dump_file, " (changed)\n");
        return true;
*************** visit_reference_op_call (tree lhs, gimpl
*** 1702,1708 ****
    struct vn_reference_s vr1;
    tree result;
  
!   vr1.vuses = valueize_vuses (shared_vuses_from_stmt (stmt));
    vr1.operands = valueize_refs (shared_reference_ops_from_call (stmt));
    vr1.hashcode = vn_reference_compute_hash (&vr1);
    result = vn_reference_lookup_1 (&vr1, NULL);
--- 1576,1582 ----
    struct vn_reference_s vr1;
    tree result;
  
!   vr1.vuse = SSA_VAL (gimple_vuse (stmt));
    vr1.operands = valueize_refs (shared_reference_ops_from_call (stmt));
    vr1.hashcode = vn_reference_compute_hash (&vr1);
    result = vn_reference_lookup_1 (&vr1, NULL);
*************** visit_reference_op_call (tree lhs, gimpl
*** 1719,1725 ****
        vn_reference_t vr2;
        changed = set_ssa_val_to (lhs, lhs);
        vr2 = (vn_reference_t) pool_alloc (current_info->references_pool);
!       vr2->vuses = valueize_vuses (copy_vuses_from_stmt (stmt));
        vr2->operands = valueize_refs (create_reference_ops_from_call (stmt));
        vr2->hashcode = vr1.hashcode;
        vr2->result = lhs;
--- 1593,1599 ----
        vn_reference_t vr2;
        changed = set_ssa_val_to (lhs, lhs);
        vr2 = (vn_reference_t) pool_alloc (current_info->references_pool);
!       vr2->vuse = SSA_VAL (gimple_vuse (stmt));
        vr2->operands = valueize_refs (create_reference_ops_from_call (stmt));
        vr2->hashcode = vr1.hashcode;
        vr2->result = lhs;
*************** static bool
*** 1740,1747 ****
  visit_reference_op_load (tree lhs, tree op, gimple stmt)
  {
    bool changed = false;
!   tree result = vn_reference_lookup (op, shared_vuses_from_stmt (stmt), true,
! 				     NULL);
  
    /* We handle type-punning through unions by value-numbering based
       on offset and size of the access.  Be prepared to handle a
--- 1614,1620 ----
  visit_reference_op_load (tree lhs, tree op, gimple stmt)
  {
    bool changed = false;
!   tree result = vn_reference_lookup (op, gimple_vuse (stmt), true, NULL);
  
    /* We handle type-punning through unions by value-numbering based
       on offset and size of the access.  Be prepared to handle a
*************** visit_reference_op_load (tree lhs, tree 
*** 1818,1824 ****
    else
      {
        changed = set_ssa_val_to (lhs, lhs);
!       vn_reference_insert (op, lhs, copy_vuses_from_stmt (stmt));
      }
  
    return changed;
--- 1691,1697 ----
    else
      {
        changed = set_ssa_val_to (lhs, lhs);
!       vn_reference_insert (op, lhs, gimple_vuse (stmt));
      }
  
    return changed;
*************** visit_reference_op_store (tree lhs, tree
*** 1851,1858 ****
       Otherwise, the vdefs for the store are used when inserting into
       the table, since the store generates a new memory state.  */
  
!   result = vn_reference_lookup (lhs, shared_vuses_from_stmt (stmt), false,
! 				NULL);
  
    if (result)
      {
--- 1724,1730 ----
       Otherwise, the vdefs for the store are used when inserting into
       the table, since the store generates a new memory state.  */
  
!   result = vn_reference_lookup (lhs, gimple_vuse (stmt), false, NULL);
  
    if (result)
      {
*************** visit_reference_op_store (tree lhs, tree
*** 1865,1872 ****
  
    if (!result || !resultsame)
      {
-       VEC(tree, gc) *vdefs = copy_vdefs_from_stmt (stmt);
-       int i;
        tree vdef;
  
        if (dump_file && (dump_flags & TDF_DETAILS))
--- 1737,1742 ----
*************** visit_reference_op_store (tree lhs, tree
*** 1880,1886 ****
  	}
        /* Have to set value numbers before insert, since insert is
  	 going to valueize the references in-place.  */
!       for (i = 0; VEC_iterate (tree, vdefs, i, vdef); i++)
  	{
  	  VN_INFO (vdef)->use_processed = true;
  	  changed |= set_ssa_val_to (vdef, vdef);
--- 1750,1756 ----
  	}
        /* Have to set value numbers before insert, since insert is
  	 going to valueize the references in-place.  */
!       if ((vdef = gimple_vdef (stmt)))
  	{
  	  VN_INFO (vdef)->use_processed = true;
  	  changed |= set_ssa_val_to (vdef, vdef);
*************** visit_reference_op_store (tree lhs, tree
*** 1889,1924 ****
        /* Do not insert structure copies into the tables.  */
        if (is_gimple_min_invariant (op)
  	  || is_gimple_reg (op))
!         vn_reference_insert (lhs, op, vdefs);
      }
    else
      {
!       /* We had a match, so value number the vdefs to have the value
! 	 number of the vuses they came from.  */
!       ssa_op_iter op_iter;
!       def_operand_p var;
!       vuse_vec_p vv;
  
        if (dump_file && (dump_flags & TDF_DETAILS))
  	fprintf (dump_file, "Store matched earlier value,"
  		 "value numbering store vdefs to matching vuses.\n");
  
!       FOR_EACH_SSA_VDEF_OPERAND (var, vv, stmt, op_iter)
! 	{
! 	  tree def = DEF_FROM_PTR (var);
! 	  tree use;
! 
! 	  /* Uh, if the vuse is a multiuse, we can't really do much
! 	     here, sadly, since we don't know which value number of
! 	     which vuse to use.  */
! 	  if (VUSE_VECT_NUM_ELEM (*vv) != 1)
! 	    use = def;
! 	  else
! 	    use = VUSE_ELEMENT_VAR (*vv, 0);
  
! 	  VN_INFO (def)->use_processed = true;
! 	  changed |= set_ssa_val_to (def, SSA_VAL (use));
! 	}
      }
  
    return changed;
--- 1759,1781 ----
        /* Do not insert structure copies into the tables.  */
        if (is_gimple_min_invariant (op)
  	  || is_gimple_reg (op))
!         vn_reference_insert (lhs, op, vdef);
      }
    else
      {
!       /* We had a match, so value number the vdef to have the value
! 	 number of the vuse it came from.  */
!       tree def, use;
  
        if (dump_file && (dump_flags & TDF_DETAILS))
  	fprintf (dump_file, "Store matched earlier value,"
  		 "value numbering store vdefs to matching vuses.\n");
  
!       def = gimple_vdef (stmt);
!       use = gimple_vuse (stmt);
  
!       VN_INFO (def)->use_processed = true;
!       changed |= set_ssa_val_to (def, SSA_VAL (use));
      }
  
    return changed;
*************** init_scc_vn (void)
*** 2775,2781 ****
    gcc_obstack_init (&vn_ssa_aux_obstack);
  
    shared_lookup_phiargs = NULL;
-   shared_lookup_vops = NULL;
    shared_lookup_references = NULL;
    rpo_numbers = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS);
    rpo_numbers_temp = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS);
--- 2632,2637 ----
*************** free_scc_vn (void)
*** 2821,2827 ****
    htab_delete (constant_to_value_id);
    BITMAP_FREE (constant_value_ids);
    VEC_free (tree, heap, shared_lookup_phiargs);
-   VEC_free (tree, gc, shared_lookup_vops);
    VEC_free (vn_reference_op_s, heap, shared_lookup_references);
    XDELETEVEC (rpo_numbers);
  
--- 2677,2682 ----
*************** run_scc_vn (bool may_insert_arg)
*** 2914,2920 ****
        if (gimple_default_def (cfun, param) != NULL)
  	{
  	  tree def = gimple_default_def (cfun, param);
! 	  SSA_VAL (def) = def;
  	}
      }
  
--- 2769,2775 ----
        if (gimple_default_def (cfun, param) != NULL)
  	{
  	  tree def = gimple_default_def (cfun, param);
! 	  VN_INFO (def)->valnum = def;
  	}
      }
  
*************** expressions_equal_p (tree e1, tree e2)
*** 3047,3074 ****
    return false;
  }
  
- /* Sort the VUSE array so that we can do equality comparisons
-    quicker on two vuse vecs.  */
- 
- void
- sort_vuses (VEC (tree,gc) *vuses)
- {
-   if (VEC_length (tree, vuses) > 1)
-     qsort (VEC_address (tree, vuses),
- 	   VEC_length (tree, vuses),
- 	   sizeof (tree),
- 	   operand_build_cmp);
- }
- 
- /* Sort the VUSE array so that we can do equality comparisons
-    quicker on two vuse vecs.  */
- 
- void
- sort_vuses_heap (VEC (tree,heap) *vuses)
- {
-   if (VEC_length (tree, vuses) > 1)
-     qsort (VEC_address (tree, vuses),
- 	   VEC_length (tree, vuses),
- 	   sizeof (tree),
- 	   operand_build_cmp);
- }
--- 2902,2904 ----
Index: gcc/tree-ssa-sccvn.h
===================================================================
*** gcc/tree-ssa-sccvn.h	(revision 142546)
--- gcc/tree-ssa-sccvn.h	(working copy)
*************** typedef const vn_reference_op_s *const_v
*** 79,98 ****
  DEF_VEC_O(vn_reference_op_s);
  DEF_VEC_ALLOC_O(vn_reference_op_s, heap);
  
! /* A reference operation in the hashtable is representation as a
!    collection of vuses, representing the memory state at the time of
     the operation, and a collection of operands that make up the
     addressing calculation.  If two vn_reference_t's have the same set
     of operands, they access the same memory location. We also store
!    the resulting value number, and the hashcode.  The vuses are
!    always stored in order sorted by ssa name version.  */
  
  typedef struct vn_reference_s
  {
    /* Unique identifier that all expressions with the same value have. */
    unsigned int value_id;
    hashval_t hashcode;
!   VEC (tree, gc) *vuses;
    VEC (vn_reference_op_s, heap) *operands;
    tree result;
  } *vn_reference_t;
--- 79,97 ----
  DEF_VEC_O(vn_reference_op_s);
  DEF_VEC_ALLOC_O(vn_reference_op_s, heap);
  
! /* A reference operation in the hashtable is representation as
!    the vuse, representing the memory state at the time of
     the operation, and a collection of operands that make up the
     addressing calculation.  If two vn_reference_t's have the same set
     of operands, they access the same memory location. We also store
!    the resulting value number, and the hashcode.  */
  
  typedef struct vn_reference_s
  {
    /* Unique identifier that all expressions with the same value have. */
    unsigned int value_id;
    hashval_t hashcode;
!   tree vuse;
    VEC (vn_reference_op_s, heap) *operands;
    tree result;
  } *vn_reference_t;
*************** vn_nary_op_t vn_nary_op_insert_pieces (u
*** 176,187 ****
  				       tree, tree, unsigned int);
  void copy_reference_ops_from_ref (tree, VEC(vn_reference_op_s, heap) **);
  void copy_reference_ops_from_call (gimple, VEC(vn_reference_op_s, heap) **);
! tree vn_reference_lookup_pieces (VEC (tree, gc) *,
  				 VEC (vn_reference_op_s, heap) *,
  				 vn_reference_t *, bool);
! tree vn_reference_lookup (tree, VEC (tree, gc) *, bool, vn_reference_t *);
! vn_reference_t vn_reference_insert (tree, tree, VEC (tree, gc) *);
! vn_reference_t vn_reference_insert_pieces (VEC (tree, gc) *,
  					   VEC (vn_reference_op_s, heap) *,
  					   tree, unsigned int);
  tree vn_phi_lookup (gimple);
--- 175,186 ----
  				       tree, tree, unsigned int);
  void copy_reference_ops_from_ref (tree, VEC(vn_reference_op_s, heap) **);
  void copy_reference_ops_from_call (gimple, VEC(vn_reference_op_s, heap) **);
! tree vn_reference_lookup_pieces (tree,
  				 VEC (vn_reference_op_s, heap) *,
  				 vn_reference_t *, bool);
! tree vn_reference_lookup (tree, tree, bool, vn_reference_t *);
! vn_reference_t vn_reference_insert (tree, tree, tree);
! vn_reference_t vn_reference_insert_pieces (tree,
  					   VEC (vn_reference_op_s, heap) *,
  					   tree, unsigned int);
  tree vn_phi_lookup (gimple);
*************** unsigned int get_next_value_id (void);
*** 195,199 ****
  unsigned int get_constant_value_id (tree);
  unsigned int get_or_alloc_constant_value_id (tree);
  bool value_id_constant_p (unsigned int);
- VEC (tree, gc) *shared_vuses_from_stmt (gimple);
  #endif /* TREE_SSA_SCCVN_H  */
--- 194,197 ----
Index: gcc/tree-dfa.c
===================================================================
*** gcc/tree-dfa.c	(revision 142546)
--- gcc/tree-dfa.c	(working copy)
*************** refs_may_alias_p (tree ref1, tree ref2)
*** 1060,1096 ****
  }
  
  /* Given a stmt STMT that references memory, return the single stmt
!    that is reached by following the VUSE -> VDEF link.  Returns
!    NULL_TREE, if there is no single stmt that defines all VUSEs of
!    STMT.
!    Note that for a stmt with a single virtual operand this may return
!    a PHI node as well.  Note that if all VUSEs are default definitions
!    this function will return an empty statement.  */
  
  gimple
  get_single_def_stmt (gimple stmt)
  {
!   gimple def_stmt = NULL;
!   tree use;
!   ssa_op_iter iter;
! 
!   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VIRTUAL_USES)
!     {
!       gimple tmp = SSA_NAME_DEF_STMT (use);
! 
!       /* ???  This is too simplistic for multiple virtual operands
! 	 reaching different PHI nodes of the same basic blocks or for
! 	 reaching all default definitions.  */
!       if (def_stmt
! 	  && def_stmt != tmp
! 	  && !(gimple_nop_p (def_stmt)
! 	       && gimple_nop_p (tmp)))
! 	return NULL;
! 
!       def_stmt = tmp;
!     }
! 
!   return def_stmt;
  }
  
  /* Given a PHI node of virtual operands, tries to eliminate cyclic
--- 1060,1074 ----
  }
  
  /* Given a stmt STMT that references memory, return the single stmt
!    that is reached by following the VUSE -> VDEF link.
!    Note that this may return a PHI node as well.
!    Note that if the VUSE is a default definition this function will
!    return an empty statement.  */
  
  gimple
  get_single_def_stmt (gimple stmt)
  {
!   return SSA_NAME_DEF_STMT (gimple_vuse (stmt));
  }
  
  /* Given a PHI node of virtual operands, tries to eliminate cyclic
*************** get_single_def_stmt_from_phi (tree ref, 
*** 1130,1137 ****
  	  if (!is_gimple_assign (def_stmt)
  	      || refs_may_alias_p (ref, gimple_assign_lhs (def_stmt)))
  	    return NULL;
- 	  /* ???  This will only work, reaching the PHI node again if
- 	     there is a single virtual operand on def_stmt.  */
  	  def_stmt = get_single_def_stmt (def_stmt);
  	  if (!def_stmt)
  	    return NULL;
--- 1108,1113 ----
*************** get_single_def_stmt_from_phi (tree ref, 
*** 1150,1172 ****
  gimple
  get_single_def_stmt_with_phi (tree ref, gimple stmt)
  {
!   switch (NUM_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_USES))
!     {
!     case 0:
!       gcc_unreachable ();
  
!     case 1:
!       {
! 	gimple def_stmt = SSA_NAME_DEF_STMT (SINGLE_SSA_TREE_OPERAND
! 					     (stmt, SSA_OP_VIRTUAL_USES));
! 	/* We can handle lookups over PHI nodes only for a single
! 	   virtual operand.  */
! 	if (gimple_code (def_stmt) == GIMPLE_PHI)
! 	  return get_single_def_stmt_from_phi (ref, def_stmt);
! 	return def_stmt;
!       }
  
!     default:
!       return get_single_def_stmt (stmt);
!     }
  }
--- 1126,1135 ----
  gimple
  get_single_def_stmt_with_phi (tree ref, gimple stmt)
  {
!   gimple def_stmt = SSA_NAME_DEF_STMT (gimple_vuse (stmt));
  
!   if (gimple_code (def_stmt) == GIMPLE_PHI)
!     return get_single_def_stmt_from_phi (ref, def_stmt);
  
!   return def_stmt;
  }
Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c	(revision 142546)
--- gcc/tree-ssa-pre.c	(working copy)
*************** do_unary:
*** 1218,1265 ****
    return e;
  }
  
! /* Translate the vuses in the VUSES vector backwards through phi nodes
!    in PHIBLOCK, so that they have the value they would have in
!    BLOCK. */
! 
! static VEC(tree, gc) *
! translate_vuses_through_block (VEC (tree, gc) *vuses,
! 			       basic_block phiblock,
! 			       basic_block block)
! {
!   tree oldvuse;
!   VEC(tree, gc) *result = NULL;
!   int i;
! 
!   for (i = 0; VEC_iterate (tree, vuses, i, oldvuse); i++)
!     {
!       gimple phi = SSA_NAME_DEF_STMT (oldvuse);
!       if (gimple_code (phi) == GIMPLE_PHI
! 	  && gimple_bb (phi) == phiblock)
! 	{
! 	  edge e = find_edge (block, gimple_bb (phi));
! 	  if (e)
! 	    {
! 	      tree def = PHI_ARG_DEF (phi, e->dest_idx);
! 	      if (def != oldvuse)
! 		{
! 		  if (!result)
! 		    result = VEC_copy (tree, gc, vuses);
! 		  VEC_replace (tree, result, i, def);
! 		}
! 	    }
! 	}
!     }
  
!   /* We avoid creating a new copy of the vuses unless something
!      actually changed, so result can be NULL.  */
!   if (result)
      {
!       sort_vuses (result);
!       return result;
      }
-   return vuses;
  
  }
  
  /* Like find_leader, but checks for the value existing in SET1 *or*
--- 1218,1241 ----
    return e;
  }
  
! /* Translate the VUSE backwards through phi nodes in PHIBLOCK, so that
!    it has the value it would have in BLOCK.  */
  
! static tree
! translate_vuse_through_block (tree vuse,
! 			      basic_block phiblock,
! 			      basic_block block)
! {
!   gimple phi = SSA_NAME_DEF_STMT (vuse);
!   if (gimple_code (phi) == GIMPLE_PHI
!       && gimple_bb (phi) == phiblock)
      {
!       edge e = find_edge (block, gimple_bb (phi));
!       if (e)
! 	return PHI_ARG_DEF (phi, e->dest_idx);
      }
  
+   return vuse;
  }
  
  /* Like find_leader, but checks for the value existing in SET1 *or*
*************** phi_translate_1 (pre_expr expr, bitmap_s
*** 1531,1538 ****
        {
  	vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
  	VEC (vn_reference_op_s, heap) *operands = ref->operands;
! 	VEC (tree, gc) *vuses = ref->vuses;
! 	VEC (tree, gc) *newvuses = vuses;
  	VEC (vn_reference_op_s, heap) *newoperands = NULL;
  	bool changed = false;
  	unsigned int i;
--- 1507,1514 ----
        {
  	vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
  	VEC (vn_reference_op_s, heap) *operands = ref->operands;
! 	tree vuse = ref->vuse;
! 	tree newvuse = vuse;
  	VEC (vn_reference_op_s, heap) *newoperands = NULL;
  	bool changed = false;
  	unsigned int i;
*************** phi_translate_1 (pre_expr expr, bitmap_s
*** 1623,1637 ****
  	    return NULL;
  	  }
  
! 	newvuses = translate_vuses_through_block (vuses, phiblock, pred);
! 	changed |= newvuses != vuses;
  
  	if (changed)
  	  {
  	    unsigned int new_val_id;
  	    pre_expr constant;
  
! 	    tree result = vn_reference_lookup_pieces (newvuses,
  						      newoperands,
  						      &newref, true);
  	    if (newref)
--- 1599,1614 ----
  	    return NULL;
  	  }
  
! 	if (vuse)
! 	  newvuse = translate_vuse_through_block (vuse, phiblock, pred);
! 	changed |= newvuse != vuse;
  
  	if (changed)
  	  {
  	    unsigned int new_val_id;
  	    pre_expr constant;
  
! 	    tree result = vn_reference_lookup_pieces (newvuse,
  						      newoperands,
  						      &newref, true);
  	    if (newref)
*************** phi_translate_1 (pre_expr expr, bitmap_s
*** 1662,1668 ****
  		new_val_id = get_next_value_id ();
  		VEC_safe_grow_cleared (bitmap_set_t, heap, value_expressions,
  				       get_max_value_id() + 1);
! 		newref = vn_reference_insert_pieces (newvuses,
  						     newoperands,
  						     result, new_val_id);
  		newoperands = NULL;
--- 1639,1645 ----
  		new_val_id = get_next_value_id ();
  		VEC_safe_grow_cleared (bitmap_set_t, heap, value_expressions,
  				       get_max_value_id() + 1);
! 		newref = vn_reference_insert_pieces (newvuse,
  						     newoperands,
  						     result, new_val_id);
  		newoperands = NULL;
*************** bitmap_find_leader (bitmap_set_t set, un
*** 1834,1855 ****
  static bool
  value_dies_in_block_x (pre_expr expr, basic_block block)
  {
!   int i;
!   tree vuse;
!   VEC (tree, gc) *vuses = PRE_EXPR_REFERENCE (expr)->vuses;
  
!   /* Conservatively, a value dies if it's vuses are defined in this
       block, unless they come from phi nodes (which are merge operations,
       rather than stores.  */
!   for (i = 0; VEC_iterate (tree, vuses, i, vuse); i++)
      {
        gimple def = SSA_NAME_DEF_STMT (vuse);
! 
!       if (gimple_bb (def) != block)
! 	continue;
!       if (gimple_code (def) == GIMPLE_PHI)
! 	continue;
!       return true;
      }
    return false;
  }
--- 1811,1827 ----
  static bool
  value_dies_in_block_x (pre_expr expr, basic_block block)
  {
!   tree vuse = PRE_EXPR_REFERENCE (expr)->vuse;
  
!   /* Conservatively, a value dies if it's vuse is defined in this
       block, unless they come from phi nodes (which are merge operations,
       rather than stores.  */
!   if (vuse)
      {
        gimple def = SSA_NAME_DEF_STMT (vuse);
!       if (gimple_bb (def) == block
! 	  && gimple_code (def) != GIMPLE_PHI)
! 	return true;
      }
    return false;
  }
*************** vro_valid_in_sets (bitmap_set_t set1, bi
*** 1913,1919 ****
     ONLY SET2 CAN BE NULL.
     This means that we have a leader for each part of the expression
     (if it consists of values), or the expression is an SSA_NAME.
!    For loads/calls, we also see if the vuses are killed in this block.
  */
  
  static bool
--- 1885,1891 ----
     ONLY SET2 CAN BE NULL.
     This means that we have a leader for each part of the expression
     (if it consists of values), or the expression is an SSA_NAME.
!    For loads/calls, we also see if the vuse is killed in this block.
  */
  
  static bool
*************** compute_avail (void)
*** 3674,3680 ****
  		  continue;
  
  		copy_reference_ops_from_call (stmt, &ops);
! 		vn_reference_lookup_pieces (shared_vuses_from_stmt (stmt),
  					    ops, &ref, false);
  		VEC_free (vn_reference_op_s, heap, ops);
  		if (!ref)
--- 3646,3652 ----
  		  continue;
  
  		copy_reference_ops_from_call (stmt, &ops);
! 		vn_reference_lookup_pieces (gimple_vuse (stmt),
  					    ops, &ref, false);
  		VEC_free (vn_reference_op_s, heap, ops);
  		if (!ref)
*************** compute_avail (void)
*** 3749,3755 ****
  		      vn_reference_op_t vro;
  
  		      vn_reference_lookup (gimple_assign_rhs1 (stmt),
! 					   shared_vuses_from_stmt (stmt),
  					   false, &ref);
  		      if (!ref)
  			continue;
--- 3721,3727 ----
  		      vn_reference_op_t vro;
  
  		      vn_reference_lookup (gimple_assign_rhs1 (stmt),
! 					   gimple_vuse (stmt),
  					   false, &ref);
  		      if (!ref)
  			continue;
Index: gcc/gimple.h
===================================================================
*** gcc/gimple.h	(revision 142546)
--- gcc/gimple.h	(working copy)
*************** gimple_set_vdef_ops (gimple g, struct vo
*** 1359,1364 ****
--- 1359,1390 ----
  }
  
  
+ /* Return the single VUSE operand of the statement G.  */
+ 
+ static inline tree
+ gimple_vuse (const_gimple g)
+ {
+   struct voptype_d *ops = gimple_vuse_ops (g);
+   if (!ops)
+     /* The VMAYUSE is in the vdef ops list.  */
+     ops = gimple_vdef_ops (g);
+   if (!ops)
+     return NULL_TREE;
+   return VUSE_OP (ops, 0);
+ }
+ 
+ /* Return the single VDEF operand of the statement G.  */
+ 
+ static inline tree
+ gimple_vdef (const_gimple g)
+ {
+   struct voptype_d *ops = gimple_vdef_ops (g);
+   if (!ops)
+     return NULL_TREE;
+   return VDEF_RESULT (ops);
+ }
+ 
+ 
  /* Return the set of symbols loaded by statement G.  Each element of the
     set is the DECL_UID of the corresponding symbol.  */
  



More information about the Gcc-patches mailing list