GCC's bacl-end & assemble emission (29)

9.5.9. Miscellaneous

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 }

 

你可能感兴趣的:(GCC's bacl-end & assemble emission (29))