/* IRA conflict builder.
   Copyright (C) 2006-2017 Free Software Foundation, Inc.
   Contributed by Vladimir Makarov <vmakarov@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 "target.h"
#include "rtl.h"
#include "predict.h"
#include "memmodel.h"
#include "tm_p.h"
#include "insn-config.h"
#include "regs.h"
#include "ira.h"
#include "ira-int.h"
#include "params.h"
#include "sparseset.h"
#include "addresses.h"

/* This file contains code responsible for allocno conflict creation,
   allocno copy creation and allocno info accumulation on upper level
   regions.  */

/* ira_allocnos_num array of arrays of bits, recording whether two
   allocno's conflict (can't go in the same hardware register).

   Some arrays will be used as conflict bit vector of the
   corresponding allocnos see function build_object_conflicts.  */
static IRA_INT_TYPE **conflicts;

/* Macro to test a conflict of C1 and C2 in `conflicts'.  */
#define OBJECTS_CONFLICT_P(C1, C2)					\
  (OBJECT_MIN (C1) <= OBJECT_CONFLICT_ID (C2)				\
   && OBJECT_CONFLICT_ID (C2) <= OBJECT_MAX (C1)			\
   && TEST_MINMAX_SET_BIT (conflicts[OBJECT_CONFLICT_ID (C1)],		\
			   OBJECT_CONFLICT_ID (C2),			\
			   OBJECT_MIN (C1), OBJECT_MAX (C1)))


/* Record a conflict between objects OBJ1 and OBJ2.  If necessary,
   canonicalize the conflict by recording it for lower-order subobjects
   of the corresponding allocnos.  */
static void
record_object_conflict (ira_object_t obj1, ira_object_t obj2)
{
  ira_allocno_t a1 = OBJECT_ALLOCNO (obj1);
  ira_allocno_t a2 = OBJECT_ALLOCNO (obj2);
  int w1 = OBJECT_SUBWORD (obj1);
  int w2 = OBJECT_SUBWORD (obj2);
  int id1, id2;

  /* Canonicalize the conflict.  If two identically-numbered words
     conflict, always record this as a conflict between words 0.  That
     is the only information we need, and it is easier to test for if
     it is collected in each allocno's lowest-order object.  */
  if (w1 == w2 && w1 > 0)
    {
      obj1 = ALLOCNO_OBJECT (a1, 0);
      obj2 = ALLOCNO_OBJECT (a2, 0);
    }
  id1 = OBJECT_CONFLICT_ID (obj1);
  id2 = OBJECT_CONFLICT_ID (obj2);

  SET_MINMAX_SET_BIT (conflicts[id1], id2, OBJECT_MIN (obj1),
		      OBJECT_MAX (obj1));
  SET_MINMAX_SET_BIT (conflicts[id2], id1, OBJECT_MIN (obj2),
		      OBJECT_MAX (obj2));
}

/* Build allocno conflict table by processing allocno live ranges.
   Return true if the table was built.  The table is not built if it
   is too big.  */
