diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index f924fb8..990c4e9 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1428,7 +1428,6 @@ OBJS = \
 	tree-ssa-ccp.o \
 	tree-ssa-coalesce.o \
 	tree-ssa-copy.o \
-	tree-ssa-copyrename.o \
 	tree-ssa-dce.o \
 	tree-ssa-dom.o \
 	tree-ssa-dse.o \
diff --git a/gcc/common.opt b/gcc/common.opt
index b49ac46..fefaee7 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2207,16 +2207,16 @@ Common Report Var(flag_tree_ch) Optimization
 Enable loop header copying on trees
 
 ftree-coalesce-inlined-vars
-Common Report Var(flag_ssa_coalesce_vars,1) Init(2) RejectNegative Optimization
-Enable coalescing of copy-related user variables that are inlined
+Common Ignore RejectNegative
+Does nothing.  Preserved for backward compatibility.
 
 ftree-coalesce-vars
-Common Report Var(flag_ssa_coalesce_vars,2) Optimization
-Enable coalescing of all copy-related user variables
+Common Ignore
+Does nothing.  Preserved for backward compatibility.
 
 ftree-copyrename
-Common Report Var(flag_tree_copyrename) Optimization
-Replace SSA temporaries with better names in copies
+Common Ignore
+Does nothing.  Preserved for backward compatibility.
 
 ftree-copy-prop
 Common Report Var(flag_tree_copy_prop) Optimization
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 9749727..5d2c516 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -442,8 +442,7 @@ Objective-C and Objective-C++ Dialects}.
 -fstack-protector-explicit -fstdarg-opt -fstrict-aliasing @gol
 -fstrict-overflow -fthread-jumps -ftracer -ftree-bit-ccp @gol
 -ftree-builtin-call-dce -ftree-ccp -ftree-ch @gol
--ftree-coalesce-inline-vars -ftree-coalesce-vars -ftree-copy-prop @gol
--ftree-copyrename -ftree-dce -ftree-dominator-opts -ftree-dse @gol
+-ftree-copy-prop -ftree-dce -ftree-dominator-opts -ftree-dse @gol
 -ftree-forwprop -ftree-fre -ftree-loop-if-convert @gol
 -ftree-loop-if-convert-stores -ftree-loop-im @gol
 -ftree-phiprop -ftree-loop-distribution -ftree-loop-distribute-patterns @gol
@@ -8822,32 +8821,6 @@ Perform scalar replacement of aggregates.  This pass replaces structure
 references with scalars to prevent committing structures to memory too
 early.  This flag is enabled by default at @option{-O} and higher.
 
-@item -ftree-copyrename
-@opindex ftree-copyrename
-Perform copy renaming on trees.  This pass attempts to rename compiler
-temporaries to other variables at copy locations, usually resulting in
-variable names which more closely resemble the original variables.  This flag
-is enabled by default at @option{-O} and higher.
-
-@item -ftree-coalesce-inlined-vars
-@opindex ftree-coalesce-inlined-vars
-Tell the copyrename pass (see @option{-ftree-copyrename}) to attempt to
-combine small user-defined variables too, but only if they are inlined
-from other functions.  It is a more limited form of
-@option{-ftree-coalesce-vars}.  This may harm debug information of such
-inlined variables, but it keeps variables of the inlined-into
-function apart from each other, such that they are more likely to
-contain the expected values in a debugging session.
-
-@item -ftree-coalesce-vars
-@opindex ftree-coalesce-vars
-Tell the copyrename pass (see @option{-ftree-copyrename}) to attempt to
-combine small user-defined variables too, instead of just compiler
-temporaries.  This may severely limit the ability to debug an optimized
-program compiled with @option{-fno-var-tracking-assignments}.  In the
-negated form, this flag prevents SSA coalescing of user variables,
-including inlined ones.  This option is enabled by default.
-
 @item -ftree-ter
 @opindex ftree-ter
 Perform temporary expression replacement during the SSA->normal phase.  Single
diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c
index efc93b7..62ae577 100644
--- a/gcc/gimple-expr.c
+++ b/gcc/gimple-expr.c
@@ -399,13 +399,14 @@ copy_var_decl (tree var, tree name, tree type)
 bool
 gimple_can_coalesce_p (tree name1, tree name2)
 {
-  /* First check the SSA_NAME's associated DECL.  We only want to
-     coalesce if they have the same DECL or both have no associated DECL.  */
+  /* First check the SSA_NAME's associated DECL.  Without
+     optimization, we only want to coalesce if they have the same DECL
+     or both have no associated DECL.  */
   tree var1 = SSA_NAME_VAR (name1);
   tree var2 = SSA_NAME_VAR (name2);
   var1 = (var1 && (!VAR_P (var1) || !DECL_IGNORED_P (var1))) ? var1 : NULL_TREE;
   var2 = (var2 && (!VAR_P (var2) || !DECL_IGNORED_P (var2))) ? var2 : NULL_TREE;
-  if (var1 != var2)
+  if (var1 != var2 && !optimize)
     return false;
 
   /* Now check the types.  If the types are the same, then we should
diff --git a/gcc/opts.c b/gcc/opts.c
index 39c190d..8149421 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -453,7 +453,6 @@ static const struct default_options default_options_table[] =
     { OPT_LEVELS_1_PLUS, OPT_ftree_dse, NULL, 1 },
     { OPT_LEVELS_1_PLUS, OPT_ftree_ter, NULL, 1 },
     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_sra, NULL, 1 },
-    { OPT_LEVELS_1_PLUS, OPT_ftree_copyrename, NULL, 1 },
     { OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 },
     { OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 },
     { OPT_LEVELS_1_PLUS, OPT_ftree_sink, NULL, 1 },
diff --git a/gcc/passes.def b/gcc/passes.def
index 1d598b2..f8fd0ef 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -77,7 +77,6 @@ along with GCC; see the file COPYING3.  If not see
       NEXT_PASS (pass_all_early_optimizations);
       PUSH_INSERT_PASSES_WITHIN (pass_all_early_optimizations)
 	  NEXT_PASS (pass_remove_cgraph_callee_edges);
-	  NEXT_PASS (pass_rename_ssa_copies);
 	  NEXT_PASS (pass_object_sizes);
 	  NEXT_PASS (pass_ccp);
 	  /* After CCP we rewrite no longer addressed locals into SSA
@@ -154,7 +153,6 @@ along with GCC; see the file COPYING3.  If not see
       /* Initial scalar cleanups before alias computation.
 	 They ensure memory accesses are not indirect wherever possible.  */
       NEXT_PASS (pass_strip_predict_hints);
-      NEXT_PASS (pass_rename_ssa_copies);
       NEXT_PASS (pass_ccp);
       /* After CCP we rewrite no longer addressed locals into SSA
 	 form if possible.  */
@@ -182,7 +180,6 @@ along with GCC; see the file COPYING3.  If not see
       NEXT_PASS (pass_stdarg);
       NEXT_PASS (pass_lower_complex);
       NEXT_PASS (pass_sra);
-      NEXT_PASS (pass_rename_ssa_copies);
       /* The dom pass will also resolve all __builtin_constant_p calls
          that are still there to 0.  This has to be done after some
 	 propagations have already run, but before some more dead code
@@ -291,7 +288,6 @@ along with GCC; see the file COPYING3.  If not see
       NEXT_PASS (pass_fold_builtins);
       NEXT_PASS (pass_optimize_widening_mul);
       NEXT_PASS (pass_tail_calls);
-      NEXT_PASS (pass_rename_ssa_copies);
       /* FIXME: If DCE is not run before checking for uninitialized uses,
 	 we may get false warnings (e.g., testsuite/gcc.dg/uninit-5.c).
 	 However, this also causes us to misdiagnose cases that should be
@@ -326,7 +322,6 @@ along with GCC; see the file COPYING3.  If not see
       NEXT_PASS (pass_dce);
       NEXT_PASS (pass_asan);
       NEXT_PASS (pass_tsan);
-      NEXT_PASS (pass_rename_ssa_copies);
       /* ???  We do want some kind of loop invariant motion, but we possibly
          need to adjust LIM to be more friendly towards preserving accurate
 	 debug information here.  */
diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c
index 1afeefe..8557d84 100644
--- a/gcc/tree-ssa-coalesce.c
+++ b/gcc/tree-ssa-coalesce.c
@@ -825,13 +825,23 @@ live_track_clear_base_vars (live_track_p ptr)
    base variable are added.  */
 
 static ssa_conflicts_p
-build_ssa_conflict_graph (tree_live_info_p liveinfo)
+build_ssa_conflict_graph (tree_live_info_p liveinfo, bitmap param_defaults)
 {
   ssa_conflicts_p graph;
   var_map map;
   basic_block bb;
   ssa_op_iter iter;
   live_track_p live;
+  basic_block entry;
+
+  /* If we are optimizing, we may attempt to coalesce variables from
+     different base variables, including different parameters, so we
+     have to make sure default defs live at the entry block conflict
+     with each other.  */
+  if (optimize)
+    entry = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+  else
+    entry = NULL;
 
   map = live_var_map (liveinfo);
   graph = ssa_conflicts_new (num_var_partitions (map));
@@ -890,6 +900,36 @@ build_ssa_conflict_graph (tree_live_info_p liveinfo)
 	    live_track_process_def (live, result, graph);
 	}
 
+      /* Pretend there are defs for params' default defs at the start
+	 of the (post-)entry block.  We run after abnormal coalescing,
+	 so we can't assume the leader variable is the default
+	 definition, but because of SSA_NAME_VAR adjustments in
+	 attempt_coalesce, we can assume that if there is any
+	 PARM_DECL in the partition, it will be the leader's
+	 SSA_NAME_VAR.  */
+      if (bb == entry)
+	{
+	  unsigned base;
+	  bitmap_iterator bi;
+	  EXECUTE_IF_SET_IN_BITMAP (live->live_base_var, 0, base, bi)
+	    {
+	      bitmap_iterator bi2;
+	      unsigned part;
+	      EXECUTE_IF_SET_IN_BITMAP (live->live_base_partitions[base],
+					0, part, bi2)
+		{
+		  tree var = partition_to_var (map, part);
+		  if (!SSA_NAME_VAR (var)
+		      || TREE_CODE (SSA_NAME_VAR (var)) != PARM_DECL
+		      || !(SSA_NAME_IS_DEFAULT_DEF (var)
+			   || (param_defaults
+			       && bitmap_bit_p (param_defaults, part))))
+		    continue;
+		  live_track_process_def (live, var, graph);
+		}
+	    }
+	}
+
      live_track_clear_base_vars (live);
     }
 
