OSDN Git Service

2008-12-12 Benjamin Kosnik <bkoz@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / genautomata.c
index 38a1718..d314b8f 100644 (file)
@@ -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
    Free Software Foundation, Inc.
 
    Written by Vladimir Makarov <vmakarov@redhat.com>
@@ -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,9 +17,8 @@ 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
+<http://www.gnu.org/licenses/>.  */
 
 /* References:
 
@@ -109,18 +108,16 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "rtl.h"
 #include "obstack.h"
 #include "errors.h"
+#include "gensupport.h"
 
 #include <math.h>
 #include "hashtab.h"
-#include "varray.h"
 #include "vec.h"
 
 #ifndef CHAR_BIT
 #define CHAR_BIT 8
 #endif
 
-#include "genattrtab.h"
-
 /* Positions in machine description file.  Now they are not used.  But
    they could be used in the future for better diagnostic messages.  */
 typedef int pos_t;
@@ -132,6 +129,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 +182,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;
 
@@ -531,21 +223,30 @@ DEF_VEC_I(vect_el_t);
 DEF_VEC_ALLOC_I(vect_el_t, heap);
 typedef VEC(vect_el_t,heap) *vla_hwint_t;
 \f
+/* Forward declarations of functions used before their definitions, only.  */
+static regexp_t gen_regexp_sequence    (const char *);
+static void reserv_sets_or             (reserv_sets_t, reserv_sets_t,
+                                       reserv_sets_t);
+static reserv_sets_t get_excl_set      (reserv_sets_t);
+static int check_presence_pattern_sets (reserv_sets_t,
+                                       reserv_sets_t, int);
+static int check_absence_pattern_sets  (reserv_sets_t, reserv_sets_t,
+                                       int);
+static arc_t first_out_arc             (const_state_t);
+static arc_t next_out_arc              (arc_t);
+
+\f
 
 /* Options with the following names can be set up in automata_option
    construction.  Because the strings occur more one time we use the
    macros.  */
 
 #define NO_MINIMIZATION_OPTION "-no-minimization"
-
 #define TIME_OPTION "-time"
-
+#define STATS_OPTION "-stats"
 #define V_OPTION "-v"
-
 #define W_OPTION "-w"
-
 #define NDFA_OPTION "-ndfa"
-
 #define PROGRESS_OPTION "-progress"
 
 /* The following flags are set up by function `initiate_automaton_gen'.  */
@@ -566,6 +267,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;
@@ -767,7 +471,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 +484,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 +680,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 +704,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 +715,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 +734,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 +831,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 +877,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 +1085,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)
@@ -1541,7 +1237,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 +1250,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);
@@ -1563,7 +1259,6 @@ gen_cpu_unit (rtx def)
       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++;
     }
 }
 
@@ -1571,7 +1266,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 +1280,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++;
     }
 }
 
@@ -1601,7 +1295,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,7 +1314,7 @@ 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);
@@ -1628,7 +1322,6 @@ gen_bypass (rtx def)
        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++;
       }
 }
 
@@ -1637,7 +1330,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 +1349,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;
@@ -1668,7 +1361,6 @@ gen_excl_set (rtx def)
       DECL_EXCL (decl)->names [i]
        = second_str_cpu_units [i - first_vect_length];
   VEC_safe_push (decl_t,heap, decls, decl);
-  num_dfa_decls++;
 }
 
 /* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
@@ -1710,14 +1402,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)
     {
@@ -1738,7 +1430,6 @@ gen_presence_absence_set (rtx def, int presence_p, int final_p)
       DECL_ABSENCE (decl)->final_p = final_p;
     }
   VEC_safe_push (decl_t,heap, decls, decl);
-  num_dfa_decls++;
 }
 
 /* Process a PRESENCE_SET.
@@ -1746,7 +1437,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 +1448,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 +1459,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 +1470,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 +1481,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 +1494,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++;
     }
 }
 
@@ -1816,13 +1506,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 +1547,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 +1584,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 +1613,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 +1639,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 +1663,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 +1689,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++;
 }
 
 /* Process a DEFINE_INSN_RESERVATION.
@@ -2016,12 +1707,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
@@ -2030,7 +1721,6 @@ gen_insn_reserv (rtx def)
   DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
   DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3));
   VEC_safe_push (decl_t,heap, decls, decl);
-  num_dfa_decls++;
 }
 
 \f
@@ -2059,7 +1749,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 +1764,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
@@ -2160,7 +1850,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 +1863,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
@@ -2258,7 +1948,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 +1962,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));
@@ -2370,7 +2060,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 +2113,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 +2160,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 +2195,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));
@@ -2652,7 +2343,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)
                  {
@@ -2732,8 +2423,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);
@@ -2984,7 +2673,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;
@@ -3425,7 +3114,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 +3124,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++;
 }
 
 \f
@@ -3469,7 +3157,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 +3195,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;
@@ -3701,11 +3389,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 +3415,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 +3440,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 +3626,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 +3667,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 +3681,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 +3692,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)
@@ -4127,7 +3796,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 +3867,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 +3884,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 +3899,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 +3914,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 +3973,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 +4010,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 +4026,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)
@@ -4532,7 +4200,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 +4256,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 +4273,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 +4305,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 +4321,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 +4371,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 <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
        REGEXP_SEQUENCE (result)->regexps [i]
          = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
       break;
 
     case rm_allof:
-      result = copy_node (regexp,
-                          sizeof (struct regexp) + sizeof (regexp_t)
-                         * (REGEXP_ALLOF (regexp)->regexps_num - 1));
+      result = XCOPYNODEVAR (struct regexp, regexp,
+                            sizeof (struct regexp) + sizeof (regexp_t)
+                            * (REGEXP_ALLOF (regexp)->regexps_num - 1));
       for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
        REGEXP_ALLOF (result)->regexps [i]
          = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
       break;
 
     case rm_oneof:
-      result = copy_node (regexp,
-                          sizeof (struct regexp) + sizeof (regexp_t)
-                         * (REGEXP_ONEOF (regexp)->regexps_num - 1));
+      result = XCOPYNODEVAR (struct regexp, regexp,
+                            sizeof (struct regexp) + sizeof (regexp_t)
+                            * (REGEXP_ONEOF (regexp)->regexps_num - 1));
       for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
        REGEXP_ONEOF (result)->regexps [i]
          = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
       break;
 
     case rm_nothing:
-      result = copy_node (regexp, sizeof (struct regexp));
+      result = XCOPYNODE (struct regexp, regexp);
       break;
 
     default:
@@ -4769,8 +4437,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 +4474,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 +4518,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 +4561,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 +4616,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 +4626,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 +4668,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 +4678,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 +4723,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;
@@ -5093,9 +4761,9 @@ transform_3 (regexp_t regexp)
                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;
@@ -5702,22 +5370,17 @@ make_automaton (automaton_t automaton)
                            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
@@ -5734,12 +5397,12 @@ make_automaton (automaton_t automaton)
            fprintf (stderr, ".");
         }
       gcc_assert (advance_cycle_ainsn);
-      add_arc (state, state2, advance_cycle_ainsn, 1);
+      add_arc (state, state2, advance_cycle_ainsn);
     }
   VEC_free (state_t,heap, state_stack);
 }
 
-/* Foms lists of all arcs of STATE marked by the same ainsn.  */
+/* Form lists of all arcs of STATE marked by the same ainsn.  */
 static void
 form_arcs_marked_by_insn (state_t state)
 {
@@ -5842,7 +5505,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,7 +5517,6 @@ 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)
@@ -5959,27 +5621,20 @@ add_achieved_state (state_t state)
    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 +5645,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 +5669,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,53 +5696,89 @@ 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
@@ -6081,6 +5789,7 @@ 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);
 }
+
 /* 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
@@ -6098,7 +5807,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 +5816,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.  */
@@ -6149,7 +5856,6 @@ static void
 evaluate_equiv_classes (automaton_t automaton,
                        VEC(state_t,heap) **equiv_classes)
 {
-  state_t new_equiv_class;
   int new_equiv_class_num;
   int odd_iteration_flag;
   int finish_flag;
@@ -6158,12 +5864,14 @@ evaluate_equiv_classes (automaton_t automaton,
 
   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
     {
@@ -6261,7 +5969,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;
@@ -6514,7 +6222,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 +6326,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 +6352,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 +6406,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 +6464,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 +6485,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 +6502,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;
@@ -6973,48 +6681,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 +6792,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 +6825,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 +6835,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 +6852,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 +6868,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 +6915,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
@@ -7395,7 +7003,7 @@ 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);
@@ -7633,7 +7241,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 +7261,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)
@@ -7738,54 +7346,6 @@ output_trans_table (automaton_t automaton)
   VEC_free (vect_el_t,heap, transition_vect);
 }
 
