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

📄 reload1.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
		    {		    case RELOAD_OTHER:		    case RELOAD_FOR_OUTPUT:		    case RELOAD_FOR_INPUT:		      this_needs = insn_needs;		      this_groups = insn_groups;		      this_total_groups = &insn_total_groups;		      break;		    case RELOAD_FOR_INPUT_RELOAD_ADDRESS:		      this_needs = insn_needs_for_inputs;		      this_groups = insn_groups_for_inputs;		      this_total_groups = &insn_total_groups_for_inputs;		      break;		    case RELOAD_FOR_OUTPUT_RELOAD_ADDRESS:		      this_needs = insn_needs_for_outputs;		      this_groups = insn_groups_for_outputs;		      this_total_groups = &insn_total_groups_for_outputs;		      break;		    case RELOAD_FOR_OPERAND_ADDRESS:		      this_needs = insn_needs_for_operands;		      this_groups = insn_groups_for_operands;		      this_total_groups = &insn_total_groups_for_operands;		      break;		    }		  mode = reload_inmode[i];		  if (GET_MODE_SIZE (reload_outmode[i]) > GET_MODE_SIZE (mode))		    mode = reload_outmode[i];		  size = CLASS_MAX_NREGS (class, mode);		  if (size > 1)		    {		      enum machine_mode other_mode, allocate_mode;		      /* Count number of groups needed separately from			 number of individual regs needed.  */		      this_groups[(int) class]++;		      p = reg_class_superclasses[(int) class];		      while (*p != LIM_REG_CLASSES)			this_groups[(int) *p++]++;		      (*this_total_groups)++;		      /* Record size and mode of a group of this class.  */		      /* If more than one size group is needed,			 make all groups the largest needed size.  */		      if (group_size[(int) class] < size)			{			  other_mode = group_mode[(int) class];			  allocate_mode = mode;			  group_size[(int) class] = size;			  group_mode[(int) class] = mode;			}		      else			{			  other_mode = mode;			  allocate_mode = group_mode[(int) class];			}		      /* Crash if two dissimilar machine modes both need			 groups of consecutive regs of the same class.  */		      if (other_mode != VOIDmode			  && other_mode != allocate_mode			  && ! modes_equiv_for_class_p (allocate_mode,							other_mode,							class))			abort ();		    }		  else if (size == 1)		    {		      this_needs[(int) class] += 1;		      p = reg_class_superclasses[(int) class];		      while (*p != LIM_REG_CLASSES)			this_needs[(int) *p++] += 1;		    }		  else		    abort ();		}	      /* All reloads have been counted for this insn;		 now merge the various times of use.		 This sets insn_needs, etc., to the maximum total number		 of registers needed at any point in this insn.  */	      for (i = 0; i < N_REG_CLASSES; i++)		{		  int this_max;		  this_max = insn_needs_for_inputs[i];		  if (insn_needs_for_outputs[i] > this_max)		    this_max = insn_needs_for_outputs[i];		  if (insn_needs_for_operands[i] > this_max)		    this_max = insn_needs_for_operands[i];		  insn_needs[i] += this_max;		  this_max = insn_groups_for_inputs[i];		  if (insn_groups_for_outputs[i] > this_max)		    this_max = insn_groups_for_outputs[i];		  if (insn_groups_for_operands[i] > this_max)		    this_max = insn_groups_for_operands[i];		  insn_groups[i] += this_max;		}	      insn_total_groups += MAX (insn_total_groups_for_inputs,					MAX (insn_total_groups_for_outputs,					     insn_total_groups_for_operands));	      /* If this is a CALL_INSN and caller-saves will need		 a spill register, act as if the spill register is		 needed for this insn.   However, the spill register		 can be used by any reload of this insn, so we only		 need do something if no need for that class has		 been recorded.		 The assumption that every CALL_INSN will trigger a		 caller-save is highly conservative, however, the number		 of cases where caller-saves will need a spill register but		 a block containing a CALL_INSN won't need a spill register		 of that class should be quite rare.		 If a group is needed, the size and mode of the group will		 have been set up at the beginning of this loop.  */	      if (GET_CODE (insn) == CALL_INSN		  && caller_save_spill_class != NO_REGS)		{		  int *caller_save_needs		    = (caller_save_group_size > 1 ? insn_groups : insn_needs);		  if (caller_save_needs[(int) caller_save_spill_class] == 0)		    {		      register enum reg_class *p			= reg_class_superclasses[(int) caller_save_spill_class];		      caller_save_needs[(int) caller_save_spill_class]++;		      while (*p != LIM_REG_CLASSES)			caller_save_needs[(int) *p++] += 1;		    }		  if (caller_save_group_size > 1)		    insn_total_groups = MAX (insn_total_groups, 1);                /* Show that this basic block will need a register of                   this class.  */                if (global                    && ! (basic_block_needs[(int) caller_save_spill_class]                          [this_block]))                  {                    basic_block_needs[(int) caller_save_spill_class]                      [this_block] = 1;                    new_basic_block_needs = 1;                  }		}#ifdef SMALL_REGISTER_CLASSES	      /* If this insn stores the value of a function call,		 and that value is in a register that has been spilled,		 and if the insn needs a reload in a class		 that might use that register as the reload register,		 then add add an extra need in that class.		 This makes sure we have a register available that does		 not overlap the return value.  */	      if (avoid_return_reg)		{		  int regno = REGNO (avoid_return_reg);		  int nregs		    = HARD_REGNO_NREGS (regno, GET_MODE (avoid_return_reg));		  int r;		  int inc_groups = 0;		  for (r = regno; r < regno + nregs; r++)		    if (spill_reg_order[r] >= 0)		      for (i = 0; i < N_REG_CLASSES; i++)			if (TEST_HARD_REG_BIT (reg_class_contents[i], r))			  {			    if (insn_needs[i] > 0)			      insn_needs[i]++;			    if (insn_groups[i] > 0				&& nregs > 1)			      inc_groups = 1;			  }		  if (inc_groups)		    insn_groups[i]++;		}#endif /* SMALL_REGISTER_CLASSES */	      /* For each class, collect maximum need of any insn.  */	      for (i = 0; i < N_REG_CLASSES; i++)		{		  if (max_needs[i] < insn_needs[i])		    {		      max_needs[i] = insn_needs[i];		      max_needs_insn[i] = insn;		    }		  if (max_groups[i] < insn_groups[i])		    {		      max_groups[i] = insn_groups[i];		      max_groups_insn[i] = insn;		    }		  if (insn_total_groups > 0)		    if (max_nongroups[i] < insn_needs[i])		      {			max_nongroups[i] = insn_needs[i];			max_nongroups_insn[i] = insn;		      }		}	    }	  /* Note that there is a continue statement above.  */	}      /* If we allocated any new memory locations, make another pass	 since it might have changed elimination offsets.  */      if (starting_frame_size != get_frame_size ())	something_changed = 1;      if (dumpfile)	for (i = 0; i < N_REG_CLASSES; i++)	  {	    if (max_needs[i] > 0)	      fprintf (dumpfile,			 ";; Need %d reg%s of class %s (for insn %d).\n",		       max_needs[i], max_needs[i] == 1 ? "" : "s",		       reg_class_names[i], INSN_UID (max_needs_insn[i]));	    if (max_nongroups[i] > 0)	      fprintf (dumpfile,		       ";; Need %d nongroup reg%s of class %s (for insn %d).\n",		       max_nongroups[i], max_nongroups[i] == 1 ? "" : "s",		       reg_class_names[i], INSN_UID (max_nongroups_insn[i]));	    if (max_groups[i] > 0)	      fprintf (dumpfile,		       ";; Need %d group%s (%smode) of class %s (for insn %d).\n",		       max_groups[i], max_groups[i] == 1 ? "" : "s",		       mode_name[(int) group_mode[i]],		       reg_class_names[i], INSN_UID (max_groups_insn[i]));	  }			       /* If we have caller-saves, set up the save areas and see if caller-save	 will need a spill register.  */      if (caller_save_needed	  && ! setup_save_areas (&something_changed)	  && caller_save_spill_class  == NO_REGS)	{	  /* The class we will need depends on whether the machine	     supports the sum of two registers for an address; see	     find_address_reloads for details.  */	  caller_save_spill_class	    = double_reg_address_ok ? INDEX_REG_CLASS : BASE_REG_CLASS;	  caller_save_group_size	    = CLASS_MAX_NREGS (caller_save_spill_class, Pmode);	  something_changed = 1;	}      /* Now deduct from the needs for the registers already	 available (already spilled).  */      CLEAR_HARD_REG_SET (counted_for_groups);      CLEAR_HARD_REG_SET (counted_for_nongroups);      /* First find all regs alone in their class	 and count them (if desired) for non-groups.	 We would be screwed if a group took the only reg in a class	 for which a non-group reload is needed.	 (Note there is still a bug; if a class has 2 regs,	 both could be stolen by groups and we would lose the same way.	 With luck, no machine will need a nongroup in a 2-reg class.)  */      for (i = 0; i < n_spills; i++)	{	  register enum reg_class *p;	  class = (int) REGNO_REG_CLASS (spill_regs[i]);	  if (reg_class_size[class] == 1 && max_nongroups[class] > 0)	    {	      max_needs[class]--;	      p = reg_class_superclasses[class];	      while (*p != LIM_REG_CLASSES)		max_needs[(int) *p++]--;	      SET_HARD_REG_BIT (counted_for_nongroups, spill_regs[i]);	      max_nongroups[class]--;	      p = reg_class_superclasses[class];	      while (*p != LIM_REG_CLASSES)		{		  if (max_nongroups[(int) *p] > 0)		    SET_HARD_REG_BIT (counted_for_nongroups, spill_regs[i]);		  max_nongroups[(int) *p++]--;		}	    }	}      /* Now find all consecutive groups of spilled registers	 and mark each group off against the need for such groups.	 But don't count them against ordinary need, yet.  */      count_possible_groups (group_size, group_mode, max_groups);      /* Now count all spill regs against the individual need,	 This includes those counted above for groups,	 but not those previously counted for nongroups.	 Those that weren't counted_for_groups can also count against	 the not-in-group need.  */      for (i = 0; i < n_spills; i++)	{	  register enum reg_class *p;	  class = (int) REGNO_REG_CLASS (spill_regs[i]);	  /* Those counted at the beginning shouldn't be counted twice.  */	  if (! TEST_HARD_REG_BIT (counted_for_nongroups, spill_regs[i]))	    {	      max_needs[class]--;	      p = reg_class_superclasses[class];	      while (*p != LIM_REG_CLASSES)		max_needs[(int) *p++]--;	      if (! TEST_HARD_REG_BIT (counted_for_groups, spill_regs[i]))		{		  if (max_nongroups[class] > 0)		    SET_HARD_REG_BIT (counted_for_nongroups, spill_regs[i]);		  max_nongroups[class]--;		  p = reg_class_superclasses[class];		  while (*p != LIM_REG_CLASSES)		    {		      if (max_nongroups[(int) *p] > 0)			SET_HARD_REG_BIT (counted_for_nongroups,					  spill_regs[i]);		      max_nongroups[(int) *p++]--;		    }		}	    }	}      /* See if anything that happened changes which eliminations are valid.	 For example, on the Sparc, whether or not the frame pointer can	 be eliminated can depend on what registers have been used.  We need	 not check some conditions again (such as flag_omit_frame_pointer)	 since they can't have changed.  */      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)	if ((ep->from == FRAME_POINTER_REGNUM && FRAME_POINTER_REQUIRED)#ifdef ELIMINABLE_REGS	    || ! CAN_ELIMINATE (ep->from, ep->to)#endif	    )	  ep->can_eliminate = 0;      /* Look for the case where we have discovered that we can't replace	 register A with register B and that means that we will now be	 trying to replace register A with register C.  This means we can	 no longer replace register C with register B and we need to disable	 such an elimination, if it exists.  This occurs often with A == ap,	 B == sp, and C == fp.  */      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)	{	  struct elim_table *op;	  register int new_to = -1;	  if (! ep->can_eliminate && ep->can_eliminate_previous)	    {	      /* Find the current elimination for ep->from, if there is a		 new one.  */

⌨️ 快捷键说明

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