/* Coalesce SSA_NAMES together for the out-of-ssa pass.
   Copyright (C) 2004-2021 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 "backend.h"
#include "tree.h"
#include "gimple.h"
#include "predict.h"
#include "memmodel.h"
#include "tm_p.h"
#include "ssa.h"
#include "tree-ssa.h"
#include "tree-pretty-print.h"
#include "diagnostic-core.h"
#include "dumpfile.h"
#include "gimple-iterator.h"
#include "tree-ssa-live.h"
#include "tree-ssa-coalesce.h"
#include "explow.h"
#include "tree-dfa.h"
#include "stor-layout.h"

/* This set of routines implements a coalesce_list.  This is an object which
   is used to track pairs of ssa_names which are desirable to coalesce
   together to avoid copies.  Costs are associated with each pair, and when
   all desired information has been collected, the object can be used to
   order the pairs for processing.  */

/* This structure defines a pair entry.  */

struct coalesce_pair
{
  int first_element;
  int second_element;
  int cost;

  /* A count of the number of unique partitions this pair would conflict
     with if coalescing was successful.  This is the secondary sort key,
     given two pairs with equal costs, we will prefer the pair with a smaller
     conflict set.

     This is lazily initialized when we discover two coalescing pairs have
     the same primary cost.

     Note this is not updated and propagated as pairs are coalesced.  */
  int conflict_count;

  /* The order in which coalescing pairs are discovered is recorded in this
     field, which is used as the final tie breaker when sorting coalesce
     pairs.  */
  int index;
};

/* This represents a conflict graph.  Implemented as an array of bitmaps.
   A full matrix is used for conflicts rather than just upper triangular form.
   this makes it much simpler and faster to perform conflict merges.  */

struct ssa_conflicts
{
  bitmap_obstack obstack;	/* A place to allocate our bitmaps.  */
  vec<bitmap> conflicts;
};

/* The narrow API of the qsort comparison function doesn't allow easy
   access to additional arguments.  So we have two globals (ick) to hold
   the data we need.  They're initialized before the call to qsort and
   wiped immediately after.  */
static ssa_conflicts *conflicts_;
static var_map map_;

/* Coalesce pair hashtable helpers.  */

struct coalesce_pair_hasher : nofree_ptr_hash <coalesce_pair>
{
  static inline hashval_t hash (const coalesce_pair *);
  static inline bool equal (const coalesce_pair *, const coalesce_pair *);
};

/* Hash function for coalesce list.  Calculate hash for PAIR.   */

inline hashval_t
coalesce_pair_hasher::hash (const coalesce_pair *pair)
{
  hashval_t a = (hashval_t)(pair->first_element);
  hashval_t b = (hashval_t)(pair->second_element);

  return b * (b - 1) / 2 + a;
}

/* Equality function for coalesce list hash table.  Compare PAIR1 and PAIR2,
   returning TRUE if the two pairs are equivalent.  */

inline bool
coalesce_pair_hasher::equal (const coalesce_pair *p1, const coalesce_pair *p2)
{
  return (p1->first_element == p2->first_element
	  && p1->second_element == p2->second_element);
}

typedef hash_table<coalesce_pair_hasher> coalesce_table_type;
typedef coalesce_table_type::iterator coalesce_iterator_type;


struct cost_one_pair
{
  int first_element;
  int second_element;
  cost_one_pair *next;
};

/* This structure maintains the list of coalesce pairs.  */

struct coalesce_list
{
  coalesce_table_type *list;	/* Hash table.  */
  coalesce_pair **sorted;	/* List when sorted.  */
  int num_sorted;		/* Number in the sorted list.  */
  cost_one_pair *cost_one_list;/* Single use coalesces with cost 1.  */
  obstack ob;
};

#define NO_BEST_COALESCE	-1
#define MUST_COALESCE_COST	INT_MAX


/* Return cost of execution of copy instruction with FREQUENCY.  */

static inline int
coalesce_cost (int frequency, bool optimize_for_size)
{
  /* Base costs on BB frequencies bounded by 1.  */
  int cost = frequency;

  if (!cost)
    cost = 1;

  if (optimize_for_size)
    cost = 1;

  return cost;
}


/* Return the cost of executing a copy instruction in basic block BB.  */

static inline int
coalesce_cost_bb (basic_block bb)
{
  return coalesce_cost (bb->count.to_frequency (cfun),
			optimize_bb_for_size_p (bb));
}


/* Return the cost of executing a copy instruction on edge E.  */

static inline int
coalesce_cost_edge (edge e)
{
  int mult = 1;

  /* Inserting copy on critical edge costs more than inserting it elsewhere.  */
  if (EDGE_CRITICAL_P (e))
    mult = 2;
  if (e->flags & EDGE_ABNORMAL)
    return MUST_COALESCE_COST;
  if (e->flags & EDGE_EH)
    {
      edge e2;
      edge_iterator ei;
      FOR_EACH_EDGE (e2, ei, e->dest->preds)
	if (e2 != e)
	  {
	    /* Putting code on EH edge that leads to BB
	       with multiple predecestors imply splitting of
	       edge too.  */
	    if (mult < 2)
	      mult = 2;
	    /* If there are multiple EH predecestors, we
	       also copy EH regions and produce separate
	       landing pad.  This is expensive.  */
	    if (e2->flags & EDGE_EH)
	      {
	        mult = 5;
	        break;
	      }
	  }
    }

  return coalesce_cost (EDGE_FREQUENCY (e),
			optimize_edge_for_size_p (e)) * mult;
}


/* Retrieve a pair to coalesce from the cost_one_list in CL.  Returns the
   2 elements via P1 and P2.  1 is returned by the function if there is a pair,
   NO_BEST_COALESCE is returned if there aren't any.  */

static inline int
pop_cost_one_pair (coalesce_list *cl, int *p1, int *p2)
{
  cost_one_pair *ptr;

  ptr = cl->cost_one_list;
  if (!ptr)
    return NO_BEST_COALESCE;

  *p1 = ptr->first_element;
  *p2 = ptr->second_element;
  cl->cost_one_list = ptr->next;

  return 1;
}

/* Retrieve the most expensive remaining pair to coalesce from CL.  Returns the
   2 elements via P1 and P2.  Their calculated cost is returned by the function.
   NO_BEST_COALESCE is returned if the coalesce list is empty.  */

static inline int
pop_best_coalesce (coalesce_list *cl, int *p1, int *p2)
{
  coalesce_pair *node;
  int ret;

  if (cl->sorted == NULL)
    return pop_cost_one_pair (cl, p1, p2);

  if (cl->num_sorted == 0)
    return pop_cost_one_pair (cl, p1, p2);

  node = cl->sorted[--(cl->num_sorted)];
  *p1 = node->first_element;
  *p2 = node->second_element;
  ret = node->cost;

  return ret;
}


/* Create a new empty coalesce list object and return it.  */

static inline coalesce_list *
create_coalesce_list (void)
{
  coalesce_list *list;
  unsigned size = num_ssa_names * 3;

  if (size < 40)
    size = 40;

  list = (coalesce_list *) xmalloc (sizeof (struct coalesce_list));
  list->list = new coalesce_table_type (size);
  list->sorted = NULL;
  list->num_sorted = 0;
  list->cost_one_list = NULL;
  gcc_obstack_init (&list->ob);
  return list;
}


/* Delete coalesce list CL.  */

static inline void
delete_coalesce_list (coalesce_list *cl)
{
  gcc_assert (cl->cost_one_list == NULL);
  delete cl->list;
  cl->list = NULL;
  free (cl->sorted);
  gcc_assert (cl->num_sorted == 0);
  obstack_free (&cl->ob, NULL);
  free (cl);
}

/* Return the number of unique coalesce pairs in CL.  */

static inline int
num_coalesce_pairs (coalesce_list *cl)
{
  return cl->list->elements ();
}

/* Find a matching coalesce pair object in CL for the pair P1 and P2.  If
   one isn't found, return NULL if CREATE is false, otherwise create a new
   coalesce pair object and return it.  */

static coalesce_pair *
find_coalesce_pair (coalesce_list *cl, int p1, int p2, bool create)
{
  struct coalesce_pair p;
  coalesce_pair **slot;
  unsigned int hash;

  /* Normalize so that p1 is the smaller value.  */
  if (p2 < p1)
    {
      p.first_element = p2;
      p.second_element = p1;
    }
  else
    {
      p.first_element = p1;
      p.second_element = p2;
    }

  hash = coalesce_pair_hasher::hash (&p);
  slot = cl->list->find_slot_with_hash (&p, hash, create ? INSERT : NO_INSERT);
  if (!slot)
    return NULL;

  if (!*slot)
    {
      struct coalesce_pair * pair = XOBNEW (&cl->ob, struct coalesce_pair);
      gcc_assert (cl->sorted == NULL);
      pair->first_element = p.first_element;
      pair->second_element = p.second_element;
      pair->cost = 0;
      pair->index = num_coalesce_pairs (cl);
      pair->conflict_count = 0;
      *slot = pair;
    }

  return (struct coalesce_pair *) *slot;
}

static inline void
add_cost_one_coalesce (coalesce_list *cl, int p1, int p2)
{
  cost_one_pair *pair;

  pair = XOBNEW (&cl->ob, cost_one_pair);
  pair->first_element = p1;
  pair->second_element = p2;
  pair->next = cl->cost_one_list;
  cl->cost_one_list = pair;
}


/* Add a coalesce between P1 and P2 in list CL with a cost of VALUE.  */

static inline void
add_coalesce (coalesce_list *cl, int p1, int p2, int value)
{
  coalesce_pair *node;

  gcc_assert (cl->sorted == NULL);
  if (p1 == p2)
    return;

  node = find_coalesce_pair (cl, p1, p2, true);

  /* Once the value is at least MUST_COALESCE_COST - 1, leave it that way.  */
  if (node->cost < MUST_COALESCE_COST - 1)
    {
      if (value < MUST_COALESCE_COST - 1)
	node->cost += value;
      else
	node->cost = value;
    }
}

/* Compute and record how many unique conflicts would exist for the
   representative partition for each coalesce pair in CL.

   CONFLICTS is the conflict graph and MAP is the current partition view.  */

static void
initialize_conflict_count (coalesce_pair *p,
			   ssa_conflicts *conflicts,
			   var_map map)
{
  int p1 = var_to_partition (map, ssa_name (p->first_element));
  int p2 = var_to_partition (map, ssa_name (p->second_element));

  /* 4 cases.  If both P1 and P2 have conflicts, then build their
     union and count the members.  Else handle the degenerate cases
     in the obvious ways.  */
  if (conflicts->conflicts[p1] && conflicts->conflicts[p2])
    p->conflict_count = bitmap_count_unique_bits (conflicts->conflicts[p1],
						  conflicts->conflicts[p2]);
  else if (conflicts->conflicts[p1])
    p->conflict_count = bitmap_count_bits (conflicts->conflicts[p1]);
  else if (conflicts->conflicts[p2])
    p->conflict_count = bitmap_count_bits (conflicts->conflicts[p2]);
  else
    p->conflict_count = 0;
}


/* Comparison function to allow qsort to sort P1 and P2 in Ascending order.  */

static int
compare_pairs (const void *p1, const void *p2)
{
  coalesce_pair *const *const pp1 = (coalesce_pair *const *) p1;
  coalesce_pair *const *const pp2 = (coalesce_pair *const *) p2;
  int result;

  result = (* pp1)->cost - (* pp2)->cost;
  /* We use the size of the resulting conflict set as the secondary sort key.
     Given two equal costing coalesce pairs, we want to prefer the pair that
     has the smaller conflict set.  */
  if (result == 0)
    {
      if (flag_expensive_optimizations)
	{
	  /* Lazily initialize the conflict counts as it's fairly expensive
	     to compute.  */
	  if ((*pp2)->conflict_count == 0)
	    initialize_conflict_count (*pp2, conflicts_, map_);
	  if ((*pp1)->conflict_count == 0)
	    initialize_conflict_count (*pp1, conflicts_, map_);

	  result = (*pp2)->conflict_count - (*pp1)->conflict_count;
	}

      /* And if everything else is equal, then sort based on which
	 coalesce pair was found first.  */
      if (result == 0)
	result = (*pp2)->index - (*pp1)->index;
    }

  return result;
}

