loop.c per qty variables merge

Jan Hubicka hubicka@atrey.karlin.mff.cuni.cz
Tue Nov 23 01:34:00 GMT 1999


Hi
This patch unites almost all per-qtty values in local alloc. 
I've left out the qty_phys* because they are zeroed by bzero or loop
(for small count). I expect purpose of this is that zeroing is performance
problem.

Patch have no measurable performance effects on local alloc.

Mon Nov 22 21:24:38 CET 1999  Jan Hubicka  <hubicka@freesoft.cz>

	* local-alloc.c (qty): New structure and static variable.
	(qty_phys_reg): Remove, all references changed to qty.
	(qty_n_refs): Likewise.
	(qty_min_class): Likewise.
	(qty_birth): Likewise.
	(qty_death): Likewise.
	(qty_size): Likewise.
	(qty_mode): Likewise.
	(qty_n_calls_crossed): Likewise.
	(qty_alternate_class): Likewise.
	(qty_changes_size): Likewise.
	(qty_first_reg): Likewise.
	(alloc_qty): Rename variable QTY to QTYNO.
	(finf_free_reg): Likewise.
	(local_alloc): Allocate qty, do not allocate the removed variables.

*** local-alloc.c.old2	Mon Nov 22 20:50:55 1999
--- local-alloc.c	Mon Nov 22 21:39:08 1999
*************** Boston, MA 02111-1307, USA.  */
*** 78,177 ****
  
  static int next_qty;
  
! /* In all the following vectors indexed by quantity number.  */
  
! /* Element Q is the hard reg number chosen for quantity Q,
!    or -1 if none was found.  */
  
! static short *qty_phys_reg;
  
! /* We maintain two hard register sets that indicate suggested hard registers
!    for each quantity.  The first, qty_phys_copy_sugg, contains hard registers
!    that are tied to the quantity by a simple copy.  The second contains all
!    hard registers that are tied to the quantity via an arithmetic operation.
  
!    The former register set is given priority for allocation.  This tends to
!    eliminate copy insns.  */
  
! /* Element Q is a set of hard registers that are suggested for quantity Q by
!    copy insns.  */
  
! static HARD_REG_SET *qty_phys_copy_sugg;
  
! /* Element Q is a set of hard registers that are suggested for quantity Q by
!    arithmetic insns.  */
  
! static HARD_REG_SET *qty_phys_sugg;
  
! /* Element Q is the number of suggested registers in qty_phys_copy_sugg.  */
  
! static short *qty_phys_num_copy_sugg;
  
! /* Element Q is the number of suggested registers in qty_phys_sugg.  */
  
! static short *qty_phys_num_sugg;
  
! /* Element Q is the number of refs to quantity Q.  */
  
! static int *qty_n_refs;
  
! /* Element Q is a reg class contained in (smaller than) the
!    preferred classes of all the pseudo regs that are tied in quantity Q.
!    This is the preferred class for allocating that quantity.  */
  
! static enum reg_class *qty_min_class;
  
! /* Insn number (counting from head of basic block)
!    where quantity Q was born.  -1 if birth has not been recorded.  */
  
! static int *qty_birth;
  
! /* Insn number (counting from head of basic block)
!    where quantity Q died.  Due to the way tying is done,
!    and the fact that we consider in this pass only regs that die but once,
!    a quantity can die only once.  Each quantity's life span
!    is a set of consecutive insns.  -1 if death has not been recorded.  */
  
! static int *qty_death;
  
! /* Number of words needed to hold the data in quantity Q.
!    This depends on its machine mode.  It is used for these purposes:
!    1. It is used in computing the relative importances of qtys,
!       which determines the order in which we look for regs for them.
!    2. It is used in rules that prevent tying several registers of
!       different sizes in a way that is geometrically impossible
!       (see combine_regs).  */
  
! static int *qty_size;
  
! /* This holds the mode of the registers that are tied to qty Q,
!    or VOIDmode if registers with differing modes are tied together.  */
  
! static enum machine_mode *qty_mode;
  
! /* Number of times a reg tied to qty Q lives across a CALL_INSN.  */
  
! static int *qty_n_calls_crossed;
  
! /* Register class within which we allocate qty Q if we can't get
!    its preferred class.  */
  
