⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 local-alloc.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
{  /* Note that the quotient will never be bigger than     the value of floor_log2 times the maximum number of     times a register can occur in one insn (surely less than 100).     Multiplying this by 10000 can't overflow.  */  register int pri1    = (((double) (floor_log2 (qty_n_refs[q1]) * qty_n_refs[q1] * qty_size[q1])	/ (qty_death[q1] - qty_birth[q1]))       * 10000);  register int pri2    = (((double) (floor_log2 (qty_n_refs[q2]) * qty_n_refs[q2] * qty_size[q2])	/ (qty_death[q2] - qty_birth[q2]))       * 10000);  return pri2 - pri1;}static intqty_compare_1 (q1, q2)     int *q1, *q2;{  register int tem;  /* Note that the quotient will never be bigger than     the value of floor_log2 times the maximum number of     times a register can occur in one insn (surely less than 100).     Multiplying this by 10000 can't overflow.  */  register int pri1    = (((double) (floor_log2 (qty_n_refs[*q1]) * qty_n_refs[*q1]		  * qty_size[*q1])	/ (qty_death[*q1] - qty_birth[*q1]))       * 10000);  register int pri2    = (((double) (floor_log2 (qty_n_refs[*q2]) * qty_n_refs[*q2]		  * qty_size[*q2])	/ (qty_death[*q2] - qty_birth[*q2]))       * 10000);  tem = pri2 - pri1;  if (tem != 0) return tem;  /* If qtys are equally good, sort by qty number,     so that the results of qsort leave nothing to chance.  */  return *q1 - *q2;}/* Compare two quantities' priority for getting real registers.  This version   is called for quantities that have suggested hard registers.  First priority   goes to quantities that have copy preferences, then to those that have   normal preferences.  Within those groups, quantities with the lower   number of preferences have the highest priority.  Of those, we use the same   algorithm as above.  */static intqty_sugg_compare (q1, q2)     int q1, q2;{  register int sugg1 = (qty_phys_num_copy_sugg[q1]			? qty_phys_num_copy_sugg[q1]			: qty_phys_num_sugg[q1] * FIRST_PSEUDO_REGISTER);  register int sugg2 = (qty_phys_num_copy_sugg[q2]			? qty_phys_num_copy_sugg[q2]			: qty_phys_num_sugg[q2] * FIRST_PSEUDO_REGISTER);  /* Note that the quotient will never be bigger than     the value of floor_log2 times the maximum number of     times a register can occur in one insn (surely less than 100).     Multiplying this by 10000 can't overflow.  */  register int pri1    = (((double) (floor_log2 (qty_n_refs[q1]) * qty_n_refs[q1] * qty_size[q1])	/ (qty_death[q1] - qty_birth[q1]))       * 10000);  register int pri2    = (((double) (floor_log2 (qty_n_refs[q2]) * qty_n_refs[q2] * qty_size[q2])	/ (qty_death[q2] - qty_birth[q2]))       * 10000);  if (sugg1 != sugg2)    return sugg1 - sugg2;    return pri2 - pri1;}static intqty_sugg_compare_1 (q1, q2)     int *q1, *q2;{  register int sugg1 = (qty_phys_num_copy_sugg[*q1]			? qty_phys_num_copy_sugg[*q1]			: qty_phys_num_sugg[*q1] * FIRST_PSEUDO_REGISTER);  register int sugg2 = (qty_phys_num_copy_sugg[*q2]			? qty_phys_num_copy_sugg[*q2]			: qty_phys_num_sugg[*q2] * FIRST_PSEUDO_REGISTER);  /* Note that the quotient will never be bigger than     the value of floor_log2 times the maximum number of     times a register can occur in one insn (surely less than 100).     Multiplying this by 10000 can't overflow.  */  register int pri1    = (((double) (floor_log2 (qty_n_refs[*q1]) * qty_n_refs[*q1]		  * qty_size[*q1])	/ (qty_death[*q1] - qty_birth[*q1]))       * 10000);  register int pri2    = (((double) (floor_log2 (qty_n_refs[*q2]) * qty_n_refs[*q2]		  * qty_size[*q2])	/ (qty_death[*q2] - qty_birth[*q2]))       * 10000);  if (sugg1 != sugg2)    return sugg1 - sugg2;    if (pri1 != pri2)    return pri2 - pri1;  /* If qtys are equally good, sort by qty number,     so that the results of qsort leave nothing to chance.  */  return *q1 - *q2;}/* Attempt to combine the two registers (rtx's) USEDREG and SETREG.   Returns 1 if have done so, or 0 if cannot.   Combining registers means marking them as having the same quantity   and adjusting the offsets within the quantity if either of   them is a SUBREG).   We don't actually combine a hard reg with a pseudo; instead   we just record the hard reg as the suggestion for the pseudo's quantity.   If we really combined them, we could lose if the pseudo lives   across an insn that clobbers the hard reg (eg, movstr).   ALREADY_DEAD is non-zero if USEDREG is known to be dead even though   there is no REG_DEAD note on INSN.  This occurs during the processing   of REG_NO_CONFLICT blocks.   MAY_SAVE_COPYCOPY is non-zero if this insn is simply copying USEDREG to   SETREG or if the input and output must share a register.   In that case, we record a hard reg suggestion in QTY_PHYS_COPY_SUGG.      There are elaborate checks for the validity of combining.  */   static intcombine_regs (usedreg, setreg, may_save_copy, insn_number, insn, already_dead)     rtx usedreg, setreg;     int may_save_copy;     int insn_number;     rtx insn;     int already_dead;{  register int ureg, sreg;  register int offset = 0;  int usize, ssize;  register int sqty;  /* Determine the numbers and sizes of registers being used.  If a subreg     is present that does not change the entire register, don't consider     this a copy insn.  */  while (GET_CODE (usedreg) == SUBREG)    {      if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (usedreg))) > UNITS_PER_WORD)	may_save_copy = 0;      offset += SUBREG_WORD (usedreg);      usedreg = SUBREG_REG (usedreg);    }  if (GET_CODE (usedreg) != REG)    return 0;  ureg = REGNO (usedreg);  usize = REG_SIZE (usedreg);  while (GET_CODE (setreg) == SUBREG)    {      if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (setreg))) > UNITS_PER_WORD)	may_save_copy = 0;      offset -= SUBREG_WORD (setreg);      setreg = SUBREG_REG (setreg);    }  if (GET_CODE (setreg) != REG)    return 0;  sreg = REGNO (setreg);  ssize = REG_SIZE (setreg);  /* If UREG is a pseudo-register that hasn't already been assigned a     quantity number, it means that it is not local to this block or dies     more than once.  In either event, we can't do anything with it.  */  if ((ureg >= FIRST_PSEUDO_REGISTER && reg_qty[ureg] < 0)      /* Do not combine registers unless one fits within the other.  */      || (offset > 0 && usize + offset > ssize)      || (offset < 0 && usize + offset < ssize)      /* 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.	 These have already been taken care of.  This probably wouldn't	 combine anyway, but don't take any chances.  */      || (ureg >= FIRST_PSEUDO_REGISTER	  && find_reg_note (insn, REG_NO_CONFLICT, usedreg))      /* Don't tie something to itself.  In most cases it would make no	 difference, but it would screw up if the reg being tied to itself	 also dies in this insn.  */      || ureg == sreg      /* Don't try to connect two different hardware registers.  */      || (ureg < FIRST_PSEUDO_REGISTER && sreg < FIRST_PSEUDO_REGISTER)      /* Don't connect two different machine modes if they have different	 implications as to which registers may be used.  */      || !MODES_TIEABLE_P (GET_MODE (usedreg), GET_MODE (setreg)))    return 0;  /* Now, if UREG is a hard reg and SREG is a pseudo, record the hard reg in     qty_phys_sugg for the pseudo instead of tying them.     Return "failure" so that the lifespan of UREG is terminated here;     that way the two lifespans will be disjoint and nothing will prevent     the pseudo reg from being given this hard reg.  */  if (ureg < FIRST_PSEUDO_REGISTER)    {      /* Allocate a quantity number so we have a place to put our	 suggestions.  */      if (reg_qty[sreg] == -2)	reg_is_born (setreg, 2 * insn_number);      if (reg_qty[sreg] >= 0)	{	  if (may_save_copy	      && ! TEST_HARD_REG_BIT (qty_phys_copy_sugg[reg_qty[sreg]], ureg))	    {	      SET_HARD_REG_BIT (qty_phys_copy_sugg[reg_qty[sreg]], ureg);	      qty_phys_num_copy_sugg[reg_qty[sreg]]++;	    }	  else if (! TEST_HARD_REG_BIT (qty_phys_sugg[reg_qty[sreg]], ureg))	    {	      SET_HARD_REG_BIT (qty_phys_sugg[reg_qty[sreg]], ureg);	      qty_phys_num_sugg[reg_qty[sreg]]++;	    }	}      return 0;    }  /* Similarly for SREG a hard register and UREG a pseudo register.  */  if (sreg < FIRST_PSEUDO_REGISTER)    {      if (may_save_copy	  && ! TEST_HARD_REG_BIT (qty_phys_copy_sugg[reg_qty[ureg]], sreg))	{	  SET_HARD_REG_BIT (qty_phys_copy_sugg[reg_qty[ureg]], sreg);	  qty_phys_num_copy_sugg[reg_qty[ureg]]++;	}      else if (! TEST_HARD_REG_BIT (qty_phys_sugg[reg_qty[ureg]], sreg))	{	  SET_HARD_REG_BIT (qty_phys_sugg[reg_qty[ureg]], sreg);	  qty_phys_num_sugg[reg_qty[ureg]]++;	}      return 0;    }  /* At this point we know that SREG and UREG are both pseudos.     Do nothing if SREG already has a quantity or is a register that we     don't allocate.  */  if (reg_qty[sreg] >= -1      /* If we are not going to let any regs live across calls,	 don't tie a call-crossing reg to a non-call-crossing reg.  */      || (current_function_has_nonlocal_label	  && ((reg_n_calls_crossed[ureg] > 0)	      != (reg_n_calls_crossed[sreg] > 0))))    return 0;  /* We don't already know about SREG, so tie it to UREG     if this is the last use of UREG, provided the classes they want     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    return 0;  return 1;}/* Return 1 if the preferred class of REG allows it to be tied   to a quantity or register whose class is CLASS.   True if REG's reg class either contains or is contained in CLASS.  */static intreg_meets_class_p (reg, class)     int reg;     enum reg_class class;{  register enum reg_class rclass = reg_preferred_class (reg);  return (reg_class_subset_p (rclass, class)	  || reg_class_subset_p (class, rclass));}/* Return 1 if the two specified classes have registers in common.   If CALL_SAVED, then consider only call-saved registers.  */static intreg_classes_overlap_p (c1, c2, call_saved)     register enum reg_class c1;     register enum reg_class c2;     int call_saved;{  HARD_REG_SET c;  int i;  COPY_HARD_REG_SET (c, reg_class_contents[(int) c1]);  AND_HARD_REG_SET (c, reg_class_contents[(int) c2]);  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)    if (TEST_HARD_REG_BIT (c, i)	&& (! call_saved || ! call_used_regs[i]))      return 1;  return 0;}/* Update the class of QTY assuming that REG is being tied to it.  */static voidupdate_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.   REG is whatever is set or clobbered.  SETTER is the rtx that   is modifying the register.   If it is not really a register, we do nothing.   The file-global variables `this_insn' and `this_insn_number'   carry info from `block_alloc'.  */static voidreg_is_set (reg, setter)     rtx reg;     rtx setter;{  /* Note that note_stores will only pass us a SUBREG if it is a SUBREG of     a hard register.  These may actually not exist any more.  */  if (GET_CODE (reg) != SUBREG      && GET_CODE (reg) != REG)    return;  /* Mark this register as being born.  If it is used in a CLOBBER, mark     it as being born halfway between the previous insn and this insn so that     it conflicts with our inputs but not the outputs of the previous insn.  */  reg_is_born (reg, 2 * this_insn_number - (GET_CODE (setter) == CLOBBER));}/* Handle beginning of the life of register REG.   BIRTH is 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -