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

📄 reload1.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	      for (op = reg_eliminate;		   op < &reg_eliminate[NUM_ELIMINABLE_REGS]; op++)		if (op->from == ep->from && op->can_eliminate)		  {		    new_to = op->to;		    break;		  }	      /* See if there is an elimination of NEW_TO -> EP->TO.  If so,		 disable it.  */	      for (op = reg_eliminate;		   op < &reg_eliminate[NUM_ELIMINABLE_REGS]; op++)		if (op->from == new_to && op->to == ep->to)		  op->can_eliminate = 0;	    }	}      /* See if any registers that we thought we could eliminate the previous	 time are no longer eliminable.  If so, something has changed and we	 must spill the register.  Also, recompute the number of eliminable	 registers and see if the frame pointer is needed; it is if there is	 no elimination of the frame pointer that we can perform.  */      frame_pointer_needed = 1;      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)	{	  if (ep->can_eliminate && ep->from == FRAME_POINTER_REGNUM)	    frame_pointer_needed = 0;	  if (! ep->can_eliminate && ep->can_eliminate_previous)	    {	      ep->can_eliminate_previous = 0;	      spill_hard_reg (ep->from, global, dumpfile, 1);	      regs_ever_live[ep->from] = 1;	      something_changed = 1;	      num_eliminable--;	    }	}      /* 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 && ! something_changed)	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, 0);      /* 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'.	 ??? Note there is a problem here.	 When there is a need for a group in a high-numbered class,	 and also need for non-group regs that come from a lower class,	 the non-group regs are chosen first.  If there aren't many regs,	 they might leave no room for a group.	 This was happening on the 386.  To fix it, we added the code	 that calls possible_group_p, so that the lower class won't	 break up the last possible group.	 Really fixing the problem would require changes above	 in counting the regs already spilled, and in choose_reload_regs.	 It might be hard to avoid introducing bugs there.  */      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)	    {	      /* If any single spilled regs happen to form groups,		 count them now.  Maybe we don't really need		 to spill another group.  */	      count_possible_groups (group_size, group_mode, max_groups);	      /* 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 && ! TEST_HARD_REG_BIT (bad_spill_regs, 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])			    && ! TEST_HARD_REG_BIT (counted_for_nongroups,						    other)			    /* We don't want one part of another group.			       We could get "two groups" that overlap!  */			    && ! TEST_HARD_REG_BIT (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])			    && ! TEST_HARD_REG_BIT (counted_for_nongroups,						    other)			    && ! TEST_HARD_REG_BIT (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.  */			  SET_HARD_REG_BIT (counted_for_groups, j);			  SET_HARD_REG_BIT (counted_for_groups, other);			  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			    && 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])			    && ! TEST_HARD_REG_BIT (counted_for_nongroups,						    j + 1))			  break;		      }		  /* I should be the index in potential_reload_regs		     of the new reload reg we have found.  */		  if (i >= FIRST_PSEUDO_REGISTER)		    {		      /* There are no groups left to spill.  */		      spill_failure (max_groups_insn[class]);		      failure = 1;		      goto failed;		    }		  else		    something_changed		      |= new_spill_reg (i, class, max_needs, NULL_PTR,					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 + group_size[class] <= 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				   && ! TEST_HARD_REG_BIT (bad_spill_regs, j + k)				   && 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;				  SET_HARD_REG_BIT (counted_for_groups, j + k);				  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, NULL_PTR,						      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;			    }			}		    }		  /* We couldn't find any registers for this reload.		     Avoid going into an infinite loop.  */		  if (i >= FIRST_PSEUDO_REGISTER)		    {		      /* There are no groups left.  */		      spill_failure (max_groups_insn[class]);		      failure = 1;		      goto failed;		    }		}	    }	  /* 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;	      /* If we couldn't get a register, try to get one even if we		 might foreclose possible groups.  This may cause problems		 later, but that's better than aborting now, since it is		 possible that we will, in fact, be able to form the needed		 group even with this allocation.  */	      if (i >= FIRST_PSEUDO_REGISTER		  && (asm_noperands (max_needs[class] > 0				     ? max_needs_insn[class]				     : max_nongroups_insn[class])		      < 0))		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]))		    break;	      /* I should be the index in potential_reload_regs		 of the new reload reg we have found.  */	      if (i >= FIRST_PSEUDO_REGISTER)		{		  /* There are no possible registers left to spill.  */		  spill_failure (max_needs[class] > 0 ? max_needs_insn[class]				 : max_nongroups_insn[class]);		  failure = 1;		  goto failed;		}	      else		something_changed		  |= new_spill_reg (i, class, max_needs, max_nongroups,				    global, dumpfile);	    }	}    }  /* If global-alloc was run, notify it of any register eliminations we have     done.  */  if (global)    for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)      if (ep->can_eliminate)	mark_elimination (ep->from, ep->to);  /* Insert code to save and restore call-clobbered hard regs     around calls.  Tell if what mode to use so that we will process     those insns in reload_as_needed if we have to.  */  if (caller_save_needed)    save_call_clobbered_regs (num_eliminable ? QImode			      : caller_save_spill_class != NO_REGS ? HImode			      : VOIDmode);  /* If a pseudo has no hard reg, delete the insns that made the equivalence.     If that insn didn't set the register (i.e., it copied the register to     memory), just delete that insn instead of the equivalencing insn plus     anything now dead.  If we call delete_dead_insn on that insn, we may     delete the insn that actually sets the register if the register die     there and that is incorrect.  */  for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)    if (reg_renumber[i] < 0 && reg_equiv_init[i] != 0	&& GET_CODE (reg_equiv_init[i]) != NOTE)      {	if (reg_set_p (regno_reg_rtx[i], PATTERN (reg_equiv_init[i])))	  delete_dead_insn (reg_equiv_init[i]);	else	  {	    PUT_CODE (reg_equiv_init[i], NOTE);	    NOTE_SOURCE_FILE (reg_equiv_init[i]) = 0;	    NOTE_LINE_NUMBER (reg_equiv_init[i]) = NOTE_INSN_DELETED;	  }      }  /* 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 || something_needs_elimination      || (caller_save_needed && num_eliminable)      || caller_save_spill_class != NO_REGS)    reload_as_needed (first, global);  /* If we were able to eliminate the frame pointer, show that it is no     longer live at the start of any basic block.  If it is live by     virtue of being in a pseudo, that pseudo will be marked live     and hence the frame pointer will be known to be live via that     pseudo.  */  if (! frame_pointer_needed)    for (i = 0; i < n_basic_blocks; i++)      basic_block_live_at_start[i][FRAME_POINTER_REGNUM / REGSET_ELT_BITS]	&= ~ ((REGSET_ELT_TYPE) 1 << (FRAME_POINTER_REGNUM % REGSET_ELT_BITS));  reload_in_progress = 0;  /* Come here (with failure set nonzero) if we can't get enough spill regs     and we decide not to abort about it.  */ failed:  /* 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;      int in_struct = 0;      if (reg_equiv_mem[i])	{	  ad

⌨️ 快捷键说明

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