! static enum reg_class *qty_alternate_class;
  
! /* Element Q is nonzero if this quantity has been used in a SUBREG
!    that changes its size.  */
  
! static char *qty_changes_size;
  
! /* Element Q is the register number of one pseudo register whose
!    reg_qty value is Q.  This register should be the head of the chain
!    maintained in reg_next_in_qty.  */
  
- static int *qty_first_reg;
  
  /* If (REG N) has been assigned a quantity number, is a register number
     of another register assigned the same quantity number, or -1 for the
!    end of the chain.  qty_first_reg point to the head of this chain.  */
  
  static int *reg_next_in_qty;
  
--- 78,185 ----
  
  static int next_qty;
  
! /* Information we maitain about each quantity.  */
! struct qty
! {
!   /* The number of refs to quantity Q.  */
  
!   int n_refs;
  
!   /* Insn number (counting from head of basic block)
!      where quantity Q was born.  -1 if birth has not been recorded.  */
  
!   int birth;
  
!   /* Insn number (counting from head of basic block)
!      where given quantity died.  Due to the way tying is done,
!      and the fact that we consider in this pass only regs that die but once,
!      a quantity can die only once.  Each quantity's life span
!      is a set of consecutive insns.  -1 if death has not been recorded.  */
  
!   int death;
  
!   /* Number of words needed to hold the data in given quantity.
!      This depends on its machine mode.  It is used for these purposes:
!      1. It is used in computing the relative importances of qtys,
! 	which determines the order in which we look for regs for them.
!      2. It is used in rules that prevent tying several registers of
! 	different sizes in a way that is geometrically impossible
! 	(see combine_regs).  */
  
!   int size;
  
!   /* Number of times a reg tied to given qty lives across a CALL_INSN.  */
  
!   int n_calls_crossed;
  
!   /* The register number of one pseudo register whose reg_qty value is Q.
!      This register should be the head of the chain
!      maintained in reg_next_in_qty.  */
  
!   int first_reg;
  
!   /* Reg class contained in (smaller than) the preferred classes of all
!      the pseudo regs that are tied in given quantity.
!      This is the preferred class for allocating that quantity.  */
! 
!   enum reg_class min_class;
  
!   /* Register class within which we allocate given qty if we can't get
!      its preferred class.  */
  
!   enum reg_class alternate_class;
  
!   /* This holds the mode of the registers that are tied to given qty,
!      or VOIDmode if registers with differing modes are tied together.  */
  
!   enum machine_mode mode;
  
!   /* the hard reg number chosen for given quantity,
!      or -1 if none was found.  */
  
!   short phys_reg;
  
!   /* Nonzero if this quantity has been used in a SUBREG that changes
!      its size.  */
  
!   char changes_size;
  
! };
  
! static struct qty *qty;
  
! /* These fields are kept separately to speedup their clearing.  */
  
! /* We maintain two hard register sets that indicate suggested hard registers
!    for each quantity.  The first, phys_copy_sugg, contains hard registers
!    that are tied to the quantity by a simple copy.  The second contains all
!    hard registers that are tied to the quantity via an arithmetic operation.
  
!    The former register set is given priority for allocation.  This tends to
!    eliminate copy insns.  */
  
! /* Element Q is a set of hard registers that are suggested for quantity Q by
!    copy insns.  */
  
! static HARD_REG_SET *qty_phys_copy_sugg;
  
! /* Element Q is a set of hard registers that are suggested for quantity Q by
!    arithmetic insns.  */
! 
! static HARD_REG_SET *qty_phys_sugg;
! 
! /* Element Q is the number of suggested registers in qty_phys_copy_sugg.  */
  
! static short *qty_phys_num_copy_sugg;
  
! /* Element Q is the number of suggested registers in qty_phys_sugg.  */
  
! static short *qty_phys_num_sugg;
  
  
  /* If (REG N) has been assigned a quantity number, is a register number
     of another register assigned the same quantity number, or -1 for the
!    end of the chain.  qty->first_reg point to the head of this chain.  */
  
  static int *reg_next_in_qty;
  
