OSDN Git Service

* config/s390/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New.
[pf3gnuchains/gcc-fork.git] / gcc / genautomata.c
index f4fc572..900cfb6 100644 (file)
@@ -1,5 +1,5 @@
 /* Pipeline hazard description translator.
-   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
 
    Written by Vladimir Makarov <vmakarov@redhat.com>
    
@@ -195,6 +195,7 @@ struct automaton;
 struct state_ainsn_table;
 
 /* The following typedefs are for brevity.  */
+typedef struct unit_decl *unit_decl_t;
 typedef struct decl *decl_t;
 typedef struct regexp *regexp_t;
 typedef struct unit_set_el *unit_set_el_t;
@@ -203,6 +204,7 @@ typedef struct state *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 struct state_ainsn_table *state_ainsn_table_t;
 
 
@@ -328,6 +330,17 @@ static arc_t next_out_arc      PARAMS ((arc_t));
 static void initiate_arcs      PARAMS ((void));
 static void finish_arcs        PARAMS ((void));
 
+static automata_list_el_t get_free_automata_list_el PARAMS ((void));
+static void free_automata_list_el PARAMS ((automata_list_el_t));
+static void free_automata_list PARAMS ((automata_list_el_t));
+static unsigned automata_list_hash PARAMS ((const void *));
+static int automata_list_eq_p PARAMS ((const void *, const void *));
+static void initiate_automata_lists PARAMS ((void));
+static void automata_list_start PARAMS ((void));
+static void automata_list_add PARAMS ((automaton_t));
+static automata_list_el_t automata_list_finish PARAMS ((void));
+static void finish_automata_lists PARAMS ((void));
+
 static void initiate_excl_sets             PARAMS ((void));
 static reserv_sets_t get_excl_set          PARAMS ((reserv_sets_t));
 
@@ -343,6 +356,12 @@ static regexp_t regexp_transform_func
 static regexp_t transform_regexp            PARAMS ((regexp_t));
 static void transform_insn_regexps          PARAMS ((void));
 
+static void process_unit_to_form_the_same_automaton_unit_lists
+                                            PARAMS ((regexp_t, regexp_t, int));
+static void form_the_same_automaton_unit_lists_from_regexp PARAMS ((regexp_t));
+static void form_the_same_automaton_unit_lists PARAMS ((void));
+static void check_unit_distributions_to_automata PARAMS ((void));
+
 static int process_seq_for_forming_states   PARAMS ((regexp_t, automaton_t,
                                                     int));
 static void finish_forming_alt_state        PARAMS ((alt_state_t,
@@ -436,7 +455,7 @@ static void add_vect_el              PARAMS ((vla_hwint_t *,
 static void add_states_vect_el           PARAMS ((state_t));
 static void output_trans_table           PARAMS ((automaton_t));
 static void output_state_alts_table      PARAMS ((automaton_t));
-static void min_issue_delay_pass_states  PARAMS ((state_t, ainsn_t));
+static int min_issue_delay_pass_states  PARAMS ((state_t, ainsn_t));
 static int min_issue_delay               PARAMS ((state_t, ainsn_t));
 static void initiate_min_issue_delay_pass_states PARAMS ((void));
 static void output_min_issue_delay_table PARAMS ((automaton_t));
@@ -444,12 +463,16 @@ static void output_dead_lock_vect        PARAMS ((automaton_t));
 static void output_reserved_units_table  PARAMS ((automaton_t));
 static void output_tables                PARAMS ((void));
 static void output_max_insn_queue_index_def PARAMS ((void));
+static void output_insn_code_cases   PARAMS ((void (*) (automata_list_el_t)));
+static void output_automata_list_min_issue_delay_code PARAMS ((automata_list_el_t));
 static void output_internal_min_issue_delay_func PARAMS ((void));
+static void output_automata_list_transition_code PARAMS ((automata_list_el_t));
 static void output_internal_trans_func   PARAMS ((void));
 static void output_internal_insn_code_evaluation PARAMS ((const char *,
                                                          const char *, int));
 static void output_dfa_insn_code_func          PARAMS ((void));
 static void output_trans_func                   PARAMS ((void));
+static void output_automata_list_state_alts_code PARAMS ((automata_list_el_t));
 static void output_internal_state_alts_func     PARAMS ((void));
 static void output_state_alts_func              PARAMS ((void));
 static void output_min_issue_delay_func         PARAMS ((void));
@@ -485,13 +508,15 @@ static void output_statistics              PARAMS ((FILE *));
 static void output_time_statistics         PARAMS ((FILE *));
 static void generate                       PARAMS ((void));
 
-static void make_insn_alts_attr               PARAMS ((void));
-static void make_internal_dfa_insn_code_attr  PARAMS ((void));
-static void make_default_insn_latency_attr    PARAMS ((void));
-static void make_bypass_attr                  PARAMS ((void));
-static const char *file_name_suffix           PARAMS ((const char *));
-static const char *base_file_name             PARAMS ((const char *));
-static void check_automata                   PARAMS ((void));
+static void make_insn_alts_attr                PARAMS ((void));
+static void make_internal_dfa_insn_code_attr   PARAMS ((void));
+static void make_default_insn_latency_attr     PARAMS ((void));
+static void make_bypass_attr                   PARAMS ((void));
+static const char *file_name_suffix            PARAMS ((const char *));
+static const char *base_file_name              PARAMS ((const char *));
+static void check_automata_insn_issues        PARAMS ((void));
+static void add_automaton_state                PARAMS ((state_t));
+static void form_important_insn_automata_lists PARAMS ((void));
 
 /* Undefined position.  */
 static pos_t no_pos = 0;
@@ -696,6 +721,15 @@ struct unit_decl
   /* The following field value is nonzero if the unit is used in an
      regexp.  */
   char unit_is_used;
+
+  /* The following field value is used to form cyclic lists of units
+     which should be in the same automaton because the unit is
+     reserved not on all alternatives of a regexp on a cycle.  */
+  unit_decl_t the_same_automaton_unit;
+  /* The following field is TRUE if we already reported that the unit
+     is not in the same automaton.  */
+  int the_same_automaton_message_reported_p;
+
   /* The following field value is order number (0, 1, ...) of given
      unit.  */
   int unit_num;
@@ -828,6 +862,11 @@ struct insn_reserv_decl
      during an automaton minimization) and marked by given insn
      enters.  */
   int state_alts;
+  /* The following member value is the list to automata which can be
+     changed by the insn issue.  */
+  automata_list_el_t important_automata_list;
+  /* The following member is used to process insn once for output.  */
+  int processed_p;
 };
 
 /* This contains a declaration mentioned above.  */
@@ -865,7 +904,7 @@ enum regexp_mode
 struct unit_regexp
 {
   char *name;
-  struct unit_decl *unit_decl;
+  unit_decl_t unit_decl;
 };
 
 /* Define_reservation in a reservation.  */
@@ -970,7 +1009,7 @@ struct description
    presence_list, absence_list.  */
 struct unit_set_el
 {
-  struct unit_decl *unit_decl;
+  unit_decl_t unit_decl;
   unit_set_el_t next_unit_set_el;
 };
 
@@ -1040,7 +1079,7 @@ struct state
 };
 
 /* The following macro is an initial value of member
-   `longest_path_length' of a state. */
+   `longest_path_length' of a state.  */
 #define UNDEFINED_LONGEST_PATH_LENGTH -1
 
 /* Automaton arc.  */
@@ -1111,7 +1150,7 @@ struct ainsn
   /* The following member has nonzero value if there is arc from state of
      the automaton marked by the ainsn.  */
   char arc_exists_p;
-  /* Cyclic list of insns of a equivalence class is formed with the
+  /* Cyclic list of insns of an equivalence class is formed with the
      aid of the following field.  */
   ainsn_t next_equiv_class_insn;
   /* The following field value is nonzero if the insn declaration is
@@ -1121,6 +1160,10 @@ struct ainsn
      It is necessary because many insns may be equivalent with the
      point of view of pipeline hazards.  */
   int insn_equiv_class_num;
+  /* The following member value is TRUE if there is an arc in the
+     automaton marked by the insn into another state.  In other
+     words, the insn can change the state of the automaton.  */
+  int important_p;
 };
 
 /* The folowing describes an automaton for PHR.  */
@@ -1170,6 +1213,15 @@ struct automaton
   int min_issue_delay_table_compression_factor;
 };
 
+/* The following is the element of the list of automata.  */
+struct automata_list_el
+{
+  /* The automaton itself.  */
+  automaton_t automaton;
+  /* The next automata set element.  */
+  automata_list_el_t next_automata_list_el;
+};
+
 /* The following structure describes a table state X ainsn -> int(>= 0).  */
 struct state_ainsn_table
 {
@@ -1232,7 +1284,7 @@ check_name (name, pos)
    following.  */
 static vla_ptr_t decls;
 
-/* Given a pointer to a (char *) and a separator, return a alloc'ed
+/* Given a pointer to a (char *) and a separator, return an alloc'ed
    string containing the next separated element, taking parentheses
    into account if PAR_FLAG has nonzero value.  Advance the pointer to
    after the string scanned, or the end-of-string.  Return NULL if at
@@ -1435,7 +1487,7 @@ gen_bypass (def)
       }
 }
 
-/* Process a EXCLUSION_SET.  
+/* Process an EXCLUSION_SET.  
 
    This gives information about a cpu unit conflicts.  We fill a
    struct unit_rel_decl (excl) with information used later by
@@ -1514,7 +1566,7 @@ gen_presence_set (def)
   num_dfa_decls++;
 }
 
-/* Process a ABSENCE_SET.  
+/* Process an ABSENCE_SET.  
 
    This gives information about a cpu unit reservation requirements.
    We fill a struct unit_rel_decl (absence) with information used
@@ -1582,7 +1634,7 @@ gen_automaton (def)
     }
 }
 
-/* Process a AUTOMATA_OPTION.  
+/* Process an AUTOMATA_OPTION.  
 
    This gives information how to generate finite state automaton used
    for recognizing pipeline hazards.  */
@@ -1823,7 +1875,7 @@ string_hash (string)
    Key of the table elements is name of given automaton.  Rememeber
    that automaton names have own space.  */
 
-/* The function evaluates hash value of a automaton declaration.  The
+/* The function evaluates hash value of an automaton declaration.  The
    function is used by abstract data `hashtab'.  The function returns
    hash value (0..UINT_MAX) of given automaton declaration.  */
 static unsigned
@@ -1925,7 +1977,7 @@ finish_automaton_decl_table ()
    define_insn_reservation).  Rememeber that insn names have own
    space.  */
 
