GCC后端及汇编发布(25)

9.5.8. 自动机的生成

由新式流水线危险识别器生成的最重要的数据是这个确定性有限状态自动机。它现在将被从在上面节中所收集的数据中构建出来。

 

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.    转换单元使用表达式

首先,在 define_insn_reservation 的单元使用表达式中,尝试找出任一替代( alternative ),并且如果存在,这个表达式将被转换到形式: A|B|C|… (即“ | ”跑到最外面去了)。那么当真正构建自动机时,可以很容易地找出非确定性的部分。

 

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 }

 

在正在构建的自动机中,其状态是由所有 CPU 周期中可用的资源来确定的(换句话来说,状态描述了在每个周期中所占用的资源)。状态的迁移由指令发布或 CPU 周期的推进来驱动。为了表示周期的推进,我们需要一条伪指令,这就是为什么在这里有 add_advance_cycle_insn_decl 。它把 advance_cycle_insn_decl 加入指令集。

 

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 }

 

在构建了这个伪指令之后,现在我们可以转换 regexp 了。这个转换将剥除额外的括号,并且如果出现替代,重组元素使它变得明显。

 

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 }

 

这个转换的服务由 regexp_transform_func 来提供,它递归进入 regexp ,从底自上进行转换。

 

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 }

 

3 个方式来转换 regexp 。第一个方法把,如:“ 4 * exp ”的形式改变为一个大小为 4 exp 的序列,就像: (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 }

 

regrexp 里,表达式 (A,B,...) sequence 的形式(‘ , ’代表周期的推进), (A+B+...) allof 的形式(‘ + ’代表单元的全体存在),而 (A|B|...) oneof 的形式(‘ | ’代表其中一个单元的存在)。 transform_2 将执行以下的转换。

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

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

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

为了理解 transform_2 ,记住,这个函数正如在 regexp_transform_func 中所调用的那样,从底自上处理 regexp

 

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 }

 

transform_3 将进行以下的转换:

   ...,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),...

记住,这个函数正如在 regexp_transform_func 中所调用的那样,从底自上处理 regexp

 

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 }

 

transform_regexp 里,直到没有转换可以做才退出。返回到 expand_automata ,然后 check_unit_distributions_to_automata 将进行合法性检查。在这里所执行的检查基于,在每个周期,在所有替代中的功能单元都必须属于同一个自动机,这个假定。

 

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 }

 

在每次的调用在, check_regexp_units_distribution 检查一个 define_insn_reservation 的替代。让我们看到更清楚些。假定对于一个 define_insn_reservation ,我们有单元使用表达式:

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

注意到它必须是简化的形式,因为它已经经过了转换。

5366 行开始的 FOR 循环里,这个表达式被如下重组在 cycle_alt_unit_usages 中。

71 cycle_alt_unit_usages

然后在 5402 行的 FOR 循环确定,在相同周期中功能单元属于相同的自动机。注意到在 5405 行的 FOR 循环仅检查,相同周期的,在 cycle_alt_unit_usages 中相邻的单元。

你可能感兴趣的:(GCC后端及汇编发布(25))