diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index b055a43..ed56d1d 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1698,33 +1698,73 @@ vn_nary_op_eq (const void *p1, const void *p2)
   return true;
 }
 
-/* Lookup a n-ary operation by its pieces 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 or if the result field of the operation
-   is NULL. VNRESULT will contain the vn_nary_op_t from the hashtable
-   if it exists.  */
+/* Initialize VNO from the pieces provided.  */
 
-tree
-vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code,
-			  tree type, tree op0, tree op1, tree op2,
-			  tree op3, vn_nary_op_t *vnresult)
+static void
+init_vn_nary_op_from_pieces (vn_nary_op_t vno, unsigned int length,
+			     enum tree_code code, tree type, tree op0,
+			     tree op1, tree op2, tree op3)
+{
+  vno->opcode = code;
+  vno->length = length;
+  vno->type = type;
+  vno->op[0] = op0;
+  vno->op[1] = op1;
+  vno->op[2] = op2;
+  vno->op[3] = op3;
+}
+
+/* Initialize VNO from OP.  */
+
+static void
+init_vn_nary_op_from_op (vn_nary_op_t vno, tree op)
+{
+  unsigned i;
+
+  vno->opcode = TREE_CODE (op);
+  vno->length = TREE_CODE_LENGTH (TREE_CODE (op));
+  vno->type = TREE_TYPE (op);
+  for (i = 0; i < vno->length; ++i)
+    vno->op[i] = TREE_OPERAND (op, i);
+}
+
+/* Initialize VNO from STMT.  */
+
+static void
+init_vn_nary_op_from_stmt (vn_nary_op_t vno, gimple stmt)
+{
+  unsigned i;
+
+  vno->opcode = gimple_assign_rhs_code (stmt);
+  vno->length = gimple_num_ops (stmt) - 1;
+  vno->type = gimple_expr_type (stmt);
+  for (i = 0; i < vno->length; ++i)
+    vno->op[i] = gimple_op (stmt, i + 1);
+  if (vno->opcode == REALPART_EXPR
+      || vno->opcode == IMAGPART_EXPR
+      || vno->opcode == VIEW_CONVERT_EXPR)
+    vno->op[0] = TREE_OPERAND (vno->op[0], 0);
+}
+
+/* Compute the hashcode for VNO and look for it in the hash table;
+   return the resulting value number if it exists in the hash table.
+   Return NULL_TREE if it does not exist in the hash table or if the
+   result field of the operation is NULL.  VNRESULT will contain the
+   vn_nary_op_t from the hashtable if it exists.  */
+
+static tree
+vn_nary_op_lookup_1 (vn_nary_op_t vno, vn_nary_op_t *vnresult)
 {
   void **slot;
-  struct vn_nary_op_s vno1;
+
   if (vnresult)
     *vnresult = NULL;
-  vno1.opcode = code;
-  vno1.length = length;
-  vno1.type = type;
-  vno1.op[0] = op0;
-  vno1.op[1] = op1;
-  vno1.op[2] = op2;
-  vno1.op[3] = op3;
-  vno1.hashcode = vn_nary_op_compute_hash (&vno1);
-  slot = htab_find_slot_with_hash (current_info->nary, &vno1, vno1.hashcode,
+
+  vno->hashcode = vn_nary_op_compute_hash (vno);
+  slot = htab_find_slot_with_hash (current_info->nary, vno, vno->hashcode,
 				   NO_INSERT);
   if (!slot && current_info == optimistic_info)
-    slot = htab_find_slot_with_hash (valid_info->nary, &vno1, vno1.hashcode,
+    slot = htab_find_slot_with_hash (valid_info->nary, vno, vno->hashcode,
 				     NO_INSERT);
   if (!slot)
     return NULL_TREE;
@@ -1733,6 +1773,22 @@ vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code,
   return ((vn_nary_op_t)*slot)->result;
 }
 
+/* Lookup a n-ary operation by its pieces 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 or if the result field of the operation
+   is NULL. VNRESULT will contain the vn_nary_op_t from the hashtable
+   if it exists.  */
+
+tree
+vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code,
+			  tree type, tree op0, tree op1, tree op2,
+			  tree op3, vn_nary_op_t *vnresult)
+{
+  struct vn_nary_op_s vno1;
+  init_vn_nary_op_from_pieces (&vno1, length, code, type, op0, op1, op2, op3);
+  return vn_nary_op_lookup_1 (&vno1, vnresult);
+}
+
 /* Lookup OP 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 or if the result field of the operation
@@ -1742,28 +1798,9 @@ vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code,
 tree
 vn_nary_op_lookup (tree op, vn_nary_op_t *vnresult)
 {
-  void **slot;
   struct vn_nary_op_s vno1;
-  unsigned i;
-
-  if (vnresult)
-    *vnresult = NULL;
-  vno1.opcode = TREE_CODE (op);
-  vno1.length = TREE_CODE_LENGTH (TREE_CODE (op));
-  vno1.type = TREE_TYPE (op);
-  for (i = 0; i < vno1.length; ++i)
-    vno1.op[i] = TREE_OPERAND (op, i);
-  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;
-  if (vnresult)
-    *vnresult = (vn_nary_op_t)*slot;
-  return ((vn_nary_op_t)*slot)->result;
+  init_vn_nary_op_from_op (&vno1, op);
+  return vn_nary_op_lookup_1 (&vno1, vnresult);
 }
 
 /* Lookup the rhs of STMT in the current hash table, and return the resulting
@@ -1774,32 +1811,59 @@ vn_nary_op_lookup (tree op, vn_nary_op_t *vnresult)
 tree
 vn_nary_op_lookup_stmt (gimple stmt, vn_nary_op_t *vnresult)
 {
-  void **slot;
   struct vn_nary_op_s vno1;
-  unsigned i;
+  init_vn_nary_op_from_stmt (&vno1, stmt);
+  return vn_nary_op_lookup_1 (&vno1, vnresult);
+}
 
-  if (vnresult)
-    *vnresult = NULL;
-  vno1.opcode = gimple_assign_rhs_code (stmt);
-  vno1.length = gimple_num_ops (stmt) - 1;
-  vno1.type = gimple_expr_type (stmt);
-  for (i = 0; i < vno1.length; ++i)
-    vno1.op[i] = gimple_op (stmt, i + 1);
-  if (vno1.opcode == REALPART_EXPR
-      || vno1.opcode == IMAGPART_EXPR
-      || vno1.opcode == VIEW_CONVERT_EXPR)
-    vno1.op[0] = TREE_OPERAND (vno1.op[0], 0);
-  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;
-  if (vnresult)
-    *vnresult = (vn_nary_op_t)*slot;
-  return ((vn_nary_op_t)*slot)->result;
+/* Return the size of a vn_nary_op_t with LENGTH operands.  */
+
+static size_t
+sizeof_vn_nary_op (unsigned int length)
+{
+  return sizeof (struct vn_nary_op_s) - sizeof (tree) * (4 - length);
+}
+
+/* Allocate a vn_nary_op_t with LENGTH operands on STACK.  */
+
+static vn_nary_op_t
+alloc_vn_nary_op_noinit (unsigned int length, struct obstack *stack)
+{
+  return (vn_nary_op_t) obstack_alloc (stack, sizeof_vn_nary_op (length));
+}
+
+/* Allocate and initialize a vn_nary_op_t on CURRENT_INFO's
+   obstack.  */
+
+static vn_nary_op_t
+alloc_vn_nary_op (unsigned int length, tree result, unsigned int value_id)
+{
+  vn_nary_op_t vno1 = alloc_vn_nary_op_noinit (length,
+					       &current_info->nary_obstack);
+
+  vno1->value_id = value_id;
+  vno1->length = length;
+  vno1->result = result;
+
+  return vno1;
+}
+
+/* Insert VNO into TABLE.  If COMPUTE_HASH is true, then compute
+   VNO->HASHCODE first.  */
+
+static vn_nary_op_t
+vn_nary_op_insert_into (vn_nary_op_t vno, htab_t table, bool compute_hash)
+{
+  void **slot;
+
+  if (compute_hash)
+    vno->hashcode = vn_nary_op_compute_hash (vno);
+
+  slot = htab_find_slot_with_hash (table, vno, vno->hashcode, INSERT);
+  gcc_assert (!*slot);
+
+  *slot = vno;
+  return vno;
 }
 
 /* Insert a n-ary operation into the current hash table using it's
@@ -1813,33 +1877,11 @@ vn_nary_op_insert_pieces (unsigned int length, enum tree_code code,
 			  tree result,
 			  unsigned int value_id)
 {
-  void **slot;
   vn_nary_op_t vno1;
 
-  vno1 = (vn_nary_op_t) obstack_alloc (&current_info->nary_obstack,
-				       (sizeof (struct vn_nary_op_s)
-					- sizeof (tree) * (4 - length)));
-  vno1->value_id = value_id;
-  vno1->opcode = code;
-  vno1->length = length;
-  vno1->type = type;
-  if (length >= 1)
-    vno1->op[0] = op0;
-  if (length >= 2)
-    vno1->op[1] = op1;
-  if (length >= 3)
-    vno1->op[2] = op2;
-  if (length >= 4)
-    vno1->op[3] = op3;
-  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;
-  return vno1;
-
+  vno1 = alloc_vn_nary_op (length, result, value_id);
+  init_vn_nary_op_from_pieces (vno1, length, code, type, op0, op1, op2, op3);
+  return vn_nary_op_insert_into (vno1, current_info->nary, true);
 }
 
 /* Insert OP into the current hash table with a value number of
@@ -1850,27 +1892,11 @@ vn_nary_op_t
 vn_nary_op_insert (tree op, tree result)
 {
   unsigned length = TREE_CODE_LENGTH (TREE_CODE (op));
-  void **slot;
   vn_nary_op_t vno1;
-  unsigned i;
 
-  vno1 = (vn_nary_op_t) obstack_alloc (&current_info->nary_obstack,
-			(sizeof (struct vn_nary_op_s)
-			 - sizeof (tree) * (4 - length)));
-  vno1->value_id = VN_INFO (result)->value_id;
-  vno1->opcode = TREE_CODE (op);
-  vno1->length = length;
-  vno1->type = TREE_TYPE (op);
-  for (i = 0; i < vno1->length; ++i)
-    vno1->op[i] = TREE_OPERAND (op, i);
-  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;
-  return vno1;
+  vno1 = alloc_vn_nary_op (length, result, VN_INFO (result)->value_id);
+  init_vn_nary_op_from_op (vno1, op);
+  return vn_nary_op_insert_into (vno1, current_info->nary, true);
 }
 
 /* Insert the rhs of STMT into the current hash table with a value number of
@@ -1880,31 +1906,11 @@ vn_nary_op_t
 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 = (vn_nary_op_t) obstack_alloc (&current_info->nary_obstack,
-				       (sizeof (struct vn_nary_op_s)
-					- sizeof (tree) * (4 - length)));
-  vno1->value_id = VN_INFO (result)->value_id;
-  vno1->opcode = gimple_assign_rhs_code (stmt);
-  vno1->length = length;
-  vno1->type = gimple_expr_type (stmt);
-  for (i = 0; i < vno1->length; ++i)
-    vno1->op[i] = gimple_op (stmt, i + 1);
-  if (vno1->opcode == REALPART_EXPR
-      || vno1->opcode == IMAGPART_EXPR
-      || vno1->opcode == VIEW_CONVERT_EXPR)
-    vno1->op[0] = TREE_OPERAND (vno1->op[0], 0);
-  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;
-  return vno1;
+  vno1 = alloc_vn_nary_op (length, result, VN_INFO (result)->value_id);
+  init_vn_nary_op_from_stmt (vno1, stmt);
+  return vn_nary_op_insert_into (vno1, current_info->nary, true);
 }
 
 /* Compute a hashcode for PHI operation VP1 and return it.  */
@@ -3043,14 +3049,11 @@ sort_scc (VEC (tree, heap) *scc)
 static void
 copy_nary (vn_nary_op_t onary, vn_tables_t info)
 {
-  size_t size = (sizeof (struct vn_nary_op_s)
-		 - sizeof (tree) * (4 - onary->length));
-  vn_nary_op_t nary = (vn_nary_op_t) obstack_alloc (&info->nary_obstack, size);
-  void **slot;
+  size_t size = sizeof_vn_nary_op (onary->length);
+  vn_nary_op_t nary = alloc_vn_nary_op_noinit (onary->length,
+					       &info->nary_obstack);
   memcpy (nary, onary, size);
-  slot = htab_find_slot_with_hash (info->nary, nary, nary->hashcode, INSERT);
-  gcc_assert (!*slot);
-  *slot = nary;
+  vn_nary_op_insert_into (nary, info->nary, false);
 }
 
 /* Insert the no longer used phi OPHI to the hash INFO.  */
@@ -3414,6 +3417,20 @@ free_scc_vn (void)
   XDELETE (optimistic_info);
 }
 
