/* Coalesce SSA_NAMES together for the out-of-ssa pass.
   Copyright (C) 2004-2024 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"
#include "gimple-lower-bitint.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;

	  if (map->bitint)
	    {
	      build_bitint_stmt_ssa_conflicts (stmt, live, graph, map->bitint,
					       live_track_process_def,
					       live_track_process_use);
	      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);
	  if (map->bitint && !bitmap_bit_p (map->bitint, ver))
	    continue;

	  /* 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);
		    if (map->bitint && !bitmap_bit_p (map->bitint, v1))
		      break;
		    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);
		if (map->bitint && !lhs)
		  break;
		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);
		    if (map->bitint && !bitmap_bit_p (map->bitint, v1))
		      break;
		    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 (map->bitint && !bitmap_bit_p (map->bitint, v1))
		      continue;

		    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
		    = (VAR_P (SSA_NAME_VAR (a)) || 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);
	      }
	  }
    }

  if (map->bitint
      && flag_tree_coalesce_vars
      && (optimize > 1 || parts < 500))
    for (i = 0; i < (unsigned) parts; ++i)
      {
	tree s1 = partition_to_var (map, i);
	int p1 = partition_find (tentative, i);
	for (unsigned j = i + 1; j < (unsigned) parts; ++j)
	  {
	    tree s2 = partition_to_var (map, j);
	    if (s1 == s2)
	      continue;
	    if (tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (s1)),
				    TYPE_SIZE (TREE_TYPE (s2))))
	      {
		int p2 = partition_find (tentative, j);

		if (p1 == p2)
		  continue;

		partition_union (tentative, p1, p2);
		if (partition_find (tentative, i) != p1)
		  break;
	      }
	  }
      }

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

/* For the bitint lowering pass, try harder.  Partitions which contain
   SSA_NAME default def of a PARM_DECL or have RESULT_DECL need to have
   compatible types because they will use that RESULT_DECL or PARM_DECL.
   Other partitions can have even incompatible _BitInt types, as long
   as they have the same size - those will use VAR_DECLs which are just
   arrays of the limbs.  */

static void
coalesce_bitint (var_map map, ssa_conflicts *graph)
{
  unsigned n = num_var_partitions (map);
  if (optimize <= 1 && n > 500)
    return;

  bool try_same_size = false;
  FILE *debug_file = (dump_flags & TDF_DETAILS) ? dump_file : NULL;
  for (unsigned i = 0; i < n; ++i)
    {
      tree s1 = partition_to_var (map, i);
      if ((unsigned) var_to_partition (map, s1) != i)
	continue;
      int v1 = SSA_NAME_VERSION (s1);
      for (unsigned j = i + 1; j < n; ++j)
	{
	  tree s2 = partition_to_var (map, j);
	  if (s1 == s2 || (unsigned) var_to_partition (map, s2) != j)
	    continue;
	  if (!types_compatible_p (TREE_TYPE (s1), TREE_TYPE (s2)))
	    {
	      if (!try_same_size
		  && tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (s1)),
					 TYPE_SIZE (TREE_TYPE (s2))))
		try_same_size = true;
	      continue;
	    }
	  int v2 = SSA_NAME_VERSION (s2);
	  if (attempt_coalesce (map, graph, v1, v2, debug_file)
	      && partition_to_var (map, i) != s1)
	    break;
	}
    }

  if (!try_same_size)
    return;

  unsigned i;
  bitmap_iterator bi;
  bitmap same_type = NULL;

  EXECUTE_IF_SET_IN_BITMAP (map->bitint, 0, i, bi)
    {
      tree s = ssa_name (i);
      if (!SSA_NAME_VAR (s))
	continue;
      if (TREE_CODE (SSA_NAME_VAR (s)) != RESULT_DECL
	  && (TREE_CODE (SSA_NAME_VAR (s)) != PARM_DECL
	      || !SSA_NAME_IS_DEFAULT_DEF (s)))
	continue;
      if (same_type == NULL)
	same_type = BITMAP_ALLOC (NULL);
      int p = var_to_partition (map, s);
      bitmap_set_bit (same_type, p);
    }

  for (i = 0; i < n; ++i)
    {
      if (same_type && bitmap_bit_p (same_type, i))
	continue;
      tree s1 = partition_to_var (map, i);
      if ((unsigned) var_to_partition (map, s1) != i)
	continue;
      int v1 = SSA_NAME_VERSION (s1);
      for (unsigned j = i + 1; j < n; ++j)
	{
	  if (same_type && bitmap_bit_p (same_type, j))
	    continue;

	  tree s2 = partition_to_var (map, j);
	  if (s1 == s2 || (unsigned) var_to_partition (map, s2) != j)
	    continue;

	  if (!tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (s1)),
				   TYPE_SIZE (TREE_TYPE (s2))))
	    continue;

	  int v2 = SSA_NAME_VERSION (s2);
	  if (attempt_coalesce (map, graph, v1, v2, debug_file)
	      && partition_to_var (map, i) != s1)
	    break;
	}
    }

  BITMAP_FREE (same_type);
}

/* 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 (map->bitint)
    bitmap_ior_into (used_in_copies, map->bitint);

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

  if (map->bitint && flag_tree_coalesce_vars)
    coalesce_bitint (map, graph);

  ssa_conflicts_delete (graph);
}