static bool
build_conflict_bit_table (void)
{
  int i;
  unsigned int j;
  enum reg_class aclass;
  int object_set_words, allocated_words_num, conflict_bit_vec_words_num;
  live_range_t r;
  ira_allocno_t allocno;
  ira_allocno_iterator ai;
  sparseset objects_live;
  ira_object_t obj;
  ira_allocno_object_iterator aoi;

  allocated_words_num = 0;
  FOR_EACH_ALLOCNO (allocno, ai)
    FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
      {
	if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
	  continue;
	conflict_bit_vec_words_num
	  = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
	     / IRA_INT_BITS);
	allocated_words_num += conflict_bit_vec_words_num;
	if ((uint64_t) allocated_words_num * sizeof (IRA_INT_TYPE)
	    > (uint64_t) IRA_MAX_CONFLICT_TABLE_SIZE * 1024 * 1024)
	  {
	    if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
	      fprintf
		(ira_dump_file,
		 "+++Conflict table will be too big(>%dMB) -- don't use it\n",
		 IRA_MAX_CONFLICT_TABLE_SIZE);
	    return false;
	  }
      }

  conflicts = (IRA_INT_TYPE **) ira_allocate (sizeof (IRA_INT_TYPE *)
					      * ira_objects_num);
  allocated_words_num = 0;
  FOR_EACH_ALLOCNO (allocno, ai)
    FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
      {
	int id = OBJECT_CONFLICT_ID (obj);
	if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
	  {
	    conflicts[id] = NULL;
	    continue;
	  }
	conflict_bit_vec_words_num
	  = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
	     / IRA_INT_BITS);
	allocated_words_num += conflict_bit_vec_words_num;
	conflicts[id]
	  = (IRA_INT_TYPE *) ira_allocate (sizeof (IRA_INT_TYPE)
					   * conflict_bit_vec_words_num);
	memset (conflicts[id], 0,
		sizeof (IRA_INT_TYPE) * conflict_bit_vec_words_num);
      }

  object_set_words = (ira_objects_num + IRA_INT_BITS - 1) / IRA_INT_BITS;
  if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
    fprintf
      (ira_dump_file,
       "+++Allocating %ld bytes for conflict table (uncompressed size %ld)\n",
       (long) allocated_words_num * sizeof (IRA_INT_TYPE),
       (long) object_set_words * ira_objects_num * sizeof (IRA_INT_TYPE));

  objects_live = sparseset_alloc (ira_objects_num);
  for (i = 0; i < ira_max_point; i++)
    {
      for (r = ira_start_point_ranges[i]; r != NULL; r = r->start_next)
	{
	  ira_object_t obj = r->object;
	  ira_allocno_t allocno = OBJECT_ALLOCNO (obj);
	  int id = OBJECT_CONFLICT_ID (obj);

	  gcc_assert (id < ira_objects_num);

	  aclass = ALLOCNO_CLASS (allocno);
	  EXECUTE_IF_SET_IN_SPARSESET (objects_live, j)
	    {
	      ira_object_t live_obj = ira_object_id_map[j];
	      ira_allocno_t live_a = OBJECT_ALLOCNO (live_obj);
	      enum reg_class live_aclass = ALLOCNO_CLASS (live_a);

	      if (ira_reg_classes_intersect_p[aclass][live_aclass]
		  /* Don't set up conflict for the allocno with itself.  */
		  && live_a != allocno)
		{
		  record_object_conflict (obj, live_obj);
		}
	    }
	  sparseset_set_bit (objects_live, id);
	}

      for (r = ira_finish_point_ranges[i]; r != NULL; r = r->finish_next)
	sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (r->object));
    }
  sparseset_free (objects_live);
  return true;
}

/* Return true iff allocnos A1 and A2 cannot be allocated to the same
   register due to conflicts.  */

static bool
allocnos_conflict_for_copy_p (ira_allocno_t a1, ira_allocno_t a2)
{
  /* Due to the fact that we canonicalize conflicts (see
     record_object_conflict), we only need to test for conflicts of
     the lowest order words.  */
  ira_object_t obj1 = ALLOCNO_OBJECT (a1, 0);
  ira_object_t obj2 = ALLOCNO_OBJECT (a2, 0);

  return OBJECTS_CONFLICT_P (obj1, obj2);
}

/* Check that X is REG or SUBREG of REG.  */
#define REG_SUBREG_P(x)							\
   (REG_P (x) || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))))

/* Return X if X is a REG, otherwise it should be SUBREG of REG and
   the function returns the reg in this case.  *OFFSET will be set to
   0 in the first case or the regno offset in the first case.  */
static rtx
go_through_subreg (rtx x, int *offset)
{
  rtx reg;

  *offset = 0;
  if (REG_P (x))
    return x;
  ira_assert (GET_CODE (x) == SUBREG);
  reg = SUBREG_REG (x);
  ira_assert (REG_P (reg));
  if (REGNO (reg) < FIRST_PSEUDO_REGISTER)
    *offset = subreg_regno_offset (REGNO (reg), GET_MODE (reg),
				   SUBREG_BYTE (x), GET_MODE (x));
  else
    *offset = (SUBREG_BYTE (x) / REGMODE_NATURAL_SIZE (GET_MODE (x)));
  return reg;
}