-/* The function evaluates hash value of a insn declaration.  The
+/* The function evaluates hash value of an insn declaration.  The
    function is used by abstract data `hashtab'.  The function returns
    hash value (0..UINT_MAX) of given insn declaration.  */
 static unsigned
@@ -2191,6 +2243,15 @@ add_excls (dest_list, source_list, excl_pos)
            error ("unit `%s' excludes itself", src->unit_decl->name);
            continue;
          }
+       if (dst->unit_decl->automaton_name != NULL
+           && src->unit_decl->automaton_name != NULL
+           && strcmp (dst->unit_decl->automaton_name,
+                      src->unit_decl->automaton_name) != 0)
+         {
+           error ("units `%s' and `%s' in exclusion set belong to different automata",
+                  src->unit_decl->name, dst->unit_decl->name);
+           continue;
+         }
        for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
             curr_el != NULL;
             prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
@@ -2284,6 +2345,17 @@ add_presence_absence (dest_list, source_list, req_pos, presence_p)
                    : "unit `%s' requires own absence"), src->unit_decl->name);
            continue;
          }
+       if (dst->unit_decl->automaton_name != NULL
+           && src->unit_decl->automaton_name != NULL
+           && strcmp (dst->unit_decl->automaton_name,
+                      src->unit_decl->automaton_name) != 0)
+         {
+           error ((presence_p
+                   ? "units `%s' and `%s' in presence set belong to different automata"
+                   : "units `%s' and `%s' in absence set belong to different automata"),
+                  src->unit_decl->name, dst->unit_decl->name);
+           continue;
+         }
        for (curr_el = (presence_p
                        ? dst->unit_decl->presence_list
                        : dst->unit_decl->absence_list), prev_el = NULL;
@@ -2932,6 +3004,7 @@ evaluate_max_reserv_cycles ()
          description->max_insn_reserv_cycles = max_insn_cycles_num;
       }
     }
+  description->max_insn_reserv_cycles++;
 }
 
 /* The following function calls functions for checking all
@@ -3261,7 +3334,7 @@ finish_alt_states ()
 
 /* This page contains abstract data `state'.  */
 
-/* Maximal length of reservations in cycles (> 1).  */
+/* Maximal length of reservations in cycles (>= 1).  */
 static int max_cycles_num;
 
 /* Number of set elements (see type set_el_t) needed for
@@ -3280,7 +3353,7 @@ static int els_in_reservs;
 static vla_ptr_t units_container;
 
 /* The start address of the array.  */
-static struct unit_decl **units_array;
+static unit_decl_t *units_array;
 
 /* Empty reservation of maximal length.  */
 static reserv_sets_t empty_reserv;
