X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgenautomata.c;h=beda6cdb5ca62151d6b3658569a9e51372b67a6f;hb=dd90e580a01914c35fe4d2538bf53aa14fc9bcce;hp=38a1718cf5df46c2e8d7a623710e9bac2facd3b8;hpb=c966a2e26443d130bc0826ff41bb220ed16526c6;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/genautomata.c b/gcc/genautomata.c index 38a1718cf5d..beda6cdb5ca 100644 --- a/gcc/genautomata.c +++ b/gcc/genautomata.c @@ -1,5 +1,5 @@ /* Pipeline hazard description translator. - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Written by Vladimir Makarov @@ -8,7 +8,7 @@ This file is part of GCC. 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 @@ -17,27 +17,30 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 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 +. */ /* References: - 1. Detecting pipeline structural hazards quickly. T. Proebsting, + 1. The finite state automaton based pipeline hazard recognizer and + instruction scheduler in GCC. V. Makarov. Proceedings of GCC + summit, 2003. + + 2. Detecting pipeline structural hazards quickly. T. Proebsting, C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, pages 280--286, 1994. This article is a good start point to understand usage of finite state automata for pipeline hazard recognizers. But I'd - recommend the 2nd article for more deep understanding. + recommend the 1st and 3rd article for more deep understanding. - 2. Efficient Instruction Scheduling Using Finite State Automata: + 3. Efficient Instruction Scheduling Using Finite State Automata: V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best article about usage of finite state automata for pipeline hazard recognizers. - The current implementation is different from the 2nd article in the - following: + The current implementation is described in the 1st article and it + is different from the 3rd article in the following: 1. New operator `|' (alternative) is permitted in functional unit reservation which can be treated deterministically and @@ -109,18 +112,16 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "rtl.h" #include "obstack.h" #include "errors.h" +#include "gensupport.h" #include #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; @@ -132,6 +133,7 @@ typedef unsigned HOST_WIDE_INT set_el_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 @@ -184,329 +186,23 @@ struct state_ainsn_table; /* 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; @@ -517,19 +213,32 @@ static struct obstack irp; /* Declare vector types for various data structures: */ DEF_VEC_P(alt_state_t); -DEF_VEC_ALLOC_P(alt_state_t,heap); +DEF_VEC_ALLOC_P(alt_state_t, heap); DEF_VEC_P(ainsn_t); -DEF_VEC_ALLOC_P(ainsn_t,heap); +DEF_VEC_ALLOC_P(ainsn_t, heap); DEF_VEC_P(state_t); -DEF_VEC_ALLOC_P(state_t,heap); +DEF_VEC_ALLOC_P(state_t, heap); DEF_VEC_P(decl_t); -DEF_VEC_ALLOC_P(decl_t,heap); +DEF_VEC_ALLOC_P(decl_t, heap); DEF_VEC_P(reserv_sets_t); -DEF_VEC_ALLOC_P(reserv_sets_t,heap); +DEF_VEC_ALLOC_P(reserv_sets_t, heap); DEF_VEC_I(vect_el_t); DEF_VEC_ALLOC_I(vect_el_t, heap); -typedef VEC(vect_el_t,heap) *vla_hwint_t; +typedef VEC(vect_el_t, heap) *vla_hwint_t; + +/* 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); + /* Options with the following names can be set up in automata_option @@ -537,15 +246,11 @@ typedef VEC(vect_el_t,heap) *vla_hwint_t; 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'. */ @@ -566,6 +271,9 @@ static int split_argument; /* 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; @@ -759,7 +467,10 @@ struct insn_reserv_decl insn. */ int insn_num; /* The following field value is list of bypasses in which given insn - is output insn. */ + is output insn. Bypasses with the same input insn stay one after + another in the list in the same order as their occurrences in the + description but the bypass without a guard stays always the last + in a row of bypasses with the same input insn. */ struct bypass_decl *bypass_list; /* The following fields are defined by automaton generator. */ @@ -767,7 +478,7 @@ struct insn_reserv_decl /* 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; @@ -780,10 +491,6 @@ struct insn_reserv_decl 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; @@ -980,6 +687,7 @@ struct state /* 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. */ @@ -1003,6 +711,7 @@ struct state 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. */ @@ -1013,17 +722,8 @@ struct state /* 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 { @@ -1041,10 +741,6 @@ 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 @@ -1142,10 +838,9 @@ struct automaton /* 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; @@ -1189,56 +884,56 @@ struct state_ainsn_table #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__); \ @@ -1397,6 +1092,14 @@ regexp_mode_check_failed (enum regexp_mode mode, #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) @@ -1434,7 +1137,7 @@ check_name (const char * name, pos_t pos ATTRIBUTE_UNUSED) /* Pointers to all declarations during IR generation are stored in the following. */ -static VEC(decl_t,heap) *decls; +static VEC(decl_t, heap) *decls; /* Given a pointer to a (char *) and a separator, return an alloc'ed string containing the next separated element, taking parentheses @@ -1541,7 +1244,7 @@ get_str_vect (const char *str, int *els_num, int sep, int paren_p) 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; @@ -1554,7 +1257,7 @@ gen_cpu_unit (rtx def) 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); @@ -1562,8 +1265,7 @@ gen_cpu_unit (rtx def) DECL_UNIT (decl)->query_p = 0; DECL_UNIT (decl)->min_occ_cycle_num = -1; DECL_UNIT (decl)->in_set_p = 0; - VEC_safe_push (decl_t,heap, decls, decl); - num_dfa_decls++; + VEC_safe_push (decl_t, heap, decls, decl); } } @@ -1571,7 +1273,7 @@ gen_cpu_unit (rtx def) 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; @@ -1585,14 +1287,13 @@ gen_query_cpu_unit (rtx def) 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++; + VEC_safe_push (decl_t, heap, decls, decl); } } @@ -1601,7 +1302,7 @@ gen_query_cpu_unit (rtx def) 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; @@ -1620,15 +1321,14 @@ gen_bypass (rtx def) for (i = 0; i < out_length; i++) for (j = 0; j < in_length; j++) { - decl = create_node (sizeof (struct decl)); + decl = XCREATENODE (struct decl); decl->mode = dm_bypass; decl->pos = 0; DECL_BYPASS (decl)->latency = XINT (def, 0); DECL_BYPASS (decl)->out_insn_name = out_insns [i]; DECL_BYPASS (decl)->in_insn_name = in_insns [j]; DECL_BYPASS (decl)->bypass_guard_name = XSTR (def, 3); - VEC_safe_push (decl_t,heap, decls, decl); - num_dfa_decls++; + VEC_safe_push (decl_t, heap, decls, decl); } } @@ -1637,7 +1337,7 @@ gen_bypass (rtx def) 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; @@ -1656,7 +1356,7 @@ gen_excl_set (rtx def) 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; @@ -1667,8 +1367,7 @@ gen_excl_set (rtx def) else DECL_EXCL (decl)->names [i] = second_str_cpu_units [i - first_vect_length]; - VEC_safe_push (decl_t,heap, decls, decl); - num_dfa_decls++; + VEC_safe_push (decl_t, heap, decls, decl); } /* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET, @@ -1710,14 +1409,14 @@ gen_presence_absence_set (rtx def, int presence_p, int final_p) : (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) { @@ -1737,8 +1436,7 @@ gen_presence_absence_set (rtx def, int presence_p, int final_p) DECL_ABSENCE (decl)->patterns_num = patterns_length; DECL_ABSENCE (decl)->final_p = final_p; } - VEC_safe_push (decl_t,heap, decls, decl); - num_dfa_decls++; + VEC_safe_push (decl_t, heap, decls, decl); } /* Process a PRESENCE_SET. @@ -1746,7 +1444,7 @@ gen_presence_absence_set (rtx def, int presence_p, int final_p) 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); @@ -1757,7 +1455,7 @@ gen_presence_set (rtx def) 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); @@ -1768,7 +1466,7 @@ gen_final_presence_set (rtx def) 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); @@ -1779,7 +1477,7 @@ gen_absence_set (rtx def) 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); @@ -1790,7 +1488,7 @@ gen_final_absence_set (rtx def) 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; @@ -1803,12 +1501,11 @@ gen_automaton (rtx def) 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++; + VEC_safe_push (decl_t, heap, decls, decl); } } @@ -1816,13 +1513,15 @@ gen_automaton (rtx def) 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) @@ -1855,19 +1554,19 @@ gen_regexp_el (const char *str) 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; } @@ -1892,7 +1591,7 @@ gen_regexp_repeat (const char *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]); @@ -1921,8 +1620,8 @@ gen_regexp_allof (const char *str) 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++) @@ -1947,8 +1646,8 @@ gen_regexp_oneof (const char *str) 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++) @@ -1971,8 +1670,8 @@ gen_regexp_sequence (const char *str) 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++) @@ -1997,18 +1696,17 @@ gen_regexp (const char *str) 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++; + VEC_safe_push (decl_t, heap, decls, decl); } /* Process a DEFINE_INSN_RESERVATION. @@ -2016,12 +1714,12 @@ gen_reserv (rtx def) 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 @@ -2029,8 +1727,7 @@ gen_insn_reserv (rtx def) DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1); DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2); DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3)); - VEC_safe_push (decl_t,heap, decls, decl); - num_dfa_decls++; + VEC_safe_push (decl_t, heap, decls, decl); } @@ -2059,7 +1756,7 @@ string_hash (const char *string) 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); @@ -2074,8 +1771,8 @@ static int 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 @@ -2099,7 +1796,7 @@ insert_automaton_decl (decl_t automaton_decl) { void **entry_ptr; - entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1); + entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, INSERT); if (*entry_ptr == NULL) *entry_ptr = (void *) automaton_decl; return (decl_t) *entry_ptr; @@ -2160,7 +1857,7 @@ finish_automaton_decl_table (void) 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); @@ -2173,8 +1870,8 @@ insn_decl_hash (const void *insn_decl) 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 @@ -2198,7 +1895,7 @@ insert_insn_decl (decl_t insn_decl) { void **entry_ptr; - entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1); + entry_ptr = htab_find_slot (insn_decl_table, insn_decl, INSERT); if (*entry_ptr == NULL) *entry_ptr = (void *) insn_decl; return (decl_t) *entry_ptr; @@ -2258,7 +1955,7 @@ finish_insn_decl_table (void) 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)); @@ -2272,8 +1969,8 @@ decl_hash (const void *decl) 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)); @@ -2299,7 +1996,7 @@ insert_decl (decl_t decl) { void **entry_ptr; - entry_ptr = htab_find_slot (decl_table, decl, 1); + entry_ptr = htab_find_slot (decl_table, decl, INSERT); if (*entry_ptr == NULL) *entry_ptr = (void *) decl; return (decl_t) *entry_ptr; @@ -2370,7 +2067,7 @@ process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED) 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) @@ -2423,7 +2120,7 @@ add_excls (unit_set_el_t dest_list, unit_set_el_t source_list, 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; @@ -2470,7 +2167,7 @@ process_presence_absence_names (char **names, int num, : "`%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) @@ -2505,8 +2202,9 @@ process_presence_absence_patterns (char ***patterns, int num, { 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)); @@ -2616,8 +2314,7 @@ add_presence_absence (unit_set_el_t dest_list, no_error_flag = 0; } else - warning - (0, "unit `%s' excludes and requires presence of `%s'", + warning ("unit `%s' excludes and requires presence of `%s'", dst->unit_decl->name, unit->name); } } @@ -2630,15 +2327,13 @@ add_presence_absence (unit_set_el_t dest_list, { if (!w_flag) { - error - ("unit `%s' requires absence and presence of `%s'", - dst->unit_decl->name, unit->name); + error ("unit `%s' requires absence and presence of `%s'", + dst->unit_decl->name, unit->name); no_error_flag = 0; } else - warning - (0, "unit `%s' requires absence and presence of `%s'", - dst->unit_decl->name, unit->name); + warning ("unit `%s' requires absence and presence of `%s'", + dst->unit_decl->name, unit->name); } if (no_error_flag) { @@ -2652,7 +2347,7 @@ add_presence_absence (unit_set_el_t dest_list, 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) { @@ -2676,18 +2371,67 @@ add_presence_absence (unit_set_el_t dest_list, } -/* The function searches for bypass with given IN_INSN_RESERV in given - BYPASS_LIST. */ -static struct bypass_decl * -find_bypass (struct bypass_decl *bypass_list, - struct insn_reserv_decl *in_insn_reserv) +/* The function inserts BYPASS in the list of bypasses of the + corresponding output insn. The order of bypasses in the list is + decribed in a comment for member `bypass_list' (see above). If + there is already the same bypass in the list the function reports + this and does nothing. */ +static void +insert_bypass (struct bypass_decl *bypass) { - struct bypass_decl *bypass; + struct bypass_decl *curr, *last; + struct insn_reserv_decl *out_insn_reserv = bypass->out_insn_reserv; + struct insn_reserv_decl *in_insn_reserv = bypass->in_insn_reserv; - for (bypass = bypass_list; bypass != NULL; bypass = bypass->next) - if (bypass->in_insn_reserv == in_insn_reserv) - break; - return bypass; + for (curr = out_insn_reserv->bypass_list, last = NULL; + curr != NULL; + last = curr, curr = curr->next) + if (curr->in_insn_reserv == in_insn_reserv) + { + if ((bypass->bypass_guard_name != NULL + && curr->bypass_guard_name != NULL + && ! strcmp (bypass->bypass_guard_name, curr->bypass_guard_name)) + || bypass->bypass_guard_name == curr->bypass_guard_name) + { + if (bypass->bypass_guard_name == NULL) + { + if (!w_flag) + error ("the same bypass `%s - %s' is already defined", + bypass->out_insn_name, bypass->in_insn_name); + else + warning ("the same bypass `%s - %s' is already defined", + bypass->out_insn_name, bypass->in_insn_name); + } + else if (!w_flag) + error ("the same bypass `%s - %s' (guard %s) is already defined", + bypass->out_insn_name, bypass->in_insn_name, + bypass->bypass_guard_name); + else + warning + ("the same bypass `%s - %s' (guard %s) is already defined", + bypass->out_insn_name, bypass->in_insn_name, + bypass->bypass_guard_name); + return; + } + if (curr->bypass_guard_name == NULL) + break; + if (curr->next == NULL || curr->next->in_insn_reserv != in_insn_reserv) + { + last = curr; + break; + } + + } + if (last == NULL) + { + bypass->next = out_insn_reserv->bypass_list; + out_insn_reserv->bypass_list = bypass; + } + else + { + bypass->next = last->next; + last->next = bypass; + } } /* The function processes pipeline description declarations, checks @@ -2700,7 +2444,6 @@ process_decls (void) decl_t decl_in_table; decl_t out_insn_reserv; decl_t in_insn_reserv; - struct bypass_decl *bypass; int automaton_presence; int i; @@ -2719,7 +2462,7 @@ process_decls (void) error ("repeated declaration of automaton `%s'", DECL_AUTOMATON (decl)->name); else - warning (0, "repeated declaration of automaton `%s'", + warning ("repeated declaration of automaton `%s'", DECL_AUTOMATON (decl)->name); } } @@ -2732,8 +2475,6 @@ process_decls (void) 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); @@ -2825,36 +2566,7 @@ process_decls (void) = DECL_INSN_RESERV (out_insn_reserv); DECL_BYPASS (decl)->in_insn_reserv = DECL_INSN_RESERV (in_insn_reserv); - bypass - = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list, - DECL_BYPASS (decl)->in_insn_reserv); - if (bypass != NULL) - { - if (DECL_BYPASS (decl)->latency == bypass->latency) - { - if (!w_flag) - error - ("the same bypass `%s - %s' is already defined", - DECL_BYPASS (decl)->out_insn_name, - DECL_BYPASS (decl)->in_insn_name); - else - warning - (0, "the same bypass `%s - %s' is already defined", - DECL_BYPASS (decl)->out_insn_name, - DECL_BYPASS (decl)->in_insn_name); - } - else - error ("bypass `%s - %s' is already defined", - DECL_BYPASS (decl)->out_insn_name, - DECL_BYPASS (decl)->in_insn_name); - } - else - { - DECL_BYPASS (decl)->next - = DECL_INSN_RESERV (out_insn_reserv)->bypass_list; - DECL_INSN_RESERV (out_insn_reserv)->bypass_list - = DECL_BYPASS (decl); - } + insert_bypass (DECL_BYPASS (decl)); } } } @@ -2949,7 +2661,7 @@ check_automaton_usage (void) if (!w_flag) error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name); else - warning (0, "automaton `%s' is not used", + warning ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name); } } @@ -2984,7 +2696,7 @@ process_regexp (regexp_t regexp) 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; @@ -3063,14 +2775,14 @@ check_usage (void) if (!w_flag) error ("unit `%s' is not used", DECL_UNIT (decl)->name); else - warning (0, "unit `%s' is not used", DECL_UNIT (decl)->name); + warning ("unit `%s' is not used", DECL_UNIT (decl)->name); } else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used) { if (!w_flag) error ("reservation `%s' is not used", DECL_RESERV (decl)->name); else - warning (0, "reservation `%s' is not used", DECL_RESERV (decl)->name); + warning ("reservation `%s' is not used", DECL_RESERV (decl)->name); } } } @@ -3224,7 +2936,7 @@ process_regexp_cycles (regexp_t regexp, int max_start_cycle, { int max_cycle = 0; int min_cycle = 0; - + for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) { process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i], @@ -3244,7 +2956,7 @@ process_regexp_cycles (regexp_t regexp, int max_start_cycle, { int max_cycle = 0; int min_cycle = 0; - + for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++) { process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i], @@ -3425,7 +3137,7 @@ static decl_t advance_cycle_insn_decl; 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; @@ -3435,7 +3147,6 @@ add_advance_cycle_insn_decl (void) description->decls [description->decls_num] = advance_cycle_insn_decl; description->decls_num++; description->insns_num++; - num_dfa_decls++; } @@ -3469,7 +3180,7 @@ get_free_alt_state (void) #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; @@ -3507,11 +3218,11 @@ free_alt_states (alt_state_t alt_states_list) 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; @@ -3525,7 +3236,7 @@ static alt_state_t uniq_sort_alt_states (alt_state_t alt_states_list) { alt_state_t curr_alt_state; - VEC(alt_state_t,heap) *alt_states; + VEC(alt_state_t, heap) *alt_states; size_t i; size_t prev_unique_state_ind; alt_state_t result; @@ -3535,11 +3246,11 @@ uniq_sort_alt_states (alt_state_t alt_states_list) if (alt_states_list->next_alt_state == 0) return alt_states_list; - alt_states = VEC_alloc (alt_state_t,heap, 150); + alt_states = VEC_alloc (alt_state_t, heap, 150); for (curr_alt_state = alt_states_list; curr_alt_state != NULL; curr_alt_state = curr_alt_state->next_alt_state) - VEC_safe_push (alt_state_t,heap, alt_states, curr_alt_state); + VEC_safe_push (alt_state_t, heap, alt_states, curr_alt_state); qsort (VEC_address (alt_state_t, alt_states), VEC_length (alt_state_t, alt_states), @@ -3563,7 +3274,7 @@ uniq_sort_alt_states (alt_state_t alt_states_list) result = VEC_index (alt_state_t, alt_states, 0); - VEC_free (alt_state_t,heap, alt_states); + VEC_free (alt_state_t, heap, alt_states); return result; } @@ -3701,11 +3412,11 @@ reserv_sets_hash_value (reserv_sets_t reservs) /* 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; @@ -3727,7 +3438,7 @@ reserv_sets_cmp (reserv_sets_t reservs_1, reserv_sets_t reservs_2) /* 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; } @@ -3752,23 +3463,6 @@ test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num) * 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. */ @@ -3955,18 +3649,16 @@ get_free_state (int with_reservs, automaton_t automaton) 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) @@ -3998,12 +3690,12 @@ state_hash (const void *state) 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) @@ -4012,7 +3704,7 @@ state_hash (const void *state) } 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; } @@ -4023,17 +3715,17 @@ state_eq_p (const void *state_1, const void *state_2) 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) @@ -4053,7 +3745,7 @@ insert_state (state_t state) { void **entry_ptr; - entry_ptr = htab_find_slot (state_table, (void *) state, 1); + entry_ptr = htab_find_slot (state_table, (void *) state, INSERT); if (*entry_ptr == NULL) *entry_ptr = (void *) state; return (state_t) *entry_ptr; @@ -4127,7 +3819,7 @@ initiate_states (void) 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; @@ -4198,6 +3890,7 @@ remove_arc (state_t from_state, arc_t arc) 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); } @@ -4214,12 +3907,10 @@ find_arc (state_t from_state, state_t to_state, ainsn_t insn) 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; @@ -4231,7 +3922,7 @@ add_arc (state_t from_state, state_t to_state, ainsn_t ainsn, #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; @@ -4246,14 +3937,14 @@ add_arc (state_t from_state, state_t to_state, ainsn_t ainsn, 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; } @@ -4305,7 +3996,7 @@ get_free_automata_list_el (void) = 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; @@ -4342,10 +4033,10 @@ static hashval_t 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) @@ -4358,11 +4049,11 @@ automata_list_hash (const void *automata_list) 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) @@ -4410,7 +4101,7 @@ automata_list_finish (void) if (current_automata_list == NULL) return NULL; entry_ptr = htab_find_slot (automata_list_table, - (void *) current_automata_list, 1); + (void *) current_automata_list, INSERT); if (*entry_ptr == NULL) *entry_ptr = (void *) current_automata_list; else @@ -4532,7 +4223,7 @@ form_reserv_sets_list (pattern_set_el_t pattern_list) 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++) @@ -4588,11 +4279,11 @@ initiate_presence_absence_pattern_sets (void) } /* 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; @@ -4605,9 +4296,9 @@ check_presence_pattern_sets (reserv_sets_t checked_set, 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) @@ -4637,11 +4328,11 @@ check_presence_pattern_sets (reserv_sets_t checked_set, } /* 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; @@ -4653,9 +4344,9 @@ check_absence_pattern_sets (reserv_sets_t checked_set, 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) @@ -4703,44 +4394,44 @@ copy_insn_regexp (regexp_t regexp) 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 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: @@ -4769,8 +4460,8 @@ transform_1 (regexp_t regexp) 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; @@ -4806,11 +4497,11 @@ transform_2 (regexp_t regexp) { 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 @@ -4850,10 +4541,10 @@ transform_2 (regexp_t regexp) { 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 @@ -4893,10 +4584,10 @@ transform_2 (regexp_t regexp) { 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 @@ -4948,9 +4639,9 @@ transform_3 (regexp_t regexp) { 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 @@ -4958,9 +4649,9 @@ transform_3 (regexp_t regexp) 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 @@ -5000,9 +4691,9 @@ transform_3 (regexp_t regexp) { 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 @@ -5010,9 +4701,9 @@ transform_3 (regexp_t regexp) 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 @@ -5055,8 +4746,8 @@ transform_3 (regexp_t regexp) { 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; @@ -5088,14 +4779,14 @@ transform_3 (regexp_t regexp) default: break; } - + if (allof_length == 1) REGEXP_SEQUENCE (result)->regexps [i] = allof_op; else { - allof = create_node (sizeof (struct regexp) - + sizeof (regexp_t) - * (allof_length - 1)); + allof = XCREATENODEVAR (struct regexp, sizeof (struct regexp) + + sizeof (regexp_t) + * (allof_length - 1)); allof->mode = rm_allof; allof->pos = regexp->pos; REGEXP_ALLOF (allof)->regexps_num = allof_length; @@ -5224,18 +4915,23 @@ transform_insn_regexps (void) about units to automata distribution has been output. */ static int annotation_message_reported_p; +/* The vector contains all decls which are automata. */ +static VEC(decl_t, heap) *automaton_decls; + /* The following structure describes usage of a unit in a reservation. */ struct unit_usage { unit_decl_t unit_decl; /* The following forms a list of units used on the same cycle in the - same alternative. */ + same alternative. The list is ordered by the correspdoning unit + declarations and there is no unit declaration duplication in the + list. */ struct unit_usage *next; }; typedef struct unit_usage *unit_usage_t; DEF_VEC_P(unit_usage_t); -DEF_VEC_ALLOC_P(unit_usage_t,heap); +DEF_VEC_ALLOC_P(unit_usage_t, heap); /* Obstack for unit_usage structures. */ static struct obstack unit_usages; @@ -5244,9 +4940,9 @@ static struct obstack unit_usages; structures. There is an element for each combination of (alternative number, cycle). Unit usages on given cycle in alternative with given number are referred through element with - index equals to the cycle * number of all alternatives in the regexp - + the alternative number. */ -static VEC(unit_usage_t,heap) *cycle_alt_unit_usages; + index equals to the cycle * number of all alternatives in the + regexp + the alternative number. */ +static VEC(unit_usage_t, heap) *cycle_alt_unit_usages; /* The following function creates the structure unit_usage for UNIT on CYCLE in REGEXP alternative with ALT_NUM. The structure is made @@ -5257,7 +4953,7 @@ store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle, { size_t length; unit_decl_t unit_decl; - unit_usage_t unit_usage_ptr; + unit_usage_t unit_usage_ptr, curr, prev; int index; gcc_assert (regexp && regexp->mode == rm_oneof @@ -5266,33 +4962,100 @@ store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle, length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num; while (VEC_length (unit_usage_t, cycle_alt_unit_usages) < length) - VEC_safe_push (unit_usage_t,heap, cycle_alt_unit_usages, 0); - + VEC_safe_push (unit_usage_t, heap, cycle_alt_unit_usages, 0); + + index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num; + prev = NULL; + for (curr = VEC_index (unit_usage_t, cycle_alt_unit_usages, index); + curr != NULL; + prev = curr, curr = curr->next) + if (curr->unit_decl >= unit_decl) + break; + if (curr != NULL && curr->unit_decl == unit_decl) + return; obstack_blank (&unit_usages, sizeof (struct unit_usage)); unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages); obstack_finish (&unit_usages); unit_usage_ptr->unit_decl = unit_decl; - index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num; - unit_usage_ptr->next = VEC_index (unit_usage_t, cycle_alt_unit_usages, index); - VEC_replace (unit_usage_t, cycle_alt_unit_usages, index, unit_usage_ptr); unit_decl->last_distribution_check_cycle = -1; /* undefined */ + unit_usage_ptr->next = curr; + if (prev == NULL) + VEC_replace (unit_usage_t, cycle_alt_unit_usages, index, unit_usage_ptr); + else + prev->next = unit_usage_ptr; +} + +/* Return true if unit UNIT_DECL is present on the LIST. */ +static bool +unit_present_on_list_p (unit_usage_t list, unit_decl_t unit_decl) +{ + while (list != NULL) + { + if (list->unit_decl == unit_decl) + return true; + list = list->next; + } + return false; +} + +/* The function returns true if reservations of alternatives ALT1 and + ALT2 are equal after excluding reservations of units of + EXCLUDED_AUTOMATON_DECL. */ +static bool +equal_alternatives_p (int alt1, int alt2, int n_alts, + struct automaton_decl *excluded_automaton_decl) +{ + int i; + unit_usage_t list1, list2; + + for (i = 0; + i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); + i += n_alts) + { + for (list1 = VEC_index (unit_usage_t, cycle_alt_unit_usages, i + alt1), + list2 = VEC_index (unit_usage_t, cycle_alt_unit_usages, i + alt2);; + list1 = list1->next, list2 = list2->next) + { + while (list1 != NULL + && list1->unit_decl->automaton_decl == excluded_automaton_decl) + list1 = list1->next; + while (list2 != NULL + && list2->unit_decl->automaton_decl == excluded_automaton_decl) + list2 = list2->next; + if (list1 == NULL || list2 == NULL) + { + if (list1 != list2) + return false; + else + break; + } + if (list1->unit_decl != list2->unit_decl) + return false; + } + } + return true; } +DEF_VEC_I(int); +DEF_VEC_ALLOC_I(int, heap); + /* The function processes given REGEXP to find units with the wrong distribution. */ static void check_regexp_units_distribution (const char *insn_reserv_name, regexp_t regexp) { - int i, j, k, cycle; + int i, j, k, cycle, start, n_alts, alt, alt2; + bool annotation_reservation_message_reported_p; regexp_t seq, allof, unit; - struct unit_usage *unit_usage_ptr, *other_unit_usage_ptr; + struct unit_usage *unit_usage_ptr; + VEC(int, heap) *marked; if (regexp == NULL || regexp->mode != rm_oneof) return; /* Store all unit usages in the regexp: */ obstack_init (&unit_usages); - cycle_alt_unit_usages = 0; + cycle_alt_unit_usages = VEC_alloc (unit_usage_t, heap, 10); for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--) { @@ -5315,14 +5078,14 @@ check_regexp_units_distribution (const char *insn_reserv_name, gcc_assert (unit->mode == rm_nothing); } break; - + case rm_unit: store_alt_unit_usage (regexp, allof, j, i); break; - + case rm_nothing: break; - + default: gcc_unreachable (); } @@ -5338,10 +5101,10 @@ check_regexp_units_distribution (const char *insn_reserv_name, case rm_unit: store_alt_unit_usage (regexp, unit, 0, i); break; - + case rm_nothing: break; - + default: gcc_unreachable (); } @@ -5361,48 +5124,84 @@ check_regexp_units_distribution (const char *insn_reserv_name, } /* Check distribution: */ for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++) + for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i); + unit_usage_ptr != NULL; + unit_usage_ptr = unit_usage_ptr->next) + unit_usage_ptr->unit_decl->last_distribution_check_cycle = -1; + n_alts = REGEXP_ONEOF (regexp)->regexps_num; + marked = VEC_alloc (int, heap, n_alts); + for (i = 0; i < n_alts; i++) + VEC_safe_push (int, heap, marked, 0); + annotation_reservation_message_reported_p = false; + for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++) { - cycle = i / REGEXP_ONEOF (regexp)->regexps_num; + cycle = i / n_alts; + start = cycle * n_alts; for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i); unit_usage_ptr != NULL; unit_usage_ptr = unit_usage_ptr->next) - if (cycle != unit_usage_ptr->unit_decl->last_distribution_check_cycle) - { - unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle; - for (k = cycle * REGEXP_ONEOF (regexp)->regexps_num; - k < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages) - && k == cycle * REGEXP_ONEOF (regexp)->regexps_num; - k++) - { - for (other_unit_usage_ptr - = VEC_index (unit_usage_t, cycle_alt_unit_usages, k); - other_unit_usage_ptr != NULL; - other_unit_usage_ptr = other_unit_usage_ptr->next) - if (unit_usage_ptr->unit_decl->automaton_decl - == other_unit_usage_ptr->unit_decl->automaton_decl) - break; - if (other_unit_usage_ptr == NULL - && (VEC_index (unit_usage_t, cycle_alt_unit_usages, k) - != NULL)) - break; - } - if (k < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages) - && k == cycle * REGEXP_ONEOF (regexp)->regexps_num) - { - if (!annotation_message_reported_p) - { - fprintf (stderr, "\n"); - error ("The following units do not satisfy units-automata distribution rule"); - error (" (A unit of given unit automaton should be on each reserv. altern.)"); - annotation_message_reported_p = TRUE; - } - error ("Unit %s, reserv. %s, cycle %d", - unit_usage_ptr->unit_decl->name, insn_reserv_name, - cycle); - } - } + { + if (unit_usage_ptr->unit_decl->last_distribution_check_cycle == cycle) + continue; + unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle; + for (alt = 0; alt < n_alts; alt++) + if (! unit_present_on_list_p (VEC_index (unit_usage_t, + cycle_alt_unit_usages, + start + alt), + unit_usage_ptr->unit_decl)) + break; + if (alt >= n_alts) + continue; + memset (VEC_address (int, marked), 0, n_alts * sizeof (int)); + for (alt = 0; alt < n_alts; alt++) + { + if (! unit_present_on_list_p (VEC_index (unit_usage_t, + cycle_alt_unit_usages, + start + alt), + unit_usage_ptr->unit_decl)) + continue; + for (j = 0; + j < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); + j++) + { + alt2 = j % n_alts; + if (! unit_present_on_list_p + (VEC_index (unit_usage_t, cycle_alt_unit_usages, + start + alt2), + unit_usage_ptr->unit_decl) + && equal_alternatives_p (alt, alt2, n_alts, + unit_usage_ptr + ->unit_decl->automaton_decl)) + { + VEC_replace (int, marked, alt, 1); + VEC_replace (int, marked, alt2, 1); + } + } + } + for (alt = 0; alt < n_alts && VEC_index (int, marked, alt); alt++) + ; + if (alt < n_alts && 0) + { + if (! annotation_message_reported_p) + { + fprintf (stderr, "\n"); + error ("The following units do not satisfy units-automata distribution rule"); + error ("(Unit presence on one alt and its absence on other alt\n"); + error (" result in different other automata reservations)"); + annotation_message_reported_p = TRUE; + } + if (! annotation_reservation_message_reported_p) + { + error ("Reserv %s:", insn_reserv_name); + annotation_reservation_message_reported_p = true; + } + error (" Unit %s, cycle %d, alt %d, another alt %d", + unit_usage_ptr->unit_decl->name, cycle, i % n_alts, alt); + } + } } - VEC_free (unit_usage_t,heap, cycle_alt_unit_usages); + VEC_free (int, heap, marked); + VEC_free (unit_usage_t, heap, cycle_alt_unit_usages); obstack_free (&unit_usages, NULL); } @@ -5416,15 +5215,26 @@ check_unit_distributions_to_automata (void) if (progress_flag) fprintf (stderr, "Check unit distributions to automata..."); - annotation_message_reported_p = FALSE; + automaton_decls = NULL; for (i = 0; i < description->decls_num; i++) { decl = description->decls [i]; - if (decl->mode == dm_insn_reserv) - check_regexp_units_distribution - (DECL_INSN_RESERV (decl)->name, - DECL_INSN_RESERV (decl)->transformed_regexp); + if (decl->mode == dm_automaton) + VEC_safe_push (decl_t, heap, automaton_decls, decl); + } + if (VEC_length (decl_t, automaton_decls) > 1) + { + annotation_message_reported_p = FALSE; + for (i = 0; i < description->decls_num; i++) + { + decl = description->decls [i]; + if (decl->mode == dm_insn_reserv) + check_regexp_units_distribution + (DECL_INSN_RESERV (decl)->name, + DECL_INSN_RESERV (decl)->transformed_regexp); + } } + VEC_free (decl_t, heap, automaton_decls); if (progress_flag) fprintf (stderr, "done\n"); } @@ -5461,7 +5271,7 @@ process_seq_for_forming_states (regexp_t regexp, automaton_t automaton, set_state_reserv (state_being_formed, curr_cycle, REGEXP_UNIT (regexp)->unit_decl->unit_num); return curr_cycle; - + case rm_sequence: for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++) curr_cycle @@ -5473,7 +5283,7 @@ process_seq_for_forming_states (regexp_t regexp, automaton_t automaton, { int finish_cycle = 0; int cycle; - + for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) { cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp) @@ -5584,7 +5394,7 @@ form_ainsn_with_same_reservs (automaton_t automaton) { ainsn_t curr_ainsn; size_t i; - VEC(ainsn_t,heap) *last_insns = VEC_alloc (ainsn_t,heap, 150); + VEC(ainsn_t, heap) *last_insns = VEC_alloc (ainsn_t, heap, 150); for (curr_ainsn = automaton->ainsn_list; curr_ainsn != NULL; @@ -5616,7 +5426,7 @@ form_ainsn_with_same_reservs (automaton_t automaton) curr_ainsn->first_insn_with_same_reservs = 1; } } - VEC_free (ainsn_t,heap, last_insns); + VEC_free (ainsn_t, heap, last_insns); } /* Forming unit reservations which can affect creating the automaton @@ -5660,7 +5470,7 @@ make_automaton (automaton_t automaton) state_t state2; ainsn_t advance_cycle_ainsn; arc_t added_arc; - VEC(state_t,heap) *state_stack = VEC_alloc(state_t,heap, 150); + VEC(state_t, heap) *state_stack = VEC_alloc(state_t, heap, 150); int states_n; reserv_sets_t reservs_matter = form_reservs_matter (automaton); @@ -5668,7 +5478,7 @@ make_automaton (automaton_t automaton) start_state = insert_state (get_free_state (1, automaton)); automaton->start_state = start_state; start_state->it_was_placed_in_stack_for_NDFA_forming = 1; - VEC_safe_push (state_t,heap, state_stack, start_state); + VEC_safe_push (state_t, heap, state_stack, start_state); states_n = 1; while (VEC_length (state_t, state_stack) != 0) { @@ -5697,27 +5507,22 @@ make_automaton (automaton_t automaton) { state2->it_was_placed_in_stack_for_NDFA_forming = 1; - VEC_safe_push (state_t,heap, state_stack, state2); + VEC_safe_push (state_t, heap, state_stack, state2); states_n++; if (progress_flag && states_n % 100 == 0) fprintf (stderr, "."); } - added_arc = add_arc (state, state2, ainsn, 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 @@ -5728,18 +5533,18 @@ make_automaton (automaton_t automaton) if (!state2->it_was_placed_in_stack_for_NDFA_forming) { state2->it_was_placed_in_stack_for_NDFA_forming = 1; - VEC_safe_push (state_t,heap, state_stack, state2); + VEC_safe_push (state_t, heap, state_stack, state2); states_n++; if (progress_flag && states_n % 100 == 0) fprintf (stderr, "."); } gcc_assert (advance_cycle_ainsn); - add_arc (state, state2, advance_cycle_ainsn, 1); + add_arc (state, state2, advance_cycle_ainsn); } - VEC_free (state_t,heap, state_stack); + VEC_free (state_t, heap, state_stack); } -/* Foms lists of all arcs of STATE marked by the same ainsn. */ +/* Form lists of all arcs of STATE marked by the same ainsn. */ static void form_arcs_marked_by_insn (state_t state) { @@ -5769,7 +5574,7 @@ form_arcs_marked_by_insn (state_t state) static int create_composed_state (state_t original_state, arc_t arcs_marked_by_insn, - VEC(state_t,heap) **state_stack) + VEC(state_t, heap) **state_stack) { state_t state; alt_state_t alt_state, curr_alt_state; @@ -5842,7 +5647,7 @@ create_composed_state (state_t original_state, arc_t arcs_marked_by_insn, 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, @@ -5854,13 +5659,12 @@ create_composed_state (state_t original_state, arc_t arcs_marked_by_insn, 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) { state->it_was_placed_in_stack_for_DFA_forming = 1; - VEC_safe_push (state_t,heap, *state_stack, state); + VEC_safe_push (state_t, heap, *state_stack, state); } return new_state_p; } @@ -5874,16 +5678,16 @@ NDFA_to_DFA (automaton_t automaton) state_t start_state; state_t state; decl_t decl; - VEC(state_t,heap) *state_stack; + VEC(state_t, heap) *state_stack; int i; int states_n; - state_stack = VEC_alloc (state_t,heap, 0); + state_stack = VEC_alloc (state_t, heap, 0); /* Create the start state (empty state). */ start_state = automaton->start_state; start_state->it_was_placed_in_stack_for_DFA_forming = 1; - VEC_safe_push (state_t,heap, state_stack, start_state); + VEC_safe_push (state_t, heap, state_stack, start_state); states_n = 1; while (VEC_length (state_t, state_stack) != 0) { @@ -5903,7 +5707,7 @@ NDFA_to_DFA (automaton_t automaton) } } } - VEC_free (state_t,heap, state_stack); + VEC_free (state_t, heap, state_stack); } /* The following variable value is current number (1, 2, ...) of passing @@ -5945,41 +5749,34 @@ initiate_pass_states (void) /* The following vla is used for storing pointers to all achieved states. */ -static VEC(state_t,heap) *all_achieved_states; +static VEC(state_t, heap) *all_achieved_states; /* This function is called by function pass_states to add an achieved STATE. */ static void add_achieved_state (state_t state) { - VEC_safe_push (state_t,heap, all_achieved_states, state); + VEC_safe_push (state_t, heap, all_achieved_states, state); } /* The function sets up equivalence numbers of insns which mark all 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 @@ -5990,10 +5787,7 @@ clear_arc_insns_equiv_num (state_t state) 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; } @@ -6017,6 +5811,26 @@ first_cycle_unit_presence (state_t state, int unit_num) 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 @@ -6024,63 +5838,100 @@ first_cycle_unit_presence (state_t state, int unit_num) 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 into vla TO. */ static void -copy_equiv_class (VEC(state_t,heap) **to, VEC(state_t,heap) *from) +copy_equiv_class (VEC(state_t, heap) **to, VEC(state_t, heap) *from) { - VEC_free (state_t,heap, *to); - *to = VEC_copy (state_t,heap, from); + VEC_free (state_t, heap, *to); + *to = VEC_copy (state_t, heap, from); } + /* The function processes equivalence class given by its first state, FIRST_STATE, on odd iteration if ODD_ITERATION_FLAG. If there are not equivalent states, the function partitions the class @@ -6090,7 +5941,7 @@ copy_equiv_class (VEC(state_t,heap) **to, VEC(state_t,heap) *from) partitioned, the function returns nonzero value. */ static int partition_equiv_class (state_t first_state, int odd_iteration_flag, - VEC(state_t,heap) **next_iteration_classes, + VEC(state_t, heap) **next_iteration_classes, int *new_equiv_class_num_ptr) { state_t new_equiv_class; @@ -6098,7 +5949,6 @@ partition_equiv_class (state_t first_state, int odd_iteration_flag, state_t curr_state; state_t prev_state; state_t next_state; - int out_arcs_num; partition_p = 0; @@ -6108,15 +5958,14 @@ partition_equiv_class (state_t first_state, int odd_iteration_flag, 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. */ @@ -6138,7 +5987,7 @@ partition_equiv_class (state_t first_state, int odd_iteration_flag, clear_arc_insns_equiv_num (first_state); } if (new_equiv_class != NULL) - VEC_safe_push (state_t,heap, *next_iteration_classes, new_equiv_class); + VEC_safe_push (state_t, heap, *next_iteration_classes, new_equiv_class); first_state = new_equiv_class; } return partition_p; @@ -6147,23 +5996,24 @@ partition_equiv_class (state_t first_state, int odd_iteration_flag, /* The function finds equivalent states of AUTOMATON. */ static void evaluate_equiv_classes (automaton_t automaton, - VEC(state_t,heap) **equiv_classes) + VEC(state_t, heap) **equiv_classes) { - state_t new_equiv_class; int new_equiv_class_num; int odd_iteration_flag; int finish_flag; - VEC (state_t,heap) *next_iteration_classes; + VEC (state_t, heap) *next_iteration_classes; size_t i; - all_achieved_states = VEC_alloc (state_t,heap, 1500); + all_achieved_states = VEC_alloc (state_t, heap, 1500); pass_states (automaton, add_achieved_state); - 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 { @@ -6188,13 +6038,13 @@ evaluate_equiv_classes (automaton_t automaton, finish_flag = 0; } while (!finish_flag); - VEC_free (state_t,heap, next_iteration_classes); - VEC_free (state_t,heap, all_achieved_states); + VEC_free (state_t, heap, next_iteration_classes); + VEC_free (state_t, heap, all_achieved_states); } /* The function merges equivalent states of AUTOMATON. */ static void -merge_states (automaton_t automaton, VEC(state_t,heap) *equiv_classes) +merge_states (automaton_t automaton, VEC(state_t, heap) *equiv_classes) { state_t curr_state; state_t new_state; @@ -6261,7 +6111,7 @@ merge_states (automaton_t automaton, VEC(state_t,heap) *equiv_classes) 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; @@ -6309,13 +6159,13 @@ set_new_cycle_flags (state_t state) static void minimize_DFA (automaton_t automaton) { - VEC(state_t,heap) *equiv_classes = 0; + VEC(state_t, heap) *equiv_classes = 0; evaluate_equiv_classes (automaton, &equiv_classes); merge_states (automaton, equiv_classes); pass_states (automaton, set_new_cycle_flags); - VEC_free (state_t,heap, equiv_classes); + VEC_free (state_t, heap, equiv_classes); } /* Values of two variables are counted number of states and arcs in an @@ -6514,7 +6364,7 @@ static void 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)) @@ -6618,11 +6468,11 @@ static int 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; @@ -6644,7 +6494,7 @@ units_to_automata_heuristic_distr (void) 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) @@ -6698,7 +6548,7 @@ create_ainsns (void) 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; @@ -6756,7 +6606,7 @@ create_automata (void) 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; @@ -6777,7 +6627,7 @@ create_automata (void) 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); @@ -6794,7 +6644,7 @@ create_automata (void) } 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; @@ -6855,11 +6705,11 @@ form_regexp (regexp_t regexp) const char *name = (regexp->mode == rm_unit ? REGEXP_UNIT (regexp)->name : REGEXP_RESERV (regexp)->name); - + obstack_grow (&irp, name, strlen (name)); break; } - + case rm_sequence: for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++) { @@ -6885,7 +6735,7 @@ form_regexp (regexp_t regexp) } obstack_1grow (&irp, ')'); break; - + case rm_oneof: for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++) { @@ -6898,11 +6748,11 @@ form_regexp (regexp_t regexp) obstack_1grow (&irp, ')'); } break; - + case rm_repeat: { char digits [30]; - + if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof) @@ -6973,48 +6823,6 @@ output_range_type (FILE *f, long int min_range_value, 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) @@ -7126,53 +6934,6 @@ output_trans_base_vect_name (FILE *f, automaton_t automaton) 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) @@ -7206,9 +6967,6 @@ output_reserved_units_table_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: */ @@ -7219,8 +6977,6 @@ output_reserved_units_table_name (FILE *f, automaton_t automaton) #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" @@ -7238,8 +6994,6 @@ output_reserved_units_table_name (FILE *f, automaton_t automaton) #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" @@ -7256,8 +7010,12 @@ output_reserved_units_table_name (FILE *f, automaton_t automaton) #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" @@ -7299,14 +7057,6 @@ output_reserved_units_table_name (FILE *f, automaton_t automaton) 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 @@ -7350,7 +7100,7 @@ output_translate_vect (automaton_t automaton) int insn_value; vla_hwint_t translate_vect; - translate_vect = VEC_alloc (vect_el_t,heap, description->insns_num); + translate_vect = VEC_alloc (vect_el_t, heap, description->insns_num); for (insn_value = 0; insn_value < description->insns_num; insn_value++) /* Undefined value */ @@ -7371,7 +7121,7 @@ output_translate_vect (automaton_t automaton) fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n"); output_vect (translate_vect); fprintf (output_file, "};\n\n"); - VEC_free (vect_el_t,heap, translate_vect); + VEC_free (vect_el_t, heap, translate_vect); } /* The value in a table state x ainsn -> something which represents @@ -7395,19 +7145,19 @@ create_state_ainsn_table (automaton_t automaton) int full_vect_length; int i; - tab = create_node (sizeof (struct state_ainsn_table)); + tab = XCREATENODE (struct state_ainsn_table); tab->automaton = automaton; - tab->comb_vect = VEC_alloc (vect_el_t,heap, 10000); - tab->check_vect = VEC_alloc (vect_el_t,heap, 10000); + tab->comb_vect = VEC_alloc (vect_el_t, heap, 10000); + tab->check_vect = VEC_alloc (vect_el_t, heap, 10000); tab->base_vect = 0; - VEC_safe_grow (vect_el_t,heap, tab->base_vect, + VEC_safe_grow (vect_el_t, heap, tab->base_vect, automaton->achieved_states_num); full_vect_length = (automaton->insn_equiv_classes_num * automaton->achieved_states_num); - tab->full_vect = VEC_alloc (vect_el_t,heap, full_vect_length); + tab->full_vect = VEC_alloc (vect_el_t, heap, full_vect_length); for (i = 0; i < full_vect_length; i++) VEC_quick_push (vect_el_t, tab->full_vect, undefined_vect_el_value); @@ -7495,7 +7245,7 @@ add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect) { size_t full_base = tab->automaton->insn_equiv_classes_num * vect_num; if (VEC_length (vect_el_t, tab->full_vect) < full_base + vect_length) - VEC_safe_grow (vect_el_t,heap, tab->full_vect, + VEC_safe_grow (vect_el_t, heap, tab->full_vect, full_base + vect_length); for (i = 0; i < vect_length; i++) VEC_replace (vect_el_t, tab->full_vect, full_base + i, @@ -7595,8 +7345,8 @@ add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect) no_state_value = tab->automaton->achieved_states_num; while (additional_els_num > 0) { - VEC_safe_push (vect_el_t,heap, tab->comb_vect, vect_el); - VEC_safe_push (vect_el_t,heap, tab->check_vect, no_state_value); + VEC_safe_push (vect_el_t, heap, tab->comb_vect, vect_el); + VEC_safe_push (vect_el_t, heap, tab->check_vect, no_state_value); additional_els_num--; } gcc_assert (VEC_length (vect_el_t, tab->comb_vect) @@ -7633,7 +7383,7 @@ add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect) /* 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; @@ -7653,11 +7403,11 @@ static int 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) @@ -7679,19 +7429,19 @@ add_vect_el (vla_hwint_t *vect, ainsn_t ainsn, int el_value) for (vect_index = VEC_length (vect_el_t, *vect); vect_index <= equiv_class_num; vect_index++) - VEC_safe_push (vect_el_t,heap, *vect, undefined_vect_el_value); + VEC_safe_push (vect_el_t, heap, *vect, undefined_vect_el_value); VEC_replace (vect_el_t, *vect, equiv_class_num, el_value); } /* This is for forming vector of states of an automaton. */ -static VEC(state_t,heap) *output_states_vect; +static VEC(state_t, heap) *output_states_vect; /* The function is called by function pass_states. The function adds STATE to `output_states_vect'. */ static void add_states_vect_el (state_t state) { - VEC_safe_push (state_t,heap, output_states_vect, state); + VEC_safe_push (state_t, heap, output_states_vect, state); } /* Form and output vectors (comb, check, base or full vector) @@ -7734,56 +7484,8 @@ output_trans_table (automaton_t automaton) output_trans_full_vect_name, output_trans_comb_vect_name, output_trans_check_vect_name, output_trans_base_vect_name); - VEC_free (state_t,heap, output_states_vect); - VEC_free (vect_el_t,heap, transition_vect); -} - -/* 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); + VEC_free (state_t, heap, output_states_vect); + VEC_free (vect_el_t, heap, transition_vect); } /* The current number of passing states to find minimal issue delay @@ -7873,7 +7575,7 @@ output_min_issue_delay_table (automaton_t automaton) min_issue_delay_len = (VEC_length (state_t, output_states_vect) * automaton->insn_equiv_classes_num); - min_issue_delay_vect = VEC_alloc (vect_el_t,heap, min_issue_delay_len); + min_issue_delay_vect = VEC_alloc (vect_el_t, heap, min_issue_delay_len); for (i = 0; i < min_issue_delay_len; i++) VEC_quick_push (vect_el_t, min_issue_delay_vect, 0); @@ -7915,7 +7617,7 @@ output_min_issue_delay_table (automaton_t automaton) compressed_min_issue_delay_len = (min_issue_delay_len+cfactor-1) / cfactor; compressed_min_issue_delay_vect - = VEC_alloc (vect_el_t,heap, compressed_min_issue_delay_len); + = VEC_alloc (vect_el_t, heap, compressed_min_issue_delay_len); for (i = 0; i < compressed_min_issue_delay_len; i++) VEC_quick_push (vect_el_t, compressed_min_issue_delay_vect, 0); @@ -7931,9 +7633,9 @@ output_min_issue_delay_table (automaton_t automaton) } output_vect (compressed_min_issue_delay_vect); fprintf (output_file, "};\n\n"); - VEC_free (state_t,heap, output_states_vect); - VEC_free (vect_el_t,heap, min_issue_delay_vect); - VEC_free (vect_el_t,heap, compressed_min_issue_delay_vect); + VEC_free (state_t, heap, output_states_vect); + VEC_free (vect_el_t, heap, min_issue_delay_vect); + VEC_free (vect_el_t, heap, compressed_min_issue_delay_vect); } /* Form and output vector representing the locked states of @@ -7952,7 +7654,7 @@ output_dead_lock_vect (automaton_t automaton) output_states_vect = 0; pass_states (automaton, add_states_vect_el); - VEC_safe_grow (vect_el_t,heap, dead_lock_vect, + VEC_safe_grow (vect_el_t, heap, dead_lock_vect, VEC_length (state_t, output_states_vect)); for (i = 0; i < VEC_length (state_t, output_states_vect); i++) { @@ -7980,8 +7682,8 @@ output_dead_lock_vect (automaton_t automaton) fprintf (output_file, "[] = {\n"); output_vect (dead_lock_vect); fprintf (output_file, "};\n\n"); - VEC_free (state_t,heap, output_states_vect); - VEC_free (vect_el_t,heap, dead_lock_vect); + VEC_free (state_t, heap, output_states_vect); + VEC_free (vect_el_t, heap, dead_lock_vect); } /* Form and output vector representing reserved units of the states of @@ -7995,6 +7697,9 @@ output_reserved_units_table (automaton_t automaton) 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); @@ -8003,8 +7708,8 @@ output_reserved_units_table (automaton_t automaton) reserved_units_size = (VEC_length (state_t, output_states_vect) * state_byte_size); - reserved_units_table = VEC_alloc (vect_el_t,heap, reserved_units_size); - + reserved_units_table = VEC_alloc (vect_el_t, heap, reserved_units_size); + for (i = 0; i < reserved_units_size; i++) VEC_quick_push (vect_el_t, reserved_units_table, 0); for (n = 0; n < VEC_length (state_t, output_states_vect); n++) @@ -8022,6 +7727,7 @@ output_reserved_units_table (automaton_t automaton) 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); @@ -8029,10 +7735,11 @@ output_reserved_units_table (automaton_t automaton) 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); + VEC_free (state_t, heap, output_states_vect); + VEC_free (vect_el_t, heap, reserved_units_table); } /* The function outputs all tables representing DFA(s) used for fast @@ -8049,16 +7756,9 @@ output_tables (void) { 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); @@ -8359,8 +8059,8 @@ dfa_insn_code_enlarge (int uid)\n\ {\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, @@ -8405,101 +8105,8 @@ output_trans_func (void) 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'. */ @@ -8517,9 +8124,9 @@ output_min_issue_delay_func (void) 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"); } @@ -8552,8 +8159,8 @@ output_dead_lock_func (void) { 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'. */ @@ -8580,8 +8187,8 @@ output_reset_func (void) { 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'. */ @@ -8611,13 +8218,13 @@ output_min_insn_conflict_delay_func (void) 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 @@ -8633,18 +8240,6 @@ output_internal_insn_latency_func (void) 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); @@ -8661,6 +8256,27 @@ output_internal_insn_latency_func (void) } 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, @@ -8685,19 +8301,32 @@ output_internal_insn_latency_func (void) (advance_cycle_insn_decl)->insn_num)); fprintf (output_file, " case %d:\n", bypass->in_insn_reserv->insn_num); - if (bypass->bypass_guard_name == NULL) - fprintf (output_file, " return %d;\n", - bypass->latency); - else + for (;;) { - fprintf (output_file, - " if (%s (%s, %s))\n", - bypass->bypass_guard_name, INSN_PARAMETER_NAME, - INSN2_PARAMETER_NAME); - fprintf (output_file, - " return %d;\n break;\n", - bypass->latency); + if (bypass->bypass_guard_name == NULL) + { + gcc_assert (bypass->next == NULL + || (bypass->in_insn_reserv + != bypass->next->in_insn_reserv)); + fprintf (output_file, " return %d;\n", + bypass->latency); + } + else + { + fprintf (output_file, + " if (%s (%s, %s))\n", + bypass->bypass_guard_name, INSN_PARAMETER_NAME, + INSN2_PARAMETER_NAME); + fprintf (output_file, " return %d;\n", + bypass->latency); + } + if (bypass->next == NULL + || bypass->in_insn_reserv != bypass->next->in_insn_reserv) + break; + bypass = bypass->next; } + if (bypass->bypass_guard_name != NULL) + fprintf (output_file, " break;\n"); } fputs (" }\n break;\n", output_file); } @@ -8706,6 +8335,50 @@ output_internal_insn_latency_func (void) 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) @@ -8724,6 +8397,21 @@ 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) @@ -8754,7 +8442,7 @@ output_print_reservation_func (void) { gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num); j++; - + fprintf (output_file, "\n \"%s\",", regexp_representation (DECL_INSN_RESERV (decl)->regexp)); finish_regexp_representation (); @@ -8788,8 +8476,8 @@ 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); } @@ -8828,7 +8516,7 @@ output_get_cpu_unit_code_func (void) 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++) @@ -8875,23 +8563,61 @@ output_cpu_unit_reservation_p (void) 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) { @@ -8903,6 +8629,16 @@ 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'. */ @@ -8912,7 +8648,7 @@ output_dfa_start_func (void) fprintf (output_file, "void\n%s (void)\n{\n %s = get_max_uid ();\n", DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME); - fprintf (output_file, " %s = xmalloc (%s * sizeof (int));\n", + fprintf (output_file, " %s = XNEWVEC (int, %s);\n", DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME); fprintf (output_file, " %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME); } @@ -8984,7 +8720,7 @@ output_description (void) { 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"); @@ -9108,7 +8844,7 @@ output_automaton_units (automaton_t automaton) /* The following variable is used for forming array of all possible cpu unit reservations described by the current DFA state. */ -static VEC(reserv_sets_t,heap) *state_reservs; +static VEC(reserv_sets_t, heap) *state_reservs; /* The function forms `state_reservs' for STATE. */ static void @@ -9122,7 +8858,7 @@ add_state_reservs (state_t state) curr_alt_state = curr_alt_state->next_sorted_alt_state) add_state_reservs (curr_alt_state->state); else - VEC_safe_push (reserv_sets_t,heap, state_reservs, state->reservs); + VEC_safe_push (reserv_sets_t, heap, state_reservs, state->reservs); } /* The function outputs readable representation of all out arcs of @@ -9168,8 +8904,8 @@ output_state_arcs (state_t state) 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"); } @@ -9179,8 +8915,8 @@ output_state_arcs (state_t state) 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 @@ -9220,7 +8956,7 @@ output_state (state_t state) VEC_length (reserv_sets_t, state_reservs), sizeof (reserv_sets_t), state_reservs_cmp); remove_state_duplicate_reservs (); - for (i = 1; i < VEC_length (reserv_sets_t, state_reservs); i++) + for (i = 0; i < VEC_length (reserv_sets_t, state_reservs); i++) { fprintf (output_description_file, " "); output_reserv_sets (output_description_file, @@ -9229,7 +8965,7 @@ output_state (state_t state) } fprintf (output_description_file, "\n"); output_state_arcs (state); - VEC_free (reserv_sets_t,heap, state_reservs); + VEC_free (reserv_sets_t, heap, state_reservs); } /* The following function output readable representation of @@ -9266,8 +9002,6 @@ output_statistics (FILE *f) #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 @@ -9301,12 +9035,6 @@ output_statistics (FILE *f) (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); @@ -9314,10 +9042,6 @@ output_statistics (FILE *f) += 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 @@ -9331,9 +9055,6 @@ output_statistics (FILE *f) 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 @@ -9386,160 +9107,6 @@ generate (void) -/* 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); -} - - - -/* 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); -} - - - -/* 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); -} - - - -/* 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); -} - - - /* This page mainly contains top level functions of pipeline hazards description translator. */ @@ -9582,7 +9149,7 @@ base_file_name (const char *file_name) /* 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; @@ -9592,6 +9159,7 @@ initiate_automaton_gen (int argc, char **argv) split_argument = 0; /* default value */ no_minimization_flag = 0; time_flag = 0; + stats_flag = 0; v_flag = 0; w_flag = 0; progress_flag = 0; @@ -9600,6 +9168,8 @@ initiate_automaton_gen (int argc, char **argv) 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) @@ -9660,10 +9230,9 @@ check_automata_insn_issues (void) automaton->corresponding_automaton_decl->name, reserv_ainsn->insn_reserv_decl->name); else - warning - (0, "Automaton `%s': Insn `%s' will never be issued", - automaton->corresponding_automaton_decl->name, - reserv_ainsn->insn_reserv_decl->name); + warning ("Automaton `%s': Insn `%s' will never be issued", + automaton->corresponding_automaton_decl->name, + reserv_ainsn->insn_reserv_decl->name); } else { @@ -9671,7 +9240,7 @@ check_automata_insn_issues (void) error ("Insn `%s' will never be issued", reserv_ainsn->insn_reserv_decl->name); else - warning (0, "Insn `%s' will never be issued", + warning ("Insn `%s' will never be issued", reserv_ainsn->insn_reserv_decl->name); } } @@ -9680,14 +9249,14 @@ check_automata_insn_issues (void) /* The following vla is used for storing pointers to all achieved states. */ -static VEC(state_t,heap) *automaton_states; +static VEC(state_t, heap) *automaton_states; /* This function is called by function pass_states to add an achieved STATE. */ static void add_automaton_state (state_t state) { - VEC_safe_push (state_t,heap, automaton_states, state); + VEC_safe_push (state_t, heap, automaton_states, state); } /* The following function forms list of important automata (whose @@ -9726,7 +9295,7 @@ form_important_insn_automata_lists (void) } } } - VEC_free (state_t,heap, automaton_states); + VEC_free (state_t, heap, automaton_states); /* Create automata sets for the insns. */ for (i = 0; i < description->decls_num; i++) @@ -9756,14 +9325,15 @@ form_important_insn_automata_lists (void) /* 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++) @@ -9796,31 +9366,15 @@ expand_automata (void) 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..."); @@ -9840,11 +9394,6 @@ write_automata (void) 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 (); @@ -9852,13 +9401,17 @@ write_automata (void) 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 (); @@ -9882,9 +9435,11 @@ write_automata (void) 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 (); @@ -9904,8 +9459,8 @@ write_automata (void) { 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 (); @@ -9915,3 +9470,112 @@ write_automata (void) 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; + + if (VEC_length (decl_t, decls) > 0) + { + expand_automata (); + if (!have_error) + { + puts ("/* Generated automatically by the program `genautomata'\n" + " from the machine description file `md'. */\n\n" + "#include \"config.h\"\n" + "#include \"system.h\"\n" + "#include \"coretypes.h\"\n" + "#include \"tm.h\"\n" + "#include \"rtl.h\"\n" + "#include \"tm_p.h\"\n" + "#include \"insn-config.h\"\n" + "#include \"recog.h\"\n" + "#include \"regs.h\"\n" + "#include \"output.h\"\n" + "#include \"insn-attr.h\"\n" + "#include \"toplev.h\"\n" + "#include \"flags.h\"\n" + "#include \"function.h\"\n"); + + write_automata (); + } + } + + fflush (stdout); + return (ferror (stdout) != 0 || have_error + ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); +}