GCC后端及汇编发布(29)

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

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 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 }

 

expand_automata9850行,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 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 }

 

接着在expand_automata9854行,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 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 }

 

上面在9762pass_states从自动机的start_state开始通过状态迁移遍历所有的状态并把所遇到的状态放入新创建的缓存automaton_states中。

 

9736 static void

9737 add_automaton_state (state_tstate)                                                       ingenautomata.c

9738 {

9739   VLA_PTR_ADD (automaton_states, state);

9740 }

 

在这之后,在9763行的FOR循环接着访问在automaton_states中的状态,如果从这个状态我们可以到达其它状态,我们就认为关联的指令是重要的。通过这个方式,我们过滤出单个迁移构成的封闭的环。

接着在9783行的FOR循环找出上面找到的包含重要ainsn的自动机。最后,这个自动机列表将被保存在automata_list_table中,这个表构建在initiate_automata_lists中。

然后在expand_automata9857行,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)                                              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 }

 

在上面的9482行,descriptioninsns_num记录了define_insn_reservation,包括advance_cycle_insn_decl的数目(参考process_declsadd_advance_cycle_insn_decl)。而在9486行,decls_num记录了所有为自动机生成所构建的decl(参见expand_automata9818行,及add_advance_cycle_insn_decl)。

接着在expand_automata9853行,make_insn_alts_attr构建另一个深度嵌套的条件表达式,它返回特定指令的替代的数目,并通过名为“*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 }

 

接着在expand_automata9854行,make_default_insn_latency_attr构建了另一个条件表达式,它返回指定指令的default_latency,并通过名为“*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 }

 

而在expand_automata9855行,make_bypass_attr计算指令列表的数目(参考process_decls2962行),如果存在指令类别,构建一个向量,它保存具有bypass_list的指令类别中的条件部分,并通过名为“*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 }

 

原创粉丝点击