/* Iterate over CL using ITER, returning values in PAIR.  */

#define FOR_EACH_PARTITION_PAIR(PAIR, ITER, CL)		\
  FOR_EACH_HASH_TABLE_ELEMENT (*(CL)->list, (PAIR), coalesce_pair_p, (ITER))


/* Prepare CL for removal of preferred pairs.  When finished they are sorted
   in order from most important coalesce to least important.  */

static void
sort_coalesce_list (coalesce_list *cl, ssa_conflicts *conflicts, var_map map)
{
  unsigned x, num;
  coalesce_pair *p;
  coalesce_iterator_type ppi;

  gcc_assert (cl->sorted == NULL);

  num = num_coalesce_pairs (cl);
  cl->num_sorted = num;
  if (num == 0)
    return;

  /* Allocate a vector for the pair pointers.  */
  cl->sorted = XNEWVEC (coalesce_pair *, num);

  /* Populate the vector with pointers to the pairs.  */
  x = 0;
  FOR_EACH_PARTITION_PAIR (p, ppi, cl)
    cl->sorted[x++] = p;
  gcc_assert (x == num);

  /* Already sorted.  */
  if (num == 1)
    return;

  /* We don't want to depend on qsort_r, so we have to stuff away
     additional data into globals so it can be referenced in
     compare_pairs.  */
  conflicts_ = conflicts;
  map_ = map;
  qsort (cl->sorted, num, sizeof (coalesce_pair *), compare_pairs);
  conflicts_ = NULL;
  map_ = NULL;
}


/* Send debug info for coalesce list CL to file F.  */

static void
dump_coalesce_list (FILE *f, coalesce_list *cl)
{
  coalesce_pair *node;
  coalesce_iterator_type ppi;

  int x;
  tree var;

  if (cl->sorted == NULL)
    {
      fprintf (f, "Coalesce List:\n");
      FOR_EACH_PARTITION_PAIR (node, ppi, cl)
        {
	  tree var1 = ssa_name (node->first_element);
	  tree var2 = ssa_name (node->second_element);
	  print_generic_expr (f, var1, TDF_SLIM);
	  fprintf (f, " <-> ");
	  print_generic_expr (f, var2, TDF_SLIM);
	  fprintf (f, "  (%1d, %1d), ", node->cost, node->conflict_count);
	  fprintf (f, "\n");
	}
    }
  else
    {
      fprintf (f, "Sorted Coalesce list:\n");
      for (x = cl->num_sorted - 1 ; x >=0; x--)
        {
	  node = cl->sorted[x];
	  fprintf (f, "(%d, %d) ", node->cost, node->conflict_count);
	  var = ssa_name (node->first_element);
	  print_generic_expr (f, var, TDF_SLIM);
	  fprintf (f, " <-> ");
	  var = ssa_name (node->second_element);
	  print_generic_expr (f, var, TDF_SLIM);
	  fprintf (f, "\n");
	}
    }
}


/* Return an empty new conflict graph for SIZE elements.  */

static inline ssa_conflicts *
ssa_conflicts_new (unsigned size)
{
  ssa_conflicts *ptr;

  ptr = XNEW (ssa_conflicts);
  bitmap_obstack_initialize (&ptr->obstack);
  ptr->conflicts.create (size);
  ptr->conflicts.safe_grow_cleared (size, true);
  return ptr;
}


/* Free storage for conflict graph PTR.  */

static inline void
ssa_conflicts_delete (ssa_conflicts *ptr)
{
  bitmap_obstack_release (&ptr->obstack);
  ptr->conflicts.release ();
  free (ptr);
}


/* Test if elements X and Y conflict in graph PTR.  */

static inline bool
ssa_conflicts_test_p (ssa_conflicts *ptr, unsigned x, unsigned y)
{
  bitmap bx = ptr->conflicts[x];
  bitmap by = ptr->conflicts[y];

  gcc_checking_assert (x != y);

  if (bx)
    /* Avoid the lookup if Y has no conflicts.  */
    return by ? bitmap_bit_p (bx, y) : false;
  else
    return false;
}


/* Add a conflict with Y to the bitmap for X in graph PTR.  */

static inline void
ssa_conflicts_add_one (ssa_conflicts *ptr, unsigned x, unsigned y)
{
  bitmap bx = ptr->conflicts[x];
  /* If there are no conflicts yet, allocate the bitmap and set bit.  */
  if (! bx)
    bx = ptr->conflicts[x] = BITMAP_ALLOC (&ptr->obstack);
  bitmap_set_bit (bx, y);
}


/* Add conflicts between X and Y in graph PTR.  */

static inline void
ssa_conflicts_add (ssa_conflicts *ptr, unsigned x, unsigned y)
{
  gcc_checking_assert (x != y);
  ssa_conflicts_add_one (ptr, x, y);
  ssa_conflicts_add_one (ptr, y, x);
}


/* Merge all Y's conflict into X in graph PTR.  */

static inline void
ssa_conflicts_merge (ssa_conflicts *ptr, unsigned x, unsigned y)
{
  unsigned z;
  bitmap_iterator bi;
  bitmap bx = ptr->conflicts[x];
  bitmap by = ptr->conflicts[y];

  gcc_checking_assert (x != y);
  if (! by)
    return;

  /* Add a conflict between X and every one Y has.  If the bitmap doesn't
     exist, then it has already been coalesced, and we don't need to add a
     conflict.  */
  EXECUTE_IF_SET_IN_BITMAP (by, 0, z, bi)
    {
      bitmap bz = ptr->conflicts[z];
      if (bz)
	{
	  bool was_there = bitmap_clear_bit (bz, y);
	  gcc_checking_assert (was_there);
	  bitmap_set_bit (bz, x);
	}
    }

  if (bx)
    {
      /* If X has conflicts, add Y's to X.  */
      bitmap_ior_into (bx, by);
      BITMAP_FREE (by);
      ptr->conflicts[y] = NULL;
    }
  else
    {
      /* If X has no conflicts, simply use Y's.  */
      ptr->conflicts[x] = by;
      ptr->conflicts[y] = NULL;
    }
}


