static const char *attr_numeral PARAMS ((int));
static int attr_equal_p PARAMS ((rtx, rtx));
static rtx attr_copy_rtx PARAMS ((rtx));
+static int attr_rtx_cost PARAMS ((rtx));
#define oballoc(size) obstack_alloc (hash_obstack, size)
\f
/* Not found; create a permanent copy and add it to the hash table. */
new_str = (char *) obstack_alloc (hash_obstack, len + 1);
- bcopy (str, new_str, len);
+ memcpy (new_str, str, len);
new_str[len] = '\0';
attr_hash_add_string (hashcode, new_str);
/* This lets us free all storage allocated below, if appropriate. */
first_spacer = (char *) obstack_finish (rtl_obstack);
- bcopy ((char *) XVEC (exp, 0)->elem, (char *) tests, len * sizeof (rtx));
+ memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
/* See if default value needs simplification. */
if (GET_CODE (defval) == COND)
rtx newexp = rtx_alloc (COND);
XVEC (newexp, 0) = rtvec_alloc (len);
- bcopy ((char *) tests, (char *) XVEC (newexp, 0)->elem,
- len * sizeof (rtx));
+ memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
XEXP (newexp, 1) = new_defval;
return newexp;
}
return exp;
}
+/* Compute approximate cost of the expression. Used to decide whether
+ expression is cheap enought for inline. */
+static int
+attr_rtx_cost (x)
+ rtx x;
+{
+ int cost = 0;
+ enum rtx_code code;
+ if (!x)
+ return 0;
+ code = GET_CODE (x);
+ switch (code)
+ {
+ case MATCH_OPERAND:
+ if (XSTR (x, 1)[0])
+ return 10;
+ else
+ return 0;
+ case EQ_ATTR:
+ /* Alternatives don't result into function call. */
+ if (!strcmp (XSTR (x, 0), "alternative"))
+ return 0;
+ else
+ return 5;
+ default:
+ {
+ int i, j;
+ const char *fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ switch (fmt[i])
+ {
+ case 'V':
+ case 'E':
+ for (j = 0; j < XVECLEN (x, i); j++)
+ cost += attr_rtx_cost (XVECEXP (x, i, j));
+ break;
+ case 'e':
+ cost += attr_rtx_cost (XEXP (x, i));
+ break;
+ }
+ }
+ }
+ break;
+ }
+ return cost;
+}
\f
/* Given an expression, see if it can be simplified for a particular insn
code based on the values of other attributes being tested. This can
for (av = attr->first_value; av; av = av->next)
for (ie = av->first_insn; ie; ie = ie->next)
if (ie->insn_code == insn_code)
- return evaluate_eq_attr (exp, av->value, insn_code, insn_index);
+ {
+ rtx x;
+ struct obstack *old = rtl_obstack;
+ rtl_obstack = temp_obstack;
+ x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
+ x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
+ rtl_obstack = old;
+ if (attr_rtx_cost(x) < 20)
+ return attr_copy_rtx (x);
+ }
break;
default:
insn_code_values
= (struct attr_value_list **) alloca ((insn_code_number + 2)
* sizeof (struct attr_value_list *));
- bzero ((char *) insn_code_values,
+ memset ((char *) insn_code_values, 0,
(insn_code_number + 2) * sizeof (struct attr_value_list *));
/* Offset the table address so we can index by -2 or -1. */
PUT_MODE (copy, GET_MODE (orig));
RTX_UNCHANGING_P (copy) = 1;
- bcopy ((char *) &XEXP (orig, 0), (char *) &XEXP (copy, 0),
- GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
+ memcpy (&XEXP (copy, 0), &XEXP (orig, 0),
+ GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
return copy;
#endif
}