现在的位置: 首页 > 综合 > 正文

GCC’s bacl-end & assemble emission (31) cont

2013年03月23日 ⁄ 综合 ⁄ 共 10145字 ⁄ 字号 评论关闭

In next step, simliarly, the left bottom node of EQ_ATTR_ATL for theNOT sub-tree returns itself as left at line 3322.

figure 86 : step 2 for optimizing attribute

For the rigth child of IOR inside NOT, a new EQ_ATTR_ATL is createdat line 3585, and returns as rigth at line 3326.

figure 87 : step 3 for optimizing attribute

Now as theforth step, IOR node inside NOT node has EQ_ATTR_ATL for its both left andrightresult, at line 3334, attr_alt_intersection is invoked to create anew EQ_ATTR_ATL.

figure 88 : step 4 for optimizing attribute

 

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 }

 

The EQ_ATTR_ATL is created at line 3211 above. This node is returnedback as leftat line 3525. See belowfigure for the EQ_ATTR_ATL object.

figure 89 : step 5 for optimizing attribute

At line 3543, attr_alt_complement is invoked to create newEQ_ATTR_ATL for the NOT operation.

 

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 }

 

After NOT returns this EQ_ATTR_ATL back to IOR in below figure, atline 3334, attr_alt_intersectionis invoked for the OR operation. This time, notice that the EQ_ATTR_ATLreturned by NOT has 1 in second children,the new EQ_ATTR_ATL is created at line 3214.

figure 90 : step 6 for optimizing attribute

Similiarly, in sixth step the left bottom EQ_ATTR_ATL of rightbranch of root AND returns itself to its parent as indicated in followingfigure.

figure 91 : step 7 for optimizing attribute

As its sibling is EQ_ATTR but not “alternative” ones, evaluate_eq_attr,at line 3599 in simplify_test_exp,is invoked for the handling. Notice the FORloops at line of 3594 and 3595, it can easily find out if the instruction usesthis attribute value or not as we have linked all instructions using the valuetegother.

Below in evaluate_eq_attr, parameter exp isthe rtx object of EQ_ATTR which comes from the COND expression we try tosimplify in optimize_attrsand parameter valueis the attribute value used by the instruction of insn_code (see line 3594~3596 in simplify_test_exp). In evaluate_eq_attr, we can seewhat the result of exp is after applying known attributes’ valueused by the instruction.

 

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 }

 

For valueof COND, we know that its even No. children are the conditional test, and odd No.children are value of the attribute. So here, we recur simplify_test_exp for thetests and recur evaluate_eq_attr for the values. The neteffect is transforming COND object into IOR/AND tree which can be handled againby simplify_test_expand evaluate_eq_attr.

To see the function clearer assuming following example (in itcond*_s stands for cond* after simplified, val*_e stands for val* afterevaluating):

figure 92 : simpilfy for optimizing attribute value of COND

The transformation is identical. The new created expression at righthand side of above figure is handled by simplify_test_exp atline 3600. The process we see above will repeat. For concise purpose, in theexmaple of optimize attribute, surppose hypothesis attribute “ccc” containsCONST_STRING value “n4” which isused by the instruction. And we can get following step.

figure 93 : step 8 for optimizing attribute

Notice that at line 3601, in simplify_test_exp, the reformed attribute will be evaluated by attr_rtx_cost to see if itis worth to expand the whole expression (seefigure 92, if some values arearithmetic expressions, the whole expression may not be simplified too much, sowe don’t want to return this big one. In fact, this expression must stay in thevalue list of certain attribute, it will get simplilfied at its place and willbe expanded into function get_attr_*. That means if we want to get value ofthis complex expression during building get_attr_* function for currentattribute, we can invoke get_attr_* functions for those attributes applied). For our assuming example here, see that true_rtx is object of CONST_INT(see line 6009, in main), and its rtx code is ‘w’. The result ofattr_rtx_costis 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     case MATCH_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 }

 

Then in next step, IOR node returns true_rtx, at line 3435 in simplify_test_exp.

figure 94 : step 9 for optimizing attribute

It is easy for NOT returns false_rtx as receiving true_rtx at line 3539 in simplify_test_exp.

figure 95 : step 10 for optimizing attribute

At last, we get the result: false_rtx! That means the instruction does notsatisfied the conditional test, and the attribue value is not used. While ifthe conditional test after simplification is true_rtx that means the valueassociated is used by the instruction.

figure 96 : step 11 for optimizing attribute

Notice that between line 2548 and 2562, adjacent same values willcause their conditions to be merged by IOR (logic OR operator), however thealgorithm doesn’t promise to exhaust all chances. But it is expected to do goodenough job in most of time.

 

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 }

 

In rest code of simplify_cond, if the last test of the CONDis found equal to new_defval above, at line 2572, this test is removed (as defaultvalue will be used if the test fails). Seems a buglies when len == 0 at line 2585, at this case ret should be assigned with new_defvalat line 2590.

抱歉!评论已关闭.