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]

[PATCH][tuples] Tuplify SCCVN


This patch tuplifies SCCVN.  I have re-enabled FRE as far as to do
the value-numbering.  This causes a lot of testcases to change from
FAIL due to missing dump file to a regular FAIL.

The most interesting part is how we treat simplifying across
statements (and thus VN_INFO->expr).  I have wrapped the access
to it and create regular tree expressions on demand.  We may miss
some simplifications now (gimple_fold is not gimple_fold_build), but
in the end we'll notice only after FRE is fully converted.

Nevertheless - bootstrapped and tested on x86_64-unknown-linux-gnu.

Ok for tuples?  (I appreciate a review as I'm only getting familiar
with the new API)

Thanks,
Richard.

2008-06-24  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-sccvn.c (vn_get_expr_for): New function.
	(vuses_to_vec): Tuplify.
	(copy_vuses_from_stmt): Likewise.
	(vdefs_to_vec): Likewise.
	(copy_vdefs_from_stmt): Likewise.
	(shared_vuses_from_stmt): Likewise.
	(copy_reference_ops_from_call): New function split out from
	copy_reference_ops_from_ref.
	(create_reference_ops_from_call): New function.
	(shared_reference_ops_from_call): Likewise.
	(get_def_ref_stmt_vuses): Tuplify.
	(vn_reference_lookup): Likewise.
	(vn_nary_op_lookup_stmt): New function.
	(vn_nary_op_insert_stmt): Likewise.
	(vn_phi_lookup): Tuplify.
	(vn_phi_insert): Likewise.
	(defs_to_varying): Likewise.
	(visit_unary_op): Likewise.
	(visit_binary_op): Likewise.
	(visit_reference_op_call): New function.
	(visit_reference_op_load): Tuplify.
	(visit_reference_op_store): Likewise.
	(visit_phi): Likewise.
	(stmt_has_constants): New function.
	(simplify_binary_expression): Tuplify.
	(simplify_unary_expression): Likewise.
	(try_to_simplify): Likewise.
	(visit_use): Likewise.
	(compare_ops): Likewise.
	(DFS): Likewise.
	(run_scc_vn): Likewise.
	* tree-ssa-sccvn.h (shared_vuses_from_stmt): Adjust prototype.
	(copy_vuses_from_stmt): Likewise.
	(vn_get_expr_for): Declare.
	(vn_nary_op_lookup_stmt): Likewise.
	(vn_nary_op_insert_stmt): Likewise.
	* tree-dfa.c (get_single_def_stmt): Tuplify.
	(get_single_def_stmt_from_phi): Likewise.
	(get_single_def_stmt_with_phi): Likewise.
	* tree-ssa-pre.c (do_SCCVN_insertion): Use vn_get_expr_for.
	(eliminate): Likewise.
	(execute_pre): Enable SCCVN.
	(gate_fre): Enable.
	* tree-flow.h (get_single_def_stmt): Adjust prototype.
	(get_single_def_stmt_from_phi): Likewise.
	(get_single_def_stmt_with_phi): Likewise.
	(vn_lookup_or_add_with_stmt): Likewise.
	(vn_lookup_with_stmt): Likewise.
	* gimple.c (gimple_fold): Fix.
	* tree-vn.c (vn_add): Disable call to add_to_value.
	(vn_add_with_vuses): Likewise.
	(vn_lookup_with_stmt): Tuplify.
	(vn_lookup_or_add_with_stmt): Likewise.

Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c.orig	2008-06-24 13:13:07.000000000 +0200
+++ gcc/tree-ssa-sccvn.c	2008-06-24 16:15:01.000000000 +0200
@@ -46,8 +46,6 @@ along with GCC; see the file COPYING3.  
 #include "tree-ssa-propagate.h"
 #include "tree-ssa-sccvn.h"
 
-/* FIXME tuples.  */
-#if 0
 /* This algorithm is based on the SCC algorithm presented by Keith
    Cooper and L. Taylor Simpson in "SCC-Based Value numbering"
    (http://citeseer.ist.psu.edu/41805.html).  In
@@ -274,6 +272,55 @@ VN_INFO_GET (tree name)
 }
 
 
+/* Get the representative expression for the SSA_NAME NAME.  Returns
+   the representative SSA_NAME if there is no expression associated with it.  */
+
+tree
+vn_get_expr_for (tree name)
+{
+  vn_ssa_aux_t vn = VN_INFO (name);
+  gimple def_stmt;
+  tree expr;
+
+  if (vn->valnum == VN_TOP)
+    return name;
+
+  /* If the value-number is a constant it is the representative
+     expression.  */
+  if (TREE_CODE (vn->valnum) != SSA_NAME)
+    return vn->valnum;
+
+  /* Get to the information of the value of this SSA_NAME.  */
+  vn = VN_INFO (vn->valnum);
+
+  /* If the value-number is a constant it is the representative
+     expression.  */
+  if (TREE_CODE (vn->valnum) != SSA_NAME)
+    return vn->valnum;
+
+  /* Else if we have an expression, return it.  */
+  if (vn->expr != NULL_TREE)
+    return vn->expr;
+
+  /* Otherwise use the defining statement to build the expression.  */
+  def_stmt = SSA_NAME_DEF_STMT (vn->valnum);
+
+  /* If the value number is a default-definition use it directly.  */
+  if (gimple_nop_p (def_stmt))
+    return vn->valnum;
+
+  /* ???  This will return NULL_TREE if the stmt cannot be simplified.  */
+  expr = gimple_fold (def_stmt);
+  if (!expr)
+    return vn->valnum;
+
+  /* Cache the expression.  */
+  vn->expr = expr;
+
+  return expr;
+}
+
+
 /* Free a phi operation structure VP.  */
 
 static void