@@ -3318,21 +3391,34 @@ static unsigned
 reserv_sets_hash_value (reservs)
      reserv_sets_t reservs;
 {
-  unsigned int hash_value;
-  int reservs_num;
+  set_el_t hash_value;
+  unsigned result;
+  int reservs_num, i;
   set_el_t *reserv_ptr;
 
   hash_value = 0;
   reservs_num = els_in_reservs;
   reserv_ptr = reservs;
+  i = 0;
   while (reservs_num != 0)
     {
       reservs_num--;
-      hash_value = ((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
-                    | (hash_value << CHAR_BIT)) + *reserv_ptr;
+      hash_value += ((*reserv_ptr >> i)
+                    | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
+      i++;
+      if (i == sizeof (set_el_t) * CHAR_BIT)
+       i = 0;
       reserv_ptr++;
     }
-  return hash_value;
+  if (sizeof (set_el_t) <= sizeof (unsigned))
+    return hash_value;
+  result = 0;
+  for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1)
+    {
+      result += (unsigned) hash_value;
+      hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT;
+    }
+  return result;
 }
 
 /* Comparison of given reservation sets.  */
@@ -3565,12 +3651,10 @@ output_cycle_reservs (f, reservs, start_cycle, repetition_num)
     fprintf (f, NOTHING_NAME);
   if (repetition_num <= 0)
     abort ();
-  if (reserved_units_num != 0 && repetition_num != 1)
-    {
-      if (reserved_units_num > 1)
-        fprintf (f, ")");
-      fprintf (f, "*%d", repetition_num);
-    }
+  if (reserved_units_num > 1)
+    fprintf (f, ")");
+  if (repetition_num != 1)
+    fprintf (f, "*%d", repetition_num);
 }
 
 /* The function outputs string representation of units reservation in
@@ -3583,10 +3667,8 @@ output_reserv_sets (f, reservs)
   int start_cycle = 0;
   int cycle;
   int repetition_num;
-  int next_cycle_output_flag;
 
   repetition_num = 0;
-  next_cycle_output_flag = 0;
   for (cycle = 0; cycle < max_cycles_num; cycle++)
     if (repetition_num == 0)
       {
@@ -3602,16 +3684,15 @@ output_reserv_sets (f, reservs)
       repetition_num++;
     else
       {
-        if (next_cycle_output_flag)
+        if (start_cycle != 0)
           fprintf (f, ", ");
         output_cycle_reservs (f, reservs, start_cycle, repetition_num);
-        next_cycle_output_flag = 1;
         repetition_num = 1;
         start_cycle = cycle;
       }
-  if (!next_cycle_output_flag)
+  if (start_cycle < max_cycles_num)
     {
-      if (next_cycle_output_flag)
+      if (start_cycle != 0)
         fprintf (f, ", ");
       output_cycle_reservs (f, reservs, start_cycle, repetition_num);
     }
@@ -3823,7 +3904,8 @@ initiate_states ()
 
   VLA_PTR_CREATE (units_container, description->units_num, "units_container");
   units_array
-    = (description->decls_num ? VLA_PTR_BEGIN (units_container) : NULL);
+    = (description->decls_num && description->units_num
+       ? VLA_PTR_BEGIN (units_container) : NULL);
   for (i = 0; i < description->decls_num; i++)
     {
       decl = description->decls [i];
@@ -3831,8 +3913,6 @@ initiate_states ()
        units_array [decl->decl.unit.unit_num] = &decl->decl.unit;
     }
   max_cycles_num = description->max_insn_reserv_cycles;
-  if (max_cycles_num == 0)
-    max_cycles_num++;
   els_in_cycle_reserv
     = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
        / (sizeof (set_el_t) * CHAR_BIT));
@@ -3988,6 +4068,160 @@ finish_arcs ()
 
 \f
 
+/* Abstract data `automata lists'.  */
+
+/* List of free states.  */
+static automata_list_el_t first_free_automata_list_el;
+
+/* The list being formed.  */
+static automata_list_el_t current_automata_list;
+
+/* Hash table of automata lists.  */
+static htab_t automata_list_table;
+
+/* The following function returns free automata list el.  It may be
+   new allocated node or node freed earlier.  */
+static automata_list_el_t 
+get_free_automata_list_el ()
+{
+  automata_list_el_t result;
+
+  if (first_free_automata_list_el != NULL)
+    {
+      result = first_free_automata_list_el;
+      first_free_automata_list_el
+       = first_free_automata_list_el->next_automata_list_el;
+    }
+  else
+    result = create_node (sizeof (struct automata_list_el));
+  result->automaton = NULL;
+  result->next_automata_list_el = NULL;
+  return result;
+}
+
+/* The function frees node AUTOMATA_LIST_EL.  */
+static void
+free_automata_list_el (automata_list_el)
+     automata_list_el_t automata_list_el;
+{
+  if (automata_list_el == NULL)
+    return;
+  automata_list_el->next_automata_list_el = first_free_automata_list_el;
+  first_free_automata_list_el = automata_list_el;
+}
+
+/* The function frees list AUTOMATA_LIST.  */
+static void
+free_automata_list (automata_list)
+     automata_list_el_t automata_list;
+{
+  automata_list_el_t curr_automata_list_el;
+  automata_list_el_t next_automata_list_el;
+
+  for (curr_automata_list_el = automata_list;
+       curr_automata_list_el != NULL;
+       curr_automata_list_el = next_automata_list_el)
+    {
+      next_automata_list_el = curr_automata_list_el->next_automata_list_el;
+      free_automata_list_el (curr_automata_list_el);
+    }
+}
+
+/* Hash value of AUTOMATA_LIST.  */
+static unsigned
+automata_list_hash (automata_list)
+     const void *automata_list;
+{
+  unsigned int hash_value;
+  automata_list_el_t curr_automata_list_el;
+
+  hash_value = 0;
+  for (curr_automata_list_el = (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)
+                  | (hash_value << CHAR_BIT))
+                 + curr_automata_list_el->automaton->automaton_order_num);
+  return hash_value;
+}
+
+/* Return nonzero value if the automata_lists are the same.  */
+static int
+automata_list_eq_p (automata_list_1, automata_list_2)
+     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;
+
+  for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
+        automata_list_el_2 = (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)
+    if (automata_list_el_1->automaton != automata_list_el_2->automaton)
+      return 0;
+  return automata_list_el_1 == automata_list_el_2;
+}
+
+/* Initialization of the abstract data.  */
+static void
+initiate_automata_lists ()
+{
+  first_free_automata_list_el = NULL;
+  automata_list_table = htab_create (1500, automata_list_hash,
+                                    automata_list_eq_p, (htab_del) 0);
+}
+
+/* The following function starts new automata list and makes it the
+   current one.  */
+static void
+automata_list_start ()
+{
+  current_automata_list = NULL;
+}
+
+/* The following function adds AUTOMATON to the current list.  */
+static void
+automata_list_add (automaton)
+     automaton_t automaton;
+{
+  automata_list_el_t el;
+
+  el = get_free_automata_list_el ();
+  el->automaton = automaton;
+  el->next_automata_list_el = current_automata_list;
+  current_automata_list = el;
+}
+
+/* The following function finishes forming the current list, inserts
+   it into the table and returns it.  */
+static automata_list_el_t
+automata_list_finish ()
+{
+  void **entry_ptr;
+
+  if (current_automata_list == NULL)
+    return NULL;
+  entry_ptr = htab_find_slot (automata_list_table,
+                             (void *) current_automata_list, 1);
+  if (*entry_ptr == NULL)
+    *entry_ptr = (void *) current_automata_list;
+  else
+    free_automata_list (current_automata_list);
+  current_automata_list = NULL;
+  return (automata_list_el_t) *entry_ptr;
+}
+
+/* Finishing work with the abstract data.  */
+static void
+finish_automata_lists ()
+{
+  htab_delete (automata_list_table);
+}
+
+\f
+
 /* The page contains abstract data for work with exclusion sets (see
    exclusion_set in file rtl.def).  */
 
@@ -4414,7 +4648,9 @@ transform_2 (regexp)
 
 /* The function makes transformations
    ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
-   ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...  */
+   ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
+   ...+(A,B,...)+C+... -> (...+A+C+...),B,...
+   ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),...  */
 static regexp_t
 transform_3 (regexp)
      regexp_t regexp;
@@ -4470,10 +4706,10 @@ transform_3 (regexp)
     }
   else if (regexp->mode == rm_allof)
     {
-      regexp_t oneof;
-      int oneof_index;
+      regexp_t oneof, seq;
+      int oneof_index, max_seq_length, allof_length;
       regexp_t result;
-      regexp_t allof;
+      regexp_t allof, allof_op;
       int i, j;
 
       for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
@@ -4516,6 +4752,82 @@ transform_3 (regexp)
          regexp_transformed_p = 1;
          regexp = result;
        }
+      max_seq_length = 0;
+      for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
+       if (regexp->regexp.allof.regexps [i]->mode == rm_sequence)
+         {
+           seq = regexp->regexp.allof.regexps [i];
+           if (max_seq_length < seq->regexp.sequence.regexps_num)
+             max_seq_length = seq->regexp.sequence.regexps_num;
+         }
+       else if (regexp->regexp.allof.regexps [i]->mode != rm_unit)
+         {
+           max_seq_length = 0;
+           break;
+         }
+      if (max_seq_length != 0)
+       {
+         if (max_seq_length == 1 || regexp->regexp.allof.regexps_num <= 1)
+           abort ();
+         result = create_node (sizeof (struct regexp)
+                               + sizeof (regexp_t) * (max_seq_length - 1));
+         result->mode = rm_sequence;
+         result->pos = regexp->pos;
+         result->regexp.sequence.regexps_num = max_seq_length;
+         for (i = 0; i < max_seq_length; i++)
+           {
+             allof_length = 0;
+             for (j = 0; j < regexp->regexp.allof.regexps_num; j++)
+               if (regexp->regexp.allof.regexps [j]->mode == rm_sequence
+                   && (i < (regexp->regexp.allof.regexps [j]
+                            ->regexp.sequence.regexps_num)))
+                 {
+                   allof_op = (regexp->regexp.allof.regexps [j]
+                               ->regexp.sequence.regexps [i]);
+                   allof_length++;
+                 }
+               else if (i == 0
+                        && regexp->regexp.allof.regexps [j]->mode == rm_unit)
+                 {
+                   allof_op = regexp->regexp.allof.regexps [j];
+                   allof_length++;
+                 }
+             if (allof_length == 1)
+               result->regexp.sequence.regexps [i] = allof_op;
+             else
+               {
+                 allof = create_node (sizeof (struct regexp)
+                                      + sizeof (regexp_t)
+                                      * (allof_length - 1));
+                 allof->mode = rm_allof;
+                 allof->pos = regexp->pos;
+                 allof->regexp.allof.regexps_num = allof_length;
+                 result->regexp.sequence.regexps [i] = allof;
+                 allof_length = 0;
+                 for (j = 0; j < regexp->regexp.allof.regexps_num; j++)
+                   if (regexp->regexp.allof.regexps [j]->mode == rm_sequence
+                       && (i < (regexp->regexp.allof.regexps [j]
+                                ->regexp.sequence.regexps_num)))
+                     {
+                       allof_op = (regexp->regexp.allof.regexps [j]
+                                   ->regexp.sequence.regexps [i]);
+                       allof->regexp.allof.regexps [allof_length] = allof_op;
+                       
+                       allof_length++;
+                     }
+                   else if (i == 0
+                            && (regexp->regexp.allof.regexps [j]->mode
+                                == rm_unit))
+                     {
+                       allof_op = regexp->regexp.allof.regexps [j];
+                       allof->regexp.allof.regexps [allof_length] = allof_op;
+                       allof_length++;
+                     }
+               }
+           }
+         regexp_transformed_p = 1;
+         regexp = result;
+       }
     }
   return regexp;
 }
