Then return from create_automata , then generate , continue with 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 }
At line 9850 in expand_automata , check_automata_insn_issues checks if any instruction class will not be issued, which means the define_insn_reservation is wrong.
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 }
Then at line 9854, in expand_automata , form_important_insn_automata_lists filters out automaton that doesn’t contain meaningful state transition.
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 }
Above at line 9762, pass_states traverses all states via state transition from the start_state of automaton, and put state encountering into new created buffer automaton_states .
9736 static void
9737 add_automaton_state ( state_t state) in genautomata.c
9738 {
9739 VLA_PTR_ADD (automaton_states, state);
9740 }
After that ,at line 9763, the FOR loop then visits states in automaton_states , if from this state we can arrive other state, we think the instruction associated is important. By this way, we can filter out closed loop formed by singled transition.
And the FOR loop at line 9783, finds out the automatons that contain important ainsn found above. Finially, this automata list will be saved in automata_list_table , which is created in initiate_automata_lists .
Next in expand_automata , at line 9857, make_internal_dfa_insn_code_attr generates the first deep conditional expression which returns the insn_num for all define_insn_reservation (the sequence number for the pattern, genereated in gen_insn_reserv ), and saves it by attribute with name “*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 }
Above at line 9482, insns_num of description records the number of define_insn_reservation including advance_cycle_insn_decl (refer to process_decls and add_advance_cycle_insn_decl ). And at line 9486, decls_num records all decls created for automaton generation (refer to line 9818 in expand_automata and add_advance_cycle_insn_decl ).
Following in expand_automata , at line 9853, make_insn_alts_attr creates a deep conditional expression which returns number of alternatives for certain instruction, and saves it by attribute with name “*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 }
At line 9854 in expand_automata , make_default_insn_latency_attr creates a switch-case alike expression which returns default_latency for certain instruction, and saves it by attribute with name “*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 }
At line 9855 in expand_automata , make_bypass_attr counts the number of instruction classes (refer to line 2962, process_decls ), and if there is any, creates a vector which records the condition part of instruction classes having bypass_list, and save it by attribute with name “*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 }