summaryrefslogtreecommitdiff
path: root/gcc/genattrtab.c
diff options
context:
space:
mode:
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2006-01-23 15:15:52 +0000
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2006-01-23 15:15:52 +0000
commit0f7f3d52328105d181007dcc5ba527ebdde17366 (patch)
treee315ad25f6c7c0742772baee24304e78ebe61107 /gcc/genattrtab.c
parentc966a2e26443d130bc0826ff41bb220ed16526c6 (diff)
downloadgcc-0f7f3d52328105d181007dcc5ba527ebdde17366.tar.gz
r110127@banpei: zack | 2006-01-22 14:49:27 -0800
* genattrtab.c: Don't include genattrtab.h. Define ATTR_NONE and ATTR_SPECIAL (from genattrtab.h). Don't define num_dfa_decls nor any of the random handful of variables that used to be necessary when this program was linked with rtlanal.o. Prune set of forward function declarations. (struct attr_desc): Remove static_p field. (hash_obstack, temp_obstack, attr_hash_table, attr_printf) (check_attr_test, make_internal_attr, make_numeric_value): Make static. (attr_string): Do not read the character one past the length of the string. (write_attr_get, find_attr, make_internal_attr): Don't touch static_p. (struct insn_reserv, all_insn_reservs, last_insn_reserv_p) (n_insn_reservs, gen_insn_reserv, struct bypass_list, all_bypasses) (n_bypasses, gen_bypass_1, gen_bypass, process_bypasses) (make_automaton_attrs): New. (main): Do not call into genautomata. Call local gen_bypass and gen_insn_reserv as appropriate. Call make_automaton_attrs. Remove special case for insn_alts. * genautomata.c: Include gensupport.h; not genattrtab.h nor varray.h (leftover from previous change). Prune set of forward function declarations. Remove state_alts fields from all structures. Remove state_alts_table from struct automaton. Make everything except main static. Do not maintain num_dfa_decls. Do not maintain state_alts fields of various structures. (process_decls): Don't validate condexp for dm_insn_reserv decls. (add_arc): Remove state_alts argument. All callers updated. (output_reserved_units_table): Emit #ifdef here... (output_tables): ...not here. Don't generate state_alts tables. (expand_automata): Don't generate attributes. (write_automata): Don't generate state_alts functions. (main): New function. (it_is_empty_reserv_sets, output_state_alts_full_vect_name) (output_state_alts_comb_vect_name, output_state_alts_check_vect_name) (AUTOMATON_STATE_ALTS_MACRO_NAME, INTERNAL_STATE_ALTS_FUNC_NAME) (STATE_ALTS_FUNC_NAME, INSN_DEFAULT_LATENCY_FUNC_NAME) (BYPASS_P_FUNC_NAME, output_state_alts_table) (output_automata_list_state_alts_code, output_internal_state_alts_func) (output_state_alts_func, make_insn_alts_attr, make_bypass_attr) (make_internal_dfa_insn_code_attr, make_default_insn_latency_attr): Delete. * genattr.c: Declare internal_dfa_insn_code in insn-attr.h. * genattrtab.h: Delete file. * Makefile.in (OBJS-common): Add insn-automata.o. (insn-automata.o): New rule. (simple_generated_c): Add insn-automata.c. (build/genattrtab.o, build/genautomata.o): Update dependencies. (genprogmd): Add automata. (build/genattrtab): Needs no extra objects nor libraries. (build/genautomata): Needs build/vec.o and -lm. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@110123 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/genattrtab.c')
-rw-r--r--gcc/genattrtab.c394
1 files changed, 215 insertions, 179 deletions
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index 287c69b4631..755a9a41f02 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -109,23 +109,17 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
-#include "ggc.h"
#include "gensupport.h"
-
-#ifdef HAVE_SYS_RESOURCE_H
-# include <sys/resource.h>
-#endif
-
-/* We must include obstack.h after <sys/time.h>, to avoid lossage with
- /usr/include/sys/stdtypes.h on Sun OS 4.x. */
#include "obstack.h"
#include "errors.h"
-#include "genattrtab.h"
+/* Flags for make_internal_attr's `special' parameter. */
+#define ATTR_NONE 0
+#define ATTR_SPECIAL (1 << 0)
static struct obstack obstack1, obstack2;
-struct obstack *hash_obstack = &obstack1;
-struct obstack *temp_obstack = &obstack2;
+static struct obstack *hash_obstack = &obstack1;
+static struct obstack *temp_obstack = &obstack2;
/* enough space to reserve for printing out ints */
#define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
@@ -183,7 +177,6 @@ struct attr_desc
unsigned is_numeric : 1; /* Values of this attribute are numeric. */
unsigned is_const : 1; /* Attribute value constant for each run. */
unsigned is_special : 1; /* Don't call `write_attr_set'. */
- unsigned static_p : 1; /* Make the output function static. */
};
/* Structure for each DEFINE_DELAY. */
@@ -217,8 +210,6 @@ static int num_delays;
static int have_annul_true, have_annul_false;
static int num_insn_ents;
-int num_dfa_decls;
-
/* Stores, for each insn code, the number of constraint alternatives. */
static int *insn_n_alternatives;
@@ -240,16 +231,6 @@ static const char *delay_type_str;
static const char *delay_1_0_str;
static const char *num_delay_slots_str;
-/* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
- called. */
-
-int reload_completed = 0;
-
-/* Some machines test `optimize' in macros called from rtlanal.c, so we need
- to define it here. */
-
-int optimize = 0;
-
/* Simplify an expression. Only call the routine if there is something to
simplify. */
#define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
@@ -258,88 +239,44 @@ int optimize = 0;
#define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
-/* These are referenced by rtlanal.c and hence need to be defined somewhere.
- They won't actually be used. */
-
-rtx global_rtl[GR_MAX];
-rtx pic_offset_table_rtx;
-
-static void attr_hash_add_rtx (int, rtx);
-static void attr_hash_add_string (int, char *);
-static rtx attr_rtx (enum rtx_code, ...);
-static rtx attr_rtx_1 (enum rtx_code, va_list);
-static char *attr_string (const char *, int);
-static rtx check_attr_value (rtx, struct attr_desc *);
-static rtx convert_set_attr_alternative (rtx, struct insn_def *);
-static rtx convert_set_attr (rtx, struct insn_def *);
-static void check_defs (void);
-static rtx make_canonical (struct attr_desc *, rtx);
-static struct attr_value *get_attr_value (rtx, struct attr_desc *, int);
-static rtx copy_rtx_unchanging (rtx);
-static rtx copy_boolean (rtx);
-static void expand_delays (void);
-static void fill_attr (struct attr_desc *);
-static rtx substitute_address (rtx, rtx (*) (rtx), rtx (*) (rtx));
-static void make_length_attrs (void);
-static rtx identity_fn (rtx);
-static rtx zero_fn (rtx);
-static rtx one_fn (rtx);
-static rtx max_fn (rtx);
-static rtx min_fn (rtx);
-static void write_length_unit_log (void);
-static rtx simplify_cond (rtx, int, int);
-static void clear_struct_flag (rtx);
-static void remove_insn_ent (struct attr_value *, struct insn_ent *);
-static void insert_insn_ent (struct attr_value *, struct insn_ent *);
-static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int);
-static rtx make_alternative_compare (int);
-static int compute_alternative_mask (rtx, enum rtx_code);
-static rtx evaluate_eq_attr (rtx, rtx, int, int);
-static rtx simplify_and_tree (rtx, rtx *, int, int);
-static rtx simplify_or_tree (rtx, rtx *, int, int);
-static rtx simplify_test_exp (rtx, int, int);
-static rtx simplify_test_exp_in_temp (rtx, int, int);
-static void optimize_attrs (void);
-static void gen_attr (rtx, int);
-static int count_alternatives (rtx);
-static int compares_alternatives_p (rtx);
-static int contained_in_p (rtx, rtx);
-static void gen_insn (rtx, int);
-static void gen_delay (rtx, int);
-static void write_test_expr (rtx, int);
-static int max_attr_value (rtx, int*);
-static int min_attr_value (rtx, int*);
-static int or_attr_value (rtx, int*);
-static void walk_attr_value (rtx);
-static void write_attr_get (struct attr_desc *);
-static rtx eliminate_known_true (rtx, rtx, int, int);
-static void write_attr_set (struct attr_desc *, int, rtx,
- const char *, const char *, rtx,
- int, int);
-static void write_insn_cases (struct insn_ent *, int);
-static void write_attr_case (struct attr_desc *, struct attr_value *,
- int, const char *, const char *, int, rtx);
-static void write_attr_valueq (struct attr_desc *, const char *);
-static void write_attr_value (struct attr_desc *, rtx);
-static void write_upcase (const char *);
-static void write_indent (int);
-static void write_eligible_delay (const char *);
-static int write_expr_attr_cache (rtx, struct attr_desc *);
-static void write_const_num_delay_slots (void);
-static char *next_comma_elt (const char **);
+/* Forward declarations of functions used before their definitions, only. */
+static char *attr_string (const char *, int);
+static char *attr_printf (unsigned int, const char *, ...)
+ ATTRIBUTE_PRINTF_2;
+static rtx make_numeric_value (int);
static struct attr_desc *find_attr (const char **, int);
-static struct attr_value *find_most_used (struct attr_desc *);
-static rtx attr_eq (const char *, const char *);
-static const char *attr_numeral (int);
-static int attr_equal_p (rtx, rtx);
-static rtx attr_copy_rtx (rtx);
-static int attr_rtx_cost (rtx);
-static bool attr_alt_subset_p (rtx, rtx);
+static rtx mk_attr_alt (int);
+static char *next_comma_elt (const char **);
+static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int);
+static rtx copy_boolean (rtx);
+static int compares_alternatives_p (rtx);
+static void make_internal_attr (const char *, rtx, int);
+static void insert_insn_ent (struct attr_value *, struct insn_ent *);
+static void walk_attr_value (rtx);
+static int max_attr_value (rtx, int*);
+static int min_attr_value (rtx, int*);
+static int or_attr_value (rtx, int*);
+static rtx simplify_test_exp (rtx, int, int);
+static rtx simplify_test_exp_in_temp (rtx, int, int);
+static rtx copy_rtx_unchanging (rtx);
+static bool attr_alt_subset_p (rtx, rtx);
static bool attr_alt_subset_of_compl_p (rtx, rtx);
-static rtx attr_alt_intersection (rtx, rtx);
-static rtx attr_alt_union (rtx, rtx);
-static rtx attr_alt_complement (rtx);
-static rtx mk_attr_alt (int);
+static void clear_struct_flag (rtx);
+static void write_attr_valueq (struct attr_desc *, const char *);
+static struct attr_value *find_most_used (struct attr_desc *);
+static void write_attr_set (struct attr_desc *, int, rtx,
+ const char *, const char *, rtx,
+ int, int);
+static void write_attr_case (struct attr_desc *, struct attr_value *,
+ int, const char *, const char *, int, rtx);
+static void write_attr_value (struct attr_desc *, rtx);
+static void write_upcase (const char *);
+static void write_indent (int);
+static rtx identity_fn (rtx);
+static rtx zero_fn (rtx);
+static rtx one_fn (rtx);
+static rtx max_fn (rtx);
+static rtx min_fn (rtx);
#define oballoc(size) obstack_alloc (hash_obstack, size)
@@ -368,7 +305,7 @@ struct attr_hash
for each. */
#define RTL_HASH_SIZE 4093
-struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
+static struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
/* Here is how primitive or already-shared RTL's hash
codes are made. */
@@ -603,7 +540,7 @@ attr_rtx (enum rtx_code code, ...)
rtx attr_printf (len, format, [arg1, ..., argn]) */
-char *
+static char *
attr_printf (unsigned int len, const char *fmt, ...)
{
char str[256];
@@ -644,7 +581,7 @@ attr_string (const char *str, int len)
/* Compute the hash code. */
hashcode = (len + 1) * 613 + (unsigned) str[0];
- for (i = 1; i <= len; i += 2)
+ for (i = 1; i < len; i += 2)
hashcode = ((hashcode * 613) + (unsigned) str[i]);
if (hashcode < 0)
hashcode = -hashcode;
@@ -773,7 +710,7 @@ attr_copy_rtx (rtx orig)
Return the new expression, if any. */
-rtx
+static rtx
check_attr_test (rtx exp, int is_const, int lineno)
{
struct attr_desc *attr;
@@ -3711,8 +3648,6 @@ write_attr_get (struct attr_desc *attr)
/* Write out start of function, then all values with explicit `case' lines,
then a `default', then the value with the most uses. */
- if (attr->static_p)
- printf ("static ");
if (!attr->is_numeric)
printf ("enum attr_%s\n", attr->name);
else
@@ -4281,7 +4216,6 @@ find_attr (const char **name_p, int create)
attr->name = DEF_ATTR_STRING (name);
attr->first_value = attr->default_val = NULL;
attr->is_numeric = attr->is_const = attr->is_special = 0;
- attr->static_p = 0;
attr->next = attrs[index];
attrs[index] = attr;
@@ -4292,7 +4226,7 @@ find_attr (const char **name_p, int create)
/* Create internal attribute with the given default value. */
-void
+static void
make_internal_attr (const char *name, rtx value, int special)
{
struct attr_desc *attr;
@@ -4303,7 +4237,6 @@ make_internal_attr (const char *name, rtx value, int special)
attr->is_numeric = 1;
attr->is_const = 0;
attr->is_special = (special & ATTR_SPECIAL) != 0;
- attr->static_p = (special & ATTR_STATIC) != 0;
attr->default_val = get_attr_value (value, attr, -2);
}
@@ -4328,7 +4261,7 @@ find_most_used (struct attr_desc *attr)
/* Return (attr_value "n") */
-rtx
+static rtx
make_numeric_value (int n)
{
static rtx int_values[20];
@@ -4388,6 +4321,168 @@ write_const_num_delay_slots (void)
printf (" }\n}\n\n");
}
}
+
+/* Synthetic attributes used by insn-automata.c and the scheduler.
+ These are primarily concerned with (define_insn_reservation)
+ patterns. */
+
+struct insn_reserv
+{
+ struct insn_reserv *next;
+
+ const char *name;
+ int default_latency;
+ rtx condexp;
+
+ /* Sequence number of this insn. */
+ int insn_num;
+
+ /* Whether a (define_bypass) construct names this insn in its
+ output list. */
+ bool bypassed;
+};
+
+static struct insn_reserv *all_insn_reservs = 0;
+static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs;
+static size_t n_insn_reservs;
+
+/* Store information from a DEFINE_INSN_RESERVATION for future
+ attribute generation. */
+static void
+gen_insn_reserv (rtx def)
+{
+ struct insn_reserv *decl = oballoc (sizeof (struct insn_reserv));
+
+ decl->name = DEF_ATTR_STRING (XSTR (def, 0));
+ decl->default_latency = XINT (def, 1);
+ decl->condexp = check_attr_test (XEXP (def, 2), 0, 0);
+ decl->insn_num = n_insn_reservs;
+ decl->bypassed = false;
+ decl->next = 0;
+
+ *last_insn_reserv_p = decl;
+ last_insn_reserv_p = &decl->next;
+ n_insn_reservs++;
+}
+
+/* Store information from a DEFINE_BYPASS for future attribute
+ generation. The only thing we care about is the list of output
+ insns, which will later be used to tag reservation structures with
+ a 'bypassed' bit. */
+
+struct bypass_list
+{
+ struct bypass_list *next;
+ const char *insn;
+};
+
+static struct bypass_list *all_bypasses;
+static size_t n_bypasses;
+
+static void
+gen_bypass_1 (const char *s, size_t len)
+{
+ struct bypass_list *b;
+
+ if (len == 0)
+ return;
+
+ s = attr_string (s, len);
+ for (b = all_bypasses; b; b = b->next)
+ if (s == b->insn)
+ return; /* already got that one */
+
+ b = oballoc (sizeof (struct bypass_list));
+ b->insn = s;
+ b->next = all_bypasses;
+ all_bypasses = b;
+ n_bypasses++;
+}
+
+static void
+gen_bypass (rtx def)
+{
+ const char *p, *base;
+
+ for (p = base = XSTR (def, 1); *p; p++)
+ if (*p == ',')
+ {
+ gen_bypass_1 (base, p - base);
+ base = p + 1;
+ }
+ gen_bypass_1 (base, p - base);
+}
+
+/* Find and mark all of the bypassed insns. */
+static void
+process_bypasses (void)
+{
+ struct bypass_list *b;
+ struct insn_reserv *r;
+
+ /* The reservation list is likely to be much longer than the bypass
+ list. */
+ for (r = all_insn_reservs; r; r = r->next)
+ for (b = all_bypasses; b; b = b->next)
+ if (r->name == b->insn)
+ r->bypassed = true;
+}
+
+/* Create all of the attributes that describe automaton properties. */
+static void
+make_automaton_attrs (void)
+{
+ int i;
+ struct insn_reserv *decl;
+ rtx code_exp, lats_exp, byps_exp;
+
+ 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)
+ {
+ 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);
+ }
+
+ if (n_bypasses == 0)
+ byps_exp = make_numeric_value (0);
+ else
+ {
+ process_bypasses ();
+
+ byps_exp = rtx_alloc (COND);
+ XVEC (byps_exp, 0) = rtvec_alloc (n_bypasses * 2);
+ XEXP (byps_exp, 1) = make_numeric_value (0);
+ for (decl = all_insn_reservs, i = 0;
+ decl;
+ decl = decl->next)
+ if (decl->bypassed)
+ {
+ XVECEXP (byps_exp, 0, i) = decl->condexp;
+ XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1);
+ i += 2;
+ }
+ }
+
+ 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);
+}
int
main (int argc, char **argv)
@@ -4425,7 +4520,6 @@ from the machine description file `md'. */\n\n");
/* Read the machine description. */
- initiate_automaton_gen (argc, argv);
while (1)
{
int lineno;
@@ -4450,54 +4544,14 @@ from the machine description file `md'. */\n\n");
gen_delay (desc, lineno);
break;
- case DEFINE_CPU_UNIT:
- gen_cpu_unit (desc);
- break;
-
- case DEFINE_QUERY_CPU_UNIT:
- gen_query_cpu_unit (desc);
+ case DEFINE_INSN_RESERVATION:
+ gen_insn_reserv (desc);
break;
case DEFINE_BYPASS:
gen_bypass (desc);
break;
- case EXCLUSION_SET:
- gen_excl_set (desc);
- break;
-
- case PRESENCE_SET:
- gen_presence_set (desc);
- break;
-
- case FINAL_PRESENCE_SET:
- gen_final_presence_set (desc);
- break;
-
- case ABSENCE_SET:
- gen_absence_set (desc);
- break;
-
- case FINAL_ABSENCE_SET:
- gen_final_absence_set (desc);
- break;
-
- case DEFINE_AUTOMATON:
- gen_automaton (desc);
- break;
-
- case AUTOMATA_OPTION:
- gen_automata_option (desc);
- break;
-
- case DEFINE_RESERVATION:
- gen_reserv (desc);
- break;
-
- case DEFINE_INSN_RESERVATION:
- gen_insn_reserv (desc);
- break;
-
default:
break;
}
@@ -4522,11 +4576,6 @@ from the machine description file `md'. */\n\n");
if (num_delays)
expand_delays ();
- /* Build DFA, output some functions and expand DFA information
- to new attributes. */
- if (num_dfa_decls)
- expand_automata ();
-
printf ("#include \"config.h\"\n");
printf ("#include \"system.h\"\n");
printf ("#include \"coretypes.h\"\n");
@@ -4557,6 +4606,9 @@ from the machine description file `md'. */\n\n");
if (id->insn_code >= 0)
insn_n_alternatives[id->insn_code] = id->num_alternatives;
+ /* Construct extra attributes for automata. */
+ make_automaton_attrs ();
+
/* Prepare to write out attribute subroutines by checking everything stored
away and building the attribute cases. */
@@ -4587,18 +4639,7 @@ from the machine description file `md'. */\n\n");
for (attr = attrs[i]; attr; attr = attr->next)
{
if (! attr->is_special && ! attr->is_const)
- {
- int insn_alts_p;
-
- insn_alts_p
- = (attr->name [0] == '*'
- && strcmp (&attr->name[1], INSN_ALTS_FUNC_NAME) == 0);
- if (insn_alts_p)
- printf ("\n#if AUTOMATON_ALTS\n");
- write_attr_get (attr);
- if (insn_alts_p)
- printf ("#endif\n\n");
- }
+ write_attr_get (attr);
}
/* Write out delay eligibility information, if DEFINE_DELAY present.
@@ -4613,11 +4654,6 @@ from the machine description file `md'. */\n\n");
write_eligible_delay ("annul_false");
}
- /* Output code for pipeline hazards recognition based on DFA
- (deterministic finite-state automata). */
- if (num_dfa_decls)
- write_automata ();
-
/* Write out constant delay slot info. */
write_const_num_delay_slots ();