@@ -4574,6 +4886,10 @@ transform_insn_regexps ()
   decl_t decl;
   int i;
 
+  transform_time = create_ticker ();
+  add_advance_cycle_insn_decl ();
+  fprintf (stderr, "Reservation transformation...");
+  fflush (stderr);
   for (i = 0; i < description->decls_num; i++)
     {
       decl = description->decls [i];
@@ -4582,6 +4898,207 @@ transform_insn_regexps ()
          = transform_regexp (copy_insn_regexp
                              (decl->decl.insn_reserv.regexp));
     }
+  fprintf (stderr, "done\n");
+  ticker_off (&transform_time);
+  fflush (stderr);
+}
+
+\f
+
+/* The following variable is an array indexed by cycle.  Each element
+   contains cyclic list of units which should be in the same cycle.  */
+static unit_decl_t *the_same_automaton_lists;
+
+/* The function processes all alternative reservations on CYCLE in
+   given REGEXP to check the UNIT is not reserved on the all
+   alternatives.  If it is true, the unit should be in the same
+   automaton with other analogous units reserved on CYCLE in given
+   REGEXP.  */
+static void
+process_unit_to_form_the_same_automaton_unit_lists (unit, regexp, cycle)
+     regexp_t unit;
+     regexp_t regexp;
+     int cycle;
+{
+  int i, k;
+  regexp_t seq, allof;
+  unit_decl_t unit_decl, last;
+
+  if (regexp == NULL || regexp->mode != rm_oneof)
+    abort ();
+  unit_decl = unit->regexp.unit.unit_decl;
+  for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
+    {
+      seq = regexp->regexp.oneof.regexps [i];
+      if (seq->mode == rm_sequence)
+       {
+         if (cycle >= seq->regexp.sequence.regexps_num)
+           break;
+         allof = seq->regexp.sequence.regexps [cycle];
+         if (allof->mode == rm_allof)
+           {
+             for (k = 0; k < allof->regexp.allof.regexps_num; k++)
+               if (allof->regexp.allof.regexps [k]->mode == rm_unit
+                   && (allof->regexp.allof.regexps [k]->regexp.unit.unit_decl
+                       == unit_decl))
+                 break;
+             if (k >= allof->regexp.allof.regexps_num)
+               break;
+           }
+         else if (allof->mode == rm_unit
+                  && allof->regexp.unit.unit_decl != unit_decl)
+           break;
+       }
+      else if (cycle != 0)
+       break;
+      else if (seq->mode == rm_allof)
+       {
+         for (k = 0; k < seq->regexp.allof.regexps_num; k++)
+           if (seq->regexp.allof.regexps [k]->mode == rm_unit
+               && (seq->regexp.allof.regexps [k]->regexp.unit.unit_decl
+                   == unit_decl))
+             break;
+         if (k >= seq->regexp.allof.regexps_num)
+           break;
+       }
+      else if (seq->mode == rm_unit && seq->regexp.unit.unit_decl != unit_decl)
+       break;
+    }
+  if (i >= 0)
+    {
+      if (the_same_automaton_lists [cycle] == NULL)
+       the_same_automaton_lists [cycle] = unit_decl;
+      else
+       {
+         for (last = the_same_automaton_lists [cycle];;)
+           {
+             if (last == unit_decl)
+               return;
+             if (last->the_same_automaton_unit
+                 == the_same_automaton_lists [cycle])
+               break;
+             last = last->the_same_automaton_unit;
+           }
+         last->the_same_automaton_unit = unit_decl->the_same_automaton_unit;
+         unit_decl->the_same_automaton_unit
+           = the_same_automaton_lists [cycle];
+       }
+    }
+}
+
+/* The function processes given REGEXP to find units which should be
+   in the same automaton.  */
+static void
+form_the_same_automaton_unit_lists_from_regexp (regexp)
+     regexp_t regexp;
+{
+  int i, j, k;
+  regexp_t seq, allof, unit;
+
+  if (regexp == NULL || regexp->mode != rm_oneof)
+    return;
+  for (i = 0; i < description->max_insn_reserv_cycles; i++)
+    the_same_automaton_lists [i] = NULL;
+  for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
+    {
+      seq = regexp->regexp.oneof.regexps [i];
+      if (seq->mode == rm_sequence)
+       for (j = 0; j < seq->regexp.sequence.regexps_num; j++)
+         {
+           allof = seq->regexp.sequence.regexps [j];
+           if (allof->mode == rm_allof)
+             for (k = 0; k < allof->regexp.allof.regexps_num; k++)
+               {
+                 unit = allof->regexp.allof.regexps [k];
+                 if (unit->mode == rm_unit)
+                   process_unit_to_form_the_same_automaton_unit_lists
+                     (unit, regexp, j);
+                 else if (unit->mode != rm_nothing)
+                   abort ();
+               }
+           else if (allof->mode == rm_unit)
+             process_unit_to_form_the_same_automaton_unit_lists
+               (allof, regexp, j);
+           else if (allof->mode != rm_nothing)
+             abort ();
+         }
+      else if (seq->mode == rm_allof)
+       for (k = 0; k < seq->regexp.allof.regexps_num; k++)
+         {
+           unit = seq->regexp.allof.regexps [k];
+           if (unit->mode == rm_unit)
+             process_unit_to_form_the_same_automaton_unit_lists
+               (unit, regexp, 0);
+           else if (unit->mode != rm_nothing)
+             abort ();
+         }
+      else if (seq->mode == rm_unit)
+       process_unit_to_form_the_same_automaton_unit_lists (seq, regexp, 0);
+      else if (seq->mode != rm_nothing)
+       abort ();
+    }
+}
+
+/* The function initializes data to search for units which should be
+   in the same automaton and call function
+   `form_the_same_automaton_unit_lists_from_regexp' for each insn
+   reservation regexp.  */
+static void
+form_the_same_automaton_unit_lists ()
+{
+  decl_t decl;
+  int i;
+
+  the_same_automaton_lists
+    = (unit_decl_t *) xmalloc (description->max_insn_reserv_cycles
+                              * sizeof (unit_decl_t));
+  for (i = 0; i < description->decls_num; i++)
+    {
+      decl = description->decls [i];
+      if (decl->mode == dm_unit)
+       {
+         decl->decl.unit.the_same_automaton_message_reported_p = FALSE;
+         decl->decl.unit.the_same_automaton_unit = &decl->decl.unit;
+       }
+    }
+  for (i = 0; i < description->decls_num; i++)
+    {
+      decl = description->decls [i];
+      if (decl->mode == dm_insn_reserv)
+       form_the_same_automaton_unit_lists_from_regexp
+         (decl->decl.insn_reserv.transformed_regexp);
+    }
+  free (the_same_automaton_lists);
+}
+
+/* The function finds units which should be in the same automaton and,
+   if they are not, reports about it.  */
+static void
+check_unit_distributions_to_automata ()
+{
+  decl_t decl;
+  unit_decl_t start_unit_decl, unit_decl;
+  int i;
+
+  form_the_same_automaton_unit_lists ();
+  for (i = 0; i < description->decls_num; i++)
+    {
+      decl = description->decls [i];
+      if (decl->mode == dm_unit)
+       {
+         start_unit_decl = &decl->decl.unit;
+         if (!start_unit_decl->the_same_automaton_message_reported_p)
+           for (unit_decl = start_unit_decl->the_same_automaton_unit;
+                unit_decl != start_unit_decl;
+                unit_decl = unit_decl->the_same_automaton_unit)
+             if (start_unit_decl->automaton_decl != unit_decl->automaton_decl)
+               {
+                 error ("Units `%s' and `%s' should be in the same automaton",
+                        start_unit_decl->name, unit_decl->name);
+                 unit_decl->the_same_automaton_message_reported_p = TRUE;
+               }
+       }
+    }
 }
 
 \f
