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

📄 rtlanal.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Analyze RTL for C-Compiler   Copyright (C) 1987, 1988 Free Software Foundation, Inc.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 1, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */#include "config.h"#include "rtl.h"extern void note_stores ();static int reg_set_p ();/* Return 1 if the value of X is unstable   (would be different at a different point in the program).   The frame pointer, arg pointer, etc. are considered stable   (within one function) and so is anything marked `unchanging'.  */intrtx_unstable_p (x)     rtx x;{  register RTX_CODE code = GET_CODE (x);  register int i;  register char *fmt;  if (code == MEM)    return ! RTX_UNCHANGING_P (x);  if (code == QUEUED)    return 1;  if (code == CONST || code == CONST_INT)    return 0;  if (code == REG)    return ! (REGNO (x) == FRAME_POINTER_REGNUM	      || REGNO (x) == ARG_POINTER_REGNUM	      || RTX_UNCHANGING_P (x));  fmt = GET_RTX_FORMAT (code);  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)    if (fmt[i] == 'e')      if (rtx_unstable_p (XEXP (x, i)))	return 1;  return 0;}/* Return 1 if X has a value that can vary even between two   executions of the program.  0 means X can be compared reliably   against certain constants or near-constants.   The frame pointer and the arg pointer are considered constant.  */intrtx_varies_p (x)     rtx x;{  register RTX_CODE code = GET_CODE (x);  register int i;  register char *fmt;  if (code == MEM)    return 1;  if (code == QUEUED)    return 1;  if (code == CONST || code == CONST_INT)    return 0;  if (code == REG)    return ! (REGNO (x) == FRAME_POINTER_REGNUM	      || REGNO (x) == ARG_POINTER_REGNUM);  fmt = GET_RTX_FORMAT (code);  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)    if (fmt[i] == 'e')      if (rtx_varies_p (XEXP (x, i)))	return 1;  return 0;}/* Return 1 if X refers to a memory location whose address    cannot be compared reliably with constant addresses,   or if X refers to a BLKmode memory object.  */intrtx_addr_varies_p (x)     rtx x;{  register enum rtx_code code;  register int i;  register char *fmt;  if (x == 0)    return 0;  code = GET_CODE (x);  if (code == MEM)    return GET_MODE (x) == BLKmode || rtx_varies_p (XEXP (x, 0));  fmt = GET_RTX_FORMAT (code);  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)    if (fmt[i] == 'e')      if (rtx_addr_varies_p (XEXP (x, i)))	return 1;  return 0;}/* Nonzero if register REG appears somewhere within IN.   Also works if REG is not a register; in this case it checks   for a subexpression of IN that is Lisp "equal" to REG.  */intreg_mentioned_p (reg, in)     register rtx reg, in;{  register char *fmt;  register int i;  register enum rtx_code code;  if (in == 0)    return 0;  if (reg == in)    return 1;  code = GET_CODE (in);  switch (code)    {      /* Compare registers by number.  */    case REG:      return GET_CODE (reg) == REG && REGNO (in) == REGNO (reg);      /* These codes have no constituent expressions	 and are unique.  */    case CC0:    case PC:      return 0;    case CONST_INT:      return GET_CODE (reg) == CONST_INT && INTVAL (in) == INTVAL (reg);    }  if (GET_CODE (reg) == code && rtx_equal_p (reg, in))    return 1;  fmt = GET_RTX_FORMAT (code);  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)    {      if (fmt[i] == 'E')	{	  register int j;	  for (j = XVECLEN (in, i) - 1; j >= 0; j--)	    if (reg_mentioned_p (reg, XVECEXP (in, i, j)))	      return 1;	}      else if (fmt[i] == 'e'	       && reg_mentioned_p (reg, XEXP (in, i)))	return 1;    }  return 0;}/* Nonzero if register REG is used in an insn between   FROM_INSN and TO_INSN (exclusive of those two).  */intreg_used_between_p (reg, from_insn, to_insn)     rtx reg, from_insn, to_insn;{  register rtx insn;  register RTX_CODE code;  for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))    if (((code = GET_CODE (insn)) == INSN	 || code == JUMP_INSN || code == CALL_INSN)	&& reg_mentioned_p (reg, PATTERN (insn)))      return 1;  return 0;}/* Nonzero if register REG is set or clobbered in an insn between   FROM_INSN and TO_INSN (exclusive of those two).   Does not notice increments, only SET and CLOBBER.  */intreg_set_between_p (reg, from_insn, to_insn)     rtx reg, from_insn, to_insn;{  register rtx insn;  register RTX_CODE code;  for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))    if (((code = GET_CODE (insn)) == INSN	 || code == JUMP_INSN || code == CALL_INSN)	&& reg_set_p (reg, PATTERN (insn)))      return 1;  return 0;}/* Internals of reg_set_between_p.  */static rtx reg_set_reg;static int reg_set_flag;static voidreg_set_p_1 (x)     rtx x;{  if (reg_overlap_mentioned_p (reg_set_reg, x))    reg_set_flag = 1;}static intreg_set_p (reg, insn)     rtx reg, insn;{  reg_set_reg = reg;  reg_set_flag = 0;  note_stores (insn, reg_set_p_1);  return reg_set_flag;}/* Return nonzero if hard register in range [REGNO, ENDREGNO)   appears either explicitly or implicitly in X   other than being stored into.   References contained within the substructure at LOC do not count.   LOC may be zero, meaning don't ignore anything.  */intrefers_to_regno_p (regno, endregno, x, loc)     int regno, endregno;     rtx x;     rtx *loc;{  register int i;  register RTX_CODE code;  register char *fmt; repeat:  code = GET_CODE (x);  if (code == REG)    {      i = REGNO (x);      return (endregno > i && regno < i + HARD_REGNO_NREGS (i, GET_MODE (x)));    }  if (code == SET)    {      /* Note setting a SUBREG counts as referring to the REG it is in!  */      if (GET_CODE (SET_DEST (x)) != REG	  && refers_to_regno_p (regno, endregno, SET_DEST (x), loc))	return 1;      if (loc == &SET_SRC (x))	return 0;      x = SET_SRC (x);      goto repeat;    }  if (code == CLOBBER)    {      if (GET_CODE (SET_DEST (x)) != REG	  && refers_to_regno_p (regno, endregno, SET_DEST (x), loc))	return 1;      return 0;    }  /* X does not match, so try its subexpressions.  */  fmt = GET_RTX_FORMAT (code);  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)    {      if (fmt[i] == 'e' && loc != &XEXP (x, i))	{	  if (i == 0)	    {	      x = XEXP (x, 0);	      goto repeat;	    }	  else	    if (refers_to_regno_p (regno, endregno, XEXP (x, i), loc))	      return 1;	}      else if (fmt[i] == 'E')	{	  register int j;	  for (j = XVECLEN (x, i) - 1; j >=0; j--)	    if (loc != &XVECEXP (x, i, j)		&& refers_to_regno_p (regno, endregno, XVECEXP (x, i, j), loc))	      return 1;	}    }  return 0;}/* Nonzero if X contains any reg that overlaps hard register REG.  */intreg_overlap_mentioned_p (reg, x)     rtx reg, x;{  int regno = REGNO (reg);  int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));  return refers_to_regno_p (regno, endregno, x, 0);}/* This is 1 until after reload pass.  */int rtx_equal_function_value_matters;/* Return 1 if X and Y are identical-looking rtx's.   This is the Lisp function EQUAL for rtx arguments.  */intrtx_equal_p (x, y)     rtx x, y;{  register int i;  register int j;  register enum rtx_code code;  register char *fmt;  if (x == y)    return 1;  if (x == 0 || y == 0)    return 0;  code = GET_CODE (x);  /* Rtx's of different codes cannot be equal.  */  if (code != GET_CODE (y))    return 0;  /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.     (REG:SI x) and (REG:HI x) are NOT equivalent.  */  if (GET_MODE (x) != GET_MODE (y))    return 0;  /* These three types of rtx's can be compared nonrecursively.  */  /* Until the end of reload,     don't consider the a reference to the return register of the current     function the same as the return from a called function.  This eases     the job of function integration.  Once the distinction no longer     matters, the insn will be deleted.  */  if (code == REG)    return (REGNO (x) == REGNO (y)	    && (! rtx_equal_function_value_matters		|| REG_FUNCTION_VALUE_P (x) == REG_FUNCTION_VALUE_P (y)));  if (code == LABEL_REF)    return XEXP (x, 0) == XEXP (y, 0);  if (code == SYMBOL_REF)

⌨️ 快捷键说明

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