/* Dump a conflicts graph.  */

static void
ssa_conflicts_dump (FILE *file, ssa_conflicts *ptr)
{
  unsigned x;
  bitmap b;

  fprintf (file, "\nConflict graph:\n");

  FOR_EACH_VEC_ELT (ptr->conflicts, x, b)
    if (b)
      {
	fprintf (file, "%d: ", x);
	dump_bitmap (file, b);
      }
}


/* This structure is used to efficiently record the current status of live
   SSA_NAMES when building a conflict graph.
   LIVE_BASE_VAR has a bit set for each base variable which has at least one
   ssa version live.
   LIVE_BASE_PARTITIONS is an array of bitmaps using the basevar table as an
   index, and is used to track what partitions of each base variable are
   live.  This makes it easy to add conflicts between just live partitions
   with the same base variable.
   The values in LIVE_BASE_PARTITIONS are only valid if the base variable is
   marked as being live.  This delays clearing of these bitmaps until
   they are actually needed again.  */

class live_track
{
public:
  bitmap_obstack obstack;	/* A place to allocate our bitmaps.  */
  bitmap_head live_base_var;		/* Indicates if a basevar is live.  */
  bitmap_head *live_base_partitions;	/* Live partitions for each basevar.  */
  var_map map;			/* Var_map being used for partition mapping.  */
};


/* This routine will create a new live track structure based on the partitions
   in MAP.  */

static live_track *
new_live_track (var_map map)
{
  live_track *ptr;
  int lim, x;

  /* Make sure there is a partition view in place.  */
  gcc_assert (map->partition_to_base_index != NULL);

  ptr = XNEW (live_track);
  ptr->map = map;
  lim = num_basevars (map);
  bitmap_obstack_initialize (&ptr->obstack);
  ptr->live_base_partitions = XNEWVEC (bitmap_head, lim);
  bitmap_initialize (&ptr->live_base_var, &ptr->obstack);
  for (x = 0; x < lim; x++)
    bitmap_initialize (&ptr->live_base_partitions[x], &ptr->obstack);
  return ptr;
}


/* This routine will free the memory associated with PTR.  */

static void
delete_live_track (live_track *ptr)
{
  bitmap_obstack_release (&ptr->obstack);
  XDELETEVEC (ptr->live_base_partitions);
  XDELETE (ptr);
}


/* This function will remove PARTITION from the live list in PTR.  */

static inline void
live_track_remove_partition (live_track *ptr, int partition)
{
  int root;

  root = basevar_index (ptr->map, partition);
  bitmap_clear_bit (&ptr->live_base_partitions[root], partition);
  /* If the element list is empty, make the base variable not live either.  */
  if (bitmap_empty_p (&ptr->live_base_partitions[root]))
    bitmap_clear_bit (&ptr->live_base_var, root);
}


/* This function will adds PARTITION to the live list in PTR.  */

static inline void
live_track_add_partition (live_track *ptr, int partition)
{
  int root;

  root = basevar_index (ptr->map, partition);
  /* If this base var wasn't live before, it is now.  Clear the element list
     since it was delayed until needed.  */
  if (bitmap_set_bit (&ptr->live_base_var, root))
    bitmap_clear (&ptr->live_base_partitions[root]);
  bitmap_set_bit (&ptr->live_base_partitions[root], partition);

}


/* Clear the live bit for VAR in PTR.  */

static inline void
live_track_clear_var (live_track *ptr, tree var)
{
  int p;

  p = var_to_partition (ptr->map, var);
  if (p != NO_PARTITION)
    live_track_remove_partition (ptr, p);
}


/* Return TRUE if VAR is live in PTR.  */

static inline bool
live_track_live_p (live_track *ptr, tree var)
{
  int p, root;

  p = var_to_partition (ptr->map, var);
  if (p != NO_PARTITION)
    {
      root = basevar_index (ptr->map, p);
      if (bitmap_bit_p (&ptr->live_base_var, root))
	return bitmap_bit_p (&ptr->live_base_partitions[root], p);
    }
  return false;
}


/* This routine will add USE to PTR.  USE will be marked as live in both the
   ssa live map and the live bitmap for the root of USE.  */

static inline void
live_track_process_use (live_track *ptr, tree use)
{
  int p;

  p = var_to_partition (ptr->map, use);
  if (p == NO_PARTITION)
    return;

  /* Mark as live in the appropriate live list.  */
  live_track_add_partition (ptr, p);
}


/* This routine will process a DEF in PTR.  DEF will be removed from the live
   lists, and if there are any other live partitions with the same base
   variable, conflicts will be added to GRAPH.  */

static inline void
live_track_process_def (live_track *ptr, tree def, ssa_conflicts *graph)
{
  int p, root;
  bitmap b;
  unsigned x;
  bitmap_iterator bi;

  p = var_to_partition (ptr->map, def);
  if (p == NO_PARTITION)
    return;

  /* Clear the liveness bit.  */
  live_track_remove_partition (ptr, p);

  /* If the bitmap isn't empty now, conflicts need to be added.  */
  root = basevar_index (ptr->map, p);
  if (bitmap_bit_p (&ptr->live_base_var, root))
    {
      b = &ptr->live_base_partitions[root];
      EXECUTE_IF_SET_IN_BITMAP (b, 0, x, bi)
        ssa_conflicts_add (graph, p, x);
    }
}


/* Initialize PTR with the partitions set in INIT.  */

static inline void
live_track_init (live_track *ptr, bitmap init)
{
  unsigned p;
  bitmap_iterator bi;

  /* Mark all live on exit partitions.  */
  EXECUTE_IF_SET_IN_BITMAP (init, 0, p, bi)
    live_track_add_partition (ptr, p);
}


/* This routine will clear all live partitions in PTR.   */

static inline void
live_track_clear_base_vars (live_track *ptr)
{
  /* Simply clear the live base list.  Anything marked as live in the element
     lists will be cleared later if/when the base variable ever comes alive
     again.  */
  bitmap_clear (&ptr->live_base_var);
}