+/* Set *ID if we computed something useful in RESULT.  */
+
+static void
+set_value_id_for_result (tree result, unsigned int *id)
+{
+  if (result)
+    {
+      if (TREE_CODE (result) == SSA_NAME)
+	*id = VN_INFO (result)->value_id;
+      else if (is_gimple_min_invariant (result))
+	*id = get_or_alloc_constant_value_id (result);
+    }
+}
+
 /* Set the value ids in the valid hash tables.  */
 
 static void
@@ -3429,39 +3446,15 @@ set_hashtable_value_ids (void)
 
   FOR_EACH_HTAB_ELEMENT (valid_info->nary,
 			 vno, vn_nary_op_t, hi)
-    {
-      if (vno->result)
-	{
-	  if (TREE_CODE (vno->result) == SSA_NAME)
-	    vno->value_id = VN_INFO (vno->result)->value_id;
-	  else if (is_gimple_min_invariant (vno->result))
-	    vno->value_id = get_or_alloc_constant_value_id (vno->result);
-	}
-    }
+    set_value_id_for_result (vno->result, &vno->value_id);
 
   FOR_EACH_HTAB_ELEMENT (valid_info->phis,
 			 vp, vn_phi_t, hi)
-    {
-      if (vp->result)
-	{
-	  if (TREE_CODE (vp->result) == SSA_NAME)
-	    vp->value_id = VN_INFO (vp->result)->value_id;
-	  else if (is_gimple_min_invariant (vp->result))
-	    vp->value_id = get_or_alloc_constant_value_id (vp->result);
-	}
-    }
+    set_value_id_for_result (vp->result, &vp->value_id);
 
   FOR_EACH_HTAB_ELEMENT (valid_info->references,
 			 vr, vn_reference_t, hi)
-    {
-      if (vr->result)
-	{
-	  if (TREE_CODE (vr->result) == SSA_NAME)
-	    vr->value_id = VN_INFO (vr->result)->value_id;
-	  else if (is_gimple_min_invariant (vr->result))
-	    vr->value_id = get_or_alloc_constant_value_id (vr->result);
-	}
-    }
+    set_value_id_for_result (vr->result, &vr->value_id);
 }
 
 /* Do SCCVN.  Returns true if it finished, false if we bailed out