*************** alloc_qty (regno, mode, size, birth)
*** 258,278 ****
       enum machine_mode mode;
       int size, birth;
  {
!   register int qty = next_qty++;
  
!   reg_qty[regno] = qty;
    reg_offset[regno] = 0;
    reg_next_in_qty[regno] = -1;
  
!   qty_first_reg[qty] = regno;
!   qty_size[qty] = size;
!   qty_mode[qty] = mode;
!   qty_birth[qty] = birth;
!   qty_n_calls_crossed[qty] = REG_N_CALLS_CROSSED (regno);
!   qty_min_class[qty] = reg_preferred_class (regno);
!   qty_alternate_class[qty] = reg_alternate_class (regno);
!   qty_n_refs[qty] = REG_N_REFS (regno);
!   qty_changes_size[qty] = REG_CHANGES_SIZE (regno);
  }
  
  /* Main entry point of this file.  */
--- 266,286 ----
       enum machine_mode mode;
       int size, birth;
  {
!   register int qtyno = next_qty++;
  
!   reg_qty[regno] = qtyno;
    reg_offset[regno] = 0;
    reg_next_in_qty[regno] = -1;
  
!   qty[qtyno].first_reg = regno;
!   qty[qtyno].size = size;
!   qty[qtyno].mode = mode;
!   qty[qtyno].birth = birth;
!   qty[qtyno].n_calls_crossed = REG_N_CALLS_CROSSED (regno);
!   qty[qtyno].min_class = reg_preferred_class (regno);
!   qty[qtyno].alternate_class = reg_alternate_class (regno);
!   qty[qtyno].n_refs = REG_N_REFS (regno);
!   qty[qtyno].changes_size = REG_CHANGES_SIZE (regno);
  }
  
  /* Main entry point of this file.  */
*************** local_alloc ()
*** 298,322 ****
       See the declarations of these variables, above,
       for what they mean.  */
  
!   qty_phys_reg = (short *) xmalloc (max_qty * sizeof (short));
    qty_phys_copy_sugg
      = (HARD_REG_SET *) xmalloc (max_qty * sizeof (HARD_REG_SET));
    qty_phys_num_copy_sugg = (short *) xmalloc (max_qty * sizeof (short));
    qty_phys_sugg = (HARD_REG_SET *) xmalloc (max_qty * sizeof (HARD_REG_SET));
    qty_phys_num_sugg = (short *) xmalloc (max_qty * sizeof (short));
-   qty_birth = (int *) xmalloc (max_qty * sizeof (int));
-   qty_death = (int *) xmalloc (max_qty * sizeof (int));
-   qty_first_reg = (int *) xmalloc (max_qty * sizeof (int));
-   qty_size = (int *) xmalloc (max_qty * sizeof (int));
-   qty_mode
-     = (enum machine_mode *) xmalloc (max_qty * sizeof (enum machine_mode));
-   qty_n_calls_crossed = (int *) xmalloc (max_qty * sizeof (int));
-   qty_min_class
-     = (enum reg_class *) xmalloc (max_qty * sizeof (enum reg_class));
-   qty_alternate_class
-     = (enum reg_class *) xmalloc (max_qty * sizeof (enum reg_class));
-   qty_n_refs = (int *) xmalloc (max_qty * sizeof (int));
-   qty_changes_size = (char *) xmalloc (max_qty * sizeof (char));
  
    reg_qty = (int *) xmalloc (max_regno * sizeof (int));
    reg_offset = (char *) xmalloc (max_regno * sizeof (char));
--- 306,317 ----
       See the declarations of these variables, above,
       for what they mean.  */
  
!   qty = (struct qty *) xmalloc (max_qty * sizeof (struct qty));
    qty_phys_copy_sugg
      = (HARD_REG_SET *) xmalloc (max_qty * sizeof (HARD_REG_SET));
    qty_phys_num_copy_sugg = (short *) xmalloc (max_qty * sizeof (short));
    qty_phys_sugg = (HARD_REG_SET *) xmalloc (max_qty * sizeof (HARD_REG_SET));
    qty_phys_num_sugg = (short *) xmalloc (max_qty * sizeof (short));
  
    reg_qty = (int *) xmalloc (max_regno * sizeof (int));
    reg_offset = (char *) xmalloc (max_regno * sizeof (char));
*************** local_alloc ()
*** 385,405 ****
        block_alloc (b);
      }
  
!   free (qty_phys_reg);
    free (qty_phys_copy_sugg);
    free (qty_phys_num_copy_sugg);
    free (qty_phys_sugg);
    free (qty_phys_num_sugg);
-   free (qty_birth);
-   free (qty_death);
-   free (qty_first_reg);
-   free (qty_size);
-   free (qty_mode);
-   free (qty_n_calls_crossed);
-   free (qty_min_class);
-   free (qty_alternate_class);
-   free (qty_n_refs);
-   free (qty_changes_size);
  
    free (reg_qty);
    free (reg_offset);
--- 380,390 ----
        block_alloc (b);
      }
  
!   free (qty);
    free (qty_phys_copy_sugg);
    free (qty_phys_num_copy_sugg);
    free (qty_phys_sugg);
    free (qty_phys_num_sugg);
  
    free (reg_qty);
    free (reg_offset);
*************** block_alloc (b)
*** 717,726 ****
      {
        q = qty_order[i];
        if (qty_phys_num_sugg[q] != 0 || qty_phys_num_copy_sugg[q] != 0)
! 	qty_phys_reg[q] = find_free_reg (qty_min_class[q], qty_mode[q], q,
! 					 0, 1, qty_birth[q], qty_death[q]);
        else
! 	qty_phys_reg[q] = -1;
      }
  
    /* Order the qtys so we assign them registers in order of 
--- 702,711 ----
      {
        q = qty_order[i];
        if (qty_phys_num_sugg[q] != 0 || qty_phys_num_copy_sugg[q] != 0)
! 	qty[q].phys_reg = find_free_reg (qty[q].min_class, qty[q].mode, q,
! 					 0, 1, qty[q].birth, qty[q].death);
        else
! 	qty[q].phys_reg = -1;
      }
  
    /* Order the qtys so we assign them registers in order of 
*************** block_alloc (b)
*** 767,773 ****
    for (i = 0; i < next_qty; i++)
      {
        q = qty_order[i];
!       if (qty_phys_reg[q] < 0)
  	{
  #ifdef INSN_SCHEDULING
  	  /* These values represent the adjusted lifetime of a qty so
--- 752,758 ----
    for (i = 0; i < next_qty; i++)
      {
        q = qty_order[i];
!       if (qty[q].phys_reg < 0)
  	{
  #ifdef INSN_SCHEDULING
  	  /* These values represent the adjusted lifetime of a qty so
*************** block_alloc (b)
*** 787,795 ****
  
  	     If allocation using the extended lifetime fails we will try
  	     again with the qty's unadjusted lifetime.  */
! 	  int fake_birth = MAX (0, qty_birth[q] - 2 + qty_birth[q] % 2);
  	  int fake_death = MIN (insn_number * 2 + 1,
! 				qty_death[q] + 2 - qty_death[q] % 2);
  #endif
  
  	  if (N_REG_CLASSES > 1)
--- 772,780 ----
  
  	     If allocation using the extended lifetime fails we will try
  	     again with the qty's unadjusted lifetime.  */
! 	  int fake_birth = MAX (0, qty[q].birth - 2 + qty[q].birth % 2);
  	  int fake_death = MIN (insn_number * 2 + 1,
! 				qty[q].death + 2 - qty[q].death % 2);
  #endif
  
  	  if (N_REG_CLASSES > 1)
*************** block_alloc (b)
*** 807,823 ****
  		  && !SMALL_REGISTER_CLASSES)
  		{
  		
! 		  qty_phys_reg[q] = find_free_reg (qty_min_class[q], 
! 						   qty_mode[q], q, 0, 0,
  						   fake_birth, fake_death);
! 		  if (qty_phys_reg[q] >= 0)
  		    continue;
  		}
  #endif
! 	      qty_phys_reg[q] = find_free_reg (qty_min_class[q], 
! 					       qty_mode[q], q, 0, 0,
! 					       qty_birth[q], qty_death[q]);
! 	      if (qty_phys_reg[q] >= 0)
  		continue;
  	    }
  
--- 792,808 ----
  		  && !SMALL_REGISTER_CLASSES)
  		{
  		
! 		  qty[q].phys_reg = find_free_reg (qty[q].min_class, 
! 						   qty[q].mode, q, 0, 0,
  						   fake_birth, fake_death);
! 		  if (qty[q].phys_reg >= 0)
  		    continue;
  		}
  #endif