@@ -1126,11 +1166,12 @@ create_outofssa_var_map (coalesce_list_p cl, bitmap used_in_copy)
 
 static inline bool
 attempt_coalesce (var_map map, ssa_conflicts_p graph, int x, int y,
-		  FILE *debug)
+		  bitmap param_defaults, FILE *debug)
 {
   int z;
   tree var1, var2;
   int p1, p2;
+  bool default_def = false;
 
   p1 = var_to_partition (map, ssa_name (x));
   p2 = var_to_partition (map, ssa_name (y));
@@ -1158,6 +1199,70 @@ attempt_coalesce (var_map map, ssa_conflicts_p graph, int x, int y,
     {
       var1 = partition_to_var (map, p1);
       var2 = partition_to_var (map, p2);
+
+      tree leader;
+
+      if (var1 == var2 || !SSA_NAME_VAR (var2)
+	  || SSA_NAME_VAR (var1) == SSA_NAME_VAR (var2))
+	{
+	  leader = SSA_NAME_VAR (var1);
+	  default_def = (leader && TREE_CODE (leader) == PARM_DECL
+			 && (SSA_NAME_IS_DEFAULT_DEF (var1)
+			     || bitmap_bit_p (param_defaults, p1)));
+	}
+      else if (!SSA_NAME_VAR (var1))
+	{
+	  leader = SSA_NAME_VAR (var2);
+	  default_def = (leader && TREE_CODE (leader) == PARM_DECL
+			 && (SSA_NAME_IS_DEFAULT_DEF (var2)
+			     || bitmap_bit_p (param_defaults, p2)));
+	}
+      else if ((TREE_CODE (SSA_NAME_VAR (var1)) == PARM_DECL
+		&& (SSA_NAME_IS_DEFAULT_DEF (var1)
+		    || bitmap_bit_p (param_defaults, p1)))
+	       || TREE_CODE (SSA_NAME_VAR (var1)) == RESULT_DECL)
+	{
+	  if ((TREE_CODE (SSA_NAME_VAR (var2)) == PARM_DECL
+	       && (SSA_NAME_IS_DEFAULT_DEF (var2)
+		   || bitmap_bit_p (param_defaults, p2)))
+	      || TREE_CODE (SSA_NAME_VAR (var2)) == RESULT_DECL)
+	    {
+	      /* We only have one RESULT_DECL, and two PARM_DECL
+		 DEFAULT_DEFs would have conflicted, so we know either
+		 one of var1 or var2 is a PARM_DECL, and the other is
+		 a RESULT_DECL.  */
+	      if (debug)
+		fprintf (debug, ": Cannot coalesce PARM_DECL and RESULT_DECL\n");
+	      return false;
+	    }
+	  leader = SSA_NAME_VAR (var1);
+	  default_def = TREE_CODE (leader) == PARM_DECL;
+	}
+      else if ((TREE_CODE (SSA_NAME_VAR (var2)) == PARM_DECL
+		&& (SSA_NAME_IS_DEFAULT_DEF (var2)
+		    || bitmap_bit_p (param_defaults, p2)))
+	       || TREE_CODE (SSA_NAME_VAR (var2)) == RESULT_DECL)
+	{
+	  leader = SSA_NAME_VAR (var2);
+	  default_def = TREE_CODE (leader) == PARM_DECL;
+	}
+      else if (TREE_CODE (SSA_NAME_VAR (var1)) == PARM_DECL)
+	leader = SSA_NAME_VAR (var1);
+      else if (TREE_CODE (SSA_NAME_VAR (var2)) == PARM_DECL)
+	leader = SSA_NAME_VAR (var2);
+      else if (TREE_CODE (SSA_NAME_VAR (var1)) == VAR_DECL
+	       && !DECL_IGNORED_P (SSA_NAME_VAR (var1)))
+	leader = SSA_NAME_VAR (var1);
+      else if (TREE_CODE (SSA_NAME_VAR (var2)) == VAR_DECL
+	       && !DECL_IGNORED_P (SSA_NAME_VAR (var2)))
+	leader = SSA_NAME_VAR (var2);
+      else if (TREE_CODE (SSA_NAME_VAR (var1)) == VAR_DECL)
+	leader = SSA_NAME_VAR (var1);
+      else if (TREE_CODE (SSA_NAME_VAR (var2)) == VAR_DECL)
+	leader = SSA_NAME_VAR (var2);
+      else /* What else could it be?  */
+	gcc_unreachable ();
+
       z = var_union (map, var1, var2);
       if (z == NO_PARTITION)
 	{
@@ -1173,8 +1278,46 @@ attempt_coalesce (var_map map, ssa_conflicts_p graph, int x, int y,
       else
 	ssa_conflicts_merge (graph, p2, p1);
 
+      if (z == p1)
+	{
+	  if (SSA_NAME_VAR (var1) != leader)
+	    {
+	      replace_ssa_name_symbol (var1, leader);
+	      if (debug)
+		{
+		  fprintf (debug, ": Renamed ");
+		  print_generic_expr (debug, var1, TDF_SLIM);
+		}
+	    }
+	  if (default_def)
+	    {
+	      if (SSA_NAME_IS_DEFAULT_DEF (var2))
+		bitmap_clear_bit (param_defaults, p2);
+	      bitmap_set_bit (param_defaults, p1);
+	    }
+	}
+      else
+	{
+	  if (SSA_NAME_VAR (var2) != leader)
+	    {
+	      replace_ssa_name_symbol (var2, leader);
+	      if (debug)
+		{
+		  fprintf (debug, ": Renamed ");
+		  print_generic_expr (debug, var2, TDF_SLIM);
+		}
+	    }
+	  if (default_def)
+	    {
+	      if (SSA_NAME_IS_DEFAULT_DEF (var1))
+		bitmap_clear_bit (param_defaults, p1);
+	      bitmap_set_bit (param_defaults, p2);
+	    }
+	}
+
       if (debug)
 	fprintf (debug, ": Success -> %d\n", z);
+
       return true;
     }
 
@@ -1190,7 +1333,7 @@ attempt_coalesce (var_map map, ssa_conflicts_p graph, int x, int y,
 
 static void
 coalesce_partitions (var_map map, ssa_conflicts_p graph, coalesce_list_p cl,
-		     FILE *debug)
+		     bitmap param_defaults, FILE *debug)
 {
   int x = 0, y = 0;
   tree var1, var2;
@@ -1226,7 +1369,7 @@ coalesce_partitions (var_map map, ssa_conflicts_p graph, coalesce_list_p cl,
 		if (debug)
 		  fprintf (debug, "Abnormal coalesce: ");
 
-		if (!attempt_coalesce (map, graph, v1, v2, debug))
+		if (!attempt_coalesce (map, graph, v1, v2, param_defaults, debug))
 		  fail_abnormal_edge_coalesce (v1, v2);
 	      }
 	  }
@@ -1244,7 +1387,7 @@ coalesce_partitions (var_map map, ssa_conflicts_p graph, coalesce_list_p cl,
 
       if (debug)
 	fprintf (debug, "Coalesce list: ");
-      attempt_coalesce (map, graph, x, y, debug);
+      attempt_coalesce (map, graph, x, y, param_defaults, debug);
     }
 }
 
@@ -1272,6 +1415,178 @@ ssa_name_var_hash::equal (const value_type *n1, const compare_type *n2)
 }
 
 
+/* Output partition map MAP with coalescing plan PART to file F.  */
+
+void
+dump_part_var_map (FILE *f, partition part, var_map map)
+{
+  int t;
+  unsigned x, y;
+  int p;
+
+  fprintf (f, "\nCoalescible Partition map \n\n");
+
+  for (x = 0; x < map->num_partitions; x++)
+    {
+      if (map->view_to_partition != NULL)
+	p = map->view_to_partition[x];
+      else
+	p = x;
+
+      if (ssa_name (p) == NULL_TREE
+	  || virtual_operand_p (ssa_name (p)))
+        continue;
+
+      t = 0;
+      for (y = 1; y < num_ssa_names; y++)
+        {
+	  tree var = version_to_var (map, y);
+	  if (!var)
+	    continue;
+	  int q = var_to_partition (map, var);
+	  p = partition_find (part, q);
+	  gcc_assert (map->partition_to_base_index[q]
+		      == map->partition_to_base_index[p]);
+
+	  if (p == (int)x)
+	    {
+	      if (t++ == 0)
+	        {
+		  fprintf (f, "Partition %d, base %d (", x,
+			   map->partition_to_base_index[q]);
+		  print_generic_expr (f, partition_to_var (map, q), TDF_SLIM);
+		  fprintf (f, " - ");
+		}
+	      fprintf (f, "%d ", y);
+	    }
+	}
+      if (t != 0)
+	fprintf (f, ")\n");
+    }
+  fprintf (f, "\n");
+}
+
+/* Fill in MAP's partition_to_base_index, with one index for each
+   partition of SSA names USED_IN_COPIES and related by CL
+   coalesce possibilities.  */
+
+static void
+compute_optimized_partition_bases (var_map map, bitmap used_in_copies,
+				   coalesce_list_p cl)
+{
+  int parts = num_var_partitions (map);
+  partition tentative = partition_new (parts);
+
+  /* Partition the SSA versions so that, for each coalescible
+     pair, both of its members are in the same partition in
+     TENTATIVE.  */
+  gcc_assert (!cl->sorted);
+  coalesce_pair_p node;
+  coalesce_iterator_type ppi;
+  FOR_EACH_PARTITION_PAIR (node, ppi, cl)
+    {
+      tree v1 = ssa_name (node->first_element);
+      int p1 = partition_find (tentative, var_to_partition (map, v1));
+      tree v2 = ssa_name (node->second_element);
+      int p2 = partition_find (tentative, var_to_partition (map, v2));
+
+      if (p1 == p2)
+	continue;
+
+      partition_union (tentative, p1, p2);
+    }
+
+  /* We have to deal with cost one pairs too.  */
+  for (cost_one_pair_d *co = cl->cost_one_list; co; co = co->next)
+    {
+      tree v1 = ssa_name (co->first_element);
+      int p1 = partition_find (tentative, var_to_partition (map, v1));
+      tree v2 = ssa_name (co->second_element);
+      int p2 = partition_find (tentative, var_to_partition (map, v2));
+
+      if (p1 == p2)
+	continue;
+
+      partition_union (tentative, p1, p2);
+    }
+
+  /* And also with abnormal edges.  */
+  basic_block bb;
+  edge e;
+  edge_iterator ei;
+  FOR_EACH_BB_FN (bb, cfun)
+    {
+      FOR_EACH_EDGE (e, ei, bb->preds)
+	if (e->flags & EDGE_ABNORMAL)
+	  {
+	    gphi_iterator gsi;
+	    for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
+		 gsi_next (&gsi))
+	      {
+		gphi *phi = gsi.phi ();
+		tree arg = PHI_ARG_DEF (phi, e->dest_idx);
+		if (SSA_NAME_IS_DEFAULT_DEF (arg)
+		    && (!SSA_NAME_VAR (arg)
+			|| TREE_CODE (SSA_NAME_VAR (arg)) != PARM_DECL))
+		  continue;
+
+		tree res = PHI_RESULT (phi);
+
+		int p1 = partition_find (tentative, var_to_partition (map, res));
+		int p2 = partition_find (tentative, var_to_partition (map, arg));
+
+		if (p1 == p2)
+		  continue;
+
+		partition_union (tentative, p1, p2);
+	      }
+	  }
+    }
+  
+
+  map->partition_to_base_index = XCNEWVEC (int, parts);
+  auto_vec<unsigned int> index_map (parts);
+  if (parts)
+    index_map.quick_grow (parts);
+
+  const unsigned no_part = -1;
+  unsigned count = parts;
+  while (count)
+    index_map[--count] = no_part;
+
+  /* Initialize MAP's mapping from partition to base index, using
+     as base indices an enumeration of the TENTATIVE partitions in
+     which each SSA version ended up, so that we compute conflicts
+     between all SSA versions that ended up in the same potential
+     coalesce partition.  */
+  bitmap_iterator bi;
+  unsigned i;
+  EXECUTE_IF_SET_IN_BITMAP (used_in_copies, 0, i, bi)
+    {
+      int pidx = var_to_partition (map, ssa_name (i));
+      int base = partition_find (tentative, pidx);
+      if (index_map[base] != no_part)
+	continue;
+      index_map[base] = count++;
+    }
+
+  map->num_basevars = count;
+
+  EXECUTE_IF_SET_IN_BITMAP (used_in_copies, 0, i, bi)
+    {
+      int pidx = var_to_partition (map, ssa_name (i));
+      int base = partition_find (tentative, pidx);
+      gcc_assert (index_map[base] < count);
+      map->partition_to_base_index[pidx] = index_map[base];
+    }
+
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    dump_part_var_map (dump_file, tentative, map);
+
+  partition_delete (tentative);
+}
+
+
 /* Reduce the number of copies by coalescing variables in the function.  Return
    a partition map with the resulting coalesces.  */
 
@@ -1332,7 +1647,12 @@ coalesce_ssa_name (void)
     dump_var_map (dump_file, map);
 
   /* Don't calculate live ranges for variables not in the coalesce list.  */
-  partition_view_bitmap (map, used_in_copies, true);
+  partition_view_bitmap (map, used_in_copies, !optimize);
+
+  /* If we are optimizing, compute the base indices ourselves.  */
+  if (optimize)
+    compute_optimized_partition_bases (map, used_in_copies, cl);
+
   BITMAP_FREE (used_in_copies);
 
   if (num_var_partitions (map) < 1)
@@ -1341,6 +1661,8 @@ coalesce_ssa_name (void)
       return map;
     }
 
