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

📄 reload1.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
			  && reg_classes_intersect_p (class,						      reload_reg_class[j]))			{			  nongroup_need = 1;			  break;			}		  /* Decide which time-of-use to count this reload for.  */		  switch (reload_when_needed[i])		    {		    case RELOAD_OTHER:		      this_needs = &insn_needs.other;		      break;		    case RELOAD_FOR_INPUT:		      this_needs = &insn_needs.input;		      break;		    case RELOAD_FOR_OUTPUT:		      this_needs = &insn_needs.output;		      break;		    case RELOAD_FOR_INSN:		      this_needs = &insn_needs.insn;		      break;		    case RELOAD_FOR_OTHER_ADDRESS:		      this_needs = &insn_needs.other_addr;		      break;		    case RELOAD_FOR_INPUT_ADDRESS:		      this_needs = &insn_needs.in_addr[reload_opnum[i]];		      break;		    case RELOAD_FOR_OUTPUT_ADDRESS:		      this_needs = &insn_needs.out_addr[reload_opnum[i]];		      break;		    case RELOAD_FOR_OPERAND_ADDRESS:		      this_needs = &insn_needs.op_addr;		      break;		    case RELOAD_FOR_OPADDR_ADDR:		      this_needs = &insn_needs.op_addr_reload;		      break;		    }		  if (size > 1)		    {		      enum machine_mode other_mode, allocate_mode;		      /* Count number of groups needed separately from			 number of individual regs needed.  */		      this_needs->groups[(int) class]++;		      p = reg_class_superclasses[(int) class];		      while (*p != LIM_REG_CLASSES)			this_needs->groups[(int) *p++]++;		      /* 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))			fatal_insn ("Two dissimilar machine modes both need groups of consecutive regs of the same class",				    insn);		    }		  else if (size == 1)		    {		      this_needs->regs[nongroup_need][(int) class] += 1;		      p = reg_class_superclasses[(int) class];		      while (*p != LIM_REG_CLASSES)			this_needs->regs[nongroup_need][(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 in_max, out_max;		  /* Compute normal and nongroup needs.  */		  for (j = 0; j <= 1; j++)		    {		      for (in_max = 0, out_max = 0, k = 0;			   k < reload_n_operands; k++)			{			  in_max			    = MAX (in_max, insn_needs.in_addr[k].regs[j][i]);			  out_max			    = MAX (out_max, insn_needs.out_addr[k].regs[j][i]);			}		      /* RELOAD_FOR_INSN reloads conflict with inputs, outputs,			 and operand addresses but not things used to reload			 them.  Similarly, RELOAD_FOR_OPERAND_ADDRESS reloads			 don't conflict with things needed to reload inputs or			 outputs. */		      in_max = MAX (MAX (insn_needs.op_addr.regs[j][i],					 insn_needs.op_addr_reload.regs[j][i]),				    in_max);		      out_max = MAX (out_max, insn_needs.insn.regs[j][i]);		      insn_needs.input.regs[j][i]			= MAX (insn_needs.input.regs[j][i]			       + insn_needs.op_addr.regs[j][i]			       + insn_needs.insn.regs[j][i],			       in_max + insn_needs.input.regs[j][i]);		      insn_needs.output.regs[j][i] += out_max;		      insn_needs.other.regs[j][i]			+= MAX (MAX (insn_needs.input.regs[j][i],				     insn_needs.output.regs[j][i]),				insn_needs.other_addr.regs[j][i]);		    }		  /* Now compute group needs.  */		  for (in_max = 0, out_max = 0, j = 0;		       j < reload_n_operands; j++)		    {		      in_max = MAX (in_max, insn_needs.in_addr[j].groups[i]);		      out_max			= MAX (out_max, insn_needs.out_addr[j].groups[i]);		    }		  in_max = MAX (MAX (insn_needs.op_addr.groups[i],				     insn_needs.op_addr_reload.groups[i]),				in_max);		  out_max = MAX (out_max, insn_needs.insn.groups[i]);		  insn_needs.input.groups[i]		    = MAX (insn_needs.input.groups[i]			   + insn_needs.op_addr.groups[i]			   + insn_needs.insn.groups[i],			   in_max + insn_needs.input.groups[i]);		  insn_needs.output.groups[i] += out_max;		  insn_needs.other.groups[i]		    += MAX (MAX (insn_needs.input.groups[i],				 insn_needs.output.groups[i]),			    insn_needs.other_addr.groups[i]);		}	      /* 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)		{		  /* See if this register would conflict with any reload		     that needs a group.  */		  int nongroup_need = 0;		  int *caller_save_needs;		  for (j = 0; j < n_reloads; j++)		    if ((CLASS_MAX_NREGS (reload_reg_class[j],					  (GET_MODE_SIZE (reload_outmode[j])					   > GET_MODE_SIZE (reload_inmode[j]))					  ? reload_outmode[j]					  : reload_inmode[j])			 > 1)			&& reg_classes_intersect_p (caller_save_spill_class,						    reload_reg_class[j]))		      {			nongroup_need = 1;			break;		      }		  caller_save_needs 		    = (caller_save_group_size > 1		       ? insn_needs.other.groups		       : insn_needs.other.regs[nongroup_need]); 		  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;		    }		  /* 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 basic_needs[N_REG_CLASSES], basic_groups[N_REG_CLASSES];		  /* First compute the "basic needs", which counts a		     need only in the smallest class in which it		     is required.  */		  bcopy ((char *) insn_needs.other.regs[0],			 (char *) basic_needs, sizeof basic_needs);		  bcopy ((char *) insn_needs.other.groups,			 (char *) basic_groups, sizeof basic_groups);		  for (i = 0; i < N_REG_CLASSES; i++)		    {		      enum reg_class *p;		      if (basic_needs[i] >= 0)			for (p = reg_class_superclasses[i];			     *p != LIM_REG_CLASSES; p++)			  basic_needs[(int) *p] -= basic_needs[i];		      if (basic_groups[i] >= 0)			for (p = reg_class_superclasses[i];			     *p != LIM_REG_CLASSES; p++)			  basic_groups[(int) *p] -= basic_groups[i];		    }		  /* Now count extra regs if there might be a conflict with		     the return value register. */		  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 (basic_needs[i] > 0)			      {				enum reg_class *p;				insn_needs.other.regs[0][i]++;				p = reg_class_superclasses[i];				while (*p != LIM_REG_CLASSES)				  insn_needs.other.regs[0][(int) *p++]++;			      }			    if (basic_groups[i] > 0)			      {				enum reg_class *p;				insn_needs.other.groups[i]++;				p = reg_class_superclasses[i];				while (*p != LIM_REG_CLASSES)				  insn_needs.other.groups[(int) *p++]++;			      }			  }		}#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.other.regs[0][i])		    {		      max_needs[i] = insn_needs.other.regs[0][i];		      max_needs_insn[i] = insn;		    }		  if (max_groups[i] < insn_needs.other.groups[i])		    {		      max_groups[i] = insn_needs.other.groups[i];		      max_groups_insn[i] = insn;		    }		  if (max_nongroups[i] < insn_needs.other.regs[1][i])		    {		      max_nongroups[i] = insn_needs.other.regs[1][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);

⌨️ 快捷键说明

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