OSDN Git Service

Add Go frontend, libgo library, and Go testsuite.
[pf3gnuchains/gcc-fork.git] / gcc / genautomata.c
index 96737bc..afc97af 100644 (file)
@@ -1,5 +1,5 @@
 /* Pipeline hazard description translator.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    Written by Vladimir Makarov <vmakarov@redhat.com>
@@ -22,21 +22,25 @@ along with GCC; see the file COPYING3.  If not see
 
 /* References:
 
-   1. Detecting pipeline structural hazards quickly. T. Proebsting,
+   1. The finite state automaton based pipeline hazard recognizer and
+      instruction scheduler in GCC.  V. Makarov.  Proceedings of GCC
+      summit, 2003.
+
+   2. Detecting pipeline structural hazards quickly. T. Proebsting,
       C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
       Principles of Programming Languages, pages 280--286, 1994.
 
       This article is a good start point to understand usage of finite
       state automata for pipeline hazard recognizers.  But I'd
-      recommend the 2nd article for more deep understanding.
+      recommend the 1st and 3rd article for more deep understanding.
 
-   2. Efficient Instruction Scheduling Using Finite State Automata:
+   3. Efficient Instruction Scheduling Using Finite State Automata:
       V. Bala and N. Rubin, Proceedings of MICRO-28.  This is the best
       article about usage of finite state automata for pipeline hazard
       recognizers.
 
-   The current implementation is different from the 2nd article in the
-   following:
+   The current implementation is described in the 1st article and it
+   is different from the 3rd article in the following:
 
    1. New operator `|' (alternative) is permitted in functional unit
       reservation which can be treated deterministically and
@@ -209,19 +213,19 @@ static struct obstack irp;
 /* Declare vector types for various data structures: */
 
 DEF_VEC_P(alt_state_t);
-DEF_VEC_ALLOC_P(alt_state_t,heap);
+DEF_VEC_ALLOC_P(alt_state_t, heap);
 DEF_VEC_P(ainsn_t);
-DEF_VEC_ALLOC_P(ainsn_t,heap);
+DEF_VEC_ALLOC_P(ainsn_t, heap);
 DEF_VEC_P(state_t);
-DEF_VEC_ALLOC_P(state_t,heap);
+DEF_VEC_ALLOC_P(state_t, heap);
 DEF_VEC_P(decl_t);
-DEF_VEC_ALLOC_P(decl_t,heap);
+DEF_VEC_ALLOC_P(decl_t, heap);
 DEF_VEC_P(reserv_sets_t);
-DEF_VEC_ALLOC_P(reserv_sets_t,heap);
+DEF_VEC_ALLOC_P(reserv_sets_t, heap);
 
 DEF_VEC_I(vect_el_t);
 DEF_VEC_ALLOC_I(vect_el_t, heap);
-typedef VEC(vect_el_t,heap) *vla_hwint_t;
+typedef VEC(vect_el_t, heap) *vla_hwint_t;
 \f
 /* Forward declarations of functions used before their definitions, only.  */
 static regexp_t gen_regexp_sequence    (const char *);
@@ -463,7 +467,10 @@ struct insn_reserv_decl
      insn.  */
   int insn_num;
   /* The following field value is list of bypasses in which given insn
-     is output insn.  */
+     is output insn.  Bypasses with the same input insn stay one after
+     another in the list in the same order as their occurrences in the
+     description but the bypass without a guard stays always the last
+     in a row of bypasses with the same input insn.  */
   struct bypass_decl *bypass_list;
 
   /* The following fields are defined by automaton generator.  */
@@ -471,7 +478,7 @@ struct insn_reserv_decl
   /* The following field is the insn regexp transformed that
      the regexp has not optional regexp, repetition regexp, and an
      reservation name (i.e. reservation identifiers are changed by the
-     corresponding regexp) and all alternations are the topest level
+     corresponding regexp) and all alternations are the top level
      of the regexp.  The value can be NULL only if it is special
      insn `cycle advancing'.  */
   regexp_t transformed_regexp;