/* Process registers REG1 and REG2 in move INSN with execution
   frequency FREQ.  The function also processes the registers in a
   potential move insn (INSN == NULL in this case) with frequency
   FREQ.  The function can modify hard register costs of the
   corresponding allocnos or create a copy involving the corresponding
   allocnos.  The function does nothing if the both registers are hard
   registers.  When nothing is changed, the function returns
   FALSE.  */
static bool
process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
		       rtx_insn *insn, int freq)
{
  int allocno_preferenced_hard_regno, cost, index, offset1, offset2;
  bool only_regs_p;
  ira_allocno_t a;
  reg_class_t rclass, aclass;
  machine_mode mode;
  ira_copy_t cp;

  gcc_assert (REG_SUBREG_P (reg1) && REG_SUBREG_P (reg2));
  only_regs_p = REG_P (reg1) && REG_P (reg2);
  reg1 = go_through_subreg (reg1, &offset1);
  reg2 = go_through_subreg (reg2, &offset2);
  /* Set up hard regno preferenced by allocno.  If allocno gets the
     hard regno the copy (or potential move) insn will be removed.  */
  if (HARD_REGISTER_P (reg1))
    {
      if (HARD_REGISTER_P (reg2))
	return false;
      allocno_preferenced_hard_regno = REGNO (reg1) + offset1 - offset2;
      a = ira_curr_regno_allocno_map[REGNO (reg2)];
    }
  else if (HARD_REGISTER_P (reg2))
    {
      allocno_preferenced_hard_regno = REGNO (reg2) + offset2 - offset1;
      a = ira_curr_regno_allocno_map[REGNO (reg1)];
    }
  else
    {
      ira_allocno_t a1 = ira_curr_regno_allocno_map[REGNO (reg1)];
      ira_allocno_t a2 = ira_curr_regno_allocno_map[REGNO (reg2)];

      if (!allocnos_conflict_for_copy_p (a1, a2) && offset1 == offset2)
	{
	  cp = ira_add_allocno_copy (a1, a2, freq, constraint_p, insn,
				     ira_curr_loop_tree_node);
	  bitmap_set_bit (ira_curr_loop_tree_node->local_copies, cp->num);
	  return true;
	}
      else
	return false;
    }

  if (! IN_RANGE (allocno_preferenced_hard_regno,
		  0, FIRST_PSEUDO_REGISTER - 1))
    /* Can not be tied.  */
    return false;
  rclass = REGNO_REG_CLASS (allocno_preferenced_hard_regno);
  mode = ALLOCNO_MODE (a);
  aclass = ALLOCNO_CLASS (a);
  if (only_regs_p && insn != NULL_RTX
      && reg_class_size[rclass] <= ira_reg_class_max_nregs [rclass][mode])
    /* It is already taken into account in ira-costs.c.  */
    return false;
  index = ira_class_hard_reg_index[aclass][allocno_preferenced_hard_regno];
  if (index < 0)
    /* Can not be tied.  It is not in the allocno class.  */
    return false;
  ira_init_register_move_cost_if_necessary (mode);
  if (HARD_REGISTER_P (reg1))
    cost = ira_register_move_cost[mode][aclass][rclass] * freq;
  else
    cost = ira_register_move_cost[mode][rclass][aclass] * freq;
  do
    {
      ira_allocate_and_set_costs
	(&ALLOCNO_HARD_REG_COSTS (a), aclass,
	 ALLOCNO_CLASS_COST (a));
      ira_allocate_and_set_costs
	(&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), aclass, 0);
      ALLOCNO_HARD_REG_COSTS (a)[index] -= cost;
      ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index] -= cost;
      if (ALLOCNO_HARD_REG_COSTS (a)[index] < ALLOCNO_CLASS_COST (a))
	ALLOCNO_CLASS_COST (a) = ALLOCNO_HARD_REG_COSTS (a)[index];
      ira_add_allocno_pref (a, allocno_preferenced_hard_regno, freq);
      a = ira_parent_or_cap_allocno (a);
    }
  while (a != NULL);
  return true;
}

/* Process all of the output registers of the current insn which are
   not bound (BOUND_P) and the input register REG (its operand number
   OP_NUM) which dies in the insn as if there were a move insn between
   them with frequency FREQ.  */
