This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: two dfa problems


"Vladimir N. Makarov" wrote:

> Richard Henderson wrote:
>
> > Both of these issues show up with -mcpu=ev5, with the patch attached,
> > on the fortran test case also attached.
> >
> > (1) Exponential behaviour in max_issue.
> >
> >     While compiling (iirc) iqtest_, we have 18 instructions ready at
> >     the beginning of the block, which as far as I can see causes us
> >     to try 2**18 alternatives.  Certainly the compiler hangs for
> >     longer than I cared to wait.
> >

Richard, I'll look at this problem tomorrow.  But I think your estimation is
not accurate.

>
> >     I think the algorithm here is wrong, but I don't know how to fix
> >     it exactly.  The hack attached prevents the exponential runaway,
> >     but I think we should not be trying alternatives with instructions
> >     of the same type.  That is, once we've tried an instruction of
> >     type TYPE_IADD at position 0, we should not try a different insn
> >     of type TYPE_IADD there, since it won't help produce a better
> >     sloting.
> >
> > (2) Too many instructions issued per cycle.
> >
> >     The .28.sched2 dump contains for MAIN__
> >
> >          16--> 1144 $29=unspec[$29,0x3e] 10            :ev5_e01
> >          16--> 34   $16=$9                             :ev5_e01
> >          16--> 38   $18=0x18                           :ev5_e01
> >          16--> 40   $19=0x18                           :ev5_e01
> >
> >     which has overcommitted both E0 and E1.  The issue rate is
> >     set to 4 because we can issue to E0,E1,FA,FM in one cycle,
> >     but that is not the case here.  I'm not sure what is going on.
>
> Richard, Thanks for the information.
>
> I've found that a wrong automata is generated.  I'll look at it.  May be the
> problem is in 64bit host.  As I know it was not tested on 64bit host.

   I've found the reason of generation of the wrong automaton.  It is a design
flaw in splitting automata when operator `|' is present.  Nobody used such
operator at least in articles which I read (as "Efficient Instruction
Scheduling for Delayed-load Architectures, S. Kurlander, T. Proebsting, and C.
Fischer. " or "Efficient Instruction Scheduling Using Finite State Automata: V.
Bala and N. Rubin, Proceedings of MICRO-28.").  Therefore I've missed the
problem.

Your ev5 description contains

(define_cpu_unit "ev5_e1,ev5_fm" "ev5_0")
(define_cpu_unit "ev5_e0,ev5_imul" "ev5_1")
(define_reservation "ev5_e01" "ev5_e0|ev5_e1")

(define_insn_reservation "ev5_cmov" 2
  (and (eq_attr "cpu" "ev5")
       (eq_attr "type" "icmov"))
  "ev5_e01")

We have the following reservation in automaton ev5_0

ev5_e1, nothing

Let us look at insn reservation (icmov)

ev5_e0|ev5_e1

For automaton ev5_0, it will be looked as

nothing|ev5_e1

`Nothing' will be chosen for the insn reservation because it is the first
possible alternative.  As the result we have the same reservation again.

ev5_1, nothing

It means that we can issue infinite number of such insns.  To prevent this we
should put ev5_e1 and ev5_e0 in the same automaton.  There is the same problem
with `ev5_fm' and `ev5_fa'.   Putting ev5_fm and ev5_fa in the same automaton
(ev5_0) results in the huge automaton.  The solution is to put them into ev5_e2
(with fdiv).  If such solution were not acceptable, we could remove occurrence
of ev5_fa from fdiv reservations nearby the end of the long reservations.  The
bigger cycle on which the unit is reserved, the bigger the automaton is, and
the less probability of pipeline hazard on such reservation.

  Because It is easy to miss such problem, I've made a patch which generates
error (and reports the units) if the units should be in the same automaton.  In
general, units should be in the same automaton if the units are reserved on the
same cycle of a reservation and not present on all alternatives of the
reservation.  I've committed the patch.  Here the ChangeLog entry is

2002-05-05  Vladimir Makarov  <vmakarov@redhat.com>

        * genautomata.c (form_the_same_automaton_unit_lists_from_regexp,
        process_unit_to_form_the_same_automaton_unit_lists,
        form_the_same_automaton_unit_lists
        check_unit_distributions_to_automata): New prototypes and
        functions.
        (check_automata): Rename it into `check_automata_insn_issues'.
        (unit_decl): New fields `the_same_automaton_unit' and
        `the_same_automaton_message_reported_p'.
        (unit_decl_t): New typedef.
        (the_same_automaton_lists): New gloval variable.
        (unit_regexp, unit_set_el, units_array, units_cmp,
        output_get_cpu_unit_code_func): Use the typedef.
        (evaluate_max_reserv_cycles): Increment
        `description->max_insn_reserv_cycles'.
        (initiate_states): Don't increment `max_cycles_num'.
        (transform_insn_regexps): Move code around transformation of
        regexps from `generate'.
        (generate): Remove call of `transform_insn_regexps'.
        (expand_automata): Call `transform_insn_regexps' and
        `check_unit_distributions_to_automata'.  Check errors before
        `generate'.

        * config/sparc/ultra3.md (us3_a0, us3_a1): Move the units into
        automaton `ultrasparc3_1'.


The patch is in the attachment.  As you see only ultrasparc (of pa, sparc and
sh4) had a minor such problem.  I've fixed it too.

Vlad

Index: genautomata.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genautomata.c,v
retrieving revision 1.6
diff -d -c -p -r1.6 genautomata.c
*** genautomata.c	3 May 2002 21:13:25 -0000	1.6
--- genautomata.c	5 May 2002 16:45:07 -0000
*************** struct automaton;
*** 195,200 ****
--- 195,201 ----
  struct state_ainsn_table;
  
  /* The following typedefs are for brevity.  */
+ typedef struct unit_decl *unit_decl_t;
  typedef struct decl *decl_t;
  typedef struct regexp *regexp_t;
  typedef struct unit_set_el *unit_set_el_t;
*************** static regexp_t regexp_transform_func
*** 355,360 ****
--- 356,367 ----
  static regexp_t transform_regexp            PARAMS ((regexp_t));
  static void transform_insn_regexps          PARAMS ((void));
  
+ static void process_unit_to_form_the_same_automaton_unit_lists
+                                             PARAMS ((regexp_t, regexp_t, int));
+ static void form_the_same_automaton_unit_lists_from_regexp PARAMS ((regexp_t));
+ static void form_the_same_automaton_unit_lists PARAMS ((void));
+ static void check_unit_distributions_to_automata PARAMS ((void));
+ 
  static int process_seq_for_forming_states   PARAMS ((regexp_t, automaton_t,
  						     int));
  static void finish_forming_alt_state        PARAMS ((alt_state_t,
*************** static void make_default_insn_latency_at
*** 507,513 ****
  static void make_bypass_attr                   PARAMS ((void));
  static const char *file_name_suffix            PARAMS ((const char *));
  static const char *base_file_name              PARAMS ((const char *));
! static void check_automata	               PARAMS ((void));
  static void add_automaton_state                PARAMS ((state_t));
  static void form_important_insn_automata_lists PARAMS ((void));
  
--- 514,520 ----
  static void make_bypass_attr                   PARAMS ((void));
  static const char *file_name_suffix            PARAMS ((const char *));
  static const char *base_file_name              PARAMS ((const char *));
! static void check_automata_insn_issues	       PARAMS ((void));
  static void add_automaton_state                PARAMS ((state_t));
  static void form_important_insn_automata_lists PARAMS ((void));
  
*************** struct unit_decl
*** 714,719 ****
--- 721,735 ----
    /* The following field value is nonzero if the unit is used in an
       regexp.  */
    char unit_is_used;
+ 
+   /* The following field value is used to form cyclic lists of units
+      which should be in the same automaton because the unit is
+      reserved not on all alternatives of a regexp on a cycle.  */
+   unit_decl_t the_same_automaton_unit;
+   /* The following field is TRUE if we already reported that the unit
+      is not in the same automaton.  */
+   int the_same_automaton_message_reported_p;
+ 
    /* The following field value is order number (0, 1, ...) of given
       unit.  */
    int unit_num;
*************** struct insn_reserv_decl
*** 847,853 ****
       enters.  */
    int state_alts;
    /* The following member value is the list to automata which can be
!      changed by the insn issue. */
    automata_list_el_t important_automata_list;
    /* The following member is used to process insn once for output.  */
    int processed_p;
--- 863,869 ----
       enters.  */
    int state_alts;
    /* The following member value is the list to automata which can be
!      changed by the insn issue.  */
    automata_list_el_t important_automata_list;
    /* The following member is used to process insn once for output.  */
    int processed_p;
*************** enum regexp_mode
*** 888,894 ****
  struct unit_regexp
  {
    char *name;
!   struct unit_decl *unit_decl;
  };
  
  /* Define_reservation in a reservation.  */
--- 904,910 ----
  struct unit_regexp
  {
    char *name;
!   unit_decl_t unit_decl;
  };
  
  /* Define_reservation in a reservation.  */
*************** struct description
*** 993,999 ****
     presence_list, absence_list.  */
  struct unit_set_el
  {
!   struct unit_decl *unit_decl;
    unit_set_el_t next_unit_set_el;
  };
  
--- 1009,1015 ----
     presence_list, absence_list.  */
  struct unit_set_el
  {
!   unit_decl_t unit_decl;
    unit_set_el_t next_unit_set_el;
  };
  
*************** struct state
*** 1063,1069 ****
  };
  
  /* The following macro is an initial value of member
!    `longest_path_length' of a state. */
  #define UNDEFINED_LONGEST_PATH_LENGTH -1
  
  /* Automaton arc.  */
--- 1079,1085 ----
  };
  
  /* The following macro is an initial value of member
!    `longest_path_length' of a state.  */
  #define UNDEFINED_LONGEST_PATH_LENGTH -1
  
  /* Automaton arc.  */
