GCC后端及汇编发布(31)续

在下一步,同样的,对应NOT子树的EQ_ATTR_ATL的底部节点,在3322行把自身作为left返回。

图86:优化属性,步骤2

对于NOT内部右侧的孩子IOR,在3585行构建一个新的EQ_ATTR_ATL,并在3326行作为rigth返回。

图87:优化属性,步骤3

现在作为第四步,在NOT节点中的IOR节点具有EQ_ATTR_ATL,作为其leftright的结果,在3334行,调用attr_alt_intersection来构建新的EQ_ATTR_ATL。

图88:优化属性,步骤4

 

3204 static rtx

3205 attr_alt_intersection (rtx s1, rtx s2)                                                      in genattrtab.c

3206 {

3207  rtx result = rtx_alloc (EQ_ATTR_ALT);

3208

3209   switch ((XINT (s1, 1)<< 1) | XINT (s2, 1))

3210   {

3211     case (0<< 1) | 0:

3212       XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);

3213       break;

3214     case (0<< 1) | 1:

3215       XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);

3216       break;

3217     case (1<< 1) | 0:

3218       XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);

3219       break;

3220     case (1<< 1) | 1:

3221       XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);

3222       break;

3223     default:

3224       abort ();

3225   }

3226   XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);

3227

3228   returnresult;

3229 }

 

这个EQ_ATTR_ATL在上面3211行构建的。这个节点在3525行作为left返回。参见下图中的这个EQ_ATTR_ATL对象。

图89:优化属性,步骤5

在3543行,attr_alt_complement被调用来为这个NOT操作构建新的EQ_ATTR_ATL。

 

3262 static rtx

3263 attr_alt_complement (rtx s)                                                                  in genattrtab.c

3264 {

3265   rtx result = rtx_alloc (EQ_ATTR_ALT);

3266

3267   XINT (result, 0) = XINT (s, 0);

3268   XINT (result, 1) = 1 - XINT (s, 1);

3269

3270   returnresult;

3271 }

 

在NOT把这个EQ_ATTR_ATL返回给下图的IOR后,在3334行,为这个OR操作调用attr_alt_intersection。这次,注意到由NOT返回的EQ_ATTR_ATL,其第二个孩子是1,在3214行构建新的EQ_ATTR_ATL。

图90:优化属性,步骤6

类似的,在第六步,根节点AND的右分枝的左侧底部的EQ_ATTR_ATL,把自己返回给父节点,如下图所示。

图91:优化属性,步骤7

因为其兄弟是EQ_ATTR,而不是“alternative”,在simplify_test_exp 的3599行,调用evaluate_eq_attr来做处理。注意3594及3595行的FOR循环,因为我们已经把所有指令按所使用的属性值链接在一起,很容易找出这个指令是否使用这个属性值。

下面在evaluate_eq_attr中,参数exp是EQ_ATTR的rtx对象,它来自我们试图在optimize_attrs中简化的COND表达式,参数value是编码为insn_code的指令(参见simplify_test_exp的3594~3596行)所使用的属性值。在evaluate_eq_attr中,我们可以看到应用了已知的,该指令所使用的,属性值之后,exp的结果是什么。

 

2768 static rtx

2769 evaluate_eq_attr (rtx exp, rtx value,int insn_code, int insn_index)           in genattrtab.c

