]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/genautomata.c
Daily bump.
[gcc.git] / gcc / genautomata.c
index 514c2e69255deca94caea48640f7583572825f59..d408eed77b5f1795ef2e2d689550c69a00ff4025 100644 (file)
@@ -1,6 +1,5 @@
 /* Pipeline hazard description translator.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
-   Free Software Foundation, Inc.
+   Copyright (C) 2000-2019 Free Software Foundation, Inc.
 
    Written by Vladimir Makarov <vmakarov@redhat.com>
 
@@ -115,8 +114,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gensupport.h"
 
 #include <math.h>
-#include "hashtab.h"
-#include "vec.h"
+#include "fnmatch.h"
 
 #ifndef CHAR_BIT
 #define CHAR_BIT 8
@@ -212,20 +210,8 @@ static struct obstack irp;
 \f
 /* Declare vector types for various data structures: */
 
-DEF_VEC_P(alt_state_t);
-DEF_VEC_ALLOC_P(alt_state_t, heap);
-DEF_VEC_P(ainsn_t);
-DEF_VEC_ALLOC_P(ainsn_t, heap);
-DEF_VEC_P(state_t);
-DEF_VEC_ALLOC_P(state_t, heap);
-DEF_VEC_P(decl_t);
-DEF_VEC_ALLOC_P(decl_t, heap);
-DEF_VEC_P(reserv_sets_t);
-DEF_VEC_ALLOC_P(reserv_sets_t, heap);
-
-DEF_VEC_I(vect_el_t);
-DEF_VEC_ALLOC_I(vect_el_t, heap);
-typedef VEC(vect_el_t, heap) *vla_hwint_t;
+
+typedef vec<vect_el_t> vla_hwint_t;
 \f
 /* Forward declarations of functions used before their definitions, only.  */
 static regexp_t gen_regexp_sequence    (const char *);
@@ -251,6 +237,8 @@ static arc_t next_out_arc              (arc_t);
 #define V_OPTION "-v"
 #define W_OPTION "-w"
 #define NDFA_OPTION "-ndfa"
+#define COLLAPSE_OPTION "-collapse-ndfa"
+#define NO_COMB_OPTION "-no-comb-vect"
 #define PROGRESS_OPTION "-progress"
 
 /* The following flags are set up by function `initiate_automaton_gen'.  */
@@ -258,9 +246,17 @@ static arc_t next_out_arc              (arc_t);
 /* Make automata with nondeterministic reservation by insns (`-ndfa').  */
 static int ndfa_flag;
 
+/* When making an NDFA, produce additional transitions that collapse
+   NDFA state into a deterministic one suitable for querying CPU units.
+   Provide advance-state transitions only for deterministic states.  */
+static int collapse_flag;
+
 /* Do not make minimization of DFA (`-no-minimization').  */
 static int no_minimization_flag;
 
+/* Do not try to generate a comb vector (`-no-comb-vect').  */
+static int no_comb_flag;
+
 /* Value of this variable is number of automata being generated.  The
    actual number of automata may be less this value if there is not
    sufficient number of units.  This value is defined by argument of
@@ -384,8 +380,8 @@ struct unit_decl
 struct bypass_decl
 {
   int latency;
-  const char *out_insn_name;
-  const char *in_insn_name;
+  const char *out_pattern;
+  const char *in_pattern;
   const char *bypass_guard_name;
 
   /* The following fields are defined by checker.  */
@@ -603,7 +599,7 @@ struct regexp
    NDFA.  */
 struct description
 {
-  int decls_num;
+  int decls_num, normal_decls_num;
 
   /* The following fields are defined by checker.  */
 
@@ -623,9 +619,8 @@ struct description
   automaton_t first_automaton;
 
   /* The following field is created by pipeline hazard parser and
-     contains all declarations.  We allocate additional entry for
-     special insn "cycle advancing" which is added by the automaton
-     generator.  */
+     contains all declarations.  We allocate additional entries for
+     two special insns which are added by the automaton generator.  */
   decl_t decls [1];
 };
 
@@ -810,6 +805,9 @@ struct automaton
   /* The following field value is the list of insn declarations for
      given automaton.  */
   ainsn_t ainsn_list;
+  /* Pointers to the ainsns corresponding to the special reservations.  */
+  ainsn_t advance_ainsn, collapse_ainsn;
+
   /* The following field value is the corresponding automaton
      declaration.  This field is not NULL only if the automatic
      partition on automata is not used.  */
@@ -881,7 +879,7 @@ struct state_ainsn_table
 /* Macros to access members of unions.  Use only them for access to
    union members of declarations and regexps.  */
 
-#if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
+#if CHECKING_P && (GCC_VERSION >= 2007)
 
 #define DECL_UNIT(d) __extension__                                     \
 (({ __typeof (d) const _decl = (d);                                    \
@@ -1072,7 +1070,7 @@ regexp_mode_check_failed (enum regexp_mode mode,
   exit (1);
 }
 
-#else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
+#else /* #if CHECKING_P && (GCC_VERSION >= 2007) */
 
 #define DECL_UNIT(d) (&(d)->decl.unit)
 #define DECL_BYPASS(d) (&(d)->decl.bypass)
@@ -1090,7 +1088,7 @@ regexp_mode_check_failed (enum regexp_mode mode,
 #define REGEXP_ALLOF(r) (&(r)->regexp.allof)
 #define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
 
-#endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
+#endif /* #if CHECKING_P && (GCC_VERSION >= 2007) */
 
 #define XCREATENODE(T) ((T *) create_node (sizeof (T)))
 #define XCREATENODEVEC(T, N) ((T *) create_node (sizeof (T) * (N)))
@@ -1137,7 +1135,7 @@ check_name (const char * name, pos_t pos ATTRIBUTE_UNUSED)
 
 /* Pointers to all declarations during IR generation are stored in the
    following.  */
-static VEC(decl_t, heap) *decls;
+static vec<decl_t> decls;
 
 /* Given a pointer to a (char *) and a separator, return an alloc'ed
    string containing the next separated element, taking parentheses
@@ -1178,7 +1176,7 @@ next_sep_el (const char **pstr, int sep, int par_flag)
        }
     }
   obstack_1grow (&irp, '\0');
-  out_str = obstack_base (&irp);
+  out_str = (char *) obstack_base (&irp);
   obstack_finish (&irp);
 
   *pstr = p;
@@ -1245,16 +1243,18 @@ 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'.  */
 static void
-gen_cpu_unit (rtx def)
+gen_cpu_unit (md_rtx_info *info)
 {
   decl_t decl;
   char **str_cpu_units;
   int vect_length;
   int i;
 
+  rtx def = info->def;
   str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
   if (str_cpu_units == NULL)
-    fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+             XSTR (def, 0), GET_RTX_NAME (GET_CODE (def)));
   for (i = 0; i < vect_length; i++)
     {
       decl = XCREATENODE (struct decl);
@@ -1265,7 +1265,7 @@ gen_cpu_unit (rtx def)
       DECL_UNIT (decl)->query_p = 0;
       DECL_UNIT (decl)->min_occ_cycle_num = -1;
       DECL_UNIT (decl)->in_set_p = 0;
-      VEC_safe_push (decl_t, heap, decls, decl);
+      decls.safe_push (decl);
     }
 }
 
@@ -1274,17 +1274,19 @@ 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'.  */
 static void
-gen_query_cpu_unit (rtx def)
+gen_query_cpu_unit (md_rtx_info *info)
 {
   decl_t decl;
   char **str_cpu_units;
   int vect_length;
   int i;
 
+  rtx def = info->def;
   str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',',
                                FALSE);
   if (str_cpu_units == NULL)
-    fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+             XSTR (def, 0), GET_RTX_NAME (GET_CODE (def)));
   for (i = 0; i < vect_length; i++)
     {
       decl = XCREATENODE (struct decl);
@@ -1293,7 +1295,7 @@ gen_query_cpu_unit (rtx def)
       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);
+      decls.safe_push (decl);
     }
 }
 
@@ -1303,21 +1305,24 @@ gen_query_cpu_unit (rtx def)
    in a struct bypass_decl with information used later by
    `expand_automata'.  */
 static void
-gen_bypass (rtx def)
+gen_bypass (md_rtx_info *info)
 {
   decl_t decl;
-  char **out_insns;
+  char **out_patterns;
   int out_length;
-  char **in_insns;
+  char **in_patterns;
   int in_length;
   int i, j;
 
-  out_insns = get_str_vect (XSTR (def, 1), &out_length, ',', FALSE);
-  if (out_insns == NULL)
-    fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
-  in_insns = get_str_vect (XSTR (def, 2), &in_length, ',', FALSE);
-  if (in_insns == NULL)
-    fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
+  rtx def = info->def;
+  out_patterns = get_str_vect (XSTR (def, 1), &out_length, ',', FALSE);
+  if (out_patterns == NULL)
+    fatal_at (info->loc, "invalid string `%s' in %s",
+             XSTR (def, 1), GET_RTX_NAME (GET_CODE (def)));
+  in_patterns = get_str_vect (XSTR (def, 2), &in_length, ',', FALSE);
+  if (in_patterns == NULL)
+    fatal_at (info->loc, "invalid string `%s' in %s",
+             XSTR (def, 2), GET_RTX_NAME (GET_CODE (def)));
   for (i = 0; i < out_length; i++)
     for (j = 0; j < in_length; j++)
       {
@@ -1325,10 +1330,10 @@ gen_bypass (rtx def)
        decl->mode = dm_bypass;
        decl->pos = 0;
        DECL_BYPASS (decl)->latency = XINT (def, 0);
-       DECL_BYPASS (decl)->out_insn_name = out_insns [i];
-       DECL_BYPASS (decl)->in_insn_name = in_insns [j];
+       DECL_BYPASS (decl)->out_pattern = out_patterns[i];
+       DECL_BYPASS (decl)->in_pattern = in_patterns[j];
        DECL_BYPASS (decl)->bypass_guard_name = XSTR (def, 3);
-       VEC_safe_push (decl_t, heap, decls, decl);
+       decls.safe_push (decl);
       }
 }
 
@@ -1338,7 +1343,7 @@ gen_bypass (rtx def)
    struct excl_rel_decl (excl) with information used later by
    `expand_automata'.  */
 static void
-gen_excl_set (rtx def)
+gen_excl_set (md_rtx_info *info)
 {
   decl_t decl;
   char **first_str_cpu_units;
@@ -1347,16 +1352,20 @@ gen_excl_set (rtx def)
   int length;
   int i;
 
+  rtx def = info->def;
   first_str_cpu_units
     = get_str_vect (XSTR (def, 0), &first_vect_length, ',', FALSE);
   if (first_str_cpu_units == NULL)
-    fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+             XSTR (def, 0), GET_RTX_NAME (GET_CODE (def)));
   second_str_cpu_units = get_str_vect (XSTR (def, 1), &length, ',',
                                       FALSE);
   if (second_str_cpu_units == NULL)
-    fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+             XSTR (def, 1), GET_RTX_NAME (GET_CODE (def)));
   length += first_vect_length;
-  decl = XCREATENODEVAR (struct decl, 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;
@@ -1367,7 +1376,7 @@ gen_excl_set (rtx def)
     else
       DECL_EXCL (decl)->names [i]
        = second_str_cpu_units [i - first_vect_length];
-  VEC_safe_push (decl_t, heap, decls, decl);
+  decls.safe_push (decl);
 }
 
 /* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
@@ -1377,7 +1386,7 @@ gen_excl_set (rtx def)
    We fill a struct unit_pattern_rel_decl with information used later
    by `expand_automata'.  */
 static void
-gen_presence_absence_set (rtx def, int presence_p, int final_p)
+gen_presence_absence_set (md_rtx_info *info, int presence_p, int final_p)
 {
   decl_t decl;
   char **str_cpu_units;
@@ -1388,27 +1397,17 @@ gen_presence_absence_set (rtx def, int presence_p, int final_p)
   int patterns_length;
   int i;
 
+  rtx def = info->def;
   str_cpu_units = get_str_vect (XSTR (def, 0), &cpu_units_length, ',',
                                FALSE);
   if (str_cpu_units == NULL)
-    fatal ((presence_p
-           ? (final_p
-              ? "invalid first string `%s' in final_presence_set"
-              : "invalid first string `%s' in presence_set")
-           : (final_p
-              ? "invalid first string `%s' in final_absence_set"
-              : "invalid first string `%s' in absence_set")),
-          XSTR (def, 0));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+             XSTR (def, 0), GET_RTX_NAME (GET_CODE (def)));
   str_pattern_lists = get_str_vect (XSTR (def, 1),
                                    &patterns_length, ',', FALSE);
   if (str_pattern_lists == NULL)
-    fatal ((presence_p
-           ? (final_p
-              ? "invalid second string `%s' in final_presence_set"
-              : "invalid second string `%s' in presence_set")
-           : (final_p
-              ? "invalid second string `%s' in final_absence_set"
-              : "invalid second string `%s' in absence_set")), XSTR (def, 1));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+             XSTR (def, 1), GET_RTX_NAME (GET_CODE (def)));
   str_patterns = XOBNEWVEC (&irp, char **, patterns_length);
   for (i = 0; i < patterns_length; i++)
     {
@@ -1436,18 +1435,18 @@ gen_presence_absence_set (rtx def, int presence_p, int final_p)
       DECL_ABSENCE (decl)->patterns_num = patterns_length;
       DECL_ABSENCE (decl)->final_p = final_p;
     }
-  VEC_safe_push (decl_t, heap, decls, decl);
+  decls.safe_push (decl);
 }
 
 /* Process a PRESENCE_SET.
 
-    This gives information about a cpu unit reservation requirements.
+   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'.  */
 static void
-gen_presence_set (rtx def)
+gen_presence_set (md_rtx_info *info)
 {
-  gen_presence_absence_set (def, TRUE, FALSE);
+  gen_presence_absence_set (info, TRUE, FALSE);
 }
 
 /* Process a FINAL_PRESENCE_SET.
@@ -1456,9 +1455,9 @@ gen_presence_set (rtx def)
    We fill a struct unit_pattern_rel_decl (presence) with information
    used later by `expand_automata'.  */
 static void
-gen_final_presence_set (rtx def)
+gen_final_presence_set (md_rtx_info *info)
 {
-  gen_presence_absence_set (def, TRUE, TRUE);
+  gen_presence_absence_set (info, TRUE, TRUE);
 }
 
 /* Process an ABSENCE_SET.
@@ -1467,9 +1466,9 @@ gen_final_presence_set (rtx def)
    We fill a struct unit_pattern_rel_decl (absence) with information
    used later by `expand_automata'.  */
 static void
-gen_absence_set (rtx def)
+gen_absence_set (md_rtx_info *info)
 {
-  gen_presence_absence_set (def, FALSE, FALSE);
+  gen_presence_absence_set (info, FALSE, FALSE);
 }
 
 /* Process a FINAL_ABSENCE_SET.
@@ -1478,9 +1477,9 @@ gen_absence_set (rtx def)
    We fill a struct unit_pattern_rel_decl (absence) with information
    used later by `expand_automata'.  */
 static void
-gen_final_absence_set (rtx def)
+gen_final_absence_set (md_rtx_info *info)
 {
-  gen_presence_absence_set (def, FALSE, TRUE);
+  gen_presence_absence_set (info, FALSE, TRUE);
 }
 
 /* Process a DEFINE_AUTOMATON.
@@ -1489,23 +1488,25 @@ gen_final_absence_set (rtx def)
    recognizing pipeline hazards.  We fill a struct automaton_decl
    with information used later by `expand_automata'.  */
 static void
-gen_automaton (rtx def)
+gen_automaton (md_rtx_info *info)
 {
   decl_t decl;
   char **str_automata;
   int vect_length;
   int i;
 
+  rtx def = info->def;
   str_automata = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
   if (str_automata == NULL)
-    fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+             XSTR (def, 0), GET_RTX_NAME (GET_CODE (def)));
   for (i = 0; i < vect_length; i++)
     {
       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);
+      decls.safe_push (decl);
     }
 }
 
@@ -1514,24 +1515,30 @@ gen_automaton (rtx def)
    This gives information how to generate finite state automaton used
    for recognizing pipeline hazards.  */
 static void
-gen_automata_option (rtx def)
+gen_automata_option (md_rtx_info *info)
 {
-  if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
+  const char *option = XSTR (info->def, 0);
+  if (strcmp (option, NO_MINIMIZATION_OPTION + 1) == 0)
     no_minimization_flag = 1;
-  else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
+  else if (strcmp (option, TIME_OPTION + 1) == 0)
     time_flag = 1;
-  else if (strcmp (XSTR (def, 0), STATS_OPTION + 1) == 0)
+  else if (strcmp (option, STATS_OPTION + 1) == 0)
     stats_flag = 1;
-  else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
+  else if (strcmp (option, V_OPTION + 1) == 0)
     v_flag = 1;
-  else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
+  else if (strcmp (option, W_OPTION + 1) == 0)
     w_flag = 1;
-  else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
+  else if (strcmp (option, NDFA_OPTION + 1) == 0)
     ndfa_flag = 1;
-  else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
+  else if (strcmp (option, COLLAPSE_OPTION + 1) == 0)
+    collapse_flag = 1;
+  else if (strcmp (option, NO_COMB_OPTION + 1) == 0)
+    no_comb_flag = 1;
+  else if (strcmp (option, PROGRESS_OPTION + 1) == 0)
     progress_flag = 1;
   else
-    fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
+    fatal_at (info->loc, "invalid option `%s' in %s",
+             option, GET_RTX_NAME (GET_CODE (info->def)));
 }
 
 /* Name in reservation to denote absence reservation.  */
@@ -1603,7 +1610,7 @@ gen_regexp_repeat (const char *str)
       return regexp;
     }
   else
-    return gen_regexp_el (str);
+    return gen_regexp_el (repeat_vect[0]);
 }
 
 /* Parse reservation STR which possibly contains separator '+'.  */
@@ -1629,7 +1636,7 @@ gen_regexp_allof (const char *str)
       return allof;
     }
   else
-    return gen_regexp_repeat (str);
+    return gen_regexp_repeat (allof_vect[0]);
 }
 
 /* Parse reservation STR which possibly contains separator '|'.  */
@@ -1655,7 +1662,7 @@ gen_regexp_oneof (const char *str)
       return oneof;
     }
   else
-    return gen_regexp_allof (str);
+    return gen_regexp_allof (oneof_vect[0]);
 }
 
 /* Parse reservation STR which possibly contains separator ','.  */
@@ -1668,6 +1675,10 @@ gen_regexp_sequence (const char *str)
   int i;
 
   sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
+  if (els_num == -1)
+    fatal ("unbalanced parentheses in reservation `%s'", str);
+  if (sequence_vect == NULL)
+    fatal ("invalid reservation `%s'", str);
   if (els_num > 1)
     {
       sequence = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
@@ -1680,7 +1691,7 @@ gen_regexp_sequence (const char *str)
       return sequence;
     }
   else
-    return gen_regexp_oneof (str);
+    return gen_regexp_oneof (sequence_vect[0]);
 }
 
 /* Parse construction reservation STR.  */
@@ -1688,7 +1699,7 @@ static regexp_t
 gen_regexp (const char *str)
 {
   reserv_str = str;
-  return gen_regexp_sequence (str);;
+  return gen_regexp_sequence (str);
 }
 
 /* Process a DEFINE_RESERVATION.
@@ -1697,16 +1708,17 @@ gen_regexp (const char *str)
    in a struct reserv_decl with information used later by
    `expand_automata'.  */
 static void
-gen_reserv (rtx def)
+gen_reserv (md_rtx_info *info)
 {
   decl_t decl;
 
+  rtx def = info->def;
   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);
+  decls.safe_push (decl);
 }
 
 /* Process a DEFINE_INSN_RESERVATION.
@@ -1715,10 +1727,11 @@ gen_reserv (rtx def)
    insn.  We fill a struct insn_reserv_decl with information used
    later by `expand_automata'.  */
 static void
-gen_insn_reserv (rtx def)
+gen_insn_reserv (md_rtx_info *info)
 {
   decl_t decl;
 
+  rtx def = info->def;
   decl = XCREATENODE (struct decl);
   decl->mode = dm_insn_reserv;
   decl->pos = 0;
@@ -1727,7 +1740,7 @@ gen_insn_reserv (rtx def)
   DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
   DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
   DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3));
-  VEC_safe_push (decl_t, heap, decls, decl);
+  decls.safe_push (decl);
 }
 
 \f
@@ -1796,7 +1809,7 @@ insert_automaton_decl (decl_t automaton_decl)
 {
   void **entry_ptr;
 
-  entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1);
+  entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, INSERT);
   if (*entry_ptr == NULL)
     *entry_ptr = (void *) automaton_decl;
   return (decl_t) *entry_ptr;
@@ -1895,7 +1908,7 @@ insert_insn_decl (decl_t insn_decl)
 {
   void **entry_ptr;
 
-  entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1);
+  entry_ptr = htab_find_slot (insn_decl_table, insn_decl, INSERT);
   if (*entry_ptr == NULL)
     *entry_ptr = (void *) insn_decl;
   return (decl_t) *entry_ptr;
@@ -1996,7 +2009,7 @@ insert_decl (decl_t decl)
 {
   void **entry_ptr;
 
-  entry_ptr = htab_find_slot (decl_table, decl, 1);
+  entry_ptr = htab_find_slot (decl_table, decl, INSERT);
   if (*entry_ptr == NULL)
     *entry_ptr = (void *) decl;
   return (decl_t) *entry_ptr;
@@ -2314,8 +2327,7 @@ add_presence_absence (unit_set_el_t dest_list,
                          no_error_flag = 0;
                        }
                      else
-                       warning
-                         (0, "unit `%s' excludes and requires presence of `%s'",
+                       warning ("unit `%s' excludes and requires presence of `%s'",
                           dst->unit_decl->name, unit->name);
                    }
                }
@@ -2328,22 +2340,20 @@ add_presence_absence (unit_set_el_t dest_list,
                  {
                    if (!w_flag)
                      {
-                       error
-                         ("unit `%s' requires absence and presence of `%s'",
-                          dst->unit_decl->name, unit->name);
+                       error ("unit `%s' requires absence and presence of `%s'",
+                              dst->unit_decl->name, unit->name);
                        no_error_flag = 0;
                      }
                    else
-                     warning
-                       (0, "unit `%s' requires absence and presence of `%s'",
-                        dst->unit_decl->name, unit->name);
+                     warning ("unit `%s' requires absence and presence of `%s'",
+                              dst->unit_decl->name, unit->name);
                  }
            if (no_error_flag)
              {
                for (prev_el = (presence_p
                                ? (final_p
                                   ? dst->unit_decl->final_presence_list
-                                  : dst->unit_decl->final_presence_list)
+                                  : dst->unit_decl->presence_list)
                                : (final_p
                                   ? dst->unit_decl->final_absence_list
                                   : dst->unit_decl->absence_list));
@@ -2376,7 +2386,7 @@ add_presence_absence (unit_set_el_t dest_list,
 
 /* The function inserts BYPASS in the list of bypasses of the
    corresponding output insn.  The order of bypasses in the list is
-   decribed in a comment for member `bypass_list' (see above).  If
+   described in a comment for member `bypass_list' (see above).  If
    there is already the same bypass in the list the function reports
    this and does nothing.  */
 static void
@@ -2385,7 +2395,7 @@ insert_bypass (struct bypass_decl *bypass)
   struct bypass_decl *curr, *last;
   struct insn_reserv_decl *out_insn_reserv = bypass->out_insn_reserv;
   struct insn_reserv_decl *in_insn_reserv = bypass->in_insn_reserv;
-  
+
   for (curr = out_insn_reserv->bypass_list, last = NULL;
        curr != NULL;
        last = curr, curr = curr->next)
@@ -2400,19 +2410,19 @@ insert_bypass (struct bypass_decl *bypass)
              {
                if (!w_flag)
                  error ("the same bypass `%s - %s' is already defined",
-                        bypass->out_insn_name, bypass->in_insn_name);
+                        bypass->out_pattern, bypass->in_pattern);
                else
-                 warning (0, "the same bypass `%s - %s' is already defined",
-                          bypass->out_insn_name, bypass->in_insn_name);
+                 warning ("the same bypass `%s - %s' is already defined",
+                          bypass->out_pattern, bypass->in_pattern);
              }
            else if (!w_flag)
              error ("the same bypass `%s - %s' (guard %s) is already defined",
-                    bypass->out_insn_name, bypass->in_insn_name,
+                    bypass->out_pattern, bypass->in_pattern,
                     bypass->bypass_guard_name);
            else
              warning
-               (0, "the same bypass `%s - %s' (guard %s) is already defined",
-                bypass->out_insn_name, bypass->in_insn_name,
+               ("the same bypass `%s - %s' (guard %s) is already defined",
+                bypass->out_pattern, bypass->in_pattern,
                 bypass->bypass_guard_name);
            return;
          }
@@ -2423,7 +2433,7 @@ insert_bypass (struct bypass_decl *bypass)
            last = curr;
            break;
          }
-         
+
       }
   if (last == NULL)
     {
@@ -2437,6 +2447,92 @@ insert_bypass (struct bypass_decl *bypass)
     }
 }
 
+/* BYPASS is a define_bypass decl that includes glob pattern PATTERN.
+   Call FN (BYPASS, INSN, DATA) for each matching instruction INSN.  */
+
+static void
+for_each_matching_insn (decl_t bypass, const char *pattern,
+                       void (*fn) (decl_t, decl_t, void *), void *data)
+{
+  decl_t insn_reserv;
+  bool matched_p;
+  int i;
+
+  matched_p = false;
+  if (strpbrk (pattern, "*?["))
+    for (i = 0; i < description->decls_num; i++)
+      {
+       insn_reserv = description->decls[i];
+       if (insn_reserv->mode == dm_insn_reserv
+           && fnmatch (pattern, DECL_INSN_RESERV (insn_reserv)->name, 0) == 0)
+         {
+           fn (bypass, insn_reserv, data);
+           matched_p = true;
+         }
+      }
+  else
+    {
+      insn_reserv = find_insn_decl (pattern);
+      if (insn_reserv)
+       {
+         fn (bypass, insn_reserv, data);
+         matched_p = true;
+       }
+    }
+  if (!matched_p)
+    error ("there is no insn reservation that matches `%s'", pattern);
+}
+
+/* A subroutine of process_bypass that is called for each pair
+   of matching instructions.  OUT_INSN_RESERV is the output
+   instruction and DATA is the input instruction.  */
+
+static void
+process_bypass_2 (decl_t model, decl_t out_insn_reserv, void *data)
+{
+  struct bypass_decl *bypass;
+  decl_t in_insn_reserv;
+
+  in_insn_reserv = (decl_t) data;
+  if (strcmp (DECL_INSN_RESERV (in_insn_reserv)->name,
+             DECL_BYPASS (model)->in_pattern) == 0
+      && strcmp (DECL_INSN_RESERV (out_insn_reserv)->name,
+                DECL_BYPASS (model)->out_pattern) == 0)
+    bypass = DECL_BYPASS (model);
+  else
+    {
+      bypass = XCNEW (struct bypass_decl);
+      bypass->latency = DECL_BYPASS (model)->latency;
+      bypass->out_pattern = DECL_INSN_RESERV (out_insn_reserv)->name;
+      bypass->in_pattern = DECL_INSN_RESERV (in_insn_reserv)->name;
+      bypass->bypass_guard_name = DECL_BYPASS (model)->bypass_guard_name;
+    }
+  bypass->out_insn_reserv = DECL_INSN_RESERV (out_insn_reserv);
+  bypass->in_insn_reserv = DECL_INSN_RESERV (in_insn_reserv);
+  insert_bypass (bypass);
+}
+
+/* A subroutine of process_bypass that is called for each input
+   instruction IN_INSN_RESERV.  */
+
+static void
+process_bypass_1 (decl_t bypass, decl_t in_insn_reserv,
+                 void *data ATTRIBUTE_UNUSED)
+{
+  for_each_matching_insn (bypass, DECL_BYPASS (bypass)->out_pattern,
+                         process_bypass_2, in_insn_reserv);
+}
+
+/* Process define_bypass decl BYPASS, inserting a bypass for each specific
+   pair of insn reservations.  */
+
+static void
+process_bypass (decl_t bypass)
+{
+  for_each_matching_insn (bypass, DECL_BYPASS (bypass)->in_pattern,
+                         process_bypass_1, NULL);
+}
+
 /* The function processes pipeline description declarations, checks
    their correctness, and forms exclusion/presence/absence sets.  */
 static void
@@ -2445,8 +2541,6 @@ process_decls (void)
   decl_t decl;
   decl_t automaton_decl;
   decl_t decl_in_table;
-  decl_t out_insn_reserv;
-  decl_t in_insn_reserv;
   int automaton_presence;
   int i;
 
@@ -2465,7 +2559,7 @@ process_decls (void)
                error ("repeated declaration of automaton `%s'",
                       DECL_AUTOMATON (decl)->name);
              else
-               warning (0, "repeated declaration of automaton `%s'",
+               warning ("repeated declaration of automaton `%s'",
                         DECL_AUTOMATON (decl)->name);
            }
        }
@@ -2492,8 +2586,8 @@ process_decls (void)
        {
          if (DECL_BYPASS (decl)->latency < 0)
            error ("define_bypass `%s - %s' has negative latency time",
-                  DECL_BYPASS (decl)->out_insn_name,
-                  DECL_BYPASS (decl)->in_insn_name);
+                  DECL_BYPASS (decl)->out_pattern,
+                  DECL_BYPASS (decl)->in_pattern);
        }
       else if (decl->mode == dm_unit || decl->mode == dm_reserv)
        {
@@ -2554,24 +2648,7 @@ process_decls (void)
     {
       decl = description->decls [i];
       if (decl->mode == dm_bypass)
-       {
-         out_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->out_insn_name);
-         in_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->in_insn_name);
-         if (out_insn_reserv == NULL)
-           error ("there is no insn reservation `%s'",
-                  DECL_BYPASS (decl)->out_insn_name);
-         else if (in_insn_reserv == NULL)
-           error ("there is no insn reservation `%s'",
-                  DECL_BYPASS (decl)->in_insn_name);
-         else
-           {
-             DECL_BYPASS (decl)->out_insn_reserv
-               = DECL_INSN_RESERV (out_insn_reserv);
-             DECL_BYPASS (decl)->in_insn_reserv
-               = DECL_INSN_RESERV (in_insn_reserv);
-             insert_bypass (DECL_BYPASS (decl));
-           }
-       }
+       process_bypass (decl);
     }
 
   /* Check exclusion set declarations and form exclusion sets.  */
@@ -2664,7 +2741,7 @@ check_automaton_usage (void)
          if (!w_flag)
            error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
          else
-           warning (0, "automaton `%s' is not used",
+           warning ("automaton `%s' is not used",
                     DECL_AUTOMATON (decl)->name);
        }
     }
@@ -2778,14 +2855,14 @@ check_usage (void)
          if (!w_flag)
            error ("unit `%s' is not used", DECL_UNIT (decl)->name);
          else
-           warning (0, "unit `%s' is not used", DECL_UNIT (decl)->name);
+           warning ("unit `%s' is not used", DECL_UNIT (decl)->name);
        }
       else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
        {
          if (!w_flag)
            error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
          else
-           warning (0, "reservation `%s' is not used", DECL_RESERV (decl)->name);
+           warning ("reservation `%s' is not used", DECL_RESERV (decl)->name);
        }
     }
 }
