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

9.6.1.3.    Optimizationfor attributes

Some attributes contain complex expression as its value. Take anexample from file i386.md, the defintion of "length_immediate"attribute is as below.

 

189  (define_attr"length_immediate" ""

190   (cond [(eq_attr "type""incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")

191            (const_int 0)

192         (eq_attr "unit" "i387,sse,mmx")

193            (const_int 0)

194         (eq_attr "type""alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,

195                         imul,icmp,push,pop")

196            (symbol_ref"ix86_attr_length_immediate_default(insn,1)")

197         (eq_attr "type" "imov,test")

198            (symbol_ref"ix86_attr_length_immediate_default(insn,0)")

199         (eq_attr "type" "call")

200            (if_then_else (match_operand 0"constant_call_address_operand" "")

201              (const_int 4)

202              (const_int 0))

203         (eq_attr "type" "callv")

204            (if_then_else (match_operand 1"constant_call_address_operand" "")

205              (const_int 4)

206              (const_int 0))

207         ;; We don't know the size before shorten_branches. Expect

208         ;; the instruction to fit for better scheduling.

209         (eq_attr "type" "ibr")

210            (const_int 1)

211         ]

212         (symbol_ref "/* Update immediate_length and other attributes! */

213                      abort(),1")))

 

Line from 190 to 213 is the expression for the default value of theattribute. It is very diffcult to generate get_attr_length_immediate from this nativeform for the associated instruction. However, as the default value will be usedfor instructions don’t explicitly declare value for this attribute, and theinstuction must take one value in the value list for every attribute at anypoint of time. And when an instruction is selected, the conditional test of itsdefine_insn pattern must be passed. That is most attributes’ value aredetermined. So it is better to apply these attributes’ value into thisexpression to get the most reduced form, and saves this reduced expression forthe instruction. It is the purpose of the so-called attribute optimization.

However, always remember that now the rtx object of this attributeis not what we see above. The major difference is that all IF_THEN_ELSE objectsare reformed into COND objects (see get_attr_value, and make_canonical invoked).

 

3624 static void

3625 optimize_attrs (void)                                                                          in genattrtab.c

3626 {

3627   struct attr_desc*attr;

3628   struct attr_value*av;

3629   struct insn_ent*ie;

3630   rtx newexp;

3631   int i;

3632   structattr_value_list

3633   {

3634     struct attr_value*av;

3635     struct insn_ent*ie;

3636     struct attr_desc*attr;

3637     struct attr_value_list*next;

3638   };

3639   structattr_value_list **insn_code_values;

3640   structattr_value_list *ivbuf;

3641   structattr_value_list *iv;

3642

3643   /* For each insncode, make a list of all the insn_ent's for it,

3644     for all values for all attributes.  */

3645

3646   if (num_insn_ents == 0)

3647     return;

3648

3649   /* Make 2 extraelements, for "code" values -2 and -1.  */

3650  insn_code_values = xcalloc ((insn_code_number + 2),

3651                           sizeof (struct attr_value_list*));

3652

3653   /* Offset the tableaddress so we can index by -2 or -1.  */

3654   insn_code_values += 2;

3655

3656   iv = ivbuf = xmalloc (num_insn_ents * sizeof (structattr_value_list));

3657

3658   for (i = 0; i < MAX_ATTRS_INDEX; i++)

3659     for (attr =attrs[i];attr; attr = attr->next)

3660       for (av =attr->first_value; av; av = av->next)

3661         for (ie =av->first_insn; ie; ie = ie->next)

3662        {

3663          iv->attr = attr;

3664          iv->av = av;

3665          iv->ie = ie;

3666          iv->next =insn_code_values[ie->insn_code];

3667          insn_code_values[ie->insn_code] = iv;

3668           iv++;

3669         }

3670

3671   /* Sanity check onnum_insn_ents.  */

3672   if (iv != ivbuf + num_insn_ents)

3673     abort ();

3674

3675   /* Process one insncode at a time.  */

3676   for (i = -2; i < insn_code_number; i++)

3677   {

3678     /* Clear theATTR_CURR_SIMPLIFIED_P flag everywhere relevant.

3679       We use it to mean "alreadysimplified for this insn".  */

3680     for (iv =insn_code_values[i]; iv; iv = iv->next)

3681       clear_struct_flag (iv->av->value);

3682

3683     for (iv =insn_code_values[i]; iv; iv = iv->next)

3684     {

3685       structobstack *old = rtl_obstack;

3686

3687       attr = iv->attr;

3688       av = iv->av;

3689       ie = iv->ie;

3690       if (GET_CODE (av->value) != COND)

3691         continue;

3692

3693       rtl_obstack = temp_obstack;

3694       newexp = av->value;

3695       while(GET_CODE (newexp) == COND)

3696       {

3697         rtx newexp2 = simplify_cond (newexp, ie->insn_code,

3698                                 ie->insn_index);

3699         if (newexp2 == newexp)

3700           break;

3701         newexp = newexp2;

3702       }

3703

3704       rtl_obstack = old;

3705       if (newexp != av->value)

3706       {

3707         newexp = attr_copy_rtx (newexp);

3708         remove_insn_ent (av, ie);

3709         av = get_attr_value (newexp, attr, ie->insn_code);

3710         iv->av = av;

3711         insert_insn_ent (av, ie);

3712       }

3713     }

3714   }

3715

3716   free (ivbuf);

3717   free (insn_code_values - 2);

3718 }

 

To understand the massive FORloops at line 3658, see following figure. Before these loops the data mapis as following, all instructions using the same attribute value form alist kept in data object of attribute value (notice that default value has beenlinked into value, see fill_attr).

figure 82 : attributes optimization, figure 1

The FOR loops group dataas indicated by below figure. Data enclosed by green line forms an iv, dataenclosed by red line forms the next iv. The data has three levels, attributeis at the top hierarchy, value is at middle, and insn is at the bottom. The groupingis low level first, and data related of 3 levels are put tegother (Also seethat insn enclosed by green line must have smaller insn code than that enclosedin red line, refer to gen_insn and fill_attr).

figure 83 : attributes optimization, figure 2

Notice that the FOR loopsat line 3676 and 3683, the traverse order of the ivs is by increasing insn codeorder. It is necessary to process according to insn code. It is because duringthe simplification we may get following data – a new attribute value is addedas result of simplifying for the instruction (it doesn’t look like any othervalues in the list, it is commonly the case instruction using default value),and the insnis moved under that value. So if we process accoding to value, the new valueshould be revisited – it is reducdant work.


figure 84 : attributes optimization, figure 3

For every attribute value that is of COND, simplify_cond is used tocheck if any simplification can be done. Before studying the fucntion pleaseremember that COND though resemble switch-case statement, the test ofconditions must be performed in turn. So it is very important to arrange theconditions in correct order. It is the responsibility of the author of machinedescription file.

 

2492 static rtx

2493 simplify_cond (rtx exp, int insn_code,int insn_index)                           ingenattrtab.c

2494 {

2495   int i, j;

2496   /* We store the desired contents here,

2497     then build a new expression if they don'tmatch EXP.  */

2498   rtx defval = XEXP (exp, 1);

2499   rtx new_defval = XEXP (exp, 1);

2500   int len = XVECLEN (exp, 0);

2501   rtx *tests = xmalloc (len * sizeof (rtx));

2502   int allsame = 1;

2503   rtx ret;

2504

2505   /* This lets us free all storage allocatedbelow, if appropriate.  */

2506   obstack_finish (rtl_obstack);

2507

2508   memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));

2509

2510   /* See if default value needssimplification.  */

2511   if (GET_CODE (defval) == COND)

2512     new_defval = simplify_cond (defval, insn_code, insn_index);

2513

2514   /* Simplify the subexpressions, and see whattests we can get rid of.  */

2515

2516   for (i = 0; i< len; i += 2)

2517   {

2518     rtx newtest, newval;

2519

2520     /* Simplify this test.  */

2521     newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);

2522     tests[i] = newtest;

2523

2524     newval = tests[i + 1];

2525     /* See if this value may needsimplification.  */

2526     if (GET_CODE (newval) == COND)

2527       newval = simplify_cond (newval, insn_code, insn_index);

2528

2529     /* Look for ways to delete or combine thistest.  */

2530     if (newtest == true_rtx)

2531     {

2532       /* If test istrue, make this value the default

2533         and discard this + any followingtests.  */

2534       len = i;

2535       defval = tests[i + 1];

2536       new_defval = newval;

2537     }

2538

2539     else if (newtest == false_rtx)

2540     {

2541       /* If test isfalse, discard it and its value.  */

2542      for (j = i; j < len - 2; j++)

2543         tests[j] = tests[j + 2];

2544       i -= 2;

2545       len -= 2;

2546     }

2547

2548     else if (i > 0 && attr_equal_p(newval, tests[i - 1]))

2549     {

2550       /* If thisvalue and the value for the prev test are the same,

2551         merge the tests.  */

2552

2553       tests[i - 2]

2554          = insert_right_side (IOR, tests[i - 2], newtest,

2555                          insn_code,insn_index);

2556

2557       /* Delete thistest/value.  */

2558      for (j = i; j < len - 2; j++)

2559         tests[j] = tests[j + 2];

2560       len -= 2;

2561       i -= 2;

2562     }

2563

2564     else

2565       tests[i + 1] = newval;

2566   }

 

 

defvalat line 2498 and new_defaultat line 2499 are both aliases for default value of attribute in interested. tests atline 2508, holds the rest of the COND object, in which conditional test forvalues are handled by simplify_test_exp_in_temp at line 2521.Notice that for every COND encountered during the process, simplify_cond is recursed.

 

3139 static rtx

3140 simplify_test_exp_in_temp (rtx exp, intinsn_code, int insn_index)         in genattrtab.c

3141 {

3142   rtx x;

3143   structobstack *old;

3144   if (ATTR_IND_SIMPLIFIED_P (exp))

3145     return exp;

3146   old = rtl_obstack;

3147   rtl_obstack = temp_obstack;

3148   x = simplify_test_exp (exp, insn_code,insn_index);

3149   rtl_obstack = old;

3150   if (x == exp || rtl_obstack == temp_obstack)

3151     return x;

3152   returnattr_copy_rtx (x);

3153 }

 

simplify_test_exp_in_temp will recur indirectly, and all running simplify_test_exp_in_tempuse the same memory stack – temp_obstack. These functions share same rtxobject in temp_obstack,till top simplify_test_exp_in_tempexits. And at this point, the rtx object should be copied to the originalmemory stack (via attr_copy_rtx). So simplify_test_exp works with temp_obstack beginning at line 3148.

 

3304 static rtx

3305 simplify_test_exp (rtx exp, intinsn_code, int insn_index)                       in genattrtab.c

3306 {

3307   rtx left, right;

3308   struct attr_desc*attr;

3309   struct attr_value*av;

3310   structinsn_ent *ie;

3311   int i;

3312   rtx newexp = exp;

3313   bool left_alt, right_alt;

3314

3315  /* Don't re-simplifysomething we already simplified.  */

3316   if (ATTR_IND_SIMPLIFIED_P (exp) ||ATTR_CURR_SIMPLIFIED_P (exp))

3317     return exp;

3318

3319   switch(GET_CODE (exp))

3320   {

3321     case AND:

3322       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);

3323       SIMPLIFY_ALTERNATIVE (left);

3324       if (left == false_rtx)

3325         return false_rtx;

3326       right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);

3327       SIMPLIFY_ALTERNATIVE (right);

3328       if (left == false_rtx)

3329         return false_rtx;

3330

3331       if (GET_CODE (left) == EQ_ATTR_ALT

3332           && GET_CODE (right) ==EQ_ATTR_ALT)

3333       {

3334         exp = attr_alt_intersection (left, right);

3335         return simplify_test_exp (exp, insn_code,insn_index);

3336       }

3337

3338       /* If eitherside is an IOR and we have (eq_attr "alternative" ..")

3339         present on both sides, apply thedistributive law since this will

3340         yield simplifications.  */

3341       if ((GET_CODE (left) == IOR || GET_CODE(right) == IOR)

3342         && compute_alternative_mask (left, IOR)

3343         && compute_alternative_mask (right, IOR))

3344       {

3345         if (GET_CODE (left) == IOR)

3346         {

3347           rtx tem = left;

3348           left = right;

3349           right = tem;

3350         }

3351

3352         newexp = attr_rtx(IOR,

3353                        attr_rtx(AND, left, XEXP (right, 0)),

3354                        attr_rtx(AND, left, XEXP (right, 1)));

3355

3356         return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);

3357       }

3358

3359       /* Try with theterm on both sides.  */

3360       right = simplify_and_tree (right, &left, insn_code, insn_index);

3361       if (left == XEXP (exp, 0) && right == XEXP (exp,1))

3362         left = simplify_and_tree (left, &right, insn_code, insn_index);

3363

3364       if (left == false_rtx || right == false_rtx)

3365         return false_rtx;

3366       else if (left == true_rtx)

3367       {

3368         returnright;

3369       }

3370       else if (right == true_rtx)

3371       {

3372         returnleft;

3373       }

3374       /* See if allor all but one of the insn's alternatives are specified

3375         in this tree. Optimize if so.  */

3376

3377       if (GET_CODE (left) == NOT)

3378         left_alt = (GET_CODE (XEXP (left,0)) == EQ_ATTR

3379            && XSTR (XEXP (left,0), 0) == alternative_name);

3380       else

3381         left_alt = (GET_CODE (left) == EQ_ATTR_ALT

3382            && XINT (left, 1));

3383

3384       if (GET_CODE (right) == NOT)

3385         right_alt = (GET_CODE (XEXP (right,0)) == EQ_ATTR

3386            && XSTR (XEXP (right,0), 0) == alternative_name);

3387       else

3388         right_alt = (GET_CODE (right) ==EQ_ATTR_ALT

3389            && XINT (right, 1));

3390

3391       if (insn_code >= 0

3392           && (GET_CODE (left) == AND

3393           || left_alt

3394           || GET_CODE (right) == AND

3395           || right_alt))

3396       {

3397         i = compute_alternative_mask (exp, AND);

3398         if (i & ~insn_alternatives[insn_code])

3399           fatal ("invalid alternativespecified for pattern number %d",

3400               insn_index);

3401

3402         /* If allalternatives are excluded, this is false. */

3403         i ^= insn_alternatives[insn_code];

3404         if (i == 0)

3405           returnfalse_rtx;

3406         else if ((i & (i - 1)) == 0&& insn_alternatives[insn_code]> 1)

3407         {

3408           /* If justone excluded, AND a comparison with that one to the

3409             front of the tree. The others willbe eliminated by

3410             optimization. We do not want to dothis if the insn has one

3411             alternative and we have tested noneof them!  */

3412           left = make_alternative_compare (i);

3413           right = simplify_and_tree (exp, &left, insn_code, insn_index);

3414           newexp = attr_rtx(AND, left, right);

3415

3416           returnSIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);

3417         }

3418       }