static void
process_reg_shuffles (rtx reg, int op_num, int freq, bool *bound_p)
{
  int i;
  rtx another_reg;

  gcc_assert (REG_SUBREG_P (reg));
  for (i = 0; i < recog_data.n_operands; i++)
    {
      another_reg = recog_data.operand[i];

      if (!REG_SUBREG_P (another_reg) || op_num == i
	  || recog_data.operand_type[i] != OP_OUT
	  || bound_p[i])
	continue;

      process_regs_for_copy (reg, another_reg, false, NULL, freq);
    }
}

/* Process INSN and create allocno copies if necessary.  For example,
   it might be because INSN is a pseudo-register move or INSN is two
   operand insn.  */
static void
add_insn_allocno_copies (rtx_insn *insn)
{
  rtx set, operand, dup;
  bool bound_p[MAX_RECOG_OPERANDS];
  int i, n, freq;
  HARD_REG_SET alts;

  freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
  if (freq == 0)
    freq = 1;
  if ((set = single_set (insn)) != NULL_RTX
      && REG_SUBREG_P (SET_DEST (set)) && REG_SUBREG_P (SET_SRC (set))
      && ! side_effects_p (set)
      && find_reg_note (insn, REG_DEAD,
			REG_P (SET_SRC (set))
			? SET_SRC (set)
			: SUBREG_REG (SET_SRC (set))) != NULL_RTX)
    {
      process_regs_for_copy (SET_SRC (set), SET_DEST (set),
			     false, insn, freq);
      return;
    }
  /* Fast check of possibility of constraint or shuffle copies.  If
     there are no dead registers, there will be no such copies.  */
  if (! find_reg_note (insn, REG_DEAD, NULL_RTX))
    return;
  ira_setup_alts (insn, alts);
  for (i = 0; i < recog_data.n_operands; i++)
    bound_p[i] = false;
  for (i = 0; i < recog_data.n_operands; i++)
    {
      operand = recog_data.operand[i];
      if (! REG_SUBREG_P (operand))
	continue;
      if ((n = ira_get_dup_out_num (i, alts)) >= 0)
	{
	  bound_p[n] = true;
	  dup = recog_data.operand[n];
	  if (REG_SUBREG_P (dup)
	      && find_reg_note (insn, REG_DEAD,
				REG_P (operand)
				? operand
				: SUBREG_REG (operand)) != NULL_RTX)
	    process_regs_for_copy (operand, dup, true, NULL,
				   freq);
	}
    }
  for (i = 0; i < recog_data.n_operands; i++)
    {
      operand = recog_data.operand[i];
      if (REG_SUBREG_P (operand)
	  && find_reg_note (insn, REG_DEAD,
			    REG_P (operand)
			    ? operand : SUBREG_REG (operand)) != NULL_RTX)
	/* If an operand dies, prefer its hard register for the output
	   operands by decreasing the hard register cost or creating
	   the corresponding allocno copies.  The cost will not
	   correspond to a real move insn cost, so make the frequency
	   smaller.  */
	process_reg_shuffles (operand, i, freq < 8 ? 1 : freq / 8, bound_p);
    }
}

/* Add copies originated from BB given by LOOP_TREE_NODE.  */
static void
add_copies (ira_loop_tree_node_t loop_tree_node)
{
  basic_block bb;
  rtx_insn *insn;

  bb = loop_tree_node->bb;
  if (bb == NULL)
    return;
  FOR_BB_INSNS (bb, insn)
    if (NONDEBUG_INSN_P (insn))
      add_insn_allocno_copies (insn);
}

/* Propagate copies the corresponding allocnos on upper loop tree
   level.  */
static void
propagate_copies (void)
{
  ira_copy_t cp;
  ira_copy_iterator ci;
  ira_allocno_t a1, a2, parent_a1, parent_a2;

  FOR_EACH_COPY (cp, ci)
    {
      a1 = cp->first;
      a2 = cp->second;
      if (ALLOCNO_LOOP_TREE_NODE (a1) == ira_loop_tree_root)
	continue;
      ira_assert ((ALLOCNO_LOOP_TREE_NODE (a2) != ira_loop_tree_root));
      parent_a1 = ira_parent_or_cap_allocno (a1);
      parent_a2 = ira_parent_or_cap_allocno (a2);
      ira_assert (parent_a1 != NULL && parent_a2 != NULL);
      if (! allocnos_conflict_for_copy_p (parent_a1, parent_a2))
	ira_add_allocno_copy (parent_a1, parent_a2, cp->freq,
			      cp->constraint_p, cp->insn, cp->loop_tree_node);
    }
}