-/* Form and output vectors (comb, check, base or simple vect)
-   representing alts number table of AUTOMATON.  The table is state x
-   ainsn -> number of possible alternative reservations by the
-   ainsn.  */
-static void
-output_state_alts_table (automaton_t automaton)
-{
-  size_t i;
-  arc_t arc;
-  vla_hwint_t state_alts_vect;
-
-  undefined_vect_el_value = 0; /* no alts when transition is not possible */
-  automaton->state_alts_table = create_state_ainsn_table (automaton);
-  /* Create vect of pointers to states ordered by num of transitions
-     from the state (state with the maximum num is the first).  */
-  output_states_vect = 0;
-  pass_states (automaton, add_states_vect_el);
-  qsort (VEC_address (state_t, output_states_vect),
-        VEC_length (state_t, output_states_vect),
-         sizeof (state_t), compare_transition_els_num);
-
-  /* Create base, comb, and check vectors.  */
-  state_alts_vect = 0;
-
-  for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
-    {
-      VEC_truncate (vect_el_t, state_alts_vect, 0);
-      for (arc = first_out_arc (VEC_index (state_t, output_states_vect, i));
-          arc != NULL;
-          arc = next_out_arc (arc))
-        {
-          gcc_assert (arc->insn);
-          if (arc->insn->first_ainsn_with_given_equivalence_num)
-            add_vect_el (&state_alts_vect, arc->insn, arc->state_alts);
-        }
-      add_vect (automaton->state_alts_table,
-               VEC_index (state_t, output_states_vect, i)->order_state_num,
-                state_alts_vect);
-    }
-  output_state_ainsn_table
-    (automaton->state_alts_table, "state insn alternatives",
-     output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
-     output_state_alts_check_vect_name, output_state_alts_base_vect_name);
-
-  VEC_free (state_t,heap, output_states_vect);
-  VEC_free (vect_el_t,heap, state_alts_vect);
-}
-
 /* The current number of passing states to find minimal issue delay
    value for an ainsn and state.  */
 static int curr_state_pass_num;
@@ -7995,6 +7555,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);
@@ -8022,6 +7585,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,7 +7593,8 @@ 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);
@@ -8049,16 +7614,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 +7917,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 +7963,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 +7982,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 +8017,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 +8045,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 +8076,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 +8098,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 +8114,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,
@@ -8706,6 +8180,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 +8242,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)
@@ -8788,8 +8321,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 +8361,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 +8408,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 +8474,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 +8493,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 +8565,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");
@@ -9168,8 +8749,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 +8760,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
@@ -9266,8 +8847,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 +8880,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 +8887,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 +8900,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 +8952,6 @@ generate (void)
 
 \f
 
