diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d0e34c8c45fe7f7eb9671b1b11f219966a803003..fd231baa49680d14cfb0550837070e063409bb7a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2005-09-27  Jeff Law  <law@redhat.com>
+
+	* passes.c (init_optimization_passes): Replace copy propagation
+	passes immediately after DOM with phi-only copy propagation
+	pases.  Add phi-only copy propagation pass after first DOM pass.
+	* tree-pass.h (pass_phi_only_copy_prop): Declare.
+	* tree-ssa-copy.c (init_copy_prop): Accept new PHI_ONLY argument.
+	If true, then mark all non-control statements with DONT_SIMULATE_AGAIN.
+	(execute_copy_prop): Accept new PHI_ONLY argument.  Pass it along
+	to init_copy_prop.  Callers updated.
+	(do_phi_only_copy_prop): New function.
+	(pass_phi_only_copy_prop): New pass descriptor.
+
 2005-09-27  Nick Clifton  <nickc@redhat.com>
 
 	* libgcc2.c (__popcount_tab): Remove redundant prototype.
diff --git a/gcc/passes.c b/gcc/passes.c
index 6a35b1750a7cbe14e62c320f0b15c6aa049a40c4..b03eae39f4398033943c2baebb4cf7053c545432 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -494,6 +494,12 @@ init_optimization_passes (void)
   NEXT_PASS (pass_merge_phi);
   NEXT_PASS (pass_dominator);
 
+  /* The only copy propagation opportunities left after DOM
+     should be due to degenerate PHI nodes.  So rather than
+     run the full copy propagator, just discover and copy
+     propagate away the degenerate PHI nodes.  */
+  NEXT_PASS (pass_phi_only_copy_prop);
+
   NEXT_PASS (pass_phiopt);
   NEXT_PASS (pass_may_alias);
   NEXT_PASS (pass_tail_recursion);
@@ -508,7 +514,13 @@ init_optimization_passes (void)
   NEXT_PASS (pass_may_alias);
   NEXT_PASS (pass_rename_ssa_copies);
   NEXT_PASS (pass_dominator);
-  NEXT_PASS (pass_copy_prop);
+
+  /* The only copy propagation opportunities left after DOM
+     should be due to degenerate PHI nodes.  So rather than
+     run the full copy propagator, just discover and copy
+     propagate away the degenerate PHI nodes.  */
+  NEXT_PASS (pass_phi_only_copy_prop);
+
   NEXT_PASS (pass_dce);
   NEXT_PASS (pass_dse);
   NEXT_PASS (pass_may_alias);
@@ -529,7 +541,13 @@ init_optimization_passes (void)
   NEXT_PASS (pass_sink_code);
   NEXT_PASS (pass_tree_loop);
   NEXT_PASS (pass_dominator);
-  NEXT_PASS (pass_copy_prop);
+
+  /* The only copy propagation opportunities left after DOM
+     should be due to degenerate PHI nodes.  So rather than
+     run the full copy propagator, just discover and copy
+     propagate away the degenerate PHI nodes.  */
+  NEXT_PASS (pass_phi_only_copy_prop);
+
   NEXT_PASS (pass_cd_dce);
 
   /* FIXME: If DCE is not run before checking for uninitialized uses,
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 57dc029438eeea05da849250a3cebb600819dc22..6674884944a7f4a01d384dad7bd9c2e4fee04fd4 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -275,6 +275,7 @@ extern struct tree_opt_pass pass_sink_code;
 extern struct tree_opt_pass pass_fre;
 extern struct tree_opt_pass pass_linear_transform;
 extern struct tree_opt_pass pass_copy_prop;
+extern struct tree_opt_pass pass_phi_only_copy_prop;
 extern struct tree_opt_pass pass_store_ccp;
 extern struct tree_opt_pass pass_store_copy_prop;
 extern struct tree_opt_pass pass_vrp;
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 47ac55f3b5fad14f347c6c560be12905c8fd2933..575fe09d6e47ece6aadb1bee23f6bee5be2a213e 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -838,10 +838,12 @@ copy_prop_visit_phi_node (tree phi)
 }
 
 
-/* Initialize structures used for copy propagation.  */
+/* Initialize structures used for copy propagation.   PHIS_ONLY is true
+   if we should only consider PHI nodes as generating copy propagation
+   opportunities.  */
 
 static void
