9.5.7.5. 5th, 6th Loops of Processing Decls – DECL_PRESENCE/_ABSENCE
Simliarly, the fifth loop binds decl of present_set pattern with corresponding decls of define_cpu_unit pattern. The handling is nearly the same as that in forth loop (refer to 8.1.3 Overview of DEFINE_INSN_RESERVATION pattern ).
process_decls (continued)
3016 /* Check absence set declarations and form absence sets. */
3017 for (i = 0; i < description ->decls_num; i++)
3018 {
3019 decl = description ->decls [i];
3020 if (decl->mode == dm_absence)
3021 {
3022 unit_set_el_t unit_set_el_list;
3023 pattern_set_el_t pattern_set_el_list;
3024
3025 unit_set_el_list
3026 = process_presence_absence_names
3027 (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
3028 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
3029 pattern_set_el_list
3030 = process_presence_absence_patterns
3031 (DECL_ABSENCE (decl)->patterns,
3032 DECL_ABSENCE (decl)->patterns_num,
3033 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
3034 add_presence_absence (unit_set_el_list, pattern_set_el_list,
3035 decl->pos, FALSE,
3036 DECL_ABSENCE (decl)->final_p);
3037 }
3038 }
3039 }
The sixth loop then binds decl of absent_set pattern with corresponding decls of define_cpu_unit pattern. The handling is nearly the same as that in above loop. (refer to 8.1.3 Overview of DEFINE_INSN_RESERVATION pattern ).
process_decls (continued)
3016 /* Check absence set declarations and form absence sets. */
3017 for (i = 0; i < description ->decls_num; i++)
3018 {
3019 decl = description ->decls [i];
3020 if (decl->mode == dm_absence)
3021 {
3022 unit_set_el_t unit_set_el_list;
3023 pattern_set_el_t pattern_set_el_list;
3024
3025 unit_set_el_list
3026 = process_presence_absence_names
3027 (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
3028 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
3029 pattern_set_el_list
3030 = process_presence_absence_patterns
3031 (DECL_ABSENCE (decl)->patterns,
3032 DECL_ABSENCE (decl)->patterns_num,
3033 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
3034 add_presence_absence (unit_set_el_list, pattern_set_el_list,
3035 decl->pos, FALSE,
3036 DECL_ABSENCE (decl)->final_p);
3037 }
3038 }
3039 }
At line 3023, pattern_set_el_t is typedef as pointer type of pattern_set_el below, which will constuct a list. As the second operand of these patterns is a list, and of which every element is also a unit list sperated by white space, unit_decls at line 1056 is declared as unit_decl**.
1051 struct pattern_set_el
1052 {
1053 /* The number of units in unit_decls. */
1054 int units_num;
1055 /* The units forming the pattern. */
1056 struct unit_decl **unit_decls;
1057 pattern_set_el_t next_pattern_set_el;
1058 };
From section 9.3.8. Read in EXCLUSION_SET pattern , we know that parameter names is an array recording the first operand of the pattern, process_presence_absence_names creates a list of unit_set_el_t out of this array to bind decl of the unit.
2546 static unit_set_el_t
2547 process_presence_absence_names (char **names, int num,
2548 pos_t req_pos ATTRIBUTE_UNUSED,
2549 int presence_p, int final_p)
2550 {
2551 unit_set_el_t el_list;
2552 unit_set_el_t last_el;
2553 unit_set_el_t new_el;
2554 decl_t decl_in_table;
2555 int i;
2556
2557 el_list = NULL;
2558 last_el = NULL;
2559 for (i = 0; i < num; i++)
2560 {
2561 decl_in_table = find_decl (names [i]);
2562 if (decl_in_table == NULL)
2563 error ((presence_p
2564 ? (final_p
2565 ? "unit `%s' in final presence set is not declared"
2566 : "unit `%s' in presence set is not declared")
2567 : (final_p
2568 ? "unit `%s' in final absence set is not declared"
2569 : "unit `%s' in absence set is not declared")), names [i]);
2570 else if (decl_in_table->mode != dm_unit)
2571 error ((presence_p
2572 ? (final_p
2573 ? "`%s' in final presence set is not unit"
2574 : "`%s' in presence set is not unit")
2575 : (final_p
2576 ? "`%s' in final absence set is not unit"
2577 : "`%s' in absence set is not unit")), names [i]);
2578 else
2579 {
2580 new_el = create_node (sizeof (struct unit_set_el));
2581 new_el->unit_decl = DECL_UNIT (decl_in_table);
2582 new_el->next_unit_set_el = NULL;
2583 if (last_el == NULL)
2584 el_list = last_el = new_el;
2585 else
2586 {
2587 last_el->next_unit_set_el = new_el;
2588 last_el = last_el->next_unit_set_el;
2589 }
2590 }
2591 }
2592 return el_list;
2593 }
Similarly, parameter patterns is the array holding the second operand, here it also contains strings of patterns’ name, also needs process_presence_absence_patterns to bind to decl of the unit.
2598 static pattern_set_el_t
2599 process_presence_absence_patterns (char ***patterns, int num,
2600 pos_t req_pos ATTRIBUTE_UNUSED,
2601 int presence_p, int final_p)
2602 {
2603 pattern_set_el_t el_list;
2604 pattern_set_el_t last_el;
2605 pattern_set_el_t new_el;
2606 decl_t decl_in_table;
2607 int i, j;
2608
2609 el_list = NULL;
2610 last_el = NULL;
2611 for (i = 0; i < num; i++)
2612 {
2613 for (j = 0; patterns [i] [j] != NULL; j++)
2614 ;
2615 new_el = create_node (sizeof (struct pattern_set_el)
2616 + sizeof (struct unit_decl *) * j);
2617 new_el->unit_decls
2618 = (struct unit_decl **) ((char *) new_el
2619 + sizeof (struct pattern_set_el));
2620 new_el->next_pattern_set_el = NULL;
2621 if (last_el == NULL)
2622 el_list = last_el = new_el;
2623 else
2624 {
2625 last_el->next_pattern_set_el = new_el;
2626 last_el = last_el->next_pattern_set_el;
2627 }
2628 new_el->units_num = 0;
2629 for (j = 0; patterns [i] [j] != NULL; j++)
2630 {
2631 decl_in_table = find_decl (patterns [i] [j]);
2632 if (decl_in_table == NULL)
2633 error ((presence_p
2634 ? (final_p
2635 ? "unit `%s' in final presence set is not declared"
2636 : "unit `%s' in presence set is not declared")
2637 : (final_p
2638 ? "unit `%s' in final absence set is not declared"
2639 : "unit `%s' in absence set is not declared")),
2640 patterns [i] [j]);
2641 else if (decl_in_table->mode != dm_unit)
2642 error ((presence_p
2643 ? (final_p
2644 ? "`%s' in final presence set is not unit"
2645 : "`%s' in presence set is not unit")
2646 : (final_p
2647 ? "`%s' in final absence set is not unit"
2648 : "`%s' in absence set is not unit")),
2649 patterns [i] [j]);
2650 else
2651 {
2652 new_el->unit_decls [new_el->units_num]
2653 = DECL_UNIT (decl_in_table);
2654 new_el->units_num++;
2655 }
2656 }
2657 }
2658 return el_list;
2659 }
Note the memory for unit_decls field of pattern_set_el is allocated at line 2618 too. As every such pattern just see only one spot, it should combine these spots of view to get the whole constrains of the unit. It needs add_presence_absence to do the combination.
2669 static void
2670 add_presence_absence (unit_set_el_t dest_list,
2671 pattern_set_el_t pattern_list,
2672 pos_t req_pos ATTRIBUTE_UNUSED,
2673 int presence_p, int final_p)
2674 {
2675 unit_set_el_t dst;
2676 pattern_set_el_t pat;
2677 struct unit_decl *unit;
2678 unit_set_el_t curr_excl_el;
2679 pattern_set_el_t curr_pat_el;
2680 pattern_set_el_t prev_el;
2681 pattern_set_el_t copy;
2682 int i;
2683 int no_error_flag;
2684
2685 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2686 for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el)
2687 {
2688 for (i = 0; i < pat->units_num; i++)
2689 {
2690 unit = pat->unit_decls [i];
2691 if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p)
2692 {
2693 error ("unit `%s' requires own absence", unit->name);
2694 continue ;
2695 }
2696 if (dst->unit_decl->automaton_name != NULL
2697 && unit->automaton_name != NULL
2698 && strcmp (dst->unit_decl->automaton_name,
2699 unit->automaton_name) != 0)
2700 {
2701 error ((presence_p
2702 ? (final_p
2703 ? "units `%s' and `%s' in final presence set belong to different automata"
2704 : "units `%s' and `%s' in presence set belong to different automata")
2705 : (final_p
2706 ? "units `%s' and `%s' in final absence set belong to different automata"
2707 : "units `%s' and `%s' in absence set belong to different automata")),
2708 unit->name, dst->unit_decl->name);
2709 continue ;
2710 }
2711 no_error_flag = 1;
2712 if (presence_p)
2713 for (curr_excl_el = dst->unit_decl->excl_list;
2714 curr_excl_el != NULL;
2715 curr_excl_el = curr_excl_el->next_unit_set_el)
2716 {
2717 if (unit == curr_excl_el->unit_decl && pat->units_num == 1)
2718 {
2719 if (!w_flag )
2720 {
2721 error ("unit `%s' excludes and requires presence of `%s'",
2722 dst->unit_decl->name, unit->name);
2723 no_error_flag = 0;
2724 }
2725 else
2726 warning
2727 ("unit `%s' excludes and requires presence of `%s'",
2728 dst->unit_decl->name, unit->name);
2729 }
2730 }
2731 else if (pat->units_num == 1)
2732 for (curr_pat_el = dst->unit_decl->presence_list;
2733 curr_pat_el != NULL;
2734 curr_pat_el = curr_pat_el->next_pattern_set_el)
2735 if (curr_pat_el->units_num == 1
2736 && unit == curr_pat_el->unit_decls [0])
2737 {
2738 if (!w_flag )
2739 {
2740 error
2741 ("unit `%s' requires absence and presence of `%s'",
2742 dst->unit_decl->name, unit->name);
2743 no_error_flag = 0;
2744 }
2745 else
2746 warning
2747 ("unit `%s' requires absence and presence of `%s'",
2748 dst->unit_decl->name, unit->name);
2749 }
2750 if (no_error_flag)
2751 {
2752 for (prev_el = (presence_p
2753 ? (final_p
2754 ? dst->unit_decl->final_presence_list
2755 : dst->unit_decl->final_presence_list)
2756 : (final_p
2757 ? dst->unit_decl->final_absence_list
2758 : dst->unit_decl->absence_list));
2759 prev_el != NULL && prev_el->next_pattern_set_el != NULL;
2760 prev_el = prev_el->next_pattern_set_el)
2761 ;
2762 copy = copy_node (pat, sizeof (*pat));
2763 copy->next_pattern_set_el = NULL;
2764 if (prev_el == NULL)
2765 {
2766 if (presence_p)
2767 {
2768 if (final_p)
2769 dst->unit_decl->final_presence_list = copy;
2770 else
2771 dst->unit_decl->presence_list = copy;
2772 }
2773 else if (final_p)
2774 dst->unit_decl->final_absence_list = copy;
2775 else
2776 dst->unit_decl->absence_list = copy;
2777 }
2778 else
2779 prev_el->next_pattern_set_el = copy;
2780 }
2781 }
2782 }
2783 }
See that at line 2713, “dst->unit_decl->excl_list” has been prepared in previous section. Note that above the contradiction between contrains presence and absence, unless leading to fatal error, will not be notified, as automaton thus generated can recognize and avoid these contradiction.
9.5.7.6. Validating Decls
Notice that all decls still kept in array of decls . The loops we see above just binds related decls tegother. After that check_automaton_usage checks if any automaton is not used – that is no CPU unit is bound with the automaton (see 9.5.7.2 Second Loop of Processing Decls - DECL_UNIT , line 2875).
3044 static void
3045 check_automaton_usage (void) in genautomata.c
3046 {
3047 decl_t decl;
3048 int i;
3049
3050 for (i = 0; i < description ->decls_num; i++)
3051 {
3052 decl = description ->decls [i];
3053 if (decl->mode == dm_automaton
3054 && !DECL_AUTOMATON (decl)->automaton_is_used)
3055 {
3056 if (!w_flag )
3057 error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
3058 else
3059 warning ("automaton `%s' is not used",
3060 DECL_AUTOMATON (decl)->name);
3061 }
3062 }
3063 }
9.5.7.7. Handle DECL_RESERV & DECL_INSN_RESERV
As we have seen, the regexp part of decl of define_insn_reservation describes the cpu units the instruction using in cpu cycles. process_regexp_decls places all decls of units in interested into hash table decl_table , and binds define_reservation and define_ins_reserv at place to with decl of the units.
3125 static void
3126 process_regexp_decls (void) in genautomata.c
3127 {
3128 decl_t decl;
3129 int i;
3130
3131 for (i = 0; i < description ->decls_num; i++)
3132 {
3133 decl = description ->decls [i];
3134 if (decl->mode == dm_reserv)
3135 DECL_RESERV (decl)->regexp
3136 = process_regexp (DECL_RESERV (decl)->regexp);
3137 else if (decl->mode == dm_insn_reserv)
3138 DECL_INSN_RESERV (decl)->regexp
3139 = process_regexp (DECL_INSN_RESERV (decl)->regexp);
3140 }
3141 }
The generation of regexp see section 9.3.11. Read in DEFINE_RESERVATION pattern . In the machine description file, DEFINE_RESERVATION pattern, at using position, is not different from common units, so at creating regexp , it will be given rm_unit as kind. However, decl of the unit can tell the truth, so checking at line 3088 and updates if so.
3070 static regexp_t
3071 process_regexp (regexp_t regexp) in genautomata.c
3072 {
3073 decl_t decl_in_table;
3074 regexp_t new_regexp;
3075 int i;
3076
3077 if (regexp->mode == rm_unit)
3078 {
3079 decl_in_table = find_decl (REGEXP_UNIT (regexp)->name);
3080 if (decl_in_table == NULL)
3081 error ("undeclared unit or reservation `%s'",
3082 REGEXP_UNIT (regexp)->name);
3083 else if (decl_in_table->mode == dm_unit)
3084 {
3085 DECL_UNIT (decl_in_table)->unit_is_used = 1;
3086 REGEXP_UNIT (regexp)->unit_decl = DECL_UNIT (decl_in_table);
3087 }
3088 else if (decl_in_table->mode == dm_reserv)
3089 {
3090 DECL_RESERV (decl_in_table)->reserv_is_used = 1;
3091 new_regexp = create_node (sizeof (struct regexp));
3092 new_regexp->mode = rm_reserv;
3093 new_regexp->pos = regexp->pos;
3094 REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
3095 REGEXP_RESERV (new_regexp)->reserv_decl
3096 = DECL_RESERV (decl_in_table);
3097 regexp = new_regexp;
3098 }
3099 else
3100 abort ();
3101 }
3102 else if (regexp->mode == rm_sequence)
3103 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3104 REGEXP_SEQUENCE (regexp)->regexps [i]
3105 = process_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
3106 else if (regexp->mode == rm_allof)
3107 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3108 REGEXP_ALLOF (regexp)->regexps [i]
3109 = process_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
3110 else if (regexp->mode == rm_oneof)
3111 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3112 REGEXP_ONEOF (regexp)->regexps [i]
3113 = process_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
3114 else if (regexp->mode == rm_repeat)
3115 REGEXP_REPEAT (regexp)->regexp
3116 = process_regexp (REGEXP_REPEAT (regexp)->regexp);
3117 else if (regexp->mode != rm_nothing)
3118 abort ();
3119 return regexp;
3120 }
Finally, we can get following data structure.
figure 70 : example of decl of DEFINE_INSN_RESERVATION pattern
Next check_usage checks whether there is any CPU unit not refered.
3147 static void
3148 check_usage (void) in genautomata.c
3149 {
3150 decl_t decl;
3151 int i;
3152
3153 for (i = 0; i < description ->decls_num; i++)
3154 {
3155 decl = description ->decls [i];
3156 if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used)
3157 {
3158 if (!w_flag )
3159 error ("unit `%s' is not used", DECL_UNIT (decl)->name);
3160 else
3161 warning ("unit `%s' is not used", DECL_UNIT (decl)->name);
3162 }
3163 else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
3164 {
3165 if (!w_flag )
3166 error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
3167 else
3168 warning ("reservation `%s' is not used", DECL_RESERV (decl)->name);
3169 }
3170 }
3171 }
Introducing define_reservation brings the risk of loop of references among patterns of this kind. This kind of error is fatal and shouldn’t go ahead. So we need the checking here.
3239 static void
3240 check_loops_in_regexps (void) in genautomata.c
3241 {
3242 decl_t decl;
3243 int i;
3244
3245 for (i = 0; i < description ->decls_num; i++)
3246 {
3247 decl = description ->decls [i];
3248 if (decl->mode == dm_reserv)
3249 DECL_RESERV (decl)->loop_pass_num = 0;
3250 }
3251 for (i = 0; i < description ->decls_num; i++)
3252 {
3253 decl = description ->decls [i];
3254 curr_loop_pass_num = i;
3255
3256 if (decl->mode == dm_reserv)
3257 {
3258 DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num ;
3259 if (loop_in_regexp (DECL_RESERV (decl)->regexp, decl))
3260 {
3261 if (DECL_RESERV (decl)->regexp == NULL)
3262 abort ();
3263 error ("cycle in definition of reservation `%s'",
3264 DECL_RESERV (decl)->name);
3265 }
3266 }
3267 }
3268 }
In process_regexp , define_reservation only be expanded once. That is, for example, exsiting define_reservation patterns A and B, they refer each other. By process_regexp , we will get following expanded form ( à means reference, ßß means expand to include the referring part):
a à A à B ßß A (decl_reserv)
b à B à A ßß B (decl_reserv)
It is the case we must prevent. In check_loops_in_regexps , first resets loop_pass_num of all define_reservation patterns. In FOR loop at line 3251 , one of define_reservation patterns referred each other must be processed first, at which time the define_reservation pattern it refers still has loop_pass_num as 0, and enters ELSE block at line 3198 for the processing. As start_declis always the first pattern, it satisfies condition at line 3191, and finds out the loop reference. And condition at line 3194 allows multiple non-loop references of define_reservation patterns.
3180 static int
3181 loop_in_regexp (regexp_t regexp, decl_t start_decl) in genautomata.c
3182 {
3183 int i;
3184
3185 if (regexp == NULL)
3186 return 0;
3187 if (regexp->mode == rm_unit)
3188 return 0;
3189 else if (regexp->mode == rm_reserv)
3190 {
3191 if (start_decl->mode == dm_reserv
3192 && REGEXP_RESERV (regexp)->reserv_decl == DECL_RESERV (start_decl))
3193 return 1;
3194 else if (REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
3195 == curr_loop_pass_num )
3196 /* declaration has been processed. */
3197 return 0;
3198 else
3199 {
3200 REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
3201 = curr_loop_pass_num ;
3202 return loop_in_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp,
3203 start_decl);
3204 }
3205 }
3206 else if (regexp->mode == rm_sequence)
3207 {
3208 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3209 if (loop_in_regexp (REGEXP_SEQUENCE (regexp)->regexps [i], start_decl))
3210 return 1;
3211 return 0;
3212 }
3213 else if (regexp->mode == rm_allof)
3214 {
3215 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3216 if (loop_in_regexp (REGEXP_ALLOF (regexp)->regexps [i], start_decl))
3217 return 1;
3218 return 0;
3219 }
3220 else if (regexp->mode == rm_oneof)
3221 {
3222 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3223 if (loop_in_regexp (REGEXP_ONEOF (regexp)->regexps [i], start_decl))
3224 return 1;
3225 return 0;
3226 }
3227 else if (regexp->mode == rm_repeat)
3228 return loop_in_regexp (REGEXP_REPEAT (regexp)->regexp, start_decl);
3229 else
3230 {
3231 if (regexp->mode != rm_nothing)
3232 abort ();
3233 return 0;
3234 }
3235 }
Following, in check_all_description , evaluate_max_reserv_cycles is invoked, in which the global variable description will record the maximum cycles appear in define_insn_reservation patterns.
3362 static void
3363 evaluate_max_reserv_cycles (void) in genautomata.c
3364 {
3365 int max_insn_cycles_num;
3366 int min_insn_cycles_num;
3367 decl_t decl;
3368 int i;
3369
3370 description ->max_insn_reserv_cycles = 0;
3371 for (i = 0; i < description ->decls_num; i++)
3372 {
3373 decl = description ->decls [i];
3374 if (decl->mode == dm_insn_reserv)
3375 {
3376 process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0,
3377 &max_insn_cycles_num, &min_insn_cycles_num);
3378 if (description ->max_insn_reserv_cycles < max_insn_cycles_num)
3379 description ->max_insn_reserv_cycles = max_insn_cycles_num;
3380 }
3381 }
3382 description ->max_insn_reserv_cycles++;
3383 }
We need maximum and minimum number of cycle, because in below, a bitmap will be created and associated with every state to indicate resource allocation (usage). The size of the bitmap is decided by units number mutiply with (maximum cycle number – minimux cycle number).
process_regexp_cycles recurses down into the regexp , and sets max_occ_cycle_num and min_occ_cycle_num field of unit_decl accordingly.
3272 static void
3273 process_regexp_cycles (regexp_t regexp, int max_start_cycle, in genautomata.c
3274 int min_start_cycle, int *max_finish_cycle,
3275 int *min_finish_cycle)
3276 {
3277 int i;
3278
3279 if (regexp->mode == rm_unit)
3280 {
3281 if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle)
3282 REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle;
3283 if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle
3284 || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1)
3285 REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle;
3286 *max_finish_cycle = max_start_cycle;
3287 *min_finish_cycle = min_start_cycle;
3288 }
3289 else if (regexp->mode == rm_reserv)
3290 process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
3291 max_start_cycle, min_start_cycle,
3292 max_finish_cycle, min_finish_cycle);
3293 else if (regexp->mode == rm_repeat)
3294 {
3295 for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++)
3296 {
3297 process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
3298 max_start_cycle, min_start_cycle,
3299 max_finish_cycle, min_finish_cycle);
3300 max_start_cycle = *max_finish_cycle + 1;
3301 min_start_cycle = *min_finish_cycle + 1;
3302 }
3303 }
3304 else if (regexp->mode == rm_sequence)
3305 {
3306 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3307 {
3308 process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
3309 max_start_cycle, min_start_cycle,
3310 max_finish_cycle, min_finish_cycle);
3311 max_start_cycle = *max_finish_cycle + 1;
3312 min_start_cycle = *min_finish_cycle + 1;
3313 }
3314 }
3315 else if (regexp->mode == rm_allof)
3316 {
3317 int max_cycle = 0;
3318 int min_cycle = 0;
3319
3320 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3321 {
3322 process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
3323 max_start_cycle, min_start_cycle,
3324 max_finish_cycle, min_finish_cycle);
3325 if (max_cycle < *max_finish_cycle)
3326 max_cycle = *max_finish_cycle;
3327 if (i == 0 || min_cycle > *min_finish_cycle)
3328 min_cycle = *min_finish_cycle;
3329 }
3330 *max_finish_cycle = max_cycle;
3331 *min_finish_cycle = min_cycle;
3332 }
3333 else if (regexp->mode == rm_oneof)
3334 {
3335 int max_cycle = 0;
3336 int min_cycle = 0;
3337
3338 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3339 {
3340 process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
3341 max_start_cycle, min_start_cycle,
3342 max_finish_cycle, min_finish_cycle);
3343 if (max_cycle < *max_finish_cycle)
3344 max_cycle = *max_finish_cycle;
3345 if (i == 0 || min_cycle > *min_finish_cycle)
3346 min_cycle = *min_finish_cycle;
3347 }
3348 *max_finish_cycle = max_cycle;
3349 *min_finish_cycle = min_cycle;
3350 }
3351 else
3352 {
3353 if (regexp->mode != rm_nothing)
3354 abort ();
3355 *max_finish_cycle = max_start_cycle;
3356 *min_finish_cycle = min_start_cycle;
3357 }
3358 }