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

来源:互联网 发布:信鸽邮件群发软件 编辑:程序博客网 时间:2024/06/05 06:32

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 ofattributes...");

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 genattrtabstuff...");

9868 }

 

At line 9850 inexpand_automata,check_automata_insn_issueschecks if any instruction class will not be issued, which means thedefine_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 neverbe issued",

9721                    reserv_ainsn->insn_reserv_decl->name);

9722             else

9723               warning ("Insn `%s' willnever be issued",

9724                      reserv_ainsn->insn_reserv_decl->name);

9725           }

9726       }

9727   }

9728 }

 

Then at line 9854, in expand_automata, form_important_insn_automata_listsfilters 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 forforming important insn automata sets");

9756   /* Mark importantainsns.  */

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 automatasets 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_stateof automaton, and put state encountering into new created buffer automaton_states.

 

9736 static void

9737 add_automaton_state (state_tstate)                                                       ingenautomata.c

9738 {

9739   VLA_PTR_ADD (automaton_states, state);

9740 }

 

After that ,at line 9763, the FORloop then visits states in automaton_states, if from this state we canarrive other state, we think the instruction associated is important. By thisway, we can filter out closed loop formed by singled transition.

And the FOR loop at line9783, finds out the automatons that contain important ainsn found above. Finially, thisautomata 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_attrgenerates the first deep conditional expression which returns the insn_num forall define_insn_reservation (the sequence number for the pattern, genereated ingen_insn_reserv), and saves it by attribute with name “*internal_dfa_insn_code”

 

9474 static void

9475 make_internal_dfa_insn_code_attr (void)                                              ingenautomata.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 ofdefine_insn_reservation including advance_cycle_insn_decl (refer to process_decls and add_advance_cycle_insn_decl). Andat line 9486, decls_numrecords 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_attrcreates a deep conditional expression which returns number of alternatives forcertain instruction, and saves it by attribute with name “*insn_alts”.

 

9437 static void

9438 make_insn_alts_attr (void)                                                                  ingenautomata.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 inexpand_automata,make_default_insn_latency_attrcreates a switch-case alike expression which returns default_latency forcertain instruction, and saves it by attribute with name “*insn_default_latency”.

 

9511 static void

9512 make_default_insn_latency_attr (void)                                                 ingenautomata.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 inexpand_automata,make_bypass_attrcounts the number of instruction classes (refer to line 2962, process_decls), and if there is any, creates a vector which records the conditionpart of instruction classes having bypass_list, and save it by attribute withname “*bypass_p”.

 

9545 static void

9546 make_bypass_attr (void)                                                                     ingenautomata.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 }

 

原创粉丝点击