*************** evaluate_max_reserv_cycles ()
*** 2988,2993 ****
--- 3004,3010 ----
  	  description->max_insn_reserv_cycles = max_insn_cycles_num;
        }
      }
+   description->max_insn_reserv_cycles++;
  }
  
  /* The following function calls functions for checking all
*************** finish_alt_states ()
*** 3317,3323 ****
  
  /* This page contains abstract data `state'.  */
  
! /* Maximal length of reservations in cycles (> 1).  */
  static int max_cycles_num;
  
  /* Number of set elements (see type set_el_t) needed for
--- 3334,3340 ----
  
  /* This page contains abstract data `state'.  */
  
! /* Maximal length of reservations in cycles (>= 1).  */
  static int max_cycles_num;
  
  /* Number of set elements (see type set_el_t) needed for
*************** static int els_in_reservs;
*** 3336,3342 ****
  static vla_ptr_t units_container;
  
  /* The start address of the array.  */
! static struct unit_decl **units_array;
  
  /* Empty reservation of maximal length.  */
  static reserv_sets_t empty_reserv;
--- 3353,3359 ----
  static vla_ptr_t units_container;
  
  /* The start address of the array.  */
! static unit_decl_t *units_array;
  
  /* Empty reservation of maximal length.  */
  static reserv_sets_t empty_reserv;
*************** initiate_states ()
*** 3884,3891 ****
  	units_array [decl->decl.unit.unit_num] = &decl->decl.unit;
      }
    max_cycles_num = description->max_insn_reserv_cycles;
-   if (max_cycles_num == 0)
-     max_cycles_num++;
    els_in_cycle_reserv
      = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
         / (sizeof (set_el_t) * CHAR_BIT));
--- 3901,3906 ----
*************** transform_insn_regexps ()
*** 4781,4786 ****
--- 4796,4805 ----
    decl_t decl;
    int i;
  
+   transform_time = create_ticker ();
+   add_advance_cycle_insn_decl ();
+   fprintf (stderr, "Reservation transformation...");
+   fflush (stderr);
    for (i = 0; i < description->decls_num; i++)
      {
        decl = description->decls [i];
*************** transform_insn_regexps ()
*** 4789,4794 ****
--- 4808,5014 ----
  	  = transform_regexp (copy_insn_regexp
  			      (decl->decl.insn_reserv.regexp));
      }
