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:
Jakub Jelinek 2010-06-21 18:27:25 +02:00 committed by Jakub Jelinek
parent 6747788144
commit 2b21299c80
5 changed files with 322 additions and 27 deletions

View File

@ -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 %%.

View File

@ -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) \

View File

@ -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. */

View File

@ -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");

View File

@ -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);
}