! 	      qty[q].phys_reg = find_free_reg (qty[q].min_class, 
! 					       qty[q].mode, q, 0, 0,
! 					       qty[q].birth, qty[q].death);
! 	      if (qty[q].phys_reg >= 0)
  		continue;
  	    }
  
*************** block_alloc (b)
*** 826,840 ****
  	  if (flag_schedule_insns_after_reload
  	      && !optimize_size
  	      && !SMALL_REGISTER_CLASSES
! 	      && qty_alternate_class[q] != NO_REGS)
! 	    qty_phys_reg[q] = find_free_reg (qty_alternate_class[q],
! 					     qty_mode[q], q, 0, 0,
  					     fake_birth, fake_death);
  #endif
! 	  if (qty_alternate_class[q] != NO_REGS)
! 	    qty_phys_reg[q] = find_free_reg (qty_alternate_class[q],
! 					     qty_mode[q], q, 0, 0,
! 					     qty_birth[q], qty_death[q]);
  	}
      }
  
--- 811,825 ----
  	  if (flag_schedule_insns_after_reload
  	      && !optimize_size
  	      && !SMALL_REGISTER_CLASSES
! 	      && qty[q].alternate_class != NO_REGS)
! 	    qty[q].phys_reg = find_free_reg (qty[q].alternate_class,
! 					     qty[q].mode, q, 0, 0,
  					     fake_birth, fake_death);
  #endif
! 	  if (qty[q].alternate_class != NO_REGS)
! 	    qty[q].phys_reg = find_free_reg (qty[q].alternate_class,
! 					     qty[q].mode, q, 0, 0,
! 					     qty[q].birth, qty[q].death);
  	}
      }
  
*************** block_alloc (b)
*** 842,851 ****
       to the pseudo regs belonging to the qtys.  */
  
    for (q = 0; q < next_qty; q++)
!     if (qty_phys_reg[q] >= 0)
        {
! 	for (i = qty_first_reg[q]; i >= 0; i = reg_next_in_qty[i])
! 	  reg_renumber[i] = qty_phys_reg[q] + reg_offset[i];
        }
  
    /* Clean up.  */
--- 827,836 ----
       to the pseudo regs belonging to the qtys.  */
  
    for (q = 0; q < next_qty; q++)
!     if (qty[q].phys_reg >= 0)
        {
! 	for (i = qty[q].first_reg; i >= 0; i = reg_next_in_qty[i])
! 	  reg_renumber[i] = qty[q].phys_reg + reg_offset[i];
        }
  
    /* Clean up.  */
*************** block_alloc (b)
*** 870,877 ****
     QTY_CMP_PRI is also used by qty_sugg_compare.  */
  
  #define QTY_CMP_PRI(q)		\
!   ((int) (((double) (floor_log2 (qty_n_refs[q]) * qty_n_refs[q] * qty_size[q]) \
! 	  / (qty_death[q] - qty_birth[q])) * 10000))
  
  static int
  qty_compare (q1, q2)
--- 855,862 ----
     QTY_CMP_PRI is also used by qty_sugg_compare.  */
  
  #define QTY_CMP_PRI(q)		\
!   ((int) (((double) (floor_log2 (qty[q].n_refs) * qty[q].n_refs * qty[q].size) \
! 	  / (qty[q].death - qty[q].birth)) * 10000))
  
  static int
  qty_compare (q1, q2)