+   fprintf (stderr, "done\n");
+   ticker_off (&transform_time);
+   fflush (stderr);
+ }
+ 
+ 
+ 
+ /* The following variable is an array indexed by cycle.  Each element
+    contains cyclic list of units which should be in the same cycle.  */
+ static unit_decl_t *the_same_automaton_lists;
+ 
+ /* The function processes all alternative reservations on CYCLE in
+    given REGEXP to check the UNIT is not reserved on the all
+    alternatives.  If it is true, the unit should be in the same
+    automaton with other analogous units reserved on CYCLE in given
+    REGEXP.  */
+ static void
+ process_unit_to_form_the_same_automaton_unit_lists (unit, regexp, cycle)
+      regexp_t unit;
+      regexp_t regexp;
+      int cycle;
+ {
+   int i, k;
+   regexp_t seq, allof;
+   unit_decl_t unit_decl, last;
+ 
+   if (regexp == NULL || regexp->mode != rm_oneof)
+     abort ();
+   unit_decl = unit->regexp.unit.unit_decl;
+   for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
+     {
+       seq = regexp->regexp.oneof.regexps [i];
+       if (seq->mode == rm_sequence)
+ 	{
+ 	  if (cycle >= seq->regexp.sequence.regexps_num)
+ 	    break;
+ 	  allof = seq->regexp.sequence.regexps [cycle];
+ 	  if (allof->mode == rm_allof)
+ 	    {
+ 	      for (k = 0; k < allof->regexp.allof.regexps_num; k++)
+ 		if (allof->regexp.allof.regexps [k]->mode == rm_unit
+ 		    && (allof->regexp.allof.regexps [k]->regexp.unit.unit_decl
+ 			== unit_decl))
+ 		  break;
+ 	      if (k >= allof->regexp.allof.regexps_num)
+ 		break;
+ 	    }
+ 	  else if (allof->mode == rm_unit
+ 		   && allof->regexp.unit.unit_decl != unit_decl)
+ 	    break;
+ 	}
+       else if (cycle != 0)
+ 	break;
+       else if (seq->mode == rm_allof)
+ 	{
+ 	  for (k = 0; k < seq->regexp.allof.regexps_num; k++)
+ 	    if (seq->regexp.allof.regexps [k]->mode == rm_unit
+ 		&& (seq->regexp.allof.regexps [k]->regexp.unit.unit_decl
+ 		    == unit_decl))
+ 	      break;
+ 	  if (k >= seq->regexp.allof.regexps_num)
+ 	    break;
+ 	}
+       else if (seq->mode == rm_unit && seq->regexp.unit.unit_decl != unit_decl)
+ 	break;
+     }
+   if (i >= 0)
+     {
+       if (the_same_automaton_lists [cycle] == NULL)
+ 	the_same_automaton_lists [cycle] = unit_decl;
+       else
+ 	{
+ 	  for (last = the_same_automaton_lists [cycle];;)
+ 	    {
+ 	      if (last == unit_decl)
+ 		return;
+ 	      if (last->the_same_automaton_unit
+ 		  == the_same_automaton_lists [cycle])
+ 		break;
+ 	      last = last->the_same_automaton_unit;
+ 	    }
+ 	  last->the_same_automaton_unit = unit_decl->the_same_automaton_unit;
+ 	  unit_decl->the_same_automaton_unit
+ 	    = the_same_automaton_lists [cycle];
+ 	}
+     }
+ }
+ 
+ /* The function processes given REGEXP to find units which should be
+    in the same automaton.  */
+ static void
+ form_the_same_automaton_unit_lists_from_regexp (regexp)
+      regexp_t regexp;
+ {
+   int i, j, k;
+   regexp_t seq, allof, unit;
+ 
+   if (regexp == NULL || regexp->mode != rm_oneof)
+     return;
+   for (i = 0; i < description->max_insn_reserv_cycles; i++)
+     the_same_automaton_lists [i] = NULL;
+   for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
+     {
+       seq = regexp->regexp.oneof.regexps [i];
+       if (seq->mode == rm_sequence)
+ 	for (j = 0; j < seq->regexp.sequence.regexps_num; j++)
+ 	  {
+ 	    allof = seq->regexp.sequence.regexps [j];
+ 	    if (allof->mode == rm_allof)
+ 	      for (k = 0; k < allof->regexp.allof.regexps_num; k++)
+ 		{
+ 		  unit = allof->regexp.allof.regexps [k];
+ 		  if (unit->mode == rm_unit)
+ 		    process_unit_to_form_the_same_automaton_unit_lists
+ 		      (unit, regexp, j);
+ 		  else if (allof->mode != rm_nothing)
+ 		    abort ();
+ 		}
+ 	    else if (allof->mode == rm_unit)
+ 	      process_unit_to_form_the_same_automaton_unit_lists
+ 		(allof, regexp, j);
+ 	    else if (allof->mode != rm_nothing)
+ 	      abort ();
+ 	  }
+       else if (seq->mode == rm_allof)
+ 	for (k = 0; k < seq->regexp.allof.regexps_num; k++)
+ 	  {
+ 	    unit = seq->regexp.allof.regexps [k];
+ 	    if (unit->mode == rm_unit)
+ 	      process_unit_to_form_the_same_automaton_unit_lists
+ 		(unit, regexp, 0);
+ 	    else if (unit->mode != rm_nothing)
+ 	      abort ();
+ 	  }
+       else if (seq->mode == rm_unit)
+ 	process_unit_to_form_the_same_automaton_unit_lists (seq, regexp, 0);
+       else if (seq->mode != rm_nothing)
+ 	abort ();
+     }
+ }
+ 
+ /* The function initializes data to search for units which should be
+    in the same automaton and call function
+    `form_the_same_automaton_unit_lists_from_regexp' for each insn
+    reservation regexp.  */
+ static void
+ form_the_same_automaton_unit_lists ()
+ {
+   decl_t decl;
+   int i;
+ 
+   the_same_automaton_lists
+     = (unit_decl_t *) xmalloc (description->max_insn_reserv_cycles
+ 			       * sizeof (unit_decl_t));
+   for (i = 0; i < description->decls_num; i++)
+     {
+       decl = description->decls [i];
+       if (decl->mode == dm_unit)
+ 	{
+ 	  decl->decl.unit.the_same_automaton_message_reported_p = FALSE;
+ 	  decl->decl.unit.the_same_automaton_unit = &decl->decl.unit;
+ 	}
+     }
+   for (i = 0; i < description->decls_num; i++)
+     {
+       decl = description->decls [i];
+       if (decl->mode == dm_insn_reserv)
+ 	form_the_same_automaton_unit_lists_from_regexp
+ 	  (decl->decl.insn_reserv.transformed_regexp);
+     }
+   free (the_same_automaton_lists);
+ }
+ 
+ /* The function finds units which should be in the same automaton and,
+    if they are not, reports about it.  */
+ static void
+ check_unit_distributions_to_automata ()
+ {
+   decl_t decl;
+   unit_decl_t start_unit_decl, unit_decl;
+   int i;
+ 
+   form_the_same_automaton_unit_lists ();
+   for (i = 0; i < description->decls_num; i++)
+     {
+       decl = description->decls [i];
+       if (decl->mode == dm_unit)
+ 	{
+ 	  start_unit_decl = &decl->decl.unit;
+ 	  if (!start_unit_decl->the_same_automaton_message_reported_p)
+ 	    for (unit_decl = start_unit_decl->the_same_automaton_unit;
+ 		 unit_decl != start_unit_decl;
+ 		 unit_decl = unit_decl->the_same_automaton_unit)
+ 	      if (start_unit_decl->automaton_decl != unit_decl->automaton_decl)
+ 		{
+ 		  error ("Units `%s' and `%s' should be in the same automaton",
+ 			 start_unit_decl->name, unit_decl->name);
+ 		  unit_decl->the_same_automaton_message_reported_p = TRUE;
+ 		}
+ 	}
+     }
  }
  
  