/* Build a conflict graph based on LIVEINFO.  Any partitions which are in the
   partition view of the var_map liveinfo is based on get entries in the
   conflict graph.  Only conflicts between ssa_name partitions with the same
   base variable are added.  */

static ssa_conflicts *
build_ssa_conflict_graph (tree_live_info_p liveinfo)
{
  ssa_conflicts *graph;
  var_map map;
  basic_block bb;
  ssa_op_iter iter;
  live_track *live;
  basic_block entry;

  /* If inter-variable coalescing is enabled, 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 (flag_tree_coalesce_vars)
    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));

  live = new_live_track (map);

  for (unsigned i = 0; liveinfo->map->vec_bbs.iterate (i, &bb); ++i)
    {
      /* Start with live on exit temporaries.  */
      live_track_init (live, live_on_exit (liveinfo, bb));

      for (gimple_stmt_iterator gsi = gsi_last_bb (bb); !gsi_end_p (gsi);
	   gsi_prev (&gsi))
        {
	  tree var;
	  gimple *stmt = gsi_stmt (gsi);

	  /* A copy between 2 partitions does not introduce an interference
	     by itself.  If they did, you would never be able to coalesce
	     two things which are copied.  If the two variables really do
	     conflict, they will conflict elsewhere in the program.

	     This is handled by simply removing the SRC of the copy from the
	     live list, and processing the stmt normally.  */
	  if (is_gimple_assign (stmt))
	    {
	      tree lhs = gimple_assign_lhs (stmt);
	      tree rhs1 = gimple_assign_rhs1 (stmt);
	      if (gimple_assign_copy_p (stmt)
                  && TREE_CODE (lhs) == SSA_NAME
                  && TREE_CODE (rhs1) == SSA_NAME)
		live_track_clear_var (live, rhs1);
	    }
	  else if (is_gimple_debug (stmt))
	    continue;

	  /* For stmts with more than one SSA_NAME definition pretend all the
	     SSA_NAME outputs but the first one are live at this point, so
	     that conflicts are added in between all those even when they are
	     actually not really live after the asm, because expansion might
	     copy those into pseudos after the asm and if multiple outputs
	     share the same partition, it might overwrite those that should
	     be live.  E.g.
	     asm volatile (".." : "=r" (a) : "=r" (b) : "0" (a), "1" (a));
	     return a;
	     See PR70593.  */
	  bool first = true;
	  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF)
	    if (first)
	      first = false;
	    else
	      live_track_process_use (live, var);

	  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF)
	    live_track_process_def (live, var, graph);

	  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
	    live_track_process_use (live, var);
	}

      /* If result of a PHI is unused, looping over the statements will not
	 record any conflicts since the def was never live.  Since the PHI node
	 is going to be translated out of SSA form, it will insert a copy.
	 There must be a conflict recorded between the result of the PHI and
	 any variables that are live.  Otherwise the out-of-ssa translation
	 may create incorrect code.  */
      for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
	   gsi_next (&gsi))
	{
	  gphi *phi = gsi.phi ();
	  tree result = PHI_RESULT (phi);
	  if (virtual_operand_p (result))
	    continue;
	  if (live_track_live_p (live, result))
	    live_track_process_def (live, result, graph);
	}

      /* Pretend there are defs for params' default defs at the start
	 of the (post-)entry block.  This will prevent PARM_DECLs from
	 coalescing into the same partition.  Although RESULT_DECLs'
	 default defs don't have a useful initial value, we have to
	 prevent them from coalescing with PARM_DECLs' default defs
	 too, otherwise assign_parms would attempt to assign different
	 RTL to the same partition.  */
      if (bb == entry)
	{
	  unsigned i;
	  tree var;

	  FOR_EACH_SSA_NAME (i, var, cfun)
	    {
	      if (!SSA_NAME_IS_DEFAULT_DEF (var)
		  || !SSA_NAME_VAR (var)
		  || VAR_P (SSA_NAME_VAR (var)))
		continue;

	      live_track_process_def (live, var, graph);
	      /* Process a use too, so that it remains live and
		 conflicts with other parms' default defs, even unused
		 ones.  */
	      live_track_process_use (live, var);
	    }
	}

     live_track_clear_base_vars (live);
    }

  delete_live_track (live);
  return graph;
}

/* Print a failure to coalesce a MUST_COALESCE pair X and Y.  */

static inline void
fail_abnormal_edge_coalesce (int x, int y)
{
  fprintf (stderr, "\nUnable to coalesce ssa_names %d and %d",x, y);
  fprintf (stderr, " which are marked as MUST COALESCE.\n");
  print_generic_expr (stderr, ssa_name (x), TDF_SLIM);
  fprintf (stderr, " and  ");
  print_generic_stmt (stderr, ssa_name (y), TDF_SLIM);

  internal_error ("SSA corruption");
}

/* If VAR is an SSA_NAME associated with a PARM_DECL or a RESULT_DECL,
   and the DECL's default def is unused (i.e., it was introduced by
   create_default_def for out-of-ssa), mark VAR and the default def for
   coalescing.  */

static void
coalesce_with_default (tree var, coalesce_list *cl, bitmap used_in_copy)
{
  if (SSA_NAME_IS_DEFAULT_DEF (var)
      || !SSA_NAME_VAR (var)
      || VAR_P (SSA_NAME_VAR (var)))
    return;

  tree ssa = ssa_default_def (cfun, SSA_NAME_VAR (var));
  if (!has_zero_uses (ssa))
    return;

  add_cost_one_coalesce (cl, SSA_NAME_VERSION (ssa), SSA_NAME_VERSION (var));
  bitmap_set_bit (used_in_copy, SSA_NAME_VERSION (var));
  /* Default defs will have their used_in_copy bits set at the beginning of
     populate_coalesce_list_for_outofssa.  */
}


/* Given var_map MAP for a region, this function creates and returns a coalesce
   list as well as recording related ssa names in USED_IN_COPIES for use later
   in the out-of-ssa or live range computation process.  */

static coalesce_list *
create_coalesce_list_for_region (var_map map, bitmap used_in_copy)
{
  gimple_stmt_iterator gsi;
  basic_block bb;
  coalesce_list *cl = create_coalesce_list ();
  gimple *stmt;
  int v1, v2, cost;

  for (unsigned j = 0; map->vec_bbs.iterate (j, &bb); ++j)
    {
      tree arg;

      for (gphi_iterator gpi = gsi_start_phis (bb);
	   !gsi_end_p (gpi);
	   gsi_next (&gpi))
	{
	  gphi *phi = gpi.phi ();
	  size_t i;
	  int ver;
	  tree res;
	  bool saw_copy = false;

	  res = gimple_phi_result (phi);
	  if (virtual_operand_p (res))
	    continue;
	  ver = SSA_NAME_VERSION (res);

	  /* Register ssa_names and coalesces between the args and the result
	     of all PHI.  */
	  for (i = 0; i < gimple_phi_num_args (phi); i++)
	    {
	      edge e = gimple_phi_arg_edge (phi, i);
	      arg = PHI_ARG_DEF (phi, i);
	      if (TREE_CODE (arg) != SSA_NAME)
		continue;

	      if (gimple_can_coalesce_p (arg, res)
		  || (e->flags & EDGE_ABNORMAL))
		{
		  saw_copy = true;
		  bitmap_set_bit (used_in_copy, SSA_NAME_VERSION (arg));
		  if ((e->flags & EDGE_ABNORMAL) == 0)
		    {
		      int cost = coalesce_cost_edge (e);
		      if (cost == 1 && has_single_use (arg))
			add_cost_one_coalesce (cl, ver, SSA_NAME_VERSION (arg));
		      else
			add_coalesce (cl, ver, SSA_NAME_VERSION (arg), cost);
		    }
		}
	    }
	  if (saw_copy)
	    bitmap_set_bit (used_in_copy, ver);
	}

      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        {
	  stmt = gsi_stmt (gsi);

	  if (is_gimple_debug (stmt))
	    continue;

	  /* Check for copy coalesces.  */
	  switch (gimple_code (stmt))
	    {
	    case GIMPLE_ASSIGN:
	      {
		tree lhs = gimple_assign_lhs (stmt);
		tree rhs1 = gimple_assign_rhs1 (stmt);
		if (gimple_assign_ssa_name_copy_p (stmt)
		    && gimple_can_coalesce_p (lhs, rhs1))
		  {
		    v1 = SSA_NAME_VERSION (lhs);
		    v2 = SSA_NAME_VERSION (rhs1);
		    cost = coalesce_cost_bb (bb);
		    add_coalesce (cl, v1, v2, cost);
		    bitmap_set_bit (used_in_copy, v1);
		    bitmap_set_bit (used_in_copy, v2);
		  }
	      }
	      break;

	    case GIMPLE_RETURN:
	      {
		tree res = DECL_RESULT (current_function_decl);
		if (VOID_TYPE_P (TREE_TYPE (res))
		    || !is_gimple_reg (res))
		  break;
		tree rhs1 = gimple_return_retval (as_a <greturn *> (stmt));
		if (!rhs1)
		  break;
		tree lhs = ssa_default_def (cfun, res);
		gcc_assert (lhs);
		if (TREE_CODE (rhs1) == SSA_NAME
		    && gimple_can_coalesce_p (lhs, rhs1))
		  {
		    v1 = SSA_NAME_VERSION (lhs);
		    v2 = SSA_NAME_VERSION (rhs1);
		    cost = coalesce_cost_bb (bb);
		    add_coalesce (cl, v1, v2, cost);
		    bitmap_set_bit (used_in_copy, v1);
		    bitmap_set_bit (used_in_copy, v2);
		  }
		break;
	      }

	    case GIMPLE_ASM:
	      {
		gasm *asm_stmt = as_a <gasm *> (stmt);
		unsigned long noutputs, i;
		unsigned long ninputs;
		tree *outputs, link;
		noutputs = gimple_asm_noutputs (asm_stmt);
		ninputs = gimple_asm_ninputs (asm_stmt);
		outputs = (tree *) alloca (noutputs * sizeof (tree));
		for (i = 0; i < noutputs; ++i)
		  {
		    link = gimple_asm_output_op (asm_stmt, i);
		    outputs[i] = TREE_VALUE (link);
		  }

		for (i = 0; i < ninputs; ++i)
		  {
                    const char *constraint;
                    tree input;
		    char *end;
		    unsigned long match;

		    link = gimple_asm_input_op (asm_stmt, i);
		    constraint
		      = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
		    input = TREE_VALUE (link);

		    if (TREE_CODE (input) != SSA_NAME)
		      continue;

		    match = strtoul (constraint, &end, 10);
		    if (match >= noutputs || end == constraint)
		      continue;

		    if (TREE_CODE (outputs[match]) != SSA_NAME)
		      continue;

		    v1 = SSA_NAME_VERSION (outputs[match]);
		    v2 = SSA_NAME_VERSION (input);

		    if (gimple_can_coalesce_p (outputs[match], input))
		      {
			cost = coalesce_cost (REG_BR_PROB_BASE,
					      optimize_bb_for_size_p (bb));
			add_coalesce (cl, v1, v2, cost);
			bitmap_set_bit (used_in_copy, v1);
			bitmap_set_bit (used_in_copy, v2);
		      }
		  }
		break;
	      }

	    default:
	      break;
	    }
	}
    }

  return cl;
}


/* Hashtable support for storing SSA names hashed by their SSA_NAME_VAR.  */

struct ssa_name_var_hash : nofree_ptr_hash <tree_node>
{
  static inline hashval_t hash (const tree_node *);
  static inline int equal (const tree_node *, const tree_node *);
};

inline hashval_t
ssa_name_var_hash::hash (const_tree n)
{
  return DECL_UID (SSA_NAME_VAR (n));
}

inline int
ssa_name_var_hash::equal (const tree_node *n1, const tree_node *n2)
{
  return SSA_NAME_VAR (n1) == SSA_NAME_VAR (n2);
}