3419

3420       if (left != XEXP (exp, 0) || right != XEXP (exp,1))

3421       {

3422         newexp = attr_rtx(AND, left, right);

3423         return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);

3424       }

3425       break;

3426

3427     case IOR:

3428       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);

3429       SIMPLIFY_ALTERNATIVE (left);

3430       if (left == true_rtx)

3431         return true_rtx;

3432       right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);

3433       SIMPLIFY_ALTERNATIVE (right);

3434       if (right == true_rtx)

3435         return true_rtx;

3436

3437       if (GET_CODE (left) == EQ_ATTR_ALT

3438          && GET_CODE (right) == EQ_ATTR_ALT)

3439       {

3440         exp = attr_alt_union (left, right);

3441         return simplify_test_exp (exp, insn_code, insn_index);

3442       }

3443

3444       right = simplify_or_tree (right,&left, insn_code, insn_index);

3445       if (left == XEXP (exp, 0) && right == XEXP (exp,1))

3446         left = simplify_or_tree (left,&right, insn_code, insn_index);

3447

3448       if (right == true_rtx || left == true_rtx)

3449         return true_rtx;

3450       else if (left == false_rtx)

3451       {

3452         returnright;

3453       }

3454       else if (right == false_rtx)

3455       {

3456         returnleft;

3457       }

3458

3459       /* Test for simplecases where the distributive law is useful. I.e.,

3460         convert (ior (and (x) (y))

3461                   (and (x) (z)))

3462         to    (and (x)

3463               (ior (y) (z)))

3464       */

3465

3466       else if (GET_CODE (left) == AND&& GET_CODE (right) == AND

3467              && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))

3468       {

3469         newexp = attr_rtx(IOR, XEXP (left, 1), XEXP (right, 1));

3470

3471         left = XEXP (left, 0);

3472         right = newexp;

3473         newexp = attr_rtx(AND, left, right);

3474         return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);

3475       }

3476

3477       /* See if allor all but one of the insn's alternatives are specified

3478         in this tree. Optimize if so.  */

3479

3480       else if (insn_code >= 0

3481             && (GET_CODE (left) == IOR

3482             || (GET_CODE (left) == EQ_ATTR_ALT

3483               && !XINT (left, 1))

3484             || (GET_CODE (left) == EQ_ATTR

3485               && XSTR (left, 0) == alternative_name)

3486             || GET_CODE (right) == IOR

3487             || (GET_CODE (right) == EQ_ATTR_ALT

3488               && !XINT (right, 1))

3489             || (GET_CODE (right) == EQ_ATTR

3490               && XSTR (right, 0) == alternative_name)))

3491       {

3492         i = compute_alternative_mask (exp,IOR);

3493         if (i & ~insn_alternatives[insn_code])

3494           fatal ("invalid alternativespecified for pattern number %d",

3495                insn_index);

3496

3497         /* If all alternativesare included, this is true.  */

3498         i ^= insn_alternatives[insn_code];

3499         if (i == 0)

3500           returntrue_rtx;

3501         else if ((i & (i - 1)) == 0&& insn_alternatives[insn_code]> 1)

3502         {

3503           /* If just oneexcluded, IOR a comparison with that one to the

3504             front of the tree. The others willbe eliminated by

3505             optimization. We do not want to dothis if the insn has one

3506             alternative and we have tested noneof them!  */

3507           left = make_alternative_compare (i);

3508           right = simplify_and_tree (exp, &left, insn_code, insn_index);

3509           newexp = attr_rtx (IOR,attr_rtx (NOT, left), right);

3510

3511           returnSIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);

3512         }

3513       }

3514

3515       if (left != XEXP (exp, 0) || right != XEXP (exp,1))

3516       {

3517         newexp = attr_rtx(IOR, left, right);

3518         return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);

3519       }

3520       break;

3521

3522     case NOT:

3523       if (GET_CODE (XEXP (exp, 0)) == NOT)

3524       {

3525         left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),

3526                                  insn_code,insn_index);

3527         SIMPLIFY_ALTERNATIVE (left);

3528         returnleft;

3529          }

3530

3531       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);

3532       SIMPLIFY_ALTERNATIVE (left);

3533       if (GET_CODE (left) == NOT)

3534         return XEXP (left,0);

3535

3536       if (left == false_rtx)

3537         return true_rtx;

3538       if (left == true_rtx)

3539         return false_rtx;

3540

3541       if (GET_CODE (left) == EQ_ATTR_ALT)

3542       {

3543         exp = attr_alt_complement (left);

3544         return simplify_test_exp (exp, insn_code,insn_index);

3545       }

3546

3547       /* Try to applyDe`Morgan's laws.  */

3548       if (GET_CODE (left) == IOR)

3549       {

3550         newexp = attr_rtx(AND,

3551                        attr_rtx(NOT, XEXP (left, 0)),

3552                        attr_rtx(NOT, XEXP (left, 1)));

3553

3554         newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);

3555       }

3556       else if (GET_CODE (left) == AND)

3557       {

3558         newexp = attr_rtx(IOR,

3559                        attr_rtx(NOT, XEXP (left, 0)),

3560                        attr_rtx(NOT, XEXP (left, 1)));

3561

3562         newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);

3563       }

3564       else if (left != XEXP (exp, 0))

3565       {

3566         newexp = attr_rtx(NOT, left);

3567       }

3568       break;

3569

3570     caseEQ_ATTR_ALT:

3571       if (current_alternative_string)