@@ -1085,6 +1092,14 @@ regexp_mode_check_failed (enum regexp_mode mode,
 
 #endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
 
+#define XCREATENODE(T) ((T *) create_node (sizeof (T)))
+#define XCREATENODEVEC(T, N) ((T *) create_node (sizeof (T) * (N)))
+#define XCREATENODEVAR(T, S) ((T *) create_node ((S)))
+
+#define XCOPYNODE(T, P) ((T *) copy_node ((P), sizeof (T)))
+#define XCOPYNODEVEC(T, P, N) ((T *) copy_node ((P), sizeof (T) * (N)))
+#define XCOPYNODEVAR(T, P, S) ((T *) copy_node ((P), (S)))
+
 /* Create IR structure (node).  */
 static void *
 create_node (size_t size)
@@ -1122,7 +1137,7 @@ check_name (const char * name, pos_t pos ATTRIBUTE_UNUSED)
 
 /* Pointers to all declarations during IR generation are stored in the
    following.  */
-static VEC(decl_t,heap) *decls;
+static VEC(decl_t, heap) *decls;
 
 /* Given a pointer to a (char *) and a separator, return an alloc'ed
    string containing the next separated element, taking parentheses
@@ -1242,7 +1257,7 @@ gen_cpu_unit (rtx def)
     fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
   for (i = 0; i < vect_length; i++)
     {
-      decl = create_node (sizeof (struct decl));
+      decl = XCREATENODE (struct decl);
       decl->mode = dm_unit;
       decl->pos = 0;
       DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
@@ -1250,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);
+      VEC_safe_push (decl_t, heap, decls, decl);
     }
 }
 
@@ -1272,13 +1287,13 @@ gen_query_cpu_unit (rtx def)
     fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
   for (i = 0; i < vect_length; i++)
     {
-      decl = create_node (sizeof (struct decl));
+      decl = XCREATENODE (struct decl);
       decl->mode = dm_unit;
       decl->pos = 0;
       DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
       DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
       DECL_UNIT (decl)->query_p = 1;
-      VEC_safe_push (decl_t,heap, decls, decl);
+      VEC_safe_push (decl_t, heap, decls, decl);
     }
 }
 
@@ -1306,14 +1321,14 @@ gen_bypass (rtx def)
   for (i = 0; i < out_length; i++)
     for (j = 0; j < in_length; j++)
       {
-       decl = create_node (sizeof (struct decl));
+       decl = XCREATENODE (struct decl);
        decl->mode = dm_bypass;
        decl->pos = 0;
        DECL_BYPASS (decl)->latency = XINT (def, 0);
        DECL_BYPASS (decl)->out_insn_name = out_insns [i];
        DECL_BYPASS (decl)->in_insn_name = in_insns [j];
        DECL_BYPASS (decl)->bypass_guard_name = XSTR (def, 3);
-       VEC_safe_push (decl_t,heap, decls, decl);
+       VEC_safe_push (decl_t, heap, decls, decl);
       }
 }
 
@@ -1341,7 +1356,7 @@ gen_excl_set (rtx def)
   if (second_str_cpu_units == NULL)
     fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
   length += first_vect_length;
-  decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
+  decl = XCREATENODEVAR (struct decl, sizeof (struct decl) + (length - 1) * sizeof (char *));
   decl->mode = dm_excl;
   decl->pos = 0;
   DECL_EXCL (decl)->all_names_num = length;
@@ -1352,7 +1367,7 @@ gen_excl_set (rtx def)
     else
       DECL_EXCL (decl)->names [i]
        = second_str_cpu_units [i - first_vect_length];
-  VEC_safe_push (decl_t,heap, decls, decl);
+  VEC_safe_push (decl_t, heap, decls, decl);
 }
 
 /* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
@@ -1394,14 +1409,14 @@ gen_presence_absence_set (rtx def, int presence_p, int final_p)
            : (final_p
               ? "invalid second string `%s' in final_absence_set"
               : "invalid second string `%s' in absence_set")), XSTR (def, 1));
-  str_patterns = obstack_alloc (&irp, patterns_length * sizeof (char **));
+  str_patterns = XOBNEWVEC (&irp, char **, patterns_length);
   for (i = 0; i < patterns_length; i++)
     {
       str_patterns [i] = get_str_vect (str_pattern_lists [i],
                                       &length, ' ', FALSE);
       gcc_assert (str_patterns [i]);
     }
-  decl = create_node (sizeof (struct decl));
+  decl = XCREATENODE (struct decl);
   decl->pos = 0;
   if (presence_p)
     {
@@ -1421,7 +1436,7 @@ gen_presence_absence_set (rtx def, int presence_p, int final_p)
       DECL_ABSENCE (decl)->patterns_num = patterns_length;
       DECL_ABSENCE (decl)->final_p = final_p;
     }
-  VEC_safe_push (decl_t,heap, decls, decl);
+  VEC_safe_push (decl_t, heap, decls, decl);
 }
 
 /* Process a PRESENCE_SET.
@@ -1486,11 +1501,11 @@ gen_automaton (rtx def)
     fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
   for (i = 0; i < vect_length; i++)
     {
-      decl = create_node (sizeof (struct decl));
+      decl = XCREATENODE (struct decl);
       decl->mode = dm_automaton;
       decl->pos = 0;
       DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
-      VEC_safe_push (decl_t,heap, decls, decl);
+      VEC_safe_push (decl_t, heap, decls, decl);
     }
 }
 
@@ -1539,19 +1554,19 @@ gen_regexp_el (const char *str)
       len = strlen (str);
       if (str [len - 1] != ')')
        fatal ("garbage after ) in reservation `%s'", reserv_str);
-      dstr = alloca (len - 1);
+      dstr = XALLOCAVAR (char, len - 1);
       memcpy (dstr, str + 1, len - 2);
       dstr [len-2] = '\0';
       regexp = gen_regexp_sequence (dstr);
     }
   else if (strcmp (str, NOTHING_NAME) == 0)
     {
-      regexp = create_node (sizeof *regexp);
+      regexp = XCREATENODE (struct regexp);
       regexp->mode = rm_nothing;
     }
   else
     {
-      regexp = create_node (sizeof *regexp);
+      regexp = XCREATENODE (struct regexp);
       regexp->mode = rm_unit;
       REGEXP_UNIT (regexp)->name = str;
     }
@@ -1576,7 +1591,7 @@ gen_regexp_repeat (const char *str)
       regexp = gen_regexp_el (repeat_vect [0]);
       for (i = 1; i < els_num; i++)
        {
-         repeat = create_node (sizeof (struct regexp));
+         repeat = XCREATENODE (struct regexp);
          repeat->mode = rm_repeat;
          REGEXP_REPEAT (repeat)->regexp = regexp;
          REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]);
@@ -1588,7 +1603,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 '+'.  */
@@ -1605,8 +1620,8 @@ gen_regexp_allof (const char *str)
     fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
   if (els_num > 1)
     {
-      allof = create_node (sizeof (struct regexp)
-                          + sizeof (regexp_t) * (els_num - 1));
+      allof = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+                             + sizeof (regexp_t) * (els_num - 1));
       allof->mode = rm_allof;
       REGEXP_ALLOF (allof)->regexps_num = els_num;
       for (i = 0; i < els_num; i++)
@@ -1614,7 +1629,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 '|'.  */
@@ -1631,8 +1646,8 @@ gen_regexp_oneof (const char *str)
     fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
   if (els_num > 1)
     {
-      oneof = create_node (sizeof (struct regexp)
-                          + sizeof (regexp_t) * (els_num - 1));
+      oneof = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+                             + sizeof (regexp_t) * (els_num - 1));
       oneof->mode = rm_oneof;
       REGEXP_ONEOF (oneof)->regexps_num = els_num;
       for (i = 0; i < els_num; i++)
@@ -1640,7 +1655,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 ','.  */
@@ -1655,8 +1670,8 @@ gen_regexp_sequence (const char *str)
   sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
   if (els_num > 1)
     {
-      sequence = create_node (sizeof (struct regexp)
-                             + sizeof (regexp_t) * (els_num - 1));
+      sequence = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+                                + sizeof (regexp_t) * (els_num - 1));
       sequence->mode = rm_sequence;
       REGEXP_SEQUENCE (sequence)->regexps_num = els_num;
       for (i = 0; i < els_num; i++)
@@ -1665,7 +1680,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.  */
@@ -1673,7 +1688,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.
@@ -1686,12 +1701,12 @@ gen_reserv (rtx def)
 {
   decl_t decl;
 
-  decl = create_node (sizeof (struct decl));
+  decl = XCREATENODE (struct decl);
   decl->mode = dm_reserv;
   decl->pos = 0;
   DECL_RESERV (decl)->name = check_name (XSTR (def, 0), decl->pos);
   DECL_RESERV (decl)->regexp = gen_regexp (XSTR (def, 1));
-  VEC_safe_push (decl_t,heap, decls, decl);
+  VEC_safe_push (decl_t, heap, decls, decl);
 }
 
 /* Process a DEFINE_INSN_RESERVATION.
@@ -1704,7 +1719,7 @@ gen_insn_reserv (rtx def)
 {
   decl_t decl;
 
-  decl = create_node (sizeof (struct decl));
+  decl = XCREATENODE (struct decl);
   decl->mode = dm_insn_reserv;
   decl->pos = 0;
   DECL_INSN_RESERV (decl)->name
@@ -1712,7 +1727,7 @@ gen_insn_reserv (rtx def)
   DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
   DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
   DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3));
-  VEC_safe_push (decl_t,heap, decls, decl);
+  VEC_safe_push (decl_t, heap, decls, decl);
 }
 
 \f
@@ -1781,7 +1796,7 @@ insert_automaton_decl (decl_t automaton_decl)
 {
   void **entry_ptr;
 
-  entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1);
+  entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, INSERT);
   if (*entry_ptr == NULL)
     *entry_ptr = (void *) automaton_decl;
   return (decl_t) *entry_ptr;
@@ -1880,7 +1895,7 @@ insert_insn_decl (decl_t insn_decl)
 {
   void **entry_ptr;
 
-  entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1);
+  entry_ptr = htab_find_slot (insn_decl_table, insn_decl, INSERT);
   if (*entry_ptr == NULL)
     *entry_ptr = (void *) insn_decl;
   return (decl_t) *entry_ptr;
@@ -1981,7 +1996,7 @@ insert_decl (decl_t decl)
 {
   void **entry_ptr;
 
-  entry_ptr = htab_find_slot (decl_table, decl, 1);
+  entry_ptr = htab_find_slot (decl_table, decl, INSERT);
   if (*entry_ptr == NULL)
     *entry_ptr = (void *) decl;
   return (decl_t) *entry_ptr;
@@ -2052,7 +2067,7 @@ process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED)
        error ("`%s' in exclusion is not unit", names [i]);
       else
        {
-         new_el = create_node (sizeof (struct unit_set_el));
+         new_el = XCREATENODE (struct unit_set_el);
          new_el->unit_decl = DECL_UNIT (decl_in_table);
          new_el->next_unit_set_el = NULL;
          if (last_el == NULL)
@@ -2105,7 +2120,7 @@ add_excls (unit_set_el_t dest_list, unit_set_el_t source_list,
        if (curr_el == NULL)
          {
            /* Element not found - insert.  */
-           copy = copy_node (src, sizeof (*src));
+           copy = XCOPYNODE (struct unit_set_el, src);
            copy->next_unit_set_el = NULL;
            if (prev_el == NULL)
              dst->unit_decl->excl_list = copy;
@@ -2152,7 +2167,7 @@ process_presence_absence_names (char **names, int num,
                   : "`%s' in absence set is not unit")), names [i]);
       else
        {
-         new_el = create_node (sizeof (struct unit_set_el));
+         new_el = XCREATENODE (struct unit_set_el);
          new_el->unit_decl = DECL_UNIT (decl_in_table);
          new_el->next_unit_set_el = NULL;
          if (last_el == NULL)
@@ -2187,8 +2202,9 @@ process_presence_absence_patterns (char ***patterns, int num,
     {
       for (j = 0; patterns [i] [j] != NULL; j++)
        ;
-      new_el = create_node (sizeof (struct pattern_set_el)
-                           + sizeof (struct unit_decl *) * j);
+      new_el = XCREATENODEVAR (struct pattern_set_el,
+                              sizeof (struct pattern_set_el)
+                              + sizeof (struct unit_decl *) * j);
       new_el->unit_decls
        = (struct unit_decl **) ((char *) new_el
                                 + sizeof (struct pattern_set_el));
@@ -2298,8 +2314,7 @@ add_presence_absence (unit_set_el_t dest_list,
                          no_error_flag = 0;
                        }
                      else
-                       warning
-                         (0, "unit `%s' excludes and requires presence of `%s'",
+                       warning ("unit `%s' excludes and requires presence of `%s'",
                           dst->unit_decl->name, unit->name);
                    }
                }
@@ -2312,15 +2327,13 @@ add_presence_absence (unit_set_el_t dest_list,
                  {
                    if (!w_flag)
                      {
-                       error
-                         ("unit `%s' requires absence and presence of `%s'",
-                          dst->unit_decl->name, unit->name);
+                       error ("unit `%s' requires absence and presence of `%s'",
+                              dst->unit_decl->name, unit->name);
                        no_error_flag = 0;
                      }
                    else
-                     warning
-                       (0, "unit `%s' requires absence and presence of `%s'",
-                        dst->unit_decl->name, unit->name);
+                     warning ("unit `%s' requires absence and presence of `%s'",
+                              dst->unit_decl->name, unit->name);
                  }
            if (no_error_flag)
              {
@@ -2334,7 +2347,7 @@ add_presence_absence (unit_set_el_t dest_list,
                     prev_el != NULL && prev_el->next_pattern_set_el != NULL;
                     prev_el = prev_el->next_pattern_set_el)
                  ;
-               copy = copy_node (pat, sizeof (*pat));
+               copy = XCOPYNODE (struct pattern_set_el, pat);
                copy->next_pattern_set_el = NULL;
                if (prev_el == NULL)
                  {
@@ -2358,18 +2371,67 @@ add_presence_absence (unit_set_el_t dest_list,
 }
 
 
-/* The function searches for bypass with given IN_INSN_RESERV in given
-   BYPASS_LIST.  */
-static struct bypass_decl *
-find_bypass (struct bypass_decl *bypass_list,
-            struct insn_reserv_decl *in_insn_reserv)
+/* The function inserts BYPASS in the list of bypasses of the
+   corresponding output insn.  The order of bypasses in the list is
+   decribed in a comment for member `bypass_list' (see above).  If
+   there is already the same bypass in the list the function reports
+   this and does nothing.  */
+static void
+insert_bypass (struct bypass_decl *bypass)
 {
-  struct bypass_decl *bypass;
+  struct bypass_decl *curr, *last;
+  struct insn_reserv_decl *out_insn_reserv = bypass->out_insn_reserv;
+  struct insn_reserv_decl *in_insn_reserv = bypass->in_insn_reserv;
 
-  for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
-    if (bypass->in_insn_reserv == in_insn_reserv)
-      break;
-  return bypass;
+  for (curr = out_insn_reserv->bypass_list, last = NULL;
+       curr != NULL;
+       last = curr, curr = curr->next)
+    if (curr->in_insn_reserv == in_insn_reserv)
+      {
+       if ((bypass->bypass_guard_name != NULL
+            && curr->bypass_guard_name != NULL
+            && ! strcmp (bypass->bypass_guard_name, curr->bypass_guard_name))
+           || bypass->bypass_guard_name == curr->bypass_guard_name)
+         {
+           if (bypass->bypass_guard_name == NULL)
+             {
+               if (!w_flag)
+                 error ("the same bypass `%s - %s' is already defined",
+                        bypass->out_insn_name, bypass->in_insn_name);
+               else
+                 warning ("the same bypass `%s - %s' is already defined",
+                          bypass->out_insn_name, bypass->in_insn_name);
+             }
+           else if (!w_flag)
+             error ("the same bypass `%s - %s' (guard %s) is already defined",
+                    bypass->out_insn_name, bypass->in_insn_name,
+                    bypass->bypass_guard_name);
+           else
+             warning
+               ("the same bypass `%s - %s' (guard %s) is already defined",
+                bypass->out_insn_name, bypass->in_insn_name,
+                bypass->bypass_guard_name);
+           return;
+         }
+       if (curr->bypass_guard_name == NULL)
+         break;
+       if (curr->next == NULL || curr->next->in_insn_reserv != in_insn_reserv)
+         {
+           last = curr;
+           break;
+         }
+
+      }
+  if (last == NULL)
+    {
+      bypass->next = out_insn_reserv->bypass_list;
+      out_insn_reserv->bypass_list = bypass;
+    }
+  else
+    {
+      bypass->next = last->next;
+      last->next = bypass;
+    }
 }
 
 /* The function processes pipeline description declarations, checks
@@ -2382,7 +2444,6 @@ process_decls (void)
   decl_t decl_in_table;
   decl_t out_insn_reserv;
   decl_t in_insn_reserv;
-  struct bypass_decl *bypass;
   int automaton_presence;
   int i;
 
@@ -2401,7 +2462,7 @@ process_decls (void)
                error ("repeated declaration of automaton `%s'",
                       DECL_AUTOMATON (decl)->name);
              else
-               warning (0, "repeated declaration of automaton `%s'",
+               warning ("repeated declaration of automaton `%s'",
                         DECL_AUTOMATON (decl)->name);
            }
        }
@@ -2505,36 +2566,7 @@ process_decls (void)
                = DECL_INSN_RESERV (out_insn_reserv);
              DECL_BYPASS (decl)->in_insn_reserv
                = DECL_INSN_RESERV (in_insn_reserv);
-             bypass
-               = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list,
-                              DECL_BYPASS (decl)->in_insn_reserv);
-             if (bypass != NULL)
-               {
-                 if (DECL_BYPASS (decl)->latency == bypass->latency)
-                   {
-                     if (!w_flag)
-                       error
-                         ("the same bypass `%s - %s' is already defined",
-                          DECL_BYPASS (decl)->out_insn_name,
-                          DECL_BYPASS (decl)->in_insn_name);
-                     else
-                       warning
-                         (0, "the same bypass `%s - %s' is already defined",
-                          DECL_BYPASS (decl)->out_insn_name,
-                          DECL_BYPASS (decl)->in_insn_name);
-                   }
-                 else
-                   error ("bypass `%s - %s' is already defined",
-                          DECL_BYPASS (decl)->out_insn_name,
-                          DECL_BYPASS (decl)->in_insn_name);
-               }
-             else
-               {
-                 DECL_BYPASS (decl)->next
-                   = DECL_INSN_RESERV (out_insn_reserv)->bypass_list;
-                 DECL_INSN_RESERV (out_insn_reserv)->bypass_list
-                   = DECL_BYPASS (decl);
-               }
+             insert_bypass (DECL_BYPASS (decl));
            }
        }
     }
@@ -2629,7 +2661,7 @@ check_automaton_usage (void)
          if (!w_flag)
            error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
          else
-           warning (0, "automaton `%s' is not used",
+           warning ("automaton `%s' is not used",
                     DECL_AUTOMATON (decl)->name);
        }
     }
@@ -2664,7 +2696,7 @@ process_regexp (regexp_t regexp)
 
          case dm_reserv:
            DECL_RESERV (decl_in_table)->reserv_is_used = 1;
-           new_regexp = create_node (sizeof (struct regexp));
+           new_regexp = XCREATENODE (struct regexp);
            new_regexp->mode = rm_reserv;
            new_regexp->pos = regexp->pos;
            REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
@@ -2743,14 +2775,14 @@ check_usage (void)
          if (!w_flag)
            error ("unit `%s' is not used", DECL_UNIT (decl)->name);
          else
-           warning (0, "unit `%s' is not used", DECL_UNIT (decl)->name);
+           warning ("unit `%s' is not used", DECL_UNIT (decl)->name);
        }
       else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
        {
          if (!w_flag)
            error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
          else
-           warning (0, "reservation `%s' is not used", DECL_RESERV (decl)->name);
+           warning ("reservation `%s' is not used", DECL_RESERV (decl)->name);
        }
     }
 }
@@ -2904,7 +2936,7 @@ process_regexp_cycles (regexp_t regexp, int max_start_cycle,
       {
        int max_cycle = 0;
        int min_cycle = 0;
-       
+
        for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
          {
            process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
@@ -2924,7 +2956,7 @@ process_regexp_cycles (regexp_t regexp, int max_start_cycle,
       {
        int max_cycle = 0;
        int min_cycle = 0;
-       
+
        for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
          {
            process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
@@ -3105,7 +3137,7 @@ static decl_t advance_cycle_insn_decl;
 static void
 add_advance_cycle_insn_decl (void)
 {
-  advance_cycle_insn_decl = create_node (sizeof (struct decl));
+  advance_cycle_insn_decl = XCREATENODE (struct decl);
   advance_cycle_insn_decl->mode = dm_insn_reserv;
   advance_cycle_insn_decl->pos = no_pos;
   DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL;
@@ -3148,7 +3180,7 @@ get_free_alt_state (void)
 #ifndef NDEBUG
       allocated_alt_states_num++;
 #endif
-      result = create_node (sizeof (struct alt_state));
+      result = XCREATENODE (struct alt_state);
     }
   result->state = NULL;
   result->next_alt_state = NULL;
@@ -3204,7 +3236,7 @@ static alt_state_t
 uniq_sort_alt_states (alt_state_t alt_states_list)
 {
   alt_state_t curr_alt_state;
-  VEC(alt_state_t,heap) *alt_states;
+  VEC(alt_state_t, heap) *alt_states;
   size_t i;
   size_t prev_unique_state_ind;
   alt_state_t result;
@@ -3214,15 +3246,13 @@ uniq_sort_alt_states (alt_state_t alt_states_list)
   if (alt_states_list->next_alt_state == 0)
     return alt_states_list;
 
-  alt_states = VEC_alloc (alt_state_t,heap, 150);
+  alt_states = VEC_alloc (alt_state_t, heap, 150);
   for (curr_alt_state = alt_states_list;
        curr_alt_state != NULL;
        curr_alt_state = curr_alt_state->next_alt_state)
-    VEC_safe_push (alt_state_t,heap, alt_states, curr_alt_state);
+    VEC_safe_push (alt_state_t, heap, alt_states, curr_alt_state);
 
-  qsort (VEC_address (alt_state_t, alt_states),
-        VEC_length  (alt_state_t, alt_states),
-        sizeof (alt_state_t), alt_state_cmp);
+  VEC_qsort (alt_state_t, alt_states, alt_state_cmp);
 
   prev_unique_state_ind = 0;
   for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
@@ -3242,7 +3272,7 @@ uniq_sort_alt_states (alt_state_t alt_states_list)
 
   result = VEC_index (alt_state_t, alt_states, 0);
 
-  VEC_free (alt_state_t,heap, alt_states);
+  VEC_free (alt_state_t, heap, alt_states);
   return result;
 }
 
@@ -3282,15 +3312,18 @@ 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)
+  ((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 TEST_BIT(bitstring, bitno)                                       \
+  ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] >>                  \
+       (bitno) % (sizeof (*(bitstring)) * CHAR_BIT) & 1)
 
 \f
 
@@ -3623,7 +3656,7 @@ get_free_state (int with_reservs, automaton_t automaton)
 #ifndef NDEBUG
       allocated_states_num++;
 #endif
-      result = create_node (sizeof (struct state));
+      result = XCREATENODE (struct state);
       result->automaton = automaton;
       result->first_out_arc = NULL;
       result->unique_num = curr_unique_state_num;
@@ -3713,7 +3746,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;
@@ -3890,7 +3923,7 @@ add_arc (state_t from_state, state_t to_state, ainsn_t ainsn)
 #ifndef NDEBUG
       allocated_arcs_num++;
 #endif
-      new_arc = create_node (sizeof (struct arc));
+      new_arc = XCREATENODE (struct arc);
       new_arc->to_state = NULL;
       new_arc->insn = NULL;
       new_arc->next_out_arc = NULL;
@@ -3964,7 +3997,7 @@ get_free_automata_list_el (void)
        = first_free_automata_list_el->next_automata_list_el;
     }
   else
-    result = create_node (sizeof (struct automata_list_el));
+    result = XCREATENODE (struct automata_list_el);
   result->automaton = NULL;
   result->next_automata_list_el = NULL;
   return result;
@@ -4069,7 +4102,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
@@ -4142,20 +4175,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++)
@@ -4191,7 +4222,7 @@ form_reserv_sets_list (pattern_set_el_t pattern_list)
   prev = first = NULL;
   for (el = pattern_list; el != NULL; el = el->next_pattern_set_el)
     {
-      curr = create_node (sizeof (struct pattern_reserv));
+      curr = XCREATENODE (struct pattern_reserv);
       curr->reserv = alloc_empty_reserv_sets ();
       curr->next_pattern_reserv = NULL;
       for (i = 0; i < el->units_num; i++)
@@ -4247,28 +4278,26 @@ initiate_presence_absence_pattern_sets (void)
 }
 
 /* The function checks that CHECKED_SET satisfies all presence pattern
-   sets for units in ORIGIONAL_SET.  The function returns TRUE if it
+   sets for units in ORIGINAL_SET.  The function returns TRUE if it
    is ok.  */
 static int
 check_presence_pattern_sets (reserv_sets_t checked_set,
-                            reserv_sets_t origional_set,
+                            reserv_sets_t original_set,
                             int final_p)
 {
-  int char_num;
-  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 *) origional_set) [char_num])
-      for (i = CHAR_BIT - 1; i >= 0; i--)
-       if ((((unsigned char *) origional_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
@@ -4296,27 +4325,25 @@ check_presence_pattern_sets (reserv_sets_t checked_set,
 }
 
 /* The function checks that CHECKED_SET satisfies all absence pattern
-   sets for units in ORIGIONAL_SET.  The function returns TRUE if it
+   sets for units in ORIGINAL_SET.  The function returns TRUE if it
    is ok.  */
 static int
 check_absence_pattern_sets (reserv_sets_t checked_set,
-                           reserv_sets_t origional_set,
+                           reserv_sets_t original_set,
                            int final_p)
 {
-  int char_num;
-  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 *) origional_set) [char_num])
-      for (i = CHAR_BIT - 1; i >= 0; i--)
-       if ((((unsigned char *) origional_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
@@ -4362,44 +4389,44 @@ copy_insn_regexp (regexp_t regexp)
       break;
 
     case rm_unit:
-      result = copy_node (regexp, sizeof (struct regexp));
+      result = XCOPYNODE (struct regexp, regexp);
       break;
 
     case rm_repeat:
-      result = copy_node (regexp, sizeof (struct regexp));
+      result = XCOPYNODE (struct regexp, regexp);
       REGEXP_REPEAT (result)->regexp
         = copy_insn_regexp (REGEXP_REPEAT (regexp)->regexp);
       break;
 
     case rm_sequence:
-      result = copy_node (regexp,
-                          sizeof (struct regexp) + sizeof (regexp_t)
-                         * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
+      result = XCOPYNODEVAR (struct regexp, regexp,
+                            sizeof (struct regexp) + sizeof (regexp_t)
+                            * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
       for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
        REGEXP_SEQUENCE (result)->regexps [i]
          = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
       break;
 
     case rm_allof:
-      result = copy_node (regexp,
-                          sizeof (struct regexp) + sizeof (regexp_t)
-                         * (REGEXP_ALLOF (regexp)->regexps_num - 1));
+      result = XCOPYNODEVAR (struct regexp, regexp,
+                            sizeof (struct regexp) + sizeof (regexp_t)
+                            * (REGEXP_ALLOF (regexp)->regexps_num - 1));
       for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
        REGEXP_ALLOF (result)->regexps [i]
          = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
       break;
 
     case rm_oneof:
-      result = copy_node (regexp,
-                          sizeof (struct regexp) + sizeof (regexp_t)
-                         * (REGEXP_ONEOF (regexp)->regexps_num - 1));
+      result = XCOPYNODEVAR (struct regexp, regexp,
+                            sizeof (struct regexp) + sizeof (regexp_t)
+                            * (REGEXP_ONEOF (regexp)->regexps_num - 1));
       for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
        REGEXP_ONEOF (result)->regexps [i]
          = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
       break;
 
     case rm_nothing:
-      result = copy_node (regexp, sizeof (struct regexp));
+      result = XCOPYNODE (struct regexp, regexp);
       break;
 
     default:
@@ -4428,8 +4455,8 @@ transform_1 (regexp_t regexp)
       gcc_assert (repeat_num > 1);
       operand = REGEXP_REPEAT (regexp)->regexp;
       pos = regexp->mode;
-      regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t)
-                           * (repeat_num - 1));
+      regexp = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+                              + sizeof (regexp_t) * (repeat_num - 1));
       regexp->mode = rm_sequence;
       regexp->pos = pos;
       REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num;
@@ -4465,11 +4492,11 @@ transform_2 (regexp_t regexp)
        {
          gcc_assert (REGEXP_SEQUENCE (sequence)->regexps_num > 1
                      && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
-         result = create_node (sizeof (struct regexp)
-                                + sizeof (regexp_t)
-                               * (REGEXP_SEQUENCE (regexp)->regexps_num
-                                   + REGEXP_SEQUENCE (sequence)->regexps_num
-                                   - 2));
+         result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+                                  + sizeof (regexp_t)
+                                  * (REGEXP_SEQUENCE (regexp)->regexps_num
+                                     + REGEXP_SEQUENCE (sequence)->regexps_num
+                                     - 2));
          result->mode = rm_sequence;
          result->pos = regexp->pos;
          REGEXP_SEQUENCE (result)->regexps_num
@@ -4509,10 +4536,10 @@ transform_2 (regexp_t regexp)
        {
          gcc_assert (REGEXP_ALLOF (allof)->regexps_num > 1
                      && REGEXP_ALLOF (regexp)->regexps_num > 1);
-         result = create_node (sizeof (struct regexp)
-                                + sizeof (regexp_t)
-                               * (REGEXP_ALLOF (regexp)->regexps_num
-                                   + REGEXP_ALLOF (allof)->regexps_num - 2));
+         result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+                                  + sizeof (regexp_t)
+                                  * (REGEXP_ALLOF (regexp)->regexps_num
+                                     + REGEXP_ALLOF (allof)->regexps_num - 2));
          result->mode = rm_allof;
          result->pos = regexp->pos;
          REGEXP_ALLOF (result)->regexps_num
@@ -4552,10 +4579,10 @@ transform_2 (regexp_t regexp)
        {
          gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
                      && REGEXP_ONEOF (regexp)->regexps_num > 1);
-         result = create_node (sizeof (struct regexp)
-                               + sizeof (regexp_t)
-                               * (REGEXP_ONEOF (regexp)->regexps_num
-                                   + REGEXP_ONEOF (oneof)->regexps_num - 2));
+         result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+                                  + sizeof (regexp_t)
+                                  * (REGEXP_ONEOF (regexp)->regexps_num
+                                     + REGEXP_ONEOF (oneof)->regexps_num - 2));
          result->mode = rm_oneof;
          result->pos = regexp->pos;
          REGEXP_ONEOF (result)->regexps_num
@@ -4607,9 +4634,9 @@ transform_3 (regexp_t regexp)
        {
          gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
                      && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
-         result = create_node (sizeof (struct regexp)
-                               + sizeof (regexp_t)
-                               * (REGEXP_ONEOF (oneof)->regexps_num - 1));
+         result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+                                  + sizeof (regexp_t)
+                                  * (REGEXP_ONEOF (oneof)->regexps_num - 1));
          result->mode = rm_oneof;
          result->pos = regexp->pos;
          REGEXP_ONEOF (result)->regexps_num
@@ -4617,9 +4644,9 @@ transform_3 (regexp_t regexp)
          for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
            {
              sequence
-                = create_node (sizeof (struct regexp)
-                               + sizeof (regexp_t)
-                               * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
+                = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+                                 + sizeof (regexp_t)
+                                 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
              sequence->mode = rm_sequence;
              sequence->pos = regexp->pos;
              REGEXP_SEQUENCE (sequence)->regexps_num
@@ -4659,9 +4686,9 @@ transform_3 (regexp_t regexp)
        {
          gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
                      && REGEXP_ALLOF (regexp)->regexps_num > 1);
-         result = create_node (sizeof (struct regexp)
-                               + sizeof (regexp_t)
-                               * (REGEXP_ONEOF (oneof)->regexps_num - 1));
+         result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+                                  + sizeof (regexp_t)
+                                  * (REGEXP_ONEOF (oneof)->regexps_num - 1));
          result->mode = rm_oneof;
          result->pos = regexp->pos;
          REGEXP_ONEOF (result)->regexps_num
@@ -4669,9 +4696,9 @@ transform_3 (regexp_t regexp)
          for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
            {
              allof
-               = create_node (sizeof (struct regexp)
-                               + sizeof (regexp_t)
-                              * (REGEXP_ALLOF (regexp)->regexps_num - 1));
+               = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+                                 + sizeof (regexp_t)
+                                 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
              allof->mode = rm_allof;
              allof->pos = regexp->pos;
              REGEXP_ALLOF (allof)->regexps_num
@@ -4714,8 +4741,8 @@ transform_3 (regexp_t regexp)
        {
          gcc_assert (max_seq_length != 1
                      && REGEXP_ALLOF (regexp)->regexps_num > 1);
-         result = create_node (sizeof (struct regexp)
-                               + sizeof (regexp_t) * (max_seq_length - 1));
+         result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+                                  + sizeof (regexp_t) * (max_seq_length - 1));
          result->mode = rm_sequence;
          result->pos = regexp->pos;
          REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
@@ -4747,14 +4774,14 @@ transform_3 (regexp_t regexp)
                  default:
                    break;
                  }
-             
+
              if (allof_length == 1)
                REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
              else
                {
-                 allof = create_node (sizeof (struct regexp)
-                                      + sizeof (regexp_t)
-                                      * (allof_length - 1));
+                 allof = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
+                                         + sizeof (regexp_t)
+                                         * (allof_length - 1));
                  allof->mode = rm_allof;
                  allof->pos = regexp->pos;
                  REGEXP_ALLOF (allof)->regexps_num = allof_length;
@@ -4883,18 +4910,23 @@ transform_insn_regexps (void)
    about units to automata distribution has been output.  */
 static int annotation_message_reported_p;
 
+/* The vector contains all decls which are automata.  */
+static VEC(decl_t, heap) *automaton_decls;
+
 /* The following structure describes usage of a unit in a reservation.  */
 struct unit_usage
 {
   unit_decl_t unit_decl;
   /* The following forms a list of units used on the same cycle in the
-     same alternative.  */
+     same alternative.  The list is ordered by the correspdoning unit
+     declarations and there is no unit declaration duplication in the
+     list.  */
   struct unit_usage *next;
 };
 typedef struct unit_usage *unit_usage_t;
 
 DEF_VEC_P(unit_usage_t);
-DEF_VEC_ALLOC_P(unit_usage_t,heap);
+DEF_VEC_ALLOC_P(unit_usage_t, heap);
 
 /* Obstack for unit_usage structures.  */
 static struct obstack unit_usages;
@@ -4903,9 +4935,9 @@ static struct obstack unit_usages;
    structures.  There is an element for each combination of
    (alternative number, cycle).  Unit usages on given cycle in
    alternative with given number are referred through element with
-   index equals to the cycle * number of all alternatives in the regexp
-   + the alternative number.  */
-static VEC(unit_usage_t,heap) *cycle_alt_unit_usages;
+   index equals to the cycle * number of all alternatives in the
+   regexp + the alternative number.  */
+static VEC(unit_usage_t, heap) *cycle_alt_unit_usages;
 
 /* The following function creates the structure unit_usage for UNIT on
    CYCLE in REGEXP alternative with ALT_NUM.  The structure is made
@@ -4916,7 +4948,7 @@ store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
 {
   size_t length;
   unit_decl_t unit_decl;
-  unit_usage_t unit_usage_ptr;
+  unit_usage_t unit_usage_ptr, curr, prev;
   int index;
 
   gcc_assert (regexp && regexp->mode == rm_oneof
@@ -4925,33 +4957,100 @@ store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
 
   length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
   while (VEC_length (unit_usage_t, cycle_alt_unit_usages) < length)
-    VEC_safe_push (unit_usage_t,heap, cycle_alt_unit_usages, 0);
-  
+    VEC_safe_push (unit_usage_t, heap, cycle_alt_unit_usages, 0);
+
+  index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
+  prev = NULL;
+  for (curr = VEC_index (unit_usage_t, cycle_alt_unit_usages, index);
+       curr != NULL;
+       prev = curr, curr = curr->next)
+    if (curr->unit_decl >= unit_decl)
+      break;
+  if (curr != NULL && curr->unit_decl == unit_decl)
+    return;
   obstack_blank (&unit_usages, sizeof (struct unit_usage));
   unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages);
   obstack_finish (&unit_usages);
   unit_usage_ptr->unit_decl = unit_decl;
-  index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
-  unit_usage_ptr->next = VEC_index (unit_usage_t, cycle_alt_unit_usages, index);
-  VEC_replace (unit_usage_t, cycle_alt_unit_usages, index, unit_usage_ptr);
   unit_decl->last_distribution_check_cycle = -1; /* undefined */
+  unit_usage_ptr->next = curr;
+  if (prev == NULL)
+    VEC_replace (unit_usage_t, cycle_alt_unit_usages, index, unit_usage_ptr);
+  else
+    prev->next = unit_usage_ptr;
+}
+
+/* Return true if unit UNIT_DECL is present on the LIST.  */
+static bool
+unit_present_on_list_p (unit_usage_t list, unit_decl_t unit_decl)
+{
+  while (list != NULL)
+    {
+      if (list->unit_decl == unit_decl)
+       return true;
+      list = list->next;
+    }
+  return false;
+}
+
+/* The function returns true if reservations of alternatives ALT1 and
+   ALT2 are equal after excluding reservations of units of
+   EXCLUDED_AUTOMATON_DECL.  */
+static bool
+equal_alternatives_p (int alt1, int alt2, int n_alts,
+                     struct automaton_decl *excluded_automaton_decl)
+{
+  int i;
+  unit_usage_t list1, list2;
+
+  for (i = 0;
+       i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages);
+       i += n_alts)
+    {
+      for (list1 = VEC_index (unit_usage_t, cycle_alt_unit_usages, i + alt1),
+            list2 = VEC_index (unit_usage_t, cycle_alt_unit_usages, i + alt2);;
+          list1 = list1->next, list2 = list2->next)
+       {
+         while (list1 != NULL
+                && list1->unit_decl->automaton_decl == excluded_automaton_decl)
+           list1 = list1->next;
+         while (list2 != NULL
+                && list2->unit_decl->automaton_decl == excluded_automaton_decl)
+           list2 = list2->next;
+         if (list1 == NULL || list2 == NULL)
+           {
+             if (list1 != list2)
+               return false;
+             else
+               break;
+           }
+         if (list1->unit_decl != list2->unit_decl)
+           return false;
+       }
+    }
+  return true;
 }
 
+DEF_VEC_I(int);
+DEF_VEC_ALLOC_I(int, heap);
+
 /* The function processes given REGEXP to find units with the wrong
    distribution.  */
 static void
 check_regexp_units_distribution (const char *insn_reserv_name,
                                 regexp_t regexp)
 {
-  int i, j, k, cycle;
+  int i, j, k, cycle, start, n_alts, alt, alt2;
+  bool annotation_reservation_message_reported_p;
   regexp_t seq, allof, unit;
-  struct unit_usage *unit_usage_ptr, *other_unit_usage_ptr;
+  struct unit_usage *unit_usage_ptr;
+  VEC(int, heap) *marked;
 
   if (regexp == NULL || regexp->mode != rm_oneof)
     return;
   /* Store all unit usages in the regexp:  */
   obstack_init (&unit_usages);
-  cycle_alt_unit_usages = 0;
+  cycle_alt_unit_usages = VEC_alloc (unit_usage_t, heap, 10);
 
   for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
     {
@@ -4974,14 +5073,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 ();
                }
@@ -4997,10 +5096,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 ();
                }
@@ -5020,48 +5119,84 @@ check_regexp_units_distribution (const char *insn_reserv_name,
     }
   /* Check distribution:  */
   for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++)
+    for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i);
+        unit_usage_ptr != NULL;
+        unit_usage_ptr = unit_usage_ptr->next)
+      unit_usage_ptr->unit_decl->last_distribution_check_cycle = -1;
+  n_alts = REGEXP_ONEOF (regexp)->regexps_num;
+  marked = VEC_alloc (int, heap, n_alts);
+  for (i = 0; i < n_alts; i++)
+    VEC_safe_push (int, heap, marked, 0);
+  annotation_reservation_message_reported_p = false;
+  for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++)
     {
-      cycle = i / REGEXP_ONEOF (regexp)->regexps_num;
+      cycle = i / n_alts;
+      start = cycle * n_alts;
       for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i);
           unit_usage_ptr != NULL;
           unit_usage_ptr = unit_usage_ptr->next)
-       if (cycle != unit_usage_ptr->unit_decl->last_distribution_check_cycle)
-         {
-           unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
-           for (k = cycle * REGEXP_ONEOF (regexp)->regexps_num;
-                k < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages)
-                  && k == cycle * REGEXP_ONEOF (regexp)->regexps_num;
-                k++)
-             {
-               for (other_unit_usage_ptr
-                      = VEC_index (unit_usage_t, cycle_alt_unit_usages, k);
-                    other_unit_usage_ptr != NULL;
-                    other_unit_usage_ptr = other_unit_usage_ptr->next)
-                 if (unit_usage_ptr->unit_decl->automaton_decl
-                     == other_unit_usage_ptr->unit_decl->automaton_decl)
-                   break;
-               if (other_unit_usage_ptr == NULL
-                   && (VEC_index (unit_usage_t, cycle_alt_unit_usages, k)
-                       != NULL))
-                 break;
-             }
-           if (k < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages)
-               && k == cycle * REGEXP_ONEOF (regexp)->regexps_num)
-             {
-               if (!annotation_message_reported_p)
-                 {
-                   fprintf (stderr, "\n");
-                   error ("The following units do not satisfy units-automata distribution rule");
-                   error (" (A unit of given unit automaton should be on each reserv. altern.)");
-                   annotation_message_reported_p = TRUE;
-                 }
-               error ("Unit %s, reserv. %s, cycle %d",
-                      unit_usage_ptr->unit_decl->name, insn_reserv_name,
-                      cycle);
-             }
-         }
+       {
+         if (unit_usage_ptr->unit_decl->last_distribution_check_cycle == cycle)
+           continue;
+         unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
+         for (alt = 0; alt < n_alts; alt++)
+           if (! unit_present_on_list_p (VEC_index (unit_usage_t,
+                                                    cycle_alt_unit_usages,
+                                                    start + alt),
+                                         unit_usage_ptr->unit_decl))
+             break;
+         if (alt >= n_alts)
+           continue;
+         memset (VEC_address (int, marked), 0, n_alts * sizeof (int));
+         for (alt = 0; alt < n_alts; alt++)
+           {
+             if (! unit_present_on_list_p (VEC_index (unit_usage_t,
+                                                      cycle_alt_unit_usages,
+                                                      start + alt),
+                                           unit_usage_ptr->unit_decl))
+               continue;
+             for (j = 0;
+                  j < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages);
+                  j++)
+               {
+                 alt2 = j % n_alts;
+                 if (! unit_present_on_list_p
+                       (VEC_index (unit_usage_t, cycle_alt_unit_usages,
+                                   start + alt2),
+                        unit_usage_ptr->unit_decl)
+                     && equal_alternatives_p (alt, alt2, n_alts,
+                                              unit_usage_ptr
+                                              ->unit_decl->automaton_decl))
+                   {
+                     VEC_replace (int, marked, alt, 1);
+                     VEC_replace (int, marked, alt2, 1);
+                   }
+               }
+           }
+         for (alt = 0; alt < n_alts && VEC_index (int, marked, alt); alt++)
+           ;
+         if (alt < n_alts && 0)
+           {
+             if (! annotation_message_reported_p)
+               {
+                 fprintf (stderr, "\n");
+                 error ("The following units do not satisfy units-automata distribution rule");
+                 error ("(Unit presence on one alt and its absence on other alt\n");
+                 error (" result in different other automata reservations)");
+                 annotation_message_reported_p = TRUE;
+               }
+             if (! annotation_reservation_message_reported_p)
+               {
+                 error ("Reserv %s:", insn_reserv_name);
+                 annotation_reservation_message_reported_p = true;
+               }
+             error ("  Unit %s, cycle %d, alt %d, another alt %d",
+                    unit_usage_ptr->unit_decl->name, cycle, i % n_alts, alt);
+           }
+       }
     }
