/* Graph coloring register allocator
   Copyright (C) 2001, 2002 Free Software Foundation, Inc.
   Contributed by Michael Matz <matz@suse.de>
   and Daniel Berlin <dan@cgsoftware.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 2, 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 COPYING.  If not, write to the Free Software
   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
#include "function.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "df.h"
#include "output.h"
#include "ra.h"

/* This file is part of the graph coloring register allocator.
   It contains the graph colorizer.  Given an interference graph
   as set up in ra-build.c the toplevel function in this file
   (ra_colorize_graph) colorizes the graph, leaving a list
   of colored, coalesced and spilled nodes.

   The algorithm used is a merge of George & Appels iterative coalescing
   and optimistic coalescing, switchable at runtime.  The current default
   is "optimistic coalescing +", which is based on the normal Briggs/Cooper
   framework.  We can also use biased coloring.  Most of the structure
   here follows the different papers.

   Additionally there is a custom step to locally improve the overall
   spill cost of the colored graph (recolor_spills).  */

static void push_list (struct dlist *, struct dlist **);
static void push_list_end (struct dlist *, struct dlist **);
static void free_dlist (struct dlist **);
static void put_web_at_end (struct web *, enum node_type);
static void put_move (struct move *, enum move_type);
static void build_worklists (struct df *);
static void enable_move (struct web *);
static void decrement_degree (struct web *, int);
static void simplify (void);
static void remove_move_1 (struct web *, struct move *);
static void remove_move (struct web *, struct move *);
static void add_worklist (struct web *);
static int ok (struct web *, struct web *);
static int conservative (struct web *, struct web *);
static inline unsigned int simplify_p (enum node_type);
static void combine (struct web *, struct web *);
static void coalesce (void);
static void freeze_moves (struct web *);
static void freeze (void);
static void select_spill (void);
static int color_usable_p (int, HARD_REG_SET, HARD_REG_SET,
			   enum machine_mode);
int get_free_reg (HARD_REG_SET, HARD_REG_SET, enum machine_mode);
static int get_biased_reg (HARD_REG_SET, HARD_REG_SET, HARD_REG_SET,
			   HARD_REG_SET, enum machine_mode);
static int count_long_blocks (HARD_REG_SET, int);
static char * hardregset_to_string (HARD_REG_SET);
static void calculate_dont_begin (struct web *, HARD_REG_SET *);
static void colorize_one_web (struct web *, int);
static void assign_colors (void);
static void try_recolor_web (struct web *);
static void insert_coalesced_conflicts (void);
static int comp_webs_maxcost (const void *, const void *);
static void recolor_spills (void);
static void check_colors (void);
static void restore_conflicts_from_coalesce (struct web *);
static void break_coalesced_spills (void);
static void unalias_web (struct web *);
static void break_aliases_to_web (struct web *);
static void break_precolored_alias (struct web *);
static void init_web_pairs (void);
static void add_web_pair_cost (struct web *, struct web *,
		               unsigned HOST_WIDE_INT, unsigned int);
static int comp_web_pairs (const void *, const void *);
static void sort_and_combine_web_pairs (int);
static void aggressive_coalesce (void);
static void extended_coalesce_2 (void);
static void check_uncoalesced_moves (void);

static struct dlist *mv_worklist, *mv_coalesced, *mv_constrained;
static struct dlist *mv_frozen, *mv_active;

/* Push a node onto the front of the list.  */

static void
push_list (struct dlist *x, struct dlist **list)
{
  if (x->next || x->prev)
    abort ();
  x->next = *list;
  if (*list)
    (*list)->prev = x;
  *list = x;
}

static void
push_list_end (struct dlist *x, struct dlist **list)
{
  if (x->prev || x->next)
    abort ();
  if (!*list)
    {
      *list = x;
      return;
    }
  while ((*list)->next)
    list = &((*list)->next);
  x->prev = *list;
  (*list)->next = x;
}

/* Remove a node from the list.  */

void
remove_list (struct dlist *x, struct dlist **list)
{
  struct dlist *y = x->prev;
  if (y)
    y->next = x->next;
  else
    *list = x->next;
  y = x->next;
  if (y)
    y->prev = x->prev;
  x->next = x->prev = NULL;
}

/* Pop the front of the list.  */

struct dlist *
pop_list (struct dlist **list)
{
  struct dlist *r = *list;
  if (r)
    remove_list (r, list);
  return r;
}

/* Free the given double linked list.  */

static void
free_dlist (struct dlist **list)
{
  *list = NULL;
}

/* The web WEB should get the given new TYPE.  Put it onto the
   appropriate list.
   Inline, because it's called with constant TYPE every time.  */

inline void
put_web (struct web *web, enum node_type type)
{
  switch (type)
    {
      case INITIAL:
      case FREE:
      case FREEZE:
      case SPILL:
      case SPILLED:
      case COALESCED:
      case COLORED:
      case SELECT:
	push_list (web->dlink, &WEBS(type));
	break;
      case PRECOLORED:
	push_list (web->dlink, &WEBS(INITIAL));
	break;
      case SIMPLIFY:
	if (web->spill_temp)
	  push_list (web->dlink, &WEBS(type = SIMPLIFY_SPILL));
	else if (web->add_hardregs)
	  push_list (web->dlink, &WEBS(type = SIMPLIFY_FAT));
	else
	  push_list (web->dlink, &WEBS(SIMPLIFY));
	break;
      default:
	abort ();
    }
  web->type = type;
}

/* After we are done with the whole pass of coloring/spilling,
   we reset the lists of webs, in preparation of the next pass.
   The spilled webs become free, colored webs go to the initial list,
   coalesced webs become free or initial, according to what type of web
   they are coalesced to.  */

void
reset_lists (void)
{
  struct dlist *d;
  unsigned int i;
  if (WEBS(SIMPLIFY) || WEBS(SIMPLIFY_SPILL) || WEBS(SIMPLIFY_FAT)
      || WEBS(FREEZE) || WEBS(SPILL) || WEBS(SELECT))
    abort ();

  while ((d = pop_list (&WEBS(COALESCED))) != NULL)
    {
      struct web *web = DLIST_WEB (d);
      struct web *aweb = alias (web);
      /* Note, how alias() becomes invalid through the two put_web()'s
	 below.  It might set the type of a web to FREE (from COALESCED),
	 which itself is a target of aliasing (i.e. in the middle of
	 an alias chain).  We can handle this by checking also for
	 type == FREE.  Note nevertheless, that alias() is invalid
	 henceforth.  */
      if (aweb->type == SPILLED || aweb->type == FREE)
	put_web (web, FREE);
      else
	put_web (web, INITIAL);
    }
  while ((d = pop_list (&WEBS(SPILLED))) != NULL)
    put_web (DLIST_WEB (d), FREE);
  while ((d = pop_list (&WEBS(COLORED))) != NULL)
    put_web (DLIST_WEB (d), INITIAL);

  /* All free webs have no conflicts anymore.  */
  for (d = WEBS(FREE); d; d = d->next)
    {
      struct web *web = DLIST_WEB (d);
      BITMAP_XFREE (web->useless_conflicts);
      web->useless_conflicts = NULL;
    }

  /* Sanity check, that we only have free, initial or precolored webs.  */
  for (i = 0; i < num_webs; i++)
    {
      struct web *web = ID2WEB (i);
      if (web->type != INITIAL && web->type != FREE && web->type != PRECOLORED)
	abort ();
    }
  free_dlist (&mv_worklist);
  free_dlist (&mv_coalesced);
  free_dlist (&mv_constrained);
  free_dlist (&mv_frozen);
  free_dlist (&mv_active);
}

/* Similar to put_web(), but add the web to the end of the appropriate
   list.  Additionally TYPE may not be SIMPLIFY.  */

static void
put_web_at_end (struct web *web, enum node_type type)
{
  if (type == PRECOLORED)
    type = INITIAL;
  else if (type == SIMPLIFY)
    abort ();
  push_list_end (web->dlink, &WEBS(type));
  web->type = type;
}

/* Unlink WEB from the list it's currently on (which corresponds to
   its current type).  */

void
remove_web_from_list (struct web *web)
{
  if (web->type == PRECOLORED)
    remove_list (web->dlink, &WEBS(INITIAL));
  else
    remove_list (web->dlink, &WEBS(web->type));
}

/* Give MOVE the TYPE, and link it into the correct list.  */

static inline void
put_move (struct move *move, enum move_type type)
{
  switch (type)
    {
      case WORKLIST:
	push_list (move->dlink, &mv_worklist);
	break;
      case MV_COALESCED:
	push_list (move->dlink, &mv_coalesced);
	break;
      case CONSTRAINED:
	push_list (move->dlink, &mv_constrained);
	break;
      case FROZEN:
	push_list (move->dlink, &mv_frozen);
	break;
      case ACTIVE:
	push_list (move->dlink, &mv_active);
	break;
      default:
	abort ();
    }
  move->type = type;
}

/* Build the worklists we are going to process.  */

static void
build_worklists (struct df *df ATTRIBUTE_UNUSED)
{
  struct dlist *d, *d_next;
  struct move_list *ml;

  /* If we are not the first pass, put all stackwebs (which are still
     backed by a new pseudo, but conceptually can stand for a stackslot,
     i.e. it doesn't really matter if they get a color or not), on
     the SELECT stack first, those with lowest cost first.  This way
     they will be colored last, so do not constrain the coloring of the
     normal webs.  But still those with the highest count are colored
     before, i.e. get a color more probable.  The use of stackregs is
     a pure optimization, and all would work, if we used real stackslots
     from the begin.  */
  if (ra_pass > 1)
    {
      unsigned int i, num, max_num;
      struct web **order2web;
      max_num = num_webs - num_subwebs;
      order2web = xmalloc (max_num * sizeof (order2web[0]));
      for (i = 0, num = 0; i < max_num; i++)
	if (id2web[i]->regno >= max_normal_pseudo)
	  order2web[num++] = id2web[i];
      if (num)
	{
	  qsort (order2web, num, sizeof (order2web[0]), comp_webs_maxcost);
	  for (i = num - 1;; i--)
	    {
	      struct web *web = order2web[i];
	      struct conflict_link *wl;
	      remove_list (web->dlink, &WEBS(INITIAL));
	      put_web (web, SELECT);
	      for (wl = web->conflict_list; wl; wl = wl->next)
		{
		  struct web *pweb = wl->t;
		  pweb->num_conflicts -= 1 + web->add_hardregs;
		}
	      if (i == 0)
		break;
	    }
	}
      free (order2web);
    }

  /* For all remaining initial webs, classify them.  */
  for (d = WEBS(INITIAL); d; d = d_next)
    {
      struct web *web = DLIST_WEB (d);
      d_next = d->next;
      if (web->type == PRECOLORED)
        continue;

      remove_list (d, &WEBS(INITIAL));
      if (web->num_conflicts >= NUM_REGS (web))
	put_web (web, SPILL);
      else if (web->moves)
	put_web (web, FREEZE);
      else
	put_web (web, SIMPLIFY);
    }

  /* And put all moves on the worklist for iterated coalescing.
     Note, that if iterated coalescing is off, then wl_moves doesn't
     contain any moves.  */
  for (ml = wl_moves; ml; ml = ml->next)
    if (ml->move)
      {
	struct move *m = ml->move;
        d = ra_calloc (sizeof (struct dlist));
        DLIST_MOVE (d) = m;
        m->dlink = d;
	put_move (m, WORKLIST);
      }
}

/* Enable the active moves, in which WEB takes part, to be processed.  */

static void
enable_move (struct web *web)
{
  struct move_list *ml;
  for (ml = web->moves; ml; ml = ml->next)
    if (ml->move->type == ACTIVE)
      {
	remove_list (ml->move->dlink, &mv_active);
	put_move (ml->move, WORKLIST);
      }
}

