aboutsummaryrefslogtreecommitdiff
path: root/gcc/genattrtab.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2010-06-21 16:27:25 +0000
committerJakub Jelinek <jakub@redhat.com>2010-06-21 16:27:25 +0000
commitd45bda462e234f9791f7468dbe4fcc2b8021cf9e (patch)
treed02a0fa1435d00b56e4bf4f124a0e6956229dce6 /gcc/genattrtab.c
parent0b2a756f347b20345a1b757bcc75a3850ece6fa7 (diff)
* Makefile.in (cfgexpand.o): Depend on $(INSN_ATTR_H).
* genattrtab.c (check_tune_attr, find_tune_attr): New functions. (make_automaton_attrs): If find_tune_attr returns non-NULL, write separate internal_dfa_insn_code_* and insn_default_latency_* functions for each attribute's value and emit init_sched_attrs function and function pointers. * genattr.c (const_attrs, reservations): New variables. (gen_attr): Add const attributes to const_attrs vector. (check_tune_attr, find_tune_attr): New functions. (main): Add reservations to reservations vector. If find_tune_attr returns true, add prototype for init_sched_attrs and make internal_dfa_insn_code and insn_default_latency function pointers, otherwise define init_sched_attrs as dummy macro. * cfgexpand.c: Include insn-attr.h. (gimple_expand_cfg): Call init_sched_attrs. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@161093 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/genattrtab.c')
-rw-r--r--gcc/genattrtab.c219
1 files changed, 203 insertions, 16 deletions
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index 9fe1c5caa7c..33b66f34009 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -1,6 +1,6 @@
/* Generate code from machine description to compute values of attributes.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
@@ -4372,6 +4372,69 @@ process_bypasses (void)
r->bypassed = true;
}
+/* Check that attribute NAME is used in define_insn_reservation condition
+ EXP. Return true if it is. */
+static bool
+check_tune_attr (const char *name, rtx exp)
+{
+ switch (GET_CODE (exp))
+ {
+ case AND:
+ if (check_tune_attr (name, XEXP (exp, 0)))
+ return true;
+ return check_tune_attr (name, XEXP (exp, 1));
+
+ case IOR:
+ return (check_tune_attr (name, XEXP (exp, 0))
+ && check_tune_attr (name, XEXP (exp, 1)));
+
+ case EQ_ATTR:
+ return XSTR (exp, 0) == name;
+
+ default:
+ return false;
+ }
+}
+
+/* Try to find a const attribute (usually cpu or tune) that is used
+ in all define_insn_reservation conditions. */
+static struct attr_desc *
+find_tune_attr (rtx exp)
+{
+ struct attr_desc *attr;
+
+ switch (GET_CODE (exp))
+ {
+ case AND:
+ case IOR:
+ attr = find_tune_attr (XEXP (exp, 0));
+ if (attr)
+ return attr;
+ return find_tune_attr (XEXP (exp, 1));
+
+ case EQ_ATTR:
+ if (XSTR (exp, 0) == alternative_name)
+ return NULL;
+
+ attr = find_attr (&XSTR (exp, 0), 0);
+ gcc_assert (attr);
+
+ if (attr->is_const && !attr->is_special)
+ {
+ struct insn_reserv *decl;
+
+ for (decl = all_insn_reservs; decl; decl = decl->next)
+ if (! check_tune_attr (attr->name, decl->condexp))
+ return NULL;
+ return attr;
+ }
+ return NULL;
+
+ default:
+ return NULL;
+ }
+}
+
/* Create all of the attributes that describe automaton properties. */
static void
make_automaton_attrs (void)
@@ -4379,28 +4442,154 @@ make_automaton_attrs (void)
int i;
struct insn_reserv *decl;
rtx code_exp, lats_exp, byps_exp;
+ struct attr_desc *tune_attr;
if (n_insn_reservs == 0)
return;
- code_exp = rtx_alloc (COND);
- lats_exp = rtx_alloc (COND);
+ tune_attr = find_tune_attr (all_insn_reservs->condexp);
+ if (tune_attr != NULL)
+ {
+ rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3);
+ struct attr_value *val;
+ bool first = true;
+
+ gcc_assert (tune_attr->is_const
+ && !tune_attr->is_special
+ && !tune_attr->is_numeric);
+ for (val = tune_attr->first_value; val; val = val->next)
+ {
+ if (val == tune_attr->default_val)
+ continue;
+ gcc_assert (GET_CODE (val->value) == CONST_STRING);
+ printf ("static int internal_dfa_insn_code_%s (rtx);\n"
+ "static int insn_default_latency_%s (rtx);\n",
+ XSTR (val->value, 0), XSTR (val->value, 0));
+ }
+
+ printf ("\n");
+ printf ("int (*internal_dfa_insn_code) (rtx);\n");
+ printf ("int (*insn_default_latency) (rtx);\n");
+ printf ("\n");
+ printf ("void\n");
+ printf ("init_sched_attrs (void)\n");
+ printf ("{\n");
+
+ for (val = tune_attr->first_value; val; val = val->next)
+ {
+ int j;
+ char *name;
+ rtx test = attr_rtx (EQ_ATTR, tune_attr->name, XSTR (val->value, 0));
+
+ if (val == tune_attr->default_val)
+ continue;
+ for (decl = all_insn_reservs, i = 0;
+ decl;
+ decl = decl->next)
+ {
+ rtx ctest = test;
+ rtx condexp
+ = simplify_and_tree (decl->condexp, &ctest, -2, 0);
+ if (condexp == false_rtx)
+ continue;
+ if (condexp == true_rtx)
+ break;
+ condexps[i] = condexp;
+ condexps[i + 1] = make_numeric_value (decl->insn_num);
+ condexps[i + 2] = make_numeric_value (decl->default_latency);
+ i += 3;
+ }
+
+ code_exp = rtx_alloc (COND);
+ lats_exp = rtx_alloc (COND);
+
+ j = i / 3 * 2;
+ XVEC (code_exp, 0) = rtvec_alloc (j);
+ XVEC (lats_exp, 0) = rtvec_alloc (j);
+
+ if (decl)
+ {
+ XEXP (code_exp, 1) = make_numeric_value (decl->insn_num);
+ XEXP (lats_exp, 1) = make_numeric_value (decl->default_latency);
+ }
+ else
+ {
+ XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
+ XEXP (lats_exp, 1) = make_numeric_value (0);
+ }
+
+ while (i > 0)
+ {
+ i -= 3;
+ j -= 2;
+ XVECEXP (code_exp, 0, j) = condexps[i];
+ XVECEXP (lats_exp, 0, j) = condexps[i];
+
+ XVECEXP (code_exp, 0, j + 1) = condexps[i + 1];
+ XVECEXP (lats_exp, 0, j + 1) = condexps[i + 2];
+ }
- XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
- XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
+ name = XNEWVEC (char,
+ sizeof ("*internal_dfa_insn_code_")
+ + strlen (XSTR (val->value, 0)));
+ strcpy (name, "*internal_dfa_insn_code_");
+ strcat (name, XSTR (val->value, 0));
+ make_internal_attr (name, code_exp, ATTR_NONE);
+ strcpy (name, "*insn_default_latency_");
+ strcat (name, XSTR (val->value, 0));
+ make_internal_attr (name, lats_exp, ATTR_NONE);
+ XDELETEVEC (name);
+
+ if (first)
+ {
+ printf (" if (");
+ first = false;
+ }
+ else
+ printf (" else if (");
+ write_test_expr (test, 0);
+ printf (")\n");
+ printf (" {\n");
+ printf (" internal_dfa_insn_code\n");
+ printf (" = internal_dfa_insn_code_%s;\n",
+ XSTR (val->value, 0));
+ printf (" insn_default_latency\n");
+ printf (" = insn_default_latency_%s;\n",
+ XSTR (val->value, 0));
+ printf (" }\n");
+ }
- XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
- XEXP (lats_exp, 1) = make_numeric_value (0);
+ printf (" else\n");
+ printf (" gcc_unreachable ();\n");
+ printf ("}\n");
+ printf ("\n");
- for (decl = all_insn_reservs, i = 0;
- decl;
- decl = decl->next, i += 2)
+ XDELETEVEC (condexps);
+ }
+ else
{
- XVECEXP (code_exp, 0, i) = decl->condexp;
- XVECEXP (lats_exp, 0, i) = decl->condexp;
+ code_exp = rtx_alloc (COND);
+ lats_exp = rtx_alloc (COND);
+
+ XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
+ XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
- XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
- XVECEXP (lats_exp, 0, i+1) = make_numeric_value (decl->default_latency);
+ XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
+ XEXP (lats_exp, 1) = make_numeric_value (0);
+
+ for (decl = all_insn_reservs, i = 0;
+ decl;
+ decl = decl->next, i += 2)
+ {
+ XVECEXP (code_exp, 0, i) = decl->condexp;
+ XVECEXP (lats_exp, 0, i) = decl->condexp;
+
+ XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
+ XVECEXP (lats_exp, 0, i+1)
+ = make_numeric_value (decl->default_latency);
+ }
+ make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
+ make_internal_attr ("*insn_default_latency", lats_exp, ATTR_NONE);
}
if (n_bypasses == 0)
@@ -4423,8 +4612,6 @@ make_automaton_attrs (void)
}
}
- make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
- make_internal_attr ("*insn_default_latency", lats_exp, ATTR_NONE);
make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE);
}