/* Pipeline hazard description translator.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
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:
#include "rtl.h"
#include "obstack.h"
#include "errors.h"
+#include "gensupport.h"
#include <math.h>
#include "hashtab.h"
-#include "varray.h"
#include "vec.h"
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
-#include "genattrtab.h"
-
/* Positions in machine description file. Now they are not used. But
they could be used in the future for better diagnostic messages. */
typedef int pos_t;
/* Reservations of function units are represented by value of the following
type. */
typedef set_el_t *reserv_sets_t;
+typedef const set_el_t *const_reserv_sets_t;
/* The following structure describes a ticker. */
struct ticker
/* The following typedefs are for brevity. */
typedef struct unit_decl *unit_decl_t;
+typedef const struct unit_decl *const_unit_decl_t;
typedef struct decl *decl_t;
+typedef const struct decl *const_decl_t;
typedef struct regexp *regexp_t;
typedef struct unit_set_el *unit_set_el_t;
typedef struct pattern_set_el *pattern_set_el_t;
typedef struct pattern_reserv *pattern_reserv_t;
typedef struct alt_state *alt_state_t;
typedef struct state *state_t;
+typedef const struct state *const_state_t;
typedef struct arc *arc_t;
typedef struct ainsn *ainsn_t;
typedef struct automaton *automaton_t;
typedef struct automata_list_el *automata_list_el_t;
+typedef const struct automata_list_el *const_automata_list_el_t;
typedef struct state_ainsn_table *state_ainsn_table_t;
-
-/* Prototypes of functions gen_cpu_unit, gen_query_cpu_unit,
- gen_bypass, gen_excl_set, gen_presence_set, gen_final_presence_set,
- gen_absence_set, gen_final_absence_set, gen_automaton,
- gen_automata_option, gen_reserv, gen_insn_reserv,
- initiate_automaton_gen, expand_automata, write_automata are
- described on the file top because the functions are called from
- function `main'. */
-
-static void *create_node (size_t);
-static void *copy_node (const void *, size_t);
-static const char *check_name (const char *, pos_t);
-static char *next_sep_el (const char **, int, int);
-static int n_sep_els (const char *, int, int);
-static char **get_str_vect (const char *, int *, int, int);
-static void gen_presence_absence_set (rtx, int, int);
-static regexp_t gen_regexp_el (const char *);
-static regexp_t gen_regexp_repeat (const char *);
-static regexp_t gen_regexp_allof (const char *);
-static regexp_t gen_regexp_oneof (const char *);
-static regexp_t gen_regexp_sequence (const char *);
-static regexp_t gen_regexp (const char *);
-
-static unsigned string_hash (const char *);
-static unsigned automaton_decl_hash (const void *);
-static int automaton_decl_eq_p (const void *,
- const void *);
-static decl_t insert_automaton_decl (decl_t);
-static decl_t find_automaton_decl (const char *);
-static void initiate_automaton_decl_table (void);
-static void finish_automaton_decl_table (void);
-
-static hashval_t insn_decl_hash (const void *);
-static int insn_decl_eq_p (const void *,
- const void *);
-static decl_t insert_insn_decl (decl_t);
-static decl_t find_insn_decl (const char *);
-static void initiate_insn_decl_table (void);
-static void finish_insn_decl_table (void);
-
-static hashval_t decl_hash (const void *);
-static int decl_eq_p (const void *,
- const void *);
-static decl_t insert_decl (decl_t);
-static decl_t find_decl (const char *);
-static void initiate_decl_table (void);
-static void finish_decl_table (void);
-
-static unit_set_el_t process_excls (char **, int, pos_t);
-static void add_excls (unit_set_el_t, unit_set_el_t,
- pos_t);
-static unit_set_el_t process_presence_absence_names
- (char **, int, pos_t,
- int, int);
-static pattern_set_el_t process_presence_absence_patterns
- (char ***, int, pos_t,
- int, int);
-static void add_presence_absence (unit_set_el_t,
- pattern_set_el_t,
- pos_t, int, int);
-static void process_decls (void);
-static struct bypass_decl *find_bypass (struct bypass_decl *,
- struct insn_reserv_decl *);
-static void check_automaton_usage (void);
-static regexp_t process_regexp (regexp_t);
-static void process_regexp_decls (void);
-static void check_usage (void);
-static int loop_in_regexp (regexp_t, decl_t);
-static void check_loops_in_regexps (void);
-static void process_regexp_cycles (regexp_t, int, int,
- int *, int *);
-static void evaluate_max_reserv_cycles (void);
-static void check_all_description (void);
-
-static ticker_t create_ticker (void);
-static void ticker_off (ticker_t *);
-static void ticker_on (ticker_t *);
-static int active_time (ticker_t);
-static void print_active_time (FILE *, ticker_t);
-
-static void add_advance_cycle_insn_decl (void);
-
-static alt_state_t get_free_alt_state (void);
-static void free_alt_state (alt_state_t);
-static void free_alt_states (alt_state_t);
-static int alt_state_cmp (const void *alt_state_ptr_1,
- const void *alt_state_ptr_2);
-static alt_state_t uniq_sort_alt_states (alt_state_t);
-static int alt_states_eq (alt_state_t, alt_state_t);
-static void initiate_alt_states (void);
-static void finish_alt_states (void);
-
-static reserv_sets_t alloc_empty_reserv_sets (void);
-static unsigned reserv_sets_hash_value (reserv_sets_t);
-static int reserv_sets_cmp (reserv_sets_t, reserv_sets_t);
-static int reserv_sets_eq (reserv_sets_t, reserv_sets_t);
-static void set_unit_reserv (reserv_sets_t, int, int);
-static int test_unit_reserv (reserv_sets_t, int, int);
-static int it_is_empty_reserv_sets (reserv_sets_t)
- ATTRIBUTE_UNUSED;
-static int reserv_sets_are_intersected (reserv_sets_t, reserv_sets_t);
-static void reserv_sets_shift (reserv_sets_t, reserv_sets_t);
-static void reserv_sets_or (reserv_sets_t, reserv_sets_t,
- reserv_sets_t);
-static void reserv_sets_and (reserv_sets_t, reserv_sets_t,
- reserv_sets_t)
- ATTRIBUTE_UNUSED;
-static void output_cycle_reservs (FILE *, reserv_sets_t,
- int, int);
-static void output_reserv_sets (FILE *, reserv_sets_t);
-static state_t get_free_state (int, automaton_t);
-static void free_state (state_t);
-static hashval_t state_hash (const void *);
-static int state_eq_p (const void *, const void *);
-static state_t insert_state (state_t);
-static void set_state_reserv (state_t, int, int);
-static int intersected_state_reservs_p (state_t, state_t);
-static state_t states_union (state_t, state_t, reserv_sets_t);
-static state_t state_shift (state_t, reserv_sets_t);
-static void initiate_states (void);
-static void finish_states (void);
-
-static void free_arc (arc_t);
-static void remove_arc (state_t, arc_t);
-static arc_t find_arc (state_t, state_t, ainsn_t);
-static arc_t add_arc (state_t, state_t, ainsn_t, int);
-static arc_t first_out_arc (state_t);
-static arc_t next_out_arc (arc_t);
-static void initiate_arcs (void);
-static void finish_arcs (void);
-
-static automata_list_el_t get_free_automata_list_el (void);
-static void free_automata_list_el (automata_list_el_t);
-static void free_automata_list (automata_list_el_t);
-static hashval_t automata_list_hash (const void *);
-static int automata_list_eq_p (const void *, const void *);
-static void initiate_automata_lists (void);
-static void automata_list_start (void);
-static void automata_list_add (automaton_t);
-static automata_list_el_t automata_list_finish (void);
-static void finish_automata_lists (void);
-
-static void initiate_excl_sets (void);
-static reserv_sets_t get_excl_set (reserv_sets_t);
-
-static pattern_reserv_t form_reserv_sets_list (pattern_set_el_t);
-static void initiate_presence_absence_pattern_sets (void);
-static int check_presence_pattern_sets (reserv_sets_t,
- reserv_sets_t, int);
-static int check_absence_pattern_sets (reserv_sets_t, reserv_sets_t,
- int);
-
-static regexp_t copy_insn_regexp (regexp_t);
-static regexp_t transform_1 (regexp_t);
-static regexp_t transform_2 (regexp_t);
-static regexp_t transform_3 (regexp_t);
-static regexp_t regexp_transform_func
- (regexp_t, regexp_t (*) (regexp_t));
-static regexp_t transform_regexp (regexp_t);
-static void transform_insn_regexps (void);
-
-static void store_alt_unit_usage (regexp_t, regexp_t, int, int);
-static void check_regexp_units_distribution (const char *, regexp_t);
-static void check_unit_distributions_to_automata (void);
-
-static int process_seq_for_forming_states (regexp_t, automaton_t,
- int);
-static void finish_forming_alt_state (alt_state_t,
- automaton_t);
-static void process_alts_for_forming_states (regexp_t,
- automaton_t, int);
-static void create_alt_states (automaton_t);
-
-static void form_ainsn_with_same_reservs (automaton_t);
-
-static reserv_sets_t form_reservs_matter (automaton_t);
-static void make_automaton (automaton_t);
-static void form_arcs_marked_by_insn (state_t);
-static void NDFA_to_DFA (automaton_t);
-static void pass_state_graph (state_t, void (*) (state_t));
-static void pass_states (automaton_t,
- void (*) (state_t));
-static void initiate_pass_states (void);
-static void add_achieved_state (state_t);
-static int set_out_arc_insns_equiv_num (state_t, int);
-static void clear_arc_insns_equiv_num (state_t);
-static int first_cycle_unit_presence (state_t, int);
-static int state_is_differed (state_t, state_t, int, int);
-static void set_new_cycle_flags (state_t);
-static void minimize_DFA (automaton_t);
-static void incr_states_and_arcs_nums (state_t);
-static void count_states_and_arcs (automaton_t, int *, int *);
-static void build_automaton (automaton_t);
-
-static void set_order_state_num (state_t);
-static void enumerate_states (automaton_t);
-
-static ainsn_t insert_ainsn_into_equiv_class (ainsn_t, ainsn_t);
-static void delete_ainsn_from_equiv_class (ainsn_t);
-static void process_insn_equiv_class (ainsn_t, arc_t *);
-static void process_state_for_insn_equiv_partition (state_t);
-static void set_insn_equiv_classes (automaton_t);
-
-static double estimate_one_automaton_bound (void);
-static int compare_max_occ_cycle_nums (const void *,
- const void *);
-static void units_to_automata_heuristic_distr (void);
-static ainsn_t create_ainsns (void);
-static void units_to_automata_distr (void);
-static void create_automata (void);
-
-static void form_regexp (regexp_t);
-static const char *regexp_representation (regexp_t);
-static void finish_regexp_representation (void);
-
-static void output_range_type (FILE *, long int, long int);
-static int longest_path_length (state_t);
-static void output_chip_member_name (FILE *, automaton_t);
-static void output_temp_chip_member_name (FILE *, automaton_t);
-static void output_translate_vect_name (FILE *, automaton_t);
-static void output_trans_full_vect_name (FILE *, automaton_t);
-static void output_trans_comb_vect_name (FILE *, automaton_t);
-static void output_trans_check_vect_name (FILE *, automaton_t);
-static void output_trans_base_vect_name (FILE *, automaton_t);
-static void output_state_alts_full_vect_name (FILE *, automaton_t);
-static void output_state_alts_comb_vect_name (FILE *, automaton_t);
-static void output_state_alts_check_vect_name (FILE *, automaton_t);
-static void output_state_alts_base_vect_name (FILE *, automaton_t);
-static void output_min_issue_delay_vect_name (FILE *, automaton_t);
-static void output_dead_lock_vect_name (FILE *, automaton_t);
-static void output_reserved_units_table_name (FILE *, automaton_t);
-static void output_state_member_type (FILE *, automaton_t);
-static void output_chip_definitions (void);
-static void output_translate_vect (automaton_t);
-static int comb_vect_p (state_ainsn_table_t);
-static state_ainsn_table_t create_state_ainsn_table (automaton_t);
-static void output_state_ainsn_table
- (state_ainsn_table_t, const char *, void (*) (FILE *, automaton_t),
- void (*) (FILE *, automaton_t), void (*) (FILE *, automaton_t),
- void (*) (FILE *, automaton_t));
-static int out_state_arcs_num (state_t);
-static int compare_transition_els_num (const void *, const void *);
-static void add_states_vect_el (state_t);
-static void output_trans_table (automaton_t);
-static void output_state_alts_table (automaton_t);
-static int min_issue_delay_pass_states (state_t, ainsn_t);
-static int min_issue_delay (state_t, ainsn_t);
-static void initiate_min_issue_delay_pass_states (void);
-static void output_min_issue_delay_table (automaton_t);
-static void output_dead_lock_vect (automaton_t);
-static void output_reserved_units_table (automaton_t);
-static void output_tables (void);
-static void output_max_insn_queue_index_def (void);
-static void output_insn_code_cases (void (*) (automata_list_el_t));
-static void output_automata_list_min_issue_delay_code (automata_list_el_t);
-static void output_internal_min_issue_delay_func (void);
-static void output_automata_list_transition_code (automata_list_el_t);
-static void output_internal_trans_func (void);
-static void output_internal_insn_code_evaluation (const char *,
- const char *, int);
-static void output_dfa_insn_code_func (void);
-static void output_trans_func (void);
-static void output_automata_list_state_alts_code (automata_list_el_t);
-static void output_internal_state_alts_func (void);
-static void output_state_alts_func (void);
-static void output_min_issue_delay_func (void);
-static void output_internal_dead_lock_func (void);
-static void output_dead_lock_func (void);
-static void output_internal_reset_func (void);
-static void output_size_func (void);
-static void output_reset_func (void);
-static void output_min_insn_conflict_delay_func (void);
-static void output_internal_insn_latency_func (void);
-static void output_insn_latency_func (void);
-static void output_print_reservation_func (void);
-static int units_cmp (const void *,
- const void *);
-static void output_get_cpu_unit_code_func (void);
-static void output_cpu_unit_reservation_p (void);
-static void output_dfa_clean_insn_cache_func (void);
-static void output_dfa_start_func (void);
-static void output_dfa_finish_func (void);
-
-static void output_regexp (regexp_t );
-static void output_unit_set_el_list (unit_set_el_t);
-static void output_pattern_set_el_list (pattern_set_el_t);
-static void output_description (void);
-static void output_automaton_name (FILE *, automaton_t);
-static void output_automaton_units (automaton_t);
-static void add_state_reservs (state_t);
-static void output_state_arcs (state_t);
-static int state_reservs_cmp (const void *,
- const void *);
-static void remove_state_duplicate_reservs (void);
-static void output_state (state_t);
-static void output_automaton_descriptions (void);
-static void output_statistics (FILE *);
-static void output_time_statistics (FILE *);
-static void generate (void);
-
-static void make_insn_alts_attr (void);
-static void make_internal_dfa_insn_code_attr (void);
-static void make_default_insn_latency_attr (void);
-static void make_bypass_attr (void);
-static const char *file_name_suffix (const char *);
-static const char *base_file_name (const char *);
-static void check_automata_insn_issues (void);
-static void add_automaton_state (state_t);
-static void form_important_insn_automata_lists (void);
-
/* Undefined position. */
static pos_t no_pos = 0;
DEF_VEC_ALLOC_I(vect_el_t, heap);
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 *);
+static void reserv_sets_or (reserv_sets_t, reserv_sets_t,
+ reserv_sets_t);
+static reserv_sets_t get_excl_set (reserv_sets_t);
+static int check_presence_pattern_sets (reserv_sets_t,
+ reserv_sets_t, int);
+static int check_absence_pattern_sets (reserv_sets_t, reserv_sets_t,
+ int);
+static arc_t first_out_arc (const_state_t);
+static arc_t next_out_arc (arc_t);
+
+\f
/* Options with the following names can be set up in automata_option
construction. Because the strings occur more one time we use the
macros. */
#define NO_MINIMIZATION_OPTION "-no-minimization"
-
#define TIME_OPTION "-time"
-
+#define STATS_OPTION "-stats"
#define V_OPTION "-v"
-
#define W_OPTION "-w"
-
#define NDFA_OPTION "-ndfa"
-
#define PROGRESS_OPTION "-progress"
/* The following flags are set up by function `initiate_automaton_gen'. */
/* Flag of output time statistics (`-time'). */
static int time_flag;
+/* Flag of automata statistics (`-stats'). */
+static int stats_flag;
+
/* Flag of creation of description file which contains description of
result automaton and statistics information (`-v'). */
static int v_flag;
/* 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;
which arc marked by given insn enters from a state (fixed during
an automaton minimization). */
int equiv_class_num;
- /* The field value is state_alts of arc leaving a state (fixed
- during an automaton minimization) and marked by given insn
- enters. */
- int state_alts;
/* The following member value is the list to automata which can be
changed by the insn issue. */
automata_list_el_t important_automata_list;
/* The following field value is the first arc output from given
state. */
arc_t first_out_arc;
+ unsigned int num_out_arcs;
/* The following field is used to form NDFA. */
char it_was_placed_in_stack_for_NDFA_forming;
/* The following field is used to form DFA. */
automaton. The field value is state corresponding to equivalence
class to which given state belongs. */
state_t equiv_class_state;
+ unsigned int *presence_signature;
/* The following field value is the order number of given state.
The states in final DFA is enumerated with the aid of the
following field. */
/* The following member is used to evaluate min issue delay of insn
for a state. */
int min_insn_issue_delay;
- /* The following member is used to evaluate max issue rate of the
- processor. The value of the member is maximal length of the path
- from given state no containing arcs marked by special insn `cycle
- advancing'. */
- int longest_path_length;
};
-/* The following macro is an initial value of member
- `longest_path_length' of a state. */
-#define UNDEFINED_LONGEST_PATH_LENGTH -1
-
/* Automaton arc. */
struct arc
{
/* List of arcs marked given insn is formed with the following
field. The field is used in transformation NDFA -> DFA. */
arc_t next_arc_marked_by_insn;
- /* The following field is defined if NDFA_FLAG is zero. The member
- value is number of alternative reservations which can be used for
- transition for given state by given insn. */
- int state_alts;
};
/* The following node type describes a deterministic alternative in
/* The following field value is defined only if minimization of DFA
is used. */
int minimal_DFA_arcs_num;
- /* The following two members refer for two table state x ainsn ->
- int. */
+ /* The following member refers for two table state x ainsn -> int.
+ ??? Above sentence is incomprehensible. */
state_ainsn_table_t trans_table;
- state_ainsn_table_t state_alts_table;
/* The following member value is maximal value of min issue delay
for insns of the automaton. */
int max_min_delay;
#if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
#define DECL_UNIT(d) __extension__ \
-(({ struct decl *const _decl = (d); \
+(({ __typeof (d) const _decl = (d); \
if (_decl->mode != dm_unit) \
decl_mode_check_failed (_decl->mode, "dm_unit", \
__FILE__, __LINE__, __FUNCTION__); \
&(_decl)->decl.unit; }))
#define DECL_BYPASS(d) __extension__ \
-(({ struct decl *const _decl = (d); \
+(({ __typeof (d) const _decl = (d); \
if (_decl->mode != dm_bypass) \
decl_mode_check_failed (_decl->mode, "dm_bypass", \
__FILE__, __LINE__, __FUNCTION__); \
&(_decl)->decl.bypass; }))
#define DECL_AUTOMATON(d) __extension__ \
-(({ struct decl *const _decl = (d); \
+(({ __typeof (d) const _decl = (d); \
if (_decl->mode != dm_automaton) \
decl_mode_check_failed (_decl->mode, "dm_automaton", \
__FILE__, __LINE__, __FUNCTION__); \
&(_decl)->decl.automaton; }))
#define DECL_EXCL(d) __extension__ \
-(({ struct decl *const _decl = (d); \
+(({ __typeof (d) const _decl = (d); \
if (_decl->mode != dm_excl) \
decl_mode_check_failed (_decl->mode, "dm_excl", \
__FILE__, __LINE__, __FUNCTION__); \
&(_decl)->decl.excl; }))
#define DECL_PRESENCE(d) __extension__ \
-(({ struct decl *const _decl = (d); \
+(({ __typeof (d) const _decl = (d); \
if (_decl->mode != dm_presence) \
decl_mode_check_failed (_decl->mode, "dm_presence", \
__FILE__, __LINE__, __FUNCTION__); \
&(_decl)->decl.presence; }))
#define DECL_ABSENCE(d) __extension__ \
-(({ struct decl *const _decl = (d); \
+(({ __typeof (d) const _decl = (d); \
if (_decl->mode != dm_absence) \
decl_mode_check_failed (_decl->mode, "dm_absence", \
__FILE__, __LINE__, __FUNCTION__); \
&(_decl)->decl.absence; }))
#define DECL_RESERV(d) __extension__ \
-(({ struct decl *const _decl = (d); \
+(({ __typeof (d) const _decl = (d); \
if (_decl->mode != dm_reserv) \
decl_mode_check_failed (_decl->mode, "dm_reserv", \
__FILE__, __LINE__, __FUNCTION__); \
&(_decl)->decl.reserv; }))
#define DECL_INSN_RESERV(d) __extension__ \
-(({ struct decl *const _decl = (d); \
+(({ __typeof (d) const _decl = (d); \
if (_decl->mode != dm_insn_reserv) \
decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
__FILE__, __LINE__, __FUNCTION__); \
#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)
This gives information about a unit contained in CPU. We fill a
struct unit_decl with information used later by `expand_automata'. */
-void
+static void
gen_cpu_unit (rtx def)
{
decl_t decl;
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)->min_occ_cycle_num = -1;
DECL_UNIT (decl)->in_set_p = 0;
VEC_safe_push (decl_t,heap, decls, decl);
- num_dfa_decls++;
}
}
This gives information about a unit contained in CPU. We fill a
struct unit_decl with information used later by `expand_automata'. */
-void
+static void
gen_query_cpu_unit (rtx def)
{
decl_t 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);
- num_dfa_decls++;
}
}
This gives information about a unit contained in the CPU. We fill
in a struct bypass_decl with information used later by
`expand_automata'. */
-void
+static void
gen_bypass (rtx def)
{
decl_t 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)->in_insn_name = in_insns [j];
DECL_BYPASS (decl)->bypass_guard_name = XSTR (def, 3);
VEC_safe_push (decl_t,heap, decls, decl);
- num_dfa_decls++;
}
}
This gives information about a cpu unit conflicts. We fill a
struct excl_rel_decl (excl) with information used later by
`expand_automata'. */
-void
+static void
gen_excl_set (rtx def)
{
decl_t 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;
DECL_EXCL (decl)->names [i]
= second_str_cpu_units [i - first_vect_length];
VEC_safe_push (decl_t,heap, decls, decl);
- num_dfa_decls++;
}
/* 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)->final_p = final_p;
}
VEC_safe_push (decl_t,heap, decls, decl);
- num_dfa_decls++;
}
/* Process a PRESENCE_SET.
This gives information about a cpu unit reservation requirements.
We fill a struct unit_pattern_rel_decl (presence) with information
used later by `expand_automata'. */
-void
+static void
gen_presence_set (rtx def)
{
gen_presence_absence_set (def, TRUE, FALSE);
This gives information about a cpu unit reservation requirements.
We fill a struct unit_pattern_rel_decl (presence) with information
used later by `expand_automata'. */
-void
+static void
gen_final_presence_set (rtx def)
{
gen_presence_absence_set (def, TRUE, TRUE);
This gives information about a cpu unit reservation requirements.
We fill a struct unit_pattern_rel_decl (absence) with information
used later by `expand_automata'. */
-void
+static void
gen_absence_set (rtx def)
{
gen_presence_absence_set (def, FALSE, FALSE);
This gives information about a cpu unit reservation requirements.
We fill a struct unit_pattern_rel_decl (absence) with information
used later by `expand_automata'. */
-void
+static void
gen_final_absence_set (rtx def)
{
gen_presence_absence_set (def, FALSE, TRUE);
This gives information about a finite state automaton used for
recognizing pipeline hazards. We fill a struct automaton_decl
with information used later by `expand_automata'. */
-void
+static void
gen_automaton (rtx def)
{
decl_t decl;
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);
- num_dfa_decls++;
}
}
This gives information how to generate finite state automaton used
for recognizing pipeline hazards. */
-void
+static void
gen_automata_option (rtx def)
{
if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
no_minimization_flag = 1;
else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
time_flag = 1;
+ else if (strcmp (XSTR (def, 0), STATS_OPTION + 1) == 0)
+ stats_flag = 1;
else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
v_flag = 1;
else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
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 (struct decl));
+ regexp = XCREATENODE (struct regexp);
regexp->mode = rm_nothing;
}
else
{
- regexp = create_node (sizeof (struct decl));
+ 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]);
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++)
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++)
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++)
This gives information about a reservation of cpu units. We fill
in a struct reserv_decl with information used later by
`expand_automata'. */
-void
+static void
gen_reserv (rtx def)
{
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);
- num_dfa_decls++;
}
/* Process a DEFINE_INSN_RESERVATION.
This gives information about the reservation of cpu units by an
insn. We fill a struct insn_reserv_decl with information used
later by `expand_automata'. */
-void
+static void
gen_insn_reserv (rtx def)
{
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)->condexp = XEXP (def, 2);
DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3));
VEC_safe_push (decl_t,heap, decls, decl);
- num_dfa_decls++;
}
\f
static hashval_t
automaton_decl_hash (const void *automaton_decl)
{
- const decl_t decl = (decl_t) automaton_decl;
+ const_decl_t const decl = (const_decl_t) automaton_decl;
gcc_assert (decl->mode != dm_automaton
|| DECL_AUTOMATON (decl)->name);
automaton_decl_eq_p (const void* automaton_decl_1,
const void* automaton_decl_2)
{
- const decl_t decl1 = (decl_t) automaton_decl_1;
- const decl_t decl2 = (decl_t) automaton_decl_2;
+ const_decl_t const decl1 = (const_decl_t) automaton_decl_1;
+ const_decl_t const decl2 = (const_decl_t) automaton_decl_2;
gcc_assert (decl1->mode == dm_automaton
&& DECL_AUTOMATON (decl1)->name
static hashval_t
insn_decl_hash (const void *insn_decl)
{
- const decl_t decl = (decl_t) insn_decl;
+ const_decl_t const decl = (const_decl_t) insn_decl;
gcc_assert (decl->mode == dm_insn_reserv
&& DECL_INSN_RESERV (decl)->name);
static int
insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2)
{
- const decl_t decl1 = (decl_t) insn_decl_1;
- const decl_t decl2 = (decl_t) insn_decl_2;
+ const_decl_t const decl1 = (const_decl_t) insn_decl_1;
+ const_decl_t const decl2 = (const_decl_t) insn_decl_2;
gcc_assert (decl1->mode == dm_insn_reserv
&& DECL_INSN_RESERV (decl1)->name
static hashval_t
decl_hash (const void *decl)
{
- const decl_t d = (const decl_t) decl;
+ const_decl_t const d = (const_decl_t) decl;
gcc_assert ((d->mode == dm_unit && DECL_UNIT (d)->name)
|| (d->mode == dm_reserv && DECL_RESERV (d)->name));
static int
decl_eq_p (const void *decl_1, const void *decl_2)
{
- const decl_t d1 = (const decl_t) decl_1;
- const decl_t d2 = (const decl_t) decl_2;
+ const_decl_t const d1 = (const_decl_t) decl_1;
+ const_decl_t const d2 = (const_decl_t) decl_2;
gcc_assert ((d1->mode == dm_unit && DECL_UNIT (d1)->name)
|| (d1->mode == dm_reserv && DECL_RESERV (d1)->name));
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));
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)
{
decl = description->decls [i];
if (decl->mode == dm_insn_reserv)
{
- DECL_INSN_RESERV (decl)->condexp
- = check_attr_test (DECL_INSN_RESERV (decl)->condexp, 0, 0);
if (DECL_INSN_RESERV (decl)->default_latency < 0)
error ("define_insn_reservation `%s' has negative latency time",
DECL_INSN_RESERV (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;
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;
description->decls [description->decls_num] = advance_cycle_insn_decl;
description->decls_num++;
description->insns_num++;
- num_dfa_decls++;
}
\f
#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;
static int
alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2)
{
- if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
- == (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
+ if ((*(const alt_state_t *) alt_state_ptr_1)->state->unique_num
+ == (*(const alt_state_t *) alt_state_ptr_2)->state->unique_num)
return 0;
- else if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
- < (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
+ else if ((*(const alt_state_t *) alt_state_ptr_1)->state->unique_num
+ < (*(const alt_state_t *) alt_state_ptr_2)->state->unique_num)
return -1;
else
return 1;
/* Comparison of given reservation sets. */
static int
-reserv_sets_cmp (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
+reserv_sets_cmp (const_reserv_sets_t reservs_1, const_reserv_sets_t reservs_2)
{
int reservs_num;
- set_el_t *reserv_ptr_1;
- set_el_t *reserv_ptr_2;
+ const set_el_t *reserv_ptr_1;
+ const set_el_t *reserv_ptr_2;
gcc_assert (reservs_1 && reservs_2);
reservs_num = els_in_reservs;
/* The function checks equality of the reservation sets. */
static int
-reserv_sets_eq (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
+reserv_sets_eq (const_reserv_sets_t reservs_1, const_reserv_sets_t reservs_2)
{
return reserv_sets_cmp (reservs_1, reservs_2) == 0;
}
* sizeof (set_el_t) * CHAR_BIT + unit_num);
}
-/* The function checks that the reservation set represents no one unit
- reservation. */
-static int
-it_is_empty_reserv_sets (reserv_sets_t operand)
-{
- set_el_t *reserv_ptr;
- int reservs_num;
-
- gcc_assert (operand);
- for (reservs_num = els_in_reservs, reserv_ptr = operand;
- reservs_num != 0;
- reserv_ptr++, reservs_num--)
- if (*reserv_ptr != 0)
- return 0;
- return 1;
-}
-
/* The function checks that the reservation sets are intersected,
i.e. there is a unit reservation on a cycle in both reservation
sets. */
result->it_was_placed_in_stack_for_NDFA_forming = 0;
result->it_was_placed_in_stack_for_DFA_forming = 0;
result->component_states = NULL;
- result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
}
else
{
#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;
- result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
curr_unique_state_num++;
}
if (with_reservs)
unsigned int hash_value;
alt_state_t alt_state;
- if (((state_t) state)->component_states == NULL)
- hash_value = reserv_sets_hash_value (((state_t) state)->reservs);
+ if (((const_state_t) state)->component_states == NULL)
+ hash_value = reserv_sets_hash_value (((const_state_t) state)->reservs);
else
{
hash_value = 0;
- for (alt_state = ((state_t) state)->component_states;
+ for (alt_state = ((const_state_t) state)->component_states;
alt_state != NULL;
alt_state = alt_state->next_sorted_alt_state)
hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
}
hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
| (hash_value << CHAR_BIT))
- + ((state_t) state)->automaton->automaton_order_num);
+ + ((const_state_t) state)->automaton->automaton_order_num);
return hash_value;
}
alt_state_t alt_state_1;
alt_state_t alt_state_2;
- if (((state_t) state_1)->automaton != ((state_t) state_2)->automaton)
+ if (((const_state_t) state_1)->automaton != ((const_state_t) state_2)->automaton)
return 0;
- else if (((state_t) state_1)->component_states == NULL
- && ((state_t) state_2)->component_states == NULL)
- return reserv_sets_eq (((state_t) state_1)->reservs,
- ((state_t) state_2)->reservs);
- else if (((state_t) state_1)->component_states != NULL
- && ((state_t) state_2)->component_states != NULL)
- {
- for (alt_state_1 = ((state_t) state_1)->component_states,
- alt_state_2 = ((state_t) state_2)->component_states;
+ else if (((const_state_t) state_1)->component_states == NULL
+ && ((const_state_t) state_2)->component_states == NULL)
+ return reserv_sets_eq (((const_state_t) state_1)->reservs,
+ ((const_state_t) state_2)->reservs);
+ else if (((const_state_t) state_1)->component_states != NULL
+ && ((const_state_t) state_2)->component_states != NULL)
+ {
+ for (alt_state_1 = ((const_state_t) state_1)->component_states,
+ alt_state_2 = ((const_state_t) state_2)->component_states;
alt_state_1 != NULL && alt_state_2 != NULL;
alt_state_1 = alt_state_1->next_sorted_alt_state,
alt_state_2 = alt_state_2->next_sorted_alt_state)
int i;
if (description->units_num)
- units_array = xmalloc (description->units_num * sizeof (unit_decl_t));
+ units_array = XNEWVEC (unit_decl_t, description->units_num);
else
units_array = 0;
from_state->first_out_arc = arc->next_out_arc;
else
prev_arc->next_out_arc = arc->next_out_arc;
+ from_state->num_out_arcs--;
free_arc (arc);
}
return NULL;
}
-/* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
- and with given STATE_ALTS. The function returns added arc (or
- already existing arc). */
+/* 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
-add_arc (state_t from_state, state_t to_state, ainsn_t ainsn,
- int state_alts)
+add_arc (state_t from_state, state_t to_state, ainsn_t ainsn)
{
arc_t new_arc;
#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;
ainsn->arc_exists_p = 1;
new_arc->next_out_arc = from_state->first_out_arc;
from_state->first_out_arc = new_arc;
+ from_state->num_out_arcs++;
new_arc->next_arc_marked_by_insn = NULL;
- new_arc->state_alts = state_alts;
return new_arc;
}
/* The function returns the first arc starting from STATE. */
static arc_t
-first_out_arc (state_t state)
+first_out_arc (const_state_t state)
{
return state->first_out_arc;
}
= 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;
automata_list_hash (const void *automata_list)
{
unsigned int hash_value;
- automata_list_el_t curr_automata_list_el;
+ const_automata_list_el_t curr_automata_list_el;
hash_value = 0;
- for (curr_automata_list_el = (automata_list_el_t) automata_list;
+ for (curr_automata_list_el = (const_automata_list_el_t) automata_list;
curr_automata_list_el != NULL;
curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
static int
automata_list_eq_p (const void *automata_list_1, const void *automata_list_2)
{
- automata_list_el_t automata_list_el_1;
- automata_list_el_t automata_list_el_2;
+ const_automata_list_el_t automata_list_el_1;
+ const_automata_list_el_t automata_list_el_2;
- for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
- automata_list_el_2 = (automata_list_el_t) automata_list_2;
+ for (automata_list_el_1 = (const_automata_list_el_t) automata_list_1,
+ automata_list_el_2 = (const_automata_list_el_t) automata_list_2;
automata_list_el_1 != NULL && automata_list_el_2 != NULL;
automata_list_el_1 = automata_list_el_1->next_automata_list_el,
automata_list_el_2 = automata_list_el_2->next_automata_list_el)
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;
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])
+ if (((unsigned char *) original_set) [char_num])
for (i = CHAR_BIT - 1; i >= 0; i--)
- if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
+ if ((((unsigned char *) original_set) [char_num] >> i) & 1)
{
start_unit_num = char_num * CHAR_BIT + i;
if (start_unit_num >= description->units_num)
}
/* 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;
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])
+ if (((unsigned char *) original_set) [char_num])
for (i = CHAR_BIT - 1; i >= 0; i--)
- if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
+ if ((((unsigned char *) original_set) [char_num] >> i) & 1)
{
start_unit_num = char_num * CHAR_BIT + i;
if (start_unit_num >= description->units_num)
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;
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;
if (progress_flag && states_n % 100 == 0)
fprintf (stderr, ".");
}
- added_arc = add_arc (state, state2, ainsn, 1);
+ added_arc = add_arc (state, state2, ainsn);
if (!ndfa_flag)
break;
}
}
if (!ndfa_flag && added_arc != NULL)
{
- added_arc->state_alts = 0;
for (alt_state = ainsn->alt_states;
alt_state != NULL;
alt_state = alt_state->next_alt_state)
- {
- state2 = alt_state->state;
- if (!intersected_state_reservs_p (state, state2))
- added_arc->state_alts++;
- }
+ state2 = alt_state->state;
}
}
else
fprintf (stderr, ".");
}
gcc_assert (advance_cycle_ainsn);
- add_arc (state, state2, advance_cycle_ainsn, 1);
+ add_arc (state, state2, advance_cycle_ainsn);
}
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)
{
for (curr_arc = first_out_arc (curr_alt_state->state);
curr_arc != NULL;
curr_arc = next_out_arc (curr_arc))
- add_arc (state, curr_arc->to_state, curr_arc->insn, 1);
+ add_arc (state, curr_arc->to_state, curr_arc->insn);
}
arcs_marked_by_insn->to_state = state;
for (alts_number = 0,
remove_arc (original_state, curr_arc);
alts_number++;
}
- arcs_marked_by_insn->state_alts = alts_number;
}
}
if (!state->it_was_placed_in_stack_for_DFA_forming)
out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
nonzero value) or by equiv_class_num_2 of the destination state.
The function returns number of out arcs of STATE. */
-static int
+static void
set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
{
- int state_out_arcs_num;
arc_t arc;
- state_out_arcs_num = 0;
for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
{
- gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num
- && !arc->insn->insn_reserv_decl->state_alts);
- state_out_arcs_num++;
+ gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num);
arc->insn->insn_reserv_decl->equiv_class_num
= (odd_iteration_flag
? arc->to_state->equiv_class_num_1
: arc->to_state->equiv_class_num_2);
- arc->insn->insn_reserv_decl->state_alts = arc->state_alts;
- gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num
- && arc->insn->insn_reserv_decl->state_alts > 0);
+ gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num);
}
- return state_out_arcs_num;
}
/* The function clears equivalence numbers and alt_states in all insns
arc_t arc;
for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
- {
- arc->insn->insn_reserv_decl->equiv_class_num = 0;
- arc->insn->insn_reserv_decl->state_alts = 0;
- }
+ arc->insn->insn_reserv_decl->equiv_class_num = 0;
}
return false;
}
+/* This fills in the presence_signature[] member of STATE. */
+static void
+cache_presence (state_t state)
+{
+ int i, num = 0;
+ unsigned int sz;
+ sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
+ / (sizeof (int) * CHAR_BIT);
+
+ state->presence_signature = XCREATENODEVEC (unsigned int, sz);
+ for (i = 0; i < description->units_num; i++)
+ if (units_array [i]->query_p)
+ {
+ int presence1_p = first_cycle_unit_presence (state, i);
+ state->presence_signature[num / (sizeof (int) * CHAR_BIT)]
+ |= (!!presence1_p) << (num % (sizeof (int) * CHAR_BIT));
+ num++;
+ }
+}
+
/* The function returns nonzero value if STATE is not equivalent to
ANOTHER_STATE from the same current partition on equivalence
classes. Another state has ANOTHER_STATE_OUT_ARCS_NUM number of
by ODD_ITERATION_FLAG. */
static int
state_is_differed (state_t state, state_t another_state,
- int another_state_out_arcs_num, int odd_iteration_flag)
+ int odd_iteration_flag)
{
arc_t arc;
- int state_out_arcs_num;
- int i, presence1_p, presence2_p;
+ unsigned int sz, si;
+
+ gcc_assert (state->num_out_arcs == another_state->num_out_arcs);
+
+ sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
+ / (sizeof (int) * CHAR_BIT);
+
+ for (si = 0; si < sz; si++)
+ gcc_assert (state->presence_signature[si]
+ == another_state->presence_signature[si]);
- state_out_arcs_num = 0;
for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
{
- state_out_arcs_num++;
if ((odd_iteration_flag
? arc->to_state->equiv_class_num_1
: arc->to_state->equiv_class_num_2)
- != arc->insn->insn_reserv_decl->equiv_class_num
- || (arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
+ != arc->insn->insn_reserv_decl->equiv_class_num)
return 1;
}
- if (state_out_arcs_num != another_state_out_arcs_num)
+
+ return 0;
+}
+
+/* Compares two states pointed to by STATE_PTR_1 and STATE_PTR_2
+ and return -1, 0 or 1. This function can be used as predicate for
+ qsort(). It requires the member presence_signature[] of both
+ states be filled. */
+static int
+compare_states_for_equiv (const void *state_ptr_1,
+ const void *state_ptr_2)
+{
+ const_state_t const s1 = *(const_state_t const*)state_ptr_1;
+ const_state_t const s2 = *(const_state_t const*)state_ptr_2;
+ unsigned int sz, si;
+ if (s1->num_out_arcs < s2->num_out_arcs)
+ return -1;
+ else if (s1->num_out_arcs > s2->num_out_arcs)
return 1;
- /* Now we are looking at the states with the point of view of query
- units. */
- for (i = 0; i < description->units_num; i++)
- if (units_array [i]->query_p)
- {
- presence1_p = first_cycle_unit_presence (state, i);
- presence2_p = first_cycle_unit_presence (another_state, i);
- if ((presence1_p && !presence2_p) || (!presence1_p && presence2_p))
- return 1;
- }
+
+ sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
+ / (sizeof (int) * CHAR_BIT);
+
+ for (si = 0; si < sz; si++)
+ if (s1->presence_signature[si] < s2->presence_signature[si])
+ return -1;
+ else if (s1->presence_signature[si] > s2->presence_signature[si])
+ return 1;
return 0;
}
/* The function makes initial partition of STATES on equivalent
- classes. */
-static state_t
-init_equiv_class (VEC(state_t,heap) *states)
+ 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)
{
size_t i;
state_t prev = 0;
+ int class_num = 1;
+ *classes = VEC_alloc (state_t,heap, 150);
for (i = 0; i < VEC_length (state_t, states); i++)
{
- VEC_index (state_t, states, i)->equiv_class_num_1 = 1;
- VEC_index (state_t, states, i)->next_equiv_class_state = prev;
- prev = VEC_index (state_t, states, i);
+ state_t state = VEC_index (state_t, states, i);
+ if (prev)
+ {
+ if (compare_states_for_equiv (&prev, &state) != 0)
+ {
+ VEC_safe_push (state_t,heap, *classes, prev);
+ class_num++;
+ prev = NULL;
+ }
+ }
+ state->equiv_class_num_1 = class_num;
+ state->next_equiv_class_state = prev;
+ prev = state;
}
- return prev;
+ if (prev)
+ VEC_safe_push (state_t,heap, *classes, prev);
+ return class_num;
}
/* The function copies pointers to equivalent states from vla FROM
VEC_free (state_t,heap, *to);
*to = VEC_copy (state_t,heap, from);
}
+
/* The function processes equivalence class given by its first state,
FIRST_STATE, on odd iteration if ODD_ITERATION_FLAG. If there
are not equivalent states, the function partitions the class
state_t curr_state;
state_t prev_state;
state_t next_state;
- int out_arcs_num;
partition_p = 0;
if (first_state->next_equiv_class_state != NULL)
{
/* There are more one states in the class equivalence. */
- out_arcs_num = set_out_arc_insns_equiv_num (first_state,
- odd_iteration_flag);
+ set_out_arc_insns_equiv_num (first_state, odd_iteration_flag);
for (prev_state = first_state,
curr_state = first_state->next_equiv_class_state;
curr_state != NULL;
curr_state = next_state)
{
next_state = curr_state->next_equiv_class_state;
- if (state_is_differed (curr_state, first_state, out_arcs_num,
+ if (state_is_differed (curr_state, first_state,
odd_iteration_flag))
{
/* Remove curr state from the class equivalence. */
evaluate_equiv_classes (automaton_t automaton,
VEC(state_t,heap) **equiv_classes)
{
- state_t new_equiv_class;
int new_equiv_class_num;
int odd_iteration_flag;
int finish_flag;
all_achieved_states = VEC_alloc (state_t,heap, 1500);
pass_states (automaton, add_achieved_state);
- new_equiv_class = init_equiv_class (all_achieved_states);
- odd_iteration_flag = 0;
- new_equiv_class_num = 1;
+ 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);
- next_iteration_classes = VEC_alloc (state_t,heap, 150);
- VEC_quick_push (state_t, next_iteration_classes, new_equiv_class);
+ odd_iteration_flag = 0;
+ new_equiv_class_num = init_equiv_class (all_achieved_states,
+ &next_iteration_classes);
do
{
curr_arc = next_out_arc (curr_arc))
add_arc (first_class_state->equiv_class_state,
curr_arc->to_state->equiv_class_state,
- curr_arc->insn, curr_arc->state_alts);
+ curr_arc->insn);
/* Delete output arcs from states of given class equivalence. */
for (curr_state = first_class_state;
curr_state != NULL;
process_state_for_insn_equiv_partition (state_t state)
{
arc_t arc;
- arc_t *insn_arcs_array = xmalloc (description->insns_num * sizeof(arc_t));
+ arc_t *insn_arcs_array = XCNEWVEC (arc_t, description->insns_num);
/* Process insns of the arcs. */
for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
compare_max_occ_cycle_nums (const void *unit_decl_1,
const void *unit_decl_2)
{
- if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
- < (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
+ if ((DECL_UNIT (*(const_decl_t const*) unit_decl_1)->max_occ_cycle_num)
+ < (DECL_UNIT (*(const_decl_t const*) unit_decl_2)->max_occ_cycle_num))
return 1;
- else if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
- == (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
+ else if ((DECL_UNIT (*(const_decl_t const*) unit_decl_1)->max_occ_cycle_num)
+ == (DECL_UNIT (*(const_decl_t const*) unit_decl_2)->max_occ_cycle_num))
return 0;
else
return -1;
if (description->units_num == 0)
return;
estimation_bound = estimate_one_automaton_bound ();
- unit_decls = xmalloc (description->units_num * sizeof (unit_decl_t));
+ unit_decls = XNEWVEC (unit_decl_t, description->units_num);
for (i = 0, j = 0; i < description->decls_num; i++)
if (description->decls[i]->mode == dm_unit)
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;
fprintf (f, "int");
}
-/* The following macro value is used as value of member
- `longest_path_length' of state when we are processing path and the
- state on the path. */
-
-#define ON_THE_PATH -2
-
-/* The following recursive function searches for the length of the
- longest path starting from STATE which does not contain cycles and
- `cycle advance' arcs. */
-
-static int
-longest_path_length (state_t state)
-{
- arc_t arc;
- int length, result;
-
- if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
- {
- /* We don't expect the path cycle here. Our graph may contain
- only cycles with one state on the path not containing `cycle
- advance' arcs -- see comment below. */
- gcc_assert (state->longest_path_length != ON_THE_PATH);
-
- /* We already visited the state. */
- return state->longest_path_length;
- }
-
- result = 0;
- for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
- /* Ignore cycles containing one state and `cycle advance' arcs. */
- if (arc->to_state != state
- && (arc->insn->insn_reserv_decl
- != DECL_INSN_RESERV (advance_cycle_insn_decl)))
- {
- length = longest_path_length (arc->to_state);
- if (length > result)
- result = length;
- }
- state->longest_path_length = result + 1;
- return result;
-}
-
/* The function outputs all initialization values of VECT. */
static void
output_vect (vla_hwint_t vect)
fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
}
-/* Output name for simple alternatives number representation. */
-static void
-output_state_alts_full_vect_name (FILE *f, automaton_t automaton)
-{
- if (automaton->corresponding_automaton_decl == NULL)
- fprintf (f, "state_alts_%d", automaton->automaton_order_num);
- else
- fprintf (f, "%s_state_alts",
- automaton->corresponding_automaton_decl->name);
-}
-
-/* Output name of comb vector of the alternatives number table for given
- automaton. */
-static void
-output_state_alts_comb_vect_name (FILE *f, automaton_t automaton)
-{
- if (automaton->corresponding_automaton_decl == NULL)
- fprintf (f, "state_alts_%d", automaton->automaton_order_num);
- else
- fprintf (f, "%s_state_alts",
- automaton->corresponding_automaton_decl->name);
-}
-
-/* Output name of check vector of the alternatives number table for given
- automaton. */
-static void
-output_state_alts_check_vect_name (FILE *f, automaton_t automaton)
-{
- if (automaton->corresponding_automaton_decl == NULL)
- fprintf (f, "check_state_alts_%d", automaton->automaton_order_num);
- else
- fprintf (f, "%s_check_state_alts",
- automaton->corresponding_automaton_decl->name);
-}
-
-/* Output name of base vector of the alternatives number table for given
- automaton. */
-static void
-output_state_alts_base_vect_name (FILE *f, automaton_t automaton)
-{
- if (automaton->corresponding_automaton_decl == NULL)
- fprintf (f, "base_state_alts_%d", automaton->automaton_order_num);
- else
- fprintf (f, "%s_base_state_alts",
- automaton->corresponding_automaton_decl->name);
-}
-
/* Output name of simple min issue delay table representation. */
static void
output_min_issue_delay_vect_name (FILE *f, automaton_t automaton)
}
/* Name of the PHR interface macro. */
-#define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
-
-/* Name of the PHR interface macro. */
#define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
/* Names of an internal functions: */
#define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
-#define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
-
#define INTERNAL_RESET_FUNC_NAME "internal_reset"
#define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
#define TRANSITION_FUNC_NAME "state_transition"
-#define STATE_ALTS_FUNC_NAME "state_alts"
-
#define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
#define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
#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"
+
#define DFA_START_FUNC_NAME "dfa_start"
#define DFA_FINISH_FUNC_NAME "dfa_finish"
code with caching. */
#define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
-/* Name of function (attribute) to translate insn into internal insn
- code. */
-#define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
-
-/* Name of function (attribute) to translate insn into internal insn
- code. */
-#define BYPASS_P_FUNC_NAME "bypass_p"
-
/* Output C type which is used for representation of codes of states
of AUTOMATON. */
static void
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);
/* Return number of out arcs of STATE. */
static int
-out_state_arcs_num (state_t state)
+out_state_arcs_num (const_state_t state)
{
int result;
arc_t arc;
compare_transition_els_num (const void *state_ptr_1,
const void *state_ptr_2)
{
- int transition_els_num_1;
- int transition_els_num_2;
+ const int transition_els_num_1
+ = out_state_arcs_num (*(const_state_t const*) state_ptr_1);
+ const int transition_els_num_2
+ = out_state_arcs_num (*(const_state_t const*) state_ptr_2);
- transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
- transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
if (transition_els_num_1 < transition_els_num_2)
return 1;
else if (transition_els_num_1 == transition_els_num_2)
VEC_free (vect_el_t,heap, transition_vect);
}
-/* Form and output vectors (comb, check, base or simple vect)
- representing alts number table of AUTOMATON. The table is state x
- ainsn -> number of possible alternative reservations by the
- ainsn. */
-static void
-output_state_alts_table (automaton_t automaton)
-{
- size_t i;
- arc_t arc;
- vla_hwint_t state_alts_vect;
-
- undefined_vect_el_value = 0; /* no alts when transition is not possible */
- automaton->state_alts_table = create_state_ainsn_table (automaton);
- /* Create vect of pointers to states ordered by num of transitions
- 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);
-
- /* Create base, comb, and check vectors. */
- state_alts_vect = 0;
-
- for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
- {
- VEC_truncate (vect_el_t, state_alts_vect, 0);
- for (arc = first_out_arc (VEC_index (state_t, output_states_vect, i));
- arc != NULL;
- arc = next_out_arc (arc))
- {
- gcc_assert (arc->insn);
- if (arc->insn->first_ainsn_with_given_equivalence_num)
- add_vect_el (&state_alts_vect, arc->insn, arc->state_alts);
- }
- add_vect (automaton->state_alts_table,
- VEC_index (state_t, output_states_vect, i)->order_state_num,
- state_alts_vect);
- }
- output_state_ainsn_table
- (automaton->state_alts_table, "state insn alternatives",
- output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
- output_state_alts_check_vect_name, output_state_alts_base_vect_name);
-
- VEC_free (state_t,heap, output_states_vect);
- VEC_free (vect_el_t,heap, state_alts_vect);
-}
-
/* The current number of passing states to find minimal issue delay
value for an ainsn and state. */
static int curr_state_pass_num;
size_t n;
int i;
+ if (description->query_units_num == 0)
+ return;
+
/* Create vect of pointers to states. */
output_states_vect = 0;
pass_states (automaton, add_states_vect_el);
VEC_replace (vect_el_t, reserved_units_table, ri, x);
}
}
+ fprintf (output_file, "\n#if %s\n", CPU_UNITS_QUERY_MACRO_NAME);
fprintf (output_file, "/* Vector for reserved units of states. */\n");
fprintf (output_file, "static const ");
output_range_type (output_file, 0, 255);
output_reserved_units_table_name (output_file, automaton);
fprintf (output_file, "[] = {\n");
output_vect (reserved_units_table);
- fprintf (output_file, "};\n\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);
{
output_translate_vect (automaton);
output_trans_table (automaton);
- fprintf (output_file, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
- output_state_alts_table (automaton);
- fprintf (output_file, "\n#endif /* #if %s */\n\n",
- AUTOMATON_STATE_ALTS_MACRO_NAME);
output_min_issue_delay_table (automaton);
output_dead_lock_vect (automaton);
- fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
output_reserved_units_table (automaton);
- fprintf (output_file, "\n#endif /* #if %s */\n\n",
- CPU_UNITS_QUERY_MACRO_NAME);
}
fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
{\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);
-}
-
-/* The function outputs a code for evaluation of alternative states
- number for insns which have reservations in given AUTOMATA_LIST. */
-static void
-output_automata_list_state_alts_code (automata_list_el_t automata_list)
-{
- automata_list_el_t el;
- automaton_t automaton;
-
- fprintf (output_file, " {\n");
- for (el = automata_list; el != NULL; el = el->next_automata_list_el)
- if (comb_vect_p (el->automaton->state_alts_table))
- {
- fprintf (output_file, " int %s;\n", TEMPORARY_VARIABLE_NAME);
- break;
- }
- for (el = automata_list; el != NULL; el = el->next_automata_list_el)
- {
- automaton = el->automaton;
- if (comb_vect_p (automaton->state_alts_table))
- {
- fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
- output_state_alts_base_vect_name (output_file, automaton);
- fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
- output_chip_member_name (output_file, automaton);
- fprintf (output_file, "] + ");
- output_translate_vect_name (output_file, automaton);
- fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
- fprintf (output_file, " if (");
- output_state_alts_check_vect_name (output_file, automaton);
- fprintf (output_file, " [%s] != %s->",
- TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
- output_chip_member_name (output_file, automaton);
- fprintf (output_file, ")\n");
- fprintf (output_file, " return 0;\n");
- fprintf (output_file, " else\n");
- fprintf (output_file,
- (el == automata_list
- ? " %s = " : " %s += "),
- RESULT_VARIABLE_NAME);
- output_state_alts_comb_vect_name (output_file, automaton);
- fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
- }
- else
- {
- fprintf (output_file,
- (el == automata_list
- ? "\n %s = " : " %s += "),
- RESULT_VARIABLE_NAME);
- output_state_alts_full_vect_name (output_file, automaton);
- fprintf (output_file, " [");
- 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];\n",
- automaton->insn_equiv_classes_num);
- }
- }
- fprintf (output_file, " break;\n }\n\n");
-}
-
-/* Output function `internal_state_alts'. */
-static void
-output_internal_state_alts_func (void)
-{
- fprintf (output_file,
- "static int\n%s (int %s, struct %s *%s)\n",
- INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
- CHIP_NAME, CHIP_PARAMETER_NAME);
- fprintf (output_file, "{\n int %s;\n", RESULT_VARIABLE_NAME);
- fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
- output_insn_code_cases (output_automata_list_state_alts_code);
- fprintf (output_file,
- "\n default:\n %s = 0;\n break;\n }\n",
- RESULT_VARIABLE_NAME);
- fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
- fprintf (output_file, "}\n\n");
-}
-
-/* The function outputs PHR interface function `state_alts'. */
-static void
-output_state_alts_func (void)
-{
- fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
- STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
- STATE_TYPE_NAME, STATE_NAME, 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_STATE_ALTS_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,
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)
static int
units_cmp (const void *unit1, const void *unit2)
{
- const unit_decl_t u1 = *(unit_decl_t *) unit1;
- const unit_decl_t u2 = *(unit_decl_t *) unit2;
+ const_unit_decl_t const u1 = *(const_unit_decl_t const*) unit1;
+ const_unit_decl_t const u2 = *(const_unit_decl_t const*) unit2;
return strcmp (u1->name, u2->name);
}
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, "{\n gcc_assert (%s >= 0 && %s < %d);\n",
CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
description->query_units_num);
- for (automaton = description->first_automaton;
- automaton != NULL;
- automaton = automaton->next_automaton)
+ if (description->query_units_num > 0)
+ for (automaton = description->first_automaton;
+ automaton != NULL;
+ automaton = automaton->next_automaton)
+ {
+ fprintf (output_file, " if ((");
+ output_reserved_units_table_name (output_file, automaton);
+ fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
+ output_chip_member_name (output_file, automaton);
+ fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
+ (description->query_units_num + 7) / 8,
+ CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
+ fprintf (output_file, " return 1;\n");
+ }
+ 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, " if ((");
- output_reserved_units_table_name (output_file, automaton);
- fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
- output_chip_member_name (output_file, automaton);
- fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
- (description->query_units_num + 7) / 8,
- CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
- fprintf (output_file, " return 1;\n");
+ fprintf (output_file, " return false;\n}\n\n");
+ return;
}
- fprintf (output_file, " return 0;\n}\n\n");
+
+ 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 function `dfa_clean_insn_cache'. */
+/* The function outputs PHR interface functions `dfa_clean_insn_cache'
+ and 'dfa_clear_single_insn_cache'. */
static void
output_dfa_clean_insn_cache_func (void)
{
I_VARIABLE_NAME, I_VARIABLE_NAME,
DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
+
+ fprintf (output_file,
+ "void\n%s (rtx %s)\n{\n int %s;\n\n",
+ DFA_CLEAR_SINGLE_INSN_CACHE_FUNC_NAME, INSN_PARAMETER_NAME,
+ I_VARIABLE_NAME);
+ fprintf (output_file,
+ " %s = INSN_UID (%s);\n if (%s < %s)\n %s [%s] = -1;\n}\n\n",
+ I_VARIABLE_NAME, INSN_PARAMETER_NAME, I_VARIABLE_NAME,
+ DFA_INSN_CODES_LENGTH_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
+ I_VARIABLE_NAME);
}
/* The function outputs PHR interface function `dfa_start'. */
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");
ainsn = ainsn->next_same_reservs_insn;
}
while (ainsn != NULL);
- fprintf (output_description_file, " %d (%d)\n",
- arc->to_state->order_state_num, arc->state_alts);
+ fprintf (output_description_file, " %d \n",
+ arc->to_state->order_state_num);
}
fprintf (output_description_file, "\n");
}
static int
state_reservs_cmp (const void *reservs_ptr_1, const void *reservs_ptr_2)
{
- return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
- *(reserv_sets_t *) reservs_ptr_2);
+ return reserv_sets_cmp (*(const_reserv_sets_t const*) reservs_ptr_1,
+ *(const_reserv_sets_t const*) reservs_ptr_2);
}
/* The following function is used for sorting possible cpu unit
#ifndef NDEBUG
int transition_comb_vect_els = 0;
int transition_full_vect_els = 0;
- int state_alts_comb_vect_els = 0;
- int state_alts_full_vect_els = 0;
int min_issue_delay_vect_els = 0;
int locked_states = 0;
#endif
(comb_vect_p (automaton->trans_table)
? "use comb vect" : "use simple vect"));
fprintf
- (f, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
- (long) VEC_length (vect_el_t, automaton->state_alts_table->comb_vect),
- (long) VEC_length (vect_el_t, automaton->state_alts_table->full_vect),
- (comb_vect_p (automaton->state_alts_table)
- ? "use comb vect" : "use simple vect"));
- fprintf
(f, "%5ld min delay table els, compression factor %d\n",
(long) states_num * automaton->insn_equiv_classes_num,
automaton->min_issue_delay_table_compression_factor);
+= VEC_length (vect_el_t, automaton->trans_table->comb_vect);
transition_full_vect_els
+= VEC_length (vect_el_t, automaton->trans_table->full_vect);
- state_alts_comb_vect_els
- += VEC_length (vect_el_t, automaton->state_alts_table->comb_vect);
- state_alts_full_vect_els
- += VEC_length (vect_el_t, automaton->state_alts_table->full_vect);
min_issue_delay_vect_els
+= states_num * automaton->insn_equiv_classes_num;
locked_states
allocated_alt_states_num);
fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
transition_comb_vect_els, transition_full_vect_els);
- fprintf
- (f, "%5d all state alts comb vector els, %5d all state alts table els\n",
- state_alts_comb_vect_els, state_alts_full_vect_els);
fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
fprintf (f, "%5d all locked states\n", locked_states);
#endif
\f
-/* The following function creates insn attribute whose values are
- number alternatives in insn reservations. */
-static void
-make_insn_alts_attr (void)
-{
- int i, insn_num;
- decl_t decl;
- rtx condexp;
-
- condexp = rtx_alloc (COND);
- XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
- XEXP (condexp, 1) = make_numeric_value (0);
- for (i = insn_num = 0; i < description->decls_num; i++)
- {
- decl = description->decls [i];
- if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
- {
- XVECEXP (condexp, 0, 2 * insn_num)
- = DECL_INSN_RESERV (decl)->condexp;
- XVECEXP (condexp, 0, 2 * insn_num + 1)
- = make_numeric_value
- (DECL_INSN_RESERV (decl)->transformed_regexp->mode != rm_oneof
- ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl)
- ->transformed_regexp)->regexps_num);
- insn_num++;
- }
- }
- gcc_assert (description->insns_num == insn_num + 1);
- make_internal_attr (attr_printf (sizeof ("*")
- + strlen (INSN_ALTS_FUNC_NAME) + 1,
- "*%s", INSN_ALTS_FUNC_NAME),
- condexp, ATTR_NONE);
-}
-
-\f
-
-/* The following function creates attribute which is order number of
- insn in pipeline hazard description translator. */
-static void
-make_internal_dfa_insn_code_attr (void)
-{
- int i, insn_num;
- decl_t decl;
- rtx condexp;
-
- condexp = rtx_alloc (COND);
- XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
- XEXP (condexp, 1)
- = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl)
- ->insn_num + 1);
- for (i = insn_num = 0; i < description->decls_num; i++)
- {
- decl = description->decls [i];
- if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
- {
- XVECEXP (condexp, 0, 2 * insn_num)
- = DECL_INSN_RESERV (decl)->condexp;
- XVECEXP (condexp, 0, 2 * insn_num + 1)
- = make_numeric_value (DECL_INSN_RESERV (decl)->insn_num);
- insn_num++;
- }
- }
- gcc_assert (description->insns_num == insn_num + 1);
- make_internal_attr
- (attr_printf (sizeof ("*")
- + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
- "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
- condexp, ATTR_STATIC);
-}
-
-\f
-
-/* The following function creates attribute which order number of insn
- in pipeline hazard description translator. */
-static void
-make_default_insn_latency_attr (void)
-{
- int i, insn_num;
- decl_t decl;
- rtx condexp;
-
- condexp = rtx_alloc (COND);
- XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
- XEXP (condexp, 1) = make_numeric_value (0);
- for (i = insn_num = 0; i < description->decls_num; i++)
- {
- decl = description->decls [i];
- if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
- {
- XVECEXP (condexp, 0, 2 * insn_num)
- = DECL_INSN_RESERV (decl)->condexp;
- XVECEXP (condexp, 0, 2 * insn_num + 1)
- = make_numeric_value (DECL_INSN_RESERV (decl)->default_latency);
- insn_num++;
- }
- }
- gcc_assert (description->insns_num == insn_num + 1);
- make_internal_attr (attr_printf (sizeof ("*")
- + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
- + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
- condexp, ATTR_NONE);
-}
-
-\f
-
-/* The following function creates attribute which returns 1 if given
- output insn has bypassing and 0 otherwise. */
-static void
-make_bypass_attr (void)
-{
- int i, bypass_insn;
- int bypass_insns_num = 0;
- decl_t decl;
- rtx result_rtx;
-
- for (i = 0; i < description->decls_num; i++)
- {
- decl = description->decls [i];
- if (decl->mode == dm_insn_reserv
- && DECL_INSN_RESERV (decl)->condexp != NULL
- && DECL_INSN_RESERV (decl)->bypass_list != NULL)
- bypass_insns_num++;
- }
- if (bypass_insns_num == 0)
- result_rtx = make_numeric_value (0);
- else
- {
- result_rtx = rtx_alloc (COND);
- XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
- XEXP (result_rtx, 1) = make_numeric_value (0);
-
- for (i = bypass_insn = 0; i < description->decls_num; i++)
- {
- decl = description->decls [i];
- if (decl->mode == dm_insn_reserv
- && DECL_INSN_RESERV (decl)->condexp != NULL
- && DECL_INSN_RESERV (decl)->bypass_list != NULL)
- {
- XVECEXP (result_rtx, 0, 2 * bypass_insn)
- = DECL_INSN_RESERV (decl)->condexp;
- XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
- = make_numeric_value (1);
- bypass_insn++;
- }
- }
- }
- make_internal_attr (attr_printf (sizeof ("*")
- + strlen (BYPASS_P_FUNC_NAME) + 1,
- "*%s", BYPASS_P_FUNC_NAME),
- result_rtx, ATTR_NONE);
-}
-
-\f
-
/* This page mainly contains top level functions of pipeline hazards
description translator. */
/* The following is top level function to initialize the work of
pipeline hazards description translator. */
-void
+static void
initiate_automaton_gen (int argc, char **argv)
{
const char *base_name;
split_argument = 0; /* default value */
no_minimization_flag = 0;
time_flag = 0;
+ stats_flag = 0;
v_flag = 0;
w_flag = 0;
progress_flag = 0;
no_minimization_flag = 1;
else if (strcmp (argv [i], TIME_OPTION) == 0)
time_flag = 1;
+ else if (strcmp (argv [i], STATS_OPTION) == 0)
+ stats_flag = 1;
else if (strcmp (argv [i], V_OPTION) == 0)
v_flag = 1;
else if (strcmp (argv [i], W_OPTION) == 0)
/* The following is top level function to generate automat(a,on) for
fast recognition of pipeline hazards. */
-void
+static void
expand_automata (void)
{
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++)
if (!have_error)
{
form_important_insn_automata_lists ();
- if (progress_flag)
- fprintf (stderr, "Generation of attributes...");
- make_internal_dfa_insn_code_attr ();
- make_insn_alts_attr ();
- make_default_insn_latency_attr ();
- make_bypass_attr ();
- if (progress_flag)
- fprintf (stderr, "done\n");
}
ticker_off (&generation_time);
- ticker_off (&all_time);
- if (progress_flag)
- fprintf (stderr, "All other genattrtab stuff...");
}
/* The following is top level function to output PHR and to finish
work with pipeline description translator. */
-void
+static void
write_automata (void)
{
- if (progress_flag)
- fprintf (stderr, "done\n");
- if (have_error)
- fatal ("Errors in DFA description");
- ticker_on (&all_time);
output_time = create_ticker ();
if (progress_flag)
fprintf (stderr, "Forming and outputting automata tables...");
DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
output_dfa_insn_code_func ();
output_trans_func ();
- fprintf (output_file, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
- output_internal_state_alts_func ();
- output_state_alts_func ();
- fprintf (output_file, "\n#endif /* #if %s */\n\n",
- AUTOMATON_STATE_ALTS_MACRO_NAME);
output_min_issue_delay_func ();
output_internal_dead_lock_func ();
output_dead_lock_func ();
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 ();
fprintf (stderr, "done\n");
output_statistics (output_description_file);
}
- output_statistics (stderr);
+ if (stats_flag)
+ output_statistics (stderr);
ticker_off (&output_time);
- output_time_statistics (stderr);
+ if (time_flag)
+ output_time_statistics (stderr);
finish_states ();
finish_arcs ();
finish_automata_lists ();
{
fflush (output_description_file);
if (ferror (stdout) != 0)
- fatal ("Error in writing DFA description file %s",
- output_description_file_name);
+ fatal ("Error in writing DFA description file %s: %s",
+ output_description_file_name, xstrerror (errno));
fclose (output_description_file);
}
finish_automaton_decl_table ();
if (have_error && output_description_file != NULL)
remove (output_description_file_name);
}
+
+int
+main (int argc, char **argv)
+{
+ rtx desc;
+
+ progname = "genautomata";
+
+ if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
+ return (FATAL_EXIT_CODE);
+
+ initiate_automaton_gen (argc, argv);
+ while (1)
+ {
+ int lineno;
+ int insn_code_number;
+
+ desc = read_md_rtx (&lineno, &insn_code_number);
+ if (desc == NULL)
+ break;
+
+ switch (GET_CODE (desc))
+ {
+ case DEFINE_CPU_UNIT:
+ gen_cpu_unit (desc);
+ break;
+
+ case DEFINE_QUERY_CPU_UNIT:
+ gen_query_cpu_unit (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;
+ }
+ }
+
+ 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 ();
+ }
+
+ fflush (stdout);
+ return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
+}