由新式流水线危险识别器生成的最重要的数据是这个确定性有限状态自动机。它现在将被从在上面节中所收集的数据中构建出来。
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 }
首先,在 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 中相邻的单元。