-init_copy_prop (void)
+init_copy_prop (bool phis_only)
 {
   basic_block bb;
 
@@ -866,7 +868,7 @@ init_copy_prop (void)
 	     lists of the propagator.  */
 	  if (stmt_ends_bb_p (stmt))
 	    DONT_SIMULATE_AGAIN (stmt) = false;
-	  else if (stmt_may_generate_copy (stmt))
+	  else if (!phis_only && stmt_may_generate_copy (stmt))
 	    DONT_SIMULATE_AGAIN (stmt) = false;
 	  else
 	    {
@@ -917,10 +919,15 @@ fini_copy_prop (void)
 }
 
 
-/* Main entry point to the copy propagator.  The algorithm propagates
-   the value COPY-OF using ssa_propagate.  For every variable X_i,
-   COPY-OF(X_i) indicates which variable is X_i created from.  The
-   following example shows how the algorithm proceeds at a high level:
+/* Main entry point to the copy propagator.
+
+   PHIS_ONLY is true if we should only consider PHI nodes as generating
+   copy propagation opportunities. 
+
+   The algorithm propagates the value COPY-OF using ssa_propagate.  For
+   every variable X_i, COPY-OF(X_i) indicates which variable is X_i created
+   from.  The following example shows how the algorithm proceeds at a
+   high level:
 
 	    1	a_24 = x_1
 	    2	a_2 = PHI <a_24, x_1>
@@ -1020,10 +1027,10 @@ fini_copy_prop (void)
    x_53 and x_54 are both copies of x_898.  */
 
 static void
-execute_copy_prop (bool store_copy_prop)
+execute_copy_prop (bool store_copy_prop, bool phis_only)
 {
   do_store_copy_prop = store_copy_prop;
-  init_copy_prop ();
+  init_copy_prop (phis_only);
   ssa_propagate (copy_prop_visit_stmt, copy_prop_visit_phi_node);
   fini_copy_prop ();
 }
@@ -1038,7 +1045,7 @@ gate_copy_prop (void)
 static void
 do_copy_prop (void)
 {
-  execute_copy_prop (false);
+  execute_copy_prop (false, false);
 }
 
 struct tree_opt_pass pass_copy_prop =
@@ -1063,6 +1070,34 @@ struct tree_opt_pass pass_copy_prop =
 };
 
 
+static void
+do_phi_only_copy_prop (void)
+{
+  execute_copy_prop (false, true);
+}
+
+struct tree_opt_pass pass_phi_only_copy_prop =
+{
+  "phionlycopyprop",			/* name */
+  gate_copy_prop,			/* gate */
+  do_phi_only_copy_prop,		/* execute */
+  NULL,					/* sub */
+  NULL,					/* next */
+  0,					/* static_pass_number */
+  TV_TREE_COPY_PROP,			/* tv_id */
+  PROP_ssa | PROP_alias | PROP_cfg,	/* properties_required */
+  0,					/* properties_provided */
+  0,					/* properties_destroyed */
+  0,					/* todo_flags_start */
+  TODO_cleanup_cfg
+    | TODO_dump_func
+    | TODO_ggc_collect
+    | TODO_verify_ssa
+    | TODO_update_ssa,			/* todo_flags_finish */
+  0					/* letter */
+};
+
+
 static bool
 gate_store_copy_prop (void)
 {
@@ -1077,7 +1112,7 @@ static void
 store_copy_prop (void)
 {
   /* If STORE-COPY-PROP is not enabled, we just run regular COPY-PROP.  */
-  execute_copy_prop (flag_tree_store_copy_prop != 0);
+  execute_copy_prop (flag_tree_store_copy_prop != 0, false);
 }
 
 struct tree_opt_pass pass_store_copy_prop =