-  VEC_free (unit_usage_t,heap, cycle_alt_unit_usages);
+  VEC_free (int, heap, marked);
+  VEC_free (unit_usage_t, heap, cycle_alt_unit_usages);
   obstack_free (&unit_usages, NULL);
 }
 
@@ -5075,15 +5210,26 @@ check_unit_distributions_to_automata (void)
 
   if (progress_flag)
     fprintf (stderr, "Check unit distributions to automata...");
-  annotation_message_reported_p = FALSE;
+  automaton_decls = NULL;
   for (i = 0; i < description->decls_num; i++)
     {
       decl = description->decls [i];
-      if (decl->mode == dm_insn_reserv)
-       check_regexp_units_distribution
-         (DECL_INSN_RESERV (decl)->name,
-          DECL_INSN_RESERV (decl)->transformed_regexp);
+      if (decl->mode == dm_automaton)
+       VEC_safe_push (decl_t, heap, automaton_decls, decl);
     }
+  if (VEC_length (decl_t, automaton_decls) > 1)
+    {
+      annotation_message_reported_p = FALSE;
+      for (i = 0; i < description->decls_num; i++)
+       {
+         decl = description->decls [i];
+         if (decl->mode == dm_insn_reserv)
+           check_regexp_units_distribution
+             (DECL_INSN_RESERV (decl)->name,
+              DECL_INSN_RESERV (decl)->transformed_regexp);
+       }
+    }
+  VEC_free (decl_t, heap, automaton_decls);
   if (progress_flag)
     fprintf (stderr, "done\n");
 }
