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

来源:互联网 发布:vb status() 编辑:程序博客网 时间:2024/05/18 03:23

9.5.8. Automata generation

The most important data generated by new style pipeline hazardsrecognizer is the deterministic finite state automaton. It now will begenerated 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.    Transformunits usage expression

First, in the unit usageexpression 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 caneasily find out the nondeterministic parts.

 

5268 static void

5269 transform_insn_regexps (void)                                                            ingenautomata.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, "Reservationtransformation...");

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 byavailable resource in all CPU cycles (in other words the states describeresource occupation in every cycle). The state transition is driven byinstruction issue or CPU cycle advancing. To denote the cycle advancing, weneed a pseudo insn, that is why add_advance_cycle_insn_decl here. It adds advance_cycle_insn_declin 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 (structdecl));

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 regexpnow. The transformation will strip extra parethensis and regroup elements tomake alternatives explicitly if presenting.

 

5252 static regexp_t

5253 transform_regexp (regexp_tregexp)                                                     ingenautomata.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   returnregexp;

5264}

 

The transforming service is provided by regexp_transform_func whichrecurs into the regexpand 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_tregexp)                                                            ingenautomata.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 (structregexp) + 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   returnregexp;

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 foreither 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 functionworks on regexpfrom bottom up as invoked within regexp_transform_func.

 

4881 static regexp_t

4882 transform_2 (regexp_tregexp)                                                            ingenautomata.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 (structregexp)

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 (structregexp)

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 (structregexp)

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   returnregexp;

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 invokedwithin regexp_transform_func.

 

5025 static regexp_t

5026 transform_3 (regexp_tregexp)                                                            ingenautomata.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 (structregexp)

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 (structregexp)

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     inti, 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 (structregexp)

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 (structregexp)

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 (structregexp)

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   returnregexp;

5221 }

 

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

 

5448 static void

5449 check_unit_distributions_to_automata (void)                                         ingenautomata.c

5450 {

5451   decl_t decl;

5452   int i;

5453

5454   if (progress_flag)

5455     fprintf (stderr, "Check unitdistributions 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_tregexp)

5356 {

5357  int i, j, k, cycle;

5358   regexp_t seq, allof, unit;

5359   structunit_usage *unit_usage_ptr, *other_unit_usage_ptr;

5360

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

5362     return;

5363   /* Store all unitusages 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   /* Checkdistribution:  */

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 donot satisfy units-automata distribution rule");

5433           error (" (A unit of given unitautomaton 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 checksthe alternatives of one define_insn_reservation. Let’s see it closely. Assumingthat 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 passedtransformation.

In the FOR loop begins at line 5366, the expression is re-organizedin cycle_alt_unit_usagesas following.

t71

figure 71:cycle_alt_unit_usages

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

原创粉丝点击