/* Array used to collect all conflict allocnos for given allocno.  */
static ira_object_t *collected_conflict_objects;

/* Build conflict vectors or bit conflict vectors (whatever is more
   profitable) for object OBJ from the conflict table.  */
static void
build_object_conflicts (ira_object_t obj)
{
  int i, px, parent_num;
  ira_allocno_t parent_a, another_parent_a;
  ira_object_t parent_obj;
  ira_allocno_t a = OBJECT_ALLOCNO (obj);
  IRA_INT_TYPE *object_conflicts;
  minmax_set_iterator asi;
  int parent_min, parent_max ATTRIBUTE_UNUSED;

  object_conflicts = conflicts[OBJECT_CONFLICT_ID (obj)];
  px = 0;
  FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
			      OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
    {
      ira_object_t another_obj = ira_object_id_map[i];
      ira_allocno_t another_a = OBJECT_ALLOCNO (obj);

      ira_assert (ira_reg_classes_intersect_p
		  [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
      collected_conflict_objects[px++] = another_obj;
    }
  if (ira_conflict_vector_profitable_p (obj, px))
    {
      ira_object_t *vec;
      ira_allocate_conflict_vec (obj, px);
      vec = OBJECT_CONFLICT_VEC (obj);
      memcpy (vec, collected_conflict_objects, sizeof (ira_object_t) * px);
      vec[px] = NULL;
      OBJECT_NUM_CONFLICTS (obj) = px;
    }
  else
    {
      int conflict_bit_vec_words_num;

      OBJECT_CONFLICT_ARRAY (obj) = object_conflicts;
      if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
	conflict_bit_vec_words_num = 0;
      else
	conflict_bit_vec_words_num
	  = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
	     / IRA_INT_BITS);
      OBJECT_CONFLICT_ARRAY_SIZE (obj)
	= conflict_bit_vec_words_num * sizeof (IRA_INT_TYPE);
    }

  parent_a = ira_parent_or_cap_allocno (a);
  if (parent_a == NULL)
    return;
  ira_assert (ALLOCNO_CLASS (a) == ALLOCNO_CLASS (parent_a));
  ira_assert (ALLOCNO_NUM_OBJECTS (a) == ALLOCNO_NUM_OBJECTS (parent_a));
  parent_obj = ALLOCNO_OBJECT (parent_a, OBJECT_SUBWORD (obj));
  parent_num = OBJECT_CONFLICT_ID (parent_obj);
  parent_min = OBJECT_MIN (parent_obj);
  parent_max = OBJECT_MAX (parent_obj);
  FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
			      OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
    {
      ira_object_t another_obj = ira_object_id_map[i];
      ira_allocno_t another_a = OBJECT_ALLOCNO (another_obj);
      int another_word = OBJECT_SUBWORD (another_obj);

      ira_assert (ira_reg_classes_intersect_p
		  [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);

      another_parent_a = ira_parent_or_cap_allocno (another_a);
      if (another_parent_a == NULL)
	continue;
      ira_assert (ALLOCNO_NUM (another_parent_a) >= 0);
      ira_assert (ALLOCNO_CLASS (another_a)
		  == ALLOCNO_CLASS (another_parent_a));
      ira_assert (ALLOCNO_NUM_OBJECTS (another_a)
		  == ALLOCNO_NUM_OBJECTS (another_parent_a));
      SET_MINMAX_SET_BIT (conflicts[parent_num],
			  OBJECT_CONFLICT_ID (ALLOCNO_OBJECT (another_parent_a,
							      another_word)),
			  parent_min, parent_max);
    }
}

/* Build conflict vectors or bit conflict vectors (whatever is more
   profitable) of all allocnos from the conflict table.  */
static void
build_conflicts (void)
{
  int i;
  ira_allocno_t a, cap;

  collected_conflict_objects
    = (ira_object_t *) ira_allocate (sizeof (ira_object_t)
					  * ira_objects_num);
  for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
    for (a = ira_regno_allocno_map[i];
	 a != NULL;
	 a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
      {
	int j, nregs = ALLOCNO_NUM_OBJECTS (a);
	for (j = 0; j < nregs; j++)
	  {
	    ira_object_t obj = ALLOCNO_OBJECT (a, j);
	    build_object_conflicts (obj);
	    for (cap = ALLOCNO_CAP (a); cap != NULL; cap = ALLOCNO_CAP (cap))
	      {
		ira_object_t cap_obj = ALLOCNO_OBJECT (cap, j);
		gcc_assert (ALLOCNO_NUM_OBJECTS (cap) == ALLOCNO_NUM_OBJECTS (a));
		build_object_conflicts (cap_obj);
	      }
	  }
      }
  ira_free (collected_conflict_objects);
}



/* Print hard reg set SET with TITLE to FILE.  */
static void
print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set)
{
  int i, start;

  fputs (title, file);
  for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
      if (TEST_HARD_REG_BIT (set, i))
	{
	  if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1))
	    start = i;
	}
      if (start >= 0
	  && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
	{
	  if (start == i - 1)
	    fprintf (file, " %d", start);
	  else if (start == i - 2)
	    fprintf (file, " %d %d", start, start + 1);
	  else
	    fprintf (file, " %d-%d", start, i - 1);
	  start = -1;
	}
    }
  putc ('\n', file);
}

