/* Pipeline hazard description translator.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Written by Vladimir Makarov <vmakarov@redhat.com>
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
+Free Software Foundation; either version 3, or (at your option) any
later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
/* References:
- 1. Detecting pipeline structural hazards quickly. T. Proebsting,
+ 1. The finite state automaton based pipeline hazard recognizer and
+ instruction scheduler in GCC. V. Makarov. Proceedings of GCC
+ summit, 2003.
+
+ 2. Detecting pipeline structural hazards quickly. T. Proebsting,
C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
Principles of Programming Languages, pages 280--286, 1994.
This article is a good start point to understand usage of finite
state automata for pipeline hazard recognizers. But I'd
- recommend the 2nd article for more deep understanding.
+ recommend the 1st and 3rd article for more deep understanding.
- 2. Efficient Instruction Scheduling Using Finite State Automata:
+ 3. Efficient Instruction Scheduling Using Finite State Automata:
V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best
article about usage of finite state automata for pipeline hazard
recognizers.
- The current implementation is different from the 2nd article in the
- following:
+ The current implementation is described in the 1st article and it
+ is different from the 3rd article in the following:
1. New operator `|' (alternative) is permitted in functional unit
reservation which can be treated deterministically and
/* Declare vector types for various data structures: */
DEF_VEC_P(alt_state_t);
-DEF_VEC_ALLOC_P(alt_state_t,heap);
+DEF_VEC_ALLOC_P(alt_state_t, heap);
DEF_VEC_P(ainsn_t);
-DEF_VEC_ALLOC_P(ainsn_t,heap);
+DEF_VEC_ALLOC_P(ainsn_t, heap);
DEF_VEC_P(state_t);
-DEF_VEC_ALLOC_P(state_t,heap);
+DEF_VEC_ALLOC_P(state_t, heap);
DEF_VEC_P(decl_t);
-DEF_VEC_ALLOC_P(decl_t,heap);
+DEF_VEC_ALLOC_P(decl_t, heap);
DEF_VEC_P(reserv_sets_t);
-DEF_VEC_ALLOC_P(reserv_sets_t,heap);
+DEF_VEC_ALLOC_P(reserv_sets_t, heap);
DEF_VEC_I(vect_el_t);
DEF_VEC_ALLOC_I(vect_el_t, heap);
-typedef VEC(vect_el_t,heap) *vla_hwint_t;
+typedef VEC(vect_el_t, heap) *vla_hwint_t;
\f
/* Forward declarations of functions used before their definitions, only. */
static regexp_t gen_regexp_sequence (const char *);
insn. */
int insn_num;
/* The following field value is list of bypasses in which given insn
- is output insn. */
+ is output insn. Bypasses with the same input insn stay one after
+ another in the list in the same order as their occurrences in the
+ description but the bypass without a guard stays always the last
+ in a row of bypasses with the same input insn. */
struct bypass_decl *bypass_list;
/* The following fields are defined by automaton generator. */
/* The following field is the insn regexp transformed that
the regexp has not optional regexp, repetition regexp, and an
reservation name (i.e. reservation identifiers are changed by the
- corresponding regexp) and all alternations are the topest level
+ corresponding regexp) and all alternations are the top level
of the regexp. The value can be NULL only if it is special
insn `cycle advancing'. */
regexp_t transformed_regexp;
#endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
+#define XCREATENODE(T) ((T *) create_node (sizeof (T)))
+#define XCREATENODEVEC(T, N) ((T *) create_node (sizeof (T) * (N)))
+#define XCREATENODEVAR(T, S) ((T *) create_node ((S)))
+
+#define XCOPYNODE(T, P) ((T *) copy_node ((P), sizeof (T)))
+#define XCOPYNODEVEC(T, P, N) ((T *) copy_node ((P), sizeof (T) * (N)))
+#define XCOPYNODEVAR(T, P, S) ((T *) copy_node ((P), (S)))
+
/* Create IR structure (node). */
static void *
create_node (size_t size)
/* Pointers to all declarations during IR generation are stored in the
following. */
-static VEC(decl_t,heap) *decls;
+static VEC(decl_t, heap) *decls;
/* Given a pointer to a (char *) and a separator, return an alloc'ed
string containing the next separated element, taking parentheses
fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
for (i = 0; i < vect_length; i++)
{
- decl = create_node (sizeof (struct decl));
+ decl = XCREATENODE (struct decl);
decl->mode = dm_unit;
decl->pos = 0;
DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
DECL_UNIT (decl)->query_p = 0;
DECL_UNIT (decl)->min_occ_cycle_num = -1;
DECL_UNIT (decl)->in_set_p = 0;
- VEC_safe_push (decl_t,heap, decls, decl);
+ VEC_safe_push (decl_t, heap, decls, decl);
}
}
fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
for (i = 0; i < vect_length; i++)
{
- decl = create_node (sizeof (struct decl));
+ decl = XCREATENODE (struct decl);
decl->mode = dm_unit;
decl->pos = 0;
DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
DECL_UNIT (decl)->query_p = 1;
- VEC_safe_push (decl_t,heap, decls, decl);
+ VEC_safe_push (decl_t, heap, decls, decl);
}
}
for (i = 0; i < out_length; i++)
for (j = 0; j < in_length; j++)
{
- decl = create_node (sizeof (struct decl));
+ decl = XCREATENODE (struct decl);
decl->mode = dm_bypass;
decl->pos = 0;
DECL_BYPASS (decl)->latency = XINT (def, 0);
DECL_BYPASS (decl)->out_insn_name = out_insns [i];
DECL_BYPASS (decl)->in_insn_name = in_insns [j];
DECL_BYPASS (decl)->bypass_guard_name = XSTR (def, 3);
- VEC_safe_push (decl_t,heap, decls, decl);
+ VEC_safe_push (decl_t, heap, decls, decl);
}
}
if (second_str_cpu_units == NULL)
fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
length += first_vect_length;
- decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
+ decl = XCREATENODEVAR (struct decl, sizeof (struct decl) + (length - 1) * sizeof (char *));
decl->mode = dm_excl;
decl->pos = 0;
DECL_EXCL (decl)->all_names_num = length;
else
DECL_EXCL (decl)->names [i]
= second_str_cpu_units [i - first_vect_length];
- VEC_safe_push (decl_t,heap, decls, decl);
+ VEC_safe_push (decl_t, heap, decls, decl);
}
/* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
: (final_p
? "invalid second string `%s' in final_absence_set"
: "invalid second string `%s' in absence_set")), XSTR (def, 1));
- str_patterns = obstack_alloc (&irp, patterns_length * sizeof (char **));
+ str_patterns = XOBNEWVEC (&irp, char **, patterns_length);
for (i = 0; i < patterns_length; i++)
{
str_patterns [i] = get_str_vect (str_pattern_lists [i],
&length, ' ', FALSE);
gcc_assert (str_patterns [i]);
}
- decl = create_node (sizeof (struct decl));
+ decl = XCREATENODE (struct decl);
decl->pos = 0;
if (presence_p)
{
DECL_ABSENCE (decl)->patterns_num = patterns_length;
DECL_ABSENCE (decl)->final_p = final_p;
}
- VEC_safe_push (decl_t,heap, decls, decl);
+ VEC_safe_push (decl_t, heap, decls, decl);
}
/* Process a PRESENCE_SET.
fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
for (i = 0; i < vect_length; i++)
{
- decl = create_node (sizeof (struct decl));
+ decl = XCREATENODE (struct decl);
decl->mode = dm_automaton;
decl->pos = 0;
DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
- VEC_safe_push (decl_t,heap, decls, decl);
+ VEC_safe_push (decl_t, heap, decls, decl);
}
}
len = strlen (str);
if (str [len - 1] != ')')
fatal ("garbage after ) in reservation `%s'", reserv_str);
- dstr = alloca (len - 1);
+ dstr = XALLOCAVAR (char, len - 1);
memcpy (dstr, str + 1, len - 2);
dstr [len-2] = '\0';
regexp = gen_regexp_sequence (dstr);
}
else if (strcmp (str, NOTHING_NAME) == 0)
{
- regexp = create_node (sizeof *regexp);
+ regexp = XCREATENODE (struct regexp);
regexp->mode = rm_nothing;
}
else
{
- regexp = create_node (sizeof *regexp);
+ regexp = XCREATENODE (struct regexp);
regexp->mode = rm_unit;
REGEXP_UNIT (regexp)->name = str;
}
regexp = gen_regexp_el (repeat_vect [0]);
for (i = 1; i < els_num; i++)
{
- repeat = create_node (sizeof (struct regexp));
+ repeat = XCREATENODE (struct regexp);
repeat->mode = rm_repeat;
REGEXP_REPEAT (repeat)->regexp = regexp;
REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]);
return regexp;
}
else
- return gen_regexp_el (str);
+ return gen_regexp_el (repeat_vect[0]);
}
/* Parse reservation STR which possibly contains separator '+'. */
fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
if (els_num > 1)
{
- allof = create_node (sizeof (struct regexp)
- + sizeof (regexp_t) * (els_num - 1));
+ allof = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+ + sizeof (regexp_t) * (els_num - 1));
allof->mode = rm_allof;
REGEXP_ALLOF (allof)->regexps_num = els_num;
for (i = 0; i < els_num; i++)
return allof;
}
else
- return gen_regexp_repeat (str);
+ return gen_regexp_repeat (allof_vect[0]);
}
/* Parse reservation STR which possibly contains separator '|'. */
fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
if (els_num > 1)
{
- oneof = create_node (sizeof (struct regexp)
- + sizeof (regexp_t) * (els_num - 1));
+ oneof = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+ + sizeof (regexp_t) * (els_num - 1));
oneof->mode = rm_oneof;
REGEXP_ONEOF (oneof)->regexps_num = els_num;
for (i = 0; i < els_num; i++)
return oneof;
}
else
- return gen_regexp_allof (str);
+ return gen_regexp_allof (oneof_vect[0]);
}
/* Parse reservation STR which possibly contains separator ','. */
sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
if (els_num > 1)
{
- sequence = create_node (sizeof (struct regexp)
- + sizeof (regexp_t) * (els_num - 1));
+ sequence = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+ + sizeof (regexp_t) * (els_num - 1));
sequence->mode = rm_sequence;
REGEXP_SEQUENCE (sequence)->regexps_num = els_num;
for (i = 0; i < els_num; i++)
return sequence;
}
else
- return gen_regexp_oneof (str);
+ return gen_regexp_oneof (sequence_vect[0]);
}
/* Parse construction reservation STR. */
gen_regexp (const char *str)
{
reserv_str = str;
- return gen_regexp_sequence (str);;
+ return gen_regexp_sequence (str);
}
/* Process a DEFINE_RESERVATION.
{
decl_t decl;
- decl = create_node (sizeof (struct decl));
+ decl = XCREATENODE (struct decl);
decl->mode = dm_reserv;
decl->pos = 0;
DECL_RESERV (decl)->name = check_name (XSTR (def, 0), decl->pos);
DECL_RESERV (decl)->regexp = gen_regexp (XSTR (def, 1));
- VEC_safe_push (decl_t,heap, decls, decl);
+ VEC_safe_push (decl_t, heap, decls, decl);
}
/* Process a DEFINE_INSN_RESERVATION.
{
decl_t decl;
- decl = create_node (sizeof (struct decl));
+ decl = XCREATENODE (struct decl);
decl->mode = dm_insn_reserv;
decl->pos = 0;
DECL_INSN_RESERV (decl)->name
DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3));
- VEC_safe_push (decl_t,heap, decls, decl);
+ VEC_safe_push (decl_t, heap, decls, decl);
}
\f
{
void **entry_ptr;
- entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1);
+ entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, INSERT);
if (*entry_ptr == NULL)
*entry_ptr = (void *) automaton_decl;
return (decl_t) *entry_ptr;
{
void **entry_ptr;
- entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1);
+ entry_ptr = htab_find_slot (insn_decl_table, insn_decl, INSERT);
if (*entry_ptr == NULL)
*entry_ptr = (void *) insn_decl;
return (decl_t) *entry_ptr;
{
void **entry_ptr;
- entry_ptr = htab_find_slot (decl_table, decl, 1);
+ entry_ptr = htab_find_slot (decl_table, decl, INSERT);
if (*entry_ptr == NULL)
*entry_ptr = (void *) decl;
return (decl_t) *entry_ptr;
error ("`%s' in exclusion is not unit", names [i]);
else
{
- new_el = create_node (sizeof (struct unit_set_el));
+ new_el = XCREATENODE (struct unit_set_el);
new_el->unit_decl = DECL_UNIT (decl_in_table);
new_el->next_unit_set_el = NULL;
if (last_el == NULL)
if (curr_el == NULL)
{
/* Element not found - insert. */
- copy = copy_node (src, sizeof (*src));
+ copy = XCOPYNODE (struct unit_set_el, src);
copy->next_unit_set_el = NULL;
if (prev_el == NULL)
dst->unit_decl->excl_list = copy;
: "`%s' in absence set is not unit")), names [i]);
else
{
- new_el = create_node (sizeof (struct unit_set_el));
+ new_el = XCREATENODE (struct unit_set_el);
new_el->unit_decl = DECL_UNIT (decl_in_table);
new_el->next_unit_set_el = NULL;
if (last_el == NULL)
{
for (j = 0; patterns [i] [j] != NULL; j++)
;
- new_el = create_node (sizeof (struct pattern_set_el)
- + sizeof (struct unit_decl *) * j);
+ new_el = XCREATENODEVAR (struct pattern_set_el,
+ sizeof (struct pattern_set_el)
+ + sizeof (struct unit_decl *) * j);
new_el->unit_decls
= (struct unit_decl **) ((char *) new_el
+ sizeof (struct pattern_set_el));
no_error_flag = 0;
}
else
- warning
- (0, "unit `%s' excludes and requires presence of `%s'",
+ warning ("unit `%s' excludes and requires presence of `%s'",
dst->unit_decl->name, unit->name);
}
}
{
if (!w_flag)
{
- error
- ("unit `%s' requires absence and presence of `%s'",
- dst->unit_decl->name, unit->name);
+ error ("unit `%s' requires absence and presence of `%s'",
+ dst->unit_decl->name, unit->name);
no_error_flag = 0;
}
else
- warning
- (0, "unit `%s' requires absence and presence of `%s'",
- dst->unit_decl->name, unit->name);
+ warning ("unit `%s' requires absence and presence of `%s'",
+ dst->unit_decl->name, unit->name);
}
if (no_error_flag)
{
prev_el != NULL && prev_el->next_pattern_set_el != NULL;
prev_el = prev_el->next_pattern_set_el)
;
- copy = copy_node (pat, sizeof (*pat));
+ copy = XCOPYNODE (struct pattern_set_el, pat);
copy->next_pattern_set_el = NULL;
if (prev_el == NULL)
{
}
-/* The function searches for bypass with given IN_INSN_RESERV in given
- BYPASS_LIST. */
-static struct bypass_decl *
-find_bypass (struct bypass_decl *bypass_list,
- struct insn_reserv_decl *in_insn_reserv)
+/* The function inserts BYPASS in the list of bypasses of the
+ corresponding output insn. The order of bypasses in the list is
+ decribed in a comment for member `bypass_list' (see above). If
+ there is already the same bypass in the list the function reports
+ this and does nothing. */
+static void
+insert_bypass (struct bypass_decl *bypass)
{
- struct bypass_decl *bypass;
+ struct bypass_decl *curr, *last;
+ struct insn_reserv_decl *out_insn_reserv = bypass->out_insn_reserv;
+ struct insn_reserv_decl *in_insn_reserv = bypass->in_insn_reserv;
- for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
- if (bypass->in_insn_reserv == in_insn_reserv)
- break;
- return bypass;
+ for (curr = out_insn_reserv->bypass_list, last = NULL;
+ curr != NULL;
+ last = curr, curr = curr->next)
+ if (curr->in_insn_reserv == in_insn_reserv)
+ {
+ if ((bypass->bypass_guard_name != NULL
+ && curr->bypass_guard_name != NULL
+ && ! strcmp (bypass->bypass_guard_name, curr->bypass_guard_name))
+ || bypass->bypass_guard_name == curr->bypass_guard_name)
+ {
+ if (bypass->bypass_guard_name == NULL)
+ {
+ if (!w_flag)
+ error ("the same bypass `%s - %s' is already defined",
+ bypass->out_insn_name, bypass->in_insn_name);
+ else
+ warning ("the same bypass `%s - %s' is already defined",
+ bypass->out_insn_name, bypass->in_insn_name);
+ }
+ else if (!w_flag)
+ error ("the same bypass `%s - %s' (guard %s) is already defined",
+ bypass->out_insn_name, bypass->in_insn_name,
+ bypass->bypass_guard_name);
+ else
+ warning
+ ("the same bypass `%s - %s' (guard %s) is already defined",
+ bypass->out_insn_name, bypass->in_insn_name,
+ bypass->bypass_guard_name);
+ return;
+ }
+ if (curr->bypass_guard_name == NULL)
+ break;
+ if (curr->next == NULL || curr->next->in_insn_reserv != in_insn_reserv)
+ {
+ last = curr;
+ break;
+ }
+
+ }
+ if (last == NULL)
+ {
+ bypass->next = out_insn_reserv->bypass_list;
+ out_insn_reserv->bypass_list = bypass;
+ }
+ else
+ {
+ bypass->next = last->next;
+ last->next = bypass;
+ }
}
/* The function processes pipeline description declarations, checks
decl_t decl_in_table;
decl_t out_insn_reserv;
decl_t in_insn_reserv;
- struct bypass_decl *bypass;
int automaton_presence;
int i;
error ("repeated declaration of automaton `%s'",
DECL_AUTOMATON (decl)->name);
else
- warning (0, "repeated declaration of automaton `%s'",
+ warning ("repeated declaration of automaton `%s'",
DECL_AUTOMATON (decl)->name);
}
}
= DECL_INSN_RESERV (out_insn_reserv);
DECL_BYPASS (decl)->in_insn_reserv
= DECL_INSN_RESERV (in_insn_reserv);
- bypass
- = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list,
- DECL_BYPASS (decl)->in_insn_reserv);
- if (bypass != NULL)
- {
- if (DECL_BYPASS (decl)->latency == bypass->latency)
- {
- if (!w_flag)
- error
- ("the same bypass `%s - %s' is already defined",
- DECL_BYPASS (decl)->out_insn_name,
- DECL_BYPASS (decl)->in_insn_name);
- else
- warning
- (0, "the same bypass `%s - %s' is already defined",
- DECL_BYPASS (decl)->out_insn_name,
- DECL_BYPASS (decl)->in_insn_name);
- }
- else
- error ("bypass `%s - %s' is already defined",
- DECL_BYPASS (decl)->out_insn_name,
- DECL_BYPASS (decl)->in_insn_name);
- }
- else
- {
- DECL_BYPASS (decl)->next
- = DECL_INSN_RESERV (out_insn_reserv)->bypass_list;
- DECL_INSN_RESERV (out_insn_reserv)->bypass_list
- = DECL_BYPASS (decl);
- }
+ insert_bypass (DECL_BYPASS (decl));
}
}
}
if (!w_flag)
error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
else
- warning (0, "automaton `%s' is not used",
+ warning ("automaton `%s' is not used",
DECL_AUTOMATON (decl)->name);
}
}
case dm_reserv:
DECL_RESERV (decl_in_table)->reserv_is_used = 1;
- new_regexp = create_node (sizeof (struct regexp));
+ new_regexp = XCREATENODE (struct regexp);
new_regexp->mode = rm_reserv;
new_regexp->pos = regexp->pos;
REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
if (!w_flag)
error ("unit `%s' is not used", DECL_UNIT (decl)->name);
else
- warning (0, "unit `%s' is not used", DECL_UNIT (decl)->name);
+ warning ("unit `%s' is not used", DECL_UNIT (decl)->name);
}
else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
{
if (!w_flag)
error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
else
- warning (0, "reservation `%s' is not used", DECL_RESERV (decl)->name);
+ warning ("reservation `%s' is not used", DECL_RESERV (decl)->name);
}
}
}
{
int max_cycle = 0;
int min_cycle = 0;
-
+
for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
{
process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
{
int max_cycle = 0;
int min_cycle = 0;
-
+
for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
{
process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
static void
add_advance_cycle_insn_decl (void)
{
- advance_cycle_insn_decl = create_node (sizeof (struct decl));
+ advance_cycle_insn_decl = XCREATENODE (struct decl);
advance_cycle_insn_decl->mode = dm_insn_reserv;
advance_cycle_insn_decl->pos = no_pos;
DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL;
#ifndef NDEBUG
allocated_alt_states_num++;
#endif
- result = create_node (sizeof (struct alt_state));
+ result = XCREATENODE (struct alt_state);
}
result->state = NULL;
result->next_alt_state = NULL;
uniq_sort_alt_states (alt_state_t alt_states_list)
{
alt_state_t curr_alt_state;
- VEC(alt_state_t,heap) *alt_states;
+ VEC(alt_state_t, heap) *alt_states;
size_t i;
size_t prev_unique_state_ind;
alt_state_t result;
if (alt_states_list->next_alt_state == 0)
return alt_states_list;
- alt_states = VEC_alloc (alt_state_t,heap, 150);
+ alt_states = VEC_alloc (alt_state_t, heap, 150);
for (curr_alt_state = alt_states_list;
curr_alt_state != NULL;
curr_alt_state = curr_alt_state->next_alt_state)
- VEC_safe_push (alt_state_t,heap, alt_states, curr_alt_state);
+ VEC_safe_push (alt_state_t, heap, alt_states, curr_alt_state);
- qsort (VEC_address (alt_state_t, alt_states),
- VEC_length (alt_state_t, alt_states),
- sizeof (alt_state_t), alt_state_cmp);
+ VEC_qsort (alt_state_t, alt_states, alt_state_cmp);
prev_unique_state_ind = 0;
for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
result = VEC_index (alt_state_t, alt_states, 0);
- VEC_free (alt_state_t,heap, alt_states);
+ VEC_free (alt_state_t, heap, alt_states);
return result;
}
/* Set bit number bitno in the bit string. The macro is not side
effect proof. */
#define SET_BIT(bitstring, bitno) \
- (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
+ ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] |= \
+ (HOST_WIDE_INT)1 << (bitno) % (sizeof (*(bitstring)) * CHAR_BIT))
#define CLEAR_BIT(bitstring, bitno) \
- (((char *) (bitstring)) [(bitno) / CHAR_BIT] &= ~(1 << (bitno) % CHAR_BIT))
+ ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] &= \
+ ~((HOST_WIDE_INT)1 << (bitno) % (sizeof (*(bitstring)) * CHAR_BIT)))
/* Test if bit number bitno in the bitstring is set. The macro is not
side effect proof. */
-#define TEST_BIT(bitstring, bitno) \
- (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
+#define TEST_BIT(bitstring, bitno) \
+ ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] >> \
+ (bitno) % (sizeof (*(bitstring)) * CHAR_BIT) & 1)
\f
#ifndef NDEBUG
allocated_states_num++;
#endif
- result = create_node (sizeof (struct state));
+ result = XCREATENODE (struct state);
result->automaton = automaton;
result->first_out_arc = NULL;
result->unique_num = curr_unique_state_num;
{
void **entry_ptr;
- entry_ptr = htab_find_slot (state_table, (void *) state, 1);
+ entry_ptr = htab_find_slot (state_table, (void *) state, INSERT);
if (*entry_ptr == NULL)
*entry_ptr = (void *) state;
return (state_t) *entry_ptr;
return NULL;
}
-/* The function adds arc from FROM_STATE to TO_STATE marked by AINSN.
- The function returns added arc (or already existing arc). */
-static arc_t
+/* The function adds arc from FROM_STATE to TO_STATE marked by AINSN,
+ unless such an arc already exists. */
+static void
add_arc (state_t from_state, state_t to_state, ainsn_t ainsn)
{
arc_t new_arc;
new_arc = find_arc (from_state, to_state, ainsn);
if (new_arc != NULL)
- return new_arc;
+ return;
if (first_free_arc == NULL)
{
#ifndef NDEBUG
allocated_arcs_num++;
#endif
- new_arc = create_node (sizeof (struct arc));
+ new_arc = XCREATENODE (struct arc);
new_arc->to_state = NULL;
new_arc->insn = NULL;
new_arc->next_out_arc = NULL;
from_state->first_out_arc = new_arc;
from_state->num_out_arcs++;
new_arc->next_arc_marked_by_insn = NULL;
- return new_arc;
}
/* The function returns the first arc starting from STATE. */
= first_free_automata_list_el->next_automata_list_el;
}
else
- result = create_node (sizeof (struct automata_list_el));
+ result = XCREATENODE (struct automata_list_el);
result->automaton = NULL;
result->next_automata_list_el = NULL;
return result;
if (current_automata_list == NULL)
return NULL;
entry_ptr = htab_find_slot (automata_list_table,
- (void *) current_automata_list, 1);
+ (void *) current_automata_list, INSERT);
if (*entry_ptr == NULL)
*entry_ptr = (void *) current_automata_list;
else
static reserv_sets_t
get_excl_set (reserv_sets_t in_set)
{
- int excl_char_num;
- int chars_num;
- int i;
+ int el;
+ unsigned int i;
int start_unit_num;
int unit_num;
- chars_num = els_in_cycle_reserv * sizeof (set_el_t);
- memset (excl_set, 0, chars_num);
- for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
- if (((unsigned char *) in_set) [excl_char_num])
- for (i = CHAR_BIT - 1; i >= 0; i--)
- if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
+ memset (excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
+ for (el = 0; el < els_in_cycle_reserv; el++)
+ if (in_set[el])
+ for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++)
+ if ((in_set[el] >> i) & 1)
{
- start_unit_num = excl_char_num * CHAR_BIT + i;
+ start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i;
if (start_unit_num >= description->units_num)
return excl_set;
for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
prev = first = NULL;
for (el = pattern_list; el != NULL; el = el->next_pattern_set_el)
{
- curr = create_node (sizeof (struct pattern_reserv));
+ curr = XCREATENODE (struct pattern_reserv);
curr->reserv = alloc_empty_reserv_sets ();
curr->next_pattern_reserv = NULL;
for (i = 0; i < el->units_num; i++)
}
/* The function checks that CHECKED_SET satisfies all presence pattern
- sets for units in ORIGIONAL_SET. The function returns TRUE if it
+ sets for units in ORIGINAL_SET. The function returns TRUE if it
is ok. */
static int
check_presence_pattern_sets (reserv_sets_t checked_set,
- reserv_sets_t origional_set,
+ reserv_sets_t original_set,
int final_p)
{
- int char_num;
- int chars_num;
- int i;
+ int el;
+ unsigned int i;
int start_unit_num;
int unit_num;
int presence_p;
pattern_reserv_t pat_reserv;
- chars_num = els_in_cycle_reserv * sizeof (set_el_t);
- for (char_num = 0; char_num < chars_num; char_num++)
- if (((unsigned char *) origional_set) [char_num])
- for (i = CHAR_BIT - 1; i >= 0; i--)
- if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
+ for (el = 0; el < els_in_cycle_reserv; el++)
+ if (original_set[el])
+ for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++)
+ if ((original_set[el] >> i) & 1)
{
- start_unit_num = char_num * CHAR_BIT + i;
+ start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i;
if (start_unit_num >= description->units_num)
break;
if ((final_p
}
/* The function checks that CHECKED_SET satisfies all absence pattern
- sets for units in ORIGIONAL_SET. The function returns TRUE if it
+ sets for units in ORIGINAL_SET. The function returns TRUE if it
is ok. */
static int
check_absence_pattern_sets (reserv_sets_t checked_set,
- reserv_sets_t origional_set,
+ reserv_sets_t original_set,
int final_p)
{
- int char_num;
- int chars_num;
- int i;
+ int el;
+ unsigned int i;
int start_unit_num;
int unit_num;
pattern_reserv_t pat_reserv;
- chars_num = els_in_cycle_reserv * sizeof (set_el_t);
- for (char_num = 0; char_num < chars_num; char_num++)
- if (((unsigned char *) origional_set) [char_num])
- for (i = CHAR_BIT - 1; i >= 0; i--)
- if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
+ for (el = 0; el < els_in_cycle_reserv; el++)
+ if (original_set[el])
+ for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++)
+ if ((original_set[el] >> i) & 1)
{
- start_unit_num = char_num * CHAR_BIT + i;
+ start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i;
if (start_unit_num >= description->units_num)
break;
for (pat_reserv = (final_p
break;
case rm_unit:
- result = copy_node (regexp, sizeof (struct regexp));
+ result = XCOPYNODE (struct regexp, regexp);
break;
case rm_repeat:
- result = copy_node (regexp, sizeof (struct regexp));
+ result = XCOPYNODE (struct regexp, regexp);
REGEXP_REPEAT (result)->regexp
= copy_insn_regexp (REGEXP_REPEAT (regexp)->regexp);
break;
case rm_sequence:
- result = copy_node (regexp,
- sizeof (struct regexp) + sizeof (regexp_t)
- * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
+ result = XCOPYNODEVAR (struct regexp, regexp,
+ sizeof (struct regexp) + sizeof (regexp_t)
+ * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
REGEXP_SEQUENCE (result)->regexps [i]
= copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
break;
case rm_allof:
- result = copy_node (regexp,
- sizeof (struct regexp) + sizeof (regexp_t)
- * (REGEXP_ALLOF (regexp)->regexps_num - 1));
+ result = XCOPYNODEVAR (struct regexp, regexp,
+ sizeof (struct regexp) + sizeof (regexp_t)
+ * (REGEXP_ALLOF (regexp)->regexps_num - 1));
for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
REGEXP_ALLOF (result)->regexps [i]
= copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
break;
case rm_oneof:
- result = copy_node (regexp,
- sizeof (struct regexp) + sizeof (regexp_t)
- * (REGEXP_ONEOF (regexp)->regexps_num - 1));
+ result = XCOPYNODEVAR (struct regexp, regexp,
+ sizeof (struct regexp) + sizeof (regexp_t)
+ * (REGEXP_ONEOF (regexp)->regexps_num - 1));
for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
REGEXP_ONEOF (result)->regexps [i]
= copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
break;
case rm_nothing:
- result = copy_node (regexp, sizeof (struct regexp));
+ result = XCOPYNODE (struct regexp, regexp);
break;
default:
gcc_assert (repeat_num > 1);
operand = REGEXP_REPEAT (regexp)->regexp;
pos = regexp->mode;
- regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t)
- * (repeat_num - 1));
+ regexp = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+ + sizeof (regexp_t) * (repeat_num - 1));
regexp->mode = rm_sequence;
regexp->pos = pos;
REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num;
{
gcc_assert (REGEXP_SEQUENCE (sequence)->regexps_num > 1
&& REGEXP_SEQUENCE (regexp)->regexps_num > 1);
- result = create_node (sizeof (struct regexp)
- + sizeof (regexp_t)
- * (REGEXP_SEQUENCE (regexp)->regexps_num
- + REGEXP_SEQUENCE (sequence)->regexps_num
- - 2));
+ result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+ + sizeof (regexp_t)
+ * (REGEXP_SEQUENCE (regexp)->regexps_num
+ + REGEXP_SEQUENCE (sequence)->regexps_num
+ - 2));
result->mode = rm_sequence;
result->pos = regexp->pos;
REGEXP_SEQUENCE (result)->regexps_num
{
gcc_assert (REGEXP_ALLOF (allof)->regexps_num > 1
&& REGEXP_ALLOF (regexp)->regexps_num > 1);
- result = create_node (sizeof (struct regexp)
- + sizeof (regexp_t)
- * (REGEXP_ALLOF (regexp)->regexps_num
- + REGEXP_ALLOF (allof)->regexps_num - 2));
+ result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+ + sizeof (regexp_t)
+ * (REGEXP_ALLOF (regexp)->regexps_num
+ + REGEXP_ALLOF (allof)->regexps_num - 2));
result->mode = rm_allof;
result->pos = regexp->pos;
REGEXP_ALLOF (result)->regexps_num
{
gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
&& REGEXP_ONEOF (regexp)->regexps_num > 1);
- result = create_node (sizeof (struct regexp)
- + sizeof (regexp_t)
- * (REGEXP_ONEOF (regexp)->regexps_num
- + REGEXP_ONEOF (oneof)->regexps_num - 2));
+ result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+ + sizeof (regexp_t)
+ * (REGEXP_ONEOF (regexp)->regexps_num
+ + REGEXP_ONEOF (oneof)->regexps_num - 2));
result->mode = rm_oneof;
result->pos = regexp->pos;
REGEXP_ONEOF (result)->regexps_num
{
gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
&& REGEXP_SEQUENCE (regexp)->regexps_num > 1);
- result = create_node (sizeof (struct regexp)
- + sizeof (regexp_t)
- * (REGEXP_ONEOF (oneof)->regexps_num - 1));
+ result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+ + sizeof (regexp_t)
+ * (REGEXP_ONEOF (oneof)->regexps_num - 1));
result->mode = rm_oneof;
result->pos = regexp->pos;
REGEXP_ONEOF (result)->regexps_num
for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
{
sequence
- = create_node (sizeof (struct regexp)
- + sizeof (regexp_t)
- * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
+ = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+ + sizeof (regexp_t)
+ * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
sequence->mode = rm_sequence;
sequence->pos = regexp->pos;
REGEXP_SEQUENCE (sequence)->regexps_num
{
gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
&& REGEXP_ALLOF (regexp)->regexps_num > 1);
- result = create_node (sizeof (struct regexp)
- + sizeof (regexp_t)
- * (REGEXP_ONEOF (oneof)->regexps_num - 1));
+ result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+ + sizeof (regexp_t)
+ * (REGEXP_ONEOF (oneof)->regexps_num - 1));
result->mode = rm_oneof;
result->pos = regexp->pos;
REGEXP_ONEOF (result)->regexps_num
for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
{
allof
- = create_node (sizeof (struct regexp)
- + sizeof (regexp_t)
- * (REGEXP_ALLOF (regexp)->regexps_num - 1));
+ = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+ + sizeof (regexp_t)
+ * (REGEXP_ALLOF (regexp)->regexps_num - 1));
allof->mode = rm_allof;
allof->pos = regexp->pos;
REGEXP_ALLOF (allof)->regexps_num
{
gcc_assert (max_seq_length != 1
&& REGEXP_ALLOF (regexp)->regexps_num > 1);
- result = create_node (sizeof (struct regexp)
- + sizeof (regexp_t) * (max_seq_length - 1));
+ result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+ + sizeof (regexp_t) * (max_seq_length - 1));
result->mode = rm_sequence;
result->pos = regexp->pos;
REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
default:
break;
}
-
+
if (allof_length == 1)
REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
else
{
- allof = create_node (sizeof (struct regexp)
- + sizeof (regexp_t)
- * (allof_length - 1));
+ allof = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+ + sizeof (regexp_t)
+ * (allof_length - 1));
allof->mode = rm_allof;
allof->pos = regexp->pos;
REGEXP_ALLOF (allof)->regexps_num = allof_length;
about units to automata distribution has been output. */
static int annotation_message_reported_p;
+/* The vector contains all decls which are automata. */
+static VEC(decl_t, heap) *automaton_decls;
+
/* The following structure describes usage of a unit in a reservation. */
struct unit_usage
{
unit_decl_t unit_decl;
/* The following forms a list of units used on the same cycle in the
- same alternative. */
+ same alternative. The list is ordered by the correspdoning unit
+ declarations and there is no unit declaration duplication in the
+ list. */
struct unit_usage *next;
};
typedef struct unit_usage *unit_usage_t;
DEF_VEC_P(unit_usage_t);
-DEF_VEC_ALLOC_P(unit_usage_t,heap);
+DEF_VEC_ALLOC_P(unit_usage_t, heap);
/* Obstack for unit_usage structures. */
static struct obstack unit_usages;
structures. There is an element for each combination of
(alternative number, cycle). Unit usages on given cycle in
alternative with given number are referred through element with
- index equals to the cycle * number of all alternatives in the regexp
- + the alternative number. */
-static VEC(unit_usage_t,heap) *cycle_alt_unit_usages;
+ index equals to the cycle * number of all alternatives in the
+ regexp + the alternative number. */
+static VEC(unit_usage_t, heap) *cycle_alt_unit_usages;
/* The following function creates the structure unit_usage for UNIT on
CYCLE in REGEXP alternative with ALT_NUM. The structure is made
{
size_t length;
unit_decl_t unit_decl;
- unit_usage_t unit_usage_ptr;
+ unit_usage_t unit_usage_ptr, curr, prev;
int index;
gcc_assert (regexp && regexp->mode == rm_oneof
length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
while (VEC_length (unit_usage_t, cycle_alt_unit_usages) < length)
- VEC_safe_push (unit_usage_t,heap, cycle_alt_unit_usages, 0);
-
+ VEC_safe_push (unit_usage_t, heap, cycle_alt_unit_usages, 0);
+
+ index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
+ prev = NULL;
+ for (curr = VEC_index (unit_usage_t, cycle_alt_unit_usages, index);
+ curr != NULL;
+ prev = curr, curr = curr->next)
+ if (curr->unit_decl >= unit_decl)
+ break;
+ if (curr != NULL && curr->unit_decl == unit_decl)
+ return;
obstack_blank (&unit_usages, sizeof (struct unit_usage));
unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages);
obstack_finish (&unit_usages);
unit_usage_ptr->unit_decl = unit_decl;
- index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
- unit_usage_ptr->next = VEC_index (unit_usage_t, cycle_alt_unit_usages, index);
- VEC_replace (unit_usage_t, cycle_alt_unit_usages, index, unit_usage_ptr);
unit_decl->last_distribution_check_cycle = -1; /* undefined */
+ unit_usage_ptr->next = curr;
+ if (prev == NULL)
+ VEC_replace (unit_usage_t, cycle_alt_unit_usages, index, unit_usage_ptr);
+ else
+ prev->next = unit_usage_ptr;
+}
+
+/* Return true if unit UNIT_DECL is present on the LIST. */
+static bool
+unit_present_on_list_p (unit_usage_t list, unit_decl_t unit_decl)
+{
+ while (list != NULL)
+ {
+ if (list->unit_decl == unit_decl)
+ return true;
+ list = list->next;
+ }
+ return false;
}
+/* The function returns true if reservations of alternatives ALT1 and
+ ALT2 are equal after excluding reservations of units of
+ EXCLUDED_AUTOMATON_DECL. */
+static bool
+equal_alternatives_p (int alt1, int alt2, int n_alts,
+ struct automaton_decl *excluded_automaton_decl)
+{
+ int i;
+ unit_usage_t list1, list2;
+
+ for (i = 0;
+ i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages);
+ i += n_alts)
+ {
+ for (list1 = VEC_index (unit_usage_t, cycle_alt_unit_usages, i + alt1),
+ list2 = VEC_index (unit_usage_t, cycle_alt_unit_usages, i + alt2);;
+ list1 = list1->next, list2 = list2->next)
+ {
+ while (list1 != NULL
+ && list1->unit_decl->automaton_decl == excluded_automaton_decl)
+ list1 = list1->next;
+ while (list2 != NULL
+ && list2->unit_decl->automaton_decl == excluded_automaton_decl)
+ list2 = list2->next;
+ if (list1 == NULL || list2 == NULL)
+ {
+ if (list1 != list2)
+ return false;
+ else
+ break;
+ }
+ if (list1->unit_decl != list2->unit_decl)
+ return false;
+ }
+ }
+ return true;
+}
+
+DEF_VEC_I(int);
+DEF_VEC_ALLOC_I(int, heap);
+
/* The function processes given REGEXP to find units with the wrong
distribution. */
static void
check_regexp_units_distribution (const char *insn_reserv_name,
regexp_t regexp)
{
- int i, j, k, cycle;
+ int i, j, k, cycle, start, n_alts, alt, alt2;
+ bool annotation_reservation_message_reported_p;
regexp_t seq, allof, unit;
- struct unit_usage *unit_usage_ptr, *other_unit_usage_ptr;
+ struct unit_usage *unit_usage_ptr;
+ VEC(int, heap) *marked;
if (regexp == NULL || regexp->mode != rm_oneof)
return;
/* Store all unit usages in the regexp: */
obstack_init (&unit_usages);
- cycle_alt_unit_usages = 0;
+ cycle_alt_unit_usages = VEC_alloc (unit_usage_t, heap, 10);
for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
{
gcc_assert (unit->mode == rm_nothing);
}
break;
-
+
case rm_unit:
store_alt_unit_usage (regexp, allof, j, i);
break;
-
+
case rm_nothing:
break;
-
+
default:
gcc_unreachable ();
}
case rm_unit:
store_alt_unit_usage (regexp, unit, 0, i);
break;
-
+
case rm_nothing:
break;
-
+
default:
gcc_unreachable ();
}
}
/* Check distribution: */
for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++)
+ for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i);
+ unit_usage_ptr != NULL;
+ unit_usage_ptr = unit_usage_ptr->next)
+ unit_usage_ptr->unit_decl->last_distribution_check_cycle = -1;
+ n_alts = REGEXP_ONEOF (regexp)->regexps_num;
+ marked = VEC_alloc (int, heap, n_alts);
+ for (i = 0; i < n_alts; i++)
+ VEC_safe_push (int, heap, marked, 0);
+ annotation_reservation_message_reported_p = false;
+ for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++)
{
- cycle = i / REGEXP_ONEOF (regexp)->regexps_num;
+ cycle = i / n_alts;
+ start = cycle * n_alts;
for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i);
unit_usage_ptr != NULL;
unit_usage_ptr = unit_usage_ptr->next)
- if (cycle != unit_usage_ptr->unit_decl->last_distribution_check_cycle)
- {
- unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
- for (k = cycle * REGEXP_ONEOF (regexp)->regexps_num;
- k < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages)
- && k == cycle * REGEXP_ONEOF (regexp)->regexps_num;
- k++)
- {
- for (other_unit_usage_ptr
- = VEC_index (unit_usage_t, cycle_alt_unit_usages, k);
- other_unit_usage_ptr != NULL;
- other_unit_usage_ptr = other_unit_usage_ptr->next)
- if (unit_usage_ptr->unit_decl->automaton_decl
- == other_unit_usage_ptr->unit_decl->automaton_decl)
- break;
- if (other_unit_usage_ptr == NULL
- && (VEC_index (unit_usage_t, cycle_alt_unit_usages, k)
- != NULL))
- break;
- }
- if (k < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages)
- && k == cycle * REGEXP_ONEOF (regexp)->regexps_num)
- {
- if (!annotation_message_reported_p)
- {
- fprintf (stderr, "\n");
- error ("The following units do not satisfy units-automata distribution rule");
- error (" (A unit of given unit automaton should be on each reserv. altern.)");
- annotation_message_reported_p = TRUE;
- }
- error ("Unit %s, reserv. %s, cycle %d",
- unit_usage_ptr->unit_decl->name, insn_reserv_name,
- cycle);
- }
- }
+ {
+ if (unit_usage_ptr->unit_decl->last_distribution_check_cycle == cycle)
+ continue;
+ unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
+ for (alt = 0; alt < n_alts; alt++)
+ if (! unit_present_on_list_p (VEC_index (unit_usage_t,
+ cycle_alt_unit_usages,
+ start + alt),
+ unit_usage_ptr->unit_decl))
+ break;
+ if (alt >= n_alts)
+ continue;
+ memset (VEC_address (int, marked), 0, n_alts * sizeof (int));
+ for (alt = 0; alt < n_alts; alt++)
+ {
+ if (! unit_present_on_list_p (VEC_index (unit_usage_t,
+ cycle_alt_unit_usages,
+ start + alt),
+ unit_usage_ptr->unit_decl))
+ continue;
+ for (j = 0;
+ j < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages);
+ j++)
+ {
+ alt2 = j % n_alts;
+ if (! unit_present_on_list_p
+ (VEC_index (unit_usage_t, cycle_alt_unit_usages,
+ start + alt2),
+ unit_usage_ptr->unit_decl)
+ && equal_alternatives_p (alt, alt2, n_alts,
+ unit_usage_ptr
+ ->unit_decl->automaton_decl))
+ {
+ VEC_replace (int, marked, alt, 1);
+ VEC_replace (int, marked, alt2, 1);
+ }
+ }
+ }
+ for (alt = 0; alt < n_alts && VEC_index (int, marked, alt); alt++)
+ ;
+ if (alt < n_alts && 0)
+ {
+ if (! annotation_message_reported_p)
+ {
+ fprintf (stderr, "\n");
+ error ("The following units do not satisfy units-automata distribution rule");
+ error ("(Unit presence on one alt and its absence on other alt\n");
+ error (" result in different other automata reservations)");
+ annotation_message_reported_p = TRUE;
+ }
+ if (! annotation_reservation_message_reported_p)
+ {
+ error ("Reserv %s:", insn_reserv_name);
+ annotation_reservation_message_reported_p = true;
+ }
+ error (" Unit %s, cycle %d, alt %d, another alt %d",
+ unit_usage_ptr->unit_decl->name, cycle, i % n_alts, alt);
+ }
+ }
}
- VEC_free (unit_usage_t,heap, cycle_alt_unit_usages);
+ VEC_free (int, heap, marked);
+ VEC_free (unit_usage_t, heap, cycle_alt_unit_usages);
obstack_free (&unit_usages, NULL);
}
if (progress_flag)
fprintf (stderr, "Check unit distributions to automata...");
- annotation_message_reported_p = FALSE;
+ automaton_decls = NULL;
for (i = 0; i < description->decls_num; i++)
{
decl = description->decls [i];
- if (decl->mode == dm_insn_reserv)
- check_regexp_units_distribution
- (DECL_INSN_RESERV (decl)->name,
- DECL_INSN_RESERV (decl)->transformed_regexp);
+ if (decl->mode == dm_automaton)
+ VEC_safe_push (decl_t, heap, automaton_decls, decl);
}
+ if (VEC_length (decl_t, automaton_decls) > 1)
+ {
+ annotation_message_reported_p = FALSE;
+ for (i = 0; i < description->decls_num; i++)
+ {
+ decl = description->decls [i];
+ if (decl->mode == dm_insn_reserv)
+ check_regexp_units_distribution
+ (DECL_INSN_RESERV (decl)->name,
+ DECL_INSN_RESERV (decl)->transformed_regexp);
+ }
+ }
+ VEC_free (decl_t, heap, automaton_decls);
if (progress_flag)
fprintf (stderr, "done\n");
}
set_state_reserv (state_being_formed, curr_cycle,
REGEXP_UNIT (regexp)->unit_decl->unit_num);
return curr_cycle;
-
+
case rm_sequence:
for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
curr_cycle
{
int finish_cycle = 0;
int cycle;
-
+
for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
{
cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
{
ainsn_t curr_ainsn;
size_t i;
- VEC(ainsn_t,heap) *last_insns = VEC_alloc (ainsn_t,heap, 150);
+ VEC(ainsn_t, heap) *last_insns = VEC_alloc (ainsn_t, heap, 150);
for (curr_ainsn = automaton->ainsn_list;
curr_ainsn != NULL;
curr_ainsn->first_insn_with_same_reservs = 1;
}
}
- VEC_free (ainsn_t,heap, last_insns);
+ VEC_free (ainsn_t, heap, last_insns);
}
/* Forming unit reservations which can affect creating the automaton
state_t start_state;
state_t state2;
ainsn_t advance_cycle_ainsn;
- arc_t added_arc;
- VEC(state_t,heap) *state_stack = VEC_alloc(state_t,heap, 150);
+ VEC(state_t, heap) *state_stack = VEC_alloc(state_t, heap, 150);
int states_n;
reserv_sets_t reservs_matter = form_reservs_matter (automaton);
start_state = insert_state (get_free_state (1, automaton));
automaton->start_state = start_state;
start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
- VEC_safe_push (state_t,heap, state_stack, start_state);
+ VEC_safe_push (state_t, heap, state_stack, start_state);
states_n = 1;
while (VEC_length (state_t, state_stack) != 0)
{
{
/* We process alt_states in the same order as they are
present in the description. */
- added_arc = NULL;
for (alt_state = ainsn->alt_states;
alt_state != NULL;
alt_state = alt_state->next_alt_state)
{
state2->it_was_placed_in_stack_for_NDFA_forming
= 1;
- VEC_safe_push (state_t,heap, state_stack, state2);
+ VEC_safe_push (state_t, heap, state_stack, state2);
states_n++;
if (progress_flag && states_n % 100 == 0)
fprintf (stderr, ".");
}
- added_arc = add_arc (state, state2, ainsn);
+ add_arc (state, state2, ainsn);
if (!ndfa_flag)
break;
}
}
- if (!ndfa_flag && added_arc != NULL)
- {
- for (alt_state = ainsn->alt_states;
- alt_state != NULL;
- alt_state = alt_state->next_alt_state)
- state2 = alt_state->state;
- }
}
else
advance_cycle_ainsn = ainsn;
if (!state2->it_was_placed_in_stack_for_NDFA_forming)
{
state2->it_was_placed_in_stack_for_NDFA_forming = 1;
- VEC_safe_push (state_t,heap, state_stack, state2);
+ VEC_safe_push (state_t, heap, state_stack, state2);
states_n++;
if (progress_flag && states_n % 100 == 0)
fprintf (stderr, ".");
gcc_assert (advance_cycle_ainsn);
add_arc (state, state2, advance_cycle_ainsn);
}
- VEC_free (state_t,heap, state_stack);
+ VEC_free (state_t, heap, state_stack);
}
-/* Foms lists of all arcs of STATE marked by the same ainsn. */
+/* Form lists of all arcs of STATE marked by the same ainsn. */
static void
form_arcs_marked_by_insn (state_t state)
{
static int
create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
- VEC(state_t,heap) **state_stack)
+ VEC(state_t, heap) **state_stack)
{
state_t state;
alt_state_t alt_state, curr_alt_state;
if (!state->it_was_placed_in_stack_for_DFA_forming)
{
state->it_was_placed_in_stack_for_DFA_forming = 1;
- VEC_safe_push (state_t,heap, *state_stack, state);
+ VEC_safe_push (state_t, heap, *state_stack, state);
}
return new_state_p;
}
state_t start_state;
state_t state;
decl_t decl;
- VEC(state_t,heap) *state_stack;
+ VEC(state_t, heap) *state_stack;
int i;
int states_n;
- state_stack = VEC_alloc (state_t,heap, 0);
+ state_stack = VEC_alloc (state_t, heap, 0);
/* Create the start state (empty state). */
start_state = automaton->start_state;
start_state->it_was_placed_in_stack_for_DFA_forming = 1;
- VEC_safe_push (state_t,heap, state_stack, start_state);
+ VEC_safe_push (state_t, heap, state_stack, start_state);
states_n = 1;
while (VEC_length (state_t, state_stack) != 0)
{
}
}
}
- VEC_free (state_t,heap, state_stack);
+ VEC_free (state_t, heap, state_stack);
}
/* The following variable value is current number (1, 2, ...) of passing
/* The following vla is used for storing pointers to all achieved
states. */
-static VEC(state_t,heap) *all_achieved_states;
+static VEC(state_t, heap) *all_achieved_states;
/* This function is called by function pass_states to add an achieved
STATE. */
static void
add_achieved_state (state_t state)
{
- VEC_safe_push (state_t,heap, all_achieved_states, state);
+ VEC_safe_push (state_t, heap, all_achieved_states, state);
}
/* The function sets up equivalence numbers of insns which mark all
unsigned int sz;
sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
/ (sizeof (int) * CHAR_BIT);
-
- state->presence_signature = create_node (sz * sizeof (int));
+
+ state->presence_signature = XCREATENODEVEC (unsigned int, sz);
for (i = 0; i < description->units_num; i++)
if (units_array [i]->query_p)
{
classes and saves it into *CLASSES. This function requires the input
to be sorted via compare_states_for_equiv(). */
static int
-init_equiv_class (VEC(state_t,heap) *states, VEC (state_t,heap) **classes)
+init_equiv_class (VEC(state_t, heap) *states, VEC (state_t, heap) **classes)
{
size_t i;
state_t prev = 0;
int class_num = 1;
- *classes = VEC_alloc (state_t,heap, 150);
+ *classes = VEC_alloc (state_t, heap, 150);
for (i = 0; i < VEC_length (state_t, states); i++)
{
state_t state = VEC_index (state_t, states, i);
{
if (compare_states_for_equiv (&prev, &state) != 0)
{
- VEC_safe_push (state_t,heap, *classes, prev);
+ VEC_safe_push (state_t, heap, *classes, prev);
class_num++;
prev = NULL;
}
prev = state;
}
if (prev)
- VEC_safe_push (state_t,heap, *classes, prev);
+ VEC_safe_push (state_t, heap, *classes, prev);
return class_num;
}
/* The function copies pointers to equivalent states from vla FROM
into vla TO. */
static void
-copy_equiv_class (VEC(state_t,heap) **to, VEC(state_t,heap) *from)
+copy_equiv_class (VEC(state_t, heap) **to, VEC(state_t, heap) *from)
{
- VEC_free (state_t,heap, *to);
- *to = VEC_copy (state_t,heap, from);
+ VEC_free (state_t, heap, *to);
+ *to = VEC_copy (state_t, heap, from);
}
/* The function processes equivalence class given by its first state,
partitioned, the function returns nonzero value. */
static int
partition_equiv_class (state_t first_state, int odd_iteration_flag,
- VEC(state_t,heap) **next_iteration_classes,
+ VEC(state_t, heap) **next_iteration_classes,
int *new_equiv_class_num_ptr)
{
state_t new_equiv_class;
curr_state = next_state)
{
next_state = curr_state->next_equiv_class_state;
- if (state_is_differed (curr_state, first_state,
+ if (state_is_differed (curr_state, first_state,
odd_iteration_flag))
{
/* Remove curr state from the class equivalence. */
clear_arc_insns_equiv_num (first_state);
}
if (new_equiv_class != NULL)
- VEC_safe_push (state_t,heap, *next_iteration_classes, new_equiv_class);
+ VEC_safe_push (state_t, heap, *next_iteration_classes, new_equiv_class);
first_state = new_equiv_class;
}
return partition_p;
/* The function finds equivalent states of AUTOMATON. */
static void
evaluate_equiv_classes (automaton_t automaton,
- VEC(state_t,heap) **equiv_classes)
+ VEC(state_t, heap) **equiv_classes)
{
int new_equiv_class_num;
int odd_iteration_flag;
int finish_flag;
- VEC (state_t,heap) *next_iteration_classes;
+ VEC (state_t, heap) *next_iteration_classes;
size_t i;
- all_achieved_states = VEC_alloc (state_t,heap, 1500);
+ all_achieved_states = VEC_alloc (state_t, heap, 1500);
pass_states (automaton, add_achieved_state);
pass_states (automaton, cache_presence);
- qsort (VEC_address (state_t, all_achieved_states),
- VEC_length (state_t, all_achieved_states),
- sizeof (state_t), compare_states_for_equiv);
+ VEC_qsort (state_t, all_achieved_states, compare_states_for_equiv);
odd_iteration_flag = 0;
new_equiv_class_num = init_equiv_class (all_achieved_states,
finish_flag = 0;
}
while (!finish_flag);
- VEC_free (state_t,heap, next_iteration_classes);
- VEC_free (state_t,heap, all_achieved_states);
+ VEC_free (state_t, heap, next_iteration_classes);
+ VEC_free (state_t, heap, all_achieved_states);
}
/* The function merges equivalent states of AUTOMATON. */
static void
-merge_states (automaton_t automaton, VEC(state_t,heap) *equiv_classes)
+merge_states (automaton_t automaton, VEC(state_t, heap) *equiv_classes)
{
state_t curr_state;
state_t new_state;
static void
minimize_DFA (automaton_t automaton)
{
- VEC(state_t,heap) *equiv_classes = 0;
+ VEC(state_t, heap) *equiv_classes = 0;
evaluate_equiv_classes (automaton, &equiv_classes);
merge_states (automaton, equiv_classes);
pass_states (automaton, set_new_cycle_flags);
- VEC_free (state_t,heap, equiv_classes);
+ VEC_free (state_t, heap, equiv_classes);
}
/* Values of two variables are counted number of states and arcs in an
decl = description->decls [i];
if (decl->mode == dm_insn_reserv)
{
- curr_ainsn = create_node (sizeof (struct ainsn));
+ curr_ainsn = XCREATENODE (struct ainsn);
curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
curr_ainsn->important_p = FALSE;
curr_ainsn->next_ainsn = NULL;
curr_automaton_num < automata_num;
curr_automaton_num++, prev_automaton = curr_automaton)
{
- curr_automaton = create_node (sizeof (struct automaton));
+ curr_automaton = XCREATENODE (struct automaton);
curr_automaton->ainsn_list = create_ainsns ();
curr_automaton->corresponding_automaton_decl = NULL;
curr_automaton->next_automaton = NULL;
if (decl->mode == dm_automaton
&& DECL_AUTOMATON (decl)->automaton_is_used)
{
- curr_automaton = create_node (sizeof (struct automaton));
+ curr_automaton = XCREATENODE (struct automaton);
curr_automaton->ainsn_list = create_ainsns ();
curr_automaton->corresponding_automaton_decl
= DECL_AUTOMATON (decl);
}
if (curr_automaton_num == 0)
{
- curr_automaton = create_node (sizeof (struct automaton));
+ curr_automaton = XCREATENODE (struct automaton);
curr_automaton->ainsn_list = create_ainsns ();
curr_automaton->corresponding_automaton_decl = NULL;
curr_automaton->next_automaton = NULL;
const char *name = (regexp->mode == rm_unit
? REGEXP_UNIT (regexp)->name
: REGEXP_RESERV (regexp)->name);
-
+
obstack_grow (&irp, name, strlen (name));
break;
}
-
+
case rm_sequence:
for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
{
}
obstack_1grow (&irp, ')');
break;
-
+
case rm_oneof:
for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
{
obstack_1grow (&irp, ')');
}
break;
-
+
case rm_repeat:
{
char digits [30];
-
+
if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
|| REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
|| REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
#define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
+#define INSN_HAS_DFA_RESERVATION_P_FUNC_NAME "insn_has_dfa_reservation_p"
+
#define DFA_CLEAN_INSN_CACHE_FUNC_NAME "dfa_clean_insn_cache"
#define DFA_CLEAR_SINGLE_INSN_CACHE_FUNC_NAME "dfa_clear_single_insn_cache"
int insn_value;
vla_hwint_t translate_vect;
- translate_vect = VEC_alloc (vect_el_t,heap, description->insns_num);
+ translate_vect = VEC_alloc (vect_el_t, heap, description->insns_num);
for (insn_value = 0; insn_value < description->insns_num; insn_value++)
/* Undefined value */
fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
output_vect (translate_vect);
fprintf (output_file, "};\n\n");
- VEC_free (vect_el_t,heap, translate_vect);
+ VEC_free (vect_el_t, heap, translate_vect);
}
/* The value in a table state x ainsn -> something which represents
int full_vect_length;
int i;
- tab = create_node (sizeof (struct state_ainsn_table));
+ tab = XCREATENODE (struct state_ainsn_table);
tab->automaton = automaton;
- tab->comb_vect = VEC_alloc (vect_el_t,heap, 10000);
- tab->check_vect = VEC_alloc (vect_el_t,heap, 10000);
+ tab->comb_vect = VEC_alloc (vect_el_t, heap, 10000);
+ tab->check_vect = VEC_alloc (vect_el_t, heap, 10000);
tab->base_vect = 0;
- VEC_safe_grow (vect_el_t,heap, tab->base_vect,
+ VEC_safe_grow (vect_el_t, heap, tab->base_vect,
automaton->achieved_states_num);
full_vect_length = (automaton->insn_equiv_classes_num
* automaton->achieved_states_num);
- tab->full_vect = VEC_alloc (vect_el_t,heap, full_vect_length);
+ tab->full_vect = VEC_alloc (vect_el_t, heap, full_vect_length);
for (i = 0; i < full_vect_length; i++)
VEC_quick_push (vect_el_t, tab->full_vect, undefined_vect_el_value);
{
size_t full_base = tab->automaton->insn_equiv_classes_num * vect_num;
if (VEC_length (vect_el_t, tab->full_vect) < full_base + vect_length)
- VEC_safe_grow (vect_el_t,heap, tab->full_vect,
+ VEC_safe_grow (vect_el_t, heap, tab->full_vect,
full_base + vect_length);
for (i = 0; i < vect_length; i++)
VEC_replace (vect_el_t, tab->full_vect, full_base + i,
no_state_value = tab->automaton->achieved_states_num;
while (additional_els_num > 0)
{
- VEC_safe_push (vect_el_t,heap, tab->comb_vect, vect_el);
- VEC_safe_push (vect_el_t,heap, tab->check_vect, no_state_value);
+ VEC_safe_push (vect_el_t, heap, tab->comb_vect, vect_el);
+ VEC_safe_push (vect_el_t, heap, tab->check_vect, no_state_value);
additional_els_num--;
}
gcc_assert (VEC_length (vect_el_t, tab->comb_vect)
for (vect_index = VEC_length (vect_el_t, *vect);
vect_index <= equiv_class_num;
vect_index++)
- VEC_safe_push (vect_el_t,heap, *vect, undefined_vect_el_value);
+ VEC_safe_push (vect_el_t, heap, *vect, undefined_vect_el_value);
VEC_replace (vect_el_t, *vect, equiv_class_num, el_value);
}
/* This is for forming vector of states of an automaton. */
-static VEC(state_t,heap) *output_states_vect;
+static VEC(state_t, heap) *output_states_vect;
/* The function is called by function pass_states. The function adds
STATE to `output_states_vect'. */
static void
add_states_vect_el (state_t state)
{
- VEC_safe_push (state_t,heap, output_states_vect, state);
+ VEC_safe_push (state_t, heap, output_states_vect, state);
}
/* Form and output vectors (comb, check, base or full vector)
from the state (state with the maximum num is the first). */
output_states_vect = 0;
pass_states (automaton, add_states_vect_el);
- qsort (VEC_address (state_t, output_states_vect),
- VEC_length (state_t, output_states_vect),
- sizeof (state_t), compare_transition_els_num);
+ VEC_qsort (state_t, output_states_vect, compare_transition_els_num);
for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
{
output_trans_full_vect_name, output_trans_comb_vect_name,
output_trans_check_vect_name, output_trans_base_vect_name);
- VEC_free (state_t,heap, output_states_vect);
- VEC_free (vect_el_t,heap, transition_vect);
-}
-
-/* The current number of passing states to find minimal issue delay
- value for an ainsn and state. */
-static int curr_state_pass_num;
-
-/* This recursive function passes states to find minimal issue delay
- value for AINSN. The state being visited is STATE. The function
- returns minimal issue delay value for AINSN in STATE or -1 if we
- enter into a loop. */
-static int
-min_issue_delay_pass_states (state_t state, ainsn_t ainsn)
-{
- arc_t arc;
- int min_insn_issue_delay, insn_issue_delay;
-
- if (state->state_pass_num == curr_state_pass_num
- || state->min_insn_issue_delay != -1)
- /* We've entered into a loop or already have the correct value for
- given state and ainsn. */
- return state->min_insn_issue_delay;
- state->state_pass_num = curr_state_pass_num;
- min_insn_issue_delay = -1;
- for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
- if (arc->insn == ainsn)
- {
- min_insn_issue_delay = 0;
- break;
- }
- else
- {
- insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
- if (insn_issue_delay != -1)
- {
- if (arc->insn->insn_reserv_decl
- == DECL_INSN_RESERV (advance_cycle_insn_decl))
- insn_issue_delay++;
- if (min_insn_issue_delay == -1
- || min_insn_issue_delay > insn_issue_delay)
- {
- min_insn_issue_delay = insn_issue_delay;
- if (insn_issue_delay == 0)
- break;
- }
- }
- }
- return min_insn_issue_delay;
-}
-
-/* The function searches minimal issue delay value for AINSN in STATE.
- The function can return negative value if we can not issue AINSN. We
- will report about it later. */
-static int
-min_issue_delay (state_t state, ainsn_t ainsn)
-{
- curr_state_pass_num++;
- state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
- return state->min_insn_issue_delay;
-}
-
-/* The function initiates code for finding minimal issue delay values.
- It should be called only once. */
-static void
-initiate_min_issue_delay_pass_states (void)
-{
- curr_state_pass_num = 0;
+ VEC_free (state_t, heap, output_states_vect);
+ VEC_free (vect_el_t, heap, transition_vect);
}
/* Form and output vectors representing minimal issue delay table of
{
vla_hwint_t min_issue_delay_vect;
vla_hwint_t compressed_min_issue_delay_vect;
- vect_el_t min_delay;
ainsn_t ainsn;
- size_t i, min_issue_delay_len;
- size_t compressed_min_issue_delay_len;
+ size_t i;
+ size_t min_issue_delay_len, compressed_min_issue_delay_len;
size_t cfactor;
+ int changed;
/* Create vect of pointers to states ordered by num of transitions
from the state (state with the maximum num is the first). */
min_issue_delay_len = (VEC_length (state_t, output_states_vect)
* automaton->insn_equiv_classes_num);
- min_issue_delay_vect = VEC_alloc (vect_el_t,heap, min_issue_delay_len);
+ min_issue_delay_vect = VEC_alloc (vect_el_t, heap, min_issue_delay_len);
for (i = 0; i < min_issue_delay_len; i++)
- VEC_quick_push (vect_el_t, min_issue_delay_vect, 0);
+ VEC_quick_push (vect_el_t, min_issue_delay_vect, -1);
automaton->max_min_delay = 0;
- for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
+
+ do
+ {
+ size_t state_no;
+
+ changed = 0;
+
+ for (state_no = 0; state_no < VEC_length (state_t, output_states_vect);
+ state_no++)
+ {
+ state_t s = VEC_index (state_t, output_states_vect, state_no);
+ arc_t arc;
+
+ for (arc = first_out_arc (s); arc; arc = next_out_arc (arc))
+ {
+ int k;
+
+ size_t asn = s->order_state_num
+ * automaton->insn_equiv_classes_num
+ + arc->insn->insn_equiv_class_num;
+
+ if (VEC_index (vect_el_t, min_issue_delay_vect, asn))
+ {
+ VEC_replace (vect_el_t, min_issue_delay_vect, asn, 0);
+ changed = 1;
+ }
+
+ for (k = 0; k < automaton->insn_equiv_classes_num; k++)
+ {
+ size_t n0, n1;
+ vect_el_t delay0, delay1;
+
+ n0 = s->order_state_num
+ * automaton->insn_equiv_classes_num
+ + k;
+ n1 = arc->to_state->order_state_num
+ * automaton->insn_equiv_classes_num
+ + k;
+ delay0 = VEC_index (vect_el_t, min_issue_delay_vect, n0);
+ delay1 = VEC_index (vect_el_t, min_issue_delay_vect, n1);
+ if (delay1 != -1)
+ {
+ if (arc->insn->insn_reserv_decl
+ == DECL_INSN_RESERV (advance_cycle_insn_decl))
+ delay1++;
+ if (delay1 < delay0 || delay0 == -1)
+ {
+ VEC_replace (vect_el_t, min_issue_delay_vect, n0, delay1);
+ changed = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ while (changed);
+
+ automaton->max_min_delay = 0;
+
+ for (ainsn = automaton->ainsn_list; ainsn; ainsn = ainsn->next_ainsn)
if (ainsn->first_ainsn_with_given_equivalence_num)
{
for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
- VEC_index (state_t, output_states_vect, i)->min_insn_issue_delay = -1;
- for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
{
state_t s = VEC_index (state_t, output_states_vect, i);
- min_delay = min_issue_delay (s, ainsn);
- if (automaton->max_min_delay < min_delay)
- automaton->max_min_delay = min_delay;
- VEC_replace (vect_el_t, min_issue_delay_vect,
- s->order_state_num
- * automaton->insn_equiv_classes_num
- + ainsn->insn_equiv_class_num,
- min_delay);
+ size_t np = s->order_state_num
+ * automaton->insn_equiv_classes_num
+ + ainsn->insn_equiv_class_num;
+ vect_el_t x = VEC_index (vect_el_t, min_issue_delay_vect, np);
+
+ if (automaton->max_min_delay < x)
+ automaton->max_min_delay = x;
+ if (x == -1)
+ VEC_replace (vect_el_t, min_issue_delay_vect, np, 0);
}
}
+
fprintf (output_file, "/* Vector of min issue delay of insns. */\n");
fprintf (output_file, "static const ");
output_range_type (output_file, 0, automaton->max_min_delay);
compressed_min_issue_delay_len = (min_issue_delay_len+cfactor-1) / cfactor;
compressed_min_issue_delay_vect
- = VEC_alloc (vect_el_t,heap, compressed_min_issue_delay_len);
+ = VEC_alloc (vect_el_t, heap, compressed_min_issue_delay_len);
for (i = 0; i < compressed_min_issue_delay_len; i++)
VEC_quick_push (vect_el_t, compressed_min_issue_delay_vect, 0);
}
output_vect (compressed_min_issue_delay_vect);
fprintf (output_file, "};\n\n");
- VEC_free (state_t,heap, output_states_vect);
- VEC_free (vect_el_t,heap, min_issue_delay_vect);
- VEC_free (vect_el_t,heap, compressed_min_issue_delay_vect);
+ VEC_free (state_t, heap, output_states_vect);
+ VEC_free (vect_el_t, heap, min_issue_delay_vect);
+ VEC_free (vect_el_t, heap, compressed_min_issue_delay_vect);
}
/* Form and output vector representing the locked states of
output_states_vect = 0;
pass_states (automaton, add_states_vect_el);
- VEC_safe_grow (vect_el_t,heap, dead_lock_vect,
+ VEC_safe_grow (vect_el_t, heap, dead_lock_vect,
VEC_length (state_t, output_states_vect));
for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
{
fprintf (output_file, "[] = {\n");
output_vect (dead_lock_vect);
fprintf (output_file, "};\n\n");
- VEC_free (state_t,heap, output_states_vect);
- VEC_free (vect_el_t,heap, dead_lock_vect);
+ VEC_free (state_t, heap, output_states_vect);
+ VEC_free (vect_el_t, heap, dead_lock_vect);
}
/* Form and output vector representing reserved units of the states of
reserved_units_size = (VEC_length (state_t, output_states_vect)
* state_byte_size);
- reserved_units_table = VEC_alloc (vect_el_t,heap, reserved_units_size);
-
+ reserved_units_table = VEC_alloc (vect_el_t, heap, reserved_units_size);
+
for (i = 0; i < reserved_units_size; i++)
VEC_quick_push (vect_el_t, reserved_units_table, 0);
for (n = 0; n < VEC_length (state_t, output_states_vect); n++)
fprintf (output_file, "};\n#endif /* #if %s */\n\n",
CPU_UNITS_QUERY_MACRO_NAME);
- VEC_free (state_t,heap, output_states_vect);
- VEC_free (vect_el_t,heap, reserved_units_table);
+ VEC_free (state_t, heap, output_states_vect);
+ VEC_free (vect_el_t, heap, reserved_units_table);
}
/* The function outputs all tables representing DFA(s) used for fast
{
automaton_t automaton;
- initiate_min_issue_delay_pass_states ();
for (automaton = description->first_automaton;
automaton != NULL;
automaton = automaton->next_automaton)
{
fprintf (output_file, ") / %d];\n",
automaton->min_issue_delay_table_compression_factor);
- fprintf (output_file, " %s = (%s >> (8 - (",
+ fprintf (output_file, " %s = (%s >> (8 - ((",
TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
output_translate_vect_name (output_file, automaton);
+ fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
+ fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
+ output_chip_member_name (output_file, automaton);
+ fprintf (output_file, " * %d)", automaton->insn_equiv_classes_num);
fprintf
- (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
- INTERNAL_INSN_CODE_NAME,
+ (output_file, " %% %d + 1) * %d)) & %d;\n",
automaton->min_issue_delay_table_compression_factor,
8 / automaton->min_issue_delay_table_compression_factor,
(1 << (8 / automaton->min_issue_delay_table_compression_factor))
{\n\
int i = %s;\n\
%s = 2 * uid;\n\
- %s = xrealloc (%s,\n\
- %s * sizeof(int));\n\
+ %s = XRESIZEVEC (int, %s,\n\
+ %s);\n\
for (; i < %s; i++)\n\
%s[i] = -1;\n}\n\n",
DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
INTERNAL_INSN_CODE_NAME, -1);
- fprintf (output_file, " return %s (%s, %s);\n}\n\n",
- INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
+ fprintf (output_file, " return %s (%s, (struct %s *) %s);\n}\n\n",
+ INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME, STATE_NAME);
}
/* Output function `min_issue_delay'. */
INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
fprintf (output_file, " }\n else\n %s = %s;\n",
INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
- fprintf (output_file, "\n return %s (%s, %s);\n",
+ fprintf (output_file, "\n return %s (%s, (struct %s *) %s);\n",
INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
- STATE_NAME);
+ CHIP_NAME, STATE_NAME);
fprintf (output_file, "}\n\n");
}
{
fprintf (output_file, "int\n%s (%s %s)\n",
DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
- fprintf (output_file, "{\n return %s (%s);\n}\n\n",
- INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
+ fprintf (output_file, "{\n return %s ((struct %s *) %s);\n}\n\n",
+ INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, STATE_NAME);
}
/* Output function `internal_reset'. */
{
fprintf (output_file, "void\n%s (%s %s)\n",
RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
- fprintf (output_file, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
- STATE_NAME);
+ fprintf (output_file, "{\n %s ((struct %s *) %s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
+ CHIP_NAME, STATE_NAME);
}
/* Output function `min_insn_conflict_delay'. */
fprintf (output_file, "}\n\n");
}
-/* Output function `internal_insn_latency'. */
+/* Output the array holding default latency values. These are used in
+ insn_latency and maximal_insn_latency function implementations. */
static void
-output_internal_insn_latency_func (void)
+output_default_latencies (void)
{
- decl_t decl;
- struct bypass_decl *bypass;
int i, j, col;
+ decl_t decl;
const char *tabletype = "unsigned char";
/* Find the smallest integer type that can hold all the default
tabletype = "int";
}
- fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
- INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
- INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
- INSN2_PARAMETER_NAME);
- fprintf (output_file, "{\n");
-
- if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
- {
- fputs (" return 0;\n}\n\n", output_file);
- return;
- }
-
fprintf (output_file, " static const %s default_latencies[] =\n {",
tabletype);
}
gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
fputs ("\n };\n", output_file);
+}
+
+/* Output function `internal_insn_latency'. */
+static void
+output_internal_insn_latency_func (void)
+{
+ int i;
+ decl_t decl;
+ struct bypass_decl *bypass;
+
+ fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
+ INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
+ INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
+ INSN2_PARAMETER_NAME);
+ fprintf (output_file, "{\n");
+
+ if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
+ {
+ fputs (" return 0;\n}\n\n", output_file);
+ return;
+ }
fprintf (output_file, " if (%s >= %s || %s >= %s)\n return 0;\n",
INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
(advance_cycle_insn_decl)->insn_num));
fprintf (output_file, " case %d:\n",
bypass->in_insn_reserv->insn_num);
- if (bypass->bypass_guard_name == NULL)
- fprintf (output_file, " return %d;\n",
- bypass->latency);
- else
+ for (;;)
{
- fprintf (output_file,
- " if (%s (%s, %s))\n",
- bypass->bypass_guard_name, INSN_PARAMETER_NAME,
- INSN2_PARAMETER_NAME);
- fprintf (output_file,
- " return %d;\n break;\n",
- bypass->latency);
+ if (bypass->bypass_guard_name == NULL)
+ {
+ gcc_assert (bypass->next == NULL
+ || (bypass->in_insn_reserv
+ != bypass->next->in_insn_reserv));
+ fprintf (output_file, " return %d;\n",
+ bypass->latency);
+ }
+ else
+ {
+ fprintf (output_file,
+ " if (%s (%s, %s))\n",
+ bypass->bypass_guard_name, INSN_PARAMETER_NAME,
+ INSN2_PARAMETER_NAME);
+ fprintf (output_file, " return %d;\n",
+ bypass->latency);
+ }
+ if (bypass->next == NULL
+ || bypass->in_insn_reserv != bypass->next->in_insn_reserv)
+ break;
+ bypass = bypass->next;
}
+ if (bypass->bypass_guard_name != NULL)
+ fprintf (output_file, " break;\n");
}
fputs (" }\n break;\n", output_file);
}
INTERNAL_INSN_CODE_NAME);
}
+/* Output function `internal_maximum_insn_latency'. */
+static void
+output_internal_maximal_insn_latency_func (void)
+{
+ decl_t decl;
+ struct bypass_decl *bypass;
+ int i;
+ int max;
+
+ fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
+ "internal_maximal_insn_latency", INTERNAL_INSN_CODE_NAME,
+ INSN_PARAMETER_NAME);
+ fprintf (output_file, "{\n");
+
+ if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
+ {
+ fputs (" return 0;\n}\n\n", output_file);
+ return;
+ }
+
+ fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
+ for (i = 0; i < description->decls_num; i++)
+ if (description->decls[i]->mode == dm_insn_reserv
+ && DECL_INSN_RESERV (description->decls[i])->bypass_list)
+ {
+ decl = description->decls [i];
+ max = DECL_INSN_RESERV (decl)->default_latency;
+ fprintf (output_file,
+ " case %d: {",
+ DECL_INSN_RESERV (decl)->insn_num);
+ for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
+ bypass != NULL;
+ bypass = bypass->next)
+ {
+ if (bypass->latency > max)
+ max = bypass->latency;
+ }
+ fprintf (output_file, " return %d; }\n break;\n", max);
+ }
+
+ fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n",
+ INTERNAL_INSN_CODE_NAME);
+}
+
/* The function outputs PHR interface function `insn_latency'. */
static void
output_insn_latency_func (void)
INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
}
+/* The function outputs PHR interface function `maximal_insn_latency'. */
+static void
+output_maximal_insn_latency_func (void)
+{
+ fprintf (output_file, "int\n%s (rtx %s)\n",
+ "maximal_insn_latency", INSN_PARAMETER_NAME);
+ fprintf (output_file, "{\n int %s;\n",
+ INTERNAL_INSN_CODE_NAME);
+ output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
+ INTERNAL_INSN_CODE_NAME, 0);
+ fprintf (output_file, " return %s (%s, %s);\n}\n\n",
+ "internal_maximal_insn_latency",
+ INTERNAL_INSN_CODE_NAME, INSN_PARAMETER_NAME);
+}
+
/* The function outputs PHR interface function `print_reservation'. */
static void
output_print_reservation_func (void)
{
gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num);
j++;
-
+
fprintf (output_file, "\n \"%s\",",
regexp_representation (DECL_INSN_RESERV (decl)->regexp));
finish_regexp_representation ();
LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
fprintf (output_file, " static struct %s %s [] =\n {\n",
NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
- units = xmalloc (sizeof (unit_decl_t) * description->units_num);
+ units = XNEWVEC (unit_decl_t, description->units_num);
memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
for (i = 0; i < description->units_num; i++)
fprintf (output_file, " return 0;\n}\n\n");
}
+/* The following function outputs a function to check if insn
+ has a dfa reservation. */
+static void
+output_insn_has_dfa_reservation_p (void)
+{
+ fprintf (output_file,
+ "bool\n%s (rtx %s ATTRIBUTE_UNUSED)\n{\n",
+ INSN_HAS_DFA_RESERVATION_P_FUNC_NAME,
+ INSN_PARAMETER_NAME);
+
+ if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
+ {
+ fprintf (output_file, " return false;\n}\n\n");
+ return;
+ }
+
+ fprintf (output_file, " int %s;\n\n", INTERNAL_INSN_CODE_NAME);
+
+ fprintf (output_file, " if (%s == 0)\n %s = %s;\n",
+ INSN_PARAMETER_NAME,
+ INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
+ fprintf (output_file, " else\n\
+ {\n\
+ %s = %s (%s);\n\
+ if (%s > %s)\n\
+ %s = %s;\n\
+ }\n\n",
+ INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
+ INSN_PARAMETER_NAME,
+ INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
+ INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
+
+ fprintf (output_file, " return %s != %s;\n}\n\n",
+ INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
+}
+
/* The function outputs PHR interface functions `dfa_clean_insn_cache'
and 'dfa_clear_single_insn_cache'. */
static void
fprintf (output_file,
"void\n%s (void)\n{\n %s = get_max_uid ();\n",
DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
- fprintf (output_file, " %s = xmalloc (%s * sizeof (int));\n",
+ fprintf (output_file, " %s = XNEWVEC (int, %s);\n",
DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
fprintf (output_file, " %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);
}
{
if (DECL_UNIT (decl)->excl_list != NULL)
{
- fprintf (output_description_file, "unit %s exlusion_set: ",
+ fprintf (output_description_file, "unit %s exclusion_set: ",
DECL_UNIT (decl)->name);
output_unit_set_el_list (DECL_UNIT (decl)->excl_list);
fprintf (output_description_file, "\n");
/* The following variable is used for forming array of all possible cpu unit
reservations described by the current DFA state. */
-static VEC(reserv_sets_t,heap) *state_reservs;
+static VEC(reserv_sets_t, heap) *state_reservs;
/* The function forms `state_reservs' for STATE. */
static void
curr_alt_state = curr_alt_state->next_sorted_alt_state)
add_state_reservs (curr_alt_state->state);
else
- VEC_safe_push (reserv_sets_t,heap, state_reservs, state->reservs);
+ VEC_safe_push (reserv_sets_t, heap, state_reservs, state->reservs);
}
/* The function outputs readable representation of all out arcs of
fprintf (output_description_file,
state->new_cycle_p ? " (new cycle)\n" : "\n");
add_state_reservs (state);
- qsort (VEC_address (reserv_sets_t, state_reservs),
- VEC_length (reserv_sets_t, state_reservs),
- sizeof (reserv_sets_t), state_reservs_cmp);
+ VEC_qsort (reserv_sets_t, state_reservs, state_reservs_cmp);
remove_state_duplicate_reservs ();
- for (i = 1; i < VEC_length (reserv_sets_t, state_reservs); i++)
+ for (i = 0; i < VEC_length (reserv_sets_t, state_reservs); i++)
{
fprintf (output_description_file, " ");
output_reserv_sets (output_description_file,
}
fprintf (output_description_file, "\n");
output_state_arcs (state);
- VEC_free (reserv_sets_t,heap, state_reservs);
+ VEC_free (reserv_sets_t, heap, state_reservs);
}
/* The following function output readable representation of
automaton->corresponding_automaton_decl->name,
reserv_ainsn->insn_reserv_decl->name);
else
- warning
- (0, "Automaton `%s': Insn `%s' will never be issued",
- automaton->corresponding_automaton_decl->name,
- reserv_ainsn->insn_reserv_decl->name);
+ warning ("Automaton `%s': Insn `%s' will never be issued",
+ automaton->corresponding_automaton_decl->name,
+ reserv_ainsn->insn_reserv_decl->name);
}
else
{
error ("Insn `%s' will never be issued",
reserv_ainsn->insn_reserv_decl->name);
else
- warning (0, "Insn `%s' will never be issued",
+ warning ("Insn `%s' will never be issued",
reserv_ainsn->insn_reserv_decl->name);
}
}
/* The following vla is used for storing pointers to all achieved
states. */
-static VEC(state_t,heap) *automaton_states;
+static VEC(state_t, heap) *automaton_states;
/* This function is called by function pass_states to add an achieved
STATE. */
static void
add_automaton_state (state_t state)
{
- VEC_safe_push (state_t,heap, automaton_states, state);
+ VEC_safe_push (state_t, heap, automaton_states, state);
}
/* The following function forms list of important automata (whose
}
}
}
- VEC_free (state_t,heap, automaton_states);
+ VEC_free (state_t, heap, automaton_states);
/* Create automata sets for the insns. */
for (i = 0; i < description->decls_num; i++)
{
int i;
- description = create_node (sizeof (struct description)
- /* One entry for cycle advancing insn. */
- + sizeof (decl_t) * VEC_length (decl_t, decls));
+ description = XCREATENODEVAR (struct description,
+ sizeof (struct description)
+ /* One entry for cycle advancing insn. */
+ + sizeof (decl_t) * VEC_length (decl_t, decls));
description->decls_num = VEC_length (decl_t, decls);
description->query_units_num = 0;
for (i = 0; i < description->decls_num; i++)
output_internal_reset_func ();
output_reset_func ();
output_min_insn_conflict_delay_func ();
+ output_default_latencies ();
output_internal_insn_latency_func ();
output_insn_latency_func ();
+ output_internal_maximal_insn_latency_func ();
+ output_maximal_insn_latency_func ();
output_print_reservation_func ();
/* Output function get_cpu_unit_code. */
fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
output_get_cpu_unit_code_func ();
output_cpu_unit_reservation_p ();
+ output_insn_has_dfa_reservation_p ();
fprintf (output_file, "\n#endif /* #if %s */\n\n",
CPU_UNITS_QUERY_MACRO_NAME);
output_dfa_clean_insn_cache_func ();
progname = "genautomata";
- if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
+ if (!init_rtx_reader_args (argc, argv))
return (FATAL_EXIT_CODE);
initiate_automaton_gen (argc, argv);
if (have_error)
return FATAL_EXIT_CODE;
- puts ("/* Generated automatically by the program `genautomata'\n"
- " from the machine description file `md'. */\n\n"
- "#include \"config.h\"\n"
- "#include \"system.h\"\n"
- "#include \"coretypes.h\"\n"
- "#include \"tm.h\"\n"
- "#include \"rtl.h\"\n"
- "#include \"tm_p.h\"\n"
- "#include \"insn-config.h\"\n"
- "#include \"recog.h\"\n"
- "#include \"regs.h\"\n"
- "#include \"real.h\"\n"
- "#include \"output.h\"\n"
- "#include \"insn-attr.h\"\n"
- "#include \"toplev.h\"\n"
- "#include \"flags.h\"\n"
- "#include \"function.h\"\n");
-
if (VEC_length (decl_t, decls) > 0)
{
expand_automata ();
- write_automata ();
+ if (!have_error)
+ {
+ puts ("/* Generated automatically by the program `genautomata'\n"
+ " from the machine description file `md'. */\n\n"
+ "#include \"config.h\"\n"
+ "#include \"system.h\"\n"
+ "#include \"coretypes.h\"\n"
+ "#include \"tm.h\"\n"
+ "#include \"rtl.h\"\n"
+ "#include \"tm_p.h\"\n"
+ "#include \"insn-config.h\"\n"
+ "#include \"recog.h\"\n"
+ "#include \"regs.h\"\n"
+ "#include \"output.h\"\n"
+ "#include \"insn-attr.h\"\n"
+ "#include \"diagnostic-core.h\"\n"
+ "#include \"flags.h\"\n"
+ "#include \"function.h\"\n"
+ "#include \"emit-rtl.h\"\n");
+ /* FIXME: emit-rtl.h can go away once crtl is in rtl.h. */
+
+ write_automata ();
+ }
+ }
+ else
+ {
+ puts ("/* Generated automatically by the program `genautomata'\n"
+ " from the machine description file `md'. */\n\n"
+ "/* There is no automaton, but ISO C forbids empty\n"
+ " translation units, so include a header file with some\n"
+ " declarations, and its pre-requisite header file. */\n"
+ "#include \"config.h\"\n"
+ "#include \"system.h\"\n");
}
fflush (stdout);
- return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
+ return (ferror (stdout) != 0 || have_error
+ ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
}