/* Decrement the degree of node WEB by the amount DEC.
   Possibly change the type of WEB, if the number of conflicts is
   now smaller than its freedom.  */

static void
decrement_degree (struct web *web, int dec)
{
  int before = web->num_conflicts;
  web->num_conflicts -= dec;
  if (web->num_conflicts < NUM_REGS (web) && before >= NUM_REGS (web))
    {
      struct conflict_link *a;
      enable_move (web);
      for (a = web->conflict_list; a; a = a->next)
	{
	  struct web *aweb = a->t;
	  if (aweb->type != SELECT && aweb->type != COALESCED)
	    enable_move (aweb);
	}
      if (web->type != FREEZE)
	{
	  remove_web_from_list (web);
	  if (web->moves)
	    put_web (web, FREEZE);
	  else
	    put_web (web, SIMPLIFY);
	}
    }
}

/* Repeatedly simplify the nodes on the simplify worklists.  */

static void
simplify (void)
{
  struct dlist *d;
  struct web *web;
  struct conflict_link *wl;
  while (1)
    {
      /* We try hard to color all the webs resulting from spills first.
	 Without that on register starved machines (x86 e.g) with some live
	 DImode pseudos, -fPIC, and an asm requiring %edx, it might be, that
	 we do rounds over rounds, because the conflict graph says, we can
	 simplify those short webs, but later due to irregularities we can't
	 color those pseudos.  So we have to spill them, which in later rounds
	 leads to other spills.  */
      d = pop_list (&WEBS(SIMPLIFY));
      if (!d)
	d = pop_list (&WEBS(SIMPLIFY_FAT));
      if (!d)
	d = pop_list (&WEBS(SIMPLIFY_SPILL));
      if (!d)
	break;
      web = DLIST_WEB (d);
      ra_debug_msg (DUMP_PROCESS, " simplifying web %3d, conflicts = %d\n",
		 web->id, web->num_conflicts);
      put_web (web, SELECT);
      for (wl = web->conflict_list; wl; wl = wl->next)
	{
	  struct web *pweb = wl->t;
	  if (pweb->type != SELECT && pweb->type != COALESCED)
	    {
	      decrement_degree (pweb, 1 + web->add_hardregs);
	    }
	}
    }
}

/* Helper function to remove a move from the movelist of the web.  */

static void
remove_move_1 (struct web *web, struct move *move)
{
  struct move_list *ml = web->moves;
  if (!ml)
    return;
  if (ml->move == move)
    {
      web->moves = ml->next;
      return;
    }
  for (; ml->next && ml->next->move != move; ml = ml->next) ;
  if (!ml->next)
    return;
  ml->next = ml->next->next;
}

/* Remove a move from the movelist of the web.  Actually this is just a
   wrapper around remove_move_1(), making sure, the removed move really is
   not in the list anymore.  */

static void
remove_move (struct web *web, struct move *move)
{
  struct move_list *ml;
  remove_move_1 (web, move);
  for (ml = web->moves; ml; ml = ml->next)
    if (ml->move == move)
      abort ();
}

/* Merge the moves for the two webs into the first web's movelist.  */

void
merge_moves (struct web *u, struct web *v)
{
  regset seen;
  struct move_list *ml, *ml_next;

  seen = BITMAP_XMALLOC ();
  for (ml = u->moves; ml; ml = ml->next)
    bitmap_set_bit (seen, INSN_UID (ml->move->insn));
  for (ml = v->moves; ml; ml = ml_next)
    {
      ml_next = ml->next;
      if (! bitmap_bit_p (seen, INSN_UID (ml->move->insn)))
        {
	  ml->next = u->moves;
	  u->moves = ml;
	}
    }
  BITMAP_XFREE (seen);
  v->moves = NULL;
}

/* Add a web to the simplify worklist, from the freeze worklist.  */

static void
add_worklist (struct web *web)
{
  if (web->type != PRECOLORED && !web->moves
      && web->num_conflicts < NUM_REGS (web))
    {
      remove_list (web->dlink, &WEBS(FREEZE));
      put_web (web, SIMPLIFY);
    }
}

/* Precolored node coalescing heuristic.  */

static int
ok (struct web *target, struct web *source)
{
  struct conflict_link *wl;
  int i;
  int color = source->color;
  int size;

  /* Normally one would think, the next test wouldn't be needed.
     We try to coalesce S and T, and S has already a color, and we checked
     when processing the insns, that both have the same mode.  So naively
     we could conclude, that of course that mode was valid for this color.
     Hah.  But there is sparc.  Before reload there are copy insns
     (e.g. the ones copying arguments to locals) which happily refer to
     colors in invalid modes.  We can't coalesce those things.  */
  if (! HARD_REGNO_MODE_OK (source->color, GET_MODE (target->orig_x)))
    return 0;

  /* Sanity for funny modes.  */
  size = HARD_REGNO_NREGS (color, GET_MODE (target->orig_x));
  if (!size)
    return 0;

  /* We can't coalesce target with a precolored register which isn't in
     usable_regs.  */
  for (i = size; i--;)
    if (TEST_HARD_REG_BIT (never_use_colors, color + i)
	|| !TEST_HARD_REG_BIT (target->usable_regs, color + i)
	/* Before usually calling ok() at all, we already test, if the
	   candidates conflict in sup_igraph.  But when wide webs are
	   coalesced to hardregs, we only test the hardweb coalesced into.
	   This is only the begin color.  When actually coalescing both,
	   it will also take the following size colors, i.e. their webs.
	   We nowhere checked if the candidate possibly conflicts with
	   one of _those_, which is possible with partial conflicts,
	   so we simply do it here (this does one bit-test more than
	   necessary, the first color).  Note, that if X is precolored
	   bit [X*num_webs + Y] can't be set (see add_conflict_edge()).  */
	|| TEST_BIT (sup_igraph,
		     target->id * num_webs + hardreg2web[color + i]->id))
      return 0;

  for (wl = target->conflict_list; wl; wl = wl->next)
    {
      struct web *pweb = wl->t;
      if (pweb->type == SELECT || pweb->type == COALESCED)
	continue;

      /* Coalescing target (T) and source (S) is o.k, if for
	 all conflicts C of T it is true, that:
	  1) C will be colored, or
	  2) C is a hardreg (precolored), or
	  3) C already conflicts with S too, or
	  4) a web which contains C conflicts already with S.
	 XXX: we handle here only the special case of 4), that C is
	 a subreg, and the containing thing is the reg itself, i.e.
	 we dont handle the situation, were T conflicts with
	 (subreg:SI x 1), and S conflicts with (subreg:DI x 0), which
	 would be allowed also, as the S-conflict overlaps
	 the T-conflict.
         So, we first test the whole web for any of these conditions, and
         continue with the next C, if 1, 2 or 3 is true.  */
      if (pweb->num_conflicts < NUM_REGS (pweb)
	  || pweb->type == PRECOLORED
	  || TEST_BIT (igraph, igraph_index (source->id, pweb->id)) )
	continue;

      /* This is reached, if not one of 1, 2 or 3 was true.  In the case C has
         no subwebs, 4 can't be true either, so we can't coalesce S and T.  */
      if (wl->sub == NULL)
        return 0;
      else
	{
	  /* The main webs do _not_ conflict, only some parts of both.  This
	     means, that 4 is possibly true, so we need to check this too.
	     For this we go through all sub conflicts between T and C, and see if
	     the target part of C already conflicts with S.  When this is not
	     the case we disallow coalescing.  */
	  struct sub_conflict *sl;
	  for (sl = wl->sub; sl; sl = sl->next)
	    {
              if (!TEST_BIT (igraph, igraph_index (source->id, sl->t->id)))
	        return 0;
	    }
        }
    }
  return 1;
}

/* Non-precolored node coalescing heuristic.  */

static int
conservative (struct web *target, struct web *source)
{
  unsigned int k;
  unsigned int loop;
  regset seen;
  struct conflict_link *wl;
  unsigned int num_regs = NUM_REGS (target); /* XXX */

  /* k counts the resulting conflict weight, if target and source
     would be merged, and all low-degree neighbors would be
     removed.  */
  k = 0 * MAX (target->add_hardregs, source->add_hardregs);
  seen = BITMAP_XMALLOC ();
  for (loop = 0; loop < 2; loop++)
    for (wl = ((loop == 0) ? target : source)->conflict_list;
	 wl; wl = wl->next)
      {
	struct web *pweb = wl->t;
	if (pweb->type != SELECT && pweb->type != COALESCED
	    && pweb->num_conflicts >= NUM_REGS (pweb)
	    && ! REGNO_REG_SET_P (seen, pweb->id))
	  {
	    SET_REGNO_REG_SET (seen, pweb->id);
	    k += 1 + pweb->add_hardregs;
	  }
      }
  BITMAP_XFREE (seen);

  if (k >= num_regs)
    return 0;
  return 1;
}

/* If the web is coalesced, return it's alias.  Otherwise, return what
   was passed in.  */

struct web *
alias (struct web *web)
{
  while (web->type == COALESCED)
    web = web->alias;
  return web;
}

/* Returns nonzero, if the TYPE belongs to one of those representing
   SIMPLIFY types.  */

static inline unsigned int
simplify_p (enum node_type type)
{
  return type == SIMPLIFY || type == SIMPLIFY_SPILL || type == SIMPLIFY_FAT;
}

/* Actually combine two webs, that can be coalesced.  */

