Makefile.in (cfgexpand.o): Depend on $(INSN_ATTR_H).
* 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. From-SVN: r161093
This commit is contained in:
parent
6747788144
commit
2b21299c80
5 changed files with 322 additions and 27 deletions
|
@ -1,5 +1,21 @@
|
|||
2010-06-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* 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 %%.
|
||||
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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. */
|
||||
|
|
101
gcc/genattr.c
101
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");
|
||||
|
|
225
gcc/genattrtab.c
225
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);
|
||||
|
||||
XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
|
||||
XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
|
||||
|
||||
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)
|
||||
tune_attr = find_tune_attr (all_insn_reservs->condexp);
|
||||
if (tune_attr != NULL)
|
||||
{
|
||||
XVECEXP (code_exp, 0, i) = decl->condexp;
|
||||
XVECEXP (lats_exp, 0, i) = decl->condexp;
|
||||
rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3);
|
||||
struct attr_value *val;
|
||||
bool first = true;
|
||||
|
||||
XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
|
||||
XVECEXP (lats_exp, 0, i+1) = make_numeric_value (decl->default_latency);
|
||||
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];
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
printf (" else\n");
|
||||
printf (" gcc_unreachable ();\n");
|
||||
printf ("}\n");
|
||||
printf ("\n");
|
||||
|
||||
XDELETEVEC (condexps);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue