GCC后端及汇编发布(29)

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 }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值