static void
combine (struct web *u, struct web *v)
{
  int i;
  struct conflict_link *wl;
  if (u == v || v->type == COALESCED)
    abort ();
  if ((u->regno >= max_normal_pseudo) != (v->regno >= max_normal_pseudo))
    abort ();
  remove_web_from_list (v);
  put_web (v, COALESCED);
  v->alias = u;
  u->is_coalesced = 1;
  v->is_coalesced = 1;
  u->num_aliased += 1 + v->num_aliased;
  if (flag_ra_merge_spill_costs && u->type != PRECOLORED)
    u->spill_cost += v->spill_cost;
    /*u->spill_cost = MAX (u->spill_cost, v->spill_cost);*/
  merge_moves (u, v);
  /* combine add_hardregs's of U and V.  */

  for (wl = v->conflict_list; wl; wl = wl->next)
    {
      struct web *pweb = wl->t;
      /* We don't strictly need to move conflicts between webs which are
	 already coalesced or selected, if we do iterated coalescing, or
	 better if we need not to be able to break aliases again.
	 I.e. normally we would use the condition
	 (pweb->type != SELECT && pweb->type != COALESCED).
	 But for now we simply merge all conflicts.  It doesn't take that
         much time.  */
      if (1)
	{
	  struct web *web = u;
	  int nregs = 1 + v->add_hardregs;
	  if (u->type == PRECOLORED)
	    nregs = HARD_REGNO_NREGS (u->color, GET_MODE (v->orig_x));

	  /* For precolored U's we need to make conflicts between V's
	     neighbors and as many hardregs from U as V needed if it gets
	     color U.  For now we approximate this by V->add_hardregs, which
	     could be too much in multi-length classes.  We should really
	     count how many hardregs are needed for V with color U.  When U
	     isn't precolored this loop breaks out after one iteration.  */
	  for (i = 0; i < nregs; i++)
	    {
	      if (u->type == PRECOLORED)
		web = hardreg2web[i + u->color];
	      if (wl->sub == NULL)
		record_conflict (web, pweb);
	      else
		{
		  struct sub_conflict *sl;
		  /* So, between V and PWEB there are sub_conflicts.  We
		     need to relocate those conflicts to be between WEB (==
		     U when it wasn't precolored) and PWEB.  In the case
		     only a part of V conflicted with (part of) PWEB we
		     nevertheless make the new conflict between the whole U
		     and the (part of) PWEB.  Later we might try to find in
		     U the correct subpart corresponding (by size and
		     offset) to the part of V (sl->s) which was the source
		     of the conflict.  */
		  for (sl = wl->sub; sl; sl = sl->next)
		    {
		      /* Beware: sl->s is no subweb of web (== U) but of V.
			 We try to search a corresponding subpart of U.
			 If we found none we let it conflict with the whole U.
			 Note that find_subweb() only looks for mode and
			 subreg_byte of the REG rtx but not for the pseudo
			 reg number (otherwise it would be guaranteed to
			 _not_ find any subpart).  */
		      struct web *sweb = NULL;
		      if (SUBWEB_P (sl->s))
			sweb = find_subweb (web, sl->s->orig_x);
		      if (!sweb)
			sweb = web;
		      record_conflict (sweb, sl->t);
		    }
		}
	      if (u->type != PRECOLORED)
		break;
	    }
	  if (pweb->type != SELECT && pweb->type != COALESCED)
	    decrement_degree (pweb, 1 + v->add_hardregs);
	}
    }

  /* Now merge the usable_regs together.  */
  /* XXX That merging might normally make it necessary to
     adjust add_hardregs, which also means to adjust neighbors.  This can
     result in making some more webs trivially colorable, (or the opposite,
     if this increases our add_hardregs).  Because we intersect the
     usable_regs it should only be possible to decrease add_hardregs.  So a
     conservative solution for now is to simply don't change it.  */
  u->use_my_regs = 1;
  AND_HARD_REG_SET (u->usable_regs, v->usable_regs);
  u->regclass = reg_class_subunion[u->regclass][v->regclass];
  /* Count number of possible hardregs.  This might make U a spillweb,
     but that could also happen, if U and V together had too many
     conflicts.  */
  u->num_freedom = hard_regs_count (u->usable_regs);
  u->num_freedom -= u->add_hardregs;
  /* The next would mean an invalid coalesced move (both webs have no
     possible hardreg in common), so abort.  */
  if (!u->num_freedom)
    abort();

  if (u->num_conflicts >= NUM_REGS (u)
      && (u->type == FREEZE || simplify_p (u->type)))
    {
      remove_web_from_list (u);
      put_web (u, SPILL);
    }

  /* We want the most relaxed combination of spill_temp state.
     I.e. if any was no spilltemp or a spilltemp2, the result is so too,
     otherwise if any is short, the result is too.  It remains, when both
     are normal spilltemps.  */
  if (v->spill_temp == 0)
    u->spill_temp = 0;
  else if (v->spill_temp == 2 && u->spill_temp != 0)
    u->spill_temp = 2;
  else if (v->spill_temp == 3 && u->spill_temp == 1)
    u->spill_temp = 3;
}

/* Attempt to coalesce the first thing on the move worklist.
   This is used only for iterated coalescing.  */

static void
coalesce (void)
{
  struct dlist *d = pop_list (&mv_worklist);
  struct move *m = DLIST_MOVE (d);
  struct web *source = alias (m->source_web);
  struct web *target = alias (m->target_web);

  if (target->type == PRECOLORED)
    {
      struct web *h = source;
      source = target;
      target = h;
    }
  if (source == target)
    {
      remove_move (source, m);
      put_move (m, MV_COALESCED);
      add_worklist (source);
    }
  else if (target->type == PRECOLORED
	   || TEST_BIT (sup_igraph, source->id * num_webs + target->id)
	   || TEST_BIT (sup_igraph, target->id * num_webs + source->id))
    {
      remove_move (source, m);
      remove_move (target, m);
      put_move (m, CONSTRAINED);
      add_worklist (source);
      add_worklist (target);
    }
  else if ((source->type == PRECOLORED && ok (target, source))
	   || (source->type != PRECOLORED
	       && conservative (target, source)))
    {
      remove_move (source, m);
      remove_move (target, m);
      put_move (m, MV_COALESCED);
      combine (source, target);
      add_worklist (source);
    }
  else
    put_move (m, ACTIVE);
}

/* Freeze the moves associated with the web.  Used for iterated coalescing.  */

static void
freeze_moves (struct web *web)
{
  struct move_list *ml, *ml_next;
  for (ml = web->moves; ml; ml = ml_next)
    {
      struct move *m = ml->move;
      struct web *src, *dest;
      ml_next = ml->next;
      if (m->type == ACTIVE)
	remove_list (m->dlink, &mv_active);
      else
	remove_list (m->dlink, &mv_worklist);
      put_move (m, FROZEN);
      remove_move (web, m);
      src = alias (m->source_web);
      dest = alias (m->target_web);
      src = (src == web) ? dest : src;
      remove_move (src, m);
      /* XXX GA use the original v, instead of alias(v) */
      if (!src->moves && src->num_conflicts < NUM_REGS (src))
	{
	  remove_list (src->dlink, &WEBS(FREEZE));
	  put_web (src, SIMPLIFY);
	}
    }
}

/* Freeze the first thing on the freeze worklist (only for iterated
   coalescing).  */

static void
freeze (void)
{
  struct dlist *d = pop_list (&WEBS(FREEZE));
  put_web (DLIST_WEB (d), SIMPLIFY);
  freeze_moves (DLIST_WEB (d));
}

/* The current spill heuristic.  Returns a number for a WEB.
   Webs with higher numbers are selected later.  */

static unsigned HOST_WIDE_INT (*spill_heuristic) (struct web *);

static unsigned HOST_WIDE_INT default_spill_heuristic (struct web *);

/* Our default heuristic is similar to spill_cost / num_conflicts.
   Just scaled for integer arithmetic, and it favors coalesced webs,
   and webs which span more insns with deaths.  */

static unsigned HOST_WIDE_INT
default_spill_heuristic (struct web *web)
{
  unsigned HOST_WIDE_INT ret;
  unsigned int divisor = 1;
  /* Make coalesce targets cheaper to spill, because they will be broken
     up again into smaller parts.  */
  if (flag_ra_break_aliases)
    divisor += web->num_aliased;
  divisor += web->num_conflicts;
  ret = ((web->spill_cost << 8) + divisor - 1) / divisor;
  /* It is better to spill webs that span more insns (deaths in our
     case) than other webs with the otherwise same spill_cost.  So make
     them a little bit cheaper.  Remember that spill_cost is unsigned.  */
  if (web->span_deaths < ret)
    ret -= web->span_deaths;
  return ret;
}

/* Select the cheapest spill to be potentially spilled (we don't
   *actually* spill until we need to).  */

static void
select_spill (void)
{
  unsigned HOST_WIDE_INT best = (unsigned HOST_WIDE_INT) -1;
  struct dlist *bestd = NULL;
  unsigned HOST_WIDE_INT best2 = (unsigned HOST_WIDE_INT) -1;
  struct dlist *bestd2 = NULL;
  struct dlist *d;
  for (d = WEBS(SPILL); d; d = d->next)
    {
      struct web *w = DLIST_WEB (d);
      unsigned HOST_WIDE_INT cost = spill_heuristic (w);
      if ((!w->spill_temp) && cost < best)
	{
	  best = cost;
	  bestd = d;
	}
      /* Specially marked spill temps can be spilled.  Also coalesce
	 targets can.  Eventually they will be broken up later in the
	 colorizing process, so if we have nothing better take that.  */
      else if ((w->spill_temp == 2 || w->is_coalesced) && cost < best2)
	{
	  best2 = cost;
	  bestd2 = d;
	}
    }
  if (!bestd)
    {
      bestd = bestd2;
      best = best2;
    }
  if (!bestd)
    abort ();

  /* Note the potential spill.  */
  DLIST_WEB (bestd)->was_spilled = 1;
  remove_list (bestd, &WEBS(SPILL));
  put_web (DLIST_WEB (bestd), SIMPLIFY);
  freeze_moves (DLIST_WEB (bestd));
  ra_debug_msg (DUMP_PROCESS, " potential spill web %3d, conflicts = %d\n",
	     DLIST_WEB (bestd)->id, DLIST_WEB (bestd)->num_conflicts);
}

/* Given a set of forbidden colors to begin at, and a set of still
   free colors, and MODE, returns nonzero of color C is still usable.  */

static int
color_usable_p (int c, HARD_REG_SET dont_begin_colors,
		HARD_REG_SET free_colors, enum machine_mode  mode)
{
  if (!TEST_HARD_REG_BIT (dont_begin_colors, c)
      && TEST_HARD_REG_BIT (free_colors, c)
      && HARD_REGNO_MODE_OK (c, mode))
    {
      int i, size;
      size = HARD_REGNO_NREGS (c, mode);
      for (i = 1; i < size && TEST_HARD_REG_BIT (free_colors, c + i); i++);
      if (i == size)
	return 1;
    }
  return 0;
}

/* I don't want to clutter up the actual code with ifdef's.  */
#ifdef REG_ALLOC_ORDER
#define INV_REG_ALLOC_ORDER(c) inv_reg_alloc_order[c]
#else
#define INV_REG_ALLOC_ORDER(c) c
#endif

/* Searches in FREE_COLORS for a block of hardregs of the right length
   for MODE, which doesn't begin at a hardreg mentioned in DONT_BEGIN_COLORS.
   If it needs more than one hardreg it prefers blocks beginning
   at an even hardreg, and only gives an odd begin reg if no other
   block could be found.  */

int
get_free_reg (HARD_REG_SET dont_begin_colors, HARD_REG_SET free_colors,
	      enum machine_mode mode)
{
  int c;
  int last_resort_reg = -1;
  int pref_reg = -1;
  int pref_reg_order = INT_MAX;
  int last_resort_reg_order = INT_MAX;

  for (c = 0; c < FIRST_PSEUDO_REGISTER; c++)
    if (!TEST_HARD_REG_BIT (dont_begin_colors, c)
	&& TEST_HARD_REG_BIT (free_colors, c)
	&& HARD_REGNO_MODE_OK (c, mode))
      {
	int i, size;
	size = HARD_REGNO_NREGS (c, mode);
	for (i = 1; i < size && TEST_HARD_REG_BIT (free_colors, c + i); i++);
	if (i != size)
	  {
	    c += i;
	    continue;
	  }
	if (i == size)
	  {
	    if (size < 2 || (c & 1) == 0)
	      {
		if (INV_REG_ALLOC_ORDER (c) < pref_reg_order)
		  {
		    pref_reg = c;
		    pref_reg_order = INV_REG_ALLOC_ORDER (c);
		  }
	      }
	    else if (INV_REG_ALLOC_ORDER (c) < last_resort_reg_order)
	      {
		last_resort_reg = c;
		last_resort_reg_order = INV_REG_ALLOC_ORDER (c);
	      }
	  }
	else
	  c += i;
      }
  return pref_reg >= 0 ? pref_reg : last_resort_reg;
}

/* Similar to get_free_reg(), but first search in colors provided
   by BIAS _and_ PREFER_COLORS, then in BIAS alone, then in PREFER_COLORS
   alone, and only then for any free color.  If flag_ra_biased is zero
   only do the last two steps.  */

static int
get_biased_reg (HARD_REG_SET dont_begin_colors, HARD_REG_SET bias,
		HARD_REG_SET prefer_colors, HARD_REG_SET free_colors,
		enum machine_mode mode)
{
  int c = -1;
  HARD_REG_SET s;
  if (flag_ra_biased)
    {
      COPY_HARD_REG_SET (s, dont_begin_colors);
      IOR_COMPL_HARD_REG_SET (s, bias);
      IOR_COMPL_HARD_REG_SET (s, prefer_colors);
      c = get_free_reg (s, free_colors, mode);
      if (c >= 0)
	return c;
      COPY_HARD_REG_SET (s, dont_begin_colors);
      IOR_COMPL_HARD_REG_SET (s, bias);
      c = get_free_reg (s, free_colors, mode);
      if (c >= 0)
	return c;
    }
  COPY_HARD_REG_SET (s, dont_begin_colors);
  IOR_COMPL_HARD_REG_SET (s, prefer_colors);
  c = get_free_reg (s, free_colors, mode);
  if (c >= 0)
      return c;
  c = get_free_reg (dont_begin_colors, free_colors, mode);
  return c;
}

