9.5.9. 其它
从 create_automata 返回,然后是 generate ,接着看 expand_automata 。
expand_automata (continued)
9847 if (!have_error )
9848 {
9849 generate ();
9850 check_automata_insn_issues ();
9851 }
9852 if (!have_error )
9853 {
9854 form_important_insn_automata_lists ();
9855 if (progress_flag )
9856 fprintf (stderr , "Generation of attributes...");
9857 make_internal_dfa_insn_code_attr ();
9858 make_insn_alts_attr ();
9859 make_default_insn_latency_attr ();
9860 make_bypass_attr ();
9861 if (progress_flag )
9862 fprintf (stderr, "done/n");
9863 }
9864 ticker_off (&generation_time );
9865 ticker_off (&all_time );
9866 if (progress_flag )
9867 fprintf (stderr , "All other genattrtab stuff...");
9868 }
在 expand_automata 的 9850 行, check_automata_insn_issues 检查是否存在不会被发布的指令类别,这意味着这个 define_insn_reservation 是错误的。
9687 static void
9688 check_automata_insn_issues (void) in genautomata.c
9689 {
9690 automaton_t automaton;
9691 ainsn_t ainsn, reserv_ainsn;
9692
9693 for (automaton = description ->first_automaton;
9694 automaton != NULL;
9695 automaton = automaton->next_automaton)
9696 {
9697 for (ainsn = automaton->ainsn_list;
9698 ainsn != NULL;
9699 ainsn = ainsn->next_ainsn)
9700 if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
9701 {
9702 for (reserv_ainsn = ainsn;
9703 reserv_ainsn != NULL;
9704 reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
9705 if (automaton->corresponding_automaton_decl != NULL)
9706 {
9707 if (!w_flag )
9708 error ("Automaton `%s': Insn `%s' will never be issued",
9709 automaton->corresponding_automaton_decl->name,
9710 reserv_ainsn->insn_reserv_decl->name);
9711 else
9712 warning
9713 ("Automaton `%s': Insn `%s' will never be issued",
9714 automaton->corresponding_automaton_decl->name,
9715 reserv_ainsn->insn_reserv_decl->name);
9716 }
9717 else
9718 {
9719 if (!w_flag )
9720 error ("Insn `%s' will never be issued",
9721 reserv_ainsn->insn_reserv_decl->name);
9722 else
9723 warning ("Insn `%s' will never be issued",
9724 reserv_ainsn->insn_reserv_decl->name);
9725 }
9726 }
9727 }
9728 }
接着在 expand_automata 的 9854 行, form_important_insn_automata_lists 过滤掉不包含有效状态迁移的自动机。
9744 static void
9745 form_important_insn_automata_lists (void) in genautomata.c
9746 {
9747 automaton_t automaton;
9748 state_t *state_ptr;
9749 decl_t decl;
9750 ainsn_t ainsn;
9751 arc_t arc;
9752 int i;
9753
9754 VLA_PTR_CREATE (automaton_states , 1500,
9755 "automaton states for forming important insn automata sets");
9756 /* Mark important ainsns. */
9757 for (automaton = description ->first_automaton;
9758 automaton != NULL;
9759 automaton = automaton->next_automaton)
9760 {
9761 VLA_PTR_NULLIFY (automaton_states );
9762 pass_states (automaton, add_automaton_state );
9763 for (state_ptr = VLA_PTR_BEGIN (automaton_states );
9764 state_ptr <= ( state_t *) VLA_PTR_LAST (automaton_states );
9765 state_ptr++)
9766 {
9767 for (arc = first_out_arc (*state_ptr);
9768 arc != NULL;
9769 arc = next_out_arc (arc))
9770 if (arc->to_state != *state_ptr)
9771 {
9772 if (!arc->insn->first_insn_with_same_reservs)
9773 abort ();
9774 for (ainsn = arc->insn;
9775 ainsn != NULL;
9776 ainsn = ainsn->next_same_reservs_insn)
9777 ainsn->important_p = TRUE;
9778 }
9779 }
9780 }
9781 VLA_PTR_DELETE (automaton_states );
9782 /* Create automata sets for the insns. */
9783 for (i = 0; i < description ->decls_num; i++)
9784 {
9785 decl = description ->decls [i];
9786 if (decl->mode == dm_insn_reserv)
9787 {
9788 automata_list_start ();
9789 for (automaton = description->first_automaton;
9790 automaton != NULL;
9791 automaton = automaton->next_automaton)
9792 for (ainsn = automaton->ainsn_list;
9793 ainsn != NULL;
9794 ainsn = ainsn->next_ainsn)
9795 if (ainsn->important_p
9796 && ainsn->insn_reserv_decl == DECL_INSN_RESERV (decl))
9797 {
9798 automata_list_add (automaton);
9799 break ;
9800 }
9801 DECL_INSN_RESERV (decl)->important_automata_list
9802 = automata_list_finish ();
9803 }
9804 }
9805 }
上面在 9762 行 , pass_states 从自动机的 start_state 开始通过状态迁移遍历所有的状态 , 并把所遇到的状态放入新创建的缓存 automaton_states 中。
9736 static void
9737 add_automaton_state ( state_t state) in genautomata.c
9738 {
9739 VLA_PTR_ADD (automaton_states, state);
9740 }
在这之后,在 9763 行的 FOR 循环接着访问在 automaton_states 中的状态,如果从这个状态我们可以到达其它状态,我们就认为关联的指令是重要的。通过这个方式,我们过滤出单个迁移构成的封闭的环。
接着在 9783 行的 FOR 循环找出上面找到的包含重要 ainsn 的自动机。最后,这个自动机列表将被保存在 automata_list_table 中,这个表构建在 initiate_automata_lists 中。
然后在 expand_automata 的 9857 行, make_internal_dfa_insn_code_attr 构建一个深度嵌套的条件表达式,它为所有的 define_insn_reservation 返回 insn_num (模式的序列号,在 gen_insn_reserv 中产生),然后通过名字为“ *internal_dfa_insn_code ”的属性保存之。
9474 static void
9475 make_internal_dfa_insn_code_attr (void) in genautomata.c
9476 {
9477 int i, insn_num;
9478 decl_t decl;
9479 rtx condexp;
9480
9481 condexp = rtx_alloc (COND);
9482 XVEC (condexp, 0) = rtvec_alloc ((description ->insns_num - 1) * 2);
9483 XEXP (condexp, 1)
9484 = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl )
9485 ->insn_num + 1);
9486 for (i = insn_num = 0; i < description ->decls_num; i++)
9487 {
9488 decl = description ->decls [i];
9489 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl )
9490 {
9491 XVECEXP (condexp, 0, 2 * insn_num)
9492 = DECL_INSN_RESERV (decl)->condexp;
9493 XVECEXP (condexp, 0, 2 * insn_num + 1)
9494 = make_numeric_value (DECL_INSN_RESERV (decl)->insn_num);
9495 insn_num++;
9496 }
9497 }
9498 if (description ->insns_num != insn_num + 1)
9499 abort ();
9500 make_internal_attr
9501 (attr_printf (sizeof ("*")
9502 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
9503 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
9504 condexp, ATTR_STATIC);
9505 }
在上面的 9482 行, description 的 insns_num 记录了 define_insn_reservation ,包括 advance_cycle_insn_decl 的数目(参考 process_decls 及 add_advance_cycle_insn_decl )。而在 9486 行, decls_num 记录了所有为自动机生成所构建的 decl (参见 expand_automata 的 9818 行,及 add_advance_cycle_insn_decl )。
接着在 expand_automata 的 9853 行, make_insn_alts_attr 构建另一个深度嵌套的条件表达式,它返回特定指令的替代的数目,并通过名为“ *insn_alts ”的属性保存之。
9437 static void
9438 make_insn_alts_attr (void) in genautomata.c
9439 {
9440 int i, insn_num;
9441 decl_t decl;
9442 rtx condexp;
9443
9444 condexp = rtx_alloc (COND);
9445 XVEC (condexp, 0) = rtvec_alloc ((description ->insns_num - 1) * 2);
9446 XEXP (condexp, 1) = make_numeric_value (0);
9447 for (i = insn_num = 0; i < description ->decls_num; i++)
9448 {
9449 decl = description ->decls [i];
9450 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl )
9451 {
9452 XVECEXP (condexp, 0, 2 * insn_num)
9453 = DECL_INSN_RESERV (decl)->condexp;
9454 XVECEXP (condexp, 0, 2 * insn_num + 1)
9455 = make_numeric_value
9456 (DECL_INSN_RESERV (decl)->transformed_regexp->mode != rm_oneof
9457 ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl)
9458 ->transformed_regexp)->regexps_num);
9459 insn_num++;
9460 }
9461 }
9462 if (description ->insns_num != insn_num + 1)
9463 abort ();
9464 make_internal_attr (attr_printf (sizeof ("*")
9465 + strlen (INSN_ALTS_FUNC_NAME) + 1,
9466 "*%s", INSN_ALTS_FUNC_NAME),
9467 condexp, ATTR_NONE);
9468 }
接着在 expand_automata 的 9854 行, make_default_insn_latency_attr 构建了另一个条件表达式,它返回指定指令的 default_latency ,并通过名为“ *insn_default_latency ”的属性保存之。
9511 static void
9512 make_default_insn_latency_attr (void) in genautomata.c
9513 {
9514 int i, insn_num;
9515 decl_t decl;
9516 rtx condexp;
9517
9518 condexp = rtx_alloc (COND);
9519 XVEC (condexp, 0) = rtvec_alloc ((description ->insns_num - 1) * 2);
9520 XEXP (condexp, 1) = make_numeric_value (0);
9521 for (i = insn_num = 0; i < description ->decls_num; i++)
9522 {
9523 decl = description ->decls [i];
9524 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl )
9525 {
9526 XVECEXP (condexp, 0, 2 * insn_num)
9527 = DECL_INSN_RESERV (decl)->condexp;
9528 XVECEXP (condexp, 0, 2 * insn_num + 1)
9529 = make_numeric_value (DECL_INSN_RESERV (decl)->default_latency);
9530 insn_num++;
9531 }
9532 }
9533 if (description ->insns_num != insn_num + 1)
9534 abort ();
9535 make_internal_attr (attr_printf (sizeof ("*")
9536 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
9537 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
9538 condexp, ATTR_NONE);
9539 }
而在 expand_automata 的 9855 行, make_bypass_attr 计算指令列表的数目(参考 process_decls 的 2962 行),如果存在指令类别,构建一个向量,它保存具有 bypass_list 的指令类别中的条件部分,并通过名为“ *bypass_p ”的属性保存之。
9545 static void
9546 make_bypass_attr (void) in genautomata.c
9547 {
9548 int i, bypass_insn;
9549 int bypass_insns_num = 0;
9550 decl_t decl;
9551 rtx result_rtx;
9552
9553 for (i = 0; i < description ->decls_num; i++)
9554 {
9555 decl = description ->decls [i];
9556 if (decl->mode == dm_insn_reserv
9557 && DECL_INSN_RESERV (decl)->condexp != NULL
9558 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9559 bypass_insns_num++;
9560 }
9561 if (bypass_insns_num == 0)
9562 result_rtx = make_numeric_value (0);
9563 else
9564 {
9565 result_rtx = rtx_alloc (COND);
9566 XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
9567 XEXP (result_rtx, 1) = make_numeric_value (0);
9568
9569 for (i = bypass_insn = 0; i < description ->decls_num; i++)
9570 {
9571 decl = description ->decls [i];
9572 if (decl->mode == dm_insn_reserv
9573 && DECL_INSN_RESERV (decl)->condexp != NULL
9574 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9575 {
9576 XVECEXP (result_rtx, 0, 2 * bypass_insn)
9577 = DECL_INSN_RESERV (decl)->condexp;
9578 XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
9579 = make_numeric_value (1);
9580 bypass_insn++;
9581 }
9582 }
9583 }
9584 make_internal_attr (attr_printf (sizeof ("*")
9585 + strlen (BYPASS_P_FUNC_NAME) + 1,
9586 "*%s", BYPASS_P_FUNC_NAME),
9587 result_rtx, ATTR_NONE);
9588 }