/* This function populates coalesce list CL as well as recording related ssa
   names in USED_IN_COPIES for use later in the out-of-ssa process.  */

static void
populate_coalesce_list_for_outofssa (coalesce_list *cl, bitmap used_in_copy)
{
  tree var;
  tree first;
  int v1, v2, cost;
  unsigned i;

  /* Process result decls and live on entry variables for entry into the
     coalesce list.  */
  first = NULL_TREE;
  FOR_EACH_SSA_NAME (i, var, cfun)
    {
      if (!virtual_operand_p (var))
        {
	  coalesce_with_default (var, cl, used_in_copy);

	  /* Add coalesces between all the result decls.  */
	  if (SSA_NAME_VAR (var)
	      && TREE_CODE (SSA_NAME_VAR (var)) == RESULT_DECL)
	    {
	      bitmap_set_bit (used_in_copy, SSA_NAME_VERSION (var));
	      if (first == NULL_TREE)
		first = var;
	      else
		{
		  gcc_assert (gimple_can_coalesce_p (var, first));
		  v1 = SSA_NAME_VERSION (first);
		  v2 = SSA_NAME_VERSION (var);
		  cost = coalesce_cost_bb (EXIT_BLOCK_PTR_FOR_FN (cfun));
		  add_coalesce (cl, v1, v2, cost);
		}
	    }
	  /* Mark any default_def variables as being in the coalesce list
	     since they will have to be coalesced with the base variable.  If
	     not marked as present, they won't be in the coalesce view. */
	  if (SSA_NAME_IS_DEFAULT_DEF (var)
	      && (!has_zero_uses (var)
		  || (SSA_NAME_VAR (var)
		      && !VAR_P (SSA_NAME_VAR (var)))))
	    bitmap_set_bit (used_in_copy, SSA_NAME_VERSION (var));
	}
    }

  /* If this optimization is disabled, we need to coalesce all the
     names originating from the same SSA_NAME_VAR so debug info
     remains undisturbed.  */
  if (!flag_tree_coalesce_vars)
    {
      tree a;
      hash_table<ssa_name_var_hash> ssa_name_hash (10);

      FOR_EACH_SSA_NAME (i, a, cfun)
	{
	  if (SSA_NAME_VAR (a)
	      && !DECL_IGNORED_P (SSA_NAME_VAR (a))
	      && (!has_zero_uses (a) || !SSA_NAME_IS_DEFAULT_DEF (a)
		  || !VAR_P (SSA_NAME_VAR (a))))
	    {
	      tree *slot = ssa_name_hash.find_slot (a, INSERT);

	      if (!*slot)
		*slot = a;
	      else
		{
		  /* If the variable is a PARM_DECL or a RESULT_DECL, we
		     _require_ that all the names originating from it be
		     coalesced, because there must be a single partition
		     containing all the names so that it can be assigned
		     the canonical RTL location of the DECL safely.
		     If in_lto_p, a function could have been compiled
		     originally with optimizations and only the link
		     performed at -O0, so we can't actually require it.  */
		  const int cost
		    = (TREE_CODE (SSA_NAME_VAR (a)) == VAR_DECL || in_lto_p)
		      ? MUST_COALESCE_COST - 1 : MUST_COALESCE_COST;
		  add_coalesce (cl, SSA_NAME_VERSION (a),
				SSA_NAME_VERSION (*slot), cost);
		  bitmap_set_bit (used_in_copy, SSA_NAME_VERSION (a));
		  bitmap_set_bit (used_in_copy, SSA_NAME_VERSION (*slot));
		}
	    }
	}
    }
}


/* Attempt to coalesce ssa versions X and Y together using the partition
   mapping in MAP and checking conflicts in GRAPH.  Output any debug info to
   DEBUG, if it is nun-NULL.  */

static inline bool
attempt_coalesce (var_map map, ssa_conflicts *graph, int x, int y,
		  FILE *debug)
{
  int z;
  tree var1, var2;
  int p1, p2;

  p1 = var_to_partition (map, ssa_name (x));
  p2 = var_to_partition (map, ssa_name (y));

  if (debug)
    {
      fprintf (debug, "(%d)", x);
      print_generic_expr (debug, partition_to_var (map, p1), TDF_SLIM);
      fprintf (debug, " & (%d)", y);
      print_generic_expr (debug, partition_to_var (map, p2), TDF_SLIM);
    }

  if (p1 == p2)
    {
      if (debug)
	fprintf (debug, ": Already Coalesced.\n");
      return true;
    }

  if (debug)
    fprintf (debug, " [map: %d, %d] ", p1, p2);


  if (!ssa_conflicts_test_p (graph, p1, p2))
    {
      var1 = partition_to_var (map, p1);
      var2 = partition_to_var (map, p2);

      z = var_union (map, var1, var2);
      if (z == NO_PARTITION)
	{
	  if (debug)
	    fprintf (debug, ": Unable to perform partition union.\n");
	  return false;
	}

      /* z is the new combined partition.  Remove the other partition from
	 the list, and merge the conflicts.  */
      if (z == p1)
	ssa_conflicts_merge (graph, p1, p2);
      else
	ssa_conflicts_merge (graph, p2, p1);

      if (debug)
	fprintf (debug, ": Success -> %d\n", z);

      return true;
    }

  if (debug)
    fprintf (debug, ": Fail due to conflict\n");

  return false;
}


/* Attempt to Coalesce partitions in MAP which occur in the list CL using
   GRAPH.  Debug output is sent to DEBUG if it is non-NULL.  */