/* Counts the number of non-overlapping bitblocks of length LEN
   in FREE_COLORS.  */

static int
count_long_blocks (HARD_REG_SET free_colors, int len)
{
  int i, j;
  int count = 0;
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
      if (!TEST_HARD_REG_BIT (free_colors, i))
	continue;
      for (j = 1; j < len; j++)
	if (!TEST_HARD_REG_BIT (free_colors, i + j))
	  break;
      /* Bits [i .. i+j-1] are free.  */
      if (j == len)
	count++;
      i += j - 1;
    }
  return count;
}

/* Given a hardreg set S, return a string representing it.
   Either as 0/1 string, or as hex value depending on the implementation
   of hardreg sets.  Note that this string is statically allocated.  */

static char *
hardregset_to_string (HARD_REG_SET s)
{
  static char string[/*FIRST_PSEUDO_REGISTER + 30*/1024];
#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDE_INT
  sprintf (string, HOST_WIDE_INT_PRINT_HEX, s);
#else
  char *c = string;
  int i,j;
  c += sprintf (c, "{ ");
  for (i = 0;i < HARD_REG_SET_LONGS; i++)
    {
      for (j = 0; j < HOST_BITS_PER_WIDE_INT; j++)
	  c += sprintf (c, "%s", ( 1 << j) & s[i] ? "1" : "0");
      c += sprintf (c, "%s", i ? ", " : "");
    }
  c += sprintf (c, " }");
#endif
  return string;
}

/* For WEB, look at its already colored neighbors, and calculate
   the set of hardregs which is not allowed as color for WEB.  Place
   that set int *RESULT.  Note that the set of forbidden begin colors
   is not the same as all colors taken up by neighbors.  E.g. suppose
   two DImode webs, but only the lo-part from one conflicts with the
   hipart from the other, and suppose the other gets colors 2 and 3
   (it needs two SImode hardregs).  Now the first can take also color
   1 or 2, although in those cases there's a partial overlap.  Only
   3 can't be used as begin color.  */

static void
calculate_dont_begin (struct web *web, HARD_REG_SET *result)
{
  struct conflict_link *wl;
  HARD_REG_SET dont_begin;
  /* The bits set in dont_begin correspond to the hardregs, at which
     WEB may not begin.  This differs from the set of _all_ hardregs which
     are taken by WEB's conflicts in the presence of wide webs, where only
     some parts conflict with others.  */
  CLEAR_HARD_REG_SET (dont_begin);
  for (wl = web->conflict_list; wl; wl = wl->next)
    {
      struct web *w;
      struct web *ptarget = alias (wl->t);
      struct sub_conflict *sl = wl->sub;
      w = sl ? sl->t : wl->t;
      while (w)
	{
	  if (ptarget->type == COLORED || ptarget->type == PRECOLORED)
	    {
	      struct web *source = (sl) ? sl->s : web;
	      unsigned int tsize = HARD_REGNO_NREGS (ptarget->color,
						     GET_MODE (w->orig_x));
	      /* ssize is only a first guess for the size.  */
	      unsigned int ssize = HARD_REGNO_NREGS (ptarget->color, GET_MODE
					             (source->orig_x));
	      unsigned int tofs = 0;
	      unsigned int sofs = 0;
	      /* C1 and C2 can become negative, so unsigned
		 would be wrong.  */
	      int c1, c2;

	      if (SUBWEB_P (w)
		  && GET_MODE_SIZE (GET_MODE (w->orig_x)) >= UNITS_PER_WORD)
		tofs = (SUBREG_BYTE (w->orig_x) / UNITS_PER_WORD);
	      if (SUBWEB_P (source)
		  && GET_MODE_SIZE (GET_MODE (source->orig_x))
		     >= UNITS_PER_WORD)
		sofs = (SUBREG_BYTE (source->orig_x) / UNITS_PER_WORD);
	      c1 = ptarget->color + tofs - sofs - ssize + 1;
	      c2 = ptarget->color + tofs + tsize - 1 - sofs;
	      if (c2 >= 0)
		{
		  if (c1 < 0)
		    c1 = 0;
		  /* Because ssize was only guessed above, which influenced our
		     begin color (c1), we need adjustment, if for that color
		     another size would be needed.  This is done by moving
		     c1 to a place, where the last of sources hardregs does not
		     overlap the first of targets colors.  */
		  while (c1 + sofs
			 + HARD_REGNO_NREGS (c1, GET_MODE (source->orig_x)) - 1
			 < ptarget->color + tofs)
		    c1++;
		  while (c1 > 0 && c1 + sofs
			 + HARD_REGNO_NREGS (c1, GET_MODE (source->orig_x)) - 1
			 > ptarget->color + tofs)
		    c1--;
		  for (; c1 <= c2; c1++)
		    SET_HARD_REG_BIT (dont_begin, c1);
		}
	    }
	  /* The next if() only gets true, if there was no wl->sub at all, in
	     which case we are only making one go through this loop with W being
	     a whole web.  */
	  if (!sl)
	    break;
	  sl = sl->next;
	  w = sl ? sl->t : NULL;
	}
    }
  COPY_HARD_REG_SET (*result, dont_begin);
}

/* Try to assign a color to WEB.  If HARD if nonzero, we try many
   tricks to get it one color, including respilling already colored
   neighbors.

   We also trie very hard, to not constrain the uncolored non-spill
   neighbors, which need more hardregs than we.  Consider a situation, 2
   hardregs free for us (0 and 1), and one of our neighbors needs 2
   hardregs, and only conflicts with us.  There are 3 hardregs at all.  Now
   a simple minded method might choose 1 as color for us.  Then our neighbor
   has two free colors (0 and 2) as it should, but they are not consecutive,
   so coloring it later would fail.  This leads to nasty problems on
   register starved machines, so we try to avoid this.  */