@@ -5120,7 +5266,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
@@ -5132,7 +5278,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)
@@ -5243,7 +5389,7 @@ form_ainsn_with_same_reservs (automaton_t automaton)
 {
   ainsn_t curr_ainsn;
   size_t i;
-  VEC(ainsn_t,heap) *last_insns = VEC_alloc (ainsn_t,heap, 150);
+  VEC(ainsn_t, heap) *last_insns = VEC_alloc (ainsn_t, heap, 150);
 
   for (curr_ainsn = automaton->ainsn_list;
        curr_ainsn != NULL;
@@ -5275,7 +5421,7 @@ form_ainsn_with_same_reservs (automaton_t automaton)
             curr_ainsn->first_insn_with_same_reservs = 1;
           }
       }
-  VEC_free (ainsn_t,heap, last_insns);
+  VEC_free (ainsn_t, heap, last_insns);
 }
 
 /* Forming unit reservations which can affect creating the automaton
@@ -5319,7 +5465,7 @@ make_automaton (automaton_t automaton)
   state_t state2;
   ainsn_t advance_cycle_ainsn;
   arc_t added_arc;
-  VEC(state_t,heap) *state_stack = VEC_alloc(state_t,heap, 150);
+  VEC(state_t, heap) *state_stack = VEC_alloc(state_t, heap, 150);
   int states_n;
   reserv_sets_t reservs_matter = form_reservs_matter (automaton);
 
@@ -5327,7 +5473,7 @@ make_automaton (automaton_t automaton)
   start_state = insert_state (get_free_state (1, automaton));
   automaton->start_state = start_state;
   start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
-  VEC_safe_push (state_t,heap, state_stack, start_state);
+  VEC_safe_push (state_t, heap, state_stack, start_state);
   states_n = 1;
   while (VEC_length (state_t, state_stack) != 0)
     {
@@ -5356,7 +5502,7 @@ make_automaton (automaton_t automaton)
                           {
                             state2->it_was_placed_in_stack_for_NDFA_forming
                              = 1;
-                            VEC_safe_push (state_t,heap, state_stack, state2);
+                            VEC_safe_push (state_t, heap, state_stack, state2);
                            states_n++;
                            if (progress_flag && states_n % 100 == 0)
                              fprintf (stderr, ".");
@@ -5382,7 +5528,7 @@ make_automaton (automaton_t automaton)
       if (!state2->it_was_placed_in_stack_for_NDFA_forming)
         {
           state2->it_was_placed_in_stack_for_NDFA_forming = 1;
-          VEC_safe_push (state_t,heap, state_stack, state2);
+          VEC_safe_push (state_t, heap, state_stack, state2);
          states_n++;
          if (progress_flag && states_n % 100 == 0)
            fprintf (stderr, ".");
@@ -5390,10 +5536,10 @@ make_automaton (automaton_t automaton)
       gcc_assert (advance_cycle_ainsn);
       add_arc (state, state2, advance_cycle_ainsn);
     }
-  VEC_free (state_t,heap, state_stack);
+  VEC_free (state_t, heap, state_stack);
 }
 
-/* Foms lists of all arcs of STATE marked by the same ainsn.  */
+/* Form lists of all arcs of STATE marked by the same ainsn.  */
 static void
 form_arcs_marked_by_insn (state_t state)
 {
@@ -5423,7 +5569,7 @@ form_arcs_marked_by_insn (state_t state)
 
 static int
 create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
-                      VEC(state_t,heap) **state_stack)
+                      VEC(state_t, heap) **state_stack)
 {
   state_t state;
   alt_state_t alt_state, curr_alt_state;
@@ -5513,7 +5659,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);
+      VEC_safe_push (state_t, heap, *state_stack, state);
     }
   return new_state_p;
 }
@@ -5527,16 +5673,16 @@ NDFA_to_DFA (automaton_t automaton)
   state_t start_state;
   state_t state;
   decl_t decl;
-  VEC(state_t,heap) *state_stack;
+  VEC(state_t, heap) *state_stack;
   int i;
   int states_n;
 
-  state_stack = VEC_alloc (state_t,heap, 0);
+  state_stack = VEC_alloc (state_t, heap, 0);
 
   /* Create the start state (empty state).  */
   start_state = automaton->start_state;
   start_state->it_was_placed_in_stack_for_DFA_forming = 1;
-  VEC_safe_push (state_t,heap, state_stack, start_state);
+  VEC_safe_push (state_t, heap, state_stack, start_state);
   states_n = 1;
   while (VEC_length (state_t, state_stack) != 0)
     {
@@ -5556,7 +5702,7 @@ NDFA_to_DFA (automaton_t automaton)
            }
        }
     }