*************** init_equiv_class (states, states_num)
*** 5400,5406 ****
     removing nonequivalent states and placing them in
     *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
     assigns it to the state equivalence number.  If the class has been
!    partitioned, the function returns nonzero value. */
  static int
  partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
  		       next_iteration_classes, new_equiv_class_num_ptr)
--- 5620,5626 ----
     removing nonequivalent states and placing them in
     *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
     assigns it to the state equivalence number.  If the class has been
!    partitioned, the function returns nonzero value.  */
  static int
  partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
  		       next_iteration_classes, new_equiv_class_num_ptr)
*************** longest_path_length (state)
*** 6286,6292 ****
  
    result = 0;
    for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
!     /* Ignore cycles containing one state and `cycle advance' arcs. */
      if (arc->to_state != state
  	&& (arc->insn->insn_reserv_decl
  	    != &advance_cycle_insn_decl->decl.insn_reserv))
--- 6506,6512 ----
  
    result = 0;
    for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
!     /* Ignore cycles containing one state and `cycle advance' arcs.  */
      if (arc->to_state != state
  	&& (arc->insn->insn_reserv_decl
  	    != &advance_cycle_insn_decl->decl.insn_reserv))
*************** longest_path_length (state)
*** 6305,6311 ****
  static int max_dfa_issue_rate;
  
  /* The following function processes the longest path length staring
!    from STATE to find MAX_DFA_ISSUE_RATE. */
  
  static void
  process_state_longest_path_length (state)