*************** combine_regs (usedreg, setreg, may_save_
*** 1017,1023 ****
        /* Do not combine with a smaller already-assigned object
  	 if that smaller object is already combined with something bigger.  */
        || (ssize > usize && ureg >= FIRST_PSEUDO_REGISTER
! 	  && usize < qty_size[reg_qty[ureg]])
        /* Can't combine if SREG is not a register we can allocate.  */
        || (sreg >= FIRST_PSEUDO_REGISTER && reg_qty[sreg] == -1)
        /* Don't combine with a pseudo mentioned in a REG_NO_CONFLICT note.
--- 1002,1008 ----
        /* Do not combine with a smaller already-assigned object
  	 if that smaller object is already combined with something bigger.  */
        || (ssize > usize && ureg >= FIRST_PSEUDO_REGISTER
! 	  && usize < qty[reg_qty[ureg]].size)
        /* Can't combine if SREG is not a register we can allocate.  */
        || (sreg >= FIRST_PSEUDO_REGISTER && reg_qty[sreg] == -1)
        /* Don't combine with a pseudo mentioned in a REG_NO_CONFLICT note.
*************** combine_regs (usedreg, setreg, may_save_
*** 1106,1135 ****
       are compatible.  */
  
    if ((already_dead || find_regno_note (insn, REG_DEAD, ureg))
!       && reg_meets_class_p (sreg, qty_min_class[reg_qty[ureg]]))
      {
        /* Add SREG to UREG's quantity.  */
        sqty = reg_qty[ureg];
        reg_qty[sreg] = sqty;
        reg_offset[sreg] = reg_offset[ureg] + offset;
!       reg_next_in_qty[sreg] = qty_first_reg[sqty];
!       qty_first_reg[sqty] = sreg;
  
!       /* If SREG's reg class is smaller, set qty_min_class[SQTY].  */
        update_qty_class (sqty, sreg);
  
        /* Update info about quantity SQTY.  */
!       qty_n_calls_crossed[sqty] += REG_N_CALLS_CROSSED (sreg);
!       qty_n_refs[sqty] += REG_N_REFS (sreg);
        if (usize < ssize)
  	{
  	  register int i;
  
! 	  for (i = qty_first_reg[sqty]; i >= 0; i = reg_next_in_qty[i])
  	    reg_offset[i] -= offset;
  
! 	  qty_size[sqty] = ssize;
! 	  qty_mode[sqty] = GET_MODE (setreg);
  	}
      }
    else
--- 1091,1120 ----
       are compatible.  */
  
    if ((already_dead || find_regno_note (insn, REG_DEAD, ureg))
!       && reg_meets_class_p (sreg, qty[reg_qty[ureg]].min_class))
      {
        /* Add SREG to UREG's quantity.  */
        sqty = reg_qty[ureg];
        reg_qty[sreg] = sqty;
        reg_offset[sreg] = reg_offset[ureg] + offset;
!       reg_next_in_qty[sreg] = qty[sqty].first_reg;
!       qty[sqty].first_reg = sreg;
  
!       /* If SREG's reg class is smaller, set qty[SQTY].min_class.  */
        update_qty_class (sqty, sreg);
  
        /* Update info about quantity SQTY.  */
!       qty[sqty].n_calls_crossed += REG_N_CALLS_CROSSED (sreg);
!       qty[sqty].n_refs += REG_N_REFS (sreg);
        if (usize < ssize)
  	{
  	  register int i;
  
! 	  for (i = qty[sqty].first_reg; i >= 0; i = reg_next_in_qty[i])
  	    reg_offset[i] -= offset;
  
! 	  qty[sqty].size = ssize;
! 	  qty[sqty].mode = GET_MODE (setreg);
  	}
      }
    else
*************** reg_meets_class_p (reg, class)
*** 1152,1174 ****
  	  || reg_class_subset_p (class, rclass));
  }
  
! /* Update the class of QTY assuming that REG is being tied to it.  */
  
  static void
! update_qty_class (qty, reg)
!      int qty;
       int reg;
  {
    enum reg_class rclass = reg_preferred_class (reg);
!   if (reg_class_subset_p (rclass, qty_min_class[qty]))
!     qty_min_class[qty] = rclass;
  
    rclass = reg_alternate_class (reg);
!   if (reg_class_subset_p (rclass, qty_alternate_class[qty]))
!     qty_alternate_class[qty] = rclass;
  
    if (REG_CHANGES_SIZE (reg))
!     qty_changes_size[qty] = 1;
  }
  
  /* Handle something which alters the value of an rtx REG.
--- 1137,1159 ----
  	  || reg_class_subset_p (class, rclass));
  }
  
! /* Update the class of QTYNO assuming that REG is being tied to it.  */
  
  static void
