GCC's bacl-end & assemble emission (25)

9.5.8. Automata generation

The most important data generated by new style pipeline hazards recognizer is the deterministic finite state automaton. It now will be generated from data collected in above sections.

 

expand_automata (continued)

 

9837   if (!have_error )

9838   {

9839     transform_insn_regexps ();

9840     check_unit_distributions_to_automata ();

9841   }

9842   if (!have_error )

9843   {

9844     generate ();

9845     check_automata_insn_issues ();

9846   }

9.5.8.1.    Transform units usage expression

First, in the unit usage expression of define_insn_reservation, it tries to find out any alternatives, and if there is any, the expression will be transformed into the form as: A|B|C|… (that is “|” goes outmost). So when really building automaton, it can easily find out the nondeterministic parts.

 

5268 static void

5269 transform_insn_regexps (void)                                                            in genautomata.c

5270 {

5271   decl_t decl;

5272   int i;

5273

5274   transform_time = create_ticker ();

5275   add_advance_cycle_insn_decl ();

5276   if (progress_flag )

5277     fprintf (stderr , "Reservation transformation...");

5278   for (i = 0; i < description ->decls_num; i++)

5279   {

5280     decl = description ->decls [i];

5281     if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl )

5282       DECL_INSN_RESERV (decl)->transformed_regexp

5283            = transform_regexp (copy_insn_regexp

5284                                        (DECL_INSN_RESERV (decl)->regexp));

5285   }

5286   if (progress_flag )

5287     fprintf (stderr , "done/n");

5288   ticker_off (&transform_time );

5289 }

 

In the automaton under built, the states are discriminated by available resource in all CPU cycles (in other words the states describe resource occupation in every cycle). The state transition is driven by instruction issue or CPU cycle advancing. To denote the cycle advancing, we need a pseudo insn, that is why add_advance_cycle_insn_decl here. It adds advance_cycle_insn_decl in the instruction set.

 

3511 static decl_t advance_cycle_insn_decl ;

3512 static void

3513 add_advance_cycle_insn_decl (void)                                                    in genautomata.c

3514 {

3515   advance_cycle_insn_decl = create_node (sizeof (struct decl));

3516   advance_cycle_insn_decl ->mode = dm_insn_reserv;

3517   advance_cycle_insn_decl ->pos = no_pos;

3518   DECL_INSN_RESERV (advance_cycle_insn_decl )->regexp = NULL;

3519   DECL_INSN_RESERV (advance_cycle_insn_decl )->name = (char *) "$advance_cycle";

3520   DECL_INSN_RESERV (advance_cycle_insn_decl )->insn_num

3521     = description ->insns_num;

3522   description ->decls [description ->decls_num] = advance_cycle_insn_decl ;

3523   description ->decls_num++;

3524   description ->insns_num++;

3525   num_dfa_decls++;

3526 }

 

After creating the pseudo insn, we can transform the regexp now. The transformation will strip extra parethensis and regroup elements to make alternatives explicitly if presenting.

 

5252 static regexp_t

5253 transform_regexp (regexp_t regexp)                                                     in genautomata.c

5254 {

5255   regexp = regexp_transform_func (regexp, transform_1 );

5256   do

5257   {

5258     regexp_transformed_p = 0;

5259     regexp = regexp_transform_func (regexp, transform_2 );

5260     regexp = regexp_transform_func (regexp, transform_3 );

5261   }

5262   while (regexp_transformed_p );

5263   return regexp;

5264 }

 

The transforming service is provided by regexp_transform_func which recurs into the regexp and does transforming from bottom up.

 

5225 static regexp_t

5226 regexp_transform_func (regexp_t regexp, regexp_t (*func) (regexp_t regexp)) in genautomata.c

5227 {

5228   int i;

5229

5230   if (regexp->mode == rm_sequence)

5231     for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)

5232       REGEXP_SEQUENCE (regexp)->regexps [i]

5233         = regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i], func);

5234   else if (regexp->mode == rm_allof)

5235     for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)

5236       REGEXP_ALLOF (regexp)->regexps [i]

5237         = regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func);

5238   else if (regexp->mode == rm_oneof)

5239     for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)

5240       REGEXP_ONEOF (regexp)->regexps [i]

5241         = regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func);

5242   else if (regexp->mode == rm_repeat)

5243     REGEXP_REPEAT (regexp)->regexp

5244       = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func);

5245   else if (regexp->mode != rm_nothing && regexp->mode != rm_unit)

5246     abort ();

5247   return (*func) (regexp);

5248 }

 

There are 3 ways to transforming regexp . The first method changes form alike: 4 * exp into a sequence of exp of size 4 like: (exp, exp, exp, exp).

 

4850 static regexp_t

4851 transform_1 (regexp_t regexp)                                                            in genautomata.c

4852 {

4853   int i;

4854   int repeat_num;

4855   regexp_t operand;

4856   pos_t pos;

4857

4858   if (regexp->mode == rm_repeat)

4859   {

4860     repeat_num = REGEXP_REPEAT (regexp)->repeat_num;

4861     if (repeat_num <= 1)

4862       abort ();

4863     operand = REGEXP_REPEAT (regexp)->regexp;

4864     pos = regexp->mode;

4865     regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t )

4866                       * (repeat_num - 1));

4867     regexp->mode = rm_sequence;

4868     regexp->pos = pos;

4869     REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num;

4870     for (i = 0; i < repeat_num; i++)

4871       REGEXP_SEQUENCE (regexp)->regexps [i] = copy_insn_regexp (operand);

4872     regexp_transformed_p = 1;

4873   }

4874   return regexp;

4875 }

 

In regrexp , expression (A,B,...) is in form of sequence (‘,’ standing for the advancing cycle), (A+B+...) in form allof (‘+’ standing for all presenting of the units), and (A|B|...) form of oneof (‘|’ standing for either presenting of the units). transform_2 will makes following transformations.

   ...,(A,B,...),C,..     à ...,A,B,...,C,...

   ...+(A+B+...)+C+... à ...+A+B+...+C+...

   ...|(A|B|...)|C|...     à ...|A|B|...|C|...

To understand transform_2 , keep in mind that this function works on regexp from bottom up as invoked within regexp_transform_func .

 

4881 static regexp_t

4882 transform_2 (regexp_t regexp)                                                            in genautomata.c

4883 {

4884   if (regexp->mode == rm_sequence)

4885   {

4886     regexp_t sequence = NULL;

4887     regexp_t result;

4888     int sequence_index = 0;

4889     int i, j;

4890

4891     for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)

4892       if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_sequence)

4893       {

4894         sequence_index = i;

4895         sequence = REGEXP_SEQUENCE (regexp)->regexps [i];

4896         break ;

4897       }

4898       if (i < REGEXP_SEQUENCE (regexp)->regexps_num)

4899       {

4900         if ( REGEXP_SEQUENCE (sequence)->regexps_num <= 1

4901                 || REGEXP_SEQUENCE (regexp)->regexps_num <= 1)

4902            abort ();

4903         result = create_node (sizeof (struct regexp)

4904                                 + sizeof (regexp_t)

4905                          * (REGEXP_SEQUENCE (regexp)->regexps_num

4906                              + REGEXP_SEQUENCE (sequence)->regexps_num

4907                              - 2));

4908          result->mode = rm_sequence;

4909          result->pos = regexp->pos;

4910          REGEXP_SEQUENCE (result)->regexps_num

4911               = (REGEXP_SEQUENCE (regexp)->regexps_num

4912                + REGEXP_SEQUENCE (sequence)->regexps_num - 1);

4913         for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)

4914           if (i < sequence_index)

4915             REGEXP_SEQUENCE (result)->regexps [i]

4916                = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);

4917           else if (i > sequence_index)

4918             REGEXP_SEQUENCE (result)->regexps

4919                 [i + REGEXP_SEQUENCE (sequence)->regexps_num - 1]

4920                 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);

4921            else

4922             for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)

4923               REGEXP_SEQUENCE (result)->regexps [i + j]

4924                 = copy_insn_regexp (REGEXP_SEQUENCE (sequence)->regexps [j]);

4925         regexp_transformed_p = 1;

4926         regexp = result;

4927       }

4928   }

4929   else if (regexp->mode == rm_allof)

4930   {

4931     regexp_t allof = NULL;

4932     regexp_t result;

4933     int allof_index = 0;

4934     int i, j;

4935

4936     for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)

4937       if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_allof)

4938       {

4939         allof_index = i;

4940         allof = REGEXP_ALLOF (regexp)->regexps [i];

4941         break ;

4942       }

4943       if (i < REGEXP_ALLOF (regexp)->regexps_num)

4944       {

4945         if (REGEXP_ALLOF (allof)->regexps_num <= 1

4946             || REGEXP_ALLOF (regexp)->regexps_num <= 1)

4947            abort ();

4948          result = create_node (sizeof (struct regexp)

4949                                + sizeof (regexp_t)

4950                          * (REGEXP_ALLOF (regexp)->regexps_num

4951                             + REGEXP_ALLOF (allof)->regexps_num - 2));

4952         result->mode = rm_allof;

4953         result->pos = regexp->pos;

4954         REGEXP_ALLOF (result)->regexps_num

4955              = (REGEXP_ALLOF (regexp)->regexps_num

4956                 + REGEXP_ALLOF (allof)->regexps_num - 1);

4957          for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)

4958           if (i < allof_index)

4959             REGEXP_ALLOF (result)->regexps [i]

4960                 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);

4961           else if (i > allof_index)

4962             REGEXP_ALLOF (result)->regexps

4963                [i + REGEXP_ALLOF (allof)->regexps_num - 1]

4964                 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);

4965           else

4966             for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)

4967               REGEXP_ALLOF (result)->regexps [i + j]

4968                   = copy_insn_regexp (REGEXP_ALLOF (allof)->regexps [j]);

4969         regexp_transformed_p = 1;

4970         regexp = result;

4971       }

4972   }

4973   else if (regexp->mode == rm_oneof)

4974   {

4975     regexp_t oneof = NULL;

4976     regexp_t result;

4977     int oneof_index = 0;

4978     int i, j;

4979

4980     for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)

4981       if (REGEXP_ONEOF (regexp)->regexps [i]->mode == rm_oneof)

4982       {

4983         oneof_index = i;

4984         oneof = REGEXP_ONEOF (regexp)->regexps [i];

4985         break ;

4986       }

4987        if (i < REGEXP_ONEOF (regexp)->regexps_num)

4988       {

4989         if (REGEXP_ONEOF (oneof)->regexps_num <= 1

4990             || REGEXP_ONEOF (regexp)->regexps_num <= 1)

4991            abort ();

4992          result = create_node (sizeof (struct regexp)

4993                                 + sizeof (regexp_t )

4994                          * (REGEXP_ONEOF (regexp)->regexps_num

4995                             + REGEXP_ONEOF (oneof)->regexps_num - 2));

4996         result->mode = rm_oneof;

4997         result->pos = regexp->pos;

4998         REGEXP_ONEOF (result)->regexps_num

4999              = (REGEXP_ONEOF (regexp)->regexps_num

5000                 + REGEXP_ONEOF (oneof)->regexps_num - 1);

5001         for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)

5002           if (i < oneof_index)

5003             REGEXP_ONEOF (result)->regexps [i]

5004                 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);

5005           else if (i > oneof_index)

5006              REGEXP_ONEOF (result)->regexps

5007                 [i + REGEXP_ONEOF (oneof)->regexps_num - 1]

5008                 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);

5009           else

5010             for (j = 0; j < REGEXP_ONEOF (oneof)->regexps_num; j++)

5011                 REGEXP_ONEOF (result)->regexps [i + j]

5012                   = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [j]);

5013         regexp_transformed_p = 1;

5014         regexp = result;

5015       }

5016   }

5017   return regexp;

5018 }

 

Then transform_3 will makes following transformations:

   ...,A|B|...,C,...       à (...,A,C,...)|(...,B,C,...)|...

   ...+(A|B|...)+C+...    à (...+A+C+...)|(...+B+C+...)|...

   ...+(A,B,...)+C+...    à (...+A+C+...),B,...

   ...+(A,B,...)+(C,D,...) à (A+C),(B+D),...

Keep in mind that this function works on regexp from bottom up as invoked within regexp_transform_func .

 

5025 static regexp_t

5026 transform_3 (regexp_t regexp)                                                            in genautomata.c