-  VEC_free (state_t,heap, state_stack);
+  VEC_free (state_t, heap, state_stack);
 }
 
 /* The following variable value is current number (1, 2, ...) of passing
@@ -5598,14 +5744,14 @@ initiate_pass_states (void)
 
 /* The following vla is used for storing pointers to all achieved
    states.  */
-static VEC(state_t,heap) *all_achieved_states;
+static VEC(state_t, heap) *all_achieved_states;
 
 /* This function is called by function pass_states to add an achieved
    STATE.  */
 static void
 add_achieved_state (state_t state)
 {
-  VEC_safe_push (state_t,heap, all_achieved_states, state);
+  VEC_safe_push (state_t, heap, all_achieved_states, state);
 }
 
 /* The function sets up equivalence numbers of insns which mark all
@@ -5668,8 +5814,8 @@ 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 = create_node (sz * sizeof (int));
+
+  state->presence_signature = XCREATENODEVEC (unsigned int, sz);
   for (i = 0; i < description->units_num; i++)
     if (units_array [i]->query_p)
       {
@@ -5744,13 +5890,13 @@ compare_states_for_equiv (const void *state_ptr_1,
    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, heap) *states, VEC (state_t, heap) **classes)
 {
   size_t i;
   state_t prev = 0;
   int class_num = 1;
 
-  *classes = VEC_alloc (state_t,heap, 150);
+  *classes = VEC_alloc (state_t, heap, 150);
   for (i = 0; i < VEC_length (state_t, states); i++)
     {
       state_t state = VEC_index (state_t, states, i);
@@ -5758,7 +5904,7 @@ init_equiv_class (VEC(state_t,heap) *states, VEC (state_t,heap) **classes)
         {
          if (compare_states_for_equiv (&prev, &state) != 0)
            {
-             VEC_safe_push (state_t,heap, *classes, prev);
+             VEC_safe_push (state_t, heap, *classes, prev);
              class_num++;
              prev = NULL;
            }
@@ -5768,17 +5914,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);
+    VEC_safe_push (state_t, heap, *classes, prev);
   return class_num;
 }
 
 /* The function copies pointers to equivalent states from vla FROM
    into vla TO.  */
 static void
-copy_equiv_class (VEC(state_t,heap) **to, VEC(state_t,heap) *from)
+copy_equiv_class (VEC(state_t, heap) **to, VEC(state_t, heap) *from)
 {
-  VEC_free (state_t,heap, *to);
-  *to = VEC_copy (state_t,heap, from);
+  VEC_free (state_t, heap, *to);
+  *to = VEC_copy (state_t, heap, from);
 }
 
 /* The function processes equivalence class given by its first state,
@@ -5790,7 +5936,7 @@ copy_equiv_class (VEC(state_t,heap) **to, VEC(state_t,heap) *from)
    partitioned, the function returns nonzero value.  */
 static int
 partition_equiv_class (state_t first_state, int odd_iteration_flag,
-                      VEC(state_t,heap) **next_iteration_classes,
+                      VEC(state_t, heap) **next_iteration_classes,
                       int *new_equiv_class_num_ptr)
 {
   state_t new_equiv_class;
@@ -5814,7 +5960,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.  */
@@ -5836,7 +5982,7 @@ partition_equiv_class (state_t first_state, int odd_iteration_flag,
          clear_arc_insns_equiv_num (first_state);
        }
       if (new_equiv_class != NULL)
-       VEC_safe_push (state_t,heap, *next_iteration_classes, new_equiv_class);
+       VEC_safe_push (state_t, heap, *next_iteration_classes, new_equiv_class);
       first_state = new_equiv_class;
     }
   return partition_p;
@@ -5845,20 +5991,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)
+                       VEC(state_t, heap) **equiv_classes)
 {
   int new_equiv_class_num;
   int odd_iteration_flag;
   int finish_flag;
-  VEC (state_t,heap) *next_iteration_classes;
+  VEC (state_t, heap) *next_iteration_classes;
   size_t i;
 
-  all_achieved_states = VEC_alloc (state_t,heap, 1500);
+  all_achieved_states = VEC_alloc (state_t, heap, 1500);
   pass_states (automaton, add_achieved_state);
   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);
+  VEC_qsort (state_t, all_achieved_states, compare_states_for_equiv);
 
   odd_iteration_flag = 0;
   new_equiv_class_num = init_equiv_class (all_achieved_states,
@@ -5887,13 +6031,13 @@ evaluate_equiv_classes (automaton_t automaton,
          finish_flag = 0;
     }
   while (!finish_flag);
-  VEC_free (state_t,heap, next_iteration_classes);
-  VEC_free (state_t,heap, all_achieved_states);
+  VEC_free (state_t, heap, next_iteration_classes);
+  VEC_free (state_t, heap, all_achieved_states);
 }
 
 /* The function merges equivalent states of AUTOMATON.  */
 static void
-merge_states (automaton_t automaton, VEC(state_t,heap) *equiv_classes)
+merge_states (automaton_t automaton, VEC(state_t, heap) *equiv_classes)
 {
   state_t curr_state;
   state_t new_state;
@@ -6008,13 +6152,13 @@ set_new_cycle_flags (state_t state)
 static void
 minimize_DFA (automaton_t automaton)
 {
-  VEC(state_t,heap) *equiv_classes = 0;
+  VEC(state_t, heap) *equiv_classes = 0;
 
   evaluate_equiv_classes (automaton, &equiv_classes);
   merge_states (automaton, equiv_classes);
   pass_states (automaton, set_new_cycle_flags);
 
-  VEC_free (state_t,heap, equiv_classes);
+  VEC_free (state_t, heap, equiv_classes);
 }
 
 /* Values of two variables are counted number of states and arcs in an
@@ -6397,7 +6541,7 @@ create_ainsns (void)
       decl = description->decls [i];
       if (decl->mode == dm_insn_reserv)
        {
-         curr_ainsn = create_node (sizeof (struct ainsn));
+         curr_ainsn = XCREATENODE (struct ainsn);
          curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
          curr_ainsn->important_p = FALSE;
          curr_ainsn->next_ainsn = NULL;
@@ -6455,7 +6599,7 @@ create_automata (void)
            curr_automaton_num < automata_num;
            curr_automaton_num++, prev_automaton = curr_automaton)
         {
-         curr_automaton = create_node (sizeof (struct automaton));
+         curr_automaton = XCREATENODE (struct automaton);
          curr_automaton->ainsn_list = create_ainsns ();
          curr_automaton->corresponding_automaton_decl = NULL;
          curr_automaton->next_automaton = NULL;
@@ -6476,7 +6620,7 @@ create_automata (void)
          if (decl->mode == dm_automaton
              && DECL_AUTOMATON (decl)->automaton_is_used)
            {
-             curr_automaton = create_node (sizeof (struct automaton));
+             curr_automaton = XCREATENODE (struct automaton);
              curr_automaton->ainsn_list = create_ainsns ();
              curr_automaton->corresponding_automaton_decl
                = DECL_AUTOMATON (decl);
@@ -6493,7 +6637,7 @@ create_automata (void)
        }
       if (curr_automaton_num == 0)
        {
-         curr_automaton = create_node (sizeof (struct automaton));
+         curr_automaton = XCREATENODE (struct automaton);
          curr_automaton->ainsn_list = create_ainsns ();
          curr_automaton->corresponding_automaton_decl = NULL;
          curr_automaton->next_automaton = NULL;
@@ -6554,11 +6698,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++)
        {
@@ -6584,7 +6728,7 @@ form_regexp (regexp_t regexp)
         }
       obstack_1grow (&irp, ')');
       break;
-      
+
     case rm_oneof:
       for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
        {
@@ -6597,11 +6741,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)
@@ -6949,7 +7093,7 @@ output_translate_vect (automaton_t automaton)
   int insn_value;
   vla_hwint_t translate_vect;
 
-  translate_vect = VEC_alloc (vect_el_t,heap, description->insns_num);
+  translate_vect = VEC_alloc (vect_el_t, heap, description->insns_num);
 
   for (insn_value = 0; insn_value < description->insns_num; insn_value++)
     /* Undefined value */
@@ -6970,7 +7114,7 @@ output_translate_vect (automaton_t automaton)
   fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
   output_vect (translate_vect);
   fprintf (output_file, "};\n\n");
-  VEC_free (vect_el_t,heap, translate_vect);
+  VEC_free (vect_el_t, heap, translate_vect);
 }
 
 /* The value in a table state x ainsn -> something which represents
@@ -6994,19 +7138,19 @@ create_state_ainsn_table (automaton_t automaton)
   int full_vect_length;
   int i;
 
-  tab = create_node (sizeof (struct state_ainsn_table));
+  tab = XCREATENODE (struct state_ainsn_table);
   tab->automaton = automaton;
 
-  tab->comb_vect  = VEC_alloc (vect_el_t,heap, 10000);
-  tab->check_vect = VEC_alloc (vect_el_t,heap, 10000);
+  tab->comb_vect  = VEC_alloc (vect_el_t, heap, 10000);
+  tab->check_vect = VEC_alloc (vect_el_t, heap, 10000);
 
   tab->base_vect  = 0;
-  VEC_safe_grow (vect_el_t,heap, tab->base_vect,
+  VEC_safe_grow (vect_el_t, heap, tab->base_vect,
                 automaton->achieved_states_num);
 
   full_vect_length = (automaton->insn_equiv_classes_num
                       * automaton->achieved_states_num);
-  tab->full_vect  = VEC_alloc (vect_el_t,heap, full_vect_length);
+  tab->full_vect  = VEC_alloc (vect_el_t, heap, full_vect_length);
   for (i = 0; i < full_vect_length; i++)
     VEC_quick_push (vect_el_t, tab->full_vect, undefined_vect_el_value);
 
@@ -7094,7 +7238,7 @@ add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
   {
     size_t full_base = tab->automaton->insn_equiv_classes_num * vect_num;
     if (VEC_length (vect_el_t, tab->full_vect) < full_base + vect_length)
-      VEC_safe_grow (vect_el_t,heap, tab->full_vect,
+      VEC_safe_grow (vect_el_t, heap, tab->full_vect,
                     full_base + vect_length);
     for (i = 0; i < vect_length; i++)
       VEC_replace (vect_el_t, tab->full_vect, full_base + i,
@@ -7194,8 +7338,8 @@ add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
   no_state_value = tab->automaton->achieved_states_num;
   while (additional_els_num > 0)
     {
-      VEC_safe_push (vect_el_t,heap, tab->comb_vect, vect_el);
-      VEC_safe_push (vect_el_t,heap, tab->check_vect, no_state_value);
+      VEC_safe_push (vect_el_t, heap, tab->comb_vect, vect_el);
+      VEC_safe_push (vect_el_t, heap, tab->check_vect, no_state_value);
       additional_els_num--;
     }
   gcc_assert (VEC_length (vect_el_t, tab->comb_vect)
@@ -7278,19 +7422,19 @@ add_vect_el (vla_hwint_t *vect, ainsn_t ainsn, int el_value)
   for (vect_index = VEC_length (vect_el_t, *vect);
        vect_index <= equiv_class_num;
        vect_index++)
-    VEC_safe_push (vect_el_t,heap, *vect, undefined_vect_el_value);
+    VEC_safe_push (vect_el_t, heap, *vect, undefined_vect_el_value);
   VEC_replace (vect_el_t, *vect, equiv_class_num, el_value);
 }
 
 /* This is for forming vector of states of an automaton.  */
