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

📄 reload1.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	  max_needs[class]--;	  p = reg_class_superclasses[class];	  while (*p != LIM_REG_CLASSES)	    max_needs[(int) *p++]--;	  if (! counted_for_groups[spill_regs[i]])	    {	      if (max_nongroups[class] > 0)		counted_for_nongroups[spill_regs[i]] = 1;	      max_nongroups[class]--;	      p = reg_class_superclasses[class];	      while (*p != LIM_REG_CLASSES)		{		  if (max_nongroups[(int) *p] > 0)		    counted_for_nongroups[spill_regs[i]] = 1;		  max_nongroups[(int) *p++]--;		}	    }	}      /* If all needs are met, we win.  */      for (i = 0; i < N_REG_CLASSES; i++)	if (max_needs[i] > 0 || max_groups[i] > 0 || max_nongroups[i] > 0)	  break;      if (i == N_REG_CLASSES && !new_basic_block_needs)	break;      /* Not all needs are met; must spill more hard regs.  */      /* If any element of basic_block_needs changed from 0 to 1,	 re-spill all the regs already spilled.  This may spill	 additional pseudos that didn't spill before.  */      if (new_basic_block_needs)	for (i = 0; i < n_spills; i++)	  something_changed	    |= spill_hard_reg (spill_regs[i], global, dumpfile);      /* Now find more reload regs to satisfy the remaining need	 Do it by ascending class number, since otherwise a reg	 might be spilled for a big class and might fail to count	 for a smaller class even though it belongs to that class.	 Count spilled regs in `spills', and add entries to	 `spill_regs' and `spill_reg_order'.  */      for (class = 0; class < N_REG_CLASSES; class++)	{	  /* First get the groups of registers.	     If we got single registers first, we might fragment	     possible groups.  */	  while (max_groups[class] > 0)	    {	      /* Groups of size 2 (the only groups used on most machines)		 are treated specially.  */	      if (group_size[class] == 2)		{		  /* First, look for a register that will complete a group.  */		  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)		    {		      int j = potential_reload_regs[i];		      int other;		      if (j >= 0 && !fixed_regs[j] && j != FRAME_POINTER_REGNUM			  && !regs_explicitly_used[j]			  &&			  ((j > 0 && (other = j - 1, spill_reg_order[other] >= 0)			    && TEST_HARD_REG_BIT (reg_class_contents[class], j)			    && TEST_HARD_REG_BIT (reg_class_contents[class], other)			    && HARD_REGNO_MODE_OK (other, group_mode[class])			    && ! counted_for_nongroups[other]			    /* We don't want one part of another group.			       We could get "two groups" that overlap!  */			    && ! counted_for_groups[other])			   ||			   (j < FIRST_PSEUDO_REGISTER - 1			    && (other = j + 1, spill_reg_order[other] >= 0)			    && TEST_HARD_REG_BIT (reg_class_contents[class], j)			    && TEST_HARD_REG_BIT (reg_class_contents[class], other)			    && HARD_REGNO_MODE_OK (j, group_mode[class])			    && ! counted_for_nongroups[other]			    && ! counted_for_groups[other])))			{			  register enum reg_class *p;			  /* We have found one that will complete a group,			     so count off one group as provided.  */			  max_groups[class]--;			  p = reg_class_superclasses[class];			  while (*p != LIM_REG_CLASSES)			    max_groups[(int) *p++]--;			  /* Indicate both these regs are part of a group.  */			  counted_for_groups[j] = 1;			  counted_for_groups[other] = 1;			  break;			}		    }		  /* We can't complete a group, so start one.  */		  if (i == FIRST_PSEUDO_REGISTER)		    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)		      {			int j = potential_reload_regs[i];			if (j >= 0 && j + 1 < FIRST_PSEUDO_REGISTER			    && !fixed_regs[j] && j != FRAME_POINTER_REGNUM			    && spill_reg_order[j] < 0 && spill_reg_order[j + 1] < 0			    && TEST_HARD_REG_BIT (reg_class_contents[class], j)			    && TEST_HARD_REG_BIT (reg_class_contents[class], j + 1)			    && HARD_REGNO_MODE_OK (j, group_mode[class])			    && ! counted_for_nongroups[j + 1])			  break;		      }		  /* I should be the index in potential_reload_regs		     of the new reload reg we have found.  */		  something_changed		    |= new_spill_reg (i, class, max_needs, 0,				      global, dumpfile);		}	      else		{		  /* For groups of more than 2 registers,		     look for a sufficient sequence of unspilled registers,		     and spill them all at once.  */		  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)		    {		      int j = potential_reload_regs[i];		      int k;		      if (j >= 0 && j + 1 < FIRST_PSEUDO_REGISTER			  && HARD_REGNO_MODE_OK (j, group_mode[class]))			{			  /* Check each reg in the sequence.  */			  for (k = 0; k < group_size[class]; k++)			    if (! (spill_reg_order[j + k] < 0				   && !fixed_regs[j + k]				   && j + k != FRAME_POINTER_REGNUM				   && TEST_HARD_REG_BIT (reg_class_contents[class], j + k)))			      break;			  /* We got a full sequence, so spill them all.  */			  if (k == group_size[class])			    {			      register enum reg_class *p;			      for (k = 0; k < group_size[class]; k++)				{				  int idx;				  counted_for_groups[j + k] = 1;				  for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)				    if (potential_reload_regs[idx] == j + k)				      break;				  something_changed				    |= new_spill_reg (idx, class, max_needs, 0,						      global, dumpfile);				}			      /* We have found one that will complete a group,				 so count off one group as provided.  */			      max_groups[class]--;			      p = reg_class_superclasses[class];			      while (*p != LIM_REG_CLASSES)				max_groups[(int) *p++]--;			      break;			    }			}		    }		}	    }	  /* Now similarly satisfy all need for single registers.  */	  while (max_needs[class] > 0 || max_nongroups[class] > 0)	    {	      /* Consider the potential reload regs that aren't		 yet in use as reload regs, in order of preference.		 Find the most preferred one that's in this class.  */	      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)		if (potential_reload_regs[i] >= 0		    && TEST_HARD_REG_BIT (reg_class_contents[class],					  potential_reload_regs[i])		    /* If this reg will not be available for groups,		       pick one that does not foreclose possible groups.		       This is a kludge, and not very general,		       but it should be sufficient to make the 386 work,		       and the problem should not occur on machines with		       more registers.  */		    && (max_nongroups[class] == 0			|| possible_group_p (potential_reload_regs[i], max_groups)))		  break;	      /* I should be the index in potential_reload_regs		 of the new reload reg we have found.  */	      something_changed		|= new_spill_reg (i, class, max_needs, max_nongroups,				  global, dumpfile);	    }	}    }  /* Insert code to save and restore call-clobbered hard regs     around calls.  */  if (caller_save_needed)    save_call_clobbered_regs ();  /* Now we know for certain whether we have a frame pointer.     If not, correct all references to go through the stack pointer.     This must be done before reloading, since reloading could generate     insns where sp+const cannot validly replace the frame pointer.     *This will lose if an insn might need more spill regs after     frame pointer elimination than it needed before.*  */  if (! frame_pointer_needed)    eliminate_frame_pointer (first);  /* Use the reload registers where necessary     by generating move instructions to move the must-be-register     values into or out of the reload registers.  */  if (something_needs_reloads)    reload_as_needed (first, global);  /* Now eliminate all pseudo regs by modifying them into     their equivalent memory references.     The REG-rtx's for the pseudos are modified in place,     so all insns that used to refer to them now refer to memory.     For a reg that has a reg_equiv_address, all those insns     were changed by reloading so that no insns refer to it any longer;     but the DECL_RTL of a variable decl may refer to it,     and if so this causes the debugging info to mention the variable.  */  for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)    {      rtx addr = 0;      if (reg_equiv_mem[i])	addr = XEXP (reg_equiv_mem[i], 0);      if (reg_equiv_address[i])	addr = reg_equiv_address[i];      if (addr)	{	  if (! frame_pointer_needed)	    FIX_FRAME_POINTER_ADDRESS (addr, 0);	  if (reg_renumber[i] < 0)	    {	      rtx reg = regno_reg_rtx[i];	      XEXP (reg, 0) = addr;	      REG_USERVAR_P (reg) = 0;	      PUT_CODE (reg, MEM);	    }	  else if (reg_equiv_mem[i])	    XEXP (reg_equiv_mem[i], 0) = addr;	}    }}/* Nonzero if, after spilling reg REGNO for non-groups,   it will still be possible to find a group if we still need one.  */static intpossible_group_p (regno, max_groups)     int regno;     int *max_groups;{  int i;  int group = 0;  for (i = 0; i < (int) N_REG_CLASSES; i++)    group |= max_groups[i];  if (group == 0)    return 1;  /* Consider each pair of consecutive registers.  */  for (i = 0; i < FIRST_PSEUDO_REGISTER - 1; i++)    {      if (i == regno || i + 1 == regno)	continue;      /* A pair of consecutive regs we can still spill does the trick.  */      if (spill_reg_order[i] < 0 && spill_reg_order[i + 1] < 0	  && !regs_explicitly_used[i] && !regs_explicitly_used[i + 1]	  && !fixed_regs[i] && i != FRAME_POINTER_REGNUM	  && !fixed_regs[i + 1] && i + 1 != FRAME_POINTER_REGNUM)	return 1;      /* A pair of one already spilled and one we can spill does it	 provided the one already spilled is not otherwise reserved.  */      if (spill_reg_order[i] < 0 && !regs_explicitly_used[i]	  && !fixed_regs[i] && i != FRAME_POINTER_REGNUM	  && spill_reg_order[i + 1] >= 0	  && !counted_for_groups[i + 1]	  && !counted_for_nongroups[i + 1])	return 1;      if (spill_reg_order[i + 1] < 0 && !regs_explicitly_used[i + 1]	  && !fixed_regs[i + 1] && i + 1 != FRAME_POINTER_REGNUM	  && spill_reg_order[i] >= 0	  && !counted_for_groups[i]	  && !counted_for_nongroups[i])	return 1;    }  return 0;}/* 1 if two machine modes MODE0 and MODE1 are equivalent   as far as HARD_REGNO_MODE_OK is concerned   for registers in class CLASS.  */static intmodes_equiv_for_class_p (mode0, mode1, class)     enum machine_mode mode0, mode1;     enum reg_class class;{  register int regno;  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)    {      /* If any reg in CLASS allows one mode but not the other, fail.	 Or if the two modes have different sizes in that reg, fail.  */      if (TEST_HARD_REG_BIT (reg_class_contents[(int) class], regno)	  && (HARD_REGNO_MODE_OK (regno, mode0)	      != HARD_REGNO_MODE_OK (regno, mode1))	  && (HARD_REGNO_NREGS (regno, mode0)	      != HARD_REGNO_NREGS (regno, mode1)))	return 0;    }  return 1;}/* Add a new register to the tables of available spill-registers    (as well as spilling all pseudos allocated to the register).   I is the index of this register in potential_reload_regs.   CLASS is the regclass whose need is being satisfied.   MAX_NEEDS and MAX_NONGROUPS are the vectors of needs,    so that this register can count off against them.    MAX_NONGROUPS is 0 if this register is part of a group.   GLOBAL and DUMPFILE are the same as the args that `reload' got.  */static intnew_spill_reg (i, class, max_needs, max_nongroups, global, dumpfile)     int i;     int class;     int *max_needs;     int *max_nongroups;     int global;     FILE *dumpfile;{  register enum reg_class *p;  int val;  int regno = potential_reload_regs[i];  if (i >= FIRST_PSEUDO_REGISTER)    abort ();	/* Caller failed to find any register.  */#if 0 /* This causes errors on the 386 for code that works ok.  */  if (regs_explicitly_used[regno])    {      error ("spilling register %s, which is explicitly used",	     reg_names[regno]);      error ("(Probably too many explicit register variables");      error (" are used in this function)");    }#endif  /* Make reg REGNO an additional reload reg.  */  potential_reload_regs[i] = -1;  spill_regs[n_spills] = regno;  spill_reg_order[regno] = n_spills;  forbidden_regs[regno] = 1;  if (dumpfile)    fprintf (dumpfile, "Spilling reg %d.\n", spill_regs[n_spills]);  /* Clear off the needs we just satisfied.  */  max_needs[class]--;  p = reg_class_superclasses[class];  while (*p != LIM_REG_CLASSES)    max_needs[(int) *p++]--;  if (max_nongroups && max_nongroups[class] > 0)    {      counted_for_nongroups[regno] = 1;      max_nongroups[class]--;      p = reg_class_superclasses[class];      while (*p != LIM_REG_CLASSES)	max_nongroups[(int) *p++]--;    }  /* Spill every pseudo reg that was allocated to this reg     or to something that overlaps this reg.  */  val = spill_hard_reg (spill_regs[n_spills], global, dumpfile);  regs_ever_live[spill_regs[n_spills]] = 1;

⌨️ 快捷键说明

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