5027 {

5028   if (regexp->mode == rm_sequence)

5029   {

5030     regexp_t oneof = NULL;

5031     int oneof_index = 0;

5032     regexp_t result;

5033     regexp_t sequence;

5034     int i, j;

5035

5036     for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)

5037       if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_oneof)

5038       {

5039          oneof_index = i;

5040         oneof = REGEXP_SEQUENCE (regexp)->regexps [i];

5041         break ;

5042       }

5043       if (i < REGEXP_SEQUENCE (regexp)->regexps_num)

5044       {

5045         if (REGEXP_ONEOF (oneof)->regexps_num <= 1

5046               || REGEXP_SEQUENCE (regexp)->regexps_num <= 1)

5047            abort ();

5048         result = create_node (sizeof (struct regexp)

5049                                + sizeof (regexp_t )

5050                          * (REGEXP_ONEOF (oneof)->regexps_num - 1));

5051         result->mode = rm_oneof;

5052         result->pos = regexp->pos;

5053         REGEXP_ONEOF (result)->regexps_num

5054                    = REGEXP_ONEOF (oneof)->regexps_num;

5055         for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)

5056         {

5057           sequence

5058               = create_node (sizeof (struct regexp)

5059                               + sizeof (regexp_t )

5060                           * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));

5061            sequence->mode = rm_sequence;

5062            sequence->pos = regexp->pos;

5063            REGEXP_SEQUENCE (sequence)->regexps_num

5064                = REGEXP_SEQUENCE (regexp)->regexps_num;

5065            REGEXP_ONEOF (result)->regexps [i] = sequence;

5066           for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)

5067             if (j != oneof_index)

5068               REGEXP_SEQUENCE (sequence)->regexps [j]

5069                 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [j]);

5070             else

5071               REGEXP_SEQUENCE (sequence)->regexps [j]

5072                 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);

5073         }

5074         regexp_transformed_p = 1;

5075         regexp = result;

5076     }

5077   }

5078   else if (regexp->mode == rm_allof)

5079   {

5080     regexp_t oneof = NULL;

5081     regexp_t seq;

5082     int oneof_index = 0;

5083     int max_seq_length, allof_length;

5084     regexp_t result;

5085     regexp_t allof = NULL;

5086     regexp_t allof_op = NULL;

5087     int i, j;

5088

5089     for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)

5090       if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_oneof)

5091       {

5092         oneof_index = i;

5093         oneof = REGEXP_ALLOF (regexp)->regexps [i];

5094         break ;

5095        }

5096       if (i < REGEXP_ALLOF (regexp)->regexps_num)

5097       {

5098         if (REGEXP_ONEOF (oneof)->regexps_num <= 1

5099             || REGEXP_ALLOF (regexp)->regexps_num <= 1)

5100            abort ();

5101          result = create_node (sizeof (struct regexp)

5102                                + sizeof (regexp_t )

5103                          * (REGEXP_ONEOF (oneof)->regexps_num - 1));

5104         result->mode = rm_oneof;

5105         result->pos = regexp->pos;

5106         REGEXP_ONEOF (result)->regexps_num

5107               = REGEXP_ONEOF (oneof)->regexps_num;

5108         for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)

5109         {

5110           allof

5111              = create_node (sizeof (struct regexp)

5112                                 + sizeof (regexp_t )

5113                          * (REGEXP_ALLOF (regexp)->regexps_num - 1));

5114           allof->mode = rm_allof;

5115           allof->pos = regexp->pos;

5116            REGEXP_ALLOF (allof)->regexps_num

5117                 = REGEXP_ALLOF (regexp)->regexps_num;

5118           REGEXP_ONEOF (result)->regexps [i] = allof;

5119           for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)

5120             if (j != oneof_index)

5121               REGEXP_ALLOF (allof)->regexps [j]

5122                 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [j]);

5123             else

5124               REGEXP_ALLOF (allof)->regexps [j]

5125                 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);

5126         }

5127         regexp_transformed_p = 1;

5128         regexp = result;

5129       }

5130       max_seq_length = 0;

5131       if (regexp->mode == rm_allof)

5132         for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)

5133         {

5134           if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_sequence)

5135           {

5136             seq = REGEXP_ALLOF (regexp)->regexps [i];

5137             if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)

5138               max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;

5139           }

5140           else if (REGEXP_ALLOF (regexp)->regexps [i]->mode != rm_unit

5141              && REGEXP_ALLOF (regexp)->regexps [i]->mode != rm_nothing)

5142           {

5143             max_seq_length = 0;

5144             break ;

5145           }

5146         }

5147       if (max_seq_length != 0)

5148       {

5149         if (max_seq_length == 1 || REGEXP_ALLOF (regexp)->regexps_num <= 1)

5150           abort ();

5151         result = create_node (sizeof (struct regexp)

5152                          + sizeof (regexp_t ) * (max_seq_length - 1));

5153         result->mode = rm_sequence;

5154         result->pos = regexp->pos;

5155          REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;

5156         for (i = 0; i < max_seq_length; i++)

5157         {

5158           allof_length = 0;

5159           for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)

5160             if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence

5161                && (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)

5162                        ->regexps [j])->regexps_num)))

5163             {

5164               allof_op

5165                  = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)->regexps [j])

5166                        ->regexps [i]);

5167               allof_length++;

5168             }

5169             else if (i == 0

5170                   && (REGEXP_ALLOF (regexp)->regexps [j]->mode

5171                            == rm_unit

5172                       || (REGEXP_ALLOF (regexp)->regexps [j]->mode

5173                           == rm_nothing)))

5174             {

5175               allof_op = REGEXP_ALLOF (regexp)->regexps [j];

5176                allof_length++;

5177             }

5178             if (allof_length == 1)

5179               REGEXP_SEQUENCE (result)->regexps [i] = allof_op;

5180             else

5181             {

5182               allof = create_node (sizeof (struct regexp)

5183                                  + sizeof (regexp_t)

5184                               * (allof_length - 1));

5185               allof->mode = rm_allof;

5186               allof->pos = regexp->pos;

5187               REGEXP_ALLOF (allof)->regexps_num = allof_length;

5188               REGEXP_SEQUENCE (result)->regexps [i] = allof;

5189               allof_length = 0;

5190               for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)

5191                 if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence

5192                    && (i <

5193                        (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)

5194                          ->regexps [j])->regexps_num)))

5195                 {

5196                   allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)

5197                                 ->regexps [j])

5198                                 ->regexps [i]);

5199                   REGEXP_ALLOF (allof)->regexps [allof_length]

5200                                  = allof_op;

5201                    allof_length++;

5202                 }

5203                 else if (i == 0

5204                     && (REGEXP_ALLOF (regexp)->regexps [j]->mode

5205                           == rm_unit

5206                         || (REGEXP_ALLOF (regexp)->regexps [j]->mode

5207                           == rm_nothing)))

5208                 {

5209                   allof_op = REGEXP_ALLOF (regexp)->regexps [j];

5210                   REGEXP_ALLOF (allof)->regexps [allof_length]

5211                        = allof_op;

5212                   allof_length++;

5213                 }

5214             }

5215         }

5216         regexp_transformed_p = 1;

5217         regexp = result;

5218       }

5219   }

5220   return regexp;

5221 }

 

In transform_regexp , it won’t return until no transformation can be made. Return back to expand_automata , then check_unit_distributions_to_automata will take sanity check. Here the only check to be executed based on the assumption that the units in alternatives must belong to the same automaton for every cycle.

 

5448 static void

5449 check_unit_distributions_to_automata (void)                                         in genautomata.c

5450 {

5451   decl_t decl;

5452   int i;

5453

5454   if (progress_flag )

5455     fprintf (stderr, "Check unit distributions to automata...");

5456   annotation_message_reported_p = FALSE;

5457   for (i = 0; i < description ->decls_num; i++)

5458   {

5459     decl = description ->decls [i];

5460     if (decl->mode == dm_insn_reserv)

5461       check_regexp_units_distribution

5462         (DECL_INSN_RESERV (decl)->name,

5463          DECL_INSN_RESERV (decl)->transformed_regexp);

5464   }

5465   if (progress_flag )

5466     fprintf (stderr, "done/n");

5467 }

 

5353 static void

5354 check_regexp_units_distribution (const char *insn_reserv_name,             in genautomata.c

5355                             regexp_t regexp)