@@ -391,7 +438,7 @@ vn_reference_eq (const void *p1, const v
 /* Place the vuses from STMT into *result */
 
 static inline void
-vuses_to_vec (tree stmt, VEC (tree, gc) **result)
+vuses_to_vec (gimple stmt, VEC (tree, gc) **result)
 {
   ssa_op_iter iter;
   tree vuse;
@@ -411,7 +458,7 @@ vuses_to_vec (tree stmt, VEC (tree, gc) 
    the vector.  */
 
 VEC (tree, gc) *
-copy_vuses_from_stmt (tree stmt)
+copy_vuses_from_stmt (gimple stmt)
 {
   VEC (tree, gc) *vuses = NULL;
 
@@ -423,7 +470,7 @@ copy_vuses_from_stmt (tree stmt)
 /* Place the vdefs from STMT into *result */
 
 static inline void
-vdefs_to_vec (tree stmt, VEC (tree, gc) **result)
+vdefs_to_vec (gimple stmt, VEC (tree, gc) **result)
 {
   ssa_op_iter iter;
   tree vdef;
@@ -441,7 +488,7 @@ vdefs_to_vec (tree stmt, VEC (tree, gc) 
    the vector.  */
 
 static VEC (tree, gc) *
-copy_vdefs_from_stmt (tree stmt)
+copy_vdefs_from_stmt (gimple stmt)
 {
   VEC (tree, gc) *vdefs = NULL;
 
@@ -458,7 +505,7 @@ static VEC (tree, gc) *shared_lookup_vop
    variable.  */
 
 VEC (tree, gc) *
-shared_vuses_from_stmt (tree stmt)
+shared_vuses_from_stmt (gimple stmt)
 {
   VEC_truncate (tree, shared_lookup_vops, 0);
   vuses_to_vec (stmt, &shared_lookup_vops);
@@ -466,46 +513,12 @@ shared_vuses_from_stmt (tree stmt)
   return shared_lookup_vops;
 }
 
-/* Copy the operations present in load/store/call REF into RESULT, a vector of
+/* Copy the operations present in load/store REF into RESULT, a vector of
    vn_reference_op_s's.  */
 
 static void
 copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
 {
-  /* Calls are different from all other reference operations.  */
-  if (TREE_CODE (ref) == CALL_EXPR)
-    {
-      vn_reference_op_s temp;
-      tree callfn;
-      call_expr_arg_iterator iter;
-      tree callarg;
-
-      /* Copy the call_expr opcode, type, function being called, and
-	 arguments.  */
-      memset (&temp, 0, sizeof (temp));
-      temp.type = TREE_TYPE (ref);
-      temp.opcode = CALL_EXPR;
-      VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
-
-      callfn = get_callee_fndecl (ref);
-      if (!callfn)
-	callfn = CALL_EXPR_FN (ref);
-      temp.type = TREE_TYPE (callfn);
-      temp.opcode = TREE_CODE (callfn);
-      temp.op0 = callfn;
-      VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
-
-      FOR_EACH_CALL_EXPR_ARG (callarg, iter, ref)
-	{
-	  memset (&temp, 0, sizeof (temp));
-	  temp.type = TREE_TYPE (callarg);
-	  temp.opcode = TREE_CODE (callarg);
-	  temp.op0 = callarg;
-	  VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
-	}
-      return;
-    }
-
   if (TREE_CODE (ref) == TARGET_MEM_REF)
     {
       vn_reference_op_s temp;
@@ -612,6 +625,42 @@ copy_reference_ops_from_ref (tree ref, V
     }
 }
 
+/* Copy the operations present in load/store/call REF into RESULT, a vector of
+   vn_reference_op_s's.  */
+
+static void
+copy_reference_ops_from_call (gimple call,
+			      VEC(vn_reference_op_s, heap) **result)
+{
+  vn_reference_op_s temp;
+  tree callfn;
+  unsigned i;
+
+  /* Copy the call_expr opcode, type, function being called, and
+     arguments.  */
+  memset (&temp, 0, sizeof (temp));
+  temp.type = gimple_call_return_type (call);
+  temp.opcode = CALL_EXPR;
+  VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
+
+  callfn = gimple_call_fn (call);
+  temp.type = TREE_TYPE (callfn);
+  temp.opcode = TREE_CODE (callfn);
+  temp.op0 = callfn;
+  VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
+
+  for (i = 0; i < gimple_call_num_args (call); ++i)
+    {
+      tree callarg = gimple_call_arg (call, i);
+      memset (&temp, 0, sizeof (temp));
+      temp.type = TREE_TYPE (callarg);
+      temp.opcode = TREE_CODE (callarg);
+      temp.op0 = callarg;
+      VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
+    }
+  return;
+}
+
 /* Create a vector of vn_reference_op_s structures from REF, a
    REFERENCE_CLASS_P tree.  The vector is not shared. */
 
@@ -624,6 +673,18 @@ create_reference_ops_from_ref (tree ref)
   return result;
 }
 
+/* Create a vector of vn_reference_op_s structures from CALL, a
+   call statement.  The vector is not shared.  */
+
+static VEC(vn_reference_op_s, heap) *
+create_reference_ops_from_call (gimple call)
+{
+  VEC (vn_reference_op_s, heap) *result = NULL;
+
+  copy_reference_ops_from_call (call, &result);
+  return result;
+}
+
 static VEC(vn_reference_op_s, heap) *shared_lookup_references;
 
 /* Create a vector of vn_reference_op_s structures from REF, a
@@ -640,6 +701,20 @@ shared_reference_ops_from_ref (tree ref)
   return shared_lookup_references;
 }
 
+/* Create a vector of vn_reference_op_s structures from CALL, a
+   call statement.  The vector is shared among all callers of
+   this function.  */
+
+static VEC(vn_reference_op_s, heap) *
+shared_reference_ops_from_call (gimple call)
+{
+  if (!call)
+    return NULL;
+  VEC_truncate (vn_reference_op_s, shared_lookup_references, 0);
+  copy_reference_ops_from_call (call, &shared_lookup_references);
+  return shared_lookup_references;
+}
+
 
 /* Transform any SSA_NAME's in a vector of vn_reference_op_s
    structures into their value numbers.  This is done in-place, and
@@ -692,16 +767,17 @@ valueize_vuses (VEC (tree, gc) *orig)
    Take into account only definitions that alias REF if following
    back-edges.  */
 
-static tree
+static gimple
 get_def_ref_stmt_vuses (tree ref, VEC (tree, gc) *vuses)
 {
-  tree def_stmt, vuse;
+  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 (TREE_CODE (def_stmt) == PHI_NODE)
+  if (gimple_code (def_stmt) == GIMPLE_PHI)
     {
       /* We can only handle lookups over PHI nodes for a single
 	 virtual operand.  */
@@ -711,23 +787,22 @@ get_def_ref_stmt_vuses (tree ref, VEC (t
 	  goto cont;
 	}
       else
-	return NULL_TREE;
+	return NULL;
     }
 
   /* Verify each VUSE reaches the same defining stmt.  */
   for (i = 1; VEC_iterate (tree, vuses, i, vuse); ++i)
     {
-      tree tmp = SSA_NAME_DEF_STMT (vuse);
+      gimple tmp = SSA_NAME_DEF_STMT (vuse);
       if (tmp != def_stmt)
-	return NULL_TREE;
+	return NULL;
     }
 
   /* Now see if the definition aliases ref, and loop until it does.  */
 cont:
   while (def_stmt
-	 && TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
-	 && !get_call_expr_in (def_stmt)
-	 && !refs_may_alias_p (ref, GIMPLE_STMT_OPERAND (def_stmt, 0)))
+	 && is_gimple_assign (def_stmt)
+	 && !refs_may_alias_p (ref, gimple_get_lhs (def_stmt)))
     def_stmt = get_single_def_stmt_with_phi (ref, def_stmt);
 
   return def_stmt;
@@ -763,7 +838,8 @@ tree
 vn_reference_lookup (tree op, VEC (tree, gc) *vuses, bool maywalk)
 {
   struct vn_reference_s vr1;
-  tree result, def_stmt;
+  tree result;
+  gimple def_stmt;
 
   vr1.vuses = valueize_vuses (vuses);
   vr1.operands = valueize_refs (shared_reference_ops_from_ref (op));
@@ -776,12 +852,8 @@ vn_reference_lookup (tree op, VEC (tree,
       && maywalk
       && vr1.vuses
       && VEC_length (tree, vr1.vuses) >= 1
-      && !get_call_expr_in (op)
       && (def_stmt = get_def_ref_stmt_vuses (op, vr1.vuses))
-      && TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
-      /* If there is a call involved, op must be assumed to
-	 be clobbered.  */
-      && !get_call_expr_in (def_stmt))
+      && 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.  */
@@ -912,6 +984,33 @@ vn_nary_op_lookup (tree op)
   return ((vn_nary_op_t)*slot)->result;
 }
 
+/* Lookup the rhs of STMT in the current hash table, and return the resulting
+   value number if it exists in the hash table.  Return NULL_TREE if
+   it does not exist in the hash table. */
+
+tree
+vn_nary_op_lookup_stmt (gimple stmt)
+{
+  void **slot;
+  struct vn_nary_op_s vno1;
+  unsigned i;
+
+  vno1.opcode = gimple_subcode (stmt);
+  vno1.length = gimple_num_ops (stmt) - 1;
+  vno1.type = TREE_TYPE (gimple_assign_lhs (stmt));
+  for (i = 0; i < vno1.length; ++i)
+    vno1.op[i] = gimple_op (stmt, i + 1);
+  vno1.hashcode = vn_nary_op_compute_hash (&vno1);
+  slot = htab_find_slot_with_hash (current_info->nary, &vno1, vno1.hashcode,
+				   NO_INSERT);
+  if (!slot && current_info == optimistic_info)
+    slot = htab_find_slot_with_hash (valid_info->nary, &vno1, vno1.hashcode,
+				     NO_INSERT);
+  if (!slot)
+    return NULL_TREE;
+  return ((vn_nary_op_t)*slot)->result;
+}
+
 /* Insert OP into the current hash table with a value number of
    RESULT.  */
 
@@ -940,6 +1039,34 @@ vn_nary_op_insert (tree op, tree result)
   *slot = vno1;
 }
 
+/* Insert the rhs of STMT into the current hash table with a value number of
+   RESULT.  */
+
+void
+vn_nary_op_insert_stmt (gimple stmt, tree result)
+{
+  unsigned length = gimple_num_ops (stmt) - 1;
+  void **slot;
+  vn_nary_op_t vno1;
+  unsigned i;
+
+  vno1 = obstack_alloc (&current_info->nary_obstack,
+			(sizeof (struct vn_nary_op_s)
+			 - sizeof (tree) * (4 - length)));
+  vno1->opcode = gimple_subcode (stmt);
+  vno1->length = length;
+  vno1->type = TREE_TYPE (gimple_assign_lhs (stmt));
+  for (i = 0; i < vno1->length; ++i)
+    vno1->op[i] = gimple_op (stmt, i + 1);
+  vno1->result = result;
+  vno1->hashcode = vn_nary_op_compute_hash (vno1);
+  slot = htab_find_slot_with_hash (current_info->nary, vno1, vno1->hashcode,
+				   INSERT);
+  gcc_assert (!*slot);
+
+  *slot = vno1;
+}
+
 /* Compute a hashcode for PHI operation VP1 and return it.  */
 
 static inline hashval_t
@@ -1005,16 +1132,16 @@ static VEC(tree, heap) *shared_lookup_ph
    it does not exist in the hash table. */
 
 static tree
-vn_phi_lookup (tree phi)
+vn_phi_lookup (gimple phi)
 {
   void **slot;
   struct vn_phi_s vp1;
-  int i;
+  unsigned i;
 
   VEC_truncate (tree, shared_lookup_phiargs, 0);
 
   /* Canonicalize the SSA_NAME's to their value number.  */
-  for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+  for (i = 0; i < gimple_phi_num_args (phi); i++)
     {
       tree def = PHI_ARG_DEF (phi, i);
       def = TREE_CODE (def) == SSA_NAME ? SSA_VAL (def) : def;
@@ -1037,15 +1164,15 @@ vn_phi_lookup (tree phi)
    RESULT.  */
 
 static void
-vn_phi_insert (tree phi, tree result)
+vn_phi_insert (gimple phi, tree result)
 {
   void **slot;
   vn_phi_t vp1 = (vn_phi_t) pool_alloc (current_info->phis_pool);
-  int i;
+  unsigned i;
   VEC (tree, heap) *args = NULL;
 
   /* Canonicalize the SSA_NAME's to their value number.  */
-  for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+  for (i = 0; i < gimple_phi_num_args (phi); i++)
     {
       tree def = PHI_ARG_DEF (phi, i);
       def = TREE_CODE (def) == SSA_NAME ? SSA_VAL (def) : def;
@@ -1125,7 +1252,7 @@ set_ssa_val_to (tree from, tree to)
    Return true if a value number changed. */
 
 static bool
-defs_to_varying (tree stmt)
+defs_to_varying (gimple stmt)
 {
   bool changed = false;
   ssa_op_iter iter;
@@ -1142,7 +1269,7 @@ defs_to_varying (tree stmt)
 }
 
 static bool expr_has_constants (tree expr);
-static tree try_to_simplify (tree stmt, tree rhs);
+static tree try_to_simplify (gimple stmt);
 
 /* Visit a copy between LHS and RHS, return true if the value number
    changed.  */
@@ -1150,7 +1277,6 @@ static tree try_to_simplify (tree stmt, 
 static bool
 visit_copy (tree lhs, tree rhs)
 {
-
   /* Follow chains of copies to their destination.  */
   while (SSA_VAL (rhs) != rhs && TREE_CODE (SSA_VAL (rhs)) == SSA_NAME)
     rhs = SSA_VAL (rhs);
@@ -1167,10 +1293,10 @@ visit_copy (tree lhs, tree rhs)
    value number of LHS has changed as a result.  */
 
 static bool
-visit_unary_op (tree lhs, tree op)
+visit_unary_op (tree lhs, gimple stmt)
 {
   bool changed = false;
-  tree result = vn_nary_op_lookup (op);
+  tree result = vn_nary_op_lookup_stmt (stmt);
 
   if (result)
     {
@@ -1179,7 +1305,7 @@ visit_unary_op (tree lhs, tree op)
   else
     {
       changed = set_ssa_val_to (lhs, lhs);
-      vn_nary_op_insert (op, lhs);
+      vn_nary_op_insert_stmt (stmt, lhs);
     }
 
   return changed;
@@ -1189,10 +1315,10 @@ visit_unary_op (tree lhs, tree op)
    value number of LHS has changed as a result.  */
 
 static bool
-visit_binary_op (tree lhs, tree op)
+visit_binary_op (tree lhs, gimple stmt)
 {
   bool changed = false;
-  tree result = vn_nary_op_lookup (op);
+  tree result = vn_nary_op_lookup_stmt (stmt);
 
   if (result)
     {
@@ -1201,7 +1327,48 @@ visit_binary_op (tree lhs, tree op)
   else
     {
       changed = set_ssa_val_to (lhs, lhs);
-      vn_nary_op_insert (op, lhs);
+      vn_nary_op_insert_stmt (stmt, lhs);
+    }
+
+  return changed;
+}
+
+/* Visit a call STMT storing into LHS.  Return true if the value number
+   of the LHS has changed as a result.  */
+
+static bool
+visit_reference_op_call (tree lhs, gimple stmt)
+{
+  bool changed = false;
+  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);
+  if (result)
+    {
+      changed = set_ssa_val_to (lhs, result);
+      if (TREE_CODE (result) == SSA_NAME
+	  && VN_INFO (result)->has_constants)
+	VN_INFO (lhs)->has_constants = true;
+    }
+  else
+    {
+      void **slot;
+      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;
+      slot = htab_find_slot_with_hash (current_info->references,
+				       vr2, vr2->hashcode, INSERT);
+      if (*slot)
+	free_reference (*slot);
+      *slot = vr2;
     }
 
   return changed;
@@ -1211,7 +1378,7 @@ visit_binary_op (tree lhs, tree op)
    and return true if the value number of the LHS has changed as a result.  */
 
 static bool
-visit_reference_op_load (tree lhs, tree op, tree stmt)
+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);
@@ -1231,7 +1398,7 @@ visit_reference_op_load (tree lhs, tree 
 	  && !is_gimple_min_invariant (val)
 	  && TREE_CODE (val) != SSA_NAME)
         {
-	  tree tem = try_to_simplify (stmt, val);
+	  tree tem = try_to_simplify (stmt);
 	  if (tem)
 	    val = tem;
 	}
@@ -1243,7 +1410,7 @@ visit_reference_op_load (tree lhs, tree 
 	 a new SSA_NAME we create.  */
       if (!result && may_insert)
         {
-	  result = make_ssa_name (SSA_NAME_VAR (lhs), NULL_TREE);
+	  result = make_ssa_name (SSA_NAME_VAR (lhs), NULL);
 	  /* Initialize value-number information properly.  */
 	  VN_INFO_GET (result)->valnum = result;
 	  VN_INFO (result)->expr = val;
@@ -1299,7 +1466,7 @@ visit_reference_op_load (tree lhs, tree 
    and return true if the value number of the LHS has changed as a result.  */
 
 static bool
-visit_reference_op_store (tree lhs, tree op, tree stmt)
+visit_reference_op_store (tree lhs, tree op, gimple stmt)
 {
   bool changed = false;
   tree result;
@@ -1397,13 +1564,13 @@ visit_reference_op_store (tree lhs, tree
    changed.  */
 
 static bool
-visit_phi (tree phi)
+visit_phi (gimple phi)
 {
   bool changed = false;
   tree result;
   tree sameval = VN_TOP;
   bool allsame = true;
-  int i;
+  unsigned i;
 
   /* TODO: We could check for this in init_sccvn, and replace this
      with a gcc_assert.  */
@@ -1412,7 +1579,7 @@ visit_phi (tree phi)
 
   /* See if all non-TOP arguments have the same value.  TOP is
      equivalent to everything, so we can ignore it.  */
-  for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+  for (i = 0; i < gimple_phi_num_args (phi); i++)
     {
       tree def = PHI_ARG_DEF (phi, i);
 
@@ -1499,6 +1666,32 @@ expr_has_constants (tree expr)
   return false;
 }
 
+/* Return true if STMT contains constants.  */
+
+static bool
+stmt_has_constants (gimple stmt)
+{
+  if (gimple_code (stmt) != GIMPLE_ASSIGN)
+    return false;
+
+  switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
+    {
+    case GIMPLE_UNARY_RHS:
+      return is_gimple_min_invariant (gimple_assign_rhs1 (stmt));
+
+    case GIMPLE_BINARY_RHS:
+      return (is_gimple_min_invariant (gimple_assign_rhs1 (stmt))
+	      || is_gimple_min_invariant (gimple_assign_rhs2 (stmt)));
+    case GIMPLE_SINGLE_RHS:
+      /* Constants inside reference ops are rarely interesting, but
+	 it can take a lot of looking to find them.  */
+      return is_gimple_min_invariant (gimple_assign_rhs1 (stmt));
+    default:
+      gcc_unreachable ();
+    }
+  return false;
+}
+
 /* Replace SSA_NAMES in expr with their value numbers, and return the
    result.
    This is performed in place. */
@@ -1531,11 +1724,11 @@ valueize_expr (tree expr)
    simplified. */
 
 static tree
-simplify_binary_expression (tree stmt, tree rhs)
+simplify_binary_expression (gimple stmt)
 {
   tree result = NULL_TREE;
-  tree op0 = TREE_OPERAND (rhs, 0);
-  tree op1 = TREE_OPERAND (rhs, 1);
+  tree op0 = gimple_assign_rhs1 (stmt);
+  tree op1 = gimple_assign_rhs2 (stmt);
 
   /* This will not catch every single case we could combine, but will
      catch those with constants.  The goal here is to simultaneously
@@ -1544,7 +1737,7 @@ simplify_binary_expression (tree stmt, t
   if (TREE_CODE (op0) == SSA_NAME)
     {
       if (VN_INFO (op0)->has_constants)
-	op0 = valueize_expr (VN_INFO (op0)->expr);
+	op0 = valueize_expr (vn_get_expr_for (op0));
       else if (SSA_VAL (op0) != VN_TOP && SSA_VAL (op0) != op0)
 	op0 = SSA_VAL (op0);
     }
@@ -1552,19 +1745,20 @@ simplify_binary_expression (tree stmt, t
   if (TREE_CODE (op1) == SSA_NAME)
     {
       if (VN_INFO (op1)->has_constants)
-	op1 = valueize_expr (VN_INFO (op1)->expr);
+	op1 = valueize_expr (vn_get_expr_for (op1));
       else if (SSA_VAL (op1) != VN_TOP && SSA_VAL (op1) != op1)
 	op1 = SSA_VAL (op1);
     }
 
   /* Avoid folding if nothing changed.  */
-  if (op0 == TREE_OPERAND (rhs, 0)
-      && op1 == TREE_OPERAND (rhs, 1))
+  if (op0 == gimple_assign_rhs1 (stmt)
+      && op1 == gimple_assign_rhs2 (stmt))
     return NULL_TREE;
 
   fold_defer_overflow_warnings ();
 
-  result = fold_binary (TREE_CODE (rhs), TREE_TYPE (rhs), op0, op1);
+  result = fold_binary (gimple_subcode (stmt),
+			TREE_TYPE (gimple_get_lhs (stmt)), op0, op1);
 
   fold_undefer_overflow_warnings (result && valid_gimple_expression_p (result),
 				  stmt, 0);
@@ -1583,24 +1777,24 @@ simplify_binary_expression (tree stmt, t
    simplified. */
 
 static tree
-simplify_unary_expression (tree rhs)
+simplify_unary_expression (gimple stmt)
 {
   tree result = NULL_TREE;
-  tree op0 = TREE_OPERAND (rhs, 0);
+  tree op0 = gimple_assign_rhs1 (stmt);
 
   if (TREE_CODE (op0) != SSA_NAME)
     return NULL_TREE;
 
   if (VN_INFO (op0)->has_constants)
-    op0 = valueize_expr (VN_INFO (op0)->expr);
-  else if (CONVERT_EXPR_P (rhs)
-	   || TREE_CODE (rhs) == REALPART_EXPR
-	   || TREE_CODE (rhs) == IMAGPART_EXPR
-	   || TREE_CODE (rhs) == VIEW_CONVERT_EXPR)
+    op0 = valueize_expr (vn_get_expr_for (op0));
+  else if (gimple_assign_cast_p (stmt)
+	   || gimple_subcode (stmt) == REALPART_EXPR
+	   || gimple_subcode (stmt) == IMAGPART_EXPR
+	   || gimple_subcode (stmt) == VIEW_CONVERT_EXPR)
     {
       /* We want to do tree-combining on conversion-like expressions.
          Make sure we feed only SSA_NAMEs or constants to fold though.  */
-      tree tem = valueize_expr (VN_INFO (op0)->expr);
+      tree tem = valueize_expr (vn_get_expr_for (op0));
       if (UNARY_CLASS_P (tem)
 	  || BINARY_CLASS_P (tem)
 	  || TREE_CODE (tem) == VIEW_CONVERT_EXPR
@@ -1610,10 +1804,11 @@ simplify_unary_expression (tree rhs)
     }
 
   /* Avoid folding if nothing changed, but remember the expression.  */
-  if (op0 == TREE_OPERAND (rhs, 0))
-    return rhs;
+  if (op0 == gimple_assign_rhs1 (stmt))
+    return NULL_TREE;
 
-  result = fold_unary (TREE_CODE (rhs), TREE_TYPE (rhs), op0);
+  result = fold_unary (gimple_subcode (stmt),
+		       TREE_TYPE (gimple_get_lhs (stmt)), op0);
   if (result)
     {
       STRIP_USELESS_TYPE_CONVERSION (result);
@@ -1621,25 +1816,26 @@ simplify_unary_expression (tree rhs)
         return result;
     }
 
-  return rhs;
+  return NULL_TREE;
 }
 
 /* Try to simplify RHS using equivalences and constant folding.  */
 
 static tree
-try_to_simplify (tree stmt, tree rhs)
+try_to_simplify (gimple stmt)
 {
   tree tem;
 
   /* For stores we can end up simplifying a SSA_NAME rhs.  Just return
      in this case, there is no point in doing extra work.  */
-  if (TREE_CODE (rhs) == SSA_NAME)
-    return rhs;
+  if (gimple_assign_copy_p (stmt)
+      && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
+    return NULL_TREE;
 
-  switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
+  switch (TREE_CODE_CLASS (gimple_subcode (stmt)))
     {
     case tcc_declaration:
-      tem = get_symbol_constant_value (rhs);
+      tem = get_symbol_constant_value (gimple_assign_rhs1 (stmt));
       if (tem)
 	return tem;
       break;
@@ -1647,29 +1843,29 @@ try_to_simplify (tree stmt, tree rhs)
     case tcc_reference:
       /* Do not do full-blown reference lookup here, but simplify
 	 reads from constant aggregates.  */
-      tem = fold_const_aggregate_ref (rhs);
+      tem = fold_const_aggregate_ref (gimple_assign_rhs1 (stmt));
       if (tem)
 	return tem;
 
       /* Fallthrough for some codes that can operate on registers.  */
-      if (!(TREE_CODE (rhs) == REALPART_EXPR
-	    || TREE_CODE (rhs) == IMAGPART_EXPR
-	    || TREE_CODE (rhs) == VIEW_CONVERT_EXPR))
+      if (!(TREE_CODE (gimple_assign_rhs1 (stmt)) == REALPART_EXPR
+	    || TREE_CODE (gimple_assign_rhs1 (stmt)) == IMAGPART_EXPR
+	    || TREE_CODE (gimple_assign_rhs1 (stmt)) == VIEW_CONVERT_EXPR))
 	break;
       /* We could do a little more with unary ops, if they expand
 	 into binary ops, but it's debatable whether it is worth it. */
     case tcc_unary:
-      return simplify_unary_expression (rhs);
+      return simplify_unary_expression (stmt);
       break;
     case tcc_comparison:
     case tcc_binary:
-      return simplify_binary_expression (stmt, rhs);
+      return simplify_binary_expression (stmt);
       break;
     default:
       break;
     }
 
-  return rhs;
+  return NULL_TREE;
 }
 
 /* Visit and value number USE, return true if the value number
@@ -1679,67 +1875,54 @@ static bool
 visit_use (tree use)
 {
   bool changed = false;
-  tree stmt = SSA_NAME_DEF_STMT (use);
-  stmt_ann_t ann;
+  gimple stmt = SSA_NAME_DEF_STMT (use);
 
   VN_INFO (use)->use_processed = true;
 
   gcc_assert (!SSA_NAME_IN_FREE_LIST (use));
   if (dump_file && (dump_flags & TDF_DETAILS)
-      && !IS_EMPTY_STMT (stmt))
+      && !SSA_NAME_IS_DEFAULT_DEF (use))
     {
       fprintf (dump_file, "Value numbering ");
       print_generic_expr (dump_file, use, 0);
       fprintf (dump_file, " stmt = ");
-      print_generic_stmt (dump_file, stmt, 0);
+      print_gimple_stmt (dump_file, stmt, 0, 0);
     }
 
-  /* RETURN_EXPR may have an embedded MODIFY_STMT.  */
-  if (TREE_CODE (stmt) == RETURN_EXPR
-      && TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT)
-    stmt = TREE_OPERAND (stmt, 0);
-
-  ann = stmt_ann (stmt);
-
   /* Handle uninitialized uses.  */
-  if (IS_EMPTY_STMT (stmt))
-    {
-      changed = set_ssa_val_to (use, use);
-    }
+  if (SSA_NAME_IS_DEFAULT_DEF (use))
+    changed = set_ssa_val_to (use, use);
   else
     {
-      if (TREE_CODE (stmt) == PHI_NODE)
-	{
-	  changed = visit_phi (stmt);
-	}
-      else if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
-	       || (ann && ann->has_volatile_ops)
-	       || tree_could_throw_p (stmt))
-	{
-	  changed = defs_to_varying (stmt);
-	}
-      else
+      if (gimple_code (stmt) == GIMPLE_PHI)
+	changed = visit_phi (stmt);
+      else if ((gimple_code (stmt) != GIMPLE_ASSIGN
+		&& (gimple_code (stmt) != GIMPLE_CALL
+		    || gimple_call_lhs (stmt) == NULL_TREE))
+	       || gimple_has_volatile_ops (stmt)
+	       || stmt_could_throw_p (stmt))
+	changed = defs_to_varying (stmt);
+      else if (gimple_code (stmt) == GIMPLE_ASSIGN)
 	{
-	  tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
-	  tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+	  tree lhs = gimple_assign_lhs (stmt);
 	  tree simplified;
 
-	  STRIP_USELESS_TYPE_CONVERSION (rhs);
-
 	  /* Shortcut for copies. Simplifying copies is pointless,
 	     since we copy the expression and value they represent.  */
-	  if (TREE_CODE (rhs) == SSA_NAME && TREE_CODE (lhs) == SSA_NAME)
+	  if (gimple_assign_copy_p (stmt)
+	      && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+	      && TREE_CODE (lhs) == SSA_NAME)
 	    {
-	      changed = visit_copy (lhs, rhs);
+	      changed = visit_copy (lhs, gimple_assign_rhs1 (stmt));
 	      goto done;
 	    }
-	  simplified = try_to_simplify (stmt, rhs);
-	  if (simplified && simplified != rhs)
+	  simplified = try_to_simplify (stmt);
+	  if (simplified)
 	    {
 	      if (dump_file && (dump_flags & TDF_DETAILS))
 		{
-		  fprintf (dump_file, "RHS ");
-		  print_generic_expr (dump_file, rhs, 0);
+		  fprintf (dump_file, "RHS of ");
+		  print_gimple_stmt (dump_file, stmt, 0, 0);
 		  fprintf (dump_file, " simplified to ");
 		  print_generic_expr (dump_file, simplified, 0);
 		  if (TREE_CODE (lhs) == SSA_NAME)
@@ -1753,16 +1936,17 @@ visit_use (tree use)
 	     screw up phi congruence because constants are not
 	     uniquely associated with a single ssa name that can be
 	     looked up.  */
-	  if (simplified && is_gimple_min_invariant (simplified)
-	      && TREE_CODE (lhs) == SSA_NAME
-	      && simplified != rhs)
+	  if (simplified
+	      && is_gimple_min_invariant (simplified)
+	      && TREE_CODE (lhs) == SSA_NAME)
 	    {
 	      VN_INFO (lhs)->expr = simplified;
 	      VN_INFO (lhs)->has_constants = true;
 	      changed = set_ssa_val_to (lhs, simplified);
 	      goto done;
 	    }
-	  else if (simplified && TREE_CODE (simplified) == SSA_NAME
+	  else if (simplified
+		   && TREE_CODE (simplified) == SSA_NAME
 		   && TREE_CODE (lhs) == SSA_NAME)
 	    {
 	      changed = visit_copy (lhs, simplified);
@@ -1777,13 +1961,10 @@ visit_use (tree use)
 		     valuizing may change the IL stream.  */
 		  VN_INFO (lhs)->expr = unshare_expr (simplified);
 		}
-	      rhs = simplified;
-	    }
-	  else if (expr_has_constants (rhs) && TREE_CODE (lhs) == SSA_NAME)
-	    {
-	      VN_INFO (lhs)->has_constants = true;
-	      VN_INFO (lhs)->expr = unshare_expr (rhs);
 	    }
+	  else if (stmt_has_constants (stmt)
+		   && TREE_CODE (lhs) == SSA_NAME)
+	    VN_INFO (lhs)->has_constants = true;
 	  else if (TREE_CODE (lhs) == SSA_NAME)
 	    {
 	      /* We reset expr and constantness here because we may
@@ -1792,56 +1973,61 @@ visit_use (tree use)
 		 even if they were optimistically constant. */
 
 	      VN_INFO (lhs)->has_constants = false;
-	      VN_INFO (lhs)->expr = lhs;
+	      VN_INFO (lhs)->expr = NULL_TREE;
 	    }
 
 	  if (TREE_CODE (lhs) == SSA_NAME
 	      /* We can substitute SSA_NAMEs that are live over
 		 abnormal edges with their constant value.  */
-	      && !is_gimple_min_invariant (rhs)
+	      && !(gimple_assign_copy_p (stmt)
+		   && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
+	      && !(simplified
+		   && is_gimple_min_invariant (simplified))
 	      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
 	    changed = defs_to_varying (stmt);
 	  else if (REFERENCE_CLASS_P (lhs) || DECL_P (lhs))
 	    {
-	      changed = visit_reference_op_store (lhs, rhs, stmt);
+	      changed = visit_reference_op_store (lhs, gimple_assign_rhs1 (stmt), stmt);
 	    }
 	  else if (TREE_CODE (lhs) == SSA_NAME)
 	    {
-	      if (is_gimple_min_invariant (rhs))
+	      if ((gimple_assign_copy_p (stmt)
+		   && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
+		  || (simplified
+		      && is_gimple_min_invariant (simplified)))
 		{
 		  VN_INFO (lhs)->has_constants = true;
-		  VN_INFO (lhs)->expr = rhs;
-		  changed = set_ssa_val_to (lhs, rhs);
+		  if (simplified)
+		    changed = set_ssa_val_to (lhs, simplified);
+		  else
+		    changed = set_ssa_val_to (lhs, gimple_assign_rhs1 (stmt));
 		}
 	      else
 		{
-		  switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
+		  switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
 		    {
-		    case tcc_unary:
-		      changed = visit_unary_op (lhs, rhs);
-		      break;
-		    case tcc_binary:
-		      changed = visit_binary_op (lhs, rhs);
-		      break;
-		      /* If tcc_vl_expr ever encompasses more than
-			 CALL_EXPR, this will need to be changed.  */
-		    case tcc_vl_exp:
-		      if (call_expr_flags (rhs)  & (ECF_PURE | ECF_CONST))
-			changed = visit_reference_op_load (lhs, rhs, stmt);
-		      else
-			changed = defs_to_varying (stmt);
+		    case GIMPLE_UNARY_RHS:
+		      changed = visit_unary_op (lhs, stmt);
 		      break;
-		    case tcc_declaration:
-		    case tcc_reference:
-		      changed = visit_reference_op_load (lhs, rhs, stmt);
+		    case GIMPLE_BINARY_RHS:
+		      changed = visit_binary_op (lhs, stmt);
 		      break;
-		    case tcc_expression:
-		      if (TREE_CODE (rhs) == ADDR_EXPR)
+		    case GIMPLE_SINGLE_RHS:
+		      switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)))
 			{
-			  changed = visit_unary_op (lhs, rhs);
-			  goto done;
+			case tcc_declaration:
+			case tcc_reference:
+			  changed = visit_reference_op_load
+			      (lhs, gimple_assign_rhs1 (stmt), stmt);
+			  break;
+			case tcc_expression:
+			  if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
+			    changed = visit_unary_op (lhs, stmt);
+			  break;
+			default:
+			  changed = defs_to_varying (stmt);
 			}
-		      /* Fallthrough.  */
+		      break;
 		    default:
 		      changed = defs_to_varying (stmt);
 		      break;
@@ -1851,6 +2037,39 @@ visit_use (tree use)
 	  else
 	    changed = defs_to_varying (stmt);
 	}
+      else if (is_gimple_call (stmt))
+	{
+	  tree lhs = gimple_call_lhs (stmt);
+
+	  /* ???  We could try to simplify calls.  */
+
+	  if (stmt_has_constants (stmt)
+	      && TREE_CODE (lhs) == SSA_NAME)
+	    VN_INFO (lhs)->has_constants = true;
+	  else if (TREE_CODE (lhs) == SSA_NAME)
+	    {
+	      /* We reset expr and constantness here because we may
+		 have been value numbering optimistically, and
+		 iterating. They may become non-constant in this case,
+		 even if they were optimistically constant. */
+	      VN_INFO (lhs)->has_constants = false;
+	      VN_INFO (lhs)->expr = NULL_TREE;
+	    }
+
+	  if (TREE_CODE (lhs) == SSA_NAME
+	      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
+	    changed = defs_to_varying (stmt);
+	  /* ???  We should handle stores from calls.  */
+	  else if (TREE_CODE (lhs) == SSA_NAME)
+	    {
+	      if (gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST))
+		changed = visit_reference_op_call (lhs, stmt);
+	      else
+		changed = defs_to_varying (stmt);
+	    }
+	  else
+	    changed = defs_to_varying (stmt);
+	}
     }
  done:
   return changed;
@@ -1863,16 +2082,16 @@ compare_ops (const void *pa, const void 
 {
   const tree opa = *((const tree *)pa);
   const tree opb = *((const tree *)pb);
-  tree opstmta = SSA_NAME_DEF_STMT (opa);
-  tree opstmtb = SSA_NAME_DEF_STMT (opb);
+  gimple opstmta = SSA_NAME_DEF_STMT (opa);
+  gimple opstmtb = SSA_NAME_DEF_STMT (opb);
   basic_block bba;
   basic_block bbb;
 
-  if (IS_EMPTY_STMT (opstmta) && IS_EMPTY_STMT (opstmtb))
+  if (gimple_nop_p (opstmta) && gimple_nop_p (opstmtb))
     return 0;
-  else if (IS_EMPTY_STMT (opstmta))
+  else if (gimple_nop_p (opstmta))
     return -1;
-  else if (IS_EMPTY_STMT (opstmtb))
+  else if (gimple_nop_p (opstmtb))
     return 1;
 
   bba = gimple_bb (opstmta);
@@ -1887,13 +2106,14 @@ compare_ops (const void *pa, const void 
 
   if (bba == bbb)
     {
-      if (TREE_CODE (opstmta) == PHI_NODE && TREE_CODE (opstmtb) == PHI_NODE)
+      if (gimple_code (opstmta) == GIMPLE_PHI
+	  && gimple_code (opstmtb) == GIMPLE_PHI)
 	return 0;
-      else if (TREE_CODE (opstmta) == PHI_NODE)
+      else if (gimple_code (opstmta) == GIMPLE_PHI)
 	return -1;
-      else if (TREE_CODE (opstmtb) == PHI_NODE)
+      else if (gimple_code (opstmtb) == GIMPLE_PHI)
 	return 1;
-      return gimple_stmt_uid (opstmta) - gimple_stmt_uid (opstmtb);
+      return gimple_uid (opstmta) - gimple_uid (opstmtb);
     }
   return rpo_numbers[bba->index] - rpo_numbers[bbb->index];
 }
@@ -2019,7 +2239,8 @@ DFS (tree name)
   VEC(ssa_op_iter, heap) *itervec = NULL;
   VEC(tree, heap) *namevec = NULL;
   use_operand_p usep = NULL;
-  tree defstmt, use;
+  gimple defstmt;
+  tree use;
   ssa_op_iter iter;
 
 start_over:
@@ -2033,10 +2254,10 @@ start_over:
   defstmt = SSA_NAME_DEF_STMT (name);
 
   /* Recursively DFS on our operands, looking for SCC's.  */
-  if (!IS_EMPTY_STMT (defstmt))
+  if (!gimple_nop_p (defstmt))
     {
       /* Push a new iterator.  */
-      if (TREE_CODE (defstmt) == PHI_NODE)
+      if (gimple_code (defstmt) == GIMPLE_PHI)
 	usep = op_iter_init_phiuse (&iter, defstmt, SSA_OP_ALL_USES);
       else
 	usep = op_iter_init_use (&iter, defstmt, SSA_OP_ALL_USES);
@@ -2286,12 +2507,12 @@ run_scc_vn (bool may_insert_arg)
 	  tree name = ssa_name (i);
 	  if (name && VN_INFO (name)->visited
 	      && (SSA_VAL (name) != name
-		  || is_gimple_min_invariant (VN_INFO (name)->expr)))
+		  || is_gimple_min_invariant (vn_get_expr_for (name))))
 	    {
 	      print_generic_expr (dump_file, name, 0);
 	      fprintf (dump_file, " = ");
-	      if (is_gimple_min_invariant (VN_INFO (name)->expr))
-		print_generic_expr (dump_file, VN_INFO (name)->expr, 0);
+	      if (is_gimple_min_invariant (vn_get_expr_for (name)))
+		print_generic_expr (dump_file, vn_get_expr_for (name), 0);
 	      else
 		print_generic_expr (dump_file, SSA_VAL (name), 0);
 	      fprintf (dump_file, "\n");
@@ -2302,4 +2523,3 @@ run_scc_vn (bool may_insert_arg)
   may_insert = false;
   return true;
 }
-#endif
Index: gcc/tree-ssa-sccvn.h
===================================================================
--- gcc/tree-ssa-sccvn.h.orig	2008-06-24 13:13:07.000000000 +0200
+++ gcc/tree-ssa-sccvn.h	2008-06-24 13:13:34.000000000 +0200
@@ -54,15 +54,18 @@ typedef struct vn_ssa_aux
 /* Return the value numbering info for an SSA_NAME.  */
 extern vn_ssa_aux_t VN_INFO (tree);
 extern vn_ssa_aux_t VN_INFO_GET (tree);
+tree vn_get_expr_for (tree);
 bool run_scc_vn (bool);
 void free_scc_vn (void);
 void switch_to_PRE_table (void);
 tree vn_nary_op_lookup (tree);
+tree vn_nary_op_lookup_stmt (gimple);
 void vn_nary_op_insert (tree, tree);
+void vn_nary_op_insert_stmt (gimple, tree);
 tree vn_reference_lookup (tree, VEC (tree, gc) *, bool);
 void vn_reference_insert (tree, tree, VEC (tree, gc) *);
-VEC (tree, gc) *shared_vuses_from_stmt (tree);
-VEC (tree, gc) *copy_vuses_from_stmt (tree);
+VEC (tree, gc) *shared_vuses_from_stmt (gimple);
+VEC (tree, gc) *copy_vuses_from_stmt (gimple);
 
 
 #endif /* TREE_SSA_SCCVN_H  */
Index: gcc/tree-dfa.c
===================================================================
--- gcc/tree-dfa.c.orig	2008-06-24 13:13:07.000000000 +0200
+++ gcc/tree-dfa.c	2008-06-24 13:22:26.000000000 +0200
@@ -1092,8 +1092,6 @@ refs_may_alias_p (tree ref1, tree ref2)
   return true;
 }
 
-/* FIXME tuples */
-#if 0
 /* 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
@@ -1102,25 +1100,25 @@ refs_may_alias_p (tree ref1, tree ref2)
    a PHI node as well.  Note that if all VUSEs are default definitions
    this function will return an empty statement.  */
 
-tree
-get_single_def_stmt (tree stmt)
+gimple
+get_single_def_stmt (gimple stmt)
 {
-  tree def_stmt = NULL_TREE;
+  gimple def_stmt = NULL;
   tree use;
   ssa_op_iter iter;
 
   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VIRTUAL_USES)
     {
-      tree tmp = SSA_NAME_DEF_STMT (use);
+      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
-	  && !(IS_EMPTY_STMT (def_stmt)
-	       && IS_EMPTY_STMT (tmp)))
-	return NULL_TREE;
+	  && !(gimple_nop_p (def_stmt)
+	       && gimple_nop_p (tmp)))
+	return NULL;
 
       def_stmt = tmp;
     }
@@ -1134,25 +1132,25 @@ get_single_def_stmt (tree stmt)
    from a non-backedge.  Returns NULL_TREE if such statement within
    the above conditions cannot be found.  */
 
-tree
-get_single_def_stmt_from_phi (tree ref, tree phi)
+gimple
+get_single_def_stmt_from_phi (tree ref, gimple phi)
 {
   tree def_arg = NULL_TREE;
-  int i;
+  unsigned i;
 
   /* Find the single PHI argument that is not flowing in from a
      back edge and verify that the loop-carried definitions do
      not alias the reference we look for.  */
-  for (i = 0; i < PHI_NUM_ARGS (phi); ++i)
+  for (i = 0; i < gimple_phi_num_args (phi); ++i)
     {
       tree arg = PHI_ARG_DEF (phi, i);
-      tree def_stmt;
+      gimple def_stmt;
 
-      if (!(PHI_ARG_EDGE (phi, i)->flags & EDGE_DFS_BACK))
+      if (!(gimple_phi_arg_edge (phi, i)->flags & EDGE_DFS_BACK))
 	{
 	  /* Multiple non-back edges?  Do not try to handle this.  */
 	  if (def_arg)
-	    return NULL_TREE;
+	    return NULL;
 	  def_arg = arg;
 	  continue;
 	}
@@ -1162,14 +1160,14 @@ get_single_def_stmt_from_phi (tree ref, 
       def_stmt = SSA_NAME_DEF_STMT (arg);
       do
 	{
-	  if (TREE_CODE (def_stmt) != GIMPLE_MODIFY_STMT
-	      || refs_may_alias_p (ref, GIMPLE_STMT_OPERAND (def_stmt, 0)))
-	    return NULL_TREE;
+	  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_TREE;
+	    return NULL;
 	}
       while (def_stmt != phi);
     }
@@ -1182,8 +1180,8 @@ get_single_def_stmt_from_phi (tree ref, 
    Take into account only definitions that alias REF if following
    back-edges when looking through a loop PHI node.  */
 
-tree
-get_single_def_stmt_with_phi (tree ref, tree stmt)
+gimple
+get_single_def_stmt_with_phi (tree ref, gimple stmt)
 {
   switch (NUM_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_USES))
     {
@@ -1192,11 +1190,11 @@ get_single_def_stmt_with_phi (tree ref, 
 
     case 1:
       {
-	tree def_stmt = SSA_NAME_DEF_STMT (SINGLE_SSA_TREE_OPERAND
+	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 (TREE_CODE (def_stmt) == PHI_NODE)
+	if (gimple_code (def_stmt) == GIMPLE_PHI)
 	  return get_single_def_stmt_from_phi (ref, def_stmt);
 	return def_stmt;
       }
@@ -1205,4 +1203,3 @@ get_single_def_stmt_with_phi (tree ref, 
       return get_single_def_stmt (stmt);
     }
 }
-#endif
Index: gcc/tree-ssa-pre.c
===================================================================
--- gcc/tree-ssa-pre.c.orig	2008-06-24 13:13:07.000000000 +0200
+++ gcc/tree-ssa-pre.c	2008-06-24 15:50:55.000000000 +0200
@@ -3583,7 +3583,7 @@ do_SCCVN_insertion (tree stmt, tree ssa_
 
   /* First create a value expression from the expression we want
      to insert and associate it with the value handle for SSA_VN.  */
-  expr = create_value_expr_from (VN_INFO (ssa_vn)->expr, bb, NULL, true);
+  expr = create_value_expr_from (vn_get_expr_for (ssa_vn), bb, NULL, true);
   if (expr == NULL_TREE)
     return NULL_TREE;
   set_value_handle (expr, get_value_handle (ssa_vn));
@@ -3641,7 +3641,7 @@ eliminate (void)
 		  tree val = VN_INFO (lhs)->valnum;
 		  if (val != VN_TOP
 		      && VN_INFO (val)->needs_insertion
-		      && can_PRE_operation (VN_INFO (val)->expr))
+		      && can_PRE_operation (vn_get_expr_for (val)))
 		    sprime = do_SCCVN_insertion (stmt, val);
 		}
 
@@ -3972,6 +3972,10 @@ static unsigned int
 execute_pre (bool do_fre ATTRIBUTE_UNUSED)
 {
   /* FIXME tuples.  */
+  if (run_scc_vn (do_fre))
+    free_scc_vn ();
+
+  /* FIXME tuples.  */
 #if 0
   unsigned int todo = 0;
 
@@ -4038,8 +4042,6 @@ execute_pre (bool do_fre ATTRIBUTE_UNUSE
   fini_pre ();
 
   return todo;
-#else
-  gimple_unreachable ();
 #endif
   return 0;
 }
@@ -4091,12 +4093,7 @@ execute_fre (void)
 static bool
 gate_fre (void)
 {
-  /* FIXME tuples */
-#if 0
   return flag_tree_fre != 0;
-#else
-  return 0;
-#endif
 }
 
 struct gimple_opt_pass pass_fre =
Index: gcc/tree-flow.h
===================================================================
--- gcc/tree-flow.h.orig	2008-06-24 13:13:07.000000000 +0200
+++ gcc/tree-flow.h	2008-06-24 13:57:37.000000000 +0200
@@ -775,9 +775,9 @@ extern void set_default_def (tree, tree)
 extern tree gimple_default_def (struct function *, tree);
 extern bool stmt_references_abnormal_ssa_name (gimple);
 extern bool refs_may_alias_p (tree, tree);
-extern tree get_single_def_stmt (tree);
-extern tree get_single_def_stmt_from_phi (tree, tree);
-extern tree get_single_def_stmt_with_phi (tree, tree);
+extern gimple get_single_def_stmt (gimple);
+extern gimple get_single_def_stmt_from_phi (tree, gimple);
+extern gimple get_single_def_stmt_with_phi (tree, gimple);
 
 /* In tree-phinodes.c  */
 extern void reserve_phi_args_for_new_edge (basic_block);
@@ -1093,11 +1093,11 @@ static inline tree get_value_handle (tre
 void sort_vuses (VEC (tree, gc) *);
 void sort_vuses_heap (VEC (tree, heap) *);
 tree vn_lookup_or_add (tree);
-tree vn_lookup_or_add_with_stmt (tree, tree);
+tree vn_lookup_or_add_with_stmt (tree, gimple);
 tree vn_lookup_or_add_with_vuses (tree, VEC (tree, gc) *);
 void vn_add (tree, tree);
 void vn_add_with_vuses (tree, tree, VEC (tree, gc) *);
-tree vn_lookup_with_stmt (tree, tree);
+tree vn_lookup_with_stmt (tree, gimple);
 tree vn_lookup (tree);
 tree vn_lookup_with_vuses (tree, VEC (tree, gc) *);
 
Index: gcc/gimple.c
===================================================================
--- gcc/gimple.c.orig	2008-06-24 13:13:07.000000000 +0200
+++ gcc/gimple.c	2008-06-24 14:53:15.000000000 +0200
@@ -1878,8 +1878,6 @@ gimple_set_bb (gimple stmt, basic_block 
 tree
 gimple_fold (const_gimple stmt)
 {
-  tree t;
-
   switch (gimple_code (stmt))
     {
     case GIMPLE_COND:
@@ -1887,28 +1885,30 @@ gimple_fold (const_gimple stmt)
 			  boolean_type_node,
 			  gimple_cond_lhs (stmt),
 			  gimple_cond_rhs (stmt));
-      break;
 
     case GIMPLE_ASSIGN:
-      if (gimple_num_ops (stmt) > 2)
-	return fold_binary (gimple_assign_rhs_code (stmt),
-			    TREE_TYPE (gimple_assign_lhs (stmt)),
-			    gimple_assign_rhs1 (stmt),
-			    gimple_assign_rhs2 (stmt));
-      else
-	return fold_unary (gimple_assign_rhs_code (stmt),
-			   TREE_TYPE (gimple_assign_lhs (stmt)),
-			   gimple_assign_rhs1 (stmt));
+      switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
+	{
+	case GIMPLE_UNARY_RHS:
+	  return fold_unary (gimple_assign_rhs_code (stmt),
+			     TREE_TYPE (gimple_assign_lhs (stmt)),
+			     gimple_assign_rhs1 (stmt));
+	case GIMPLE_BINARY_RHS:
+	  return fold_binary (gimple_assign_rhs_code (stmt),
+			      TREE_TYPE (gimple_assign_lhs (stmt)),
+			      gimple_assign_rhs1 (stmt),
+			      gimple_assign_rhs2 (stmt));
+	case GIMPLE_SINGLE_RHS:
+	  return fold (gimple_assign_rhs1 (stmt));
+	default:;
+	}
       break;
 
     case GIMPLE_SWITCH:
       return gimple_switch_index (stmt);
-      break;
 
     case GIMPLE_CALL:
-      t = gimple_call_fn (stmt);
-      return fold_unary (TREE_CODE (t), TREE_TYPE (t), t);
-      break;
+      return NULL_TREE;
 
     default:
       break;
Index: gcc/tree-vn.c
===================================================================
--- gcc/tree-vn.c.orig	2008-06-24 13:13:33.000000000 +0200
+++ gcc/tree-vn.c	2008-06-24 13:57:00.000000000 +0200
@@ -208,8 +208,11 @@ vn_add (tree expr, tree val)
       gcc_unreachable ();
     }
   set_value_handle (expr, val);
+  /* FIXME: tuples.  */
+#if 0
   if (TREE_CODE (val) == VALUE_HANDLE)
     add_to_value (val, expr);
+#endif
 }
 
 /* Insert EXPR into the value numbering tables with value VAL, and
@@ -228,8 +231,11 @@ vn_add_with_vuses (tree expr, tree val, 
   vn_reference_insert (expr, val, vuses);
 
   set_value_handle (expr, val);
+  /* FIXME: tuples.  */
+#if 0
   if (TREE_CODE (val) == VALUE_HANDLE)
     add_to_value (val, expr);
+#endif
 }
 
 
@@ -281,7 +287,7 @@ vn_lookup (tree expr)
    hash value for EXPR for reference operations.  */
 
 tree
-vn_lookup_with_stmt (tree expr, tree stmt)
+vn_lookup_with_stmt (tree expr, gimple stmt)
 {
   if (stmt == NULL)
     return vn_lookup (expr);
@@ -347,7 +353,7 @@ vn_lookup_or_add (tree expr)
    STMT to get the set of vuses.  */
 
 tree
-vn_lookup_or_add_with_stmt (tree expr, tree stmt)
+vn_lookup_or_add_with_stmt (tree expr, gimple stmt)
 {
   tree v;
   if (!stmt)


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