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.