@@ -5193,7 +5710,7 @@ init_equiv_class (states, states_num)
    removing nonequivalent states and placing them in
    *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
    assigns it to the state equivalence number.  If the class has been
-   partitioned, the function returns nonzero value. */
+   partitioned, the function returns nonzero value.  */
 static int
 partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
                       next_iteration_classes, new_equiv_class_num_ptr)
@@ -5791,6 +6308,7 @@ create_ainsns ()
        {
          curr_ainsn = create_node (sizeof (struct ainsn));
          curr_ainsn->insn_reserv_decl = &decl->decl.insn_reserv;
+         curr_ainsn->important_p = FALSE;
          curr_ainsn->next_ainsn = NULL;
          if (prev_ainsn == NULL)
            first_ainsn = curr_ainsn;
@@ -5904,6 +6422,11 @@ create_automata ()
        curr_automaton != NULL;
        curr_automaton = curr_automaton->next_automaton)
     {
+      if (curr_automaton->corresponding_automaton_decl == NULL)
+       fprintf (stderr, "Create anonymous automaton ...");
+      else
+       fprintf (stderr, "Create automaton `%s'...",
+                curr_automaton->corresponding_automaton_decl->name);
       create_alt_states (curr_automaton);
       form_ainsn_with_same_reservs (curr_automaton);
       build_automaton (curr_automaton);
@@ -5911,6 +6434,7 @@ create_automata ()
       ticker_on (&equiv_time);
       set_insn_equiv_classes (curr_automaton);
       ticker_off (&equiv_time);
+      fprintf (stderr, "done\n");
     }
 }
 
@@ -6072,7 +6596,7 @@ longest_path_length (state)
 
   result = 0;
   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
-    /* Ignore cycles containing one state and `cycle advance' arcs. */
+    /* Ignore cycles containing one state and `cycle advance' arcs.  */
     if (arc->to_state != state
        && (arc->insn->insn_reserv_decl
            != &advance_cycle_insn_decl->decl.insn_reserv))
@@ -6091,7 +6615,7 @@ longest_path_length (state)
 static int max_dfa_issue_rate;
 
 /* The following function processes the longest path length staring
-   from STATE to find MAX_DFA_ISSUE_RATE. */
+   from STATE to find MAX_DFA_ISSUE_RATE.  */
 
 static void
 process_state_longest_path_length (state)
@@ -6113,7 +6637,7 @@ process_state_longest_path_length (state)
    global variable and outputs its declaration.  */
 
 static void
-output_dfa_max_issue_rate (void)
+output_dfa_max_issue_rate ()
 {
   automaton_t automaton;
 
@@ -6378,6 +6902,9 @@ output_reserved_units_table_name (f, automaton)
 /* Name of cache of insn dfa codes.  */
 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
 
+/* Name of length of cache of insn dfa codes.  */
+#define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
+
 /* Names of the PHR interface functions: */
 #define SIZE_FUNC_NAME "state_size"
 
@@ -6897,8 +7424,10 @@ static int curr_state_pass_num;
 
 
 /* This recursive function passes states to find minimal issue delay
-   value for AINSN.  The state being visited is STATE.  */
-static void
+   value for AINSN.  The state being visited is STATE.  The function
+   returns minimal issue delay value for AINSN in STATE or -1 if we
+   enter into a loop.  */
+static int
 min_issue_delay_pass_states (state, ainsn)
      state_t state;
      ainsn_t ainsn;
@@ -6906,10 +7435,13 @@ min_issue_delay_pass_states (state, ainsn)
   arc_t arc;
   int min_insn_issue_delay, insn_issue_delay;
 
-  if (state->state_pass_num == curr_state_pass_num)
-    return;
+  if (state->state_pass_num == curr_state_pass_num
+      || state->min_insn_issue_delay != -1)
+    /* We've entered into a loop or already have the correct value for
+       given state and ainsn.  */
+    return state->min_insn_issue_delay;
   state->state_pass_num = curr_state_pass_num;
-  min_insn_issue_delay = state->min_insn_issue_delay = -1;
+  min_insn_issue_delay = -1;
   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
     if (arc->insn == ainsn)
       {
@@ -6918,31 +7450,34 @@ min_issue_delay_pass_states (state, ainsn)
       }
     else
       {
-        min_issue_delay_pass_states (arc->to_state, ainsn);
-       if (arc->to_state->min_insn_issue_delay != -1)
+        insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
+       if (insn_issue_delay != -1)
          {
-           insn_issue_delay
-             = (arc->to_state->min_insn_issue_delay
-                + (arc->insn->insn_reserv_decl
-                   == &advance_cycle_insn_decl->decl.insn_reserv ? 1 : 0));
+           if (arc->insn->insn_reserv_decl
+               == &advance_cycle_insn_decl->decl.insn_reserv)
+             insn_issue_delay++;
            if (min_insn_issue_delay == -1
                || min_insn_issue_delay > insn_issue_delay)
-             min_insn_issue_delay = insn_issue_delay;
+             {
+               min_insn_issue_delay = insn_issue_delay;
+               if (insn_issue_delay == 0)
+                 break;
+             }
          }
       }
-  state->min_insn_issue_delay = min_insn_issue_delay;
+  return min_insn_issue_delay;
 }
 
 /* The function searches minimal issue delay value for AINSN in STATE.
-   The function can return negative can not issue AINSN.  We will
-   report about it later.  */
+   The function can return negative value if we can not issue AINSN.  We
+   will report about it later.  */
 static int
 min_issue_delay (state, ainsn)
      state_t state;
      ainsn_t ainsn;
 {
   curr_state_pass_num++;
-  min_issue_delay_pass_states (state, ainsn);
+  state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
   return state->min_insn_issue_delay;
 }
 
@@ -6982,15 +7517,17 @@ output_min_issue_delay_table (automaton)
        i++)
     VLA_HWINT (min_issue_delay_vect, i) = 0;
   automaton->max_min_delay = 0;
-  for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
-       state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
-       state_ptr++)
-    {
-      for (ainsn = automaton->ainsn_list;
-          ainsn != NULL;
-          ainsn = ainsn->next_ainsn)
-        if (ainsn->first_ainsn_with_given_equialence_num)
-          {
+  for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
+    if (ainsn->first_ainsn_with_given_equialence_num)
+      {
+       for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
+            state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
+            state_ptr++)
+         (*state_ptr)->min_insn_issue_delay = -1;
+       for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
+            state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
+            state_ptr++)
+         {
             min_delay = min_issue_delay (*state_ptr, ainsn);
            if (automaton->max_min_delay < min_delay)
              automaton->max_min_delay = min_delay;
@@ -6999,7 +7536,7 @@ output_min_issue_delay_table (automaton)
                       * automaton->insn_equiv_classes_num
                       + ainsn->insn_equiv_class_num) = min_delay;
          }
-    }
+      }
   fprintf (output_file, "/* Vector of min issue delay of insns.*/\n");
   fprintf (output_file, "static const ");
   output_range_type (output_file, 0, automaton->max_min_delay);
@@ -7193,26 +7730,59 @@ output_max_insn_queue_index_def ()
 }
 
 
-/* Output function `internal_min_issue_delay'.  */
+/* The function outputs switch cases for insn reseravtions using
+   function *output_automata_list_code.  */
 static void
