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

📄 emit-rtl.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 5 页
字号:
		  || (GET_CODE (PATTERN (insn)) != USE		      && GET_CODE (PATTERN (insn)) != CLOBBER))))	break;    }  return insn;}/* Find the last insn before INSN that really does something.  This routine   does not look inside SEQUENCEs.  Until reload has completed, this is the   same as prev_real_insn.  */rtxprev_active_insn (insn)     rtx insn;{  while (insn)    {      insn = PREV_INSN (insn);      if (insn == 0	  || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN	  || (GET_CODE (insn) == INSN	      && (! reload_completed		  || (GET_CODE (PATTERN (insn)) != USE		      && GET_CODE (PATTERN (insn)) != CLOBBER))))	break;    }  return insn;}/* Return the next CODE_LABEL after the insn INSN, or 0 if there is none.  */rtxnext_label (insn)     rtx insn;{  while (insn)    {      insn = NEXT_INSN (insn);      if (insn == 0 || GET_CODE (insn) == CODE_LABEL)	break;    }  return insn;}/* Return the last CODE_LABEL before the insn INSN, or 0 if there is none.  */rtxprev_label (insn)     rtx insn;{  while (insn)    {      insn = PREV_INSN (insn);      if (insn == 0 || GET_CODE (insn) == CODE_LABEL)	break;    }  return insn;}#ifdef HAVE_cc0/* INSN uses CC0 and is being moved into a delay slot.  Set up REG_CC_SETTER   and REG_CC_USER notes so we can find it.  */voidlink_cc0_insns (insn)     rtx insn;{  rtx user = next_nonnote_insn (insn);  if (GET_CODE (user) == INSN && GET_CODE (PATTERN (user)) == SEQUENCE)    user = XVECEXP (PATTERN (user), 0, 0);  REG_NOTES (user) = gen_rtx (INSN_LIST, REG_CC_SETTER, insn,			      REG_NOTES (user));  REG_NOTES (insn) = gen_rtx (INSN_LIST, REG_CC_USER, user, REG_NOTES (insn));}/* Return the next insn that uses CC0 after INSN, which is assumed to   set it.  This is the inverse of prev_cc0_setter (i.e., prev_cc0_setter   applied to the result of this function should yield INSN).   Normally, this is simply the next insn.  However, if a REG_CC_USER note   is present, it contains the insn that uses CC0.   Return 0 if we can't find the insn.  */rtxnext_cc0_user (insn)     rtx insn;{  rtx note = find_reg_note (insn, REG_CC_USER, NULL_RTX);  if (note)    return XEXP (note, 0);  insn = next_nonnote_insn (insn);  if (insn && GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)    insn = XVECEXP (PATTERN (insn), 0, 0);  if (insn && GET_RTX_CLASS (GET_CODE (insn)) == 'i'      && reg_mentioned_p (cc0_rtx, PATTERN (insn)))    return insn;  return 0;}/* Find the insn that set CC0 for INSN.  Unless INSN has a REG_CC_SETTER   note, it is the previous insn.  */rtxprev_cc0_setter (insn)     rtx insn;{  rtx note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);  rtx link;  if (note)    return XEXP (note, 0);  insn = prev_nonnote_insn (insn);  if (! sets_cc0_p (PATTERN (insn)))    abort ();  return insn;}#endif/* Try splitting insns that can be split for better scheduling.   PAT is the pattern which might split.   TRIAL is the insn providing PAT.   LAST is non-zero if we should return the last insn of the sequence produced.   If this routine succeeds in splitting, it returns the first or last   replacement insn depending on the value of LAST.  Otherwise, it   returns TRIAL.  If the insn to be returned can be split, it will be.  */rtxtry_split (pat, trial, last)     rtx pat, trial;     int last;{  rtx before = PREV_INSN (trial);  rtx after = NEXT_INSN (trial);  rtx seq = split_insns (pat, trial);  int has_barrier = 0;  rtx tem;  /* If we are splitting a JUMP_INSN, it might be followed by a BARRIER.     We may need to handle this specially.  */  if (after && GET_CODE (after) == BARRIER)    {      has_barrier = 1;      after = NEXT_INSN (after);    }  if (seq)    {      /* SEQ can either be a SEQUENCE or the pattern of a single insn.	 The latter case will normally arise only when being done so that	 it, in turn, will be split (SFmode on the 29k is an example).  */      if (GET_CODE (seq) == SEQUENCE)	{	  /* If we are splitting a JUMP_INSN, look for the JUMP_INSN in	     SEQ and copy our JUMP_LABEL to it.  If JUMP_LABEL is non-zero,	     increment the usage count so we don't delete the label.  */	  int i;	  if (GET_CODE (trial) == JUMP_INSN)	    for (i = XVECLEN (seq, 0) - 1; i >= 0; i--)	      if (GET_CODE (XVECEXP (seq, 0, i)) == JUMP_INSN)		{		  JUMP_LABEL (XVECEXP (seq, 0, i)) = JUMP_LABEL (trial);		  if (JUMP_LABEL (trial))		    LABEL_NUSES (JUMP_LABEL (trial))++;		}	  tem = emit_insn_after (seq, before);	  delete_insn (trial);	  if (has_barrier)	    emit_barrier_after (tem);	  /* Recursively call try_split for each new insn created; by the	     time control returns here that insn will be fully split, so	     set LAST and continue from the insn after the one returned.	     We can't use next_active_insn here since AFTER may be a note.	     Ignore deleted insns, which can be occur if not optimizing.  */	  for (tem = NEXT_INSN (before); tem != after;	       tem = NEXT_INSN (tem))	    if (! INSN_DELETED_P (tem))	      tem = try_split (PATTERN (tem), tem, 1);	}      /* Avoid infinite loop if the result matches the original pattern.  */      else if (rtx_equal_p (seq, pat))	return trial;      else	{	  PATTERN (trial) = seq;	  INSN_CODE (trial) = -1;	  try_split (seq, trial, last);	}      /* Return either the first or the last insn, depending on which was	 requested.  */      return last ? prev_active_insn (after) : next_active_insn (before);    }  return trial;}/* Make and return an INSN rtx, initializing all its slots.   Store PATTERN in the pattern slots.  */rtxmake_insn_raw (pattern)     rtx pattern;{  register rtx insn;  insn = rtx_alloc (INSN);  INSN_UID (insn) = cur_insn_uid++;  PATTERN (insn) = pattern;  INSN_CODE (insn) = -1;  LOG_LINKS (insn) = NULL;  REG_NOTES (insn) = NULL;  return insn;}/* Like `make_insn' but make a JUMP_INSN instead of an insn.  */static rtxmake_jump_insn_raw (pattern)     rtx pattern;{  register rtx insn;  insn = rtx_alloc (JUMP_INSN);  INSN_UID (insn) = cur_insn_uid++;  PATTERN (insn) = pattern;  INSN_CODE (insn) = -1;  LOG_LINKS (insn) = NULL;  REG_NOTES (insn) = NULL;  JUMP_LABEL (insn) = NULL;  return insn;}/* Like `make_insn' but make a CALL_INSN instead of an insn.  */static rtxmake_call_insn_raw (pattern)     rtx pattern;{  register rtx insn;  insn = rtx_alloc (CALL_INSN);  INSN_UID (insn) = cur_insn_uid++;  PATTERN (insn) = pattern;  INSN_CODE (insn) = -1;  LOG_LINKS (insn) = NULL;  REG_NOTES (insn) = NULL;  CALL_INSN_FUNCTION_USAGE (insn) = NULL;  return insn;}/* Add INSN to the end of the doubly-linked list.   INSN may be an INSN, JUMP_INSN, CALL_INSN, CODE_LABEL, BARRIER or NOTE.  */voidadd_insn (insn)     register rtx insn;{  PREV_INSN (insn) = last_insn;  NEXT_INSN (insn) = 0;  if (NULL != last_insn)    NEXT_INSN (last_insn) = insn;  if (NULL == first_insn)    first_insn = insn;  last_insn = insn;}/* Add INSN into the doubly-linked list after insn AFTER.  This and   the next should be the only functions called to insert an insn once   delay slots have been filled since only they know how to update a   SEQUENCE.  */voidadd_insn_after (insn, after)     rtx insn, after;{  rtx next = NEXT_INSN (after);  if (optimize && INSN_DELETED_P (after))    abort ();  NEXT_INSN (insn) = next;  PREV_INSN (insn) = after;  if (next)    {      PREV_INSN (next) = insn;      if (GET_CODE (next) == INSN && GET_CODE (PATTERN (next)) == SEQUENCE)	PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = insn;    }  else if (last_insn == after)    last_insn = insn;  else    {      struct sequence_stack *stack = sequence_stack;      /* Scan all pending sequences too.  */      for (; stack; stack = stack->next)	if (after == stack->last)	  {	    stack->last = insn;	    break;	  }      if (stack == 0)	abort ();    }  NEXT_INSN (after) = insn;  if (GET_CODE (after) == INSN && GET_CODE (PATTERN (after)) == SEQUENCE)    {      rtx sequence = PATTERN (after);      NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = insn;    }}/* Add INSN into the doubly-linked list before insn BEFORE.  This and   the previous should be the only functions called to insert an insn once   delay slots have been filled since only they know how to update a   SEQUENCE.  */voidadd_insn_before (insn, before)     rtx insn, before;{  rtx prev = PREV_INSN (before);  if (optimize && INSN_DELETED_P (before))    abort ();  PREV_INSN (insn) = prev;  NEXT_INSN (insn) = before;  if (prev)    {      NEXT_INSN (prev) = insn;      if (GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == SEQUENCE)	{	  rtx sequence = PATTERN (prev);	  NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = insn;	}    }  else if (first_insn == before)    first_insn = insn;  else    {      struct sequence_stack *stack = sequence_stack;      /* Scan all pending sequences too.  */      for (; stack; stack = stack->next)	if (before == stack->first)	  {	    stack->first = insn;	    break;	  }      if (stack == 0)	abort ();    }  PREV_INSN (before) = insn;  if (GET_CODE (before) == INSN && GET_CODE (PATTERN (before)) == SEQUENCE)    PREV_INSN (XVECEXP (PATTERN (before), 0, 0)) = insn;}/* Delete all insns made since FROM.   FROM becomes the new last instruction.  */voiddelete_insns_since (from)     rtx from;{  if (from == 0)    first_insn = 0;  else    NEXT_INSN (from) = 0;  last_insn = from;}/* This function is deprecated, please use sequences instead.   Move a consecutive bunch of insns to a different place in the chain.   The insns to be moved are those between FROM and TO.   They are moved to a new position after the insn AFTER.   AFTER must not be FROM or TO or any insn in between.   This function does not know about SEQUENCEs and hence should not be   called after delay-slot filling has been done.  */voidreorder_insns (from, to, after)     rtx from, to, after;{  /* Splice this bunch out of where it is now.  */  if (PREV_INSN (from))    NEXT_INSN (PREV_INSN (from)) = NEXT_INSN (to);  if (NEXT_INSN (to))    PREV_INSN (NEXT_INSN (to)) = PREV_INSN (from);  if (last_insn == to)    last_insn = PREV_INSN (from);  if (first_insn == from)    first_insn = NEXT_INSN (to);  /* Make the new neighbors point to it and it to them.  */  if (NEXT_INSN (after))    PREV_INSN (NEXT_INSN (after)) = to;  NEXT_INSN (to) = NEXT_INSN (after);  PREV_INSN (from) = after;  NEXT_INSN (after) = from;  if (after == last_insn)    last_insn = to;}/* Return the line note insn preceding INSN.  */static rtxfind_line_note (insn)     rtx insn;{  if (no_line_numbers)    return 0;  for (; insn; insn = PREV_INSN (insn))    if (GET_CODE (insn) == NOTE        && NOTE_LINE_NUMBER (insn) >= 0)      break;  return insn;}/* Like reorder_insns, but inserts line notes to preserve the line numbers   of the moved insns when debugging.  This may insert a note between AFTER   and FROM, and another one after TO.  */voidreorder_insns_with_line_notes (from, t

⌨️ 快捷键说明

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