static void
colorize_one_web (struct web *web, int hard)
{
  struct conflict_link *wl;
  HARD_REG_SET colors, dont_begin;
  int c = -1;
  int bestc = -1;
  int neighbor_needs= 0;
  struct web *fats_parent = NULL;
  int num_fat = 0;
  int long_blocks = 0;
  int best_long_blocks = -1;
  HARD_REG_SET fat_colors;
  HARD_REG_SET bias;

  CLEAR_HARD_REG_SET (fat_colors);
  
  if (web->regno >= max_normal_pseudo)
    hard = 0;

  /* First we want to know the colors at which we can't begin.  */
  calculate_dont_begin (web, &dont_begin);
  CLEAR_HARD_REG_SET (bias);

  /* Now setup the set of colors used by our neighbors neighbors,
     and search the biggest noncolored neighbor.  */
  neighbor_needs = web->add_hardregs + 1;
  for (wl = web->conflict_list; wl; wl = wl->next)
    {
      struct web *w;
      struct web *ptarget = alias (wl->t);
      struct sub_conflict *sl = wl->sub;
      IOR_HARD_REG_SET (bias, ptarget->bias_colors);
      w = sl ? sl->t : wl->t;
      if (ptarget->type != COLORED && ptarget->type != PRECOLORED
	  && !ptarget->was_spilled)
        while (w)
	  {
	    if (find_web_for_subweb (w)->type != COALESCED
		&& w->add_hardregs >= neighbor_needs)
	      {
		neighbor_needs = w->add_hardregs;
		fats_parent = ptarget;
		num_fat++;
	      }
	    if (!sl)
	      break;
	    sl = sl->next;
	    w = sl ? sl->t : NULL;
	  }
    }

  ra_debug_msg (DUMP_COLORIZE, "colorize web %d [don't begin at %s]", web->id,
             hardregset_to_string (dont_begin));

  /* If there are some fat neighbors, remember their usable regs,
     and how many blocks are free in it for that neighbor.  */
  if (num_fat)
    {
      COPY_HARD_REG_SET (fat_colors, fats_parent->usable_regs);
      long_blocks = count_long_blocks (fat_colors, neighbor_needs + 1);
    }

  /* We break out, if we found a color which doesn't constrain
     neighbors, or if we can't find any colors.  */
  while (1)
    {
      HARD_REG_SET call_clobbered;

      /* Here we choose a hard-reg for the current web.  For non spill
         temporaries we first search in the hardregs for it's preferred
	 class, then, if we found nothing appropriate, in those of the
	 alternate class.  For spill temporaries we only search in
	 usable_regs of this web (which is probably larger than that of
	 the preferred or alternate class).  All searches first try to
	 find a non-call-clobbered hard-reg.
         XXX this should be more finegraned... First look into preferred
         non-callclobbered hardregs, then _if_ the web crosses calls, in
         alternate non-cc hardregs, and only _then_ also in preferred cc
         hardregs (and alternate ones).  Currently we don't track the number
         of calls crossed for webs.  We should.  */
      if (web->use_my_regs)
	{
	  COPY_HARD_REG_SET (colors, web->usable_regs);
	  AND_HARD_REG_SET (colors,
			    usable_regs[reg_preferred_class (web->regno)]);
	}
      else
	COPY_HARD_REG_SET (colors,
			   usable_regs[reg_preferred_class (web->regno)]);
#ifdef CANNOT_CHANGE_MODE_CLASS
      if (web->mode_changed)
        AND_COMPL_HARD_REG_SET (colors, invalid_mode_change_regs);
#endif
      COPY_HARD_REG_SET (call_clobbered, colors);
      AND_HARD_REG_SET (call_clobbered, call_used_reg_set);

      /* If this web got a color in the last pass, try to give it the
	 same color again.  This will to much better colorization
	 down the line, as we spilled for a certain coloring last time.  */
      if (web->old_color)
	{
	  c = web->old_color - 1;
	  if (!color_usable_p (c, dont_begin, colors,
			       PSEUDO_REGNO_MODE (web->regno)))
	    c = -1;
	}
      else
	c = -1;
      if (c < 0)
	c = get_biased_reg (dont_begin, bias, web->prefer_colors,
			    call_clobbered, PSEUDO_REGNO_MODE (web->regno));
      if (c < 0)
	c = get_biased_reg (dont_begin, bias, web->prefer_colors,
			  colors, PSEUDO_REGNO_MODE (web->regno));

      if (c < 0)
	{
	  if (web->use_my_regs)
	    IOR_HARD_REG_SET (colors, web->usable_regs);
	  else
	    IOR_HARD_REG_SET (colors, usable_regs
			      [reg_alternate_class (web->regno)]);
#ifdef CANNOT_CHANGE_MODE_CLASS
	  if (web->mode_changed)
	    AND_COMPL_HARD_REG_SET (colors, invalid_mode_change_regs);
#endif
	  COPY_HARD_REG_SET (call_clobbered, colors);
	  AND_HARD_REG_SET (call_clobbered, call_used_reg_set);

	  c = get_biased_reg (dont_begin, bias, web->prefer_colors,
			    call_clobbered, PSEUDO_REGNO_MODE (web->regno));
	  if (c < 0)
	    c = get_biased_reg (dont_begin, bias, web->prefer_colors,
			      colors, PSEUDO_REGNO_MODE (web->regno));
	}
      if (c < 0)
	break;
      if (bestc < 0)
        bestc = c;
      /* If one of the yet uncolored neighbors, which is not a potential
	 spill needs a block of hardregs be sure, not to destroy such a block
	 by coloring one reg in the middle.  */
      if (num_fat)
	{
	  int i;
	  int new_long;
	  HARD_REG_SET colors1;
	  COPY_HARD_REG_SET (colors1, fat_colors);
	  for (i = 0; i < 1 + web->add_hardregs; i++)
	    CLEAR_HARD_REG_BIT (colors1, c + i);
	  new_long = count_long_blocks (colors1, neighbor_needs + 1);
	  /* If we changed the number of long blocks, and it's now smaller
	     than needed, we try to avoid this color.  */
	  if (long_blocks != new_long && new_long < num_fat)
	    {
	      if (new_long > best_long_blocks)
		{
		  best_long_blocks = new_long;
		  bestc = c;
		}
	      SET_HARD_REG_BIT (dont_begin, c);
	      ra_debug_msg (DUMP_COLORIZE, " avoid %d", c);
	    }
	  else
	    /* We found a color which doesn't destroy a block.  */
	    break;
	}
      /* If we havee no fat neighbors, the current color won't become
	 "better", so we've found it.  */
      else
	break;
    }
  ra_debug_msg (DUMP_COLORIZE, " --> got %d", c < 0 ? bestc : c);
  if (bestc >= 0 && c < 0 && !web->was_spilled)
    {
      /* This is a non-potential-spill web, which got a color, which did
	 destroy a hardreg block for one of it's neighbors.  We color
	 this web anyway and hope for the best for the neighbor, if we are
	 a spill temp.  */
      if (1 || web->spill_temp)
        c = bestc;
      ra_debug_msg (DUMP_COLORIZE, " [constrains neighbors]");
    }
  ra_debug_msg (DUMP_COLORIZE, "\n");

  if (c < 0)
    {
      /* Guard against a simplified node being spilled.  */
      /* Don't abort.  This can happen, when e.g. enough registers
	 are available in colors, but they are not consecutive.  This is a
	 very serious issue if this web is a short live one, because
	 even if we spill this one here, the situation won't become better
	 in the next iteration.  It probably will have the same conflicts,
	 those will have the same colors, and we would come here again, for
	 all parts, in which this one gets split by the spill.  This
	 can result in endless iteration spilling the same register again and
	 again.  That's why we try to find a neighbor, which spans more
	 instructions that ourself, and got a color, and try to spill _that_.

	 if (DLIST_WEB (d)->was_spilled < 0)
	 abort (); */
      if (hard && (!web->was_spilled || web->spill_temp))
	{
	  unsigned int loop;
	  struct web *try = NULL;
	  struct web *candidates[8];

	  ra_debug_msg (DUMP_COLORIZE, "  *** %d spilled, although %s ***\n",
		     web->id, web->spill_temp ? "spilltemp" : "non-spill");
	  /* We make multiple passes over our conflicts, first trying to
	     spill those webs, which only got a color by chance, but
	     were potential spill ones, and if that isn't enough, in a second
	     pass also to spill normal colored webs.  If we still didn't find
	     a candidate, but we are a spill-temp, we make a third pass
	     and include also webs, which were targets for coalescing, and
	     spill those.  */
	  memset (candidates, 0, sizeof candidates);
#define set_cand(i, w) \
	  do { \
	      if (!candidates[(i)] \
		  || (candidates[(i)]->spill_cost < (w)->spill_cost)) \
		candidates[(i)] = (w); \
	  } while (0)
	  for (wl = web->conflict_list; wl; wl = wl->next)
	    {
	      struct web *w = wl->t;
	      struct web *aw = alias (w);
	      /* If we are a spill-temp, we also look at webs coalesced
		 to precolored ones.  Otherwise we only look at webs which
		 themselves were colored, or coalesced to one.  */
	      if (aw->type == PRECOLORED && w != aw && web->spill_temp
		  && flag_ra_optimistic_coalescing)
		{
		  if (!w->spill_temp)
		    set_cand (4, w);
		  else if (web->spill_temp == 2
			   && w->spill_temp == 2
			   && w->spill_cost < web->spill_cost)
		    set_cand (5, w);
		  else if (web->spill_temp != 2
			   && (w->spill_temp == 2
			       || w->spill_cost < web->spill_cost))
		    set_cand (6, w);
		  continue;
		}
	      if (aw->type != COLORED)
		continue;
	      if (w->type == COLORED && !w->spill_temp && !w->is_coalesced
		  && w->was_spilled)
		{
		  if (w->spill_cost < web->spill_cost)
		    set_cand (0, w);
		  else if (web->spill_temp)
		    set_cand (1, w);
		}
	      if (w->type == COLORED && !w->spill_temp && !w->is_coalesced
		  && !w->was_spilled)
		{
		  if (w->spill_cost < web->spill_cost)
		    set_cand (2, w);
		  else if (web->spill_temp && web->spill_temp != 2)
		    set_cand (3, w);
		}
	      if (web->spill_temp)
		{
		  if (w->type == COLORED && w->spill_temp == 2
		      && !w->is_coalesced
		      && (w->spill_cost < web->spill_cost
			  || web->spill_temp != 2))
		    set_cand (4, w);
		  if (!aw->spill_temp)
		    set_cand (5, aw);
		  if (aw->spill_temp == 2
		      && (aw->spill_cost < web->spill_cost
			  || web->spill_temp != 2))
		    set_cand (6, aw);
		  /* For boehm-gc/misc.c.  If we are a difficult spilltemp,
		     also coalesced neighbors are a chance, _even_ if they
		     too are spilltemps.  At least their coalescing can be
		     broken up, which may be reset usable_regs, and makes
		     it easier colorable.  */
		  if (web->spill_temp != 2 && aw->is_coalesced
		      && flag_ra_optimistic_coalescing)
		    set_cand (7, aw);
		}
	    }
	  for (loop = 0; try == NULL && loop < 8; loop++)
	    if (candidates[loop])
	      try = candidates[loop];
#undef set_cand
	  if (try)
	    {
	      int old_c = try->color;
	      if (try->type == COALESCED)
		{
		  if (alias (try)->type != PRECOLORED)
		    abort ();
		  ra_debug_msg (DUMP_COLORIZE, "  breaking alias %d -> %d\n",
			     try->id, alias (try)->id);
		  break_precolored_alias (try);
		  colorize_one_web (web, hard);
		}
	      else
		{
		  remove_list (try->dlink, &WEBS(COLORED));
		  put_web (try, SPILLED);
		  /* Now try to colorize us again.  Can recursively make other
		     webs also spill, until there are no more unspilled
		     neighbors.  */
		  ra_debug_msg (DUMP_COLORIZE, "  trying to spill %d\n", try->id);
		  colorize_one_web (web, hard);
		  if (web->type != COLORED)
		    {
		      /* We tried recursively to spill all already colored
			 neighbors, but we are still uncolorable.  So it made
			 no sense to spill those neighbors.  Recolor them.  */
		      remove_list (try->dlink, &WEBS(SPILLED));
		      put_web (try, COLORED);
		      try->color = old_c;
		      ra_debug_msg (DUMP_COLORIZE,
				    "  spilling %d was useless\n", try->id);
		    }
		  else
		    {
		      ra_debug_msg (DUMP_COLORIZE,
				    "  to spill %d was a good idea\n",
				    try->id);
		      remove_list (try->dlink, &WEBS(SPILLED));
		      if (try->was_spilled)
			colorize_one_web (try, 0);
		      else
			colorize_one_web (try, hard - 1);
		    }
		}
	    }
	  else
	    /* No more chances to get a color, so give up hope and
	       spill us.  */
	    put_web (web, SPILLED);
	}
      else
        put_web (web, SPILLED);
    }
  else
    {
      put_web (web, COLORED);
      web->color = c;
      if (flag_ra_biased)
	{
	  int nregs = HARD_REGNO_NREGS (c, GET_MODE (web->orig_x));
	  for (wl = web->conflict_list; wl; wl = wl->next)
	    {
	      struct web *ptarget = alias (wl->t);
	      int i;
	      for (i = 0; i < nregs; i++)
		SET_HARD_REG_BIT (ptarget->bias_colors, c + i);
	    }
	}
    }
  if (web->regno >= max_normal_pseudo && web->type == SPILLED)
    {
      web->color = an_unusable_color;
      remove_list (web->dlink, &WEBS(SPILLED));
      put_web (web, COLORED);
    }
  if (web->type == SPILLED && flag_ra_optimistic_coalescing
      && web->is_coalesced)
    {
      ra_debug_msg (DUMP_COLORIZE, "breaking aliases to web %d:", web->id);
      restore_conflicts_from_coalesce (web);
      break_aliases_to_web (web);
      insert_coalesced_conflicts ();
      ra_debug_msg (DUMP_COLORIZE, "\n");
      remove_list (web->dlink, &WEBS(SPILLED));
      put_web (web, SELECT);
      web->color = -1;
    }
}

/* Assign the colors to all nodes on the select stack.  And update the
   colors of coalesced webs.  */

static void
assign_colors (void)
{
  struct dlist *d;

  while (WEBS(SELECT))
    {
      d = pop_list (&WEBS(SELECT));
      colorize_one_web (DLIST_WEB (d), 1);
    }

  for (d = WEBS(COALESCED); d; d = d->next)
    {
      struct web *a = alias (DLIST_WEB (d));
      DLIST_WEB (d)->color = a->color;
    }
}

/* WEB is a spilled web.  Look if we can improve the cost of the graph,
   by coloring WEB, even if we then need to spill some of it's neighbors.
   For this we calculate the cost for each color C, that results when we
   _would_ give WEB color C (i.e. the cost of the then spilled neighbors).
   If the lowest cost among them is smaller than the spillcost of WEB, we
   do that recoloring, and instead spill the neighbors.

   This can sometime help, when due to irregularities in register file,
   and due to multi word pseudos, the colorization is suboptimal.  But
   be aware, that currently this pass is quite slow.  */

