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

📄 cse.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 5 页
字号:
static voidrehash_using_reg (x)     rtx x;{  int i;  struct table_elt *p, *next;  unsigned hash;  if (GET_CODE (x) == SUBREG)    x = SUBREG_REG (x);  /* If X is not a register or if the register is known not to be in any     valid entries in the table, we have no work to do.  */  if (GET_CODE (x) != REG      || reg_in_table[REGNO (x)] < 0      || reg_in_table[REGNO (x)] != reg_tick[REGNO (x)])    return;  /* Scan all hash chains looking for valid entries that mention X.     If we find one and it is in the wrong hash chain, move it.  We can skip     objects that are registers, since they are handled specially.  */  for (i = 0; i < NBUCKETS; i++)    for (p = table[i]; p; p = next)      {	next = p->next_same_hash;	if (GET_CODE (p->exp) != REG && reg_mentioned_p (x, p->exp)	    && exp_equiv_p (p->exp, p->exp, 1, 0)	    && i != (hash = safe_hash (p->exp, p->mode) % NBUCKETS))	  {	    if (p->next_same_hash)	      p->next_same_hash->prev_same_hash = p->prev_same_hash;	    if (p->prev_same_hash)	      p->prev_same_hash->next_same_hash = p->next_same_hash;	    else	      table[i] = p->next_same_hash;	    p->next_same_hash = table[hash];	    p->prev_same_hash = 0;	    if (table[hash])	      table[hash]->prev_same_hash = p;	    table[hash] = p;	  }      }}/* Remove from the hash table all expressions that reference memory,   or some of them as specified by *WRITES.  */static voidinvalidate_memory (writes)     struct write_data *writes;{  register int i;  register struct table_elt *p, *next;  int all = writes->all;  int nonscalar = writes->nonscalar;  for (i = 0; i < NBUCKETS; i++)    for (p = table[i]; p; p = next)      {	next = p->next_same_hash;	if (p->in_memory	    && (all		|| (nonscalar && p->in_struct)		|| cse_rtx_addr_varies_p (p->exp)))	  remove_from_table (p, i);      }}/* Remove from the hash table any expression that is a call-clobbered   register.  Also update their TICK values.  */static voidinvalidate_for_call (){  int regno, endregno;  int i;  unsigned hash;  struct table_elt *p, *next;  int in_table = 0;  /* Go through all the hard registers.  For each that is clobbered in     a CALL_INSN, remove the register from quantity chains and update     reg_tick if defined.  Also see if any of these registers is currently     in the table.  */  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)    if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))      {	delete_reg_equiv (regno);	if (reg_tick[regno] >= 0)	  reg_tick[regno]++;	in_table |= (TEST_HARD_REG_BIT (hard_regs_in_table, regno) != 0);      }  /* In the case where we have no call-clobbered hard registers in the     table, we are done.  Otherwise, scan the table and remove any     entry that overlaps a call-clobbered register.  */  if (in_table)    for (hash = 0; hash < NBUCKETS; hash++)      for (p = table[hash]; p; p = next)	{	  next = p->next_same_hash;	  if (GET_CODE (p->exp) != REG	      || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)	    continue;	  regno = REGNO (p->exp);	  endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (p->exp));	  for (i = regno; i < endregno; i++)	    if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))	      {		remove_from_table (p, hash);		break;	      }	}}/* Given an expression X of type CONST,   and ELT which is its table entry (or 0 if it   is not in the hash table),   return an alternate expression for X as a register plus integer.   If none can be found, return 0.  */static rtxuse_related_value (x, elt)     rtx x;     struct table_elt *elt;{  register struct table_elt *relt = 0;  register struct table_elt *p, *q;  HOST_WIDE_INT offset;  /* First, is there anything related known?     If we have a table element, we can tell from that.     Otherwise, must look it up.  */  if (elt != 0 && elt->related_value != 0)    relt = elt;  else if (elt == 0 && GET_CODE (x) == CONST)    {      rtx subexp = get_related_value (x);      if (subexp != 0)	relt = lookup (subexp,		       safe_hash (subexp, GET_MODE (subexp)) % NBUCKETS,		       GET_MODE (subexp));    }  if (relt == 0)    return 0;  /* Search all related table entries for one that has an     equivalent register.  */  p = relt;  while (1)    {      /* This loop is strange in that it is executed in two different cases.	 The first is when X is already in the table.  Then it is searching	 the RELATED_VALUE list of X's class (RELT).  The second case is when	 X is not in the table.  Then RELT points to a class for the related	 value.	 Ensure that, whatever case we are in, that we ignore classes that have	 the same value as X.  */      if (rtx_equal_p (x, p->exp))	q = 0;      else	for (q = p->first_same_value; q; q = q->next_same_value)	  if (GET_CODE (q->exp) == REG)	    break;      if (q)	break;      p = p->related_value;      /* We went all the way around, so there is nothing to be found.	 Alternatively, perhaps RELT was in the table for some other reason	 and it has no related values recorded.  */      if (p == relt || p == 0)	break;    }  if (q == 0)    return 0;  offset = (get_integer_term (x) - get_integer_term (p->exp));  /* Note: OFFSET may be 0 if P->xexp and X are related by commutativity.  */  return plus_constant (q->exp, offset);}/* Hash an rtx.  We are careful to make sure the value is never negative.   Equivalent registers hash identically.   MODE is used in hashing for CONST_INTs only;   otherwise the mode of X is used.   Store 1 in do_not_record if any subexpression is volatile.   Store 1 in hash_arg_in_memory if X contains a MEM rtx   which does not have the RTX_UNCHANGING_P bit set.   In this case, also store 1 in hash_arg_in_struct   if there is a MEM rtx which has the MEM_IN_STRUCT_P bit set.   Note that cse_insn knows that the hash code of a MEM expression   is just (int) MEM plus the hash code of the address.  */static unsignedcanon_hash (x, mode)     rtx x;     enum machine_mode mode;{  register int i, j;  register unsigned hash = 0;  register enum rtx_code code;  register char *fmt;  /* repeat is used to turn tail-recursion into iteration.  */ repeat:  if (x == 0)    return hash;  code = GET_CODE (x);  switch (code)    {    case REG:      {	register int regno = REGNO (x);	/* On some machines, we can't record any non-fixed hard register,	   because extending its life will cause reload problems.  We	   consider ap, fp, and sp to be fixed for this purpose.	   On all machines, we can't record any global registers. */	if (regno < FIRST_PSEUDO_REGISTER	    && (global_regs[regno]#ifdef SMALL_REGISTER_CLASSES		|| (! fixed_regs[regno]		    && regno != FRAME_POINTER_REGNUM		    && regno != HARD_FRAME_POINTER_REGNUM		    && regno != ARG_POINTER_REGNUM		    && regno != STACK_POINTER_REGNUM)#endif		))	  {	    do_not_record = 1;	    return 0;	  }	hash += ((unsigned) REG << 7) + (unsigned) reg_qty[regno];	return hash;      }    case CONST_INT:      {	unsigned HOST_WIDE_INT tem = INTVAL (x);	hash += ((unsigned) CONST_INT << 7) + (unsigned) mode + tem;	return hash;      }    case CONST_DOUBLE:      /* This is like the general case, except that it only counts	 the integers representing the constant.  */      hash += (unsigned) code + (unsigned) GET_MODE (x);      if (GET_MODE (x) != VOIDmode)	for (i = 2; i < GET_RTX_LENGTH (CONST_DOUBLE); i++)	  {	    unsigned tem = XINT (x, i);	    hash += tem;	  }      else	hash += ((unsigned) CONST_DOUBLE_LOW (x)		 + (unsigned) CONST_DOUBLE_HIGH (x));      return hash;      /* Assume there is only one rtx object for any given label.  */    case LABEL_REF:      hash	+= ((unsigned) LABEL_REF << 7) + (unsigned HOST_WIDE_INT) XEXP (x, 0);      return hash;    case SYMBOL_REF:      hash	+= ((unsigned) SYMBOL_REF << 7) + (unsigned HOST_WIDE_INT) XSTR (x, 0);      return hash;    case MEM:      if (MEM_VOLATILE_P (x))	{	  do_not_record = 1;	  return 0;	}      if (! RTX_UNCHANGING_P (x))	{	  hash_arg_in_memory = 1;	  if (MEM_IN_STRUCT_P (x)) hash_arg_in_struct = 1;	}      /* Now that we have already found this special case,	 might as well speed it up as much as possible.  */      hash += (unsigned) MEM;      x = XEXP (x, 0);      goto repeat;    case PRE_DEC:    case PRE_INC:    case POST_DEC:    case POST_INC:    case PC:    case CC0:    case CALL:    case UNSPEC_VOLATILE:      do_not_record = 1;      return 0;    case ASM_OPERANDS:      if (MEM_VOLATILE_P (x))	{	  do_not_record = 1;	  return 0;	}    }  i = GET_RTX_LENGTH (code) - 1;  hash += (unsigned) code + (unsigned) GET_MODE (x);  fmt = GET_RTX_FORMAT (code);  for (; i >= 0; i--)    {      if (fmt[i] == 'e')	{	  rtx tem = XEXP (x, i);	  /* If we are about to do the last recursive call	     needed at this level, change it into iteration.	     This function  is called enough to be worth it.  */	  if (i == 0)	    {	      x = tem;	      goto repeat;	    }	  hash += canon_hash (tem, 0);	}      else if (fmt[i] == 'E')	for (j = 0; j < XVECLEN (x, i); j++)	  hash += canon_hash (XVECEXP (x, i, j), 0);      else if (fmt[i] == 's')	{	  register unsigned char *p = (unsigned char *) XSTR (x, i);	  if (p)	    while (*p)	      hash += *p++;	}      else if (fmt[i] == 'i')	{	  register unsigned tem = XINT (x, i);	  hash += tem;	}      else	abort ();    }  return hash;}/* Like canon_hash but with no side effects.  */static unsignedsafe_hash (x, mode)     rtx x;     enum machine_mode mode;{  int save_do_not_record = do_not_record;  int save_hash_arg_in_memory = hash_arg_in_memory;  int save_hash_arg_in_struct = hash_arg_in_struct;  unsigned hash = canon_hash (x, mode);  hash_arg_in_memory = save_hash_arg_in_memory;  hash_arg_in_struct = save_hash_arg_in_struct;  do_not_record = save_do_not_record;  return hash;}/* Return 1 iff X and Y would canonicalize into the same thing,   without actually constructing the canonicalization of either one.   If VALIDATE is nonzero,   we assume X is an expression being processed from the rtl   and Y was found in the hash table.  We check register refs   in Y for being marked as valid.   If EQUAL_VALUES is nonzero, we allow a register to match a constant value   that is known to be in the register.  Ordinarily, we don't allow them   to match, because letting them match would cause unpredictable results   in all the places that search a hash table chain for an equivalent   for a given value.  A possible equivalent that has different structure   has its hash code computed from different data.  Whether the hash code   is the same as that of the the given value is pure luck.  */static intexp_equiv_p (x, y, validate, equal_values)     rtx x, y;     int validate;     int equal_values;{  register int i, j;  register enum rtx_code code;  register char 

⌨️ 快捷键说明

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