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