From fdc86f975f675d897a1c6b0ff54ea9e875334bfb Mon Sep 17 00:00:00 2001 From: jakub Date: Mon, 21 Jun 2010 16:27:25 +0000 Subject: [PATCH] * 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: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161093 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 16 ++++ gcc/Makefile.in | 2 +- gcc/cfgexpand.c | 5 ++ gcc/genattr.c | 101 +++++++++++++++++++++++-- gcc/genattrtab.c | 219 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 319 insertions(+), 24 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aa4d2a877e4..a5534853863 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,21 @@ 2010-06-21 Jakub Jelinek + * 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. + * stmt.c (resolve_asm_operand_names): Fix handling of %%. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index b88c032a0cf..30ef1efb523 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -3193,7 +3193,7 @@ cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TREE_DUMP_H) $(EXCEPT_H) langhooks.h $(TREE_PASS_H) $(RTL_H) \ $(DIAGNOSTIC_H) $(TOPLEV_H) $(BASIC_BLOCK_H) $(FLAGS_H) debug.h $(PARAMS_H) \ value-prof.h $(TREE_INLINE_H) $(TARGET_H) $(SSAEXPAND_H) \ - tree-pretty-print.h gimple-pretty-print.h $(BITMAP_H) sbitmap.h + tree-pretty-print.h gimple-pretty-print.h $(BITMAP_H) sbitmap.h $(INSN_ATTR_H) cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \ output.h $(TOPLEV_H) $(FUNCTION_H) $(EXCEPT_H) $(TM_P_H) $(INSN_ATTR_H) \ diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index cc8ff336a42..f78badf3000 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see #include "ssaexpand.h" #include "bitmap.h" #include "sbitmap.h" +#include "insn-attr.h" /* For INSN_SCHEDULING. */ /* This variable holds information helping the rewriting of SSA trees into RTL. */ @@ -3761,6 +3762,10 @@ gimple_expand_cfg (void) set_curr_insn_block (DECL_INITIAL (current_function_decl)); prologue_locator = curr_insn_locator (); +#ifdef INSN_SCHEDULING + init_sched_attrs (); +#endif + /* Make sure first insn is a note even if we don't want linenums. This makes sure the first insn will never be deleted. Also, final expects a note to appear there. */ diff --git a/gcc/genattr.c b/gcc/genattr.c index e4609ca4174..4fd22e219e3 100644 --- a/gcc/genattr.c +++ b/gcc/genattr.c @@ -1,6 +1,6 @@ /* Generate attribute information (insn-attr.h) from machine description. - Copyright (C) 1991, 1994, 1996, 1998, 1999, 2000, 2003, 2004, 2007, 2008 - Free Software Foundation, Inc. + Copyright (C) 1991, 1994, 1996, 1998, 1999, 2000, 2003, 2004, 2007, 2008, + 2010 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) This file is part of GCC. @@ -40,12 +40,18 @@ write_upcase (const char *str) putchar (TOUPPER(*str)); } +static VEC (rtx, heap) *const_attrs, *reservations; + + static void gen_attr (rtx attr) { const char *p, *tag; int is_const = GET_CODE (XEXP (attr, 2)) == CONST; + if (is_const) + VEC_safe_push (rtx, heap, const_attrs, attr); + printf ("#define HAVE_ATTR_%s\n", XSTR (attr, 0)); /* If numeric attribute, don't need to write an enum. */ @@ -92,6 +98,68 @@ extern int insn_current_length (rtx);\n\n\ } } +/* 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 strcmp (XSTR (exp, 0), name) == 0; + + default: + return false; + } +} + +/* Try to find a const attribute (usually cpu or tune) that is used + in all define_insn_reservation conditions. */ +static bool +find_tune_attr (rtx exp) +{ + unsigned int i; + rtx attr; + + switch (GET_CODE (exp)) + { + case AND: + case IOR: + if (find_tune_attr (XEXP (exp, 0))) + return true; + return find_tune_attr (XEXP (exp, 1)); + + case EQ_ATTR: + if (strcmp (XSTR (exp, 0), "alternative") == 0) + return false; + + for (i = 0; VEC_iterate (rtx, const_attrs, i, attr); i++) + if (strcmp (XSTR (attr, 0), XSTR (exp, 0)) == 0) + { + unsigned int j; + rtx resv; + + for (j = 0; VEC_iterate (rtx, reservations, j, resv); j++) + if (! check_tune_attr (XSTR (attr, 0), XEXP (resv, 2))) + return false; + return true; + } + return false; + + default: + return false; + } +} + int main (int argc, char **argv) { @@ -162,11 +230,16 @@ main (int argc, char **argv) } else if (GET_CODE (desc) == DEFINE_INSN_RESERVATION) - num_insn_reservations++; + { + num_insn_reservations++; + VEC_safe_push (rtx, heap, reservations, desc); + } } if (num_insn_reservations > 0) { + bool has_tune_attr + = find_tune_attr (XEXP (VEC_index (rtx, reservations, 0), 2)); /* Output interface for pipeline hazards recognition based on DFA (deterministic finite state automata. */ printf ("\n#define INSN_SCHEDULING\n"); @@ -181,10 +254,24 @@ main (int argc, char **argv) printf ("#define CPU_UNITS_QUERY 0\n"); printf ("#endif\n\n"); /* Interface itself: */ - printf ("/* Internal insn code number used by automata. */\n"); - printf ("extern int internal_dfa_insn_code (rtx);\n\n"); - printf ("/* Insn latency time defined in define_insn_reservation. */\n"); - printf ("extern int insn_default_latency (rtx);\n\n"); + if (has_tune_attr) + { + printf ("/* Initialize fn pointers for internal_dfa_insn_code\n"); + printf (" and insn_default_latency. */\n"); + printf ("extern void init_sched_attrs (void);\n\n"); + printf ("/* Internal insn code number used by automata. */\n"); + printf ("extern int (*internal_dfa_insn_code) (rtx);\n\n"); + printf ("/* Insn latency time defined in define_insn_reservation. */\n"); + printf ("extern int (*insn_default_latency) (rtx);\n\n"); + } + else + { + printf ("#define init_sched_attrs() do { } while (0)\n\n"); + printf ("/* Internal insn code number used by automata. */\n"); + printf ("extern int internal_dfa_insn_code (rtx);\n\n"); + printf ("/* Insn latency time defined in define_insn_reservation. */\n"); + printf ("extern int insn_default_latency (rtx);\n\n"); + } printf ("/* Return nonzero if there is a bypass for given insn\n"); printf (" which is a data producer. */\n"); printf ("extern int bypass_p (rtx);\n\n"); 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); } -- 2.11.0