@@ -2939,7 +3016,7 @@ process_regexp_cycles (regexp_t regexp, int max_start_cycle,
       {
        int max_cycle = 0;
        int min_cycle = 0;
-       
+
        for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
          {
            process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
@@ -2959,7 +3036,7 @@ process_regexp_cycles (regexp_t regexp, int max_start_cycle,
       {
        int max_cycle = 0;
        int min_cycle = 0;
-       
+
        for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
          {
            process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
@@ -3137,6 +3214,10 @@ static ticker_t all_time;
 
 /* Pseudo insn decl which denotes advancing cycle.  */
 static decl_t advance_cycle_insn_decl;
+/* Pseudo insn decl which denotes collapsing the NDFA state.  */
+static decl_t collapse_ndfa_insn_decl;
+
+/* Create and record a decl for the special advance-cycle transition.  */
 static void
 add_advance_cycle_insn_decl (void)
 {
@@ -3152,6 +3233,31 @@ add_advance_cycle_insn_decl (void)
   description->insns_num++;
 }
 
+/* Create and record a decl for the special collapse-NDFA transition.  */
+static void
+add_collapse_ndfa_insn_decl (void)
+{
+  collapse_ndfa_insn_decl = XCREATENODE (struct decl);
+  collapse_ndfa_insn_decl->mode = dm_insn_reserv;
+  collapse_ndfa_insn_decl->pos = no_pos;
+  DECL_INSN_RESERV (collapse_ndfa_insn_decl)->regexp = NULL;
+  DECL_INSN_RESERV (collapse_ndfa_insn_decl)->name = "$collapse_ndfa";
+  DECL_INSN_RESERV (collapse_ndfa_insn_decl)->insn_num
+    = description->insns_num;
+  description->decls [description->decls_num] = collapse_ndfa_insn_decl;
+  description->decls_num++;
+  description->insns_num++;
+}
+
+/* True if DECL is either of the two special decls we created.  */
+static bool
+special_decl_p (struct insn_reserv_decl *decl)
+{
+  return (decl == DECL_INSN_RESERV (advance_cycle_insn_decl)
+         || (collapse_flag
+             && decl == DECL_INSN_RESERV (collapse_ndfa_insn_decl)));
+}
+
 \f
 /* Abstract data `alternative states' which represents
    nondeterministic nature of the description (see comments for
@@ -3239,7 +3345,6 @@ static alt_state_t
 uniq_sort_alt_states (alt_state_t alt_states_list)
 {
   alt_state_t curr_alt_state;
-  VEC(alt_state_t, heap) *alt_states;
   size_t i;
   size_t prev_unique_state_ind;
   alt_state_t result;
@@ -3249,35 +3354,30 @@ uniq_sort_alt_states (alt_state_t alt_states_list)
   if (alt_states_list->next_alt_state == 0)
     return alt_states_list;
 
-  alt_states = VEC_alloc (alt_state_t, heap, 150);
+  auto_vec<alt_state_t, 150> alt_states;
   for (curr_alt_state = alt_states_list;
        curr_alt_state != NULL;
        curr_alt_state = curr_alt_state->next_alt_state)
-    VEC_safe_push (alt_state_t, heap, alt_states, curr_alt_state);
+    alt_states.safe_push (curr_alt_state);
 
-  qsort (VEC_address (alt_state_t, alt_states),
-        VEC_length  (alt_state_t, alt_states),
-        sizeof (alt_state_t), alt_state_cmp);
+  alt_states.qsort (alt_state_cmp);
 
   prev_unique_state_ind = 0;
-  for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
-    if (VEC_index (alt_state_t, alt_states, prev_unique_state_ind)->state
-       != VEC_index (alt_state_t, alt_states, i)->state)
+  for (i = 1; i < alt_states.length (); i++)
+    if (alt_states[prev_unique_state_ind]->state != alt_states[i]->state)
       {
        prev_unique_state_ind++;
-       VEC_replace (alt_state_t, alt_states, prev_unique_state_ind,
-                    VEC_index (alt_state_t, alt_states, i));
+       alt_states[prev_unique_state_ind] = alt_states[i];
       }
-  VEC_truncate (alt_state_t, alt_states, prev_unique_state_ind + 1);
+  alt_states.truncate (prev_unique_state_ind + 1);
 
-  for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
-    VEC_index (alt_state_t, alt_states, i-1)->next_sorted_alt_state
-      = VEC_index (alt_state_t, alt_states, i);
-  VEC_last (alt_state_t, alt_states)->next_sorted_alt_state = 0;
+  for (i = 1; i < alt_states.length (); i++)
+    alt_states[i-1]->next_sorted_alt_state
+      = alt_states[i];
+  alt_states.last ()->next_sorted_alt_state = 0;
 
-  result = VEC_index (alt_state_t, alt_states, 0);
+  result = alt_states[0];
 
-  VEC_free (alt_state_t, heap, alt_states);
   return result;
 }
 
@@ -3316,16 +3416,19 @@ finish_alt_states (void)
 
 /* Set bit number bitno in the bit string.  The macro is not side
    effect proof.  */
-#define SET_BIT(bitstring, bitno)                                        \
-  (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
+#define bitmap_set_bit(bitstring, bitno)                                         \
+  ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] |=                  \
+       (HOST_WIDE_INT)1 << (bitno) % (sizeof (*(bitstring)) * CHAR_BIT))
 
 #define CLEAR_BIT(bitstring, bitno)                                      \
-  (((char *) (bitstring)) [(bitno) / CHAR_BIT] &= ~(1 << (bitno) % CHAR_BIT))
+  ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] &=                  \
+       ~((HOST_WIDE_INT)1 << (bitno) % (sizeof (*(bitstring)) * CHAR_BIT)))
 
 /* Test if bit number bitno in the bitstring is set.  The macro is not
    side effect proof.  */
-#define TEST_BIT(bitstring, bitno)                                        \
-  (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
+#define bitmap_bit_p(bitstring, bitno)                                   \
+  ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] >>                  \
+       (bitno) % (sizeof (*(bitstring)) * CHAR_BIT) & 1)
 
 \f
 
@@ -3396,7 +3499,7 @@ reserv_sets_hash_value (reserv_sets_t reservs)
     {
       reservs_num--;
       hash_value += ((*reserv_ptr >> i)
-                    | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
+                    | (*reserv_ptr << (((sizeof (set_el_t) * CHAR_BIT) - 1) & -i)));
       i++;
       if (i == sizeof (set_el_t) * CHAR_BIT)
        i = 0;
@@ -3452,7 +3555,7 @@ static void
 set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
 {
   gcc_assert (cycle_num < max_cycles_num);
-  SET_BIT (reservs, cycle_num * els_in_cycle_reserv
+  bitmap_set_bit (reservs, cycle_num * els_in_cycle_reserv
            * sizeof (set_el_t) * CHAR_BIT + unit_num);
 }
 
@@ -3462,7 +3565,7 @@ static int
 test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
 {
   gcc_assert (cycle_num < max_cycles_num);
-  return TEST_BIT (reservs, cycle_num * els_in_cycle_reserv
+  return bitmap_bit_p (reservs, cycle_num * els_in_cycle_reserv
                   * sizeof (set_el_t) * CHAR_BIT + unit_num);
 }
 
@@ -3566,7 +3669,7 @@ output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
 
   reserved_units_num = 0;
   for (unit_num = 0; unit_num < description->units_num; unit_num++)
-    if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
+    if (bitmap_bit_p (reservs, start_cycle * els_in_cycle_reserv
                   * sizeof (set_el_t) * CHAR_BIT + unit_num))
       reserved_units_num++;
   gcc_assert (repetition_num > 0);
@@ -3576,7 +3679,7 @@ output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
   for (unit_num = 0;
        unit_num < description->units_num;
        unit_num++)
-    if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
+    if (bitmap_bit_p (reservs, start_cycle * els_in_cycle_reserv
                  * sizeof (set_el_t) * CHAR_BIT + unit_num))
       {
         if (reserved_units_num != 0)
@@ -3748,7 +3851,7 @@ insert_state (state_t state)
 {
   void **entry_ptr;
 
-  entry_ptr = htab_find_slot (state_table, (void *) state, 1);
+  entry_ptr = htab_find_slot (state_table, (void *) state, INSERT);
   if (*entry_ptr == NULL)
     *entry_ptr = (void *) state;
   return (state_t) *entry_ptr;
@@ -3905,21 +4008,26 @@ find_arc (state_t from_state, state_t to_state, ainsn_t insn)
   arc_t arc;
 
   for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
-    if (arc->to_state == to_state && arc->insn == insn)
+    if (arc->insn == insn
+       && (arc->to_state == to_state
+           || (collapse_flag
+               /* Any arc is good enough for a collapse-ndfa transition.  */
+               && (insn->insn_reserv_decl
+                   == DECL_INSN_RESERV (collapse_ndfa_insn_decl)))))
       return arc;
   return NULL;
 }
 
-/* The function adds arc from FROM_STATE to TO_STATE marked by AINSN.
-   The function returns added arc (or already existing arc).  */
-static arc_t
+/* The function adds arc from FROM_STATE to TO_STATE marked by AINSN,
+   unless such an arc already exists.  */
+static void
 add_arc (state_t from_state, state_t to_state, ainsn_t ainsn)
 {
   arc_t new_arc;
 
   new_arc = find_arc (from_state, to_state, ainsn);
   if (new_arc != NULL)
-    return new_arc;
+    return;
   if (first_free_arc == NULL)
     {
 #ifndef NDEBUG
@@ -3942,7 +4050,6 @@ add_arc (state_t from_state, state_t to_state, ainsn_t ainsn)
   from_state->first_out_arc = new_arc;
   from_state->num_out_arcs++;
   new_arc->next_arc_marked_by_insn = NULL;
-  return new_arc;
 }
 
 /* The function returns the first arc starting from STATE.  */
@@ -4104,7 +4211,7 @@ automata_list_finish (void)
   if (current_automata_list == NULL)
     return NULL;
   entry_ptr = htab_find_slot (automata_list_table,
-                             (void *) current_automata_list, 1);
+                             (void *) current_automata_list, INSERT);
   if (*entry_ptr == NULL)
     *entry_ptr = (void *) current_automata_list;
   else
@@ -4164,7 +4271,7 @@ initiate_excl_sets (void)
               el != NULL;
               el = el->next_unit_set_el)
            {
-             SET_BIT (unit_excl_set, el->unit_decl->unit_num);
+             bitmap_set_bit (unit_excl_set, el->unit_decl->unit_num);
              el->unit_decl->in_set_p = TRUE;
            }
           unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set;
@@ -4177,20 +4284,18 @@ initiate_excl_sets (void)
 static reserv_sets_t
 get_excl_set (reserv_sets_t in_set)
 {
-  int excl_char_num;
-  int chars_num;
-  int i;
+  int el;
+  unsigned int i;
   int start_unit_num;
   int unit_num;
 
-  chars_num = els_in_cycle_reserv * sizeof (set_el_t);
-  memset (excl_set, 0, chars_num);
-  for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
-    if (((unsigned char *) in_set) [excl_char_num])
-      for (i = CHAR_BIT - 1; i >= 0; i--)
-       if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
+  memset (excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
+  for (el = 0; el < els_in_cycle_reserv; el++)
+    if (in_set[el])
+      for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++)
+       if ((in_set[el] >> i) & 1)
          {
-           start_unit_num = excl_char_num * CHAR_BIT + i;
+           start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i;
            if (start_unit_num >= description->units_num)
              return excl_set;
            for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
@@ -4231,7 +4336,7 @@ form_reserv_sets_list (pattern_set_el_t pattern_list)
       curr->next_pattern_reserv = NULL;
       for (i = 0; i < el->units_num; i++)
        {
-         SET_BIT (curr->reserv, el->unit_decls [i]->unit_num);
+         bitmap_set_bit (curr->reserv, el->unit_decls [i]->unit_num);
          el->unit_decls [i]->in_set_p = TRUE;
        }
       if (prev != NULL)
@@ -4289,21 +4394,19 @@ check_presence_pattern_sets (reserv_sets_t checked_set,
                             reserv_sets_t original_set,
                             int final_p)
 {
-  int char_num;
-  int chars_num;
-  int i;
+  int el;
+  unsigned int i;
   int start_unit_num;
   int unit_num;
   int presence_p;
   pattern_reserv_t pat_reserv;
 
-  chars_num = els_in_cycle_reserv * sizeof (set_el_t);
-  for (char_num = 0; char_num < chars_num; char_num++)
-    if (((unsigned char *) original_set) [char_num])
-      for (i = CHAR_BIT - 1; i >= 0; i--)
-       if ((((unsigned char *) original_set) [char_num] >> i) & 1)
+  for (el = 0; el < els_in_cycle_reserv; el++)
+    if (original_set[el])
+      for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++)
+       if ((original_set[el] >> i) & 1)
          {
-           start_unit_num = char_num * CHAR_BIT + i;
+           start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i;
            if (start_unit_num >= description->units_num)
              break;
            if ((final_p
@@ -4338,20 +4441,18 @@ check_absence_pattern_sets (reserv_sets_t checked_set,
                            reserv_sets_t original_set,
                            int final_p)
 {
-  int char_num;
-  int chars_num;
-  int i;
+  int el;
+  unsigned int i;
   int start_unit_num;
   int unit_num;
   pattern_reserv_t pat_reserv;
 
-  chars_num = els_in_cycle_reserv * sizeof (set_el_t);
-  for (char_num = 0; char_num < chars_num; char_num++)
-    if (((unsigned char *) original_set) [char_num])
-      for (i = CHAR_BIT - 1; i >= 0; i--)
-       if ((((unsigned char *) original_set) [char_num] >> i) & 1)
+  for (el = 0; el < els_in_cycle_reserv; el++)
+    if (original_set[el])
+      for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++)
+       if ((original_set[el] >> i) & 1)
          {
-           start_unit_num = char_num * CHAR_BIT + i;
+           start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i;
            if (start_unit_num >= description->units_num)
              break;
            for (pat_reserv = (final_p
@@ -4782,7 +4883,7 @@ transform_3 (regexp_t regexp)
                  default:
                    break;
                  }
-             
+
              if (allof_length == 1)
                REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
              else
@@ -4897,12 +4998,14 @@ transform_insn_regexps (void)
 
   transform_time = create_ticker ();
   add_advance_cycle_insn_decl ();
+  if (collapse_flag)
+    add_collapse_ndfa_insn_decl ();
   if (progress_flag)
     fprintf (stderr, "Reservation transformation...");
-  for (i = 0; i < description->decls_num; i++)
+  for (i = 0; i < description->normal_decls_num; i++)
     {
       decl = description->decls [i];
-      if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
+      if (decl->mode == dm_insn_reserv)
        DECL_INSN_RESERV (decl)->transformed_regexp
          = transform_regexp (copy_insn_regexp
                              (DECL_INSN_RESERV (decl)->regexp));
@@ -4919,7 +5022,7 @@ transform_insn_regexps (void)
 static int annotation_message_reported_p;
 
 /* The vector contains all decls which are automata.  */
-static VEC(decl_t, heap) *automaton_decls;
+static vec<decl_t> automaton_decls;
 
 /* The following structure describes usage of a unit in a reservation.  */
 struct unit_usage
@@ -4933,8 +5036,6 @@ struct unit_usage
 };
 typedef struct unit_usage *unit_usage_t;
 
-DEF_VEC_P(unit_usage_t);
-DEF_VEC_ALLOC_P(unit_usage_t, heap);
 
 /* Obstack for unit_usage structures.  */
 static struct obstack unit_usages;
@@ -4945,7 +5046,7 @@ static struct obstack unit_usages;
    alternative with given number are referred through element with
    index equals to the cycle * number of all alternatives in the
    regexp + the alternative number.  */
-static VEC(unit_usage_t, heap) *cycle_alt_unit_usages;
+static vec<unit_usage_t> cycle_alt_unit_usages;
 
 /* The following function creates the structure unit_usage for UNIT on
    CYCLE in REGEXP alternative with ALT_NUM.  The structure is made
@@ -4964,12 +5065,12 @@ store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
   unit_decl = REGEXP_UNIT (unit)->unit_decl;
 
   length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
-  while (VEC_length (unit_usage_t, cycle_alt_unit_usages) < length)
-    VEC_safe_push (unit_usage_t, heap, cycle_alt_unit_usages, 0);
-  
+  while (cycle_alt_unit_usages.length () < length)
+    cycle_alt_unit_usages.safe_push (NULL);
+
   index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
   prev = NULL;
-  for (curr = VEC_index (unit_usage_t, cycle_alt_unit_usages, index);
+  for (curr = cycle_alt_unit_usages[index];
        curr != NULL;
        prev = curr, curr = curr->next)
     if (curr->unit_decl >= unit_decl)
@@ -4983,7 +5084,7 @@ store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
   unit_decl->last_distribution_check_cycle = -1; /* undefined */
   unit_usage_ptr->next = curr;
   if (prev == NULL)
-    VEC_replace (unit_usage_t, cycle_alt_unit_usages, index, unit_usage_ptr);
+    cycle_alt_unit_usages[index] = unit_usage_ptr;
   else
     prev->next = unit_usage_ptr;
 }
@@ -5012,11 +5113,11 @@ equal_alternatives_p (int alt1, int alt2, int n_alts,
   unit_usage_t list1, list2;
 
   for (i = 0;
-       i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages);
+       i < (int) cycle_alt_unit_usages.length ();
        i += n_alts)
     {
-      for (list1 = VEC_index (unit_usage_t, cycle_alt_unit_usages, i + alt1),
-            list2 = VEC_index (unit_usage_t, cycle_alt_unit_usages, i + alt2);;
+      for (list1 = cycle_alt_unit_usages[i + alt1],
+            list2 = cycle_alt_unit_usages[i + alt2];;
           list1 = list1->next, list2 = list2->next)
        {
          while (list1 != NULL
@@ -5039,8 +5140,6 @@ equal_alternatives_p (int alt1, int alt2, int n_alts,
   return true;
 }
 
-DEF_VEC_I(int);
-DEF_VEC_ALLOC_I(int, heap);
 
 /* The function processes given REGEXP to find units with the wrong
    distribution.  */
@@ -5048,17 +5147,16 @@ static void
 check_regexp_units_distribution (const char *insn_reserv_name,
                                 regexp_t regexp)
 {
-  int i, j, k, cycle, cycle2, start, n_alts, alt, alt2;
+  int i, j, k, cycle, start, n_alts, alt, alt2;
   bool annotation_reservation_message_reported_p;
   regexp_t seq, allof, unit;
   struct unit_usage *unit_usage_ptr;
-  VEC(int, heap) *marked;
 
   if (regexp == NULL || regexp->mode != rm_oneof)
     return;
   /* Store all unit usages in the regexp:  */
   obstack_init (&unit_usages);
-  cycle_alt_unit_usages = VEC_alloc (unit_usage_t, heap, 10);
+  cycle_alt_unit_usages.create (10);
 
   for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
     {
@@ -5081,14 +5179,14 @@ check_regexp_units_distribution (const char *insn_reserv_name,
                        gcc_assert (unit->mode == rm_nothing);
                    }
                  break;
-                 
+
                case rm_unit:
                  store_alt_unit_usage (regexp, allof, j, i);
                  break;
-                 
+
                case rm_nothing:
                  break;
-                 
+
                default:
                  gcc_unreachable ();
                }
@@ -5104,10 +5202,10 @@ check_regexp_units_distribution (const char *insn_reserv_name,
                case rm_unit:
                  store_alt_unit_usage (regexp, unit, 0, i);
                  break;
-                 
+
                case rm_nothing:
                  break;
-                 
+
                default:
                  gcc_unreachable ();
                }
@@ -5126,21 +5224,21 @@ check_regexp_units_distribution (const char *insn_reserv_name,
        }
     }
   /* Check distribution:  */
-  for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++)
-    for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i);
+  for (i = 0; i < (int) cycle_alt_unit_usages.length (); i++)
+    for (unit_usage_ptr = cycle_alt_unit_usages[i];
         unit_usage_ptr != NULL;
         unit_usage_ptr = unit_usage_ptr->next)
       unit_usage_ptr->unit_decl->last_distribution_check_cycle = -1;
   n_alts = REGEXP_ONEOF (regexp)->regexps_num;
-  marked = VEC_alloc (int, heap, n_alts);
+  auto_vec<int> marked (n_alts);
   for (i = 0; i < n_alts; i++)
-    VEC_safe_push (int, heap, marked, 0);
+    marked.safe_push (0);
   annotation_reservation_message_reported_p = false;
-  for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++)
+  for (i = 0; i < (int) cycle_alt_unit_usages.length (); i++)
     {
       cycle = i / n_alts;
       start = cycle * n_alts;
-      for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i);
+      for (unit_usage_ptr = cycle_alt_unit_usages[i];
           unit_usage_ptr != NULL;
           unit_usage_ptr = unit_usage_ptr->next)
        {
@@ -5148,41 +5246,35 @@ check_regexp_units_distribution (const char *insn_reserv_name,
            continue;
          unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
          for (alt = 0; alt < n_alts; alt++)
-           if (! unit_present_on_list_p (VEC_index (unit_usage_t,
-                                                    cycle_alt_unit_usages,
-                                                    start + alt),
+           if (! unit_present_on_list_p (cycle_alt_unit_usages[start + alt],
                                          unit_usage_ptr->unit_decl))
              break;
          if (alt >= n_alts)
            continue;
-         memset (VEC_address (int, marked), 0, n_alts * sizeof (int));
+         memset (marked.address (), 0, n_alts * sizeof (int));
          for (alt = 0; alt < n_alts; alt++)
            {
-             if (! unit_present_on_list_p (VEC_index (unit_usage_t,
-                                                      cycle_alt_unit_usages,
-                                                      start + alt),
+             if (! unit_present_on_list_p (cycle_alt_unit_usages[start + alt],
                                            unit_usage_ptr->unit_decl))
                continue;
              for (j = 0;
-                  j < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages);
+                  j < (int) cycle_alt_unit_usages.length ();
                   j++)
                {
-                 cycle2 = j / n_alts;
                  alt2 = j % n_alts;
                  if (! unit_present_on_list_p
-                       (VEC_index (unit_usage_t, cycle_alt_unit_usages,
-                                   start + alt2),
+                       (cycle_alt_unit_usages[start + alt2],
                         unit_usage_ptr->unit_decl)
                      && equal_alternatives_p (alt, alt2, n_alts,
                                               unit_usage_ptr
                                               ->unit_decl->automaton_decl))
                    {
-                     VEC_replace (int, marked, alt, 1);
-                     VEC_replace (int, marked, alt2, 1);
+                     marked[alt] = 1;
+                     marked[alt2] = 1;
                    }
                }
            }
-         for (alt = 0; alt < n_alts && VEC_index (int, marked, alt); alt++)
+         for (alt = 0; alt < n_alts && marked[alt]; alt++)
            ;
          if (alt < n_alts && 0)
            {
@@ -5204,8 +5296,7 @@ check_regexp_units_distribution (const char *insn_reserv_name,
            }
        }
     }
-  VEC_free (int, heap, marked);
-  VEC_free (unit_usage_t, heap, cycle_alt_unit_usages);
+  cycle_alt_unit_usages.release ();
   obstack_free (&unit_usages, NULL);
 }
 
@@ -5219,14 +5310,14 @@ check_unit_distributions_to_automata (void)
 
   if (progress_flag)
     fprintf (stderr, "Check unit distributions to automata...");
-  automaton_decls = NULL;
+  automaton_decls.create (0);
   for (i = 0; i < description->decls_num; i++)
     {
       decl = description->decls [i];
       if (decl->mode == dm_automaton)
-       VEC_safe_push (decl_t, heap, automaton_decls, decl);
+       automaton_decls.safe_push (decl);
     }
-  if (VEC_length (decl_t, automaton_decls) > 1)
+  if (automaton_decls.length () > 1)
     {
       annotation_message_reported_p = FALSE;
       for (i = 0; i < description->decls_num; i++)
@@ -5238,7 +5329,7 @@ check_unit_distributions_to_automata (void)
               DECL_INSN_RESERV (decl)->transformed_regexp);
        }
     }
-  VEC_free (decl_t, heap, automaton_decls);
+  automaton_decls.release ();
   if (progress_flag)
     fprintf (stderr, "done\n");
 }
@@ -5275,7 +5366,7 @@ process_seq_for_forming_states (regexp_t regexp, automaton_t automaton,
         set_state_reserv (state_being_formed, curr_cycle,
                           REGEXP_UNIT (regexp)->unit_decl->unit_num);
       return curr_cycle;
-      
+
     case rm_sequence:
       for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
        curr_cycle
@@ -5287,7 +5378,7 @@ process_seq_for_forming_states (regexp_t regexp, automaton_t automaton,
       {
        int finish_cycle = 0;
        int cycle;
-       
+
        for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
          {
            cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
@@ -5374,7 +5465,7 @@ create_alt_states (automaton_t automaton)
        curr_ainsn = curr_ainsn->next_ainsn)
     {
       reserv_decl = curr_ainsn->insn_reserv_decl;
-      if (reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
+      if (!special_decl_p (reserv_decl))
         {
           curr_ainsn->alt_states = NULL;
           process_alts_for_forming_states (reserv_decl->transformed_regexp,
@@ -5398,39 +5489,36 @@ form_ainsn_with_same_reservs (automaton_t automaton)
 {
   ainsn_t curr_ainsn;
   size_t i;
-  VEC(ainsn_t, heap) *last_insns = VEC_alloc (ainsn_t, heap, 150);
+  auto_vec<ainsn_t, 150> last_insns;
 
   for (curr_ainsn = automaton->ainsn_list;
        curr_ainsn != NULL;
        curr_ainsn = curr_ainsn->next_ainsn)
-    if (curr_ainsn->insn_reserv_decl
-       == DECL_INSN_RESERV (advance_cycle_insn_decl))
+    if (special_decl_p (curr_ainsn->insn_reserv_decl))
       {
         curr_ainsn->next_same_reservs_insn = NULL;
         curr_ainsn->first_insn_with_same_reservs = 1;
       }
     else
       {
-        for (i = 0; i < VEC_length (ainsn_t, last_insns); i++)
+        for (i = 0; i < last_insns.length (); i++)
           if (alt_states_eq
               (curr_ainsn->sorted_alt_states,
-               VEC_index (ainsn_t, last_insns, i)->sorted_alt_states))
+               last_insns[i]->sorted_alt_states))
             break;
         curr_ainsn->next_same_reservs_insn = NULL;
-        if (i < VEC_length (ainsn_t, last_insns))
+        if (i < last_insns.length ())
           {
             curr_ainsn->first_insn_with_same_reservs = 0;
-           VEC_index (ainsn_t, last_insns, i)->next_same_reservs_insn
-             = curr_ainsn;
-            VEC_replace (ainsn_t, last_insns, i, curr_ainsn);
+           last_insns[i]->next_same_reservs_insn = curr_ainsn;
+            last_insns[i] = curr_ainsn;
           }
         else
           {
-            VEC_safe_push (ainsn_t, heap, last_insns, curr_ainsn);
+            last_insns.safe_push (curr_ainsn);
             curr_ainsn->first_insn_with_same_reservs = 1;
           }
       }
-  VEC_free (ainsn_t, heap, last_insns);
 }
 
 /* Forming unit reservations which can affect creating the automaton
@@ -5444,16 +5532,16 @@ static reserv_sets_t
 form_reservs_matter (automaton_t automaton)
 {
   int cycle, unit;
-  reserv_sets_t reservs_matter = alloc_empty_reserv_sets();
+  reserv_sets_t reservs_matter = alloc_empty_reserv_sets ();
 
   for (cycle = 0; cycle < max_cycles_num; cycle++)
     for (unit = 0; unit < description->units_num; unit++)
       if (units_array [unit]->automaton_decl
          == automaton->corresponding_automaton_decl
          && (cycle >= units_array [unit]->min_occ_cycle_num
-             /* We can not remove queried unit from reservations.  */
+             /* We cannot remove queried unit from reservations.  */
              || units_array [unit]->query_p
-             /* We can not remove units which are used
+             /* We cannot remove units which are used
                 `exclusion_set', `presence_set',
                 `final_presence_set', `absence_set', and
                 `final_absence_set'.  */
@@ -5472,9 +5560,7 @@ make_automaton (automaton_t automaton)
   state_t state;
   state_t start_state;
   state_t state2;
-  ainsn_t advance_cycle_ainsn;
-  arc_t added_arc;
-  VEC(state_t, heap) *state_stack = VEC_alloc(state_t, heap, 150);
+  auto_vec<state_t, 150> state_stack;
   int states_n;
   reserv_sets_t reservs_matter = form_reservs_matter (automaton);
 
@@ -5482,23 +5568,21 @@ make_automaton (automaton_t automaton)
   start_state = insert_state (get_free_state (1, automaton));
   automaton->start_state = start_state;
   start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
-  VEC_safe_push (state_t, heap, state_stack, start_state);
+  state_stack.safe_push (start_state);
   states_n = 1;
-  while (VEC_length (state_t, state_stack) != 0)
+  while (state_stack.length () != 0)
     {
-      state = VEC_pop (state_t, state_stack);
-      advance_cycle_ainsn = NULL;
+      state = state_stack.pop ();
       for (ainsn = automaton->ainsn_list;
           ainsn != NULL;
           ainsn = ainsn->next_ainsn)
         if (ainsn->first_insn_with_same_reservs)
           {
             insn_reserv_decl = ainsn->insn_reserv_decl;
-            if (insn_reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
+            if (!special_decl_p (insn_reserv_decl))
               {
                /* We process alt_states in the same order as they are
                    present in the description.  */
-               added_arc = NULL;
                 for (alt_state = ainsn->alt_states;
                      alt_state != NULL;
                      alt_state = alt_state->next_alt_state)
@@ -5511,41 +5595,30 @@ make_automaton (automaton_t automaton)
                           {
                             state2->it_was_placed_in_stack_for_NDFA_forming
                              = 1;
-                            VEC_safe_push (state_t, heap, state_stack, state2);
+                            state_stack.safe_push (state2);
                            states_n++;
                            if (progress_flag && states_n % 100 == 0)
                              fprintf (stderr, ".");
                           }
-                       added_arc = add_arc (state, state2, ainsn);
+                       add_arc (state, state2, ainsn);
                        if (!ndfa_flag)
                          break;
                       }
                   }
-               if (!ndfa_flag && added_arc != NULL)
-                 {
-                   for (alt_state = ainsn->alt_states;
-                        alt_state != NULL;
-                        alt_state = alt_state->next_alt_state)
-                     state2 = alt_state->state;
-                 }
               }
-            else
-              advance_cycle_ainsn = ainsn;
           }
       /* Add transition to advance cycle.  */
       state2 = state_shift (state, reservs_matter);
       if (!state2->it_was_placed_in_stack_for_NDFA_forming)
         {
           state2->it_was_placed_in_stack_for_NDFA_forming = 1;
-          VEC_safe_push (state_t, heap, state_stack, state2);
+          state_stack.safe_push (state2);
          states_n++;
          if (progress_flag && states_n % 100 == 0)
            fprintf (stderr, ".");
         }
-      gcc_assert (advance_cycle_ainsn);
-      add_arc (state, state2, advance_cycle_ainsn);
+      add_arc (state, state2, automaton->advance_ainsn);
     }
-  VEC_free (state_t, heap, state_stack);
 }
 
 /* Form lists of all arcs of STATE marked by the same ainsn.  */
@@ -5578,7 +5651,7 @@ form_arcs_marked_by_insn (state_t state)
 
 static int
 create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
-                      VEC(state_t, heap) **state_stack)
+                      vec<state_t> *state_stack)
 {
   state_t state;
   alt_state_t alt_state, curr_alt_state;
@@ -5651,7 +5724,13 @@ 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);
+                 if (!collapse_flag
+                     /* When producing collapse-NDFA transitions, we
+                        only add advance-cycle transitions to the
+                        collapsed states.  */
+                     || (curr_arc->insn->insn_reserv_decl
+                         != DECL_INSN_RESERV (advance_cycle_insn_decl)))
+                   add_arc (state, curr_arc->to_state, curr_arc->insn);
             }
           arcs_marked_by_insn->to_state = state;
           for (alts_number = 0,
@@ -5668,7 +5747,7 @@ create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
   if (!state->it_was_placed_in_stack_for_DFA_forming)
     {
       state->it_was_placed_in_stack_for_DFA_forming = 1;
-      VEC_safe_push (state_t, heap, *state_stack, state);
+      state_stack->safe_push (state);
     }
   return new_state_p;
 }
@@ -5682,25 +5761,24 @@ NDFA_to_DFA (automaton_t automaton)
   state_t start_state;
   state_t state;
   decl_t decl;
-  VEC(state_t, heap) *state_stack;
+  auto_vec<state_t> state_stack;
   int i;
   int states_n;
 
-  state_stack = VEC_alloc (state_t, heap, 0);
-
   /* Create the start state (empty state).  */
   start_state = automaton->start_state;
   start_state->it_was_placed_in_stack_for_DFA_forming = 1;
-  VEC_safe_push (state_t, heap, state_stack, start_state);
+  state_stack.safe_push (start_state);
   states_n = 1;
-  while (VEC_length (state_t, state_stack) != 0)
+  while (state_stack.length () != 0)
     {
-      state = VEC_pop (state_t, state_stack);
+      state = state_stack.pop ();
       form_arcs_marked_by_insn (state);
       for (i = 0; i < description->decls_num; i++)
        {
          decl = description->decls [i];
          if (decl->mode == dm_insn_reserv
+             && decl != collapse_ndfa_insn_decl
              && create_composed_state
                 (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
                  &state_stack))
@@ -5710,8 +5788,23 @@ NDFA_to_DFA (automaton_t automaton)
                fprintf (stderr, ".");
            }
        }
+      /* Add a transition to collapse the NDFA.  */
+      if (collapse_flag)
+       {
+         if (state->component_states != NULL)
+           {
+             state_t state2 = state->component_states->state;
+             if (!state2->it_was_placed_in_stack_for_DFA_forming)
+               {
+                 state2->it_was_placed_in_stack_for_DFA_forming = 1;
+                 state_stack.safe_push (state2);
+               }
+             add_arc (state, state2, automaton->collapse_ainsn);
+           }
+         else
+           add_arc (state, state, automaton->collapse_ainsn);
+       }
     }
-  VEC_free (state_t, heap, state_stack);
 }
 
 /* The following variable value is current number (1, 2, ...) of passing
@@ -5753,20 +5846,19 @@ initiate_pass_states (void)
 
 /* The following vla is used for storing pointers to all achieved
    states.  */
-static VEC(state_t, heap) *all_achieved_states;
+static vec<state_t> all_achieved_states;
 
 /* This function is called by function pass_states to add an achieved
    STATE.  */
 static void
 add_achieved_state (state_t state)
 {
-  VEC_safe_push (state_t, heap, all_achieved_states, state);
+  all_achieved_states.safe_push (state);
 }
 
 /* The function sets up equivalence numbers of insns which mark all
    out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
-   nonzero value) or by equiv_class_num_2 of the destination state.
-   The function returns number of out arcs of STATE.  */
+   nonzero value) or by equiv_class_num_2 of the destination state.  */
 static void
 set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
 {
@@ -5823,7 +5915,7 @@ cache_presence (state_t state)
   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)
@@ -5896,24 +5988,24 @@ compare_states_for_equiv (const void *state_ptr_1,
 }
 
 /* The function makes initial partition of STATES on equivalent
-   classes and saves it into *CLASSES.  This function requires the input
+   classes and saves it into CLASSES.  This function requires the input
    to be sorted via compare_states_for_equiv().  */
 static int
-init_equiv_class (VEC(state_t, heap) *states, VEC (state_t, heap) **classes)
+init_equiv_class (vec<state_t> states, vec<state_t> *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++)
+  classes->create (150);
+  for (i = 0; i < states.length (); i++)
     {
-      state_t state = VEC_index (state_t, states, i);
+      state_t state = states[i];
       if (prev)
         {
          if (compare_states_for_equiv (&prev, &state) != 0)
            {
-             VEC_safe_push (state_t, heap, *classes, prev);
+             classes->safe_push (prev);
              class_num++;
              prev = NULL;
            }
@@ -5923,17 +6015,17 @@ init_equiv_class (VEC(state_t, heap) *states, VEC (state_t, heap) **classes)
       prev = state;
     }
   if (prev)
-    VEC_safe_push (state_t, heap, *classes, prev);
+    classes->safe_push (prev);
   return class_num;
 }
 
 /* The function copies pointers to equivalent states from vla FROM
    into vla TO.  */
 static void
-copy_equiv_class (VEC(state_t, heap) **to, VEC(state_t, heap) *from)
+copy_equiv_class (vec<state_t> *to, vec<state_t> from)
 {
-  VEC_free (state_t, heap, *to);
-  *to = VEC_copy (state_t, heap, from);
+  to->release ();
+  *to = from.copy ();
 }
 
 /* The function processes equivalence class given by its first state,
@@ -5945,7 +6037,7 @@ copy_equiv_class (VEC(state_t, heap) **to, VEC(state_t, heap) *from)
    partitioned, the function returns nonzero value.  */
 static int
 partition_equiv_class (state_t first_state, int odd_iteration_flag,
-                      VEC(state_t, heap) **next_iteration_classes,
+                      vec<state_t> *next_iteration_classes,
                       int *new_equiv_class_num_ptr)
 {
   state_t new_equiv_class;
@@ -5969,7 +6061,7 @@ partition_equiv_class (state_t first_state, int odd_iteration_flag,
               curr_state = next_state)
            {
              next_state = curr_state->next_equiv_class_state;
-             if (state_is_differed (curr_state, first_state, 
+             if (state_is_differed (curr_state, first_state,
                                     odd_iteration_flag))
                {
                  /* Remove curr state from the class equivalence.  */
@@ -5991,7 +6083,7 @@ partition_equiv_class (state_t first_state, int odd_iteration_flag,
          clear_arc_insns_equiv_num (first_state);
        }
       if (new_equiv_class != NULL)
-       VEC_safe_push (state_t, heap, *next_iteration_classes, new_equiv_class);
+       next_iteration_classes->safe_push (new_equiv_class);
       first_state = new_equiv_class;
     }
   return partition_p;
@@ -5999,21 +6091,18 @@ partition_equiv_class (state_t first_state, int odd_iteration_flag,
 
 /* The function finds equivalent states of AUTOMATON.  */
 static void
-evaluate_equiv_classes (automaton_t automaton,
-                       VEC(state_t, heap) **equiv_classes)
+evaluate_equiv_classes (automaton_t automaton, vec<state_t> *equiv_classes)
 {
   int new_equiv_class_num;
   int odd_iteration_flag;
   int finish_flag;
-  VEC (state_t, heap) *next_iteration_classes;
+  vec<state_t> next_iteration_classes;
   size_t i;
 
-  all_achieved_states = VEC_alloc (state_t, heap, 1500);
+  all_achieved_states.create (1500);
   pass_states (automaton, add_achieved_state);
   pass_states (automaton, cache_presence);
-  qsort (VEC_address (state_t, all_achieved_states),
-        VEC_length (state_t, all_achieved_states),
-         sizeof (state_t), compare_states_for_equiv);
+  all_achieved_states.qsort (compare_states_for_equiv);
 
   odd_iteration_flag = 0;
   new_equiv_class_num = init_equiv_class (all_achieved_states,
@@ -6026,29 +6115,29 @@ evaluate_equiv_classes (automaton_t automaton,
       copy_equiv_class (equiv_classes, next_iteration_classes);
 
       /* Transfer equiv numbers for the next iteration.  */
-      for (i = 0; i < VEC_length (state_t, all_achieved_states); i++)
+      for (i = 0; i < all_achieved_states.length (); i++)
        if (odd_iteration_flag)
-         VEC_index (state_t, all_achieved_states, i)->equiv_class_num_2
-           = VEC_index (state_t, all_achieved_states, i)->equiv_class_num_1;
+         all_achieved_states[i]->equiv_class_num_2
+           = all_achieved_states[i]->equiv_class_num_1;
        else
-         VEC_index (state_t, all_achieved_states, i)->equiv_class_num_1
-           = VEC_index (state_t, all_achieved_states, i)->equiv_class_num_2;
+         all_achieved_states[i]->equiv_class_num_1
+           = all_achieved_states[i]->equiv_class_num_2;
 
-      for (i = 0; i < VEC_length (state_t, *equiv_classes); i++)
-       if (partition_equiv_class (VEC_index (state_t, *equiv_classes, i),
+      for (i = 0; i < equiv_classes->length (); i++)
+       if (partition_equiv_class ((*equiv_classes)[i],
                                   odd_iteration_flag,
                                   &next_iteration_classes,
                                   &new_equiv_class_num))
          finish_flag = 0;
     }
   while (!finish_flag);
-  VEC_free (state_t, heap, next_iteration_classes);
-  VEC_free (state_t, heap, all_achieved_states);
+  next_iteration_classes.release ();
+  all_achieved_states.release ();
 }
 
 /* The function merges equivalent states of AUTOMATON.  */
 static void
-merge_states (automaton_t automaton, VEC(state_t, heap) *equiv_classes)
+merge_states (automaton_t automaton, vec<state_t> equiv_classes)
 {
   state_t curr_state;
   state_t new_state;
@@ -6061,9 +6150,9 @@ merge_states (automaton_t automaton, VEC(state_t, heap) *equiv_classes)
 
   /* Create states corresponding to equivalence classes containing two
      or more states.  */
-  for (i = 0; i < VEC_length (state_t, equiv_classes); i++)
+  for (i = 0; i < equiv_classes.length (); i++)
     {
-      curr_state = VEC_index (state_t, equiv_classes, i);
+      curr_state = equiv_classes[i];
       if (curr_state->next_equiv_class_state != NULL)
        {
          /* There are more one states in the class equivalence.  */
@@ -6094,7 +6183,7 @@ merge_states (automaton_t automaton, VEC(state_t, heap) *equiv_classes)
                    alt_states = new_alt_state;
                  }
            }
-         /* Its is important that alt states were sorted before and
+         /* It is important that alt states were sorted before and
             after merging to have the same querying results.  */
          new_state->component_states = uniq_sort_alt_states (alt_states);
        }
@@ -6102,9 +6191,9 @@ merge_states (automaton_t automaton, VEC(state_t, heap) *equiv_classes)
        curr_state->equiv_class_state = curr_state;
     }
 
-  for (i = 0; i < VEC_length (state_t, equiv_classes); i++)
+  for (i = 0; i < equiv_classes.length (); i++)
     {
-      curr_state = VEC_index (state_t, equiv_classes, i);
+      curr_state = equiv_classes[i];
       if (curr_state->next_equiv_class_state != NULL)
        {
          first_class_state = curr_state;
@@ -6163,13 +6252,11 @@ set_new_cycle_flags (state_t state)
 static void
 minimize_DFA (automaton_t automaton)
 {
-  VEC(state_t, heap) *equiv_classes = 0;
+  auto_vec<state_t> equiv_classes;
 
   evaluate_equiv_classes (automaton, &equiv_classes);
   merge_states (automaton, equiv_classes);
   pass_states (automaton, set_new_cycle_flags);
-
-  VEC_free (state_t, heap, equiv_classes);
 }
 
 /* Values of two variables are counted number of states and arcs in an
@@ -6536,8 +6623,8 @@ units_to_automata_heuristic_distr (void)
 /* The functions creates automaton insns for each automata.  Automaton
    insn is simply insn for given automaton which makes reservation
    only of units of the automaton.  */
-static ainsn_t
-create_ainsns (void)
+static void
+create_ainsns (automaton_t automaton)
 {
   decl_t decl;
   ainsn_t first_ainsn;
@@ -6560,10 +6647,14 @@ create_ainsns (void)
            first_ainsn = curr_ainsn;
          else
            prev_ainsn->next_ainsn = curr_ainsn;
+         if (decl == advance_cycle_insn_decl)
+           automaton->advance_ainsn = curr_ainsn;
+         else if (decl == collapse_ndfa_insn_decl)
+           automaton->collapse_ainsn = curr_ainsn;
          prev_ainsn = curr_ainsn;
        }
     }
-  return first_ainsn;
+  automaton->ainsn_list = first_ainsn;
 }
 
 /* The function assigns automata to units according to constructions
@@ -6611,7 +6702,7 @@ create_automata (void)
            curr_automaton_num++, prev_automaton = curr_automaton)
         {
          curr_automaton = XCREATENODE (struct automaton);
-         curr_automaton->ainsn_list = create_ainsns ();
+         create_ainsns (curr_automaton);
          curr_automaton->corresponding_automaton_decl = NULL;
          curr_automaton->next_automaton = NULL;
           curr_automaton->automaton_order_num = curr_automaton_num;
@@ -6632,7 +6723,7 @@ create_automata (void)
              && DECL_AUTOMATON (decl)->automaton_is_used)
            {
              curr_automaton = XCREATENODE (struct automaton);
-             curr_automaton->ainsn_list = create_ainsns ();
+             create_ainsns (curr_automaton);
              curr_automaton->corresponding_automaton_decl
                = DECL_AUTOMATON (decl);
              curr_automaton->next_automaton = NULL;
@@ -6649,7 +6740,7 @@ create_automata (void)
       if (curr_automaton_num == 0)
        {
          curr_automaton = XCREATENODE (struct automaton);
-         curr_automaton->ainsn_list = create_ainsns ();
+         create_ainsns (curr_automaton);
          curr_automaton->corresponding_automaton_decl = NULL;
          curr_automaton->next_automaton = NULL;
          description->first_automaton = curr_automaton;
@@ -6709,11 +6800,11 @@ form_regexp (regexp_t regexp)
        const char *name = (regexp->mode == rm_unit
                            ? REGEXP_UNIT (regexp)->name
                            : REGEXP_RESERV (regexp)->name);
-       
+
        obstack_grow (&irp, name, strlen (name));
        break;
       }
-      
+
     case rm_sequence:
       for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
        {
@@ -6739,7 +6830,7 @@ form_regexp (regexp_t regexp)
         }
       obstack_1grow (&irp, ')');
       break;
-      
+
     case rm_oneof:
       for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
        {
@@ -6752,11 +6843,11 @@ form_regexp (regexp_t regexp)
           obstack_1grow (&irp, ')');
        }
       break;
-      
+
     case rm_repeat:
       {
        char digits [30];
-       
+
        if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
            || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
            || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
@@ -6787,7 +6878,7 @@ regexp_representation (regexp_t regexp)
 {
   form_regexp (regexp);
   obstack_1grow (&irp, '\0');
-  return obstack_base (&irp);
+  return (char *) obstack_base (&irp);
 }
 
 /* The function frees memory allocated for last formed string
@@ -6832,7 +6923,7 @@ static void
 output_vect (vla_hwint_t vect)
 {
   int els_on_line;
-  size_t vect_length = VEC_length (vect_el_t, vect);
+  size_t vect_length = vect.length ();
   size_t i;
 
   els_on_line = 1;
@@ -6841,7 +6932,7 @@ output_vect (vla_hwint_t vect)
   else
     for (i = 0; i < vect_length; i++)
       {
-       fprintf (output_file, "%5ld", (long) VEC_index (vect_el_t, vect, i));
+       fprintf (output_file, "%5ld", (long) vect[i]);
        if (els_on_line == 10)
          {
            els_on_line = 0;
@@ -6878,10 +6969,11 @@ output_temp_chip_member_name (FILE *f, automaton_t automaton)
   output_chip_member_name (f, automaton);
 }
 
-/* This is name of macro value which is code of pseudo_insn
-   representing advancing cpu cycle.  Its value is used as internal
-   code unknown insn.  */
+/* This is name of macro value which is code of pseudo_insns
+   representing advancing cpu cycle and collapsing the NDFA.
+   Its value is used as internal code unknown insn.  */
 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
+#define COLLAPSE_NDFA_VALUE_NAME "NDFA__COLLAPSE"
 
 /* Output name of translate vector for given automaton.  */
 static void
@@ -7104,17 +7196,15 @@ output_translate_vect (automaton_t automaton)
   int insn_value;
   vla_hwint_t translate_vect;
 
-  translate_vect = VEC_alloc (vect_el_t, heap, description->insns_num);
+  translate_vect.create (description->insns_num);
 
   for (insn_value = 0; insn_value < description->insns_num; insn_value++)
     /* Undefined value */
-    VEC_quick_push (vect_el_t, translate_vect,
-                   automaton->insn_equiv_classes_num);
+    translate_vect.quick_push (automaton->insn_equiv_classes_num);
 
   for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
-    VEC_replace (vect_el_t, translate_vect,
-                ainsn->insn_reserv_decl->insn_num,
-                ainsn->insn_equiv_class_num);
+    translate_vect[ainsn->insn_reserv_decl->insn_num] =
+         ainsn->insn_equiv_class_num;
 
   fprintf (output_file,
            "/* Vector translating external insn codes to internal ones.*/\n");
@@ -7125,7 +7215,7 @@ output_translate_vect (automaton_t automaton)
   fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
   output_vect (translate_vect);
   fprintf (output_file, "};\n\n");
-  VEC_free (vect_el_t, heap, translate_vect);
+  translate_vect.release ();
 }
 
 /* The value in a table state x ainsn -> something which represents
@@ -7137,8 +7227,9 @@ static int undefined_vect_el_value;
 static int
 comb_vect_p (state_ainsn_table_t tab)
 {
-  return  (2 * VEC_length (vect_el_t, tab->full_vect)
-           > 5 * VEC_length (vect_el_t, tab->comb_vect));
+  if (no_comb_flag)
+    return false;
+  return  (2 * tab->full_vect.length () > 5 * tab->comb_vect.length ());
 }
 
 /* The following function creates new table for AUTOMATON.  */
@@ -7152,18 +7243,17 @@ create_state_ainsn_table (automaton_t automaton)
   tab = XCREATENODE (struct state_ainsn_table);
   tab->automaton = automaton;
 
-  tab->comb_vect  = VEC_alloc (vect_el_t, heap, 10000);
-  tab->check_vect = VEC_alloc (vect_el_t, heap, 10000);
+  tab->comb_vect.create (10000);
+  tab->check_vect.create (10000);
 
-  tab->base_vect  = 0;
-  VEC_safe_grow (vect_el_t, heap, tab->base_vect,
-                automaton->achieved_states_num);
+  tab->base_vect.create (0);
+  tab->base_vect.safe_grow (automaton->achieved_states_num);
 
   full_vect_length = (automaton->insn_equiv_classes_num
                       * automaton->achieved_states_num);
-  tab->full_vect  = VEC_alloc (vect_el_t, heap, full_vect_length);
+  tab->full_vect.create (full_vect_length);
   for (i = 0; i < full_vect_length; i++)
-    VEC_quick_push (vect_el_t, tab->full_vect, undefined_vect_el_value);
+    tab->full_vect.quick_push (undefined_vect_el_value);
 
   tab->min_base_vect_el_value = 0;
   tab->max_base_vect_el_value = 0;
@@ -7241,29 +7331,42 @@ add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
   int i;
   unsigned long vect_mask, comb_vect_mask;
 
-  vect_length = VEC_length (vect_el_t, vect);
+  vect_length = vect.length ();
   gcc_assert (vect_length);
-  gcc_assert (VEC_last (vect_el_t, vect) != undefined_vect_el_value);
+  gcc_assert (vect.last () != undefined_vect_el_value);
   real_vect_length = tab->automaton->insn_equiv_classes_num;
   /* Form full vector in the table: */
   {
     size_t full_base = tab->automaton->insn_equiv_classes_num * vect_num;
-    if (VEC_length (vect_el_t, tab->full_vect) < full_base + vect_length)
-      VEC_safe_grow (vect_el_t, heap, tab->full_vect,
-                    full_base + vect_length);
+    if (tab->full_vect.length () < full_base + vect_length)
+      tab->full_vect.safe_grow (full_base + vect_length);
     for (i = 0; i < vect_length; i++)
-      VEC_replace (vect_el_t, tab->full_vect, full_base + i,
-                  VEC_index (vect_el_t, vect, i));
+      tab->full_vect[full_base + i] = vect[i];
   }
+
+  /* The comb_vect min/max values are also used for the full vector, so
+     compute them now.  */
+  for (vect_index = 0; vect_index < vect_length; vect_index++)
+    if (vect[vect_index] != undefined_vect_el_value)
+      {
+       vect_el_t x = vect[vect_index];
+        gcc_assert (x >= 0);
+        if (tab->max_comb_vect_el_value < x)
+          tab->max_comb_vect_el_value = x;
+        if (tab->min_comb_vect_el_value > x)
+          tab->min_comb_vect_el_value = x;
+      }
+  if (no_comb_flag)
+    return;
+
   /* Form comb vector in the table: */
-  gcc_assert (VEC_length (vect_el_t, tab->comb_vect)
-             == VEC_length (vect_el_t, tab->check_vect));
+  gcc_assert (tab->comb_vect.length () == tab->check_vect.length ());
 
-  comb_vect_els_num = VEC_length (vect_el_t, tab->comb_vect);
+  comb_vect_els_num = tab->comb_vect.length ();
   for (first_unempty_vect_index = 0;
        first_unempty_vect_index < vect_length;
        first_unempty_vect_index++)
-    if (VEC_index (vect_el_t, vect, first_unempty_vect_index)
+    if (vect[first_unempty_vect_index]
        != undefined_vect_el_value)
       break;
 
@@ -7280,10 +7383,9 @@ add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
                vect_index < vect_length
                && vect_index + comb_vect_index < comb_vect_els_num;
                vect_index++)
-            if (VEC_index (vect_el_t, vect, vect_index)
+            if (vect[vect_index]
                != undefined_vect_el_value
-                && (VEC_index (vect_el_t, tab->comb_vect,
-                              vect_index + comb_vect_index)
+                && (tab->comb_vect[vect_index + comb_vect_index]
                    != undefined_vect_el_value))
               break;
           if (vect_index >= vect_length
@@ -7300,7 +7402,7 @@ add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
        vect_index++)
     {
       vect_mask = vect_mask << 1;
-      if (VEC_index (vect_el_t, vect, vect_index) != undefined_vect_el_value)
+      if (vect[vect_index] != undefined_vect_el_value)
        vect_mask |= 1;
     }
 
@@ -7316,7 +7418,7 @@ add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
     {
       comb_vect_mask <<= 1;
       if (vect_index + comb_vect_index < comb_vect_els_num
-         && VEC_index (vect_el_t, tab->comb_vect, vect_index + comb_vect_index)
+         && tab->comb_vect[vect_index + comb_vect_index]
             != undefined_vect_el_value)
        comb_vect_mask |= 1;
     }
@@ -7327,7 +7429,7 @@ add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
        comb_vect_index++, i++)
     {
       comb_vect_mask = (comb_vect_mask << 1) | 1;
-      comb_vect_mask ^= (VEC_index (vect_el_t, tab->comb_vect, i)
+      comb_vect_mask ^= (tab->comb_vect[i]
                         == undefined_vect_el_value);
       if ((vect_mask & comb_vect_mask) == 0)
        goto found;
@@ -7349,29 +7451,22 @@ add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
   no_state_value = tab->automaton->achieved_states_num;
   while (additional_els_num > 0)
     {
-      VEC_safe_push (vect_el_t, heap, tab->comb_vect, vect_el);
-      VEC_safe_push (vect_el_t, heap, tab->check_vect, no_state_value);
+      tab->comb_vect.safe_push (vect_el);
+      tab->check_vect.safe_push (no_state_value);
       additional_els_num--;
     }
-  gcc_assert (VEC_length (vect_el_t, tab->comb_vect)
+  gcc_assert (tab->comb_vect.length ()
              >= comb_vect_index + real_vect_length);
   /* Fill comb and check vectors.  */
   for (vect_index = 0; vect_index < vect_length; vect_index++)
-    if (VEC_index (vect_el_t, vect, vect_index) != undefined_vect_el_value)
+    if (vect[vect_index] != undefined_vect_el_value)
       {
-       vect_el_t x = VEC_index (vect_el_t, vect, vect_index);
-        gcc_assert (VEC_index (vect_el_t, tab->comb_vect,
-                              comb_vect_index + vect_index)
+       vect_el_t x = vect[vect_index];
+        gcc_assert (tab->comb_vect[comb_vect_index + vect_index]
                    == undefined_vect_el_value);
         gcc_assert (x >= 0);
-        if (tab->max_comb_vect_el_value < x)
-          tab->max_comb_vect_el_value = x;
-        if (tab->min_comb_vect_el_value > x)
-          tab->min_comb_vect_el_value = x;
-       VEC_replace (vect_el_t, tab->comb_vect,
-                    comb_vect_index + vect_index, x);
-       VEC_replace (vect_el_t, tab->check_vect,
-                    comb_vect_index + vect_index, vect_num);
+       tab->comb_vect[comb_vect_index + vect_index] = x;
+       tab->check_vect[comb_vect_index + vect_index] = vect_num;
       }
   if (tab->max_comb_vect_el_value < undefined_vect_el_value)
     tab->max_comb_vect_el_value = undefined_vect_el_value;
@@ -7382,7 +7477,7 @@ add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
   if (tab->min_base_vect_el_value > comb_vect_index)
     tab->min_base_vect_el_value = comb_vect_index;
 
-  VEC_replace (vect_el_t, tab->base_vect, vect_num, comb_vect_index);
+  tab->base_vect[vect_num] = comb_vect_index;
 }
 
 /* Return number of out arcs of STATE.  */
@@ -7423,29 +7518,29 @@ compare_transition_els_num (const void *state_ptr_1,
 /* The function adds element EL_VALUE to vector VECT for a table state
    x AINSN.  */
 static void
-add_vect_el (vla_hwint_t *vect, ainsn_t ainsn, int el_value)
+add_vect_el (vla_hwint_t &vect, ainsn_t ainsn, int el_value)
 {
   int equiv_class_num;
   int vect_index;
 
   gcc_assert (ainsn);
   equiv_class_num = ainsn->insn_equiv_class_num;
-  for (vect_index = VEC_length (vect_el_t, *vect);
+  for (vect_index = vect.length ();
        vect_index <= equiv_class_num;
        vect_index++)
-    VEC_safe_push (vect_el_t, heap, *vect, undefined_vect_el_value);
-  VEC_replace (vect_el_t, *vect, equiv_class_num, el_value);
+    vect.safe_push (undefined_vect_el_value);
+  vect[equiv_class_num] = el_value;
 }
 
 /* This is for forming vector of states of an automaton.  */
-static VEC(state_t, heap) *output_states_vect;
+static vec<state_t> output_states_vect;
 
 /* The function is called by function pass_states.  The function adds
    STATE to `output_states_vect'.  */
 static void
 add_states_vect_el (state_t state)
 {
-  VEC_safe_push (state_t, heap, output_states_vect, state);
+  output_states_vect.safe_push (state);
 }
 
 /* Form and output vectors (comb, check, base or full vector)
@@ -7455,32 +7550,30 @@ output_trans_table (automaton_t automaton)
 {
   size_t i;
   arc_t arc;
-  vla_hwint_t transition_vect = 0;
+  vla_hwint_t transition_vect = vla_hwint_t ();
 
   undefined_vect_el_value = automaton->achieved_states_num;
   automaton->trans_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;
+  output_states_vect.create (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);
+  output_states_vect.qsort (compare_transition_els_num);
 
-  for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
+  for (i = 0; i < output_states_vect.length (); i++)
     {
-      VEC_truncate (vect_el_t, transition_vect, 0);
-      for (arc = first_out_arc (VEC_index (state_t, output_states_vect, i));
+      transition_vect.truncate (0);
+      for (arc = first_out_arc (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 (&transition_vect, arc->insn,
+            add_vect_el (transition_vect, arc->insn,
                          arc->to_state->order_state_num);
         }
       add_vect (automaton->trans_table,
-               VEC_index (state_t, output_states_vect, i)->order_state_num,
+               output_states_vect[i]->order_state_num,
                transition_vect);
     }
   output_state_ainsn_table
@@ -7488,74 +7581,8 @@ output_trans_table (automaton_t automaton)
      output_trans_full_vect_name, output_trans_comb_vect_name,
      output_trans_check_vect_name, output_trans_base_vect_name);
 
-  VEC_free (state_t, heap, output_states_vect);
-  VEC_free (vect_el_t, heap, transition_vect);
-}
-
-/* The current number of passing states to find minimal issue delay
-   value for an ainsn and state.  */
-static int curr_state_pass_num;
-
-/* This recursive function passes states to find minimal issue delay
-   value for AINSN.  The state being visited is STATE.  The function
-   returns minimal issue delay value for AINSN in STATE or -1 if we
-   enter into a loop.  */
-static int
-min_issue_delay_pass_states (state_t state, ainsn_t ainsn)
-{
-  arc_t arc;
-  int min_insn_issue_delay, insn_issue_delay;
-
-  if (state->state_pass_num == curr_state_pass_num
-      || state->min_insn_issue_delay != -1)
-    /* We've entered into a loop or already have the correct value for
-       given state and ainsn.  */
-    return state->min_insn_issue_delay;
-  state->state_pass_num = curr_state_pass_num;
-  min_insn_issue_delay = -1;
-  for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
-    if (arc->insn == ainsn)
-      {
-       min_insn_issue_delay = 0;
-       break;
-      }
-    else
-      {
-        insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
-       if (insn_issue_delay != -1)
-         {
-           if (arc->insn->insn_reserv_decl
-               == DECL_INSN_RESERV (advance_cycle_insn_decl))
-             insn_issue_delay++;
-           if (min_insn_issue_delay == -1
-               || min_insn_issue_delay > insn_issue_delay)
-             {
-               min_insn_issue_delay = insn_issue_delay;
-               if (insn_issue_delay == 0)
-                 break;
-             }
-         }
-      }
-  return min_insn_issue_delay;
-}
-
-/* The function searches minimal issue delay value for AINSN in STATE.
-   The function can return negative value if we can not issue AINSN.  We
-   will report about it later.  */
-static int
-min_issue_delay (state_t state, ainsn_t ainsn)
-{
-  curr_state_pass_num++;
-  state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
-  return state->min_insn_issue_delay;
-}
-
-/* The function initiates code for finding minimal issue delay values.
-   It should be called only once.  */
-static void
-initiate_min_issue_delay_pass_states (void)
-{
-  curr_state_pass_num = 0;
+  output_states_vect.release ();
+  transition_vect.release ();
 }
 
 /* Form and output vectors representing minimal issue delay table of
@@ -7566,42 +7593,101 @@ output_min_issue_delay_table (automaton_t automaton)
 {
   vla_hwint_t min_issue_delay_vect;
   vla_hwint_t compressed_min_issue_delay_vect;
-  vect_el_t min_delay;
   ainsn_t ainsn;
-  size_t i, min_issue_delay_len;
-  size_t compressed_min_issue_delay_len;
+  size_t i;
+  size_t min_issue_delay_len, compressed_min_issue_delay_len;
   size_t cfactor;
+  int changed;
 
   /* Create vect of pointers to states ordered by num of transitions
      from the state (state with the maximum num is the first).  */
-  output_states_vect = 0;
+  output_states_vect.create (0);
   pass_states (automaton, add_states_vect_el);
 
-  min_issue_delay_len = (VEC_length (state_t, output_states_vect)
+  min_issue_delay_len = (output_states_vect.length ()
                         * automaton->insn_equiv_classes_num);
-  min_issue_delay_vect = VEC_alloc (vect_el_t, heap, min_issue_delay_len);
+  min_issue_delay_vect.create (min_issue_delay_len);
   for (i = 0; i < min_issue_delay_len; i++)
-    VEC_quick_push (vect_el_t, min_issue_delay_vect, 0);
+    min_issue_delay_vect.quick_push (-1);
 
   automaton->max_min_delay = 0;
-  for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
+
+  do
+    {
+      size_t state_no;
+
+      changed = 0;
+
+      for (state_no = 0; state_no < output_states_vect.length ();
+           state_no++)
+       {
+         state_t s = output_states_vect[state_no];
+         arc_t arc;
+
+         for (arc = first_out_arc (s); arc; arc = next_out_arc (arc))
+           {
+             int k;
+
+             size_t asn = s->order_state_num
+                          * automaton->insn_equiv_classes_num
+                          + arc->insn->insn_equiv_class_num;
+
+             if (min_issue_delay_vect[asn])
+               {
+                 min_issue_delay_vect[asn] = (vect_el_t) 0;
+                 changed = 1;
+               }
+
+             for (k = 0; k < automaton->insn_equiv_classes_num; k++)
+               {
+                 size_t n0, n1;
+                 vect_el_t delay0, delay1;
+
+                 n0 = s->order_state_num
+                      * automaton->insn_equiv_classes_num
+                      + k;
+                 n1 = arc->to_state->order_state_num
+                      * automaton->insn_equiv_classes_num
+                      + k;
+                 delay0 = min_issue_delay_vect[n0];
+                 delay1 = min_issue_delay_vect[n1];
+                 if (delay1 != -1)
+                   {
+                     if (arc->insn->insn_reserv_decl
+                         == DECL_INSN_RESERV (advance_cycle_insn_decl))
+                       delay1++;
+                     if (delay1 < delay0 || delay0 == -1)
+                       {
+                         min_issue_delay_vect[n0] = delay1;
+                         changed = 1;
+                       }
+                   }
+               }
+           }
+       }
+    }
+  while (changed);
+
+  automaton->max_min_delay = 0;
+
+  for (ainsn = automaton->ainsn_list; ainsn; ainsn = ainsn->next_ainsn)
     if (ainsn->first_ainsn_with_given_equivalence_num)
       {
-       for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
-         VEC_index (state_t, output_states_vect, i)->min_insn_issue_delay = -1;
-       for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
+       for (i = 0; i < output_states_vect.length (); i++)
          {
-           state_t s = VEC_index (state_t, output_states_vect, i);
-            min_delay = min_issue_delay (s, ainsn);
-           if (automaton->max_min_delay < min_delay)
-             automaton->max_min_delay = min_delay;
-           VEC_replace (vect_el_t, min_issue_delay_vect,
-                        s->order_state_num
-                        * automaton->insn_equiv_classes_num
-                        + ainsn->insn_equiv_class_num,
-                        min_delay);
+           state_t s = output_states_vect[i];
+           size_t np = s->order_state_num
+                       * automaton->insn_equiv_classes_num
+                       + ainsn->insn_equiv_class_num;
+           vect_el_t x = min_issue_delay_vect[np];
+
+           if (automaton->max_min_delay < x)
+             automaton->max_min_delay = x;
+           if (x == -1)
+             min_issue_delay_vect[np] = (vect_el_t) 0;
          }
       }
+
   fprintf (output_file, "/* Vector of min issue delay of insns.  */\n");
   fprintf (output_file, "static const ");
   output_range_type (output_file, 0, automaton->max_min_delay);
@@ -7620,26 +7706,25 @@ output_min_issue_delay_table (automaton_t automaton)
   automaton->min_issue_delay_table_compression_factor = cfactor;
 
   compressed_min_issue_delay_len = (min_issue_delay_len+cfactor-1) / cfactor;
-  compressed_min_issue_delay_vect
-    = VEC_alloc (vect_el_t, heap, compressed_min_issue_delay_len);
+  compressed_min_issue_delay_vect.create (compressed_min_issue_delay_len);
 
   for (i = 0; i < compressed_min_issue_delay_len; i++)
-    VEC_quick_push (vect_el_t, compressed_min_issue_delay_vect, 0);
+    compressed_min_issue_delay_vect.quick_push (0);
 
   for (i = 0; i < min_issue_delay_len; i++)
     {
       size_t ci = i / cfactor;
-      vect_el_t x = VEC_index (vect_el_t, min_issue_delay_vect, i);
-      vect_el_t cx = VEC_index (vect_el_t, compressed_min_issue_delay_vect, ci);
+      vect_el_t x = min_issue_delay_vect[i];
+      vect_el_t cx = compressed_min_issue_delay_vect[ci];
 
       cx |= x << (8 - (i % cfactor + 1) * (8 / cfactor));
-      VEC_replace (vect_el_t, compressed_min_issue_delay_vect, ci, cx);
+      compressed_min_issue_delay_vect[ci] = cx;
     }
   output_vect (compressed_min_issue_delay_vect);
   fprintf (output_file, "};\n\n");
-  VEC_free (state_t, heap, output_states_vect);
-  VEC_free (vect_el_t, heap, min_issue_delay_vect);
-  VEC_free (vect_el_t, heap, compressed_min_issue_delay_vect);
+  output_states_vect.release ();
+  min_issue_delay_vect.release ();
+  compressed_min_issue_delay_vect.release ();
 }
 
 /* Form and output vector representing the locked states of
@@ -7649,31 +7734,30 @@ output_dead_lock_vect (automaton_t automaton)
 {
   size_t i;
   arc_t arc;
-  vla_hwint_t dead_lock_vect = 0;
+  vla_hwint_t dead_lock_vect = vla_hwint_t ();
 
   /* Create vect of pointers to states ordered by num of
      transitions from the state (state with the maximum num is the
      first).  */
   automaton->locked_states = 0;
-  output_states_vect = 0;
+  output_states_vect.create (0);
   pass_states (automaton, add_states_vect_el);
 
-  VEC_safe_grow (vect_el_t, heap, dead_lock_vect, 
-                VEC_length (state_t, output_states_vect));
-  for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
+  dead_lock_vect.safe_grow (output_states_vect.length ());
+  for (i = 0; i < output_states_vect.length (); i++)
     {
-      state_t s = VEC_index (state_t, output_states_vect, i);
+      state_t s = output_states_vect[i];
       arc = first_out_arc (s);
       gcc_assert (arc);
       if (next_out_arc (arc) == NULL
          && (arc->insn->insn_reserv_decl
              == DECL_INSN_RESERV (advance_cycle_insn_decl)))
        {
-         VEC_replace (vect_el_t, dead_lock_vect, s->order_state_num, 1);
+         dead_lock_vect[s->order_state_num] = 1;
          automaton->locked_states++;
        }
       else
-       VEC_replace (vect_el_t, dead_lock_vect, s->order_state_num, 0);
+       dead_lock_vect[s->order_state_num] = (vect_el_t) 0;
     }
   if (automaton->locked_states == 0)
     return;
@@ -7686,8 +7770,8 @@ output_dead_lock_vect (automaton_t automaton)
   fprintf (output_file, "[] = {\n");
   output_vect (dead_lock_vect);
   fprintf (output_file, "};\n\n");
-  VEC_free (state_t, heap, output_states_vect);
-  VEC_free (vect_el_t, heap, dead_lock_vect);
+  output_states_vect.release ();
+  dead_lock_vect.release ();
 }
 
 /* Form and output vector representing reserved units of the states of
@@ -7695,7 +7779,7 @@ output_dead_lock_vect (automaton_t automaton)
 static void
 output_reserved_units_table (automaton_t automaton)
 {
-  vla_hwint_t reserved_units_table = 0;
+  vla_hwint_t reserved_units_table = vla_hwint_t ();
   int state_byte_size;
   int reserved_units_size;
   size_t n;
@@ -7705,30 +7789,30 @@ output_reserved_units_table (automaton_t automaton)
     return;
 
   /* Create vect of pointers to states.  */
-  output_states_vect = 0;
+  output_states_vect.create (0);
   pass_states (automaton, add_states_vect_el);
   /* Create vector.  */
   state_byte_size = (description->query_units_num + 7) / 8;
-  reserved_units_size = (VEC_length (state_t, output_states_vect)
+  reserved_units_size = (output_states_vect.length ()
                         * state_byte_size);
 
-  reserved_units_table = VEC_alloc (vect_el_t, heap, reserved_units_size);
-                
+  reserved_units_table.create (reserved_units_size);
+
   for (i = 0; i < reserved_units_size; i++)
-    VEC_quick_push (vect_el_t, reserved_units_table, 0);
-  for (n = 0; n < VEC_length (state_t, output_states_vect); n++)
+    reserved_units_table.quick_push (0);
+  for (n = 0; n < output_states_vect.length (); n++)
     {
-      state_t s = VEC_index (state_t, output_states_vect, n);
+      state_t s = output_states_vect[n];
       for (i = 0; i < description->units_num; i++)
        if (units_array [i]->query_p
            && first_cycle_unit_presence (s, i))
          {
            int ri = (s->order_state_num * state_byte_size
                      + units_array [i]->query_num / 8);
-           vect_el_t x = VEC_index (vect_el_t, reserved_units_table, ri);
+           vect_el_t x = reserved_units_table[ri];
 
            x += 1 << (units_array [i]->query_num % 8);
-           VEC_replace (vect_el_t, reserved_units_table, ri, x);
+           reserved_units_table[ri] = x;
          }
     }
   fprintf (output_file, "\n#if %s\n", CPU_UNITS_QUERY_MACRO_NAME);
@@ -7742,8 +7826,8 @@ output_reserved_units_table (automaton_t automaton)
   fprintf (output_file, "};\n#endif /* #if %s */\n\n",
           CPU_UNITS_QUERY_MACRO_NAME);
 
-  VEC_free (state_t, heap, output_states_vect);
-  VEC_free (vect_el_t, heap, reserved_units_table);
+  output_states_vect.release ();
+  reserved_units_table.release ();
 }
 
 /* The function outputs all tables representing DFA(s) used for fast
@@ -7753,7 +7837,6 @@ output_tables (void)
 {
   automaton_t automaton;
 
-  initiate_min_issue_delay_pass_states ();
   for (automaton = description->first_automaton;
        automaton != NULL;
        automaton = automaton->next_automaton)
@@ -7766,6 +7849,9 @@ output_tables (void)
     }
   fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
            DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
+  if (collapse_flag)
+    fprintf (output_file, "\n#define %s %d\n\n", COLLAPSE_NDFA_VALUE_NAME,
+            DECL_INSN_RESERV (collapse_ndfa_insn_decl)->insn_num);
 }
 
 /* The function outputs definition and value of PHR interface variable
@@ -7869,12 +7955,15 @@ output_automata_list_min_issue_delay_code (automata_list_el_t automata_list)
        {
          fprintf (output_file, ") / %d];\n",
                   automaton->min_issue_delay_table_compression_factor);
-         fprintf (output_file, "      %s = (%s >> (8 - (",
+         fprintf (output_file, "      %s = (%s >> (8 - ((",
                   TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
          output_translate_vect_name (output_file, automaton);
+         fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
+         fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
+         output_chip_member_name (output_file, automaton);
+         fprintf (output_file, " * %d)", automaton->insn_equiv_classes_num);
          fprintf
-           (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
-            INTERNAL_INSN_CODE_NAME,
+           (output_file, " %% %d + 1) * %d)) & %d;\n",
             automaton->min_issue_delay_table_compression_factor,
             8 / automaton->min_issue_delay_table_compression_factor,
             (1 << (8 / automaton->min_issue_delay_table_compression_factor))
@@ -8024,14 +8113,10 @@ output_internal_trans_func (void)
 
 /* Output code
 
-  if (insn != 0)
-    {
-      insn_code = dfa_insn_code (insn);
-      if (insn_code > DFA__ADVANCE_CYCLE)
-        return code;
-    }
-  else
-    insn_code = DFA__ADVANCE_CYCLE;
+  gcc_checking_assert (insn != 0);
+  insn_code = dfa_insn_code (insn);
+  if (insn_code >= DFA__ADVANCE_CYCLE)
+    return code;
 
   where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
   code denotes CODE.  */
@@ -8040,13 +8125,12 @@ output_internal_insn_code_evaluation (const char *insn_name,
                                      const char *insn_code_name,
                                      int code)
 {
-  fprintf (output_file, "\n  if (%s != 0)\n    {\n", insn_name);
-  fprintf (output_file, "      %s = %s (%s);\n", insn_code_name,
-          DFA_INSN_CODE_FUNC_NAME, insn_name);
-  fprintf (output_file, "      if (%s > %s)\n        return %d;\n",
-          insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
-  fprintf (output_file, "    }\n  else\n    %s = %s;\n\n",
-          insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
+  fprintf (output_file, "  gcc_checking_assert (%s != 0);\n"
+           "  %s = %s (%s);\n"
+           "  if (%s >= %s)\n    return %d;\n",
+           insn_name,
+           insn_code_name, DFA_INSN_CODE_FUNC_NAME, insn_name,
+           insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
 }
 
 
@@ -8074,7 +8158,7 @@ dfa_insn_code_enlarge (int uid)\n\
           DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
           DFA_INSN_CODES_VARIABLE_NAME);
   fprintf (output_file, "\
-static inline int\n%s (rtx %s)\n\
+static inline int\n%s (rtx_insn *%s)\n\
 {\n\
   int uid = INSN_UID (%s);\n\
   int %s;\n\n",
@@ -8107,8 +8191,22 @@ output_trans_func (void)
           TRANSITION_FUNC_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, -1);
+  fprintf (output_file, "\n  if (%s == 0)\n", INSN_PARAMETER_NAME);
+  fprintf (output_file, "    %s = %s;\n",
+          INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
+  if (collapse_flag)
+    {
+      fprintf (output_file, "  else if (%s == const0_rtx)\n",
+              INSN_PARAMETER_NAME);
+      fprintf (output_file, "    %s = %s;\n",
+              INTERNAL_INSN_CODE_NAME, COLLAPSE_NDFA_VALUE_NAME);
+    }
+  fprintf (output_file, "  else\n    {\n");
+  fprintf (output_file, "      %s = %s (as_a <rtx_insn *> (%s));\n",
+          INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
+          INSN_PARAMETER_NAME);
+  fprintf (output_file, "      if (%s > %s)\n        return -1;\n    }\n",
+          INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_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);
 }
@@ -8117,7 +8215,7 @@ output_trans_func (void)
 static void
 output_min_issue_delay_func (void)
 {
-  fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
+  fprintf (output_file, "int\n%s (%s %s, rtx_insn *%s)\n",
           MIN_ISSUE_DELAY_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
           INSN_PARAMETER_NAME);
   fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
@@ -8200,7 +8298,7 @@ static void
 output_min_insn_conflict_delay_func (void)
 {
   fprintf (output_file,
-          "int\n%s (%s %s, rtx %s, rtx %s)\n",
+          "int\n%s (%s %s, rtx_insn *%s, rtx_insn *%s)\n",
           MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME,
           STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
   fprintf (output_file, "{\n  struct %s %s;\n  int %s, %s, transition;\n",
@@ -8222,7 +8320,7 @@ output_min_insn_conflict_delay_func (void)
   fprintf (output_file, "}\n\n");
 }
 
-/* Output the array holding default latency values.  These are used in 
+/* Output the array holding default latency values.  These are used in
    insn_latency and maximal_insn_latency function implementations.  */
 static void
 output_default_latencies (void)
@@ -8247,9 +8345,8 @@ output_default_latencies (void)
   fprintf (output_file, "  static const %s default_latencies[] =\n    {",
           tabletype);
 
-  for (i = 0, j = 0, col = 7; i < description->decls_num; i++)
-    if (description->decls[i]->mode == dm_insn_reserv
-       && description->decls[i] != advance_cycle_insn_decl)
+  for (i = 0, j = 0, col = 7; i < description->normal_decls_num; i++)
+    if (description->decls[i]->mode == dm_insn_reserv)
       {
        if ((col = (col+1) % 8) == 0)
          fputs ("\n     ", output_file);
@@ -8258,7 +8355,7 @@ output_default_latencies (void)
        fprintf (output_file, "% 4d,",
                 DECL_INSN_RESERV (decl)->default_latency);
       }
-  gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
+  gcc_assert (j == description->insns_num - (collapse_flag ? 2 : 1));
   fputs ("\n    };\n", output_file);
 }
 
@@ -8270,10 +8367,12 @@ output_internal_insn_latency_func (void)
   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, "static int\n"
+          "%s (int %s ATTRIBUTE_UNUSED, int %s ATTRIBUTE_UNUSED,\n"
+          "\trtx_insn *%s ATTRIBUTE_UNUSED, rtx_insn *%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)
@@ -8282,10 +8381,6 @@ output_internal_insn_latency_func (void)
       return;
     }
 
-  fprintf (output_file, "  if (%s >= %s || %s >= %s)\n    return 0;\n",
-          INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
-          INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
-
   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
@@ -8348,9 +8443,8 @@ output_internal_maximal_insn_latency_func (void)
   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, "static int\n%s (int %s ATTRIBUTE_UNUSED)\n",
+          "internal_maximal_insn_latency", INTERNAL_INSN_CODE_NAME);
   fprintf (output_file, "{\n");
 
   if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
@@ -8387,7 +8481,7 @@ output_internal_maximal_insn_latency_func (void)
 static void
 output_insn_latency_func (void)
 {
-  fprintf (output_file, "int\n%s (rtx %s, rtx %s)\n",
+  fprintf (output_file, "int\n%s (rtx_insn *%s, rtx_insn *%s)\n",
           INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
   fprintf (output_file, "{\n  int %s, %s;\n",
           INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
@@ -8405,15 +8499,14 @@ output_insn_latency_func (void)
 static void
 output_maximal_insn_latency_func (void)
 {
-  fprintf (output_file, "int\n%s (rtx %s)\n",
+  fprintf (output_file, "int\n%s (rtx_insn *%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);
+  fprintf (output_file, "  return %s (%s);\n}\n\n",
+          "internal_maximal_insn_latency", INTERNAL_INSN_CODE_NAME);
 }
 
 /* The function outputs PHR interface function `print_reservation'.  */
@@ -8424,7 +8517,7 @@ output_print_reservation_func (void)
   int i, j;
 
   fprintf (output_file,
-          "void\n%s (FILE *%s, rtx %s ATTRIBUTE_UNUSED)\n{\n",
+          "void\n%s (FILE *%s, rtx_insn *%s ATTRIBUTE_UNUSED)\n{\n",
            PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
            INSN_PARAMETER_NAME);
 
@@ -8439,20 +8532,20 @@ output_print_reservation_func (void)
   fputs ("  static const char *const reservation_names[] =\n    {",
         output_file);
 
-  for (i = 0, j = 0; i < description->decls_num; i++)
+  for (i = 0, j = 0; i < description->normal_decls_num; i++)
     {
       decl = description->decls [i];
-      if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
+      if (decl->mode == dm_insn_reserv)
        {
          gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num);
          j++;
-         
+
          fprintf (output_file, "\n      \"%s\",",
                   regexp_representation (DECL_INSN_RESERV (decl)->regexp));
          finish_regexp_representation ();
        }
     }
-  gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
+  gcc_assert (j == description->insns_num - (collapse_flag ? 2 : 1));
 
   fprintf (output_file, "\n      \"%s\"\n    };\n  int %s;\n\n",
           NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
@@ -8590,7 +8683,7 @@ static void
 output_insn_has_dfa_reservation_p (void)
 {
   fprintf (output_file,
-          "bool\n%s (rtx %s ATTRIBUTE_UNUSED)\n{\n",
+          "bool\n%s (rtx_insn *%s ATTRIBUTE_UNUSED)\n{\n",
            INSN_HAS_DFA_RESERVATION_P_FUNC_NAME,
            INSN_PARAMETER_NAME);
 
@@ -8635,7 +8728,7 @@ output_dfa_clean_insn_cache_func (void)
           DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
 
   fprintf (output_file,
-           "void\n%s (rtx %s)\n{\n  int %s;\n\n",
+           "void\n%s (rtx_insn *%s)\n{\n  int %s;\n\n",
            DFA_CLEAR_SINGLE_INSN_CACHE_FUNC_NAME, INSN_PARAMETER_NAME,
           I_VARIABLE_NAME);
   fprintf (output_file,
@@ -8762,7 +8855,7 @@ output_description (void)
        }
     }
   fprintf (output_description_file, "\n");
-  for (i = 0; i < description->decls_num; i++)
+  for (i = 0; i < description->normal_decls_num; i++)
     {
       decl = description->decls [i];
       if (decl->mode == dm_reserv)
@@ -8772,7 +8865,7 @@ output_description (void)
           output_regexp (DECL_RESERV (decl)->regexp);
           fprintf (output_description_file, "\n");
         }
-      else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
+      else if (decl->mode == dm_insn_reserv)
         {
           fprintf (output_description_file, "insn reservation %s ",
                   DECL_INSN_RESERV (decl)->name);
@@ -8785,8 +8878,8 @@ output_description (void)
       else if (decl->mode == dm_bypass)
        fprintf (output_description_file, "bypass %d %s %s\n",
                 DECL_BYPASS (decl)->latency,
-                DECL_BYPASS (decl)->out_insn_name,
-                DECL_BYPASS (decl)->in_insn_name);
+                DECL_BYPASS (decl)->out_pattern,
+                DECL_BYPASS (decl)->in_pattern);
     }
   fprintf (output_description_file, "\n\f\n");
 }
@@ -8848,7 +8941,7 @@ output_automaton_units (automaton_t automaton)
 
 /* The following variable is used for forming array of all possible cpu unit
    reservations described by the current DFA state.  */
-static VEC(reserv_sets_t, heap) *state_reservs;
+static vec<reserv_sets_t> state_reservs;
 
 /* The function forms `state_reservs' for STATE.  */
 static void
@@ -8862,7 +8955,7 @@ add_state_reservs (state_t state)
          curr_alt_state = curr_alt_state->next_sorted_alt_state)
       add_state_reservs (curr_alt_state->state);
   else
-    VEC_safe_push (reserv_sets_t, heap, state_reservs, state->reservs);
+    state_reservs.safe_push (state->reservs);
 }
 
 /* The function outputs readable representation of all out arcs of
@@ -8930,15 +9023,13 @@ remove_state_duplicate_reservs (void)
 {
   size_t i, j;
 
-  for (i = 1, j = 0; i < VEC_length (reserv_sets_t, state_reservs); i++)
-    if (reserv_sets_cmp (VEC_index (reserv_sets_t, state_reservs, j),
-                        VEC_index (reserv_sets_t, state_reservs, i)))
+  for (i = 1, j = 0; i < state_reservs.length (); i++)
+    if (reserv_sets_cmp (state_reservs[j], state_reservs[i]))
       {
        j++;
-       VEC_replace (reserv_sets_t, state_reservs, j,
-                    VEC_index (reserv_sets_t, state_reservs, i));
+       state_reservs[j] = state_reservs[i];
       }
-  VEC_truncate (reserv_sets_t, state_reservs, j + 1);
+  state_reservs.truncate (j + 1);
 }
 
 /* The following function output readable representation of DFA(s)
@@ -8950,26 +9041,23 @@ output_state (state_t state)
 {
   size_t i;
 
-  state_reservs = 0;
+  state_reservs.create (0);
 
   fprintf (output_description_file, "  State #%d", state->order_state_num);
   fprintf (output_description_file,
           state->new_cycle_p ? " (new cycle)\n" : "\n");
   add_state_reservs (state);
-  qsort (VEC_address (reserv_sets_t, state_reservs),
-        VEC_length (reserv_sets_t, state_reservs),
-         sizeof (reserv_sets_t), state_reservs_cmp);
+  state_reservs.qsort (state_reservs_cmp);
   remove_state_duplicate_reservs ();
-  for (i = 0; i < VEC_length (reserv_sets_t, state_reservs); i++)
+  for (i = 0; i < state_reservs.length (); i++)
     {
       fprintf (output_description_file, "    ");
-      output_reserv_sets (output_description_file,
-                         VEC_index (reserv_sets_t, state_reservs, i));
+      output_reserv_sets (output_description_file, state_reservs[i]);
       fprintf (output_description_file, "\n");
     }
   fprintf (output_description_file, "\n");
   output_state_arcs (state);
-  VEC_free (reserv_sets_t, heap, state_reservs);
+  state_reservs.release ();
 }
 
 /* The following function output readable representation of
@@ -9034,8 +9122,8 @@ output_statistics (FILE *f)
 #ifndef NDEBUG
       fprintf
        (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
-        (long) VEC_length (vect_el_t, automaton->trans_table->comb_vect),
-        (long) VEC_length (vect_el_t, automaton->trans_table->full_vect),
+        (long) automaton->trans_table->comb_vect.length (),
+        (long) automaton->trans_table->full_vect.length (),
         (comb_vect_p (automaton->trans_table)
          ? "use comb vect" : "use simple vect"));
       fprintf
@@ -9043,9 +9131,9 @@ output_statistics (FILE *f)
          (long) states_num * automaton->insn_equiv_classes_num,
         automaton->min_issue_delay_table_compression_factor);
       transition_comb_vect_els
-       += VEC_length (vect_el_t, automaton->trans_table->comb_vect);
+       += automaton->trans_table->comb_vect.length ();
       transition_full_vect_els
-        += VEC_length (vect_el_t, automaton->trans_table->full_vect);
+        += automaton->trans_table->full_vect.length ();
       min_issue_delay_vect_els
        += states_num * automaton->insn_equiv_classes_num;
       locked_states
@@ -9119,7 +9207,7 @@ generate (void)
 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
 
 /* The function returns suffix of given file name.  The returned
-   string can not be changed.  */
+   string cannot be changed.  */
 static const char *
 file_name_suffix (const char *file_name)
 {
@@ -9134,7 +9222,7 @@ file_name_suffix (const char *file_name)
 /* The function returns base name of given file name, i.e. pointer to
    first char after last `/' (or `\' for WIN32) in given file name,
    given file name itself if the directory name is absent.  The
-   returned string can not be changed.  */
+   returned string cannot be changed.  */
 static const char *
 base_file_name (const char *file_name)
 {
@@ -9151,44 +9239,45 @@ base_file_name (const char *file_name)
   return file_name + directory_name_length + 1;
 }
 
+/* A function passed as argument to init_rtx_reader_args_cb.  It parses the
+   options available for genautomata.  Returns true if the option was
+   recognized.  */
+static bool
+parse_automata_opt (const char *str)
+{
+  if (strcmp (str, NO_MINIMIZATION_OPTION) == 0)
+    no_minimization_flag = 1;
+  else if (strcmp (str, TIME_OPTION) == 0)
+    time_flag = 1;
+  else if (strcmp (str, STATS_OPTION) == 0)
+    stats_flag = 1;
+  else if (strcmp (str, V_OPTION) == 0)
+    v_flag = 1;
+  else if (strcmp (str, W_OPTION) == 0)
+    w_flag = 1;
+  else if (strcmp (str, NDFA_OPTION) == 0)
+    ndfa_flag = 1;
+  else if (strcmp (str, COLLAPSE_OPTION) == 0)
+    collapse_flag = 1;
+  else if (strcmp (str, PROGRESS_OPTION) == 0)
+    progress_flag = 1;
+  else if (strcmp (str, "-split") == 0)
+    {
+      fatal ("option `-split' has not been implemented yet\n");
+      /* split_argument = atoi (argument_vect [i + 1]); */
+    }
+  else
+    return false;
+
+  return true;
+}
+
 /* The following is top level function to initialize the work of
    pipeline hazards description translator.  */
 static void
-initiate_automaton_gen (int argc, char **argv)
+initiate_automaton_gen (const char **argv)
 {
   const char *base_name;
-  int i;
-
-  ndfa_flag = 0;
-  split_argument = 0;  /* default value */
-  no_minimization_flag = 0;
-  time_flag = 0;
-  stats_flag = 0;
-  v_flag = 0;
-  w_flag = 0;
-  progress_flag = 0;
-  for (i = 2; i < argc; i++)
-    if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
-      no_minimization_flag = 1;
-    else if (strcmp (argv [i], TIME_OPTION) == 0)
-      time_flag = 1;
-    else if (strcmp (argv [i], STATS_OPTION) == 0)
-      stats_flag = 1;
-    else if (strcmp (argv [i], V_OPTION) == 0)
-      v_flag = 1;
-    else if (strcmp (argv [i], W_OPTION) == 0)
-      w_flag = 1;
-    else if (strcmp (argv [i], NDFA_OPTION) == 0)
-      ndfa_flag = 1;
-    else if (strcmp (argv [i], PROGRESS_OPTION) == 0)
-      progress_flag = 1;
-    else if (strcmp (argv [i], "-split") == 0)
-      {
-       if (i + 1 >= argc)
-         fatal ("-split has no argument.");
-       fatal ("option `-split' has not been implemented yet\n");
-       /* split_argument = atoi (argument_vect [i + 1]); */
-      }
 
   /* Initialize IR storage.  */
   obstack_init (&irp);
@@ -9203,7 +9292,7 @@ initiate_automaton_gen (int argc, char **argv)
   obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
                strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
   obstack_1grow (&irp, '\0');
-  output_description_file_name = obstack_base (&irp);
+  output_description_file_name = (char *) obstack_base (&irp);
   obstack_finish (&irp);
 }
 
@@ -9222,7 +9311,8 @@ check_automata_insn_issues (void)
       for (ainsn = automaton->ainsn_list;
           ainsn != NULL;
           ainsn = ainsn->next_ainsn)
-       if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
+       if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p
+           && ainsn != automaton->collapse_ainsn)
          {
            for (reserv_ainsn = ainsn;
                 reserv_ainsn != NULL;
@@ -9234,10 +9324,9 @@ check_automata_insn_issues (void)
                           automaton->corresponding_automaton_decl->name,
                           reserv_ainsn->insn_reserv_decl->name);
                  else
-                   warning
-                     (0, "Automaton `%s': Insn `%s' will never be issued",
-                      automaton->corresponding_automaton_decl->name,
-                      reserv_ainsn->insn_reserv_decl->name);
+                   warning ("Automaton `%s': Insn `%s' will never be issued",
+                            automaton->corresponding_automaton_decl->name,
+                            reserv_ainsn->insn_reserv_decl->name);
                }
              else
                {
@@ -9245,7 +9334,7 @@ check_automata_insn_issues (void)
                    error ("Insn `%s' will never be issued",
                           reserv_ainsn->insn_reserv_decl->name);
                  else
-                   warning (0, "Insn `%s' will never be issued",
+                   warning ("Insn `%s' will never be issued",
                             reserv_ainsn->insn_reserv_decl->name);
                }
          }
@@ -9254,14 +9343,14 @@ check_automata_insn_issues (void)
 
 /* The following vla is used for storing pointers to all achieved
    states.  */
-static VEC(state_t, heap) *automaton_states;
+static vec<state_t> automaton_states;
 
 /* This function is called by function pass_states to add an achieved
    STATE.  */
 static void
 add_automaton_state (state_t state)
 {
-  VEC_safe_push (state_t, heap, automaton_states, state);
+  automaton_states.safe_push (state);
 }
 
 /* The following function forms list of important automata (whose
@@ -9276,17 +9365,17 @@ form_important_insn_automata_lists (void)
   int i;
   size_t n;
 
-  automaton_states = 0;
+  automaton_states.create (0);
   /* Mark important ainsns.  */
   for (automaton = description->first_automaton;
        automaton != NULL;
        automaton = automaton->next_automaton)
     {
-      VEC_truncate (state_t, automaton_states, 0);
+      automaton_states.truncate (0);
       pass_states (automaton, add_automaton_state);
-      for (n = 0; n < VEC_length (state_t, automaton_states); n++)
+      for (n = 0; n < automaton_states.length (); n++)
        {
-         state_t s = VEC_index (state_t, automaton_states, n);
+         state_t s = automaton_states[n];
          for (arc = first_out_arc (s);
               arc != NULL;
               arc = next_out_arc (arc))
@@ -9300,7 +9389,7 @@ form_important_insn_automata_lists (void)
              }
        }
     }
-  VEC_free (state_t, heap, automaton_states);
+  automaton_states.release ();
 
   /* Create automata sets for the insns.  */
   for (i = 0; i < description->decls_num; i++)
@@ -9337,13 +9426,14 @@ expand_automata (void)
 
   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);
+                               /* Two entries for special insns.  */
+                               + sizeof (decl_t) * (decls.length () + 1));
+  description->decls_num = decls.length ();
+  description->normal_decls_num = description->decls_num;
   description->query_units_num = 0;
   for (i = 0; i < description->decls_num; i++)
     {
-      description->decls [i] = VEC_index (decl_t, decls, i);
+      description->decls [i] = decls[i];
       if (description->decls [i]->mode == dm_unit
          && DECL_UNIT (description->decls [i])->query_p)
         DECL_UNIT (description->decls [i])->query_num
@@ -9477,109 +9567,117 @@ write_automata (void)
 }
 
 int
-main (int argc, char **argv)
+main (int argc, const char **argv)
 {
-  rtx desc;
-
   progname = "genautomata";
 
-  if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
+  if (!init_rtx_reader_args_cb (argc, argv, parse_automata_opt))
     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)
+  initiate_automaton_gen (argv);
+  md_rtx_info info;
+  while (read_md_rtx (&info))
+    switch (GET_CODE (info.def))
+      {
+      case DEFINE_CPU_UNIT:
+       gen_cpu_unit (&info);
        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_QUERY_CPU_UNIT:
+       gen_query_cpu_unit (&info);
+       break;
 
-       case DEFINE_BYPASS:
-         gen_bypass (desc);
-         break;
+      case DEFINE_BYPASS:
+       gen_bypass (&info);
+       break;
 
-       case EXCLUSION_SET:
-         gen_excl_set (desc);
-         break;
+      case EXCLUSION_SET:
+       gen_excl_set (&info);
+       break;
 
-       case PRESENCE_SET:
-         gen_presence_set (desc);
-         break;
+      case PRESENCE_SET:
+       gen_presence_set (&info);
+       break;
 
-       case FINAL_PRESENCE_SET:
-         gen_final_presence_set (desc);
-         break;
+      case FINAL_PRESENCE_SET:
+       gen_final_presence_set (&info);
+       break;
 
-       case ABSENCE_SET:
-         gen_absence_set (desc);
-         break;
+      case ABSENCE_SET:
+       gen_absence_set (&info);
+       break;
 
-       case FINAL_ABSENCE_SET:
-         gen_final_absence_set (desc);
-         break;
+      case FINAL_ABSENCE_SET:
+       gen_final_absence_set (&info);
+       break;
 
-       case DEFINE_AUTOMATON:
-         gen_automaton (desc);
-         break;
+      case DEFINE_AUTOMATON:
+       gen_automaton (&info);
+       break;
 
-       case AUTOMATA_OPTION:
-         gen_automata_option (desc);
-         break;
+      case AUTOMATA_OPTION:
+       gen_automata_option (&info);
+       break;
 
-       case DEFINE_RESERVATION:
-         gen_reserv (desc);
-         break;
+      case DEFINE_RESERVATION:
+       gen_reserv (&info);
+       break;
 
-       case DEFINE_INSN_RESERVATION:
-         gen_insn_reserv (desc);
-         break;
+      case DEFINE_INSN_RESERVATION:
+       gen_insn_reserv (&info);
+       break;
 
-       default:
-         break;
-       }
-    }
+      default:
+       break;
+      }
 
   if (have_error)
     return FATAL_EXIT_CODE;
 
-  if (VEC_length (decl_t, decls) > 0)
+  if (decls.length () > 0)
     {
       expand_automata ();
       if (!have_error)
        {
          puts ("/* Generated automatically by the program `genautomata'\n"
                "   from the machine description file `md'.  */\n\n"
+               "#define IN_TARGET_CODE 1\n"
                "#include \"config.h\"\n"
                "#include \"system.h\"\n"
                "#include \"coretypes.h\"\n"
                "#include \"tm.h\"\n"
+               "#include \"alias.h\"\n"
+               "#include \"tree.h\"\n"
+               "#include \"varasm.h\"\n"
+               "#include \"stor-layout.h\"\n"
+               "#include \"calls.h\"\n"
                "#include \"rtl.h\"\n"
+               "#include \"memmodel.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 \"diagnostic-core.h\"\n"
                "#include \"flags.h\"\n"
-               "#include \"function.h\"\n");
+               "#include \"function.h\"\n"
+               "#include \"emit-rtl.h\"\n");
+                /* FIXME: emit-rtl.h can go away once crtl is in rtl.h.  */
 
          write_automata ();
        }
     }
+  else
+    {
+      puts ("/* Generated automatically by the program `genautomata'\n"
+           "   from the machine description file `md'.  */\n\n"
+           "/* There is no automaton, but ISO C forbids empty\n"
+           "   translation units, so include a header file with some\n"
+           "   declarations, and its pre-requisite header file.  */\n"
+           "#include \"config.h\"\n"
+           "#include \"system.h\"\n");
+    }
 
   fflush (stdout);
   return (ferror (stdout) != 0 || have_error
This page took 0.145157 seconds and 5 git commands to generate.