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

📄 function.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		      && reg_mentioned_p (var, PATTERN (insn))		      && reg_mentioned_p (call_dest, PATTERN (insn)))		    {		      rtx temp = gen_reg_rtx (GET_MODE (call_dest));		      emit_insn_before (gen_move_insn (temp, call_dest), insn);		      PATTERN (insn) = replace_rtx (PATTERN (insn),						    call_dest, temp);		    }	      		  if (GET_CODE (insn) == CALL_INSN		      && GET_CODE (PATTERN (insn)) == SET)		    call_dest = SET_DEST (PATTERN (insn));		  else if (GET_CODE (insn) == CALL_INSN			   && GET_CODE (PATTERN (insn)) == PARALLEL			   && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)		    call_dest = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));		  else		    call_dest = 0;		}	      /* See if we have to do anything to INSN now that VAR is in		 memory.  If it needs to be loaded into a pseudo, use a single		 pseudo for the entire insn in case there is a MATCH_DUP		 between two operands.  We pass a pointer to the head of		 a list of struct fixup_replacements.  If fixup_var_refs_1		 needs to allocate pseudos or replacement MEMs (for SUBREGs),		 it will record them in this list.		 		 If it allocated a pseudo for any replacement, we copy into		 it here.  */	      fixup_var_refs_1 (var, promoted_mode, &PATTERN (insn), insn,				&replacements);	      /* If this is last_parm_insn, and any instructions were output		 after it to fix it up, then we must set last_parm_insn to		 the last such instruction emitted.  */	      if (insn == last_parm_insn)		last_parm_insn = PREV_INSN (next_insn);	      while (replacements)		{		  if (GET_CODE (replacements->new) == REG)		    {		      rtx insert_before;		      rtx seq;		      /* OLD might be a (subreg (mem)).  */		      if (GET_CODE (replacements->old) == SUBREG)			replacements->old			  = fixup_memory_subreg (replacements->old, insn, 0);		      else			replacements->old			  = fixup_stack_1 (replacements->old, insn);		      insert_before = insn;		      /* If we are changing the mode, do a conversion.			 This might be wasteful, but combine.c will			 eliminate much of the waste.  */		      if (GET_MODE (replacements->new)			  != GET_MODE (replacements->old))			{			  start_sequence ();			  convert_move (replacements->new,					replacements->old, unsignedp);			  seq = gen_sequence ();			  end_sequence ();			}		      else			seq = gen_move_insn (replacements->new,					     replacements->old);		      emit_insn_before (seq, insert_before);		    }		  replacements = replacements->next;		}	    }	  /* Also fix up any invalid exprs in the REG_NOTES of this insn.	     But don't touch other insns referred to by reg-notes;	     we will get them elsewhere.  */	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))	    if (GET_CODE (note) != INSN_LIST)	      XEXP (note, 0)		= walk_fixup_memory_subreg (XEXP (note, 0), insn, 1);	}      insn = next;    }}/* VAR is a MEM that used to be a pseudo register with mode PROMOTED_MODE.   See if the rtx expression at *LOC in INSN needs to be changed.     REPLACEMENTS is a pointer to a list head that starts out zero, but may   contain a list of original rtx's and replacements. If we find that we need   to modify this insn by replacing a memory reference with a pseudo or by   making a new MEM to implement a SUBREG, we consult that list to see if   we have already chosen a replacement. If none has already been allocated,   we allocate it and update the list.  fixup_var_refs_insns will copy VAR   or the SUBREG, as appropriate, to the pseudo.  */static voidfixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)     register rtx var;     enum machine_mode promoted_mode;     register rtx *loc;     rtx insn;     struct fixup_replacement **replacements;{  register int i;  register rtx x = *loc;  RTX_CODE code = GET_CODE (x);  register char *fmt;  register rtx tem, tem1;  struct fixup_replacement *replacement;  switch (code)    {    case ADDRESSOF:      if (XEXP (x, 0) == var)	{	  /* Prevent sharing of rtl that might lose.  */	  rtx sub = copy_rtx (XEXP (var, 0));	  start_sequence ();	  if (! validate_change (insn, loc, sub, 0))	    {	      rtx y = force_operand (sub, NULL_RTX);	      if (! validate_change (insn, loc, y, 0))		*loc = copy_to_reg (y);	    }	  emit_insn_before (gen_sequence (), insn);	  end_sequence ();	}      return;    case MEM:      if (var == x)	{	  /* If we already have a replacement, use it.  Otherwise, 	     try to fix up this address in case it is invalid.  */	  replacement = find_fixup_replacement (replacements, var);	  if (replacement->new)	    {	      *loc = replacement->new;	      return;	    }	  *loc = replacement->new = x = fixup_stack_1 (x, insn);	  /* Unless we are forcing memory to register or we changed the mode,	     we can leave things the way they are if the insn is valid.  */	     	  INSN_CODE (insn) = -1;	  if (! flag_force_mem && GET_MODE (x) == promoted_mode	      && recog_memoized (insn) >= 0)	    return;	  *loc = replacement->new = gen_reg_rtx (promoted_mode);	  return;	}      /* If X contains VAR, we need to unshare it here so that we update	 each occurrence separately.  But all identical MEMs in one insn	 must be replaced with the same rtx because of the possibility of	 MATCH_DUPs.  */      if (reg_mentioned_p (var, x))	{	  replacement = find_fixup_replacement (replacements, x);	  if (replacement->new == 0)	    replacement->new = copy_most_rtx (x, var);	  *loc = x = replacement->new;	}      break;    case REG:    case CC0:    case PC:    case CONST_INT:    case CONST:    case SYMBOL_REF:    case LABEL_REF:    case CONST_DOUBLE:      return;    case SIGN_EXTRACT:    case ZERO_EXTRACT:      /* Note that in some cases those types of expressions are altered	 by optimize_bit_field, and do not survive to get here.  */      if (XEXP (x, 0) == var	  || (GET_CODE (XEXP (x, 0)) == SUBREG	      && SUBREG_REG (XEXP (x, 0)) == var))	{	  /* Get TEM as a valid MEM in the mode presently in the insn.	     We don't worry about the possibility of MATCH_DUP here; it	     is highly unlikely and would be tricky to handle.  */	  tem = XEXP (x, 0);	  if (GET_CODE (tem) == SUBREG)	    {	      if (GET_MODE_BITSIZE (GET_MODE (tem))		  > GET_MODE_BITSIZE (GET_MODE (var)))		{		  replacement = find_fixup_replacement (replacements, var);		  if (replacement->new == 0)		    replacement->new = gen_reg_rtx (GET_MODE (var));		  SUBREG_REG (tem) = replacement->new;		}	      else		tem = fixup_memory_subreg (tem, insn, 0);	    }	  else	    tem = fixup_stack_1 (tem, insn);	  /* Unless we want to load from memory, get TEM into the proper mode	     for an extract from memory.  This can only be done if the	     extract is at a constant position and length.  */	  if (! flag_force_mem && GET_CODE (XEXP (x, 1)) == CONST_INT	      && GET_CODE (XEXP (x, 2)) == CONST_INT	      && ! mode_dependent_address_p (XEXP (tem, 0))	      && ! MEM_VOLATILE_P (tem))	    {	      enum machine_mode wanted_mode = VOIDmode;	      enum machine_mode is_mode = GET_MODE (tem);	      int width = INTVAL (XEXP (x, 1));	      int pos = INTVAL (XEXP (x, 2));#ifdef HAVE_extzv	      if (GET_CODE (x) == ZERO_EXTRACT)		wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];#endif#ifdef HAVE_extv	      if (GET_CODE (x) == SIGN_EXTRACT)		wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];#endif	      /* If we have a narrower mode, we can do something.  */	      if (wanted_mode != VOIDmode		  && GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))		{		  int offset = pos / BITS_PER_UNIT;		  rtx old_pos = XEXP (x, 2);		  rtx newmem;		  /* If the bytes and bits are counted differently, we		     must adjust the offset.  */		  if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN)		    offset = (GET_MODE_SIZE (is_mode)			      - GET_MODE_SIZE (wanted_mode) - offset);		  pos %= GET_MODE_BITSIZE (wanted_mode);		  newmem = gen_rtx (MEM, wanted_mode,				    plus_constant (XEXP (tem, 0), offset));		  RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (tem);		  MEM_VOLATILE_P (newmem) = MEM_VOLATILE_P (tem);		  MEM_IN_STRUCT_P (newmem) = MEM_IN_STRUCT_P (tem);		  /* Make the change and see if the insn remains valid.  */		  INSN_CODE (insn) = -1;		  XEXP (x, 0) = newmem;		  XEXP (x, 2) = GEN_INT (pos);		  if (recog_memoized (insn) >= 0)		    return;		  /* Otherwise, restore old position.  XEXP (x, 0) will be		     restored later.  */		  XEXP (x, 2) = old_pos;		}	    }	  /* If we get here, the bitfield extract insn can't accept a memory	     reference.  Copy the input into a register.  */	  tem1 = gen_reg_rtx (GET_MODE (tem));	  emit_insn_before (gen_move_insn (tem1, tem), insn);	  XEXP (x, 0) = tem1;	  return;	}      break;	          case SUBREG:      if (SUBREG_REG (x) == var)	{	  /* If this is a special SUBREG made because VAR was promoted	     from a wider mode, replace it with VAR and call ourself	     recursively, this time saying that the object previously	     had its current mode (by virtue of the SUBREG).  */	  if (SUBREG_PROMOTED_VAR_P (x))	    {	      *loc = var;	      fixup_var_refs_1 (var, GET_MODE (var), loc, insn, replacements);	      return;	    }	  /* If this SUBREG makes VAR wider, it has become a paradoxical	     SUBREG with VAR in memory, but these aren't allowed at this 	     stage of the compilation.  So load VAR into a pseudo and take	     a SUBREG of that pseudo.  */	  if (GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (var)))	    {	      replacement = find_fixup_replacement (replacements, var);	      if (replacement->new == 0)		replacement->new = gen_reg_rtx (GET_MODE (var));	      SUBREG_REG (x) = replacement->new;	      return;	    }	  /* See if we have already found a replacement for this SUBREG.	     If so, use it.  Otherwise, make a MEM and see if the insn	     is recognized.  If not, or if we should force MEM into a register,	     make a pseudo for this SUBREG.  */	  replacement = find_fixup_replacement (replacements, x);	  if (replacement->new)	    {	      *loc = replacement->new;	      return;	    }	  	  replacement->new = *loc = fixup_memory_subreg (x, insn, 0);	  INSN_CODE (insn) = -1;	  if (! flag_force_mem && recog_memoized (insn) >= 0)	    return;	  *loc = replacement->new = gen_reg_rtx (GET_MODE (x));	  return;	}      break;    case SET:      /* First do special simplification of bit-field references.  */      if (GET_CODE (SET_DEST (x)) == SIGN_EXTRACT	  || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)	optimize_bit_field (x, insn, 0);      if (GET_CODE (SET_SRC (x)) == SIGN_EXTRACT	  || GET_CODE (SET_SRC (x)) == ZERO_EXTRACT)	optimize_bit_field (x, insn, NULL_PTR);      /* For a paradoxical SUBREG inside a ZERO_EXTRACT, load the object	 into a register and then store it back out.  */      if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT	  && GET_CODE (XEXP (SET_DEST (x), 0)) == SUBREG	  && SUBREG_REG (XEXP (SET_DEST (x), 0)) == var	  && (GET_MODE_SIZE (GET_MODE (XEXP (SET_DEST (x), 0)))	      > GET_MODE_SIZE (GET_MODE (var))))	{	  replacement = find_fixup_replacement (replacements, var);	  if (replacement->new == 0)	    replacement->new = gen_reg_rtx (GET_MODE (var));	  SUBREG_REG (XEXP (SET_DEST (x), 0)) = replacement->new;	  emit_insn_after (gen_move_insn (var, replacement->new), insn);	}      /* If SET_DEST is now a paradoxical SUBREG, put the result of this	 insn into a pseudo and store the low part of the pseudo into VAR.  */      if (GET_CODE (SET_DEST (x)) == SUBREG	  && SUBREG_REG (SET_DEST (x)) == var	  && (GET_MODE_SIZE (GET_MODE (SET_DEST (x)))	      > GET_MODE_SIZE (GET_MODE (var))))	{	  SET_DEST (x) = tem = gen_reg_rtx (GET_MODE (SET_DEST (x)));	  emit_insn_after (gen_move_insn (var, gen_lowpart (GET_MODE (var),							    tem)),			   insn);	  break;	}	        {	rtx dest = SET_DEST (x);	rtx src = SET_SRC (x);	rtx outerdest = dest;	while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART	       || GET_CODE (dest) == SIGN_EXTRACT	       || GET_CODE (dest) == ZERO_EXTRACT)	  dest = XEXP (dest, 0);	if (GET_CODE (src) == SUBREG)	  src = XEXP (src, 0);	/* If VAR does not appear at the top level of the SET	   just scan the lower levels of the tree.  */        if (src != var && dest != var)	  break;	/* We will need to rerecognize this insn.  */	INSN_CODE (insn) = -1;#ifdef HAVE_insv	if (GET_CODE (outerdest) == ZERO_EXTRACT && dest == var)	  {	    /* Since this case will return, ensure we fixup

⌨️ 快捷键说明

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