-static VEC(state_t,heap) *output_states_vect;
+static VEC(state_t, heap) *output_states_vect;
 
 /* The function is called by function pass_states.  The function adds
    STATE to `output_states_vect'.  */
 static void
 add_states_vect_el (state_t state)
 {
-  VEC_safe_push (state_t,heap, output_states_vect, state);
+  VEC_safe_push (state_t, heap, output_states_vect, state);
 }
 
 /* Form and output vectors (comb, check, base or full vector)
@@ -7308,9 +7452,7 @@ output_trans_table (automaton_t automaton)
      from the state (state with the maximum num is the first).  */
   output_states_vect = 0;
   pass_states (automaton, add_states_vect_el);
-  qsort (VEC_address (state_t, output_states_vect),
-        VEC_length (state_t, output_states_vect),
-         sizeof (state_t), compare_transition_els_num);
+  VEC_qsort (state_t, output_states_vect, compare_transition_els_num);
 
   for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
     {
@@ -7333,74 +7475,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;
+  VEC_free (state_t, heap, output_states_vect);
+  VEC_free (vect_el_t, heap, transition_vect);
 }
 
 /* Form and output vectors representing minimal issue delay table of
@@ -7411,11 +7487,11 @@ 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).  */
@@ -7424,29 +7500,88 @@ output_min_issue_delay_table (automaton_t automaton)
 
   min_issue_delay_len = (VEC_length (state_t, output_states_vect)
                         * automaton->insn_equiv_classes_num);
-  min_issue_delay_vect = VEC_alloc (vect_el_t,heap, min_issue_delay_len);
+  min_issue_delay_vect = VEC_alloc (vect_el_t, heap, min_issue_delay_len);
   for (i = 0; i < min_issue_delay_len; i++)
-    VEC_quick_push (vect_el_t, min_issue_delay_vect, 0);
+    VEC_quick_push (vect_el_t, min_issue_delay_vect, -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 < VEC_length (state_t, output_states_vect);
+           state_no++)
+       {
+         state_t s = VEC_index (state_t, 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 (VEC_index (vect_el_t, min_issue_delay_vect, asn))
+               {
+                 VEC_replace (vect_el_t, min_issue_delay_vect, asn, 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 = VEC_index (vect_el_t, min_issue_delay_vect, n0);
+                 delay1 = VEC_index (vect_el_t, 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)
+                       {
+                         VEC_replace (vect_el_t, 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++)
          {
            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);
+           size_t np = s->order_state_num
+                       * automaton->insn_equiv_classes_num
+                       + ainsn->insn_equiv_class_num;
+           vect_el_t x = VEC_index (vect_el_t, min_issue_delay_vect, np);
+
+           if (automaton->max_min_delay < x)
+             automaton->max_min_delay = x;
+           if (x == -1)
+             VEC_replace (vect_el_t, min_issue_delay_vect, np, 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);
@@ -7466,7 +7601,7 @@ output_min_issue_delay_table (automaton_t automaton)
 
   compressed_min_issue_delay_len = (min_issue_delay_len+cfactor-1) / cfactor;
   compressed_min_issue_delay_vect
-    = VEC_alloc (vect_el_t,heap, compressed_min_issue_delay_len);
+    = VEC_alloc (vect_el_t, heap, compressed_min_issue_delay_len);
 
   for (i = 0; i < compressed_min_issue_delay_len; i++)
     VEC_quick_push (vect_el_t, compressed_min_issue_delay_vect, 0);
@@ -7482,9 +7617,9 @@ output_min_issue_delay_table (automaton_t automaton)
     }
   output_vect (compressed_min_issue_delay_vect);
   fprintf (output_file, "};\n\n");
-  VEC_free (state_t,heap, output_states_vect);
-  VEC_free (vect_el_t,heap, min_issue_delay_vect);
-  VEC_free (vect_el_t,heap, compressed_min_issue_delay_vect);
+  VEC_free (state_t, heap, output_states_vect);
+  VEC_free (vect_el_t, heap, min_issue_delay_vect);
+  VEC_free (vect_el_t, heap, compressed_min_issue_delay_vect);
 }
 
 /* Form and output vector representing the locked states of
@@ -7503,7 +7638,7 @@ output_dead_lock_vect (automaton_t automaton)
   output_states_vect = 0;
   pass_states (automaton, add_states_vect_el);
 
-  VEC_safe_grow (vect_el_t,heap, dead_lock_vect, 
+  VEC_safe_grow (vect_el_t, heap, dead_lock_vect,
                 VEC_length (state_t, output_states_vect));
   for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
     {
@@ -7531,8 +7666,8 @@ output_dead_lock_vect (automaton_t automaton)
   fprintf (output_file, "[] = {\n");
   output_vect (dead_lock_vect);
   fprintf (output_file, "};\n\n");
-  VEC_free (state_t,heap, output_states_vect);
-  VEC_free (vect_el_t,heap, dead_lock_vect);
+  VEC_free (state_t, heap, output_states_vect);
+  VEC_free (vect_el_t, heap, dead_lock_vect);
 }
 
 /* Form and output vector representing reserved units of the states of
@@ -7557,8 +7692,8 @@ output_reserved_units_table (automaton_t automaton)
   reserved_units_size = (VEC_length (state_t, output_states_vect)
                         * state_byte_size);
 
-  reserved_units_table = VEC_alloc (vect_el_t,heap, reserved_units_size);
-                
+  reserved_units_table = VEC_alloc (vect_el_t, heap, reserved_units_size);
+
   for (i = 0; i < reserved_units_size; i++)
     VEC_quick_push (vect_el_t, reserved_units_table, 0);
   for (n = 0; n < VEC_length (state_t, output_states_vect); n++)
@@ -7587,8 +7722,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);
+  VEC_free (state_t, heap, output_states_vect);
+  VEC_free (vect_el_t, heap, reserved_units_table);
 }
 
 /* The function outputs all tables representing DFA(s) used for fast
@@ -7598,7 +7733,6 @@ output_tables (void)
 {
   automaton_t automaton;
 
-  initiate_min_issue_delay_pass_states ();
   for (automaton = description->first_automaton;
        automaton != NULL;
        automaton = automaton->next_automaton)
@@ -7714,12 +7848,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))
@@ -7908,8 +8045,8 @@ dfa_insn_code_enlarge (int uid)\n\
 {\n\
   int i = %s;\n\
   %s = 2 * uid;\n\
-  %s = xrealloc (%s,\n\
-                 %s * sizeof(int));\n\
+  %s = XRESIZEVEC (int, %s,\n\
+                 %s);\n\
   for (; i < %s; i++)\n\
     %s[i] = -1;\n}\n\n",
           DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
@@ -7954,8 +8091,8 @@ output_trans_func (void)
   fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
   output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
                                        INTERNAL_INSN_CODE_NAME, -1);
-  fprintf (output_file, "  return %s (%s, %s);\n}\n\n",
-          INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
+  fprintf (output_file, "  return %s (%s, (struct %s *) %s);\n}\n\n",
+          INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME, STATE_NAME);
 }
 
 /* Output function `min_issue_delay'.  */
@@ -7973,9 +8110,9 @@ output_min_issue_delay_func (void)
           INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
   fprintf (output_file, "    }\n  else\n    %s = %s;\n",
           INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
-  fprintf (output_file, "\n  return %s (%s, %s);\n",
+  fprintf (output_file, "\n  return %s (%s, (struct %s *) %s);\n",
           INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
-          STATE_NAME);
+          CHIP_NAME, STATE_NAME);
   fprintf (output_file, "}\n\n");
 }
 
@@ -8008,8 +8145,8 @@ output_dead_lock_func (void)
 {
   fprintf (output_file, "int\n%s (%s %s)\n",
           DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
-  fprintf (output_file, "{\n  return %s (%s);\n}\n\n",
-          INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
+  fprintf (output_file, "{\n  return %s ((struct %s *) %s);\n}\n\n",
+          INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, STATE_NAME);
 }
 
 /* Output function `internal_reset'.  */
@@ -8036,8 +8173,8 @@ output_reset_func (void)
 {
   fprintf (output_file, "void\n%s (%s %s)\n",
           RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
-  fprintf (output_file, "{\n  %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
-          STATE_NAME);
+  fprintf (output_file, "{\n  %s ((struct %s *) %s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
+          CHIP_NAME, STATE_NAME);
 }
 
 /* Output function `min_insn_conflict_delay'.  */
@@ -8067,13 +8204,13 @@ output_min_insn_conflict_delay_func (void)
   fprintf (output_file, "}\n\n");
 }
 
-/* Output function `internal_insn_latency'.  */
+/* Output the array holding default latency values.  These are used in
+   insn_latency and maximal_insn_latency function implementations.  */
 static void
-output_internal_insn_latency_func (void)
+output_default_latencies (void)
 {
-  decl_t decl;
-  struct bypass_decl *bypass;
   int i, j, col;
+  decl_t decl;
   const char *tabletype = "unsigned char";
 
   /* Find the smallest integer type that can hold all the default
@@ -8089,18 +8226,6 @@ output_internal_insn_latency_func (void)
          tabletype = "int";
       }
 
-  fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
-          INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
-          INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
-          INSN2_PARAMETER_NAME);
-  fprintf (output_file, "{\n");
-
-  if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
-    {
-      fputs ("  return 0;\n}\n\n", output_file);
-      return;
-    }
-
   fprintf (output_file, "  static const %s default_latencies[] =\n    {",
           tabletype);
 
@@ -8117,6 +8242,27 @@ output_internal_insn_latency_func (void)
       }
   gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
   fputs ("\n    };\n", output_file);
+}
+
+/* Output function `internal_insn_latency'.  */
+static void
+output_internal_insn_latency_func (void)
+{
+  int i;
+  decl_t decl;
+  struct bypass_decl *bypass;
+
+  fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
+          INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
+          INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
+          INSN2_PARAMETER_NAME);
+  fprintf (output_file, "{\n");
+
+  if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
+    {
+      fputs ("  return 0;\n}\n\n", output_file);
+      return;
+    }
 
   fprintf (output_file, "  if (%s >= %s || %s >= %s)\n    return 0;\n",
           INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
@@ -8141,19 +8287,32 @@ output_internal_insn_latency_func (void)
                            (advance_cycle_insn_decl)->insn_num));
            fprintf (output_file, "        case %d:\n",
                     bypass->in_insn_reserv->insn_num);
-           if (bypass->bypass_guard_name == NULL)
-             fprintf (output_file, "          return %d;\n",
-                      bypass->latency);
-           else
+           for (;;)
              {
-               fprintf (output_file,
-                        "          if (%s (%s, %s))\n",
-                        bypass->bypass_guard_name, INSN_PARAMETER_NAME,
-                        INSN2_PARAMETER_NAME);
-               fprintf (output_file,
-                        "            return %d;\n          break;\n",
-                        bypass->latency);
+               if (bypass->bypass_guard_name == NULL)
+                 {
+                   gcc_assert (bypass->next == NULL
+                               || (bypass->in_insn_reserv
+                                   != bypass->next->in_insn_reserv));
+                   fprintf (output_file, "          return %d;\n",
+                            bypass->latency);
+                 }
+               else
+                 {
+                   fprintf (output_file,
+                            "          if (%s (%s, %s))\n",
+                            bypass->bypass_guard_name, INSN_PARAMETER_NAME,
+                            INSN2_PARAMETER_NAME);
+                   fprintf (output_file, "            return %d;\n",
+                            bypass->latency);
+                 }
+               if (bypass->next == NULL
+                   || bypass->in_insn_reserv != bypass->next->in_insn_reserv)
+                 break;
+               bypass = bypass->next;
              }
+           if (bypass->bypass_guard_name != NULL)
+             fprintf (output_file, "          break;\n");
          }
        fputs ("        }\n      break;\n", output_file);
       }
@@ -8162,6 +8321,50 @@ output_internal_insn_latency_func (void)
           INTERNAL_INSN_CODE_NAME);
 }
 
+/* Output function `internal_maximum_insn_latency'.  */
+static void
+output_internal_maximal_insn_latency_func (void)
+{
+  decl_t decl;
+  struct bypass_decl *bypass;
+  int i;
+  int max;
+
+  fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
+          "internal_maximal_insn_latency", INTERNAL_INSN_CODE_NAME,
+          INSN_PARAMETER_NAME);
+  fprintf (output_file, "{\n");
+
+  if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
+    {
+      fputs ("  return 0;\n}\n\n", output_file);
+      return;
+    }
+
+  fprintf (output_file, "  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
+  for (i = 0; i < description->decls_num; i++)
+    if (description->decls[i]->mode == dm_insn_reserv
+       && DECL_INSN_RESERV (description->decls[i])->bypass_list)
+      {
+       decl = description->decls [i];
+        max = DECL_INSN_RESERV (decl)->default_latency;
+       fprintf (output_file,
+                "    case %d: {",
+                DECL_INSN_RESERV (decl)->insn_num);
+       for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
+            bypass != NULL;
+            bypass = bypass->next)
+         {
+           if (bypass->latency > max)
+              max = bypass->latency;
+         }
+       fprintf (output_file, " return %d; }\n      break;\n", max);
+      }
+
+  fprintf (output_file, "    }\n  return default_latencies[%s];\n}\n\n",
+          INTERNAL_INSN_CODE_NAME);
+}
+
 /* The function outputs PHR interface function `insn_latency'.  */
 static void
 output_insn_latency_func (void)