! update_qty_class (qtyno, reg)
!      int qtyno;
       int reg;
  {
    enum reg_class rclass = reg_preferred_class (reg);
!   if (reg_class_subset_p (rclass, qty[qtyno].min_class))
!     qty[qtyno].min_class = rclass;
  
    rclass = reg_alternate_class (reg);
!   if (reg_class_subset_p (rclass, qty[qtyno].alternate_class))
!     qty[qtyno].alternate_class = rclass;
  
    if (REG_CHANGES_SIZE (reg))
!     qty[qtyno].changes_size = 1;
  }
  
  /* Handle something which alters the value of an rtx REG.
*************** reg_is_born (reg, birth)
*** 1231,1237 ****
  
        /* If this register has a quantity number, show that it isn't dead.  */
        if (reg_qty[regno] >= 0)
! 	qty_death[reg_qty[regno]] = -1;
      }
  }
  
--- 1216,1222 ----
  
        /* If this register has a quantity number, show that it isn't dead.  */
        if (reg_qty[regno] >= 0)
! 	qty[reg_qty[regno]].death = -1;
      }
  }
  
*************** wipe_dead_reg (reg, output_p)
*** 1292,1298 ****
      }
  
    else if (reg_qty[regno] >= 0)
!     qty_death[reg_qty[regno]] = 2 * this_insn_number + output_p;
  }
  
  /* Find a block of SIZE words of hard regs in reg_class CLASS
--- 1277,1283 ----
      }
  
    else if (reg_qty[regno] >= 0)
!     qty[reg_qty[regno]].death = 2 * this_insn_number + output_p;
  }
  
  /* Find a block of SIZE words of hard regs in reg_class CLASS
*************** wipe_dead_reg (reg, output_p)
*** 1301,1318 ****
     and still free between insn BORN_INDEX and insn DEAD_INDEX,
     and return the number of the first of them.
     Return -1 if such a block cannot be found. 
!    If QTY crosses calls, insist on a register preserved by calls,
     unless ACCEPT_CALL_CLOBBERED is nonzero.
  
     If JUST_TRY_SUGGESTED is non-zero, only try to see if the suggested
     register is available.  If not, return -1.  */
  
  static int
! find_free_reg (class, mode, qty, accept_call_clobbered, just_try_suggested,
  	       born_index, dead_index)
       enum reg_class class;
       enum machine_mode mode;
!      int qty;
       int accept_call_clobbered;
       int just_try_suggested;
       int born_index, dead_index;
--- 1286,1303 ----
     and still free between insn BORN_INDEX and insn DEAD_INDEX,
     and return the number of the first of them.
     Return -1 if such a block cannot be found. 
!    If QTYNO crosses calls, insist on a register preserved by calls,
     unless ACCEPT_CALL_CLOBBERED is nonzero.
  
     If JUST_TRY_SUGGESTED is non-zero, only try to see if the suggested
     register is available.  If not, return -1.  */
  
  static int
! find_free_reg (class, mode, qtyno, accept_call_clobbered, just_try_suggested,
  	       born_index, dead_index)
       enum reg_class class;
       enum machine_mode mode;
!      int qtyno;
       int accept_call_clobbered;
       int just_try_suggested;
       int born_index, dead_index;
*************** find_free_reg (class, mode, qty, accept_
*** 1333,1344 ****
    /* Don't let a pseudo live in a reg across a function call
       if we might get a nonlocal goto.  */
    if (current_function_has_nonlocal_label
!       && qty_n_calls_crossed[qty] > 0)
      return -1;
  
    if (accept_call_clobbered)
      COPY_HARD_REG_SET (used, call_fixed_reg_set);
!   else if (qty_n_calls_crossed[qty] == 0)
      COPY_HARD_REG_SET (used, fixed_reg_set);
    else
      COPY_HARD_REG_SET (used, call_used_reg_set);
--- 1318,1329 ----
    /* Don't let a pseudo live in a reg across a function call
       if we might get a nonlocal goto.  */
    if (current_function_has_nonlocal_label
!       && qty[qtyno].n_calls_crossed > 0)
      return -1;
  
    if (accept_call_clobbered)
      COPY_HARD_REG_SET (used, call_fixed_reg_set);
!   else if (qty[qtyno].n_calls_crossed == 0)
      COPY_HARD_REG_SET (used, fixed_reg_set);
    else
      COPY_HARD_REG_SET (used, call_used_reg_set);
*************** find_free_reg (class, mode, qty, accept_
*** 1370,1376 ****
  #endif
  
  #ifdef CLASS_CANNOT_CHANGE_SIZE
!   if (qty_changes_size[qty])
      IOR_HARD_REG_SET (used,
  		      reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE]);
  #endif
--- 1355,1361 ----
  #endif
  
  #ifdef CLASS_CANNOT_CHANGE_SIZE
!   if (qty[qtyno].changes_size)
      IOR_HARD_REG_SET (used,
  		      reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE]);
  #endif
