GCC后端及汇编发布(24)
2011-06-04 09:52
501 查看
9.5.7.5.
处理
decl
的第五、第六个循环
– DECL_PRESENCE
,
DECL_ABSENCE
类似的,第五个循环把present_set
模式的
decl
与对应的
define_cpu_unit
模式的
decls
。这个处理与第四个循环所做的相似(参考
DEFINE_INSN_RESERVATION模式的概览
)。
process_decls (continued)
2992
/* Check presence
set declarations and form presence sets.
*/
2993
for
(i = 0; i
< description
->decls_num;
i++)
2994
{
2995
decl = description
->decls [i];
2996
if (decl->mode == dm_presence)
2997
{
2998
unit_set_el_t
unit_set_el_list;
2999
pattern_set_el_t pattern_set_el_list;
3000
3001
unit_set_el_list
3002
= process_presence_absence_names
3003
(DECL_PRESENCE (decl)->names, DECL_PRESENCE
(decl)->names_num,
3004
decl->pos,
TRUE, DECL_PRESENCE (decl)->final_p);
3005
pattern_set_el_list
3006
= process_presence_absence_patterns
3007
(DECL_PRESENCE (decl)->patterns,
3008
DECL_PRESENCE (decl)->patterns_num,
3009
decl->pos, TRUE, DECL_PRESENCE
(decl)->final_p);
3010
add_presence_absence
(unit_set_el_list, pattern_set_el_list,
3011
decl->pos, TRUE,
3012
DECL_PRESENCE
(decl)->final_p);
3013
}
3014
}
然后第六个循环把
absent_set
模式的
decl
与
define_cpu_unit
模式的
decl
绑定起来。这个处理与上个循环的处理相似
(
参见
DEFINE_INSN_RESERVATION
模式的概览
)
。
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
}
在
3023
行的
pattern_set_el_t
被
typedef
为以下
pattern_set_el
的指针类型
,
这个结构体将构成一个链表。因为这些模式的第二个操作数是一个列表
,
而其中的每个元素又是由空格分隔的功能单元列表
,
所以在
1056
行的
unit_decls
被声明为
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
};
在
读入
EXCLUSION_SET模式
一节,我们知道参数
names
是记录模式第一个操作数的数组,这里通过
process_presence_absence_names
从这个数组构建出一个
unit_set_el_t
链表,绑定了对应功能单元的
decl
。
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
}
类似的,参数
patterns
则是记录模式第二个操作数的数组,这里面也只有代表模式名的字符串,需要通过
process_presence_absence_patterns
来绑定对应的功能单元的
decl
。
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
}
注意
pattern_set_el
结构体中
unit_decls
域所需的内存也在
2618
行一起分配了。因为每个这样的模式只是管中窥豹,要把这些局部视角组合起来,才能看到这个功能单元整体的约束情况。因此需要
add_presence_absence
来整合这些信息。
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
}
看到在
2713
行的“
dst->unit_decl->excl_list
”是在上一节准备的。注意上面
presence
及
absence
约束之间的矛盾,只要不会导致致命的错误,是不加处理的,因为由此生成的自动机是可以识别及避开这些矛盾的。
9.5.7.6.
验证
decl
注意到所有的decl
仍旧保留在
decls
数组中。上述的循环只是把相关的
decl
绑定在一起。之后
check_automaton_usage
检查是否有未被使用的自动机——即没有绑定
CPU
单元(参考
处理
decl的第二个循环
–
DECL_UNIT
,
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.
处理
DECL_RESERV
及
DECL_INSN_RESERV
我们已经看过,define_insn_reservation
的
decl
的
regexp
部分描述了在
CPU
周期中,指令所使用的
CPU
单元。
process_regexp_decls
把所有感兴趣的单元的
decl
放入哈希表
decl_table
中,并在
define_reservation
及
define_insn_reserv
里绑定对应单元的
decl
。
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
}
regexp
部分的生成参考
读入
DEFINE_RESERVATION模式
一节。在机器描述文件里,模式
DEFINE_RESERVATION
,在使用处,与普通的单元无二无别,在构建入
regexp
时,它将给定为
rm_unit
类型。不过,对应单元的
decl
可以明白告知,因此在
3088
行要进行检查,并更新之。
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
}
最后,我们可以得到以下的数据结构。
图
70
:
DEFINE_INSN_RESERVATION
模式的
decl
的例子
接下来,
check_usage
检查是否存在未被引用的
CPU
单元。
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
}
引入
define_reservation
带来了在这类模式中循环引用的危险性。这种错误是致命的,因此我们需要在这里检查这个情况。
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
}
在
process_regexp
里,
define_reservation
仅展开一次。如果存在
define_reservation
模式
A
及
B
,它们相互引用。由
process_regexp
,我们将得到如下的展开形式(
à
表示引用,
ßß
表示展开到所引用部分):
a
à
A
à
B
ßß
A (decl_reserv)
b
à
B
à
A
ßß
B (decl_reserv)
这是我们必须要防止的情形。在
check_loops_in_regexps
里,首先把所有
define_reservation
模式的
loop_pass_num
重置为
0
。在
3251
行的
FOR
循环里,相互引用的
define_reservation
模式必有一个首先得到处理,此时它所引用的
define_reservation
模式的
loop_pass_num
仍然为
0
,将进入
3198
行的
ELSE
块,对这个模式进行处理。因为
start_decl
总是第一个模式,
3191
行条件满足,查出了循环引用。而
3194
行的条件则是允许对
define_reservation
模式的多次非循环的引用。
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
}
接着,在
check_all_description
中,
evaluate_max_reserv_cycles
被调用,其中的全局变量
description
将记录在
define_insn_reservation
模式中出现的最大周期数。
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
}
我们需要最大及最小周期数,因为在下面,将构建一个位图并与每个状态关联来显示资源的分配(使用)。这个位图的大小由功能单元数乘以(最大周期数
-
最小周期数)来确定。
process_regexp_cycles
递归进入
regexp
,并相应地设置
unit_decl
的
max_occ_cycle_num
及
min_occ_cycle_num
域。
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
}
相关文章推荐