-output_internal_min_issue_delay_func ()
+output_insn_code_cases (output_automata_list_code)
+     void (*output_automata_list_code) (automata_list_el_t);
 {
+  decl_t decl, decl_2;
+  int i, j;
+
+  for (i = 0; i < description->decls_num; i++)
+    {
+      decl = description->decls [i];
+      if (decl->mode == dm_insn_reserv)
+       decl->decl.insn_reserv.processed_p = FALSE;
+    }
+  for (i = 0; i < description->decls_num; i++)
+    {
+      decl = description->decls [i];
+      if (decl->mode == dm_insn_reserv && !decl->decl.insn_reserv.processed_p)
+       {
+         for (j = i; j < description->decls_num; j++)
+           {
+             decl_2 = description->decls [j];
+             if (decl_2->mode == dm_insn_reserv
+                 && (decl_2->decl.insn_reserv.important_automata_list
+                     == decl->decl.insn_reserv.important_automata_list))
+               {
+                 decl_2->decl.insn_reserv.processed_p = TRUE;
+                 fprintf (output_file, "    case %d: /* %s */\n",
+                          decl_2->decl.insn_reserv.insn_num,
+                          decl_2->decl.insn_reserv.name);
+               }
+           }
+         (*output_automata_list_code)
+           (decl->decl.insn_reserv.important_automata_list);
+       }
+    }
+}
+
+
+/* The function outputs a code for evaluation of a minimal delay of
+   issue of insns which have reservations in given AUTOMATA_LIST.  */
+static void
+output_automata_list_min_issue_delay_code (automata_list)
+     automata_list_el_t automata_list;
+{
+  automata_list_el_t el;
   automaton_t automaton;
 
-  fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
-          INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, CHIP_NAME);
-  fprintf (output_file,
-          "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
-          INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
-          CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
-          CHIP_PARAMETER_NAME);
-  fprintf (output_file, "{\n  int %s;\n  int %s;\n",
-          TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
-  for (automaton = description->first_automaton;
-       automaton != NULL;
-       automaton = automaton->next_automaton)
+  for (el = automata_list; el != NULL; el = el->next_automata_list_el)
     {
-      fprintf (output_file, "\n  %s = ", TEMPORARY_VARIABLE_NAME);
+      automaton = el->automaton;
+      fprintf (output_file, "\n      %s = ", TEMPORARY_VARIABLE_NAME);
       output_min_issue_delay_vect_name (output_file, automaton);
       fprintf (output_file,
               (automaton->min_issue_delay_table_compression_factor != 1
@@ -7228,7 +7798,7 @@ output_internal_min_issue_delay_func ()
        {
          fprintf (output_file, ") / %d];\n",
                   automaton->min_issue_delay_table_compression_factor);
-         fprintf (output_file, "  %s = (%s >> (8 - (",
+         fprintf (output_file, "      %s = (%s >> (8 - (",
                   TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
          output_translate_vect_name (output_file, automaton);
          fprintf
@@ -7239,123 +7809,152 @@ output_internal_min_issue_delay_func ()
             (1 << (8 / automaton->min_issue_delay_table_compression_factor))
             - 1);
        }
-      if (automaton == description->first_automaton)
-       fprintf (output_file, "  %s = %s;\n",
+      if (el == automata_list)
+       fprintf (output_file, "      %s = %s;\n",
                 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
       else
        {
-         fprintf (output_file, "  if (%s > %s)\n",
+         fprintf (output_file, "      if (%s > %s)\n",
                   TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
-         fprintf (output_file, "    %s = %s;\n",
+         fprintf (output_file, "        %s = %s;\n",
                   RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
        }
     }
+  fprintf (output_file, "      break;\n\n");
+}
+
+/* Output function `internal_min_issue_delay'.  */
+static void
+output_internal_min_issue_delay_func ()
+{
+  fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
+          INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, CHIP_NAME);
+  fprintf (output_file,
+          "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s  ATTRIBUTE_UNUSED;\n",
+          INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
+          CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
+          CHIP_PARAMETER_NAME);
+  fprintf (output_file, "{\n  int %s ATTRIBUTE_UNUSED;\n  int %s;\n",
+          TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
+  fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
+  output_insn_code_cases (output_automata_list_min_issue_delay_code);
+  fprintf (output_file,
+          "\n    default:\n      %s = -1;\n      break;\n    }\n",
+          RESULT_VARIABLE_NAME);
   fprintf (output_file, "  return %s;\n", RESULT_VARIABLE_NAME);
   fprintf (output_file, "}\n\n");
 }
 
-/* Output function `internal_state_transition'.  */
+/* The function outputs a code changing state after issue of insns
+   which have reservations in given AUTOMATA_LIST.  */
 static void
-output_internal_trans_func ()
+output_automata_list_transition_code (automata_list)
+     automata_list_el_t automata_list;
 {
-  automaton_t curr_automaton;
-  automaton_t next_automaton;
+  automata_list_el_t el, next_el;
 
-  fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
-          INTERNAL_TRANSITION_FUNC_NAME, CHIP_NAME);
-  fprintf (output_file,
-          "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
-          INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
-          CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME,
-          CHIP_NAME, CHIP_PARAMETER_NAME);
-  fprintf (output_file, "{\n  int %s;\n", TEMPORARY_VARIABLE_NAME);
-  if (description->first_automaton != NULL)
-    for (curr_automaton = description->first_automaton;;
-         curr_automaton = next_automaton)
+  fprintf (output_file, "      {\n");
+  if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
+    for (el = automata_list;; el = next_el)
       {
-        next_automaton = curr_automaton->next_automaton;
-        if (next_automaton == NULL)
+        next_el = el->next_automata_list_el;
+        if (next_el == NULL)
           break;
-        fprintf (output_file, "  ");
-        output_state_member_type (output_file, curr_automaton);
+        fprintf (output_file, "        ");
+        output_state_member_type (output_file, el->automaton);
        fprintf (output_file, " ");
-        output_temp_chip_member_name (output_file, curr_automaton);
+        output_temp_chip_member_name (output_file, el->automaton);
         fprintf (output_file, ";\n");
       }
-  for (curr_automaton = description->first_automaton;
-       curr_automaton != NULL;
-       curr_automaton = curr_automaton->next_automaton)
-    if (comb_vect_p (curr_automaton->trans_table))
+  for (el = automata_list; el != NULL; el = el->next_automata_list_el)
+    if (comb_vect_p (el->automaton->trans_table))
       {
-       fprintf (output_file, "\n  %s = ", TEMPORARY_VARIABLE_NAME);
-       output_trans_base_vect_name (output_file, curr_automaton);
+       fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);
+       output_trans_base_vect_name (output_file, el->automaton);
        fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
-       output_chip_member_name (output_file, curr_automaton);
+       output_chip_member_name (output_file, el->automaton);
        fprintf (output_file, "] + ");
-       output_translate_vect_name (output_file, curr_automaton);
+       output_translate_vect_name (output_file, el->automaton);
        fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
-       fprintf (output_file, "  if (");
-       output_trans_check_vect_name (output_file, curr_automaton);
+       fprintf (output_file, "        if (");
+       output_trans_check_vect_name (output_file, el->automaton);
        fprintf (output_file, " [%s] != %s->",
                 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
-       output_chip_member_name (output_file, curr_automaton);
+       output_chip_member_name (output_file, el->automaton);
        fprintf (output_file, ")\n");
-       fprintf (output_file, "    return %s (%s, %s);\n",
+       fprintf (output_file, "          return %s (%s, %s);\n",
                 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
                 CHIP_PARAMETER_NAME);
-       fprintf (output_file, "  else\n");
-       fprintf (output_file, "    ");
-       if (curr_automaton->next_automaton != NULL)
-         output_temp_chip_member_name (output_file, curr_automaton);
+       fprintf (output_file, "        else\n");
+       fprintf (output_file, "          ");
+       if (el->next_automata_list_el != NULL)
+         output_temp_chip_member_name (output_file, el->automaton);
        else
          {
            fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
-           output_chip_member_name (output_file, curr_automaton);
+           output_chip_member_name (output_file, el->automaton);
          }
        fprintf (output_file, " = ");
-       output_trans_comb_vect_name (output_file, curr_automaton);
+       output_trans_comb_vect_name (output_file, el->automaton);
        fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
       }
     else
       {
-       fprintf (output_file, "\n  %s = ", TEMPORARY_VARIABLE_NAME);
-       output_trans_full_vect_name (output_file, curr_automaton);
+       fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);
+       output_trans_full_vect_name (output_file, el->automaton);
        fprintf (output_file, " [");
-       output_translate_vect_name (output_file, curr_automaton);
+       output_translate_vect_name (output_file, el->automaton);
        fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
        fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
-       output_chip_member_name (output_file, curr_automaton);
+       output_chip_member_name (output_file, el->automaton);
        fprintf (output_file, " * %d];\n",
-                curr_automaton->insn_equiv_classes_num);
-       fprintf (output_file, "  if (%s >= %d)\n", TEMPORARY_VARIABLE_NAME,
-                curr_automaton->achieved_states_num);
-       fprintf (output_file, "    return %s (%s, %s);\n",
+                el->automaton->insn_equiv_classes_num);
+       fprintf (output_file, "        if (%s >= %d)\n",
+                TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
+       fprintf (output_file, "          return %s (%s, %s);\n",
                 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
                 CHIP_PARAMETER_NAME);
-       fprintf (output_file, "  else\n    ");
-       if (curr_automaton->next_automaton != NULL)
-         output_temp_chip_member_name (output_file, curr_automaton);
+       fprintf (output_file, "        else\n          ");
+       if (el->next_automata_list_el != NULL)
+         output_temp_chip_member_name (output_file, el->automaton);
        else
          {
            fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
-           output_chip_member_name (output_file, curr_automaton);
+           output_chip_member_name (output_file, el->automaton);
          }
        fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
       }
-  if (description->first_automaton != NULL)
-    for (curr_automaton = description->first_automaton;;
-         curr_automaton = next_automaton)
+  if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
+    for (el = automata_list;; el = next_el)
       {
-        next_automaton = curr_automaton->next_automaton;
-        if (next_automaton == NULL)
+        next_el = el->next_automata_list_el;
+        if (next_el == NULL)
           break;
-        fprintf (output_file, "  %s->", CHIP_PARAMETER_NAME);
-        output_chip_member_name (output_file, curr_automaton);
+        fprintf (output_file, "        %s->", CHIP_PARAMETER_NAME);
+        output_chip_member_name (output_file, el->automaton);
         fprintf (output_file, " = ");
-        output_temp_chip_member_name (output_file, curr_automaton);
+        output_temp_chip_member_name (output_file, el->automaton);
         fprintf (output_file, ";\n");
       }
-  fprintf (output_file, "  return -1;\n");
+  fprintf (output_file, "        return -1;\n");
+  fprintf (output_file, "      }\n");
+}
+
+/* Output function `internal_state_transition'.  */
+static void
+output_internal_trans_func ()
+{
+  fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
+          INTERNAL_TRANSITION_FUNC_NAME, CHIP_NAME);
+  fprintf (output_file,
+          "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s  ATTRIBUTE_UNUSED;\n",
+          INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
+          CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME,
+          CHIP_NAME, CHIP_PARAMETER_NAME);
+  fprintf (output_file, "{\n  int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
+  fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
+  output_insn_code_cases (output_automata_list_transition_code);
+  fprintf (output_file, "\n    default:\n      return -1;\n    }\n");
   fprintf (output_file, "}\n\n");
 }
 
@@ -7397,7 +7996,21 @@ output_dfa_insn_code_func ()
           DFA_INSN_CODE_FUNC_NAME);
   fprintf (output_file, "static int\n%s (%s)\n\trtx %s;\n",
           DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME, INSN_PARAMETER_NAME);
-  fprintf (output_file, "{\n  int %s;\n\n", INTERNAL_INSN_CODE_NAME);
+  fprintf (output_file, "{\n  int %s;\n  int %s;\n\n",
+          INTERNAL_INSN_CODE_NAME, TEMPORARY_VARIABLE_NAME);
+  fprintf (output_file, "  if (INSN_UID (%s) >= %s)\n    {\n",
+          INSN_PARAMETER_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
+  fprintf (output_file, "      %s = %s;\n      %s = 2 * INSN_UID (%s);\n",
+          TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
+          DFA_INSN_CODES_LENGTH_VARIABLE_NAME, INSN_PARAMETER_NAME);
+  fprintf (output_file, "      %s = xrealloc (%s, %s * sizeof (int));\n",
+          DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
+          DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
+  fprintf (output_file,
+          "      for (; %s < %s; %s++)\n        %s [%s] = -1;\n    }\n",
+          TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
+          TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
+          TEMPORARY_VARIABLE_NAME);
   fprintf (output_file, "  if ((%s = %s [INSN_UID (%s)]) < 0)\n    {\n",
           INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
           INSN_PARAMETER_NAME);
@@ -7424,12 +8037,72 @@ output_trans_func ()
           INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
 }
 
-/* Output function `internal_state_alts'.  */
+/* The function outputs a code for evaluation of alternative states
+   number for insns which have reservations in given AUTOMATA_LIST.  */
 static void
-output_internal_state_alts_func ()
+output_automata_list_state_alts_code (automata_list)
+     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 ()
+{
   fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
           INTERNAL_STATE_ALTS_FUNC_NAME, CHIP_NAME);
   fprintf (output_file,
@@ -7438,53 +8111,11 @@ output_internal_state_alts_func ()
           CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
           CHIP_PARAMETER_NAME);
   fprintf (output_file, "{\n  int %s;\n", RESULT_VARIABLE_NAME);
-  for (automaton = description->first_automaton;
-       automaton != NULL;
-       automaton = automaton->next_automaton)
-    if (comb_vect_p (automaton->state_alts_table))
-      {
-       fprintf (output_file, "  int %s;\n", TEMPORARY_VARIABLE_NAME);
-       break;
-      }
-  for (automaton = description->first_automaton;
-       automaton != NULL;
-       automaton = automaton->next_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,
-                (automaton == description->first_automaton
-                 ? "    %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,
-                (automaton == description->first_automaton
-                 ? "\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, "\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");
 }
@@ -7630,8 +8261,8 @@ output_internal_insn_latency_func ()
           INTERNAL_INSN_LATENCY_FUNC_NAME);
   fprintf (output_file, "static int\n%s (%s, %s, %s, %s)",
           INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
-          INTERNAL_INSN2_CODE_NAME,
-          INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
+          INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
+          INSN2_PARAMETER_NAME);
   fprintf (output_file, "\n\tint %s;\n\tint %s;\n",
           INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
   fprintf (output_file,
@@ -7751,8 +8382,8 @@ static int
 units_cmp (unit1, unit2)
      const void *unit1, *unit2;
 {
-  const struct unit_decl *u1 = *(struct unit_decl **) unit1;
-  const struct unit_decl *u2 = *(struct unit_decl **) unit2;
+  const unit_decl_t u1 = *(unit_decl_t *) unit1;
+  const unit_decl_t u2 = *(unit_decl_t *) unit2;
 
   return strcmp (u1->name, u2->name);
 }
@@ -7781,7 +8412,7 @@ static void
 output_get_cpu_unit_code_func ()
 {
   int i;
-  struct unit_decl **units;
+  unit_decl_t *units;
   
   fprintf (output_file, "int\n%s (%s)\n\tconst char *%s;\n",
           GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
@@ -7792,12 +8423,10 @@ output_get_cpu_unit_code_func ()
           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 = (struct unit_decl **) xmalloc (sizeof (struct unit_decl *)
-                                        * description->units_num);
-  memcpy (units, units_array,
-         sizeof (struct unit_decl *) * description->units_num);
-  qsort (units, description->units_num,
-        sizeof (struct unit_decl *), units_cmp);
+  units = (unit_decl_t *) xmalloc (sizeof (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++)
     if (units [i]->query_p)
       fprintf (output_file, "      {\"%s\", %d},\n",
@@ -7863,14 +8492,16 @@ static void
 output_dfa_start_func ()
 {
   fprintf (output_file,
-          "void\n%s ()\n{\n  int %s;\n  int %s = get_max_uid ();\n\n",
-          DFA_START_FUNC_NAME, I_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
+          "void\n%s ()\n{\n  int %s;\n\n  %s = get_max_uid ();\n",
+          DFA_START_FUNC_NAME, I_VARIABLE_NAME,
+          DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
   fprintf (output_file, "  %s = (int *) xmalloc (%s * sizeof (int));\n",
-          DFA_INSN_CODES_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
+          DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
   fprintf (output_file,
           "  for (%s = 0; %s < %s; %s++)\n    %s [%s] = -1;\n}\n\n",
-          I_VARIABLE_NAME, I_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME,
-          I_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
+          I_VARIABLE_NAME, I_VARIABLE_NAME,
+          DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
+          DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
 }
 
 /* The function outputs PHR interface function `dfa_finish'.  */
@@ -8308,21 +8939,12 @@ generate ()
     automata_num = description->units_num;
   initiate_states ();
   initiate_arcs ();
+  initiate_automata_lists ();
   initiate_pass_states ();
   initiate_excl_sets ();
   initiate_presence_absence_sets ();
   automaton_generation_time = create_ticker ();
-  transform_time = create_ticker ();
-  add_advance_cycle_insn_decl ();
-  fprintf (stderr, "Reservation transformation...");
-  fflush (stderr);
-  transform_insn_regexps ();
-  fprintf (stderr, "done\n");
-  ticker_off (&transform_time);
-  fprintf (stderr, "Create automata...");
-  fflush (stderr);
   create_automata ();
-  fprintf (stderr, "done\n");
   ticker_off (&automaton_generation_time);
 }
 
@@ -8576,7 +9198,7 @@ initiate_automaton_gen (argc, argv)
 /* The following function checks existence at least one arc marked by
    each insn.  */
 static void
-check_automata ()
+check_automata_insn_issues ()
 {
   automaton_t automaton;
   ainsn_t ainsn, reserv_ainsn;
@@ -8618,6 +9240,85 @@ check_automata ()
     }
 }
 
+/* The following vla is used for storing pointers to all achieved
+   states.  */
+static vla_ptr_t automaton_states;
+
+/* This function is called by function pass_states to add an achieved
+   STATE.  */
+static void
+add_automaton_state (state)
+     state_t state;
+{
+  VLA_PTR_ADD (automaton_states, state);
+}
+
+/* The following function forms list of important automata (whose
+   states may be changed after the insn issue) for each insn.  */
+static void
+form_important_insn_automata_lists ()
+{
+  automaton_t automaton;
+  state_t *state_ptr;
+  decl_t decl;
+  ainsn_t ainsn;
+  arc_t arc;
+  int i;
+
+  VLA_PTR_CREATE (automaton_states, 1500,
+                 "automaton states for forming important insn automata sets");
+  /* Mark important ainsns.  */
+  for (automaton = description->first_automaton;
+       automaton != NULL;
+       automaton = automaton->next_automaton)
+    {
+      VLA_PTR_NULLIFY (automaton_states);
+      pass_states (automaton, add_automaton_state);
+      for (state_ptr = VLA_PTR_BEGIN (automaton_states);
+          state_ptr <= (state_t *) VLA_PTR_LAST (automaton_states);
+          state_ptr++)
+       {
+         for (arc = first_out_arc (*state_ptr);
+              arc != NULL;
+              arc = next_out_arc (arc))
+           if (arc->to_state != *state_ptr)
+             {
+               if (!arc->insn->first_insn_with_same_reservs)
+                 abort ();
+               for (ainsn = arc->insn;
+                    ainsn != NULL;
+                    ainsn = ainsn->next_same_reservs_insn)
+                 ainsn->important_p = TRUE;
+             }
+       }
+    }
+  VLA_PTR_DELETE (automaton_states);
+  /* Create automata sets for the insns.  */
+  for (i = 0; i < description->decls_num; i++)
+    {
+      decl = description->decls [i];
+      if (decl->mode == dm_insn_reserv)
+       {
+         automata_list_start ();
+         for (automaton = description->first_automaton;
+              automaton != NULL;
+              automaton = automaton->next_automaton)
+           for (ainsn = automaton->ainsn_list;
+                ainsn != NULL;
+                ainsn = ainsn->next_ainsn)
+             if (ainsn->important_p
+                 && ainsn->insn_reserv_decl == &decl->decl.insn_reserv)
+               {
+                 automata_list_add (automaton);
+                 break;
+               }
+         decl->decl.insn_reserv.important_automata_list
+           = automata_list_finish ();
+       }
+    }
+}
+
+
 /* The following is top level function to generate automat(a,on) for
    fast recognition of pipeline hazards.  */
 void
@@ -8625,48 +9326,50 @@ expand_automata ()
 {
   int i;
 
-  if (VLA_PTR_LENGTH (decls) != 0)
+  description = create_node (sizeof (struct description)
+                            /* One entry for cycle advancing insn.  */
+                            + sizeof (decl_t) * VLA_PTR_LENGTH (decls));
+  description->decls_num = VLA_PTR_LENGTH (decls);
+  description->query_units_num = 0;
+  for (i = 0; i < description->decls_num; i++)
     {
-      description = create_node (sizeof (struct description)
-                                + sizeof (decl_t)
-                                /* One entry for cycle advancing insn.  */
-                                * VLA_PTR_LENGTH (decls));
-      description->decls_num = VLA_PTR_LENGTH (decls);
-      description->query_units_num = 0;
-      for (i = 0; i < description->decls_num; i++)
-       {
-         description->decls [i] = VLA_PTR (decls, i);
-         if (description->decls [i]->mode == dm_unit
-             && description->decls [i]->decl.unit.query_p)
-           description->decls [i]->decl.unit.query_num
-             = description->query_units_num++;
-       }
-      all_time = create_ticker ();
-      check_time = create_ticker ();
-      fprintf (stderr, "Check description...");
+      description->decls [i] = VLA_PTR (decls, i);
+      if (description->decls [i]->mode == dm_unit
+         && description->decls [i]->decl.unit.query_p)
+        description->decls [i]->decl.unit.query_num
+         = description->query_units_num++;
+    }
+  all_time = create_ticker ();
+  check_time = create_ticker ();
+  fprintf (stderr, "Check description...");
+  fflush (stderr);
+  check_all_description ();
+  fprintf (stderr, "done\n");
+  ticker_off (&check_time);
+  generation_time = create_ticker ();
+  if (!have_error)
+    {
+      transform_insn_regexps ();
+      check_unit_distributions_to_automata ();
+    }
+  if (!have_error)
+    {
+      generate ();
+      check_automata_insn_issues ();
+    }
+  if (!have_error)
+    {
+      form_important_insn_automata_lists ();
+      fprintf (stderr, "Generation of attributes...");
       fflush (stderr);
-      check_all_description ();
+      make_internal_dfa_insn_code_attr ();
+      make_insn_alts_attr ();
+      make_default_insn_latency_attr ();
+      make_bypass_attr ();
       fprintf (stderr, "done\n");
-      ticker_off (&check_time);
-      generation_time = create_ticker ();
-      if (!have_error)
-       {
-         generate ();
-         check_automata ();
-         if (!have_error)
-           {
-             fprintf (stderr, "Generation of attributes...");
-             fflush (stderr);
-             make_internal_dfa_insn_code_attr ();
-             make_insn_alts_attr ();
-             make_default_insn_latency_attr ();
-             make_bypass_attr ();
-             fprintf (stderr, "done\n");
-           }
-       }
-      ticker_off (&generation_time);
-      ticker_off (&all_time);
     }
+  ticker_off (&generation_time);
+  ticker_off (&all_time);
   fprintf (stderr, "All other genattrtab stuff...");
   fflush (stderr);
 }
@@ -8693,7 +9396,9 @@ write_automata ()
   output_internal_min_issue_delay_func ();
   output_internal_trans_func ();
   /* Cache of insn dfa codes: */
-  fprintf (output_file, "\nstatic int *%s;\n\n", DFA_INSN_CODES_VARIABLE_NAME);
+  fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
+  fprintf (output_file, "\nstatic int %s;\n\n",
+          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);
@@ -8742,6 +9447,7 @@ write_automata ()
   output_time_statistics (stderr);
   finish_states ();
   finish_arcs ();
+  finish_automata_lists ();
   if (time_flag)
     {
       fprintf (stderr, "Summary:\n");