*************** find_free_reg (class, mode, qty, accept_
*** 1385,1394 ****
  
    if (just_try_suggested)
      {
!       if (qty_phys_num_copy_sugg[qty] != 0)
! 	IOR_COMPL_HARD_REG_SET (first_used, qty_phys_copy_sugg[qty]);
        else
! 	IOR_COMPL_HARD_REG_SET (first_used, qty_phys_sugg[qty]);
      }
  
    /* If all registers are excluded, we can't do anything.  */
--- 1370,1379 ----
  
    if (just_try_suggested)
      {
!       if (qty_phys_num_copy_sugg[qtyno] != 0)
! 	IOR_COMPL_HARD_REG_SET (first_used, qty_phys_copy_sugg[qtyno]);
        else
! 	IOR_COMPL_HARD_REG_SET (first_used, qty_phys_sugg[qtyno]);
      }
  
    /* If all registers are excluded, we can't do anything.  */
*************** find_free_reg (class, mode, qty, accept_
*** 1405,1411 ****
  #endif
        if (! TEST_HARD_REG_BIT (first_used, regno)
  	  && HARD_REGNO_MODE_OK (regno, mode)
! 	  && (qty_n_calls_crossed[qty] == 0
  	      || accept_call_clobbered
  	      || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
  	{
--- 1390,1396 ----
  #endif
        if (! TEST_HARD_REG_BIT (first_used, regno)
  	  && HARD_REGNO_MODE_OK (regno, mode)
! 	  && (qty[qtyno].n_calls_crossed == 0
  	      || accept_call_clobbered
  	      || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
  	{
*************** find_free_reg (class, mode, qty, accept_
*** 1433,1444 ****
    
    /* If it would be profitable to allocate a call-clobbered register
       and save and restore it around calls, do that.  */
!   if (just_try_suggested && qty_phys_num_copy_sugg[qty] != 0
!       && qty_phys_num_sugg[qty] != 0)
      {
        /* Don't try the copy-suggested regs again.  */
!       qty_phys_num_copy_sugg[qty] = 0;
!       return find_free_reg (class, mode, qty, accept_call_clobbered, 1,
  			    born_index, dead_index);
      }
  
--- 1418,1429 ----
    
    /* If it would be profitable to allocate a call-clobbered register
       and save and restore it around calls, do that.  */
!   if (just_try_suggested && qty_phys_num_copy_sugg[qtyno] != 0
!       && qty_phys_num_sugg[qtyno] != 0)
      {
        /* Don't try the copy-suggested regs again.  */
!       qty_phys_num_copy_sugg[qtyno] = 0;
!       return find_free_reg (class, mode, qtyno, accept_call_clobbered, 1,
  			    born_index, dead_index);
      }
  
*************** find_free_reg (class, mode, qty, accept_
*** 1449,1458 ****
    if (! accept_call_clobbered
        && flag_caller_saves
        && ! just_try_suggested
!       && qty_n_calls_crossed[qty] != 0
!       && CALLER_SAVE_PROFITABLE (qty_n_refs[qty], qty_n_calls_crossed[qty]))
      {
!       i = find_free_reg (class, mode, qty, 1, 0, born_index, dead_index);
        if (i >= 0)
  	caller_save_needed = 1;
        return i;
--- 1434,1443 ----
    if (! accept_call_clobbered
        && flag_caller_saves
        && ! just_try_suggested
!       && qty[qtyno].n_calls_crossed != 0
!       && CALLER_SAVE_PROFITABLE (qty[qtyno].n_refs, qty[qtyno].n_calls_crossed))
      {
!       i = find_free_reg (class, mode, qtyno, 1, 0, born_index, dead_index);
        if (i >= 0)
  	caller_save_needed = 1;
        return i;


More information about the Gcc-patches mailing list