5356 {

5357   int i, j, k, cycle;

5358   regexp_t seq, allof, unit;

5359   struct unit_usage *unit_usage_ptr, *other_unit_usage_ptr;

5360

5361   if (regexp == NULL || regexp->mode != rm_oneof)

5362     return ;

5363   /* Store all unit usages in the regexp:  */

5364   obstack_init (&unit_usages );

5365   VLA_PTR_CREATE (cycle_alt_unit_usages , 100, "unit usages on cycles");

5366   for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)

5367   {

5368     seq = REGEXP_ONEOF (regexp)->regexps [i];

5369     if (seq->mode == rm_sequence)

5370       for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++)

5371        {

5372         allof = REGEXP_SEQUENCE (seq)->regexps [j];

5373         if (allof->mode == rm_allof)

5374           for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)

5375           {

5376             unit = REGEXP_ALLOF (allof)->regexps [k];

5377             if (unit->mode == rm_unit)

5378               store_alt_unit_usage (regexp, unit, j, i);

5379             else if (unit->mode != rm_nothing)

5380               abort ();

5381           }

5382         else if (allof->mode == rm_unit)

5383           store_alt_unit_usage (regexp, allof, j, i);

5384         else if (allof->mode != rm_nothing)

5385           abort ();

5386       }

5387       else if (seq->mode == rm_allof)

5388         for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)

5389         {

5390           unit = REGEXP_ALLOF (seq)->regexps [k];

5391           if (unit->mode == rm_unit)

5392             store_alt_unit_usage (regexp, unit, 0, i);

5393           else if (unit->mode != rm_nothing)

5394             abort ();

5395         }

5396       else if (seq->mode == rm_unit)

5397         store_alt_unit_usage (regexp, seq, 0, i);

5398       else if (seq->mode != rm_nothing)

5399         abort ();

5400   }

5401   /* Check distribution:  */

5402   for (i = 0; i < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages ); i++)

5403   {

5404     cycle = i / REGEXP_ONEOF (regexp)->regexps_num;

5405     for (unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages , i);

5406       unit_usage_ptr != NULL;

5407     unit_usage_ptr = unit_usage_ptr->next)

5408     if (cycle != unit_usage_ptr->unit_decl->last_distribution_check_cycle)

5409     {

5410       unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;

5411       for (k = cycle * REGEXP_ONEOF (regexp)->regexps_num;

5412            k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages)

5413              && k == cycle * REGEXP_ONEOF (regexp)->regexps_num;

5414            k++)

5415       {

5416         for (other_unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages , k);

5417           other_unit_usage_ptr != NULL;

5418         other_unit_usage_ptr = other_unit_usage_ptr->next)

5419         if (unit_usage_ptr->unit_decl->automaton_decl

5420             == other_unit_usage_ptr->unit_decl->automaton_decl)

5421           break ;

5422         if (other_unit_usage_ptr == NULL

5423            && VLA_PTR (cycle_alt_unit_usages , k) != NULL)

5424           break ;

5425       }

5426       if (k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages )

5427          && k == cycle * REGEXP_ONEOF (regexp)->regexps_num)

5428       {

5429         if (!annotation_message_reported_p )

5430         {

5431           fprintf (stderr , "/n");

5432           error ("The following units do not satisfy units-automata distribution rule");

5433           error (" (A unit of given unit automaton should be on each reserv. altern.)");

5434           annotation_message_reported_p = TRUE;

5435         }

5436         error ("Unit %s, reserv. %s, cycle %d",

5437              unit_usage_ptr->unit_decl->name, insn_reserv_name,

5438              cycle);

5439       }

5440      }

5441   }

5442   VLA_PTR_DELETE (cycle_alt_unit_usages );

5443   obstack_free (&unit_usages , NULL);

5444 }

 

In every invocation, check_regexp_units_distribution checks the alternatives of one define_insn_reservation. Let’s see it closely. Assuming that for one define_insn_reservation, we have unit usage expression as:

(A, B+J, C) | (D, E, F) | (G, H, I)

Note that it must be the simiplied form, as it has passed transformation.

In the FOR loop begins at line 5366, the expression is re-organized in cycle_alt_unit_usages as following.

t71

figure 71 : cycle_alt_unit_usages

Then FOR loop at line 5402 makes sure that units in same cycle belong to the same automaton. Notice that FOR loop at line 5405 only checks two adjacent units of same cycle in cycle_alt_unit_usages .

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值