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

📄 sched.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
    = (char *) oballoc ((maxreg -FIRST_PSEUDO_REGISTER) * sizeof (char))      - FIRST_PSEUDO_REGISTER;  bzero (reg_known_equiv_p + FIRST_PSEUDO_REGISTER,	 (maxreg - FIRST_PSEUDO_REGISTER) * sizeof (char));  /* Fill in the entries with known constant values.  */  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))    if ((set = single_set (insn)) != 0	&& GET_CODE (SET_DEST (set)) == REG	&& REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER	&& (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0	     && reg_n_sets[REGNO (SET_DEST (set))] == 1)	    || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)	&& GET_CODE (XEXP (note, 0)) != EXPR_LIST)      {	int regno = REGNO (SET_DEST (set));	reg_known_value[regno] = XEXP (note, 0);	reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV;      }  /* Fill in the remaining entries.  */  while (--maxreg >= FIRST_PSEUDO_REGISTER)    if (reg_known_value[maxreg] == 0)      reg_known_value[maxreg] = regno_reg_rtx[maxreg];}/* Return 1 if X and Y are identical-looking rtx's.   We use the data in reg_known_value above to see if two registers with   different numbers are, in fact, equivalent.  */static intrtx_equal_for_memref_p (x, y)     rtx x, y;{  register int i;  register int j;  register enum rtx_code code;  register char *fmt;  if (x == 0 && y == 0)    return 1;  if (x == 0 || y == 0)    return 0;  x = canon_rtx (x);  y = canon_rtx (y);  if (x == y)    return 1;  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;  /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively.  */  if (code == REG)    return REGNO (x) == REGNO (y);  if (code == LABEL_REF)    return XEXP (x, 0) == XEXP (y, 0);  if (code == SYMBOL_REF)    return XSTR (x, 0) == XSTR (y, 0);  /* For commutative operations, the RTX match if the operand match in any     order.  Also handle the simple binary and unary cases without a loop.  */  if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c')    return ((rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0))	     && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1)))	    || (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 1))		&& rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 0))));  else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2')    return (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0))	    && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1)));  else if (GET_RTX_CLASS (code) == '1')    return rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0));  /* Compare the elements.  If any pair of corresponding elements     fail to match, return 0 for the whole things.  */  fmt = GET_RTX_FORMAT (code);  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)    {      switch (fmt[i])	{	case 'w':	  if (XWINT (x, i) != XWINT (y, i))	    return 0;	  break;	case 'n':	case 'i':	  if (XINT (x, i) != XINT (y, i))	    return 0;	  break;	case 'V':	case 'E':	  /* Two vectors must have the same length.  */	  if (XVECLEN (x, i) != XVECLEN (y, i))	    return 0;	  /* And the corresponding elements must match.  */	  for (j = 0; j < XVECLEN (x, i); j++)	    if (rtx_equal_for_memref_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0)	      return 0;	  break;	case 'e':	  if (rtx_equal_for_memref_p (XEXP (x, i), XEXP (y, i)) == 0)	    return 0;	  break;	case 'S':	case 's':	  if (strcmp (XSTR (x, i), XSTR (y, i)))	    return 0;	  break;	case 'u':	  /* These are just backpointers, so they don't matter.  */	  break;	case '0':	  break;	  /* It is believed that rtx's at this level will never	     contain anything but integers and other rtx's,	     except for within LABEL_REFs and SYMBOL_REFs.  */	default:	  abort ();	}    }  return 1;}/* Given an rtx X, find a SYMBOL_REF or LABEL_REF within   X and return it, or return 0 if none found.  */static rtxfind_symbolic_term (x)     rtx x;{  register int i;  register enum rtx_code code;  register char *fmt;  code = GET_CODE (x);  if (code == SYMBOL_REF || code == LABEL_REF)    return x;  if (GET_RTX_CLASS (code) == 'o')    return 0;  fmt = GET_RTX_FORMAT (code);  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)    {      rtx t;      if (fmt[i] == 'e')	{	  t = find_symbolic_term (XEXP (x, i));	  if (t != 0)	    return t;	}      else if (fmt[i] == 'E')	break;    }  return 0;}/* Return nonzero if X and Y (memory addresses) could reference the   same location in memory.  C is an offset accumulator.  When   C is nonzero, we are testing aliases between X and Y + C.   XSIZE is the size in bytes of the X reference,   similarly YSIZE is the size in bytes for Y.   If XSIZE or YSIZE is zero, we do not know the amount of memory being   referenced (the reference was BLKmode), so make the most pessimistic   assumptions.   We recognize the following cases of non-conflicting memory:	(1) addresses involving the frame pointer cannot conflict	    with addresses involving static variables.	(2) static variables with different addresses cannot conflict.   Nice to notice that varying addresses cannot conflict with fp if no   local variables had their addresses taken, but that's too hard now.  *//* ??? In Fortran, references to a array parameter can never conflict with   another array parameter.  */static intmemrefs_conflict_p (xsize, x, ysize, y, c)     rtx x, y;     int xsize, ysize;     HOST_WIDE_INT c;{  if (GET_CODE (x) == HIGH)    x = XEXP (x, 0);  else if (GET_CODE (x) == LO_SUM)    x = XEXP (x, 1);  else    x = canon_rtx (x);  if (GET_CODE (y) == HIGH)    y = XEXP (y, 0);  else if (GET_CODE (y) == LO_SUM)    y = XEXP (y, 1);  else    y = canon_rtx (y);  if (rtx_equal_for_memref_p (x, y))    return (xsize == 0 || ysize == 0 ||	    (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));  if (y == frame_pointer_rtx || y == hard_frame_pointer_rtx      || y == stack_pointer_rtx)    {      rtx t = y;      int tsize = ysize;      y = x; ysize = xsize;      x = t; xsize = tsize;    }  if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx      || x == stack_pointer_rtx)    {      rtx y1;      if (CONSTANT_P (y))	return 0;      if (GET_CODE (y) == PLUS	  && canon_rtx (XEXP (y, 0)) == x	  && (y1 = canon_rtx (XEXP (y, 1)))	  && GET_CODE (y1) == CONST_INT)	{	  c += INTVAL (y1);	  return (xsize == 0 || ysize == 0		  || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));	}      if (GET_CODE (y) == PLUS	  && (y1 = canon_rtx (XEXP (y, 0)))	  && CONSTANT_P (y1))	return 0;      return 1;    }  if (GET_CODE (x) == PLUS)    {      /* The fact that X is canonicalized means that this	 PLUS rtx is canonicalized.  */      rtx x0 = XEXP (x, 0);      rtx x1 = XEXP (x, 1);      if (GET_CODE (y) == PLUS)	{	  /* The fact that Y is canonicalized means that this	     PLUS rtx is canonicalized.  */	  rtx y0 = XEXP (y, 0);	  rtx y1 = XEXP (y, 1);	  if (rtx_equal_for_memref_p (x1, y1))	    return memrefs_conflict_p (xsize, x0, ysize, y0, c);	  if (rtx_equal_for_memref_p (x0, y0))	    return memrefs_conflict_p (xsize, x1, ysize, y1, c);	  if (GET_CODE (x1) == CONST_INT)	    if (GET_CODE (y1) == CONST_INT)	      return memrefs_conflict_p (xsize, x0, ysize, y0,					 c - INTVAL (x1) + INTVAL (y1));	    else	      return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1));	  else if (GET_CODE (y1) == CONST_INT)	    return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));	  /* Handle case where we cannot understand iteration operators,	     but we notice that the base addresses are distinct objects.  */	  x = find_symbolic_term (x);	  if (x == 0)	    return 1;	  y = find_symbolic_term (y);	  if (y == 0)	    return 1;	  return rtx_equal_for_memref_p (x, y);	}      else if (GET_CODE (x1) == CONST_INT)	return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1));    }  else if (GET_CODE (y) == PLUS)    {      /* The fact that Y is canonicalized means that this	 PLUS rtx is canonicalized.  */      rtx y0 = XEXP (y, 0);      rtx y1 = XEXP (y, 1);      if (GET_CODE (y1) == CONST_INT)	return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));      else	return 1;    }  if (GET_CODE (x) == GET_CODE (y))    switch (GET_CODE (x))      {      case MULT:	{	  /* Handle cases where we expect the second operands to be the	     same, and check only whether the first operand would conflict	     or not.  */	  rtx x0, y0;	  rtx x1 = canon_rtx (XEXP (x, 1));	  rtx y1 = canon_rtx (XEXP (y, 1));	  if (! rtx_equal_for_memref_p (x1, y1))	    return 1;	  x0 = canon_rtx (XEXP (x, 0));	  y0 = canon_rtx (XEXP (y, 0));	  if (rtx_equal_for_memref_p (x0, y0))	    return (xsize == 0 || ysize == 0		    || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));	  /* Can't properly adjust our sizes.  */	  if (GET_CODE (x1) != CONST_INT)	    return 1;	  xsize /= INTVAL (x1);	  ysize /= INTVAL (x1);	  c /= INTVAL (x1);	  return memrefs_conflict_p (xsize, x0, ysize, y0, c);	}      }  if (CONSTANT_P (x))    {      if (GET_CODE (x) == CONST_INT && GET_CODE (y) == CONST_INT)	{	  c += (INTVAL (y) - INTVAL (x));	  return (xsize == 0 || ysize == 0		  || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));	}      if (GET_CODE (x) == CONST)	{	  if (GET_CODE (y) == CONST)	    return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),				       ysize, canon_rtx (XEXP (y, 0)), c);	  else	    return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),				       ysize, y, c);	}      if (GET_CODE (y) == CONST)	return memrefs_conflict_p (xsize, x, ysize,				   canon_rtx (XEXP (y, 0)), c);      if (CONSTANT_P (y))	return (rtx_equal_for_memref_p (x, y)		&& (xsize == 0 || ysize == 0		    || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)));      return 1;    }  return 1;}/* Functions to compute memory dependencies.   Since we process the insns in execution order, we can build tables   to keep track of what registers are fixed (and not aliased), what registers   are varying in known ways, and what registers are varying in unknown   ways.   If both memory references are volatile, then there must always be a   dependence between the two references, since their order can not be   changed.  A volatile and non-volatile reference can be interchanged   though.    A MEM_IN_STRUCT reference at a non-QImode varying address can never   conflict with a non-MEM_IN_STRUCT reference at a fixed address.   We must   allow QImode aliasing because the ANSI C standard allows character   pointers to alias anything.  We are assuming that characters are   always QImode here.  *//* Read dependence: X is read after read in MEM takes place.  There can   only be a dependence here if both reads are volatile.  */intread_dependence (mem, x)     rtx mem;     rtx x;{  return MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem);}/* True dependence: X is read after store in MEM takes place.  */inttrue_dependence (mem, x)     rtx mem;     rtx x;{  /* If X is an unchanging read, then it can't possibly conflict with any     non-unchanging store.  It may conflict with an unchanging write though,     because there may be a single store to this address to initialize it.     Just fall through to the code below to resolve the case where we have     both an unchanging read and an unchanging write.  This won't handle all     cases optimally, but the possible performance loss should be     negligible.  */  if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem))

⌨️ 快捷键说明

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