@@ -8180,6 +8383,21 @@ output_insn_latency_func (void)
           INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
 }
 
+/* The function outputs PHR interface function `maximal_insn_latency'.  */
+static void
+output_maximal_insn_latency_func (void)
+{
+  fprintf (output_file, "int\n%s (rtx %s)\n",
+          "maximal_insn_latency", INSN_PARAMETER_NAME);
+  fprintf (output_file, "{\n  int %s;\n",
+          INTERNAL_INSN_CODE_NAME);
+  output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
+                                       INTERNAL_INSN_CODE_NAME, 0);
+  fprintf (output_file, "  return %s (%s, %s);\n}\n\n",
+          "internal_maximal_insn_latency",
+          INTERNAL_INSN_CODE_NAME, INSN_PARAMETER_NAME);
+}
+
 /* The function outputs PHR interface function `print_reservation'.  */
 static void
 output_print_reservation_func (void)
@@ -8210,7 +8428,7 @@ output_print_reservation_func (void)
        {
          gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num);
          j++;
-         
+
          fprintf (output_file, "\n      \"%s\",",
                   regexp_representation (DECL_INSN_RESERV (decl)->regexp));
          finish_regexp_representation ();
@@ -8284,7 +8502,7 @@ output_get_cpu_unit_code_func (void)
           LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
   fprintf (output_file, "  static struct %s %s [] =\n    {\n",
           NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
-  units = xmalloc (sizeof (unit_decl_t) * description->units_num);
+  units = XNEWVEC (unit_decl_t, description->units_num);
   memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
   qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
   for (i = 0; i < description->units_num; i++)
@@ -8416,7 +8634,7 @@ output_dfa_start_func (void)
   fprintf (output_file,
           "void\n%s (void)\n{\n  %s = get_max_uid ();\n",
           DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
-  fprintf (output_file, "  %s = xmalloc (%s * sizeof (int));\n",
+  fprintf (output_file, "  %s = XNEWVEC (int, %s);\n",
           DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
   fprintf (output_file, "  %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);
 }
@@ -8488,7 +8706,7 @@ output_description (void)
        {
          if (DECL_UNIT (decl)->excl_list != NULL)
            {
-             fprintf (output_description_file, "unit %s exlusion_set: ",
+             fprintf (output_description_file, "unit %s exclusion_set: ",
                       DECL_UNIT (decl)->name);
              output_unit_set_el_list (DECL_UNIT (decl)->excl_list);
              fprintf (output_description_file, "\n");
@@ -8612,7 +8830,7 @@ output_automaton_units (automaton_t automaton)
 
 /* The following variable is used for forming array of all possible cpu unit
    reservations described by the current DFA state.  */
-static VEC(reserv_sets_t,heap) *state_reservs;
+static VEC(reserv_sets_t, heap) *state_reservs;
 
 /* The function forms `state_reservs' for STATE.  */
 static void
@@ -8626,7 +8844,7 @@ add_state_reservs (state_t state)
          curr_alt_state = curr_alt_state->next_sorted_alt_state)
       add_state_reservs (curr_alt_state->state);
   else
-    VEC_safe_push (reserv_sets_t,heap, state_reservs, state->reservs);
+    VEC_safe_push (reserv_sets_t, heap, state_reservs, state->reservs);
 }
 
 /* The function outputs readable representation of all out arcs of
@@ -8720,11 +8938,9 @@ output_state (state_t state)
   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);
+  VEC_qsort (reserv_sets_t, state_reservs, state_reservs_cmp);
   remove_state_duplicate_reservs ();
-  for (i = 1; i < VEC_length (reserv_sets_t, state_reservs); i++)
+  for (i = 0; i < VEC_length (reserv_sets_t, state_reservs); i++)
     {
       fprintf (output_description_file, "    ");
       output_reserv_sets (output_description_file,
@@ -8733,7 +8949,7 @@ output_state (state_t state)
     }
   fprintf (output_description_file, "\n");
   output_state_arcs (state);
-  VEC_free (reserv_sets_t,heap, state_reservs);
+  VEC_free (reserv_sets_t, heap, state_reservs);
 }
 
 /* The following function output readable representation of
@@ -8998,10 +9214,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
                {
@@ -9009,7 +9224,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);
                }
          }
@@ -9018,14 +9233,14 @@ check_automata_insn_issues (void)
 
 /* The following vla is used for storing pointers to all achieved
    states.  */
-static VEC(state_t,heap) *automaton_states;
+static VEC(state_t, heap) *automaton_states;
 
 /* This function is called by function pass_states to add an achieved
    STATE.  */
 static void
 add_automaton_state (state_t state)
 {
-  VEC_safe_push (state_t,heap, automaton_states, state);
+  VEC_safe_push (state_t, heap, automaton_states, state);
 }
 
 /* The following function forms list of important automata (whose
@@ -9064,7 +9279,7 @@ form_important_insn_automata_lists (void)
              }
        }
     }
-  VEC_free (state_t,heap, automaton_states);
+  VEC_free (state_t, heap, automaton_states);
 
   /* Create automata sets for the insns.  */
   for (i = 0; i < description->decls_num; i++)
@@ -9099,9 +9314,10 @@ expand_automata (void)
 {
   int i;
 
-  description = create_node (sizeof (struct description)
-                            /* One entry for cycle advancing insn.  */
-                            + sizeof (decl_t) * VEC_length (decl_t, decls));
+  description = XCREATENODEVAR (struct description,
+                               sizeof (struct description)
+                               /* One entry for cycle advancing insn.  */
+                               + sizeof (decl_t) * VEC_length (decl_t, decls));
   description->decls_num = VEC_length (decl_t, decls);
   description->query_units_num = 0;
   for (i = 0; i < description->decls_num; i++)
@@ -9169,8 +9385,11 @@ write_automata (void)
   output_internal_reset_func ();
   output_reset_func ();
   output_min_insn_conflict_delay_func ();
+  output_default_latencies ();
   output_internal_insn_latency_func ();
   output_insn_latency_func ();
+  output_internal_maximal_insn_latency_func ();
+  output_maximal_insn_latency_func ();
   output_print_reservation_func ();
   /* Output function get_cpu_unit_code.  */
   fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
@@ -9243,7 +9462,7 @@ main (int argc, char **argv)
 
   progname = "genautomata";
 
-  if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
+  if (!init_rtx_reader_args (argc, argv))
     return (FATAL_EXIT_CODE);
 
   initiate_automaton_gen (argc, argv);
@@ -9314,30 +9533,45 @@ main (int argc, char **argv)
   if (have_error)
     return FATAL_EXIT_CODE;
 
-  puts ("/* Generated automatically by the program `genautomata'\n"
-       "   from the machine description file `md'.  */\n\n"
-       "#include \"config.h\"\n"
-       "#include \"system.h\"\n"
-       "#include \"coretypes.h\"\n"
-       "#include \"tm.h\"\n"
-       "#include \"rtl.h\"\n"
-       "#include \"tm_p.h\"\n"
-       "#include \"insn-config.h\"\n"
-       "#include \"recog.h\"\n"
-       "#include \"regs.h\"\n"
-       "#include \"real.h\"\n"
-       "#include \"output.h\"\n"
-       "#include \"insn-attr.h\"\n"
-       "#include \"toplev.h\"\n"
-       "#include \"flags.h\"\n"
-       "#include \"function.h\"\n");
-
   if (VEC_length (decl_t, decls) > 0)
     {
       expand_automata ();
-      write_automata ();
+      if (!have_error)
+       {
+         puts ("/* Generated automatically by the program `genautomata'\n"
+               "   from the machine description file `md'.  */\n\n"
+               "#include \"config.h\"\n"
+               "#include \"system.h\"\n"
+               "#include \"coretypes.h\"\n"
+               "#include \"tm.h\"\n"
+               "#include \"rtl.h\"\n"
+               "#include \"tm_p.h\"\n"
+               "#include \"insn-config.h\"\n"
+               "#include \"recog.h\"\n"
+               "#include \"regs.h\"\n"
+               "#include \"output.h\"\n"
+               "#include \"insn-attr.h\"\n"
+                "#include \"diagnostic-core.h\"\n"
+               "#include \"flags.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 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
+  return (ferror (stdout) != 0 || have_error
+         ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
 }