static void
print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
{
  HARD_REG_SET conflicting_hard_regs;
  basic_block bb;
  int n, i;

  if (reg_p)
    fprintf (file, ";; r%d", ALLOCNO_REGNO (a));
  else
    {
      fprintf (file, ";; a%d(r%d,", ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
      if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
        fprintf (file, "b%d", bb->index);
      else
        fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
      putc (')', file);
    }

  fputs (" conflicts:", file);
  n = ALLOCNO_NUM_OBJECTS (a);
  for (i = 0; i < n; i++)
    {
      ira_object_t obj = ALLOCNO_OBJECT (a, i);
      ira_object_t conflict_obj;
      ira_object_conflict_iterator oci;

      if (OBJECT_CONFLICT_ARRAY (obj) == NULL)
	continue;
      if (n > 1)
	fprintf (file, "\n;;   subobject %d:", i);
      FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
	{
	  ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
	  if (reg_p)
	    fprintf (file, " r%d,", ALLOCNO_REGNO (conflict_a));
	  else
	    {
	      fprintf (file, " a%d(r%d", ALLOCNO_NUM (conflict_a),
		       ALLOCNO_REGNO (conflict_a));
	      if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
		fprintf (file, ",w%d", OBJECT_SUBWORD (conflict_obj));
	      if ((bb = ALLOCNO_LOOP_TREE_NODE (conflict_a)->bb) != NULL)
		fprintf (file, ",b%d", bb->index);
	      else
		fprintf (file, ",l%d",
			 ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop_num);
	      putc (')', file);
	    }
	}
      COPY_HARD_REG_SET (conflicting_hard_regs, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
      AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
      AND_HARD_REG_SET (conflicting_hard_regs,
			reg_class_contents[ALLOCNO_CLASS (a)]);
      print_hard_reg_set (file, "\n;;     total conflict hard regs:",
			  conflicting_hard_regs);

      COPY_HARD_REG_SET (conflicting_hard_regs, OBJECT_CONFLICT_HARD_REGS (obj));
      AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
      AND_HARD_REG_SET (conflicting_hard_regs,
			reg_class_contents[ALLOCNO_CLASS (a)]);
      print_hard_reg_set (file, ";;     conflict hard regs:",
			  conflicting_hard_regs);
      putc ('\n', file);
    }

}

/* Print information about allocno or only regno (if REG_P) conflicts
   to FILE.  */
static void
print_conflicts (FILE *file, bool reg_p)
{
  ira_allocno_t a;
  ira_allocno_iterator ai;

  FOR_EACH_ALLOCNO (a, ai)
    print_allocno_conflicts (file, reg_p, a);
}

/* Print information about allocno or only regno (if REG_P) conflicts
   to stderr.  */
void
ira_debug_conflicts (bool reg_p)
{
  print_conflicts (stderr, reg_p);
}



/* Entry function which builds allocno conflicts and allocno copies
   and accumulate some allocno info on upper level regions.  */
void
ira_build_conflicts (void)
{
  enum reg_class base;
  ira_allocno_t a;
  ira_allocno_iterator ai;
  HARD_REG_SET temp_hard_reg_set;

  if (ira_conflicts_p)
    {
      ira_conflicts_p = build_conflict_bit_table ();
      if (ira_conflicts_p)
	{
	  ira_object_t obj;
	  ira_object_iterator oi;

	  build_conflicts ();
	  ira_traverse_loop_tree (true, ira_loop_tree_root, add_copies, NULL);
	  /* We need finished conflict table for the subsequent call.  */
	  if (flag_ira_region == IRA_REGION_ALL
	      || flag_ira_region == IRA_REGION_MIXED)
	    propagate_copies ();

	  /* Now we can free memory for the conflict table (see function
	     build_object_conflicts for details).  */
	  FOR_EACH_OBJECT (obj, oi)
	    {
	      if (OBJECT_CONFLICT_ARRAY (obj) != conflicts[OBJECT_CONFLICT_ID (obj)])
		ira_free (conflicts[OBJECT_CONFLICT_ID (obj)]);
	    }
	  ira_free (conflicts);
	}
    }
  base = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH);
  if (! targetm.class_likely_spilled_p (base))
    CLEAR_HARD_REG_SET (temp_hard_reg_set);
  else
    {
      COPY_HARD_REG_SET (temp_hard_reg_set, reg_class_contents[base]);
      AND_COMPL_HARD_REG_SET (temp_hard_reg_set, ira_no_alloc_regs);
      AND_HARD_REG_SET (temp_hard_reg_set, call_used_reg_set);
    }
  FOR_EACH_ALLOCNO (a, ai)
    {
      int i, n = ALLOCNO_NUM_OBJECTS (a);

      for (i = 0; i < n; i++)
	{
	  ira_object_t obj = ALLOCNO_OBJECT (a, i);
	  rtx allocno_reg = regno_reg_rtx [ALLOCNO_REGNO (a)];

	  if ((! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
	      /* For debugging purposes don't put user defined variables in
		 callee-clobbered registers.  However, do allow parameters
		 in callee-clobbered registers to improve debugging.  This
		 is a bit of a fragile hack.  */
	      || (optimize == 0
		  && REG_USERVAR_P (allocno_reg)
		  && ! reg_is_parm_p (allocno_reg)))
	    {
	      IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
				call_used_reg_set);
	      IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
				call_used_reg_set);
	    }
	  else if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
	    {
	      IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
				no_caller_save_reg_set);
	      IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
				temp_hard_reg_set);
	      IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
				no_caller_save_reg_set);
	      IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
				temp_hard_reg_set);
	    }

	  /* Now we deal with paradoxical subreg cases where certain registers
	     cannot be accessed in the widest mode.  */
	  machine_mode outer_mode = ALLOCNO_WMODE (a);
	  machine_mode inner_mode = ALLOCNO_MODE (a);
	  if (GET_MODE_SIZE (outer_mode) > GET_MODE_SIZE (inner_mode))
	    {
	      enum reg_class aclass = ALLOCNO_CLASS (a);
	      for (int j = ira_class_hard_regs_num[aclass] - 1; j >= 0; --j)
		{
		   int inner_regno = ira_class_hard_regs[aclass][j];
		   int outer_regno = simplify_subreg_regno (inner_regno,
							    inner_mode, 0,
							    outer_mode);
		   if (outer_regno < 0
		       || !in_hard_reg_set_p (reg_class_contents[aclass],
					      outer_mode, outer_regno))
		     {
		       SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
					 inner_regno);
		       SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj),
					 inner_regno);
		     }
		}
	    }

	  if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
	    {
	      int regno;

	      /* Allocnos bigger than the saved part of call saved
		 regs must conflict with them.  */
	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
		if (!TEST_HARD_REG_BIT (call_used_reg_set, regno)
		    && HARD_REGNO_CALL_PART_CLOBBERED (regno,
						       obj->allocno->mode))
		  {
		    SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno);
		    SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
				      regno);
		  }
	    }
	}
    }
  if (optimize && ira_conflicts_p
      && internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
    print_conflicts (ira_dump_file, false);
}
