diff options
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/ChangeLog | 16 | ||||
| -rw-r--r-- | gcc/cse.c | 91 | ||||
| -rw-r--r-- | gcc/emit-rtl.c | 8 | ||||
| -rw-r--r-- | gcc/gcse.c | 77 | ||||
| -rw-r--r-- | gcc/integrate.c | 32 | ||||
| -rw-r--r-- | gcc/rtl.h | 2 | ||||
| -rw-r--r-- | gcc/stmt.c | 20 | 
7 files changed, 195 insertions, 51 deletions
| diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b7b5afc..16fce73 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2000-09-01  Alexandre Oliva  <aoliva@redhat.com> + +	* rtl.h (ASM_OPERANDS_INPUT_CONSTRAINT_EXP): New macro. +	* gcse.c (hash_string_1): New function. +	(hash_expr_1) <ASM_OPERANDS>: Disregard filename and line number. +	(expr_equiv_p) <ASM_OPERANDS>: Likewise. +	* cse.c (rtx_cost): Don't increase the cost of ASM_OPERANDS. +	(canon_hash_string): New function. +	(canon_hash) <ASM_OPERANDS>: Disregard filename and line number. +	(exp_equiv_p) <ASM_OPERANDS>: Likewise. +	(fold_rtx): Use ASM_OPERANDS accessor macros. +	* emit-rtl.c (copy_insn_1): Likewise. +	* integrate.c (copy_rtx_and_substitute): Likewise. +	* stmt.c (expand_asm_operands): Likewise.  Give an +	ASM_OPERANDS rtx the mode of the output reg being set from it. +  2000-09-01  Fred Fish  <fnf@be.com>  	* fix-header.c (write_rbrac): Add putc and getc to list of @@ -787,12 +787,6 @@ rtx_cost (x, outer_code)        /* Used in loop.c and combine.c as a marker.  */        total = 0;        break; -    case ASM_OPERANDS: -      /* We don't want these to be used in substitutions because -	 we have no way of validating the resulting insn.  So assign -	 anything containing an ASM_OPERANDS a very high cost.  */ -      total = 1000; -      break;      default:        total = 2;      } @@ -2141,6 +2135,21 @@ use_related_value (x, elt)    return plus_constant (q->exp, offset);  } +/* Hash a string.  Just add its bytes up.  */ +static inline unsigned +canon_hash_string (ps) +     const char *ps; +{ +  unsigned hash = 0; +  const unsigned char *p = (const unsigned char *)ps; +   +  if (p) +    while (*p) +      hash += *p++; + +  return hash; +} +  /* 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; @@ -2286,6 +2295,32 @@ canon_hash (x, mode)  	  do_not_record = 1;  	  return 0;  	} +      else +	{ +	  /* We don't want to take the filename and line into account.  */ +	  hash += (unsigned) code + (unsigned) GET_MODE (x) +	    + canon_hash_string (ASM_OPERANDS_TEMPLATE (x)) +	    + canon_hash_string (ASM_OPERANDS_OUTPUT_CONSTRAINT (x)) +	    + (unsigned) ASM_OPERANDS_OUTPUT_IDX (x); + +	  if (ASM_OPERANDS_INPUT_LENGTH (x)) +	    { +	      for (i = 1; i < ASM_OPERANDS_INPUT_LENGTH (x); i++) +		{ +		  hash += (canon_hash (ASM_OPERANDS_INPUT (x, i), +				       GET_MODE (ASM_OPERANDS_INPUT (x, i))) +			   + canon_hash_string (ASM_OPERANDS_INPUT_CONSTRAINT +						(x, i))); +		} + +	      hash += canon_hash_string (ASM_OPERANDS_INPUT_CONSTRAINT (x, 0)); +	      x = ASM_OPERANDS_INPUT (x, 0); +	      mode = GET_MODE (x); +	      goto repeat; +	    } + +	  return hash; +	}        break;      default: @@ -2315,14 +2350,7 @@ canon_hash (x, mode)  	for (j = 0; j < XVECLEN (x, i); j++)  	  hash += canon_hash (XVECEXP (x, i, j), 0);        else if (fmt[i] == 's') -	{ -	  register const unsigned char *p = -	    (const unsigned char *) XSTR (x, i); - -	  if (p) -	    while (*p) -	      hash += *p++; -	} +	hash += canon_hash_string (XSTR (x, i));        else if (fmt[i] == 'i')  	{  	  register unsigned tem = XINT (x, i); @@ -2476,6 +2504,35 @@ exp_equiv_p (x, y, validate, equal_values)  		  && exp_equiv_p (XEXP (x, 1), XEXP (y, 0),  				  validate, equal_values))); +    case ASM_OPERANDS: +      /* We don't use the generic code below because we want to +	 disregard filename and line numbers.  */ + +      /* A volatile asm isn't equivalent to any other.  */ +      if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y)) +	return 0; + +      if (GET_MODE (x) != GET_MODE (y) +	  || strcmp (ASM_OPERANDS_TEMPLATE (x), ASM_OPERANDS_TEMPLATE (y)) +	  || strcmp (ASM_OPERANDS_OUTPUT_CONSTRAINT (x), +		     ASM_OPERANDS_OUTPUT_CONSTRAINT (y)) +	  || ASM_OPERANDS_OUTPUT_IDX (x) != ASM_OPERANDS_OUTPUT_IDX (y) +	  || ASM_OPERANDS_INPUT_LENGTH (x) != ASM_OPERANDS_INPUT_LENGTH (y)) +	return 0; + +      if (ASM_OPERANDS_INPUT_LENGTH (x)) +	{ +	  for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--) +	    if (! exp_equiv_p (ASM_OPERANDS_INPUT (x, i), +			       ASM_OPERANDS_INPUT (y, i), +			       validate, equal_values) +		|| strcmp (ASM_OPERANDS_INPUT_CONSTRAINT (x, i), +			   ASM_OPERANDS_INPUT_CONSTRAINT (y, i))) +	      return 0; +	} + +      return 1; +      default:        break;      } @@ -3500,9 +3557,9 @@ fold_rtx (x, insn)        }      case ASM_OPERANDS: -      for (i = XVECLEN (x, 3) - 1; i >= 0; i--) -	validate_change (insn, &XVECEXP (x, 3, i), -			 fold_rtx (XVECEXP (x, 3, i), insn), 0); +      for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--) +	validate_change (insn, &ASM_OPERANDS_INPUT (x, i), +			 fold_rtx (ASM_OPERANDS_INPUT (x, i), insn), 0);        break;      default: diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 9a32582..9eb9639 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -3913,10 +3913,10 @@ copy_insn_1 (orig)      }    else if (code == ASM_OPERANDS)      { -      orig_asm_operands_vector = XVEC (orig, 3); -      copy_asm_operands_vector = XVEC (copy, 3); -      orig_asm_constraints_vector = XVEC (orig, 4); -      copy_asm_constraints_vector = XVEC (copy, 4); +      orig_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (orig); +      copy_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (copy); +      orig_asm_constraints_vector = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (orig); +      copy_asm_constraints_vector = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy);      }    return copy; @@ -1333,6 +1333,20 @@ hash_expr (x, mode, do_not_record_p, hash_table_size)    hash = hash_expr_1 (x, mode, do_not_record_p);    return hash % hash_table_size;  } +/* Hash a string.  Just add its bytes up.  */ +static inline unsigned +hash_string_1 (ps) +     const char *ps; +{ +  unsigned hash = 0; +  const unsigned char *p = (const unsigned char *)ps; +   +  if (p) +    while (*p) +      hash += *p++; + +  return hash; +}  /* Subroutine of hash_expr to do the actual work.  */ @@ -1433,6 +1447,32 @@ hash_expr_1 (x, mode, do_not_record_p)  	  *do_not_record_p = 1;  	  return 0;  	} +      else +	{ +	  /* We don't want to take the filename and line into account.  */ +	  hash += (unsigned) code + (unsigned) GET_MODE (x) +	    + hash_string_1 (ASM_OPERANDS_TEMPLATE (x)) +	    + hash_string_1 (ASM_OPERANDS_OUTPUT_CONSTRAINT (x)) +	    + (unsigned) ASM_OPERANDS_OUTPUT_IDX (x); + +	  if (ASM_OPERANDS_INPUT_LENGTH (x)) +	    { +	      for (i = 1; i < ASM_OPERANDS_INPUT_LENGTH (x); i++) +		{ +		  hash += (hash_expr_1 (ASM_OPERANDS_INPUT (x, i), +					GET_MODE (ASM_OPERANDS_INPUT (x, i)), +					do_not_record_p) +			   + hash_string_1 (ASM_OPERANDS_INPUT_CONSTRAINT +					    (x, i))); +		} + +	      hash += hash_string_1 (ASM_OPERANDS_INPUT_CONSTRAINT (x, 0)); +	      x = ASM_OPERANDS_INPUT (x, 0); +	      mode = GET_MODE (x); +	      goto repeat; +	    } +	  return hash; +	}      default:        break; @@ -1466,14 +1506,7 @@ hash_expr_1 (x, mode, do_not_record_p)  	  }        else if (fmt[i] == 's') -	{ -	  register const unsigned char *p = -	    (const unsigned char *) XSTR (x, i); - -	  if (p) -	    while (*p) -	      hash += *p++; -	} +	hash += hash_string_1 (XSTR (x, i));        else if (fmt[i] == 'i')  	hash += (unsigned int) XINT (x, i);        else @@ -1565,6 +1598,34 @@ expr_equiv_p (x, y)  	      || (expr_equiv_p (XEXP (x, 0), XEXP (y, 1))  		  && expr_equiv_p (XEXP (x, 1), XEXP (y, 0)))); +    case ASM_OPERANDS: +      /* We don't use the generic code below because we want to +	 disregard filename and line numbers.  */ + +      /* A volatile asm isn't equivalent to any other.  */ +      if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y)) +	return 0; + +      if (GET_MODE (x) != GET_MODE (y) +	  || strcmp (ASM_OPERANDS_TEMPLATE (x), ASM_OPERANDS_TEMPLATE (y)) +	  || strcmp (ASM_OPERANDS_OUTPUT_CONSTRAINT (x), +		     ASM_OPERANDS_OUTPUT_CONSTRAINT (y)) +	  || ASM_OPERANDS_OUTPUT_IDX (x) != ASM_OPERANDS_OUTPUT_IDX (y) +	  || ASM_OPERANDS_INPUT_LENGTH (x) != ASM_OPERANDS_INPUT_LENGTH (y)) +	return 0; + +      if (ASM_OPERANDS_INPUT_LENGTH (x)) +	{ +	  for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--) +	    if (! expr_equiv_p (ASM_OPERANDS_INPUT (x, i), +				ASM_OPERANDS_INPUT (y, i)) +		|| strcmp (ASM_OPERANDS_INPUT_CONSTRAINT (x, i), +			   ASM_OPERANDS_INPUT_CONSTRAINT (y, i))) +	      return 0; +	} + +      return 1; +      default:        break;      } diff --git a/gcc/integrate.c b/gcc/integrate.c index ca5483a..e267f5e 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -2040,20 +2040,23 @@ copy_rtx_and_substitute (orig, map, for_lhs)        break;      case ASM_OPERANDS: -      /* If a single asm insn contains multiple output operands -	 then it contains multiple ASM_OPERANDS rtx's that share operand 3. -	 We must make sure that the copied insn continues to share it.  */ -      if (map->orig_asm_operands_vector == XVEC (orig, 3)) +      /* If a single asm insn contains multiple output operands then +	 it contains multiple ASM_OPERANDS rtx's that share the input +	 and constraint vecs.  We must make sure that the copied insn +	 continues to share it.  */ +      if (map->orig_asm_operands_vector == ASM_OPERANDS_INPUT_VEC (orig))  	{  	  copy = rtx_alloc (ASM_OPERANDS);  	  copy->volatil = orig->volatil; -	  XSTR (copy, 0) = XSTR (orig, 0); -	  XSTR (copy, 1) = XSTR (orig, 1); -	  XINT (copy, 2) = XINT (orig, 2); -	  XVEC (copy, 3) = map->copy_asm_operands_vector; -	  XVEC (copy, 4) = map->copy_asm_constraints_vector; -	  XSTR (copy, 5) = XSTR (orig, 5); -	  XINT (copy, 6) = XINT (orig, 6); +	  ASM_OPERANDS_TEMPLATE (copy) = ASM_OPERANDS_TEMPLATE (orig); +	  ASM_OPERANDS_OUTPUT_CONSTRAINT (copy) +	    = ASM_OPERANDS_OUTPUT_CONSTRAINT (orig); +	  ASM_OPERANDS_OUTPUT_IDX (copy) = ASM_OPERANDS_OUTPUT_IDX (orig); +	  ASM_OPERANDS_INPUT_VEC (copy) = map->copy_asm_operands_vector; +	  ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy) +	    = map->copy_asm_constraints_vector; +	  ASM_OPERANDS_SOURCE_FILE (copy) = ASM_OPERANDS_SOURCE_FILE (orig); +	  ASM_OPERANDS_SOURCE_LINE (copy) = ASM_OPERANDS_SOURCE_LINE (orig);  	  return copy;  	}        break; @@ -2212,9 +2215,10 @@ copy_rtx_and_substitute (orig, map, for_lhs)    if (code == ASM_OPERANDS && map->orig_asm_operands_vector == 0)      { -      map->orig_asm_operands_vector = XVEC (orig, 3); -      map->copy_asm_operands_vector = XVEC (copy, 3); -      map->copy_asm_constraints_vector = XVEC (copy, 4); +      map->orig_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (orig); +      map->copy_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (copy); +      map->copy_asm_constraints_vector +	= ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy);      }    return copy; @@ -800,6 +800,8 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];  #define ASM_OPERANDS_INPUT_CONSTRAINT_VEC(RTX) XCVEC ((RTX), 4, ASM_OPERANDS)  #define ASM_OPERANDS_INPUT(RTX, N) XCVECEXP ((RTX), 3, (N), ASM_OPERANDS)  #define ASM_OPERANDS_INPUT_LENGTH(RTX) XCVECLEN ((RTX), 3, ASM_OPERANDS) +#define ASM_OPERANDS_INPUT_CONSTRAINT_EXP(RTX, N) \ +			XCVECEXP ((RTX), 4, (N), ASM_OPERANDS)  #define ASM_OPERANDS_INPUT_CONSTRAINT(RTX, N) \  			XSTR (XCVECEXP ((RTX), 4, (N), ASM_OPERANDS), 0)  #define ASM_OPERANDS_INPUT_MODE(RTX, N)  \ @@ -1595,7 +1595,9 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)    argvec = rtvec_alloc (ninputs);    constraints = rtvec_alloc (ninputs); -  body = gen_rtx_ASM_OPERANDS (VOIDmode, TREE_STRING_POINTER (string), +  body = gen_rtx_ASM_OPERANDS ((noutputs == 0 ? VOIDmode +				: GET_MODE (output_rtx[0])), +			       TREE_STRING_POINTER (string),   			       empty_string, 0, argvec, constraints,  			       filename, line); @@ -1771,9 +1773,9 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)  	    warning ("asm operand %d probably doesn't match constraints", i);  	}        generating_concat_p = old_generating_concat_p; -      XVECEXP (body, 3, i) = op; +      ASM_OPERANDS_INPUT (body, i) = op; -      XVECEXP (body, 4, i)      /* constraints */ +      ASM_OPERANDS_INPUT_CONSTRAINT_EXP (body, i)  	= gen_rtx_ASM_INPUT (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),  			     orig_constraint);        i++; @@ -1785,7 +1787,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)    generating_concat_p = 0;    for (i = 0; i < ninputs - ninout; i++) -    XVECEXP (body, 3, i) = protect_from_queue (XVECEXP (body, 3, i), 0); +    ASM_OPERANDS_INPUT (body, i) +      = protect_from_queue (ASM_OPERANDS_INPUT (body, i), 0);    for (i = 0; i < noutputs; i++)      output_rtx[i] = protect_from_queue (output_rtx[i], 1); @@ -1795,9 +1798,9 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)      {        int j = inout_opnum[i]; -      XVECEXP (body, 3, ninputs - ninout + i)      /* argvec */ +      ASM_OPERANDS_INPUT (body, ninputs - ninout + i)  	= output_rtx[j]; -      XVECEXP (body, 4, ninputs - ninout + i)      /* constraints */ +      ASM_OPERANDS_INPUT_CONSTRAINT_EXP (body, ninputs - ninout + i)  	= gen_rtx_ASM_INPUT (inout_mode[i], digit_strings[j]);      } @@ -1810,7 +1813,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)    if (noutputs == 1 && nclobbers == 0)      { -      XSTR (body, 1) = TREE_STRING_POINTER (TREE_PURPOSE (outputs)); +      ASM_OPERANDS_OUTPUT_CONSTRAINT (body) +	= TREE_STRING_POINTER (TREE_PURPOSE (outputs));        insn = emit_insn (gen_rtx_SET (VOIDmode, output_rtx[0], body));      } @@ -1837,7 +1841,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)  	    = gen_rtx_SET (VOIDmode,  			   output_rtx[i],  			   gen_rtx_ASM_OPERANDS -			   (VOIDmode, +			   (GET_MODE (output_rtx[i]),  			    TREE_STRING_POINTER (string),  			    TREE_STRING_POINTER (TREE_PURPOSE (tail)),  			    i, argvec, constraints, | 
