GCC后端及汇编发布(28)
来源:互联网 发布:日本网友评价关口知宏 编辑:程序博客网 时间:2024/05/06 17:43
9.5.8.5. 有限状态自动机的最小化
用来把NDFA转换到DFA的算法不保证生成最小的DFA。因此,需要尝试最小化所产生的自动机。在这里最小化的算法是,首先假定所有的状态都是相同的,然后一个个地访问这些状态,并选出那些与第一个状态不同的状态。把这些状态放入另一个集合中,再次假定它们是相同的。然后重复上述步骤访问这些状态,直到在假定相同的集合中找不出不同的状态。接着合并相同的状态来产生最小自动机。
6357 static void
6358 minimize_DFA (automaton_t automaton) in genautomata.c
6359 {
6360 vla_ptr_t equiv_classes;
6361
6362 VLA_PTR_CREATE (equiv_classes, 1500,"equivalence classes");
6363 evaluate_equiv_classes(automaton, &equiv_classes);
6364 merge_states(automaton, &equiv_classes);
6365 pass_states(automaton, set_new_cycle_flags);
6366 VLA_PTR_DELETE (equiv_classes);
6367 }
在6363行的evaluate_equiv_class,如上面所说的那样,把状态组合为相同的集合。
6201 static void
6202 evaluate_equiv_classes (automaton_t automaton, vla_ptr_t *equiv_classes) in genautomata.c
6203 {
6204 state_t new_equiv_class;
6205 int new_equiv_class_num;
6206 int odd_iteration_flag;
6207 int finish_flag;
6208 vla_ptr_t next_iteration_classes;
6209 state_t*equiv_class_ptr;
6210 state_t *state_ptr;
6211
6212 VLA_PTR_CREATE (all_achieved_states, 1500,"all achieved states");
6213 pass_states(automaton, add_achieved_state);
6214 new_equiv_class = init_equiv_class(VLA_PTR_BEGIN (all_achieved_states),
6215 VLA_PTR_LENGTH(all_achieved_states));
6216 odd_iteration_flag = 0;
6217 new_equiv_class_num = 1;
6218 VLA_PTR_CREATE (next_iteration_classes, 150, "nextiteration classes");
6219 VLA_PTR_ADD (next_iteration_classes,new_equiv_class);
6220 do
6221 {
6222 odd_iteration_flag = !odd_iteration_flag;
6223 finish_flag = 1;
6224 copy_equiv_class(equiv_classes, &next_iteration_classes);
6225 /* Transfer equivnumbers for the next iteration. */
6226 for(state_ptr = VLA_PTR_BEGIN (all_achieved_states);
6227 state_ptr <= (state_t*) VLA_PTR_LAST (all_achieved_states);
6228 state_ptr++)
6229 if (odd_iteration_flag)
6230 (*state_ptr)->equiv_class_num_2 =(*state_ptr)->equiv_class_num_1;
6231 else
6232 (*state_ptr)->equiv_class_num_1 =(*state_ptr)->equiv_class_num_2;
6233 for(equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6234 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6235 equiv_class_ptr++)
6236 if (partition_equiv_class(equiv_class_ptr, odd_iteration_flag,
6237 &next_iteration_classes,
6238 &new_equiv_class_num))
6239 finish_flag = 0;
6240 }
6241 while(!finish_flag);
6242 VLA_PTR_DELETE (next_iteration_classes);
6243 VLA_PTR_DELETE (all_achieved_states);
6244 }
在6213行的pass_states将遍历这个自动机的状态,并通过add_achieved_state把状态加入all_achieved_states。
5998 static void
5999 add_achieved_state (state_tstate) ingenautomata.c
6000 {
6001 VLA_PTR_ADD (all_achieved_states, state);
6002 }
然后在6214行,init_equiv_class通过next_equiv_class_state域,以反序,链接起这些状态。它只是假定所有的状态都是相等的,因为next_equiv_class_state总是应该链接相同的状态。在6131行,result_equiv_class指向pass_states所访问的最后的状态。这个值在6214行被保存在next_iteration_classes里。
6118 static state_t
6119 init_equiv_class (state_t*states, int states_num) ingenautomata.c
6120 {
6121 state_t *state_ptr;
6122 state_tresult_equiv_class;
6123
6124 result_equiv_class = NULL;
6125 for(state_ptr = states; state_ptr < states + states_num; state_ptr++)
6126 {
6127 (*state_ptr)->equiv_class_num_1 = 1;
6128 (*state_ptr)->next_equiv_class_state =result_equiv_class;
6129 result_equiv_class = *state_ptr;
6130 }
6131 returnresult_equiv_class;
6132 }
在6224行,copy_equiv_class从next_iteration_classes拷贝相等状态的集合。
6049 static void
6050 copy_equiv_class (vla_ptr_t *to, const vla_ptr_t *from) in genautomata.c
6051 {
6052 state_t *class_ptr;
6053
6054 VLA_PTR_NULLIFY (*to);
6055 for(class_ptr = VLA_PTR_BEGIN (*from);
6056 class_ptr <= (state_t*) VLA_PTR_LAST (*from);
6057 class_ptr++)
6058 VLA_PTR_ADD (*to, *class_ptr);
6059 }
在evaluate_equiv_classes的6216行,变量odd_iteration_flag显示这是否是奇数次的迭代。这个标记控制equiv_class_num_1与equiv_class_num_2的填充及切换。equiv_class_num_1及equiv_class_num_2用于记录相同状态的数目。这个数目,对于每个相同状态集来说,是唯一的,并且被用作区分相同状态的集合。我们将在后面看到为什么需要这两个变量。
在evaluate_equiv_classes的6236行,partition_equiv_class把初始的假定相同状态的集合分裂为正真相同状态的(多个)集合。
6141 static int
6142 partition_equiv_class (state_t*equiv_class_ptr, int odd_iteration_flag, ingenautomata.c
6143 vla_ptr_t *next_iteration_classes,
6144 int *new_equiv_class_num_ptr)
6145 {
6146 state_tnew_equiv_class;
6147 int partition_p;
6148 state_t first_state;
6149 state_t curr_state;
6150 state_t prev_state;
6151 state_t next_state;
6152 int out_arcs_num;
6153
6154 partition_p = 0;
6155 if (*equiv_class_ptr == NULL)
6156 abort ();
6157 for(first_state = *equiv_class_ptr;
6158 first_state != NULL;
6159 first_state = new_equiv_class)
6160 {
6161 new_equiv_class = NULL;
6162 if (first_state->next_equiv_class_state!= NULL)
6163 {
6164 /* There are more one states in the classequivalence. */
6165 out_arcs_num = set_out_arc_insns_equiv_num(first_state,
6166 odd_iteration_flag);
6167 for(prev_state = first_state,
6168 curr_state =first_state->next_equiv_class_state;
6169 curr_state != NULL;
6170 curr_state = next_state)
6171 {
6172 next_state =curr_state->next_equiv_class_state;
6173 if (state_is_differed(curr_state, first_state, out_arcs_num,
6174 odd_iteration_flag))
6175 {
6176 /* Remove curr state from the classequivalence. */
6177 prev_state->next_equiv_class_state= next_state;
6178 /* Add currstate to the new class equivalence. */
6179 curr_state->next_equiv_class_state= new_equiv_class;
6180 if (new_equiv_class == NULL)
6181 (*new_equiv_class_num_ptr)++;
6182 if (odd_iteration_flag)
6183 curr_state->equiv_class_num_2 =*new_equiv_class_num_ptr;
6184 else
6185 curr_state->equiv_class_num_1 =*new_equiv_class_num_ptr;
6186 new_equiv_class = curr_state;
6187 partition_p = 1;
6188 }
6189 else
6190 prev_state = curr_state;
6191 }
6192 clear_arc_insns_equiv_num(first_state);
6193 }
6194 if (new_equiv_class != NULL)
6195 VLA_PTR_ADD (*next_iteration_classes,new_equiv_class);
6196 }
6197 returnpartition_p;
6198 }
在前面提及的算法中,在假定相同状态的集合中,其它状态将与第一个状态比较,以找出不同的状态。作为一个快速检测,如果两个状态的出口数目不相同,这两个状态可以被认为不相同。在partition_equiv_class的6165行,set_out_arc_insns_equiv_num找出集合中第一个状态的出口的数目。同时这个函数还会设置arc->insn->insn_reserv_decl->equiv_class_num,及arc->insn->insn_reserv_decl->state_alts,以显示已经得到处理arc。注意,这里arc->insn,已经不代表特定指令类别,它的意义仅在这里的处理中得到体现。
6008 static int
6009 set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag) in genautomata.c
6010 {
6011 int state_out_arcs_num;
6012 arc_t arc;
6013
6014 state_out_arcs_num = 0;
6015 for (arc =first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6016 {
6017 if(arc->insn->insn_reserv_decl->equiv_class_num != 0
6018 ||arc->insn->insn_reserv_decl->state_alts != 0)
6019 abort ();
6020 state_out_arcs_num++;
6021 arc->insn->insn_reserv_decl->equiv_class_num
6022 = (odd_iteration_flag
6023 ?arc->to_state->equiv_class_num_1
6024 :arc->to_state->equiv_class_num_2);
6025 arc->insn->insn_reserv_decl->state_alts= arc->state_alts;
6026 if(arc->insn->insn_reserv_decl->equiv_class_num == 0
6027 ||arc->insn->insn_reserv_decl->state_alts <= 0)
6028 abort ();
6029 }
6030 returnstate_out_arcs_num;
6031 }
自动机现在是DFA,因此在6015行的FOR循环中,每个arc必须关联不同的状态。在6021行,我们设置与这个状态关联的,所有arc的equiv_class_num,这将被用作判断状态相等的证据之一。
6082 static int
6083 state_is_differed (state_tstate, state_t another_state, ingenautomata.c
6084 int another_state_out_arcs_num,int odd_iteration_flag)
6085 {
6086 arc_t arc;
6087 int state_out_arcs_num;
6088 int i, presence1_p, presence2_p;
6089
6090 state_out_arcs_num = 0;
6091 for (arc =first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6092 {
6093 state_out_arcs_num++;
6094 if ((odd_iteration_flag
6095 ?arc->to_state->equiv_class_num_1
6096 :arc->to_state->equiv_class_num_2)
6097 !=arc->insn->insn_reserv_decl->equiv_class_num
6098 ||(arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
6099 return 1;
6100 }
6101 if (state_out_arcs_num !=another_state_out_arcs_num)
6102 return 1;
6103 /* Now we are looking at the states with thepoint of view of query
6104 units. */
6105 for (i = 0; i< description->units_num;i++)
6106 if (units_array [i]->query_p)
6107 {
6108 presence1_p = first_cycle_unit_presence(state, i);
6109 presence2_p = first_cycle_unit_presence (another_state,i);
6110 if ((presence1_p && !presence2_p)|| (!presence1_p && presence2_p))
6111 return1;
6112 }
6113 return 0;
6114 }
若state与another_state等效,这意味着:
1) 它们到达相同的目标状态的集合
2) 它们使用相同的功能单元的集合
3) 它们有等效的源状态的集合
state_is_differed确保前两点,而evaluate_equiv_classes中对分解集合的反复迭代,使第三点得到保证。这也是为什么在init_equiv_class中要以倒序排序状态,这样就从最后的目标状态开始,向源状态回溯。
如果状态被判定为不相同,返回到partition_equiv_class之后,所有与first_state不同的状态都放入同一个集合,同时共享同一个equiv_class_num。注意6182到6185行的赋值,在odd_iteration_flag为true时,赋值的是equiv_class_num_2(初始值为2),与上面正好相反(此时,当前使用的是equiv_class_num_1)。
这个集合则又在partition_equiv_class的6175行的FOR循环处理(它在6159行赋予first_state)。这个集合继续依照第一个状态进行分解(注意对set_out_arc_insns_equiv_num的调用),因为在这个过程中odd_iteration_flag维持不变,因此每个不同的集合有递增的equiv_class_num_2(假设使用的是equiv_class_num_1,它也在这个过程中维持不变)。
返回evaluate_equiv_classes,对新增的集合更新equiv_class_num_1或equiv_class_num_2(取决于odd_iteration_flag,用于区分不同的集合)。然后对每个新增的集合再次调用partition_equiv_class进行分解。
这个过程一直重复,直到没有再划分出新的集合为止。
在partition_equiv_class的6192行,当某个等效集被处理之后,应该恢复对应arc的域。使得这个集合与其它部分分离开来(state_is_differed总是在6009行返回1)。
6035 static void
6036 clear_arc_insns_equiv_num (state_t state) in genautomata.c
6037 {
6038 arc_t arc;
6039
6040 for (arc =first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6041 {
6042 arc->insn->insn_reserv_decl->equiv_class_num = 0;
6043 arc->insn->insn_reserv_decl->state_alts= 0;
6044 }
6045 }
在找出等效类别集合后,在minimize_DFA的6364行,我们可以通过merge_states把等效状态合并起来形成最小化的自动机。
6247 static void
6248 merge_states (automaton_tautomaton, vla_ptr_t *equiv_classes) ingenautomata.
6249 {
6250 state_t*equiv_class_ptr;
6251 state_t curr_state;
6252 state_t new_state;
6253 state_tfirst_class_state;
6254 alt_state_talt_states;
6255 alt_state_t alt_state, new_alt_state;
6256 arc_t curr_arc;
6257 arc_t next_arc;
6258
6259 /* Create statescorresponding to equivalence classes containing two
6260 or more states. */
6261 for(equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6262 equiv_class_ptr <= (state_t *)VLA_PTR_LAST (*equiv_classes);
6263 equiv_class_ptr++)
6264 if((*equiv_class_ptr)->next_equiv_class_state != NULL)
6265 {
6266 /* There aremore one states in the class equivalence. */
6267 /* Create new compound state. */
6268 new_state = get_free_state (0,automaton);
6269 alt_states = NULL;
6270 first_class_state = *equiv_class_ptr;
6271 for(curr_state = first_class_state;
6272 curr_state != NULL;
6273 curr_state =curr_state->next_equiv_class_state)
6274 {
6275 curr_state->equiv_class_state =new_state;
6276 if (curr_state->component_states ==NULL)
6277 {
6278 new_alt_state = get_free_alt_state();
6279 new_alt_state->state = curr_state;
6280 new_alt_state->next_alt_state =alt_states;
6281 alt_states = new_alt_state;
6282 }
6283 else
6284 for(alt_state = curr_state->component_states;
6285 alt_state != NULL;
6286 alt_state =alt_state->next_sorted_alt_state)
6287 {
6288 new_alt_state = get_free_alt_state();
6289 new_alt_state->state =alt_state->state;
6290 new_alt_state->next_alt_state =alt_states;
6291 alt_states = new_alt_state;
6292 }
6293 }
6294 /* Its isimportant that alt states were sorted before and
6295 after merging to have the same queryingresults. */
6296 new_state->component_states =uniq_sort_alt_states (alt_states);
6297 }
6298 else
6299 (*equiv_class_ptr)->equiv_class_state= *equiv_class_ptr;
6300 for(equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6301 equiv_class_ptr <= (state_t *)VLA_PTR_LAST (*equiv_classes);
6302 equiv_class_ptr++)
6303 if((*equiv_class_ptr)->next_equiv_class_state != NULL)
6304 {
6305 first_class_state = *equiv_class_ptr;
6306 /* Create newarcs output from the state corresponding to
6307 equiv class. */
6308 for(curr_arc = first_out_arc (first_class_state);
6309 curr_arc != NULL;
6310 curr_arc = next_out_arc (curr_arc))
6311 add_arc(first_class_state->equiv_class_state,
6312 curr_arc->to_state->equiv_class_state,
6313 curr_arc->insn,curr_arc->state_alts);
6314 /* Deleteoutput arcs from states of given class equivalence. */
6315 for(curr_state = first_class_state;
6316 curr_state != NULL;
6317 curr_state =curr_state->next_equiv_class_state)
6318 {
6319 if (automaton->start_state ==curr_state)
6320 automaton->start_state =curr_state->equiv_class_state;
6321 /* Deletethe state and its output arcs. */
6322 for(curr_arc = first_out_arc (curr_state);
6323 curr_arc != NULL;
6324 curr_arc = next_arc)
6325 {
6326 next_arc = next_out_arc (curr_arc);
6327 free_arc (curr_arc);
6328 }
6329 }
6330 }
6331 else
6332 {
6333 /*Change `to_state' of arcs output from the state of given
6334 equivalence class. */
6335 for(curr_arc = first_out_arc (*equiv_class_ptr);
6336 curr_arc != NULL;
6337 curr_arc = next_out_arc (curr_arc))
6338 curr_arc->to_state =curr_arc->to_state->equiv_class_state;
6339 }
6340 }
merge_states与create_composed_state十分类似。在上面6261行的FOR循环中,对于每个等效类别的集合,一个新状态被建立,并且所有属于这个类别的状态被排序并链接入component_states。注意6275到6299行,对于每个状态,其equiv_class_state域被设置为新状态。
接着在6300行的FOR循环里,首先构建用于来/往新状态的arc(由6308行的FOR循环处理,注意到add_arc将不会构建arc如果它已经被构建了),然后把来/往过时状态的arc移除。
在合并后,build_automaton返回到create_automata,enumerate_states找出状态的总数。
6480 static void
6481 enumerate_states (automaton_t automaton) ingenautomata.c
6482 {
6483 curr_state_order_num = 0;
6484 pass_states(automaton, set_order_state_num);
6485 automaton->achieved_states_num = curr_state_order_num;
6486 }
6472 static void
6473 set_order_state_num (state_tstate) ingenautomata.c
6474 {
6475 state->order_state_num = curr_state_order_num;
6476 curr_state_order_num++;
6477 }
我们已经构建了最小化的DFA,所有的等效状态都已经被合并。现在我们需要按等效状态类别来分组指令类别,因为属于同一个等效类别状态的指令类别可以以相同的方式处理。这在create_automata的6893行的set_insn_equiv_classes来完成。
6584 static void
6585 set_insn_equiv_classes (automaton_tautomaton) in genautomata.c
6586 {
6587 ainsn_t ainsn;
6588 ainsn_t first_insn;
6589 ainsn_t curr_insn;
6590 ainsn_t cyclic_insn_list;
6591 ainsn_t insn_with_same_reservs;
6592 int equiv_classes_num;
6593
6594 /* All insns areincluded in one equivalence class. */
6595 cyclic_insn_list = NULL;
6596 for (ainsn =automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6597 if (ainsn->first_insn_with_same_reservs)
6598 cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
6599 cyclic_insn_list);
6600 /* Process insns inorder to make equivalence partition. */
6601 pass_states (automaton, process_state_for_insn_equiv_partition);
6602 /* Enumerate equivclasses. */
6603 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6604 /* Set undefined value. */
6605 ainsn->insn_equiv_class_num = -1;
6606 equiv_classes_num= 0;
6607 for (ainsn = automaton->ainsn_list; ainsn != NULL;ainsn = ainsn->next_ainsn)
6608 if (ainsn->insn_equiv_class_num < 0)
6609 {
6610 first_insn = ainsn;
6611 if(!first_insn->first_insn_with_same_reservs)
6612 abort ();
6613 first_insn->first_ainsn_with_given_equialence_num = 1;
6614 curr_insn = first_insn;
6615 do
6616 {
6617 for(insn_with_same_reservs = curr_insn;
6618 insn_with_same_reservs != NULL;
6619 insn_with_same_reservs
6620 =insn_with_same_reservs->next_same_reservs_insn)
6621 insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
6622 curr_insn =curr_insn->next_equiv_class_insn;
6623 }
6624 while(curr_insn != first_insn);
6625 equiv_classes_num++;
6626 }
6627 automaton->insn_equiv_classes_num =equiv_classes_num;
6628 }
看到在form_ainsn_with_same_reservs中,如果这个ainsn是所有具有相同单元预订对象的第一个,或者这个指令是单独构成一个集合的advance_cycle_insn_decl,设置first_insn_with_same_reservs域。在6598行,insert_ainsn_into_equiv_class把这些指令类别通过next_equiv_class_insn链接在一起。
6495 static ainsn_t
6496 insert_ainsn_into_equiv_class (ainsn_t ainsn, in genautomata.c
6497 ainsn_t cyclic_equiv_class_insn_list)
6498 {
6499 if (cyclic_equiv_class_insn_list == NULL)
6500 ainsn->next_equiv_class_insn = ainsn;
6501 else
6502 {
6503 ainsn->next_equiv_class_insn
6504 =cyclic_equiv_class_insn_list->next_equiv_class_insn;
6505 cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
6506 }
6507 return ainsn;
6508 }
在这一步,我们得到如下数据结构。图中红色循环链表中的节点代表不同的等效指令类别列表,而蓝色的链表则由是等效的指令类别构成的。
图80:等效类别指令的分组,阶段2
由于next_same_reservs_insn所形成的链表是由form_ainsn_with_same_reservs构建的,此后经由NDFA_to_DFA及minimize_DFA的处理,这个链表已经过时。因此,接下来需要process_state_for_insn_equiv_partition来重新划分等效的指令集。
6562 static void
6563 process_state_for_insn_equiv_partition(state_t state) in genautomata.c
6564 {
6565 arc_t arc;
6566 arc_t *insn_arcs_array;
6567 int i;
6568 vla_ptr_t insn_arcs_vect;
6569
6570 VLA_PTR_CREATE (insn_arcs_vect, 500,"insn arcs vector");
6571 VLA_PTR_EXPAND (insn_arcs_vect, description->insns_num);
6572 insn_arcs_array = VLA_PTR_BEGIN(insn_arcs_vect);
6573 /* Process insns ofthe arcs. */
6574 for (i = 0; i < description->insns_num; i++)
6575 insn_arcs_array [i] = NULL;
6576 for (arc =first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6577 insn_arcs_array[arc->insn->insn_reserv_decl->insn_num] = arc;
6578 for (arc =first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6579 process_insn_equiv_class(arc->insn, insn_arcs_array);
6580 VLA_PTR_DELETE (insn_arcs_vect);
6581 }
记得first_out_arc及next_out_arc都返回从state出发的迁移(由arc代表),并且arc与(source state,target state,insn)对一一对应,检查由上面6597行的process_insn_equiv_class以arc为单位进行。
6531 static void
6532 process_insn_equiv_class (ainsn_t ainsn,arc_t *insn_arcs_array)
6533 {
6534 ainsn_t next_insn;
6535 ainsn_t curr_insn;
6536 ainsn_t cyclic_insn_list;
6537 arc_t arc;
6538
6539 if (insn_arcs_array[ainsn->insn_reserv_decl->insn_num] == NULL)
6540 abort ();
6541 curr_insn = ainsn;
6542 /* New class ofainsns which are not equivalent to given ainsn. */
6543 cyclic_insn_list = NULL;
6544 do
6545 {
6546 next_insn =curr_insn->next_equiv_class_insn;
6547 arc = insn_arcs_array[curr_insn->insn_reserv_decl->insn_num];
6548 if (arc == NULL
6549 || (insn_arcs_array[ainsn->insn_reserv_decl->insn_num]->to_state
6550 != arc->to_state))
6551 {
6552 delete_ainsn_from_equiv_class(curr_insn);
6553 cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
6554 cyclic_insn_list);
6555 }
6556 curr_insn = next_insn;
6557 }
6558 while(curr_insn != ainsn);
6559 }
我们知道使用相同的单元预订是作为等效指令类别的必要条件,因此由minimize_DFA得到的等效指令类别集合,必然不会跨越一条以上在form_ainsn_with_same_reservs中构建的next_same_reservs_insn链表,相反这些链表可能会分解成多个链表。那么在set_insn_equiv_classes中,余下的代码重新设置equiv_classes_num。
图81:等效类别指令的分组,阶段3
- GCC后端及汇编发布(28)
- GCC后端及汇编发布(1)
- GCC后端及汇编发布(2)
- GCC后端及汇编发布(3)
- GCC后端及汇编发布(4)
- GCC后端及汇编发布(5)
- GCC后端及汇编发布(6)
- GCC后端及汇编发布(7)
- GCC后端及汇编发布(8)
- GCC后端及汇编发布(9)
- GCC后端及汇编发布(10)
- GCC后端及汇编发布(11)
- GCC后端及汇编发布(12)
- GCC后端及汇编发布(13)
- GCC后端及汇编发布(14)
- GCC后端及汇编发布(15)
- GCC后端及汇编发布(16)
- GCC后端及汇编发布(17)
- 转贴:向量相似度的计算和向量夹角余旋的关系
- 谁动了我的C盘---vs2010中IntelliTrace调试
- 贪心算法
- 调试是个问题
- 乱
- GCC后端及汇编发布(28)
- Inferior UV mirror long zoom lens to focus the have influence
- GCC's bacl-end & assemble emission (28)
- 【android】android 开发错误点滴积累5月--Asset资源管理
- 全国2010年1月自学考试Java语言程序设计试题(一)
- 一卡通号
- 07.java的反射机制
- 控制台输出CString, Unicode
- 08.ArrayList_HashSet的比较,以及HashSet分析