static void
try_recolor_web (struct web *web)
{
  struct conflict_link *wl;
  unsigned HOST_WIDE_INT *cost_neighbors;
  unsigned int *min_color;
  int newcol, c;
  HARD_REG_SET precolored_neighbors, spill_temps;
  HARD_REG_SET possible_begin, wide_seen;
  cost_neighbors = xcalloc (FIRST_PSEUDO_REGISTER, sizeof (cost_neighbors[0]));
  /* For each hard-regs count the number of preceding hardregs, which
     would overlap this color, if used in WEB's mode.  */
  min_color = xcalloc (FIRST_PSEUDO_REGISTER, sizeof (int));
  CLEAR_HARD_REG_SET (possible_begin);
  for (c = 0; c < FIRST_PSEUDO_REGISTER; c++)
    {
      int i, nregs;
      if (!HARD_REGNO_MODE_OK (c, GET_MODE (web->orig_x)))
	continue;
      nregs = HARD_REGNO_NREGS (c, GET_MODE (web->orig_x));
      for (i = 0; i < nregs; i++)
	if (!TEST_HARD_REG_BIT (web->usable_regs, c + i))
	  break;
      if (i < nregs || nregs == 0)
	continue;
      SET_HARD_REG_BIT (possible_begin, c);
      for (; nregs--;)
	if (!min_color[c + nregs])
	  min_color[c + nregs] = 1 + c;
    }
  CLEAR_HARD_REG_SET (precolored_neighbors);
  CLEAR_HARD_REG_SET (spill_temps);
  CLEAR_HARD_REG_SET (wide_seen);
  for (wl = web->conflict_list; wl; wl = wl->next)
    {
      HARD_REG_SET dont_begin;
      struct web *web2 = alias (wl->t);
      struct conflict_link *nn;
      int c1, c2;
      int wide_p = 0;
      if (wl->t->type == COALESCED || web2->type != COLORED)
	{
	  if (web2->type == PRECOLORED)
	    {
	      c1 = min_color[web2->color];
	      c1 = (c1 == 0) ? web2->color : (c1 - 1);
	      c2 = web2->color;
	      for (; c1 <= c2; c1++)
	        SET_HARD_REG_BIT (precolored_neighbors, c1);
	    }
	  continue;
	}
      /* Mark colors for which some wide webs are involved.  For
	 those the independent sets are not simply one-node graphs, so
	 they can't be recolored independent from their neighborhood.  This
	 means, that our cost calculation can be incorrect (assuming it
	 can avoid spilling a web because it thinks some colors are available,
	 although it's neighbors which itself need recoloring might take
	 away exactly those colors).  */
      if (web2->add_hardregs)
	wide_p = 1;
      for (nn = web2->conflict_list; nn && !wide_p; nn = nn->next)
	if (alias (nn->t)->add_hardregs)
	  wide_p = 1;
      calculate_dont_begin (web2, &dont_begin);
      c1 = min_color[web2->color];
      /* Note that min_color[] contains 1-based values (zero means
	 undef).  */
      c1 = c1 == 0 ? web2->color : (c1 - 1);
      c2 = web2->color + HARD_REGNO_NREGS (web2->color, GET_MODE
					   (web2->orig_x)) - 1;
      for (; c1 <= c2; c1++)
	if (TEST_HARD_REG_BIT (possible_begin, c1))
	  {
	    int nregs;
	    HARD_REG_SET colors;
	    nregs = HARD_REGNO_NREGS (c1, GET_MODE (web->orig_x));
	    COPY_HARD_REG_SET (colors, web2->usable_regs);
	    for (; nregs--;)
	      CLEAR_HARD_REG_BIT (colors, c1 + nregs);
	    if (wide_p)
	      SET_HARD_REG_BIT (wide_seen, c1);
	    if (get_free_reg (dont_begin, colors,
			      GET_MODE (web2->orig_x)) < 0)
	      {
		if (web2->spill_temp)
		  SET_HARD_REG_BIT (spill_temps, c1);
		else
		  cost_neighbors[c1] += web2->spill_cost;
	      }
	  }
    }
  newcol = -1;
  for (c = 0; c < FIRST_PSEUDO_REGISTER; c++)
    if (TEST_HARD_REG_BIT (possible_begin, c)
	&& !TEST_HARD_REG_BIT (precolored_neighbors, c)
	&& !TEST_HARD_REG_BIT (spill_temps, c)
	&& (newcol == -1
	    || cost_neighbors[c] < cost_neighbors[newcol]))
      newcol = c;
  if (newcol >= 0 && cost_neighbors[newcol] < web->spill_cost)
    {
      int nregs = HARD_REGNO_NREGS (newcol, GET_MODE (web->orig_x));
      unsigned HOST_WIDE_INT cost = 0;
      int *old_colors;
      struct conflict_link *wl_next;
      ra_debug_msg (DUMP_COLORIZE, "try to set web %d to color %d\n", web->id,
		 newcol);
      remove_list (web->dlink, &WEBS(SPILLED));
      put_web (web, COLORED);
      web->color = newcol;
      old_colors = xcalloc (num_webs, sizeof (int));
      for (wl = web->conflict_list; wl; wl = wl_next)
	{
	  struct web *web2 = alias (wl->t);
	  /* If web2 is a coalesce-target, and will become spilled
	     below in colorize_one_web(), and the current conflict wl
	     between web and web2 was only the result of that coalescing
	     this conflict will be deleted, making wl invalid.  So save
	     the next conflict right now.  Note that if web2 has indeed
	     such state, then wl->next can not be deleted in this
	     iteration.  */
	  wl_next = wl->next;
	  if (web2->type == COLORED)
	    {
	      int nregs2 = HARD_REGNO_NREGS (web2->color, GET_MODE
					     (web2->orig_x));
	      if (web->color >= web2->color + nregs2
		  || web2->color >= web->color + nregs)
		continue;
	      old_colors[web2->id] = web2->color + 1;
	      web2->color = -1;
	      remove_list (web2->dlink, &WEBS(COLORED));
	      web2->type = SELECT;
	      /* Allow webs to be spilled.  */
	      if (web2->spill_temp == 0 || web2->spill_temp == 2)
		web2->was_spilled = 1;
	      colorize_one_web (web2, 1);
	      if (web2->type == SPILLED)
		cost += web2->spill_cost;
	    }
	}
      /* The actual cost may be smaller than the guessed one, because
	 partial conflicts could result in some conflicting webs getting
	 a color, where we assumed it must be spilled.  See the comment
         above what happens, when wide webs are involved, and why in that
         case there might actually be some webs spilled although thought to
         be colorable.  */
      if (cost > cost_neighbors[newcol]
	  && nregs == 1 && !TEST_HARD_REG_BIT (wide_seen, newcol))
	abort ();
      /* But if the new spill-cost is higher than our own, then really loose.
	 Respill us and recolor neighbors as before.  */
      if (cost > web->spill_cost)
	{
	  ra_debug_msg (DUMP_COLORIZE,
		     "reset coloring of web %d, too expensive\n", web->id);
	  remove_list (web->dlink, &WEBS(COLORED));
	  web->color = -1;
	  put_web (web, SPILLED);
	  for (wl = web->conflict_list; wl; wl = wl->next)
	    {
	      struct web *web2 = alias (wl->t);
	      if (old_colors[web2->id])
		{
		  if (web2->type == SPILLED)
		    {
		      remove_list (web2->dlink, &WEBS(SPILLED));
		      web2->color = old_colors[web2->id] - 1;
		      put_web (web2, COLORED);
		    }
		  else if (web2->type == COLORED)
		    web2->color = old_colors[web2->id] - 1;
		  else if (web2->type == SELECT)
		    /* This means, that WEB2 once was a part of a coalesced
		       web, which got spilled in the above colorize_one_web()
		       call, and whose parts then got split and put back
		       onto the SELECT stack.  As the cause for that splitting
		       (the coloring of WEB) was worthless, we should again
		       coalesce the parts, as they were before.  For now we
		       simply leave them SELECTed, for our caller to take
		       care.  */
		    ;
		  else
		    abort ();
		}
	    }
	}
      free (old_colors);
    }
  free (min_color);
  free (cost_neighbors);
}

/* This ensures that all conflicts of coalesced webs are seen from
   the webs coalesced into.  combine() only adds the conflicts which
   at the time of combining were not already SELECTed or COALESCED
   to not destroy num_conflicts.  Here we add all remaining conflicts
   and thereby destroy num_conflicts.  This should be used when num_conflicts
   isn't used anymore, e.g. on a completely colored graph.  */

static void
insert_coalesced_conflicts (void)
{
  struct dlist *d;
  for (d = WEBS(COALESCED); 0 && d; d = d->next)
    {
      struct web *web = DLIST_WEB (d);
      struct web *aweb = alias (web);
      struct conflict_link *wl;
      for (wl = web->conflict_list; wl; wl = wl->next)
	{
	  struct web *tweb = aweb;
	  int i;
	  int nregs = 1 + web->add_hardregs;
	  if (aweb->type == PRECOLORED)
	    nregs = HARD_REGNO_NREGS (aweb->color, GET_MODE (web->orig_x));
	  for (i = 0; i < nregs; i++)
	    {
	      if (aweb->type == PRECOLORED)
		tweb = hardreg2web[i + aweb->color];
	      /* There might be some conflict edges laying around
		 where the usable_regs don't intersect.  This can happen
		 when first some webs were coalesced and conflicts
		 propagated, then some combining narrowed usable_regs and
		 further coalescing ignored those conflicts.  Now there are
		 some edges to COALESCED webs but not to it's alias.
		 So abort only when they really should conflict.  */
	      if ((!(tweb->type == PRECOLORED
		     || TEST_BIT (sup_igraph, tweb->id * num_webs + wl->t->id))
		   || !(wl->t->type == PRECOLORED
		        || TEST_BIT (sup_igraph,
				     wl->t->id * num_webs + tweb->id)))
		  && hard_regs_intersect_p (&tweb->usable_regs,
					    &wl->t->usable_regs))
		abort ();
	      /*if (wl->sub == NULL)
		record_conflict (tweb, wl->t);
	      else
		{
		  struct sub_conflict *sl;
		  for (sl = wl->sub; sl; sl = sl->next)
		    record_conflict (tweb, sl->t);
		}*/
	      if (aweb->type != PRECOLORED)
		break;
	    }
	}
    }
}

/* A function suitable to pass to qsort().  Compare the spill costs
   of webs W1 and W2.  When used by qsort, this would order webs with
   largest cost first.  */

static int
comp_webs_maxcost (const void *w1, const void *w2)
{
  struct web *web1 = *(struct web **)w1;
  struct web *web2 = *(struct web **)w2;
  if (web1->spill_cost > web2->spill_cost)
    return -1;
  else if (web1->spill_cost < web2->spill_cost)
    return 1;
  else
    return 0;
}

/* This tries to recolor all spilled webs.  See try_recolor_web()
   how this is done.  This just calls it for each spilled web.  */

static void
recolor_spills (void)
{
  unsigned int i, num;
  struct web **order2web;
  num = num_webs - num_subwebs;
  order2web = xmalloc (num * sizeof (order2web[0]));
  for (i = 0; i < num; i++)
    {
      order2web[i] = id2web[i];
      /* If we aren't breaking aliases, combine() wasn't merging the
         spill_costs.  So do that here to have sane measures.  */
      if (!flag_ra_merge_spill_costs && id2web[i]->type == COALESCED)
	alias (id2web[i])->spill_cost += id2web[i]->spill_cost;
    }
  qsort (order2web, num, sizeof (order2web[0]), comp_webs_maxcost);
  insert_coalesced_conflicts ();
  dump_graph_cost (DUMP_COSTS, "before spill-recolor");
  for (i = 0; i < num; i++)
    {
      struct web *web = order2web[i];
      if (web->type == SPILLED)
	try_recolor_web (web);
    }
  /* It might have been decided in try_recolor_web() (in colorize_one_web())
     that a coalesced web should be spilled, so it was put on the
     select stack.  Those webs need recoloring again, and all remaining
     coalesced webs might need their color updated, so simply call
     assign_colors() again.  */
  assign_colors ();
  free (order2web);
}

/* This checks the current color assignment for obvious errors,
   like two conflicting webs overlapping in colors, or the used colors
   not being in usable regs.  */

static void
check_colors (void)
{
  unsigned int i;
  for (i = 0; i < num_webs - num_subwebs; i++)
    {
      struct web *web = id2web[i];
      struct web *aweb = alias (web);
      struct conflict_link *wl;
      int nregs, c;
      if (aweb->type == SPILLED || web->regno >= max_normal_pseudo)
	continue;
      else if (aweb->type == COLORED)
	nregs = HARD_REGNO_NREGS (aweb->color, GET_MODE (web->orig_x));
      else if (aweb->type == PRECOLORED)
	nregs = 1;
      else
	abort ();
      /* The color must be valid for the original usable_regs.  */
      for (c = 0; c < nregs; c++)
	if (!TEST_HARD_REG_BIT (web->usable_regs, aweb->color + c))
	  abort ();
      /* Search the original (pre-coalesce) conflict list.  In the current
	 one some imprecise conflicts may be noted (due to combine() or
	 insert_coalesced_conflicts() relocating partial conflicts) making
	 it look like some wide webs are in conflict and having the same
	 color.  */
      wl = (web->have_orig_conflicts ? web->orig_conflict_list
	    : web->conflict_list);
      for (; wl; wl = wl->next)
	if (wl->t->regno >= max_normal_pseudo)
	  continue;
	else if (!wl->sub)
	  {
	    struct web *web2 = alias (wl->t);
	    int nregs2;
	    if (web2->type == COLORED)
	      nregs2 = HARD_REGNO_NREGS (web2->color, GET_MODE (web2->orig_x));
	    else if (web2->type == PRECOLORED)
	      nregs2 = 1;
	    else
	      continue;
	    if (aweb->color >= web2->color + nregs2
	        || web2->color >= aweb->color + nregs)
	      continue;
	    abort ();
	  }
	else
	  {
	    struct sub_conflict *sl;
	    int scol = aweb->color;
	    int tcol = alias (wl->t)->color;
	    if (alias (wl->t)->type == SPILLED)
	      continue;
	    for (sl = wl->sub; sl; sl = sl->next)
	      {
		int ssize = HARD_REGNO_NREGS (scol, GET_MODE (sl->s->orig_x));
		int tsize = HARD_REGNO_NREGS (tcol, GET_MODE (sl->t->orig_x));
		int sofs = 0, tofs = 0;
	        if (SUBWEB_P (sl->t)
		    && GET_MODE_SIZE (GET_MODE (sl->t->orig_x)) >= UNITS_PER_WORD)
		  tofs = (SUBREG_BYTE (sl->t->orig_x) / UNITS_PER_WORD);
	        if (SUBWEB_P (sl->s)
		    && GET_MODE_SIZE (GET_MODE (sl->s->orig_x))
		       >= UNITS_PER_WORD)
		  sofs = (SUBREG_BYTE (sl->s->orig_x) / UNITS_PER_WORD);
		if ((tcol + tofs >= scol + sofs + ssize)
		    || (scol + sofs >= tcol + tofs + tsize))
		  continue;
		abort ();
	      }
	  }
    }
}

/* WEB was a coalesced web.  Make it unaliased again, and put it
   back onto SELECT stack.  */

static void
unalias_web (struct web *web)
{
  web->alias = NULL;
  web->is_coalesced = 0;
  web->color = -1;
  /* Well, initially everything was spilled, so it isn't incorrect,
     that also the individual parts can be spilled.
     XXX this isn't entirely correct, as we also relaxed the
     spill_temp flag in combine(), which might have made components
     spill, although they were a short or spilltemp web.  */
  web->was_spilled = 1;
  remove_list (web->dlink, &WEBS(COALESCED));
  /* Spilltemps must be colored right now (i.e. as early as possible),
     other webs can be deferred to the end (the code building the
     stack assumed that in this stage only one web was colored).  */
  if (web->spill_temp && web->spill_temp != 2)
    put_web (web, SELECT);
  else
    put_web_at_end (web, SELECT);
}

/* WEB is a _target_ for coalescing which got spilled.
   Break all aliases to WEB, and restore some of its member to the state
   they were before coalescing.  Due to the suboptimal structure of
   the interference graph we need to go through all coalesced webs.
   Somewhen we'll change this to be more sane.  */

static void
break_aliases_to_web (struct web *web)
{
  struct dlist *d, *d_next;
  if (web->type != SPILLED)
    abort ();
  for (d = WEBS(COALESCED); d; d = d_next)
    {
      struct web *other = DLIST_WEB (d);
      d_next = d->next;
      /* Beware: Don't use alias() here.  We really want to check only
	 one level of aliasing, i.e. only break up webs directly
	 aliased to WEB, not also those aliased through other webs.  */
      if (other->alias == web)
	{
	  unalias_web (other);
	  ra_debug_msg (DUMP_COLORIZE, " %d", other->id);
	}
    }
  web->spill_temp = web->orig_spill_temp;
  web->spill_cost = web->orig_spill_cost;
  /* Beware: The following possibly widens usable_regs again.  While
     it was narrower there might have been some conflicts added which got
     ignored because of non-intersecting hardregsets.  All those conflicts
     would now matter again.  Fortunately we only add conflicts when
     coalescing, which is also the time of narrowing.  And we remove all
     those added conflicts again now that we unalias this web.
     Therefore this is safe to do.  */
  COPY_HARD_REG_SET (web->usable_regs, web->orig_usable_regs);
  web->is_coalesced = 0;
  web->num_aliased = 0;
  web->was_spilled = 1;
  /* Reset is_coalesced flag for webs which itself are target of coalescing.
     It was cleared above if it was coalesced to WEB.  */
  for (d = WEBS(COALESCED); d; d = d->next)
    DLIST_WEB (d)->alias->is_coalesced = 1;
}

/* WEB is a web coalesced into a precolored one.  Break that alias,
   making WEB SELECTed again.  Also restores the conflicts which resulted
   from initially coalescing both.  */

static void
break_precolored_alias (struct web *web)
{
  struct web *pre = web->alias;
  struct conflict_link *wl;
  unsigned int c = pre->color;
  unsigned int nregs = HARD_REGNO_NREGS (c, GET_MODE (web->orig_x));
  if (pre->type != PRECOLORED)
    abort ();
  unalias_web (web);
  /* Now we need to look at each conflict X of WEB, if it conflicts
     with [PRE, PRE+nregs), and remove such conflicts, of X has not other
     conflicts, which are coalesced into those precolored webs.  */
  for (wl = web->conflict_list; wl; wl = wl->next)
    {
      struct web *x = wl->t;
      struct web *y;
      unsigned int i;
      struct conflict_link *wl2;
      struct conflict_link **pcl;
      HARD_REG_SET regs;
      if (!x->have_orig_conflicts)
	continue;
      /* First look at which colors can not go away, due to other coalesces
	 still existing.  */
      CLEAR_HARD_REG_SET (regs);
      for (i = 0; i < nregs; i++)
	SET_HARD_REG_BIT (regs, c + i);
      for (wl2 = x->conflict_list; wl2; wl2 = wl2->next)
	if (wl2->t->type == COALESCED && alias (wl2->t)->type == PRECOLORED)
	  CLEAR_HARD_REG_BIT (regs, alias (wl2->t)->color);
      /* Now also remove the colors of those conflicts which already
	 were there before coalescing at all.  */
      for (wl2 = x->orig_conflict_list; wl2; wl2 = wl2->next)
	if (wl2->t->type == PRECOLORED)
	  CLEAR_HARD_REG_BIT (regs, wl2->t->color);
      /* The colors now still set are those for which WEB was the last
	 cause, i.e. those which can be removed.  */
      y = NULL;
      for (i = 0; i < nregs; i++)
	if (TEST_HARD_REG_BIT (regs, c + i))
	  {
	    struct web *sub;
	    y = hardreg2web[c + i];
	    RESET_BIT (sup_igraph, x->id * num_webs + y->id);
	    RESET_BIT (sup_igraph, y->id * num_webs + x->id);
	    RESET_BIT (igraph, igraph_index (x->id, y->id));
	    for (sub = x->subreg_next; sub; sub = sub->subreg_next)
	      RESET_BIT (igraph, igraph_index (sub->id, y->id));
	  }
      if (!y)
	continue;
      pcl = &(x->conflict_list);
      while (*pcl)
	{
	  struct web *y = (*pcl)->t;
	  if (y->type != PRECOLORED || !TEST_HARD_REG_BIT (regs, y->color))
	    pcl = &((*pcl)->next);
	  else
	    *pcl = (*pcl)->next;
	}
    }
}

/* WEB is a spilled web which was target for coalescing.
   Delete all interference edges which were added due to that coalescing,
   and break up the coalescing.  */

static void
restore_conflicts_from_coalesce (struct web *web)
{
  struct conflict_link **pcl;
  struct conflict_link *wl;
  pcl = &(web->conflict_list);
  /* No original conflict list means no conflict was added at all
     after building the graph.  So neither we nor any neighbors have
     conflicts due to this coalescing.  */
  if (!web->have_orig_conflicts)
    return;
  while (*pcl)
    {
      struct web *other = (*pcl)->t;
      for (wl = web->orig_conflict_list; wl; wl = wl->next)
	if (wl->t == other)
	  break;
      if (wl)
	{
	  /* We found this conflict also in the original list, so this
	     was no new conflict.  */
	  pcl = &((*pcl)->next);
	}
      else
	{
	  /* This is a new conflict, so delete it from us and
	     the neighbor.  */
	  struct conflict_link **opcl;
	  struct conflict_link *owl;
	  struct sub_conflict *sl;
	  wl = *pcl;
	  *pcl = wl->next;
	  if (!other->have_orig_conflicts && other->type != PRECOLORED)
	    abort ();
	  for (owl = other->orig_conflict_list; owl; owl = owl->next)
	    if (owl->t == web)
	      break;
	  if (owl)
	    abort ();
	  opcl = &(other->conflict_list);
	  while (*opcl)
	    {
	      if ((*opcl)->t == web)
		{
		  owl = *opcl;
		  *opcl = owl->next;
		  break;
		}
	      else
		{
		  opcl = &((*opcl)->next);
		}
	    }
	  if (!owl && other->type != PRECOLORED)
	    abort ();
	  /* wl and owl contain the edge data to be deleted.  */
	  RESET_BIT (sup_igraph, web->id * num_webs + other->id);
	  RESET_BIT (sup_igraph, other->id * num_webs + web->id);
	  RESET_BIT (igraph, igraph_index (web->id, other->id));
	  for (sl = wl->sub; sl; sl = sl->next)
	    RESET_BIT (igraph, igraph_index (sl->s->id, sl->t->id));
	  if (other->type != PRECOLORED)
	    {
	      for (sl = owl->sub; sl; sl = sl->next)
		RESET_BIT (igraph, igraph_index (sl->s->id, sl->t->id));
	    }
	}
    }

  /* We must restore usable_regs because record_conflict will use it.  */
  COPY_HARD_REG_SET (web->usable_regs, web->orig_usable_regs);
  /* We might have deleted some conflicts above, which really are still
     there (diamond pattern coalescing).  This is because we don't reference
     count interference edges but some of them were the result of different
     coalesces.  */
  for (wl = web->conflict_list; wl; wl = wl->next)
    if (wl->t->type == COALESCED)
      {
	struct web *tweb;
	for (tweb = wl->t->alias; tweb; tweb = tweb->alias)
	  {
	    if (wl->sub == NULL)
	      record_conflict (web, tweb);
	    else
	      {
		struct sub_conflict *sl;
		for (sl = wl->sub; sl; sl = sl->next)
		  {
		    struct web *sweb = NULL;
		    if (SUBWEB_P (sl->t))
		      sweb = find_subweb (tweb, sl->t->orig_x);
		    if (!sweb)
		      sweb = tweb;
		    record_conflict (sl->s, sweb);
		  }
	      }
	    if (tweb->type != COALESCED)
	      break;
	  }
      }
}

/* Repeatedly break aliases for spilled webs, which were target for
   coalescing, and recolorize the resulting parts.  Do this as long as
   there are any spilled coalesce targets.  */

static void
break_coalesced_spills (void)
{
  int changed = 0;
  while (1)
    {
      struct dlist *d;
      struct web *web;
      for (d = WEBS(SPILLED); d; d = d->next)
	if (DLIST_WEB (d)->is_coalesced)
	  break;
      if (!d)
	break;
      changed = 1;
      web = DLIST_WEB (d);
      ra_debug_msg (DUMP_COLORIZE, "breaking aliases to web %d:", web->id);
      restore_conflicts_from_coalesce (web);
      break_aliases_to_web (web);
      /* WEB was a spilled web and isn't anymore.  Everything coalesced
	 to WEB is now SELECTed and might potentially get a color.
	 If those other webs were itself targets of coalescing it might be
	 that there are still some conflicts from aliased webs missing,
	 because they were added in combine() right into the now
	 SELECTed web.  So we need to add those missing conflicts here.  */
      insert_coalesced_conflicts ();
      ra_debug_msg (DUMP_COLORIZE, "\n");
      remove_list (d, &WEBS(SPILLED));
      put_web (web, SELECT);
      web->color = -1;
      while (WEBS(SELECT))
	{
	  d = pop_list (&WEBS(SELECT));
	  colorize_one_web (DLIST_WEB (d), 1);
	}
    }
  if (changed)
    {
      struct dlist *d;
      for (d = WEBS(COALESCED); d; d = d->next)
	{
	  struct web *a = alias (DLIST_WEB (d));
	  DLIST_WEB (d)->color = a->color;
	}
    }
  dump_graph_cost (DUMP_COSTS, "after alias-breaking");
}