-/* The following function creates insn attribute whose values are
-   number alternatives in insn reservations.  */
-static void
-make_insn_alts_attr (void)
-{
-  int i, insn_num;
-  decl_t decl;
-  rtx condexp;
-
-  condexp = rtx_alloc (COND);
-  XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
-  XEXP (condexp, 1) = make_numeric_value (0);
-  for (i = insn_num = 0; i < description->decls_num; i++)
-    {
-      decl = description->decls [i];
-      if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
-       {
-          XVECEXP (condexp, 0, 2 * insn_num)
-           = DECL_INSN_RESERV (decl)->condexp;
-          XVECEXP (condexp, 0, 2 * insn_num + 1)
-            = make_numeric_value
-             (DECL_INSN_RESERV (decl)->transformed_regexp->mode != rm_oneof
-              ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl)
-                                  ->transformed_regexp)->regexps_num);
-          insn_num++;
-        }
-    }
-  gcc_assert (description->insns_num == insn_num + 1);
-  make_internal_attr (attr_printf (sizeof ("*")
-                                  + strlen (INSN_ALTS_FUNC_NAME) + 1,
-                                  "*%s", INSN_ALTS_FUNC_NAME),
-                     condexp, ATTR_NONE);
-}
-
-\f
-
-/* The following function creates attribute which is order number of
-   insn in pipeline hazard description translator.  */
-static void
-make_internal_dfa_insn_code_attr (void)
-{
-  int i, insn_num;
-  decl_t decl;
-  rtx condexp;
-
-  condexp = rtx_alloc (COND);
-  XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
-  XEXP (condexp, 1)
-    = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl)
-                         ->insn_num + 1);
-  for (i = insn_num = 0; i < description->decls_num; i++)
-    {
-      decl = description->decls [i];
-      if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
-       {
-          XVECEXP (condexp, 0, 2 * insn_num)
-           = DECL_INSN_RESERV (decl)->condexp;
-          XVECEXP (condexp, 0, 2 * insn_num + 1)
-            = make_numeric_value (DECL_INSN_RESERV (decl)->insn_num);
-          insn_num++;
-        }
-    }
-  gcc_assert (description->insns_num == insn_num + 1);
-  make_internal_attr
-    (attr_printf (sizeof ("*")
-                 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
-                 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
-     condexp, ATTR_STATIC);
-}
-
-\f
-
-/* The following function creates attribute which order number of insn
-   in pipeline hazard description translator.  */
-static void
-make_default_insn_latency_attr (void)
-{
-  int i, insn_num;
-  decl_t decl;
-  rtx condexp;
-
-  condexp = rtx_alloc (COND);
-  XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
-  XEXP (condexp, 1) = make_numeric_value (0);
-  for (i = insn_num = 0; i < description->decls_num; i++)
-    {
-      decl = description->decls [i];
-      if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
-       {
-          XVECEXP (condexp, 0, 2 * insn_num)
-           = DECL_INSN_RESERV (decl)->condexp;
-          XVECEXP (condexp, 0, 2 * insn_num + 1)
-            = make_numeric_value (DECL_INSN_RESERV (decl)->default_latency);
-          insn_num++;
-        }
-    }
-  gcc_assert (description->insns_num == insn_num + 1);
-  make_internal_attr (attr_printf (sizeof ("*")
-                                  + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
-                                  + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
-                     condexp, ATTR_NONE);
-}
-
-\f
-
-/* The following function creates attribute which returns 1 if given
-   output insn has bypassing and 0 otherwise.  */
-static void
-make_bypass_attr (void)
-{
-  int i, bypass_insn;
-  int bypass_insns_num = 0;
-  decl_t decl;
-  rtx result_rtx;
-
-  for (i = 0; i < description->decls_num; i++)
-    {
-      decl = description->decls [i];
-      if (decl->mode == dm_insn_reserv
-         && DECL_INSN_RESERV (decl)->condexp != NULL
-         && DECL_INSN_RESERV (decl)->bypass_list != NULL)
-       bypass_insns_num++;
-    }
-  if (bypass_insns_num == 0)
-    result_rtx = make_numeric_value (0);
-  else
-    {
-      result_rtx = rtx_alloc (COND);
-      XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
-      XEXP (result_rtx, 1) = make_numeric_value (0);
-
-      for (i = bypass_insn = 0; i < description->decls_num; i++)
-        {
-          decl = description->decls [i];
-          if (decl->mode == dm_insn_reserv
-             && DECL_INSN_RESERV (decl)->condexp != NULL
-             && DECL_INSN_RESERV (decl)->bypass_list != NULL)
-           {
-              XVECEXP (result_rtx, 0, 2 * bypass_insn)
-               = DECL_INSN_RESERV (decl)->condexp;
-              XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
-               = make_numeric_value (1);
-              bypass_insn++;
-            }
-        }
-    }
-  make_internal_attr (attr_printf (sizeof ("*")
-                                  + strlen (BYPASS_P_FUNC_NAME) + 1,
-                                  "*%s", BYPASS_P_FUNC_NAME),
-                     result_rtx, ATTR_NONE);
-}
-
-\f
-
 /* This page mainly contains top level functions of pipeline hazards
    description translator.  */
 
@@ -9582,7 +8994,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 +9004,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 +9013,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)
@@ -9756,14 +9171,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 +9212,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 +9240,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 +9247,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 +9281,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 +9305,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 +9316,109 @@ 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;
+
+  puts ("/* Generated automatically by the program `genautomata'\n"
+       "   from the machine description file `md'.  */\n\n"
+       "#include \"config.h\"\n"
+       "#include \"system.h\"\n"
+       "#include \"coretypes.h\"\n"
+       "#include \"tm.h\"\n"
+       "#include \"rtl.h\"\n"
+       "#include \"tm_p.h\"\n"
+       "#include \"insn-config.h\"\n"
+       "#include \"recog.h\"\n"
+       "#include \"regs.h\"\n"
+       "#include \"real.h\"\n"
+       "#include \"output.h\"\n"
+       "#include \"insn-attr.h\"\n"
+       "#include \"toplev.h\"\n"
+       "#include \"flags.h\"\n"
+       "#include \"function.h\"\n");
+
+  if (VEC_length (decl_t, decls) > 0)
+    {
+      expand_automata ();
+      write_automata ();
+    }
+
+  fflush (stdout);
+  return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
+}