GCC后端及汇编发布(24)

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 }

 

最后,我们可以得到以下的数据结构。

t70

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 }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值