/* A structure for fast hashing of a pair of webs.
   Used to cumulate savings (from removing copy insns) for coalesced webs.
   All the pairs are also put into a single linked list.  */
struct web_pair
{
  struct web_pair *next_hash;
  struct web_pair *next_list;
  struct web *smaller;
  struct web *larger;
  unsigned int conflicts;
  unsigned HOST_WIDE_INT cost;
};

/* The actual hash table.  */
#define WEB_PAIR_HASH_SIZE 8192
static struct web_pair *web_pair_hash[WEB_PAIR_HASH_SIZE];
static struct web_pair *web_pair_list;
static unsigned int num_web_pairs;

/* Clear the hash table of web pairs.  */

static void
init_web_pairs (void)
{
  memset (web_pair_hash, 0, sizeof web_pair_hash);
  num_web_pairs = 0;
  web_pair_list = NULL;
}

/* Given two webs connected by a move with cost COST which together
   have CONFLICTS conflicts, add that pair to the hash table, or if
   already in, cumulate the costs and conflict number.  */

static void
add_web_pair_cost (struct web *web1, struct web *web2,
		   unsigned HOST_WIDE_INT cost, unsigned int conflicts)
{
  unsigned int hash;
  struct web_pair *p;
  if (web1->id > web2->id)
    {
      struct web *h = web1;
      web1 = web2;
      web2 = h;
    }
  hash = (web1->id * num_webs + web2->id) % WEB_PAIR_HASH_SIZE;
  for (p = web_pair_hash[hash]; p; p = p->next_hash)
    if (p->smaller == web1 && p->larger == web2)
      {
	p->cost += cost;
	p->conflicts += conflicts;
	return;
      }
  p = ra_alloc (sizeof *p);
  p->next_hash = web_pair_hash[hash];
  p->next_list = web_pair_list;
  p->smaller = web1;
  p->larger = web2;
  p->conflicts = conflicts;
  p->cost = cost;
  web_pair_hash[hash] = p;
  web_pair_list = p;
  num_web_pairs++;
}

/* Suitable to be passed to qsort().  Sort web pairs so, that those
   with more conflicts and higher cost (which actually is a saving
   when the moves are removed) come first.  */

static int
comp_web_pairs (const void *w1, const void *w2)
{
  struct web_pair *p1 = *(struct web_pair **)w1;
  struct web_pair *p2 = *(struct web_pair **)w2;
  if (p1->conflicts > p2->conflicts)
    return -1;
  else if (p1->conflicts < p2->conflicts)
    return 1;
  else if (p1->cost > p2->cost)
    return -1;
  else if (p1->cost < p2->cost)
    return 1;
  else
    return 0;
}

/* Given the list of web pairs, begin to combine them from the one
   with the most savings.  */

static void
sort_and_combine_web_pairs (int for_move)
{
  unsigned int i;
  struct web_pair **sorted;
  struct web_pair *p;
  if (!num_web_pairs)
    return;
  sorted = xmalloc (num_web_pairs * sizeof (sorted[0]));
  for (p = web_pair_list, i = 0; p; p = p->next_list)
    sorted[i++] = p;
  if (i != num_web_pairs)
    abort ();
  qsort (sorted, num_web_pairs, sizeof (sorted[0]), comp_web_pairs);

  /* After combining one pair, we actually should adjust the savings
     of the other pairs, if they are connected to one of the just coalesced
     pair.  Later.  */
  for (i = 0; i < num_web_pairs; i++)
    {
      struct web *w1, *w2;
      p = sorted[i];
      w1 = alias (p->smaller);
      w2 = alias (p->larger);
      if (!for_move && (w1->type == PRECOLORED || w2->type == PRECOLORED))
	continue;
      else if (w2->type == PRECOLORED)
	{
	  struct web *h = w1;
	  w1 = w2;
	  w2 = h;
	}
      if (w1 != w2
	  && !TEST_BIT (sup_igraph, w1->id * num_webs + w2->id)
	  && !TEST_BIT (sup_igraph, w2->id * num_webs + w1->id)
	  && w2->type != PRECOLORED
	  && hard_regs_intersect_p (&w1->usable_regs, &w2->usable_regs))
	  {
	    if (w1->type != PRECOLORED
		|| (w1->type == PRECOLORED && ok (w2, w1)))
	      combine (w1, w2);
	    else if (w1->type == PRECOLORED)
	      SET_HARD_REG_BIT (w2->prefer_colors, w1->color);
	  }
    }
  free (sorted);
}

/* Greedily coalesce all moves possible.  Begin with the web pair
   giving the most saving if coalesced.  */

static void
aggressive_coalesce (void)
{
  struct dlist *d;
  struct move *m;
  init_web_pairs ();
  while ((d = pop_list (&mv_worklist)) != NULL)
    if ((m = DLIST_MOVE (d)))
      {
	struct web *s = alias (m->source_web);
	struct web *t = alias (m->target_web);
	if (t->type == PRECOLORED)
	  {
	    struct web *h = s;
	    s = t;
	    t = h;
	  }
	if (s != t
	    && t->type != PRECOLORED
	    && !TEST_BIT (sup_igraph, s->id * num_webs + t->id)
	    && !TEST_BIT (sup_igraph, t->id * num_webs + s->id))
	  {
	    if ((s->type == PRECOLORED && ok (t, s))
		|| s->type != PRECOLORED)
	      {
	        put_move (m, MV_COALESCED);
		add_web_pair_cost (s, t, BLOCK_FOR_INSN (m->insn)->frequency,
				   0);
	      }
	    else if (s->type == PRECOLORED)
	      /* It is !ok(t, s).  But later when coloring the graph it might
		 be possible to take that color.  So we remember the preferred
		 color to try that first.  */
	      {
		put_move (m, CONSTRAINED);
		SET_HARD_REG_BIT (t->prefer_colors, s->color);
	      }
	  }
	else
	  {
	    put_move (m, CONSTRAINED);
	  }
      }
  sort_and_combine_web_pairs (1);
}

/* This is the difference between optimistic coalescing and
   optimistic coalescing+.  Extended coalesce tries to coalesce also
   non-conflicting nodes, not related by a move.  The criteria here is,
   the one web must be a source, the other a destination of the same insn.
   This actually makes sense, as (because they are in the same insn) they
   share many of their neighbors, and if they are coalesced, reduce the
   number of conflicts of those neighbors by one.  For this we sort the
   candidate pairs again according to savings (and this time also conflict
   number).

   This is also a comparatively slow operation, as we need to go through
   all insns, and for each insn, through all defs and uses.  */

static void
extended_coalesce_2 (void)
{
  rtx insn;
  struct ra_insn_info info;
  unsigned int n;
  init_web_pairs ();
  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
    if (INSN_P (insn) && (info = insn_df[INSN_UID (insn)]).num_defs)
      for (n = 0; n < info.num_defs; n++)
	{
	  struct web *dest = def2web[DF_REF_ID (info.defs[n])];
	  dest = alias (find_web_for_subweb (dest));
	  if (dest->type != PRECOLORED && dest->regno < max_normal_pseudo)
	    {
	      unsigned int n2;
	      for (n2 = 0; n2 < info.num_uses; n2++)
		{
		  struct web *source = use2web[DF_REF_ID (info.uses[n2])];
		  source = alias (find_web_for_subweb (source));
		  if (source->type != PRECOLORED
		      && source != dest
		      && source->regno < max_normal_pseudo
		      /* Coalesced webs end up using the same REG rtx in
			 emit_colors().  So we can only coalesce something
			 of equal modes.  */
		      && GET_MODE (source->orig_x) == GET_MODE (dest->orig_x)
		      && !TEST_BIT (sup_igraph,
				    dest->id * num_webs + source->id)
		      && !TEST_BIT (sup_igraph,
				    source->id * num_webs + dest->id)
		      && hard_regs_intersect_p (&source->usable_regs,
						&dest->usable_regs))
		    add_web_pair_cost (dest, source,
				       BLOCK_FOR_INSN (insn)->frequency,
				       dest->num_conflicts
				       + source->num_conflicts);
		}
	    }
	}
  sort_and_combine_web_pairs (0);
}

/* Check if we forgot to coalesce some moves.  */

static void
check_uncoalesced_moves (void)
{
  struct move_list *ml;
  struct move *m;
  for (ml = wl_moves; ml; ml = ml->next)
    if ((m = ml->move))
      {
	struct web *s = alias (m->source_web);
	struct web *t = alias (m->target_web);
	if (t->type == PRECOLORED)
	  {
	    struct web *h = s;
	    s = t;
	    t = h;
	  }
	if (s != t
	    && m->type != CONSTRAINED
	    /* Following can happen when a move was coalesced, but later
	       broken up again.  Then s!=t, but m is still MV_COALESCED.  */
	    && m->type != MV_COALESCED
	    && t->type != PRECOLORED
	    && ((s->type == PRECOLORED && ok (t, s))
		|| s->type != PRECOLORED)
	    && !TEST_BIT (sup_igraph, s->id * num_webs + t->id)
	    && !TEST_BIT (sup_igraph, t->id * num_webs + s->id))
	  abort ();
      }
}

/* The toplevel function in this file.  Precondition is, that
   the interference graph is built completely by ra-build.c.  This
   produces a list of spilled, colored and coalesced nodes.  */

void
ra_colorize_graph (struct df *df)
{
  if (rtl_dump_file)
    dump_igraph (df);
  build_worklists (df);

  /* With optimistic coalescing we coalesce everything we can.  */
  if (flag_ra_optimistic_coalescing)
    {
      aggressive_coalesce ();
      extended_coalesce_2 ();
    }

  /* Now build the select stack.  */
  do
    {
      simplify ();
      if (mv_worklist)
	coalesce ();
      else if (WEBS(FREEZE))
	freeze ();
      else if (WEBS(SPILL))
	select_spill ();
    }
  while (WEBS(SIMPLIFY) || WEBS(SIMPLIFY_FAT) || WEBS(SIMPLIFY_SPILL)
	 || mv_worklist || WEBS(FREEZE) || WEBS(SPILL));
  if (flag_ra_optimistic_coalescing)
    check_uncoalesced_moves ();

  /* Actually colorize the webs from the select stack.  */
  assign_colors ();
  check_colors ();
  dump_graph_cost (DUMP_COSTS, "initially");
  if (flag_ra_break_aliases)
    break_coalesced_spills ();
  check_colors ();

  /* And try to improve the cost by recoloring spilled webs.  */
  recolor_spills ();
  dump_graph_cost (DUMP_COSTS, "after spill-recolor");
  check_colors ();
}

/* Initialize this module.  */

void ra_colorize_init (void)
{
  /* FIXME: Choose spill heuristic for platform if we have one */
  spill_heuristic = default_spill_heuristic;
}

/* Free all memory.  (Note that we don't need to free any per pass
   memory).  */

void
ra_colorize_free_all (void)
{
  struct dlist *d;
  while ((d = pop_list (&WEBS(FREE))) != NULL)
    put_web (DLIST_WEB (d), INITIAL);
  while ((d = pop_list (&WEBS(INITIAL))) != NULL)
    {
      struct web *web = DLIST_WEB (d);
      struct web *wnext;
      web->orig_conflict_list = NULL;
      web->conflict_list = NULL;
      for (web = web->subreg_next; web; web = wnext)
	{
	  wnext = web->subreg_next;
	  free (web);
	}
      free (DLIST_WEB (d));
    }
}

/*
vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4:
*/