3572         returnattr_alt_bit_p (exp, atoi (current_alternative_string)) ? true_rtx: false_rtx;

3573

3574       if (!XINT (exp, 0))

3575         return XINT(exp, 1) ? true_rtx: false_rtx;

3576       break;

3577

3578     caseEQ_ATTR:

3579       if (current_alternative_string && XSTR (exp,0) == alternative_name)

3580         return (XSTR(exp, 1) == current_alternative_string

3581                      ? true_rtx : false_rtx);

3582

3583       if (XSTR (exp, 0) == alternative_name)

3584       {

3585         newexp = mk_attr_alt (1 << atoi(XSTR (exp, 1)));

3586         break;

3587       }

3588

3589       /* Look at thevalue for this insn code in the specified attribute.

3590         We normally can replace this comparisonwith the condition that

3591         would give this insn the values beingtested for.  */

3592       if (XSTR (exp, 0) != alternative_name

3593          && (attr = find_attr(&XSTR (exp, 0), 0)) != NULL)

3594         for (av =attr->first_value; av; av = av->next)

3595           for(ie = av->first_insn; ie; ie = ie->next)

3596            if (ie->insn_code == insn_code)

3597             {

3598               rtx x;

3599               x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);

3600               x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);

3601               if (attr_rtx_cost(x) < 20)

3602                 returnx;

3603            }

3604       break;

3605

3606     default:

3607       break;

3608   }

3609

3610   /* We have alreadysimplified this expression. Simplifying it again

3611     won't buy anything unless we weren't givena valid insn code

3612     to process (i.e., we are canonicalizingsomething.).  */

3613   if (insn_code != -2 /*Seems wrong: && current_alternative_string.  */

3614       && ! ATTR_IND_SIMPLIFIED_P (newexp))

3615     returncopy_rtx_unchanging (newexp);

3616

3617   returnnewexp;

3618 }

 

Above, at line 3322, macro SIMPLIFY_TEST_EXP has following definition.Below, at line 370, macro ATTR_CURR_SIMPLIFIED_P accesses in_structfield of rtx object. Here if in_struct is 1 means this rtx is fully simplifiedfor the instruction currently being processed. And we know that ATTR_IND_SIMPLIED_Paccesses unchangingfield, which if 1 means this rtx is fully simplified independent of the insncode. For both cases, no need attempt the simplification.

 

369  #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX)\     in genattrtab.c

370   (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP)? (EXP)\

371    : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))

 

At line 3323, macro SIMPLIFY_ALTERNATIVE has following definition. Inits defintion, alternative_nameis string of “alternative”, while current_alternative_string is not used in thisversion. It is always 0. So it is empty in fact.

 

375  #define SIMPLIFY_ALTERNATIVE(EXP) \                                         ingenattrtab.c

376   if (current_alternative_string                          \

377       && GET_CODE ((EXP)) == EQ_ATTR                       \

378       && XSTR ((EXP), 0) == alternative_name)                 \

379     (EXP) = (XSTR ((EXP), 1) == current_alternative_string  \

380             ? true_rtx : false_rtx);

 

Line 3328 contains a bug, left should be right. This bug has been fixed inrelease of V4.

At line 3331 insimplify_test_exp,EQ_ATTR_ALT may be created in check_attr_test, at line 943. Its first child saves the value of(1<<alternative number), which will be used as a bitmap. For EQ_ATTR_ATLobject created by mk_attr_alt in check_attr_test, the second child is always 0.

simplify_test_exp does pre-ordertraverse for the conditional test of the COND object. To see clearly how itworks, suppose we have following example. The rtx object of attribute condtionfor certain value is that at left side in the figure 85 (remember we now inside a COND object, we are just at oneswtch-case alike branch). For the first step, simplify_test_exp recuresdown the bottom of the left sub-tree and handles node of EQ_ATTR_ATL. From line3574, EQ_ATTR_ATL created by mk_attr_alt will not contain 0 in its first child, so EQ_ATTR_ATL objectreturns itself as indicated by the right side of the figure.

At line 3615,for every visited node, its in_struct field will be set, and will not behandled by following simplify_test_exp.

figure 85 : step 1 for optimizing attribute


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值