+  bitmap param_defaults = BITMAP_ALLOC (NULL);
+
   if (dump_file && (dump_flags & TDF_DETAILS))
     dump_var_map (dump_file, map);
 
@@ -1350,7 +1672,7 @@ coalesce_ssa_name (void)
     dump_live_info (dump_file, liveinfo, LIVEDUMP_ENTRY);
 
   /* Build a conflict graph.  */
-  graph = build_ssa_conflict_graph (liveinfo);
+  graph = build_ssa_conflict_graph (liveinfo, param_defaults);
   delete_tree_live_info (liveinfo);
   if (dump_file && (dump_flags & TDF_DETAILS))
     ssa_conflicts_dump (dump_file, graph);
@@ -1370,10 +1692,10 @@ coalesce_ssa_name (void)
     dump_var_map (dump_file, map);
 
   /* Now coalesce everything in the list.  */
-  coalesce_partitions (map, graph, cl,
-		       ((dump_flags & TDF_DETAILS) ? dump_file
-						   : NULL));
+  coalesce_partitions (map, graph, cl, param_defaults,
+		       ((dump_flags & TDF_DETAILS) ? dump_file : NULL));
 
+  BITMAP_FREE (param_defaults);
   delete_coalesce_list (cl);
   ssa_conflicts_delete (graph);
 
diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c
deleted file mode 100644
index f3cb56e..0000000
--- a/gcc/tree-ssa-copyrename.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/* Rename SSA copies.
-   Copyright (C) 2004-2015 Free Software Foundation, Inc.
-   Contributed by Andrew MacLeod <amacleod@redhat.com>
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "hash-set.h"
-#include "machmode.h"
-#include "vec.h"
-#include "double-int.h"
-#include "input.h"
-#include "alias.h"
-#include "symtab.h"
-#include "wide-int.h"
-#include "inchash.h"
-#include "tree.h"
-#include "fold-const.h"
-#include "predict.h"
-#include "hard-reg-set.h"
-#include "function.h"
-#include "dominance.h"
-#include "cfg.h"
-#include "basic-block.h"
-#include "tree-ssa-alias.h"
-#include "internal-fn.h"
-#include "gimple-expr.h"
-#include "is-a.h"
-#include "gimple.h"
-#include "gimple-iterator.h"
-#include "flags.h"
-#include "tree-pretty-print.h"
-#include "bitmap.h"
-#include "gimple-ssa.h"
-#include "stringpool.h"
-#include "tree-ssanames.h"
-#include "hashtab.h"
-#include "rtl.h"
-#include "statistics.h"
-#include "real.h"
-#include "fixed-value.h"
-#include "insn-config.h"
-#include "expmed.h"
-#include "dojump.h"
-#include "explow.h"
-#include "calls.h"
-#include "emit-rtl.h"
-#include "varasm.h"
-#include "stmt.h"
-#include "expr.h"
-#include "tree-dfa.h"
-#include "tree-inline.h"
-#include "tree-ssa-live.h"
-#include "tree-pass.h"
-#include "langhooks.h"
-
-static struct
-{
-  /* Number of copies coalesced.  */
-  int coalesced;
-} stats;
-
-/* The following routines implement the SSA copy renaming phase.
-
-   This optimization looks for copies between 2 SSA_NAMES, either through a
-   direct copy, or an implicit one via a PHI node result and its arguments.
-
-   Each copy is examined to determine if it is possible to rename the base
-   variable of one of the operands to the same variable as the other operand.
-   i.e.
-   T.3_5 = <blah>
-   a_1 = T.3_5
-
-   If this copy couldn't be copy propagated, it could possibly remain in the
-   program throughout the optimization phases.   After SSA->normal, it would
-   become:
-
-   T.3 = <blah>
-   a = T.3
-
-   Since T.3_5 is distinct from all other SSA versions of T.3, there is no
-   fundamental reason why the base variable needs to be T.3, subject to
-   certain restrictions.  This optimization attempts to determine if we can
-   change the base variable on copies like this, and result in code such as:
-
-   a_5 = <blah>
-   a_1 = a_5
-
-   This gives the SSA->normal pass a shot at coalescing a_1 and a_5. If it is
-   possible, the copy goes away completely. If it isn't possible, a new temp
-   will be created for a_5, and you will end up with the exact same code:
-
-   a.8 = <blah>
-   a = a.8
-
-   The other benefit of performing this optimization relates to what variables
-   are chosen in copies.  Gimplification of the program uses temporaries for
-   a lot of things. expressions like
-
-   a_1 = <blah>
-   <blah2> = a_1
-
-   get turned into
-
-   T.3_5 = <blah>
-   a_1 = T.3_5
-   <blah2> = a_1
-
-   Copy propagation is done in a forward direction, and if we can propagate
-   through the copy, we end up with:
-
-   T.3_5 = <blah>
-   <blah2> = T.3_5
-
-   The copy is gone, but so is all reference to the user variable 'a'. By
-   performing this optimization, we would see the sequence:
-
-   a_5 = <blah>
-   a_1 = a_5
-   <blah2> = a_1
-
-   which copy propagation would then turn into:
-
-   a_5 = <blah>
-   <blah2> = a_5
-
-   and so we still retain the user variable whenever possible.  */
-
-
-/* Coalesce the partitions in MAP representing VAR1 and VAR2 if it is valid.
-   Choose a representative for the partition, and send debug info to DEBUG.  */
-
-static void
-copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
-{
-  int p1, p2, p3;
-  tree root1, root2;
-  tree rep1, rep2;
-  bool ign1, ign2, abnorm;
-
-  gcc_assert (TREE_CODE (var1) == SSA_NAME);
-  gcc_assert (TREE_CODE (var2) == SSA_NAME);
-
-  register_ssa_partition (map, var1);
-  register_ssa_partition (map, var2);
-
-  p1 = partition_find (map->var_partition, SSA_NAME_VERSION (var1));
-  p2 = partition_find (map->var_partition, SSA_NAME_VERSION (var2));
-
-  if (debug)
-    {
-      fprintf (debug, "Try : ");
-      print_generic_expr (debug, var1, TDF_SLIM);
-      fprintf (debug, "(P%d) & ", p1);
-      print_generic_expr (debug, var2, TDF_SLIM);
-      fprintf (debug, "(P%d)", p2);
-    }
-
-  gcc_assert (p1 != NO_PARTITION);
-  gcc_assert (p2 != NO_PARTITION);
-
-  if (p1 == p2)
-    {
-      if (debug)
-	fprintf (debug, " : Already coalesced.\n");
-      return;
-    }
-
-  rep1 = partition_to_var (map, p1);
-  rep2 = partition_to_var (map, p2);
-  root1 = SSA_NAME_VAR (rep1);
-  root2 = SSA_NAME_VAR (rep2);
-  if (!root1 && !root2)
-    return;
-
-  /* Don't coalesce if one of the variables occurs in an abnormal PHI.  */
-  abnorm = (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rep1)
-	    || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rep2));
-  if (abnorm)
-    {
-      if (debug)
-	fprintf (debug, " : Abnormal PHI barrier.  No coalesce.\n");
-      return;
-    }
-
-  /* Partitions already have the same root, simply merge them.  */
-  if (root1 == root2)
-    {
-      p1 = partition_union (map->var_partition, p1, p2);
-      if (debug)
-	fprintf (debug, " : Same root, coalesced --> P%d.\n", p1);
-      return;
-    }
-
-  /* Never attempt to coalesce 2 different parameters.  */
-  if ((root1 && TREE_CODE (root1) == PARM_DECL)
-      && (root2 && TREE_CODE (root2) == PARM_DECL))
-    {
-      if (debug)
-        fprintf (debug, " : 2 different PARM_DECLS. No coalesce.\n");
-      return;
-    }
-
-  if ((root1 && TREE_CODE (root1) == RESULT_DECL)
-      != (root2 && TREE_CODE (root2) == RESULT_DECL))
-    {
-      if (debug)
-        fprintf (debug, " : One root a RESULT_DECL. No coalesce.\n");
-      return;
-    }
-
-  ign1 = !root1 || (TREE_CODE (root1) == VAR_DECL && DECL_IGNORED_P (root1));
-  ign2 = !root2 || (TREE_CODE (root2) == VAR_DECL && DECL_IGNORED_P (root2));
-
-  /* Refrain from coalescing user variables, if requested.  */
-  if (!ign1 && !ign2)
-    {
-      if (flag_ssa_coalesce_vars && DECL_FROM_INLINE (root2))
-	ign2 = true;
-      else if (flag_ssa_coalesce_vars && DECL_FROM_INLINE (root1))
-	ign1 = true;
-      else if (flag_ssa_coalesce_vars != 2)
-	{
-	  if (debug)
-	    fprintf (debug, " : 2 different USER vars. No coalesce.\n");
-	  return;
-	}
-      else
-	ign2 = true;
-    }
-
-  /* If both values have default defs, we can't coalesce.  If only one has a
-     tag, make sure that variable is the new root partition.  */
-  if (root1 && ssa_default_def (cfun, root1))
-    {
-      if (root2 && ssa_default_def (cfun, root2))
-	{
-	  if (debug)
-	    fprintf (debug, " : 2 default defs. No coalesce.\n");
-	  return;
-	}
-      else
-        {
-	  ign2 = true;
-	  ign1 = false;
-	}
-    }
-  else if (root2 && ssa_default_def (cfun, root2))
-    {
-      ign1 = true;
-      ign2 = false;
-    }
-
-  /* Do not coalesce if we cannot assign a symbol to the partition.  */
-  if (!(!ign2 && root2)
-      && !(!ign1 && root1))
-    {
-      if (debug)
-	fprintf (debug, " : Choosen variable has no root.  No coalesce.\n");
-      return;
-    }
-
-  /* Don't coalesce if the new chosen root variable would be read-only.
-     If both ign1 && ign2, then the root var of the larger partition
-     wins, so reject in that case if any of the root vars is TREE_READONLY.
-     Otherwise reject only if the root var, on which replace_ssa_name_symbol
-     will be called below, is readonly.  */
-  if (((root1 && TREE_READONLY (root1)) && ign2)
-      || ((root2 && TREE_READONLY (root2)) && ign1))
-    {
-      if (debug)
-	fprintf (debug, " : Readonly variable.  No coalesce.\n");
-      return;
-    }
-
-  /* Don't coalesce if the two variables aren't type compatible .  */
-  if (!types_compatible_p (TREE_TYPE (var1), TREE_TYPE (var2))
-      /* There is a disconnect between the middle-end type-system and
-         VRP, avoid coalescing enum types with different bounds.  */
-      || ((TREE_CODE (TREE_TYPE (var1)) == ENUMERAL_TYPE
-	   || TREE_CODE (TREE_TYPE (var2)) == ENUMERAL_TYPE)
-	  && TREE_TYPE (var1) != TREE_TYPE (var2)))
-    {
-      if (debug)
-	fprintf (debug, " : Incompatible types.  No coalesce.\n");
-      return;
-    }
-
-  /* Merge the two partitions.  */
-  p3 = partition_union (map->var_partition, p1, p2);
-
-  /* Set the root variable of the partition to the better choice, if there is
-     one.  */
-  if (!ign2 && root2)
-    replace_ssa_name_symbol (partition_to_var (map, p3), root2);
-  else if (!ign1 && root1)
-    replace_ssa_name_symbol (partition_to_var (map, p3), root1);
-  else
-    gcc_unreachable ();
-
-  if (debug)
-    {
-      fprintf (debug, " --> P%d ", p3);
-      print_generic_expr (debug, SSA_NAME_VAR (partition_to_var (map, p3)),
-			  TDF_SLIM);
-      fprintf (debug, "\n");
-    }
-}
-
-
-namespace {
-
-const pass_data pass_data_rename_ssa_copies =
-{
-  GIMPLE_PASS, /* type */
-  "copyrename", /* name */
-  OPTGROUP_NONE, /* optinfo_flags */
-  TV_TREE_COPY_RENAME, /* tv_id */
-  ( PROP_cfg | PROP_ssa ), /* properties_required */
-  0, /* properties_provided */
-  0, /* properties_destroyed */
-  0, /* todo_flags_start */
-  0, /* todo_flags_finish */
-};
-
-class pass_rename_ssa_copies : public gimple_opt_pass
-{
-public:
-  pass_rename_ssa_copies (gcc::context *ctxt)
-    : gimple_opt_pass (pass_data_rename_ssa_copies, ctxt)
-  {}
-
-  /* opt_pass methods: */
-  opt_pass * clone () { return new pass_rename_ssa_copies (m_ctxt); }
-  virtual bool gate (function *) { return flag_tree_copyrename != 0; }
-  virtual unsigned int execute (function *);
-
-}; // class pass_rename_ssa_copies
-
-/* This function will make a pass through the IL, and attempt to coalesce any
-   SSA versions which occur in PHI's or copies.  Coalescing is accomplished by
-   changing the underlying root variable of all coalesced version.  This will
-   then cause the SSA->normal pass to attempt to coalesce them all to the same
-   variable.  */
-
-unsigned int
-pass_rename_ssa_copies::execute (function *fun)
-{
-  var_map map;
-  basic_block bb;
-  tree var, part_var;
-  gimple stmt;
-  unsigned x;
-  FILE *debug;
-
-  memset (&stats, 0, sizeof (stats));
-
-  if (dump_file && (dump_flags & TDF_DETAILS))
-    debug = dump_file;
-  else
-    debug = NULL;
-
-  map = init_var_map (num_ssa_names);
-
-  FOR_EACH_BB_FN (bb, fun)
-    {
-      /* Scan for real copies.  */
-      for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
-	   gsi_next (&gsi))
-	{
-	  stmt = gsi_stmt (gsi);
-	  if (gimple_assign_ssa_name_copy_p (stmt))
-	    {
-	      tree lhs = gimple_assign_lhs (stmt);
-	      tree rhs = gimple_assign_rhs1 (stmt);
-
-	      copy_rename_partition_coalesce (map, lhs, rhs, debug);
-	    }
-	}
-    }
-
-  FOR_EACH_BB_FN (bb, fun)
-    {
-      /* Treat PHI nodes as copies between the result and each argument.  */
-      for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
-	   gsi_next (&gsi))
-        {
-          size_t i;
-	  tree res;
-	  gphi *phi = gsi.phi ();
-	  res = gimple_phi_result (phi);
-
-	  /* Do not process virtual SSA_NAMES.  */
-	  if (virtual_operand_p (res))
-	    continue;
-
-	  /* Make sure to only use the same partition for an argument
-	     as the result but never the other way around.  */
-	  if (SSA_NAME_VAR (res)
-	      && !DECL_IGNORED_P (SSA_NAME_VAR (res)))
-	    for (i = 0; i < gimple_phi_num_args (phi); i++)
-	      {
-		tree arg = PHI_ARG_DEF (phi, i);
-		if (TREE_CODE (arg) == SSA_NAME)
-		  copy_rename_partition_coalesce (map, res, arg,
-						  debug);
-	      }
-	  /* Else if all arguments are in the same partition try to merge
-	     it with the result.  */
-	  else
-	    {
-	      int all_p_same = -1;
-	      int p = -1;
-	      for (i = 0; i < gimple_phi_num_args (phi); i++)
-		{
-		  tree arg = PHI_ARG_DEF (phi, i);
-		  if (TREE_CODE (arg) != SSA_NAME)
-		    {
-		      all_p_same = 0;
-		      break;
-		    }
-		  else if (all_p_same == -1)
-		    {
-		      p = partition_find (map->var_partition,
-					  SSA_NAME_VERSION (arg));
-		      all_p_same = 1;
-		    }
-		  else if (all_p_same == 1
-			   && p != partition_find (map->var_partition,
-						   SSA_NAME_VERSION (arg)))
-		    {
-		      all_p_same = 0;
-		      break;
-		    }
-		}
-	      if (all_p_same == 1)
-		copy_rename_partition_coalesce (map, res,
-						PHI_ARG_DEF (phi, 0),
-						debug);
-	    }
-        }
-    }
-
-  if (debug)
-    dump_var_map (debug, map);
-
-  /* Now one more pass to make all elements of a partition share the same
-     root variable.  */
-
-  for (x = 1; x < num_ssa_names; x++)
-    {
-      part_var = partition_to_var (map, x);
-      if (!part_var)
-        continue;
-      var = ssa_name (x);
-      if (SSA_NAME_VAR (var) == SSA_NAME_VAR (part_var))
-	continue;
-      if (debug)
-        {
-	  fprintf (debug, "Coalesced ");
-	  print_generic_expr (debug, var, TDF_SLIM);
-	  fprintf (debug, " to ");
-	  print_generic_expr (debug, part_var, TDF_SLIM);
-	  fprintf (debug, "\n");
-	}
-      stats.coalesced++;
-      replace_ssa_name_symbol (var, SSA_NAME_VAR (part_var));
-    }
-
-  statistics_counter_event (fun, "copies coalesced",
-			    stats.coalesced);
-  delete_var_map (map);
-  return 0;
-}
-
-} // anon namespace
-
-gimple_opt_pass *
-make_pass_rename_ssa_copies (gcc::context *ctxt)
-{
-  return new pass_rename_ssa_copies (ctxt);
-}
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index e0c42669..46b1869 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -119,7 +119,10 @@ tree_int_map_hasher::equal (const value_type *v, const compare_type *c)
 }
 
 
-/* This routine will initialize the basevar fields of MAP.  */
+/* This routine will initialize the basevar fields of MAP with base
+   names, when we are not optimizing.  When optimizing, we'll use
+   partition numbers as base index numbers, see coalesce_ssa_name in
+   tree-ssa-coalesce.c.  */
 
 static void
 var_map_base_init (var_map map)