--- 6525,6531 ----
  static int max_dfa_issue_rate;
  
  /* The following function processes the longest path length staring
!    from STATE to find MAX_DFA_ISSUE_RATE.  */
  
  static void
  process_state_longest_path_length (state)
*************** output_reserved_units_table_name (f, aut
*** 6592,6598 ****
  /* Name of cache of insn dfa codes.  */
  #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
  
! /* Name of length of cache of insn dfa codes. */
  #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
  
  /* Names of the PHR interface functions: */
--- 6812,6818 ----
  /* Name of cache of insn dfa codes.  */
  #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
  
! /* Name of length of cache of insn dfa codes.  */
  #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
  
  /* Names of the PHR interface functions: */
*************** min_issue_delay_pass_states (state, ains
*** 7128,7134 ****
    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;
--- 7348,7354 ----
    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;
*************** static int
*** 8072,8079 ****
  units_cmp (unit1, unit2)
       const void *unit1, *unit2;
  {
!   const struct unit_decl *u1 = *(struct unit_decl **) unit1;
!   const struct unit_decl *u2 = *(struct unit_decl **) unit2;
  
    return strcmp (u1->name, u2->name);
  }
--- 8292,8299 ----
  units_cmp (unit1, unit2)
       const void *unit1, *unit2;
  {
!   const unit_decl_t u1 = *(unit_decl_t *) unit1;
!   const unit_decl_t u2 = *(unit_decl_t *) unit2;
  
    return strcmp (u1->name, u2->name);
  }
*************** static void
*** 8102,8108 ****
  output_get_cpu_unit_code_func ()
  {
    int i;
!   struct unit_decl **units;
    
    fprintf (output_file, "int\n%s (%s)\n\tconst char *%s;\n",
  	   GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
--- 8322,8328 ----
  output_get_cpu_unit_code_func ()
  {
    int i;
!   unit_decl_t *units;
    
    fprintf (output_file, "int\n%s (%s)\n\tconst char *%s;\n",
  	   GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
*************** output_get_cpu_unit_code_func ()
*** 8113,8124 ****
  	   LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
    fprintf (output_file, "  static struct %s %s [] =\n    {\n",
  	   NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
!   units = (struct unit_decl **) xmalloc (sizeof (struct unit_decl *)
! 					 * description->units_num);
!   memcpy (units, units_array,
! 	  sizeof (struct unit_decl *) * description->units_num);
!   qsort (units, description->units_num,
! 	 sizeof (struct unit_decl *), units_cmp);
    for (i = 0; i < description->units_num; i++)
      if (units [i]->query_p)
        fprintf (output_file, "      {\"%s\", %d},\n",
--- 8333,8342 ----
  	   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 = (unit_decl_t *) xmalloc (sizeof (unit_decl_t)
! 				   * description->units_num);
!   memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
!   qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
    for (i = 0; i < description->units_num; i++)
      if (units [i]->query_p)
        fprintf (output_file, "      {\"%s\", %d},\n",
*************** generate ()
*** 8636,8649 ****
    initiate_excl_sets ();
    initiate_presence_absence_sets ();
    automaton_generation_time = create_ticker ();
-   transform_time = create_ticker ();
-   add_advance_cycle_insn_decl ();
-   fprintf (stderr, "Reservation transformation...");
-   fflush (stderr);
-   transform_insn_regexps ();
-   fprintf (stderr, "done\n");
-   ticker_off (&transform_time);
-   fflush (stderr);
    create_automata ();
    ticker_off (&automaton_generation_time);
  }
--- 8854,8859 ----
*************** initiate_automaton_gen (argc, argv)
*** 8898,8904 ****
  /* The following function checks existence at least one arc marked by
     each insn.  */
  static void
! check_automata ()
  {
    automaton_t automaton;
    ainsn_t ainsn, reserv_ainsn;
--- 9108,9114 ----
  /* The following function checks existence at least one arc marked by
     each insn.  */
  static void
! check_automata_insn_issues ()
  {
    automaton_t automaton;
    ainsn_t ainsn, reserv_ainsn;
*************** form_important_insn_automata_lists ()
*** 8967,8973 ****
  
    VLA_PTR_CREATE (automaton_states, 1500,
  		  "automaton states for forming important insn automata sets");
!   /* Mark important ainsns. */
    for (automaton = description->first_automaton;
         automaton != NULL;
         automaton = automaton->next_automaton)
--- 9177,9183 ----
  
    VLA_PTR_CREATE (automaton_states, 1500,
  		  "automaton states for forming important insn automata sets");
!   /* Mark important ainsns.  */
    for (automaton = description->first_automaton;
         automaton != NULL;
         automaton = automaton->next_automaton)
*************** form_important_insn_automata_lists ()
*** 8993,8999 ****
  	}
      }
    VLA_PTR_DELETE (automaton_states);
!   /* Create automata sets for the insns. */
    for (i = 0; i < description->decls_num; i++)
      {
        decl = description->decls [i];
--- 9203,9209 ----
  	}
      }
    VLA_PTR_DELETE (automaton_states);
!   /* Create automata sets for the insns.  */
    for (i = 0; i < description->decls_num; i++)
      {
        decl = description->decls [i];
*************** expand_automata ()
*** 9049,9067 ****
    generation_time = create_ticker ();
    if (!have_error)
      {
        generate ();
!       check_automata ();
!       if (!have_error)
! 	{
! 	  form_important_insn_automata_lists ();
! 	  fprintf (stderr, "Generation of attributes...");
! 	  fflush (stderr);
! 	  make_internal_dfa_insn_code_attr ();
! 	  make_insn_alts_attr ();
! 	  make_default_insn_latency_attr ();
! 	  make_bypass_attr ();
! 	  fprintf (stderr, "done\n");
! 	}
      }
    ticker_off (&generation_time);
    ticker_off (&all_time);
--- 9259,9282 ----
    generation_time = create_ticker ();
    if (!have_error)
      {
+       transform_insn_regexps ();
+       check_unit_distributions_to_automata ();
+     }
+   if (!have_error)
+     {
        generate ();
!       check_automata_insn_issues ();
!     }
!   if (!have_error)
!     {
!       form_important_insn_automata_lists ();
!       fprintf (stderr, "Generation of attributes...");
!       fflush (stderr);
!       make_internal_dfa_insn_code_attr ();
!       make_insn_alts_attr ();
!       make_default_insn_latency_attr ();
!       make_bypass_attr ();
!       fprintf (stderr, "done\n");
      }
    ticker_off (&generation_time);
    ticker_off (&all_time);
Index: config/sparc/ultra3.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/ultra3.md,v
retrieving revision 1.1
diff -d -c -p -r1.1 ultra3.md
*** config/sparc/ultra3.md	4 May 2002 05:03:45 -0000	1.1
--- config/sparc/ultra3.md	5 May 2002 16:45:07 -0000
***************
*** 26,33 ****
  
  (define_automaton "ultrasparc3_0,ultrasparc3_1")
  
! (define_cpu_unit "us3_a0,us3_a1,us3_ms,us3_br,us3_fpm" "ultrasparc3_0")
! (define_cpu_unit "us3_slot0,us3_slot1,us3_slot2,us3_slot3,us3_fpa" "ultrasparc3_1")
  (define_cpu_unit "us3_load_writeback" "ultrasparc3_1")
  
  (define_reservation "us3_slotany" "(us3_slot0 | us3_slot1 | us3_slot2 | us3_slot3)")
--- 26,34 ----
  
  (define_automaton "ultrasparc3_0,ultrasparc3_1")
  
! (define_cpu_unit "us3_ms,us3_br,us3_fpm" "ultrasparc3_0")
! (define_cpu_unit "us3_a0,us3_a1,us3_slot0,\
!                   us3_slot1,us3_slot2,us3_slot3,us3_fpa" "ultrasparc3_1")
  (define_cpu_unit "us3_load_writeback" "ultrasparc3_1")
  
  (define_reservation "us3_slotany" "(us3_slot0 | us3_slot1 | us3_slot2 | us3_slot3)")

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]