static void
coalesce_partitions (var_map map, ssa_conflicts *graph, coalesce_list *cl,
		     FILE *debug)
{
  int x = 0, y = 0;
  tree var1, var2;
  int cost;
  basic_block bb;
  edge e;
  edge_iterator ei;

  /* First, coalesce all the copies across abnormal edges.  These are not placed
     in the coalesce list because they do not need to be sorted, and simply
     consume extra memory/compilation time in large programs.  */

  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 res = PHI_RESULT (phi);
		if (virtual_operand_p (res))
		  continue;
		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;

		int v1 = SSA_NAME_VERSION (res);
		int v2 = SSA_NAME_VERSION (arg);

		if (debug)
		  fprintf (debug, "Abnormal coalesce: ");

		if (!attempt_coalesce (map, graph, v1, v2, debug))
		  fail_abnormal_edge_coalesce (v1, v2);
	      }
	  }
    }

  /* Now process the items in the coalesce list.  */

  while ((cost = pop_best_coalesce (cl, &x, &y)) != NO_BEST_COALESCE)
    {
      var1 = ssa_name (x);
      var2 = ssa_name (y);

      /* Assert the coalesces have the same base variable.  */
      gcc_assert (gimple_can_coalesce_p (var1, var2));

      if (debug)
	fprintf (debug, "Coalesce list: ");
      attempt_coalesce (map, graph, x, y, debug);
    }
}


/* 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");
}

/* Given SSA_NAMEs NAME1 and NAME2, return true if they are candidates for
   coalescing together, false otherwise.

   This must stay consistent with compute_samebase_partition_bases and 
   compute_optimized_partition_bases.  */

bool
gimple_can_coalesce_p (tree name1, tree name2)
{
  /* 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 && !flag_tree_coalesce_vars)
    return false;

  /* Now check the types.  If the types are the same, then we should
     try to coalesce V1 and V2.  */
  tree t1 = TREE_TYPE (name1);
  tree t2 = TREE_TYPE (name2);
  if (t1 == t2)
    {
    check_modes:
      /* If the base variables are the same, we're good: none of the
	 other tests below could possibly fail.  */
      var1 = SSA_NAME_VAR (name1);
      var2 = SSA_NAME_VAR (name2);
      if (var1 == var2)
	return true;

      /* We don't want to coalesce two SSA names if one of the base
	 variables is supposed to be a register while the other is
	 supposed to be on the stack.  Anonymous SSA names most often
	 take registers, but when not optimizing, user variables
	 should go on the stack, so coalescing them with the anonymous
	 variable as the partition leader would end up assigning the
	 user variable to a register.  Don't do that!  */
      bool reg1 = use_register_for_decl (name1);
      bool reg2 = use_register_for_decl (name2);
      if (reg1 != reg2)
	return false;

      /* Check that the promoted modes and unsignedness are the same.
	 We don't want to coalesce if the promoted modes would be
	 different, or if they would sign-extend differently.  Only
	 PARM_DECLs and RESULT_DECLs have different promotion rules,
	 so skip the test if both are variables, or both are anonymous
	 SSA_NAMEs.  */
      int unsigned1, unsigned2;
      return ((!var1 || VAR_P (var1)) && (!var2 || VAR_P (var2)))
	|| ((promote_ssa_mode (name1, &unsigned1)
	     == promote_ssa_mode (name2, &unsigned2))
	    && unsigned1 == unsigned2);
    }

  /* If alignment requirements are different, we can't coalesce.  */
  if (MINIMUM_ALIGNMENT (t1,
			 var1 ? DECL_MODE (var1) : TYPE_MODE (t1),
			 var1 ? LOCAL_DECL_ALIGNMENT (var1) : TYPE_ALIGN (t1))
      != MINIMUM_ALIGNMENT (t2,
			    var2 ? DECL_MODE (var2) : TYPE_MODE (t2),
			    var2 ? LOCAL_DECL_ALIGNMENT (var2) : TYPE_ALIGN (t2)))
    return false;

  /* If the types are not the same, see whether they are compatible.  This
     (for example) allows coalescing when the types are fundamentally the
     same, but just have different names.  */
  if (types_compatible_p (t1, t2))
    goto check_modes;

  return false;
}

/* 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.  This must match gimple_can_coalesce_p in the
   optimized case.  */

static void
compute_optimized_partition_bases (var_map map, bitmap used_in_copies,
				   coalesce_list *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 *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 *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;
  unsigned i;
  edge_iterator ei;
  for (i = 0; map->vec_bbs.iterate (i, &bb); ++i)
    {
      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 res = PHI_RESULT (phi);
		if (virtual_operand_p (res))
		  continue;
		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;

		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;
  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);
}

/* Given an initial var_map MAP, coalesce variables and return a partition map
   with the resulting coalesce.  Note that this function is called in either
   live range computation context or out-of-ssa context, indicated by MAP.  */

extern void
coalesce_ssa_name (var_map map)
{
  tree_live_info_p liveinfo;
  ssa_conflicts *graph;
  coalesce_list *cl;
  auto_bitmap used_in_copies;

  bitmap_tree_view (used_in_copies);
  cl = create_coalesce_list_for_region (map, used_in_copies);
  if (map->outofssa_p)
    populate_coalesce_list_for_outofssa (cl, used_in_copies);
  bitmap_list_view (used_in_copies);

  if (dump_file && (dump_flags & TDF_DETAILS))
    dump_var_map (dump_file, map);

  partition_view_bitmap (map, used_in_copies);

  compute_optimized_partition_bases (map, used_in_copies, cl);

  if (num_var_partitions (map) < 1)
    {
      delete_coalesce_list (cl);
      return;
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    dump_var_map (dump_file, map);

  liveinfo = calculate_live_ranges (map, false);

  if (dump_file && (dump_flags & TDF_DETAILS))
    dump_live_info (dump_file, liveinfo, LIVEDUMP_ENTRY);

  /* Build a conflict graph.  */
  graph = build_ssa_conflict_graph (liveinfo);
  delete_tree_live_info (liveinfo);
  if (dump_file && (dump_flags & TDF_DETAILS))
    ssa_conflicts_dump (dump_file, graph);

  sort_coalesce_list (cl, graph, map);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "\nAfter sorting:\n");
      dump_coalesce_list (dump_file, cl);
    }

  /* First, coalesce all live on entry variables to their base variable.
     This will ensure the first use is coming from the correct location.  */

  if (dump_file && (dump_flags & TDF_DETAILS))
    dump_var_map (dump_file, map);

  /* Now coalesce everything in the list.  */
  coalesce_partitions (map, graph, cl,
		       ((dump_flags & TDF_DETAILS) ? dump_file : NULL));

  delete_coalesce_list (cl);
  ssa_conflicts_delete (graph);
}