2770 {

2771   rtx orexp, andexp;

2772   rtx right;

2773   rtx newexp;

2774   int i;

2775

2776   if (GET_CODE (value) == CONST_STRING)

2777   {

2778     if (! strcmp_check (XSTR (value, 0), XSTR(exp, 1)))

2779       newexp = true_rtx;

2780     else

2781       newexp = false_rtx;

2782   }

2783   else if (GET_CODE (value) == SYMBOL_REF)

2784   {

2785     char *p;

2786     char string[256];

2787

2788     if (GET_CODE (exp) != EQ_ATTR)

2789       abort ();

2790

2791     if (strlen (XSTR (exp, 0)) + strlen (XSTR(exp, 1)) + 2 > 256)

2792       abort ();

2793

2794     strcpy (string, XSTR (exp, 0));

2795     strcat (string, "_");

2796     strcat (string, XSTR (exp, 1));

2797     for (p =string; *p; p++)

2798       *p = TOUPPER (*p);

2799

2800     newexp = attr_rtx(EQ, value,

2801                    attr_rtx(SYMBOL_REF,

2802                           DEF_ATTR_STRING (string)));

2803   }

2804   else if (GET_CODE (value) == COND)

2805   {

2806     /* We constructan IOR of all the cases for which the requested attribute

2807       value is present. Since we start withFALSE, if it is not present,

2808       FALSE will be returned.

2809

2810       Each case is the AND of the NOT's of theprevious conditions with the

2811       current condition; in the default casethe current condition is TRUE.

2812

2813      For each possible COND value, callourselves recursively.

2814

2815       The extra TRUE and FALSE expressions willbe eliminated by another

2816       call to the simplification routine.  */

2817

2818     orexp = false_rtx;

2819     andexp = true_rtx;

2820

2821     if (current_alternative_string)

2822       clear_struct_flag (value);

2823

2824     for (i = 0; i < XVECLEN (value, 0); i += 2)

2825     {

2826       rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),

2827                                      insn_code,insn_index);

2828

2829       SIMPLIFY_ALTERNATIVE (this);

2830

2831       right = insert_right_side (AND, andexp, this,

2832                           insn_code,insn_index);

2833       right = insert_right_side (AND, right,

2834                           evaluate_eq_attr (exp,

2835                                         XVECEXP(value, 0,

2836                                                  i + 1),

2837                                        insn_code, insn_index),

2838                           insn_code,insn_index);

2839       orexp = insert_right_side (IOR, orexp, right,

2840                            insn_code,insn_index);

2841

2842       /* Add thiscondition into the AND expression.  */

2843       newexp = attr_rtx(NOT, this);

2844       andexp = insert_right_side (AND, andexp, newexp,

2845                              insn_code,insn_index);

2846     }

2847

2848     /* Handle the default case.  */

2849     right= insert_right_side (AND, andexp,

2850                         evaluate_eq_attr (exp, XEXP (value, 1),

2851                                       insn_code,insn_index),

2852                         insn_code, insn_index);

2853     newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);

2854   }

2855   else

2856     abort ();

2857

2858   /* If uses anaddress, must return original expression. But set the

2859     ATTR_IND_SIMPLIFIED_P bit so we don't tryto simplify it again.  */

2860

2861   address_used = 0;

2862   walk_attr_value (newexp);

2863

2864   if (address_used)

2865   {

2866     /* This had`&& current_alternative_string', which seems to be wrong.  */

2867     if (! ATTR_IND_SIMPLIFIED_P (exp))

2868       returncopy_rtx_unchanging (exp);

2869     return exp;

2870   }

2871   else

2872     returnnewexp;

2873 }

 

对于COND的value,我们知道其偶数序号孩子是条件测试,奇数序号孩子是属性值。因此在这里,为这些测试,我们递归调用simplify_test_exp,而为这些值,递归调用evaluate_eq_attr。其净效果是把COND对象转换为,我们可以再次通过simplify_test_expevaluate_eq_attr处理的,IOR/AND树。

为了更清楚地看这个函数,假定有以下的例子(其中cond*_s代表经过简化的cond*, val*_e代表经过评估的val*):

图92:COND优化属性值的简化

该变换是恒等的。上图右手侧新构建的表达式,由3600行的simplify_test_exp处理。我们在上面看到的过程将重复。出于简洁的目的,在这个优化属性值的例子中,假定属性“ccc”包含CONST_STRING的值“n4”,该值被这个指令使用。我们可以得到下面的步骤。

图93:优化属性,步骤8

注意在simplify_test_exp的3601,转换后的属性将被attr_rtx_cost评估,来查看是否值得展开整个表达式(看到图92,如果某些值是算术表达式,整个表达式可能不能简化很多,那么我们不希望返回这个大家伙。事实上,这个表达式必须保留在某个属性的值列表中,在这个位置上它将得到简化,并将被扩展入函数get_attr_*。这意味着,如果在为当前属性构建get_attr_*函数的过程中,我们希望得到这个复杂表达式的值,我们可以对这些使用的属性值调用get_attr_*函数)。对于这里我们假设的例子,看到true_rtx是CONST_INT对象(参见main的6009行),并且其rtx编码是‘w’’。attr_rtx_cost的结果是0。

 

3806 static int

3807 attr_rtx_cost (rtx x)                                                                                    ingenattrtab.c

3808 {

3809  int cost = 0;

3810   enum rtx_code code;

3811   if (!x)

3812     return 0;

3813   code = GET_CODE (x);

3814   switch (code)

3815   {

3816     caseMATCH_OPERAND:

3817       if (XSTR (x, 1)[0])

3818         return 10;

3819       else

3820         return 0;

3821

3822     caseEQ_ATTR_ALT:

3823       return 0;

3824

3825     caseEQ_ATTR:

3826       /* Alternativesdon't result into function call.  */

3827       if (!strcmp_check (XSTR (x, 0), alternative_name))

3828         return 0;

3829       else

3830         return 5;

3831     default:

3832     {

3833       int i, j;

3834       const char *fmt =GET_RTX_FORMAT (code);

3835       for (i =GET_RTX_LENGTH (code) - 1; i >= 0; i--)

3836       {

3837         switch(fmt[i])

3838         {

3839           case'V':

3840           case'E':

3841             for(j = 0; j < XVECLEN (x, i); j++)

3842               cost += attr_rtx_cost (XVECEXP (x, i, j));

3843             break;

3844           case'e':

3845             cost += attr_rtx_cost (XEXP (x, i));

3846             break;

3847         }

3848       }

3849     }

3850     break;

3851   }

3852   return cost;

3853 }

 

然后在下一步,IOR节点在simplify_test_exp的3435行返回true_rtx

图94:优化属性,步骤9

simplify_test_exp的3539行,接受了true_rtx,NOT立即返回false_rtx

图95:优化属性,步骤10

最后,我们得到结果:false_rtx!这意味着这个指令不满足这个条件测试,没有使用该属性值。而如果简化后的条件测试是true_rtx,就意味着关联的值被该指令使用。

图96:优化属性,步骤11

注意2548行及2562行之间,相邻的相同的值,将导致它们的条件通过IOR(逻辑OR操作符)合并,不过这个算法不保证能利用所有的机会。但是还是可以期望它,在绝大多数时间,良好工作。

 

simplify_cond (continued)

 

2568  /* If the last test in a COND has the same value

2569     as the default value, that test isn'tneeded.  */

2570

2571   while (len> 0 && attr_equal_p (tests[len - 1], new_defval))

2572     len -= 2;

2573

2574  /* See if we changedanything.  */

2575   if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp,1))

2576     allsame = 0;

2577   else

2578     for (i = 0;i < len; i++)

2579       if (! attr_equal_p (tests[i], XVECEXP(exp, 0, i)))

2580       {

2581         allsame = 0;

2582         break;

2583       }

2584

2585   if (len == 0)

2586   {

2587     if (GET_CODE (defval) == COND)

2588      ret = simplify_cond (defval, insn_code, insn_index);

2589    else

2590      ret = defval;

2591   }

2592   else if (allsame)

2593     ret = exp;

2594   else

2595   {

2596     rtx newexp = rtx_alloc (COND);

2597

2598     XVEC (newexp, 0) = rtvec_alloc (len);

2599     memcpy (XVEC (newexp, 0)->elem, tests,len * sizeof (rtx));

2600     XEXP (newexp, 1) = new_defval;

2601     ret = newexp;

2602   }

2603   free (tests);

2604   return ret;

2605 }

 

simplify_cond剩下的代码中,如果COND最后的测试被发现等于new_defval,在上面2572行移走这个测试(因为测试失败了也是使用缺省值)。在2585行,当len == 0时,似乎有一个bug,在这个情形下,ret应该被赋予2590行的new_defval



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值