00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 #include "bconfig.h"
00106 #include "system.h"
00107 #include "coretypes.h"
00108 #include "tm.h"
00109 #include "rtl.h"
00110 #include "obstack.h"
00111 #include "errors.h"
00112 #include "gensupport.h"
00113
00114 #include <math.h>
00115 #include "hashtab.h"
00116 #include "vec.h"
00117
00118 #ifndef CHAR_BIT
00119 #define CHAR_BIT 8
00120 #endif
00121
00122
00123
00124 typedef int pos_t;
00125
00126
00127
00128 typedef unsigned HOST_WIDE_INT set_el_t;
00129
00130
00131
00132 typedef set_el_t *reserv_sets_t;
00133
00134
00135 struct ticker
00136 {
00137
00138
00139
00140 int modified_creation_time;
00141
00142
00143 int incremented_off_time;
00144 };
00145
00146
00147 typedef struct ticker ticker_t;
00148
00149
00150 typedef HOST_WIDE_INT vect_el_t;
00151
00152
00153
00154
00155 struct unit_decl;
00156 struct bypass_decl;
00157 struct result_decl;
00158 struct automaton_decl;
00159 struct unit_pattern_rel_decl;
00160 struct reserv_decl;
00161 struct insn_reserv_decl;
00162 struct decl;
00163 struct unit_regexp;
00164 struct result_regexp;
00165 struct reserv_regexp;
00166 struct nothing_regexp;
00167 struct sequence_regexp;
00168 struct repeat_regexp;
00169 struct allof_regexp;
00170 struct oneof_regexp;
00171 struct regexp;
00172 struct description;
00173 struct unit_set_el;
00174 struct pattern_set_el;
00175 struct pattern_reserv;
00176 struct state;
00177 struct alt_state;
00178 struct arc;
00179 struct ainsn;
00180 struct automaton;
00181 struct state_ainsn_table;
00182
00183
00184 typedef struct unit_decl *unit_decl_t;
00185 typedef struct decl *decl_t;
00186 typedef struct regexp *regexp_t;
00187 typedef struct unit_set_el *unit_set_el_t;
00188 typedef struct pattern_set_el *pattern_set_el_t;
00189 typedef struct pattern_reserv *pattern_reserv_t;
00190 typedef struct alt_state *alt_state_t;
00191 typedef struct state *state_t;
00192 typedef struct arc *arc_t;
00193 typedef struct ainsn *ainsn_t;
00194 typedef struct automaton *automaton_t;
00195 typedef struct automata_list_el *automata_list_el_t;
00196 typedef struct state_ainsn_table *state_ainsn_table_t;
00197
00198
00199 static pos_t no_pos = 0;
00200
00201
00202 static struct obstack irp;
00203
00204
00205
00206
00207 DEF_VEC_P(alt_state_t);
00208 DEF_VEC_ALLOC_P(alt_state_t,heap);
00209 DEF_VEC_P(ainsn_t);
00210 DEF_VEC_ALLOC_P(ainsn_t,heap);
00211 DEF_VEC_P(state_t);
00212 DEF_VEC_ALLOC_P(state_t,heap);
00213 DEF_VEC_P(decl_t);
00214 DEF_VEC_ALLOC_P(decl_t,heap);
00215 DEF_VEC_P(reserv_sets_t);
00216 DEF_VEC_ALLOC_P(reserv_sets_t,heap);
00217
00218 DEF_VEC_I(vect_el_t);
00219 DEF_VEC_ALLOC_I(vect_el_t, heap);
00220 typedef VEC(vect_el_t,heap) *vla_hwint_t;
00221
00222
00223 static regexp_t gen_regexp_sequence (const char *);
00224 static void reserv_sets_or (reserv_sets_t, reserv_sets_t,
00225 reserv_sets_t);
00226 static reserv_sets_t get_excl_set (reserv_sets_t);
00227 static int check_presence_pattern_sets (reserv_sets_t,
00228 reserv_sets_t, int);
00229 static int check_absence_pattern_sets (reserv_sets_t, reserv_sets_t,
00230 int);
00231 static arc_t first_out_arc (state_t);
00232 static arc_t next_out_arc (arc_t);
00233
00234
00235
00236
00237
00238
00239
00240 #define NO_MINIMIZATION_OPTION "-no-minimization"
00241
00242 #define TIME_OPTION "-time"
00243
00244 #define V_OPTION "-v"
00245
00246 #define W_OPTION "-w"
00247
00248 #define NDFA_OPTION "-ndfa"
00249
00250 #define PROGRESS_OPTION "-progress"
00251
00252
00253
00254
00255 static int ndfa_flag;
00256
00257
00258 static int no_minimization_flag;
00259
00260
00261
00262
00263
00264
00265 static int split_argument;
00266
00267
00268 static int time_flag;
00269
00270
00271
00272 static int v_flag;
00273
00274
00275
00276 static int progress_flag;
00277
00278
00279
00280 static int w_flag;
00281
00282
00283
00284
00285 static FILE *output_file;
00286
00287
00288
00289 static FILE *output_description_file;
00290
00291
00292 static char *output_description_file_name;
00293
00294
00295
00296 static struct description *description;
00297
00298
00299
00300
00301
00302 enum decl_mode
00303 {
00304 dm_unit,
00305 dm_bypass,
00306 dm_automaton,
00307 dm_excl,
00308 dm_presence,
00309 dm_absence,
00310 dm_reserv,
00311 dm_insn_reserv
00312 };
00313
00314
00315
00316 struct unit_decl
00317 {
00318 const char *name;
00319
00320 const char *automaton_name;
00321
00322
00323 char query_p;
00324
00325
00326
00327
00328
00329 char unit_is_used;
00330
00331
00332
00333 int unit_num;
00334
00335
00336
00337 struct automaton_decl *automaton_decl;
00338
00339
00340
00341 int max_occ_cycle_num;
00342
00343
00344
00345 int min_occ_cycle_num;
00346
00347
00348 unit_set_el_t excl_list;
00349
00350
00351 pattern_set_el_t presence_list;
00352 pattern_set_el_t final_presence_list;
00353
00354
00355 pattern_set_el_t absence_list;
00356 pattern_set_el_t final_absence_list;
00357
00358
00359 int query_num;
00360
00361
00362 int last_distribution_check_cycle;
00363
00364
00365
00366
00367
00368 int corresponding_automaton_num;
00369
00370
00371
00372
00373 char in_set_p;
00374 };
00375
00376
00377 struct bypass_decl
00378 {
00379 int latency;
00380 const char *out_insn_name;
00381 const char *in_insn_name;
00382 const char *bypass_guard_name;
00383
00384
00385
00386
00387 struct insn_reserv_decl *out_insn_reserv;
00388 struct insn_reserv_decl *in_insn_reserv;
00389
00390 struct bypass_decl *next;
00391 };
00392
00393
00394 struct automaton_decl
00395 {
00396 const char *name;
00397
00398
00399
00400
00401
00402 char automaton_is_used;
00403
00404
00405
00406
00407
00408
00409
00410 automaton_t corresponding_automaton;
00411 };
00412
00413
00414
00415 struct excl_rel_decl
00416 {
00417 int all_names_num;
00418 int first_list_length;
00419 char *names [1];
00420 };
00421
00422
00423
00424 struct unit_pattern_rel_decl
00425 {
00426 int final_p;
00427 int names_num;
00428 int patterns_num;
00429 char **names;
00430 char ***patterns;
00431 };
00432
00433
00434 struct reserv_decl
00435 {
00436 const char *name;
00437 regexp_t regexp;
00438
00439
00440
00441
00442
00443 char reserv_is_used;
00444
00445
00446 int loop_pass_num;
00447 };
00448
00449
00450 struct insn_reserv_decl
00451 {
00452 rtx condexp;
00453 int default_latency;
00454 regexp_t regexp;
00455 const char *name;
00456
00457
00458
00459
00460
00461 int insn_num;
00462
00463
00464 struct bypass_decl *bypass_list;
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 regexp_t transformed_regexp;
00475
00476
00477 arc_t arcs_marked_by_insn;
00478
00479
00480
00481
00482
00483 int equiv_class_num;
00484
00485
00486 automata_list_el_t important_automata_list;
00487
00488 int processed_p;
00489 };
00490
00491
00492 struct decl
00493 {
00494
00495 enum decl_mode mode;
00496 pos_t pos;
00497 union
00498 {
00499 struct unit_decl unit;
00500 struct bypass_decl bypass;
00501 struct automaton_decl automaton;
00502 struct excl_rel_decl excl;
00503 struct unit_pattern_rel_decl presence;
00504 struct unit_pattern_rel_decl absence;
00505 struct reserv_decl reserv;
00506 struct insn_reserv_decl insn_reserv;
00507 } decl;
00508 };
00509
00510
00511 enum regexp_mode
00512 {
00513 rm_unit,
00514 rm_reserv,
00515 rm_nothing,
00516 rm_sequence,
00517 rm_repeat,
00518 rm_allof,
00519 rm_oneof
00520 };
00521
00522
00523 struct unit_regexp
00524 {
00525 const char *name;
00526 unit_decl_t unit_decl;
00527 };
00528
00529
00530 struct reserv_regexp
00531 {
00532 const char *name;
00533 struct reserv_decl *reserv_decl;
00534 };
00535
00536
00537 struct nothing_regexp
00538 {
00539
00540 char unused;
00541 };
00542
00543
00544
00545 struct sequence_regexp
00546 {
00547 int regexps_num;
00548 regexp_t regexps [1];
00549 };
00550
00551
00552 struct repeat_regexp
00553 {
00554 int repeat_num;
00555 regexp_t regexp;
00556 };
00557
00558
00559
00560 struct allof_regexp
00561 {
00562 int regexps_num;
00563 regexp_t regexps [1];
00564 };
00565
00566
00567
00568 struct oneof_regexp
00569 {
00570 int regexps_num;
00571 regexp_t regexps [1];
00572 };
00573
00574
00575 struct regexp
00576 {
00577
00578 enum regexp_mode mode;
00579 pos_t pos;
00580 union
00581 {
00582 struct unit_regexp unit;
00583 struct reserv_regexp reserv;
00584 struct nothing_regexp nothing;
00585 struct sequence_regexp sequence;
00586 struct repeat_regexp repeat;
00587 struct allof_regexp allof;
00588 struct oneof_regexp oneof;
00589 } regexp;
00590 };
00591
00592
00593
00594 struct description
00595 {
00596 int decls_num;
00597
00598
00599
00600
00601
00602 int units_num;
00603 int query_units_num;
00604 int insns_num;
00605
00606
00607
00608 int max_insn_reserv_cycles;
00609
00610
00611
00612
00613 automaton_t first_automaton;
00614
00615
00616
00617
00618
00619 decl_t decls [1];
00620 };
00621
00622
00623
00624
00625
00626
00627 struct unit_set_el
00628 {
00629 unit_decl_t unit_decl;
00630 unit_set_el_t next_unit_set_el;
00631 };
00632
00633
00634
00635
00636 struct pattern_set_el
00637 {
00638
00639 int units_num;
00640
00641 struct unit_decl **unit_decls;
00642 pattern_set_el_t next_pattern_set_el;
00643 };
00644
00645
00646
00647
00648
00649
00650
00651
00652 struct pattern_reserv
00653 {
00654 reserv_sets_t reserv;
00655 pattern_reserv_t next_pattern_reserv;
00656 };
00657
00658
00659
00660
00661
00662
00663 struct state
00664 {
00665
00666
00667 int new_cycle_p;
00668
00669
00670 reserv_sets_t reservs;
00671
00672
00673 int unique_num;
00674
00675
00676 automaton_t automaton;
00677
00678
00679 arc_t first_out_arc;
00680 unsigned int num_out_arcs;
00681
00682 char it_was_placed_in_stack_for_NDFA_forming;
00683
00684 char it_was_placed_in_stack_for_DFA_forming;
00685
00686
00687
00688
00689
00690
00691 alt_state_t component_states;
00692
00693 int pass_num;
00694
00695
00696 state_t next_equiv_class_state;
00697
00698
00699 int equiv_class_num_1, equiv_class_num_2;
00700
00701
00702
00703 state_t equiv_class_state;
00704 unsigned int *presence_signature;
00705
00706
00707
00708 int order_state_num;
00709
00710
00711 int state_pass_num;
00712
00713
00714 int min_insn_issue_delay;
00715
00716
00717
00718
00719 int longest_path_length;
00720 };
00721
00722
00723
00724 #define UNDEFINED_LONGEST_PATH_LENGTH -1
00725
00726
00727 struct arc
00728 {
00729
00730
00731 state_t to_state;
00732
00733
00734
00735
00736 ainsn_t insn;
00737
00738
00739 arc_t next_out_arc;
00740
00741
00742 arc_t next_arc_marked_by_insn;
00743 };
00744
00745
00746
00747
00748 struct alt_state
00749 {
00750
00751
00752 state_t state;
00753
00754
00755 alt_state_t next_alt_state;
00756
00757 alt_state_t next_sorted_alt_state;
00758 };
00759
00760
00761
00762 struct ainsn
00763 {
00764
00765
00766 struct insn_reserv_decl *insn_reserv_decl;
00767
00768
00769 ainsn_t next_ainsn;
00770
00771
00772
00773 alt_state_t alt_states;
00774
00775
00776
00777 alt_state_t sorted_alt_states;
00778
00779
00780 ainsn_t next_same_reservs_insn;
00781
00782
00783
00784
00785
00786 char first_insn_with_same_reservs;
00787
00788
00789 char arc_exists_p;
00790
00791
00792 ainsn_t next_equiv_class_insn;
00793
00794
00795 char first_ainsn_with_given_equivalence_num;
00796
00797
00798
00799 int insn_equiv_class_num;
00800
00801
00802
00803 int important_p;
00804 };
00805
00806
00807 struct automaton
00808 {
00809
00810
00811 ainsn_t ainsn_list;
00812
00813
00814
00815 struct automaton_decl *corresponding_automaton_decl;
00816
00817 automaton_t next_automaton;
00818
00819
00820 state_t start_state;
00821
00822
00823
00824 int insn_equiv_classes_num;
00825
00826 int achieved_states_num;
00827
00828
00829 int automaton_order_num;
00830
00831
00832 int NDFA_states_num, DFA_states_num;
00833
00834
00835 int minimal_DFA_states_num;
00836 int NDFA_arcs_num, DFA_arcs_num;
00837
00838
00839 int minimal_DFA_arcs_num;
00840
00841
00842 state_ainsn_table_t trans_table;
00843
00844
00845 int max_min_delay;
00846
00847
00848
00849 int min_issue_delay_table_compression_factor;
00850
00851 int locked_states;
00852 };
00853
00854
00855 struct automata_list_el
00856 {
00857
00858 automaton_t automaton;
00859
00860 automata_list_el_t next_automata_list_el;
00861 };
00862
00863
00864 struct state_ainsn_table
00865 {
00866
00867 automaton_t automaton;
00868
00869
00870 vla_hwint_t comb_vect;
00871 vla_hwint_t check_vect;
00872 vla_hwint_t base_vect;
00873
00874 vla_hwint_t full_vect;
00875
00876 int min_comb_vect_el_value, max_comb_vect_el_value;
00877 int min_base_vect_el_value, max_base_vect_el_value;
00878 };
00879
00880
00881
00882
00883 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
00884
00885 #define DECL_UNIT(d) __extension__ \
00886 (({ struct decl *const _decl = (d); \
00887 if (_decl->mode != dm_unit) \
00888 decl_mode_check_failed (_decl->mode, "dm_unit", \
00889 __FILE__, __LINE__, __FUNCTION__); \
00890 &(_decl)->decl.unit; }))
00891
00892 #define DECL_BYPASS(d) __extension__ \
00893 (({ struct decl *const _decl = (d); \
00894 if (_decl->mode != dm_bypass) \
00895 decl_mode_check_failed (_decl->mode, "dm_bypass", \
00896 __FILE__, __LINE__, __FUNCTION__); \
00897 &(_decl)->decl.bypass; }))
00898
00899 #define DECL_AUTOMATON(d) __extension__ \
00900 (({ struct decl *const _decl = (d); \
00901 if (_decl->mode != dm_automaton) \
00902 decl_mode_check_failed (_decl->mode, "dm_automaton", \
00903 __FILE__, __LINE__, __FUNCTION__); \
00904 &(_decl)->decl.automaton; }))
00905
00906 #define DECL_EXCL(d) __extension__ \
00907 (({ struct decl *const _decl = (d); \
00908 if (_decl->mode != dm_excl) \
00909 decl_mode_check_failed (_decl->mode, "dm_excl", \
00910 __FILE__, __LINE__, __FUNCTION__); \
00911 &(_decl)->decl.excl; }))
00912
00913 #define DECL_PRESENCE(d) __extension__ \
00914 (({ struct decl *const _decl = (d); \
00915 if (_decl->mode != dm_presence) \
00916 decl_mode_check_failed (_decl->mode, "dm_presence", \
00917 __FILE__, __LINE__, __FUNCTION__); \
00918 &(_decl)->decl.presence; }))
00919
00920 #define DECL_ABSENCE(d) __extension__ \
00921 (({ struct decl *const _decl = (d); \
00922 if (_decl->mode != dm_absence) \
00923 decl_mode_check_failed (_decl->mode, "dm_absence", \
00924 __FILE__, __LINE__, __FUNCTION__); \
00925 &(_decl)->decl.absence; }))
00926
00927 #define DECL_RESERV(d) __extension__ \
00928 (({ struct decl *const _decl = (d); \
00929 if (_decl->mode != dm_reserv) \
00930 decl_mode_check_failed (_decl->mode, "dm_reserv", \
00931 __FILE__, __LINE__, __FUNCTION__); \
00932 &(_decl)->decl.reserv; }))
00933
00934 #define DECL_INSN_RESERV(d) __extension__ \
00935 (({ struct decl *const _decl = (d); \
00936 if (_decl->mode != dm_insn_reserv) \
00937 decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
00938 __FILE__, __LINE__, __FUNCTION__); \
00939 &(_decl)->decl.insn_reserv; }))
00940
00941 static const char *decl_name (enum decl_mode);
00942 static void decl_mode_check_failed (enum decl_mode, const char *,
00943 const char *, int, const char *)
00944 ATTRIBUTE_NORETURN;
00945
00946
00947 static const char *
00948 decl_name (enum decl_mode mode)
00949 {
00950 static char str [100];
00951
00952 if (mode == dm_unit)
00953 return "dm_unit";
00954 else if (mode == dm_bypass)
00955 return "dm_bypass";
00956 else if (mode == dm_automaton)
00957 return "dm_automaton";
00958 else if (mode == dm_excl)
00959 return "dm_excl";
00960 else if (mode == dm_presence)
00961 return "dm_presence";
00962 else if (mode == dm_absence)
00963 return "dm_absence";
00964 else if (mode == dm_reserv)
00965 return "dm_reserv";
00966 else if (mode == dm_insn_reserv)
00967 return "dm_insn_reserv";
00968 else
00969 sprintf (str, "unknown (%d)", (int) mode);
00970 return str;
00971 }
00972
00973
00974
00975 static void
00976 decl_mode_check_failed (enum decl_mode mode, const char *expected_mode_str,
00977 const char *file, int line, const char *func)
00978 {
00979 fprintf
00980 (stderr,
00981 "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
00982 file, line, func, expected_mode_str, decl_name (mode));
00983 exit (1);
00984 }
00985
00986
00987 #define REGEXP_UNIT(r) __extension__ \
00988 (({ struct regexp *const _regexp = (r); \
00989 if (_regexp->mode != rm_unit) \
00990 regexp_mode_check_failed (_regexp->mode, "rm_unit", \
00991 __FILE__, __LINE__, __FUNCTION__); \
00992 &(_regexp)->regexp.unit; }))
00993
00994 #define REGEXP_RESERV(r) __extension__ \
00995 (({ struct regexp *const _regexp = (r); \
00996 if (_regexp->mode != rm_reserv) \
00997 regexp_mode_check_failed (_regexp->mode, "rm_reserv", \
00998 __FILE__, __LINE__, __FUNCTION__); \
00999 &(_regexp)->regexp.reserv; }))
01000
01001 #define REGEXP_SEQUENCE(r) __extension__ \
01002 (({ struct regexp *const _regexp = (r); \
01003 if (_regexp->mode != rm_sequence) \
01004 regexp_mode_check_failed (_regexp->mode, "rm_sequence", \
01005 __FILE__, __LINE__, __FUNCTION__); \
01006 &(_regexp)->regexp.sequence; }))
01007
01008 #define REGEXP_REPEAT(r) __extension__ \
01009 (({ struct regexp *const _regexp = (r); \
01010 if (_regexp->mode != rm_repeat) \
01011 regexp_mode_check_failed (_regexp->mode, "rm_repeat", \
01012 __FILE__, __LINE__, __FUNCTION__); \
01013 &(_regexp)->regexp.repeat; }))
01014
01015 #define REGEXP_ALLOF(r) __extension__ \
01016 (({ struct regexp *const _regexp = (r); \
01017 if (_regexp->mode != rm_allof) \
01018 regexp_mode_check_failed (_regexp->mode, "rm_allof", \
01019 __FILE__, __LINE__, __FUNCTION__); \
01020 &(_regexp)->regexp.allof; }))
01021
01022 #define REGEXP_ONEOF(r) __extension__ \
01023 (({ struct regexp *const _regexp = (r); \
01024 if (_regexp->mode != rm_oneof) \
01025 regexp_mode_check_failed (_regexp->mode, "rm_oneof", \
01026 __FILE__, __LINE__, __FUNCTION__); \
01027 &(_regexp)->regexp.oneof; }))
01028
01029 static const char *regexp_name (enum regexp_mode);
01030 static void regexp_mode_check_failed (enum regexp_mode, const char *,
01031 const char *, int,
01032 const char *) ATTRIBUTE_NORETURN;
01033
01034
01035
01036 static const char *
01037 regexp_name (enum regexp_mode mode)
01038 {
01039 switch (mode)
01040 {
01041 case rm_unit:
01042 return "rm_unit";
01043 case rm_reserv:
01044 return "rm_reserv";
01045 case rm_nothing:
01046 return "rm_nothing";
01047 case rm_sequence:
01048 return "rm_sequence";
01049 case rm_repeat:
01050 return "rm_repeat";
01051 case rm_allof:
01052 return "rm_allof";
01053 case rm_oneof:
01054 return "rm_oneof";
01055 default:
01056 gcc_unreachable ();
01057 }
01058 }
01059
01060
01061
01062 static void
01063 regexp_mode_check_failed (enum regexp_mode mode,
01064 const char *expected_mode_str,
01065 const char *file, int line, const char *func)
01066 {
01067 fprintf
01068 (stderr,
01069 "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
01070 file, line, func, expected_mode_str, regexp_name (mode));
01071 exit (1);
01072 }
01073
01074 #else
01075
01076 #define DECL_UNIT(d) (&(d)->decl.unit)
01077 #define DECL_BYPASS(d) (&(d)->decl.bypass)
01078 #define DECL_AUTOMATON(d) (&(d)->decl.automaton)
01079 #define DECL_EXCL(d) (&(d)->decl.excl)
01080 #define DECL_PRESENCE(d) (&(d)->decl.presence)
01081 #define DECL_ABSENCE(d) (&(d)->decl.absence)
01082 #define DECL_RESERV(d) (&(d)->decl.reserv)
01083 #define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
01084
01085 #define REGEXP_UNIT(r) (&(r)->regexp.unit)
01086 #define REGEXP_RESERV(r) (&(r)->regexp.reserv)
01087 #define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
01088 #define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
01089 #define REGEXP_ALLOF(r) (&(r)->regexp.allof)
01090 #define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
01091
01092 #endif
01093
01094
01095 static void *
01096 create_node (size_t size)
01097 {
01098 void *result;
01099
01100 obstack_blank (&irp, size);
01101 result = obstack_base (&irp);
01102 obstack_finish (&irp);
01103
01104 memset (result, 0, size);
01105 return result;
01106 }
01107
01108
01109 static void *
01110 copy_node (const void *from, size_t size)
01111 {
01112 void *const result = create_node (size);
01113 memcpy (result, from, size);
01114 return result;
01115 }
01116
01117
01118 static const char *
01119 check_name (const char * name, pos_t pos ATTRIBUTE_UNUSED)
01120 {
01121 const char *str;
01122
01123 for (str = name; *str != '\0'; str++)
01124 if (*str == '\"')
01125 error ("Name `%s' contains quotes", name);
01126 return name;
01127 }
01128
01129
01130
01131 static VEC(decl_t,heap) *decls;
01132
01133
01134
01135
01136
01137
01138 static char *
01139 next_sep_el (const char **pstr, int sep, int par_flag)
01140 {
01141 char *out_str;
01142 const char *p;
01143 int pars_num;
01144 int n_spaces;
01145
01146
01147 while (ISSPACE ((int) **pstr))
01148 (*pstr)++;
01149
01150 if (**pstr == '\0')
01151 return NULL;
01152
01153 n_spaces = 0;
01154 for (pars_num = 0, p = *pstr; *p != '\0'; p++)
01155 {
01156 if (par_flag && *p == '(')
01157 pars_num++;
01158 else if (par_flag && *p == ')')
01159 pars_num--;
01160 else if (pars_num == 0 && *p == sep)
01161 break;
01162 if (pars_num == 0 && ISSPACE ((int) *p))
01163 n_spaces++;
01164 else
01165 {
01166 for (; n_spaces != 0; n_spaces--)
01167 obstack_1grow (&irp, p [-n_spaces]);
01168 obstack_1grow (&irp, *p);
01169 }
01170 }
01171 obstack_1grow (&irp, '\0');
01172 out_str = obstack_base (&irp);
01173 obstack_finish (&irp);
01174
01175 *pstr = p;
01176 if (**pstr == sep)
01177 (*pstr)++;
01178
01179 return out_str;
01180 }
01181
01182
01183
01184
01185
01186 static int
01187 n_sep_els (const char *s, int sep, int par_flag)
01188 {
01189 int n;
01190 int pars_num;
01191
01192 if (*s == '\0')
01193 return 0;
01194
01195 for (pars_num = 0, n = 1; *s; s++)
01196 if (par_flag && *s == '(')
01197 pars_num++;
01198 else if (par_flag && *s == ')')
01199 pars_num--;
01200 else if (pars_num == 0 && *s == sep)
01201 n++;
01202
01203 return (pars_num != 0 ? -1 : n);
01204 }
01205
01206
01207
01208
01209
01210
01211 static char **
01212 get_str_vect (const char *str, int *els_num, int sep, int paren_p)
01213 {
01214 int i;
01215 char **vect;
01216 const char **pstr;
01217 char *trail;
01218
01219 *els_num = n_sep_els (str, sep, paren_p);
01220 if (*els_num <= 0)
01221 return NULL;
01222 obstack_blank (&irp, sizeof (char *) * (*els_num + 1));
01223 vect = (char **) obstack_base (&irp);
01224 obstack_finish (&irp);
01225 pstr = &str;
01226 for (i = 0; i < *els_num; i++)
01227 vect [i] = next_sep_el (pstr, sep, paren_p);
01228 trail = next_sep_el (pstr, sep, paren_p);
01229 gcc_assert (!trail);
01230 vect [i] = NULL;
01231 return vect;
01232 }
01233
01234
01235
01236
01237
01238 static void
01239 gen_cpu_unit (rtx def)
01240 {
01241 decl_t decl;
01242 char **str_cpu_units;
01243 int vect_length;
01244 int i;
01245
01246 str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
01247 if (str_cpu_units == NULL)
01248 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
01249 for (i = 0; i < vect_length; i++)
01250 {
01251 decl = create_node (sizeof (struct decl));
01252 decl->mode = dm_unit;
01253 decl->pos = 0;
01254 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
01255 DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
01256 DECL_UNIT (decl)->query_p = 0;
01257 DECL_UNIT (decl)->min_occ_cycle_num = -1;
01258 DECL_UNIT (decl)->in_set_p = 0;
01259 VEC_safe_push (decl_t,heap, decls, decl);
01260 }
01261 }
01262
01263
01264
01265
01266
01267 static void
01268 gen_query_cpu_unit (rtx def)
01269 {
01270 decl_t decl;
01271 char **str_cpu_units;
01272 int vect_length;
01273 int i;
01274
01275 str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',',
01276 FALSE);
01277 if (str_cpu_units == NULL)
01278 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
01279 for (i = 0; i < vect_length; i++)
01280 {
01281 decl = create_node (sizeof (struct decl));
01282 decl->mode = dm_unit;
01283 decl->pos = 0;
01284 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
01285 DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
01286 DECL_UNIT (decl)->query_p = 1;
01287 VEC_safe_push (decl_t,heap, decls, decl);
01288 }
01289 }
01290
01291
01292
01293
01294
01295
01296 static void
01297 gen_bypass (rtx def)
01298 {
01299 decl_t decl;
01300 char **out_insns;
01301 int out_length;
01302 char **in_insns;
01303 int in_length;
01304 int i, j;
01305
01306 out_insns = get_str_vect (XSTR (def, 1), &out_length, ',', FALSE);
01307 if (out_insns == NULL)
01308 fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
01309 in_insns = get_str_vect (XSTR (def, 2), &in_length, ',', FALSE);
01310 if (in_insns == NULL)
01311 fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
01312 for (i = 0; i < out_length; i++)
01313 for (j = 0; j < in_length; j++)
01314 {
01315 decl = create_node (sizeof (struct decl));
01316 decl->mode = dm_bypass;
01317 decl->pos = 0;
01318 DECL_BYPASS (decl)->latency = XINT (def, 0);
01319 DECL_BYPASS (decl)->out_insn_name = out_insns [i];
01320 DECL_BYPASS (decl)->in_insn_name = in_insns [j];
01321 DECL_BYPASS (decl)->bypass_guard_name = XSTR (def, 3);
01322 VEC_safe_push (decl_t,heap, decls, decl);
01323 }
01324 }
01325
01326
01327
01328
01329
01330
01331 static void
01332 gen_excl_set (rtx def)
01333 {
01334 decl_t decl;
01335 char **first_str_cpu_units;
01336 char **second_str_cpu_units;
01337 int first_vect_length;
01338 int length;
01339 int i;
01340
01341 first_str_cpu_units
01342 = get_str_vect (XSTR (def, 0), &first_vect_length, ',', FALSE);
01343 if (first_str_cpu_units == NULL)
01344 fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
01345 second_str_cpu_units = get_str_vect (XSTR (def, 1), &length, ',',
01346 FALSE);
01347 if (second_str_cpu_units == NULL)
01348 fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
01349 length += first_vect_length;
01350 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
01351 decl->mode = dm_excl;
01352 decl->pos = 0;
01353 DECL_EXCL (decl)->all_names_num = length;
01354 DECL_EXCL (decl)->first_list_length = first_vect_length;
01355 for (i = 0; i < length; i++)
01356 if (i < first_vect_length)
01357 DECL_EXCL (decl)->names [i] = first_str_cpu_units [i];
01358 else
01359 DECL_EXCL (decl)->names [i]
01360 = second_str_cpu_units [i - first_vect_length];
01361 VEC_safe_push (decl_t,heap, decls, decl);
01362 }
01363
01364
01365
01366
01367
01368
01369
01370 static void
01371 gen_presence_absence_set (rtx def, int presence_p, int final_p)
01372 {
01373 decl_t decl;
01374 char **str_cpu_units;
01375 char **str_pattern_lists;
01376 char ***str_patterns;
01377 int cpu_units_length;
01378 int length;
01379 int patterns_length;
01380 int i;
01381
01382 str_cpu_units = get_str_vect (XSTR (def, 0), &cpu_units_length, ',',
01383 FALSE);
01384 if (str_cpu_units == NULL)
01385 fatal ((presence_p
01386 ? (final_p
01387 ? "invalid first string `%s' in final_presence_set"
01388 : "invalid first string `%s' in presence_set")
01389 : (final_p
01390 ? "invalid first string `%s' in final_absence_set"
01391 : "invalid first string `%s' in absence_set")),
01392 XSTR (def, 0));
01393 str_pattern_lists = get_str_vect (XSTR (def, 1),
01394 &patterns_length, ',', FALSE);
01395 if (str_pattern_lists == NULL)
01396 fatal ((presence_p
01397 ? (final_p
01398 ? "invalid second string `%s' in final_presence_set"
01399 : "invalid second string `%s' in presence_set")
01400 : (final_p
01401 ? "invalid second string `%s' in final_absence_set"
01402 : "invalid second string `%s' in absence_set")), XSTR (def, 1));
01403 str_patterns = obstack_alloc (&irp, patterns_length * sizeof (char **));
01404 for (i = 0; i < patterns_length; i++)
01405 {
01406 str_patterns [i] = get_str_vect (str_pattern_lists [i],
01407 &length, ' ', FALSE);
01408 gcc_assert (str_patterns [i]);
01409 }
01410 decl = create_node (sizeof (struct decl));
01411 decl->pos = 0;
01412 if (presence_p)
01413 {
01414 decl->mode = dm_presence;
01415 DECL_PRESENCE (decl)->names_num = cpu_units_length;
01416 DECL_PRESENCE (decl)->names = str_cpu_units;
01417 DECL_PRESENCE (decl)->patterns = str_patterns;
01418 DECL_PRESENCE (decl)->patterns_num = patterns_length;
01419 DECL_PRESENCE (decl)->final_p = final_p;
01420 }
01421 else
01422 {
01423 decl->mode = dm_absence;
01424 DECL_ABSENCE (decl)->names_num = cpu_units_length;
01425 DECL_ABSENCE (decl)->names = str_cpu_units;
01426 DECL_ABSENCE (decl)->patterns = str_patterns;
01427 DECL_ABSENCE (decl)->patterns_num = patterns_length;
01428 DECL_ABSENCE (decl)->final_p = final_p;
01429 }
01430 VEC_safe_push (decl_t,heap, decls, decl);
01431 }
01432
01433
01434
01435
01436
01437
01438 static void
01439 gen_presence_set (rtx def)
01440 {
01441 gen_presence_absence_set (def, TRUE, FALSE);
01442 }
01443
01444
01445
01446
01447
01448
01449 static void
01450 gen_final_presence_set (rtx def)
01451 {
01452 gen_presence_absence_set (def, TRUE, TRUE);
01453 }
01454
01455
01456
01457
01458
01459
01460 static void
01461 gen_absence_set (rtx def)
01462 {
01463 gen_presence_absence_set (def, FALSE, FALSE);
01464 }
01465
01466
01467
01468
01469
01470
01471 static void
01472 gen_final_absence_set (rtx def)
01473 {
01474 gen_presence_absence_set (def, FALSE, TRUE);
01475 }
01476
01477
01478
01479
01480
01481
01482 static void
01483 gen_automaton (rtx def)
01484 {
01485 decl_t decl;
01486 char **str_automata;
01487 int vect_length;
01488 int i;
01489
01490 str_automata = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
01491 if (str_automata == NULL)
01492 fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
01493 for (i = 0; i < vect_length; i++)
01494 {
01495 decl = create_node (sizeof (struct decl));
01496 decl->mode = dm_automaton;
01497 decl->pos = 0;
01498 DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
01499 VEC_safe_push (decl_t,heap, decls, decl);
01500 }
01501 }
01502
01503
01504
01505
01506
01507 static void
01508 gen_automata_option (rtx def)
01509 {
01510 if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
01511 no_minimization_flag = 1;
01512 else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
01513 time_flag = 1;
01514 else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
01515 v_flag = 1;
01516 else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
01517 w_flag = 1;
01518 else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
01519 ndfa_flag = 1;
01520 else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
01521 progress_flag = 1;
01522 else
01523 fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
01524 }
01525
01526
01527 #define NOTHING_NAME "nothing"
01528
01529
01530
01531 static const char *reserv_str;
01532
01533
01534 static regexp_t
01535 gen_regexp_el (const char *str)
01536 {
01537 regexp_t regexp;
01538 char *dstr;
01539 int len;
01540
01541 if (*str == '(')
01542 {
01543 len = strlen (str);
01544 if (str [len - 1] != ')')
01545 fatal ("garbage after ) in reservation `%s'", reserv_str);
01546 dstr = alloca (len - 1);
01547 memcpy (dstr, str + 1, len - 2);
01548 dstr [len-2] = '\0';
01549 regexp = gen_regexp_sequence (dstr);
01550 }
01551 else if (strcmp (str, NOTHING_NAME) == 0)
01552 {
01553 regexp = create_node (sizeof (struct decl));
01554 regexp->mode = rm_nothing;
01555 }
01556 else
01557 {
01558 regexp = create_node (sizeof (struct decl));
01559 regexp->mode = rm_unit;
01560 REGEXP_UNIT (regexp)->name = str;
01561 }
01562 return regexp;
01563 }
01564
01565
01566 static regexp_t
01567 gen_regexp_repeat (const char *str)
01568 {
01569 regexp_t regexp;
01570 regexp_t repeat;
01571 char **repeat_vect;
01572 int els_num;
01573 int i;
01574
01575 repeat_vect = get_str_vect (str, &els_num, '*', TRUE);
01576 if (repeat_vect == NULL)
01577 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
01578 if (els_num > 1)
01579 {
01580 regexp = gen_regexp_el (repeat_vect [0]);
01581 for (i = 1; i < els_num; i++)
01582 {
01583 repeat = create_node (sizeof (struct regexp));
01584 repeat->mode = rm_repeat;
01585 REGEXP_REPEAT (repeat)->regexp = regexp;
01586 REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]);
01587 if (REGEXP_REPEAT (repeat)->repeat_num <= 1)
01588 fatal ("repetition `%s' <= 1 in reservation `%s'",
01589 str, reserv_str);
01590 regexp = repeat;
01591 }
01592 return regexp;
01593 }
01594 else
01595 return gen_regexp_el (str);
01596 }
01597
01598
01599 static regexp_t
01600 gen_regexp_allof (const char *str)
01601 {
01602 regexp_t allof;
01603 char **allof_vect;
01604 int els_num;
01605 int i;
01606
01607 allof_vect = get_str_vect (str, &els_num, '+', TRUE);
01608 if (allof_vect == NULL)
01609 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
01610 if (els_num > 1)
01611 {
01612 allof = create_node (sizeof (struct regexp)
01613 + sizeof (regexp_t) * (els_num - 1));
01614 allof->mode = rm_allof;
01615 REGEXP_ALLOF (allof)->regexps_num = els_num;
01616 for (i = 0; i < els_num; i++)
01617 REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]);
01618 return allof;
01619 }
01620 else
01621 return gen_regexp_repeat (str);
01622 }
01623
01624
01625 static regexp_t
01626 gen_regexp_oneof (const char *str)
01627 {
01628 regexp_t oneof;
01629 char **oneof_vect;
01630 int els_num;
01631 int i;
01632
01633 oneof_vect = get_str_vect (str, &els_num, '|', TRUE);
01634 if (oneof_vect == NULL)
01635 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
01636 if (els_num > 1)
01637 {
01638 oneof = create_node (sizeof (struct regexp)
01639 + sizeof (regexp_t) * (els_num - 1));
01640 oneof->mode = rm_oneof;
01641 REGEXP_ONEOF (oneof)->regexps_num = els_num;
01642 for (i = 0; i < els_num; i++)
01643 REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]);
01644 return oneof;
01645 }
01646 else
01647 return gen_regexp_allof (str);
01648 }
01649
01650
01651 static regexp_t
01652 gen_regexp_sequence (const char *str)
01653 {
01654 regexp_t sequence;
01655 char **sequence_vect;
01656 int els_num;
01657 int i;
01658
01659 sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
01660 if (els_num > 1)
01661 {
01662 sequence = create_node (sizeof (struct regexp)
01663 + sizeof (regexp_t) * (els_num - 1));
01664 sequence->mode = rm_sequence;
01665 REGEXP_SEQUENCE (sequence)->regexps_num = els_num;
01666 for (i = 0; i < els_num; i++)
01667 REGEXP_SEQUENCE (sequence)->regexps [i]
01668 = gen_regexp_oneof (sequence_vect [i]);
01669 return sequence;
01670 }
01671 else
01672 return gen_regexp_oneof (str);
01673 }
01674
01675
01676 static regexp_t
01677 gen_regexp (const char *str)
01678 {
01679 reserv_str = str;
01680 return gen_regexp_sequence (str);;
01681 }
01682
01683
01684
01685
01686
01687
01688 static void
01689 gen_reserv (rtx def)
01690 {
01691 decl_t decl;
01692
01693 decl = create_node (sizeof (struct decl));
01694 decl->mode = dm_reserv;
01695 decl->pos = 0;
01696 DECL_RESERV (decl)->name = check_name (XSTR (def, 0), decl->pos);
01697 DECL_RESERV (decl)->regexp = gen_regexp (XSTR (def, 1));
01698 VEC_safe_push (decl_t,heap, decls, decl);
01699 }
01700
01701
01702
01703
01704
01705
01706 static void
01707 gen_insn_reserv (rtx def)
01708 {
01709 decl_t decl;
01710
01711 decl = create_node (sizeof (struct decl));
01712 decl->mode = dm_insn_reserv;
01713 decl->pos = 0;
01714 DECL_INSN_RESERV (decl)->name
01715 = check_name (XSTR (def, 0), decl->pos);
01716 DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
01717 DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
01718 DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3));
01719 VEC_safe_push (decl_t,heap, decls, decl);
01720 }
01721
01722
01723
01724
01725 static unsigned
01726 string_hash (const char *string)
01727 {
01728 unsigned result, i;
01729
01730 for (result = i = 0;*string++ != '\0'; i++)
01731 result += ((unsigned char) *string << (i % CHAR_BIT));
01732 return result;
01733 }
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745 static hashval_t
01746 automaton_decl_hash (const void *automaton_decl)
01747 {
01748 const decl_t decl = (decl_t) automaton_decl;
01749
01750 gcc_assert (decl->mode != dm_automaton
01751 || DECL_AUTOMATON (decl)->name);
01752 return string_hash (DECL_AUTOMATON (decl)->name);
01753 }
01754
01755
01756
01757
01758
01759 static int
01760 automaton_decl_eq_p (const void* automaton_decl_1,
01761 const void* automaton_decl_2)
01762 {
01763 const decl_t decl1 = (decl_t) automaton_decl_1;
01764 const decl_t decl2 = (decl_t) automaton_decl_2;
01765
01766 gcc_assert (decl1->mode == dm_automaton
01767 && DECL_AUTOMATON (decl1)->name
01768 && decl2->mode == dm_automaton
01769 && DECL_AUTOMATON (decl2)->name);
01770 return strcmp (DECL_AUTOMATON (decl1)->name,
01771 DECL_AUTOMATON (decl2)->name) == 0;
01772 }
01773
01774
01775
01776 static htab_t automaton_decl_table;
01777
01778
01779
01780
01781
01782
01783 static decl_t
01784 insert_automaton_decl (decl_t automaton_decl)
01785 {
01786 void **entry_ptr;
01787
01788 entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1);
01789 if (*entry_ptr == NULL)
01790 *entry_ptr = (void *) automaton_decl;
01791 return (decl_t) *entry_ptr;
01792 }
01793
01794
01795
01796
01797 static struct decl work_automaton_decl;
01798
01799
01800
01801
01802
01803 static decl_t
01804 find_automaton_decl (const char *name)
01805 {
01806 void *entry;
01807
01808 work_automaton_decl.mode = dm_automaton;
01809 DECL_AUTOMATON (&work_automaton_decl)->name = name;
01810 entry = htab_find (automaton_decl_table, &work_automaton_decl);
01811 return (decl_t) entry;
01812 }
01813
01814
01815
01816
01817
01818 static void
01819 initiate_automaton_decl_table (void)
01820 {
01821 work_automaton_decl.mode = dm_automaton;
01822 automaton_decl_table = htab_create (10, automaton_decl_hash,
01823 automaton_decl_eq_p, (htab_del) 0);
01824 }
01825
01826
01827
01828
01829 static void
01830 finish_automaton_decl_table (void)
01831 {
01832 htab_delete (automaton_decl_table);
01833 }
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846 static hashval_t
01847 insn_decl_hash (const void *insn_decl)
01848 {
01849 const decl_t decl = (decl_t) insn_decl;
01850
01851 gcc_assert (decl->mode == dm_insn_reserv
01852 && DECL_INSN_RESERV (decl)->name);
01853 return string_hash (DECL_INSN_RESERV (decl)->name);
01854 }
01855
01856
01857
01858
01859 static int
01860 insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2)
01861 {
01862 const decl_t decl1 = (decl_t) insn_decl_1;
01863 const decl_t decl2 = (decl_t) insn_decl_2;
01864
01865 gcc_assert (decl1->mode == dm_insn_reserv
01866 && DECL_INSN_RESERV (decl1)->name
01867 && decl2->mode == dm_insn_reserv
01868 && DECL_INSN_RESERV (decl2)->name);
01869 return strcmp (DECL_INSN_RESERV (decl1)->name,
01870 DECL_INSN_RESERV (decl2)->name) == 0;
01871 }
01872
01873
01874
01875
01876 static htab_t insn_decl_table;
01877
01878
01879
01880
01881
01882 static decl_t
01883 insert_insn_decl (decl_t insn_decl)
01884 {
01885 void **entry_ptr;
01886
01887 entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1);
01888 if (*entry_ptr == NULL)
01889 *entry_ptr = (void *) insn_decl;
01890 return (decl_t) *entry_ptr;
01891 }
01892
01893
01894
01895
01896 static struct decl work_insn_decl;
01897
01898
01899
01900
01901
01902 static decl_t
01903 find_insn_decl (const char *name)
01904 {
01905 void *entry;
01906
01907 work_insn_decl.mode = dm_insn_reserv;
01908 DECL_INSN_RESERV (&work_insn_decl)->name = name;
01909 entry = htab_find (insn_decl_table, &work_insn_decl);
01910 return (decl_t) entry;
01911 }
01912
01913
01914
01915
01916
01917 static void
01918 initiate_insn_decl_table (void)
01919 {
01920 work_insn_decl.mode = dm_insn_reserv;
01921 insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
01922 (htab_del) 0);
01923 }
01924
01925
01926
01927
01928 static void
01929 finish_insn_decl_table (void)
01930 {
01931 htab_delete (insn_decl_table);
01932 }
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944 static hashval_t
01945 decl_hash (const void *decl)
01946 {
01947 const decl_t d = (const decl_t) decl;
01948
01949 gcc_assert ((d->mode == dm_unit && DECL_UNIT (d)->name)
01950 || (d->mode == dm_reserv && DECL_RESERV (d)->name));
01951 return string_hash (d->mode == dm_unit
01952 ? DECL_UNIT (d)->name : DECL_RESERV (d)->name);
01953 }
01954
01955
01956
01957
01958 static int
01959 decl_eq_p (const void *decl_1, const void *decl_2)
01960 {
01961 const decl_t d1 = (const decl_t) decl_1;
01962 const decl_t d2 = (const decl_t) decl_2;
01963
01964 gcc_assert ((d1->mode == dm_unit && DECL_UNIT (d1)->name)
01965 || (d1->mode == dm_reserv && DECL_RESERV (d1)->name));
01966 gcc_assert ((d2->mode == dm_unit && DECL_UNIT (d2)->name)
01967 || (d2->mode == dm_reserv && DECL_RESERV (d2)->name));
01968 return strcmp ((d1->mode == dm_unit
01969 ? DECL_UNIT (d1)->name : DECL_RESERV (d1)->name),
01970 (d2->mode == dm_unit
01971 ? DECL_UNIT (d2)->name : DECL_RESERV (d2)->name)) == 0;
01972 }
01973
01974
01975
01976 static htab_t decl_table;
01977
01978
01979
01980
01981
01982
01983 static decl_t
01984 insert_decl (decl_t decl)
01985 {
01986 void **entry_ptr;
01987
01988 entry_ptr = htab_find_slot (decl_table, decl, 1);
01989 if (*entry_ptr == NULL)
01990 *entry_ptr = (void *) decl;
01991 return (decl_t) *entry_ptr;
01992 }
01993
01994
01995
01996 static struct decl work_decl;
01997
01998
01999
02000
02001
02002 static decl_t
02003 find_decl (const char *name)
02004 {
02005 void *entry;
02006
02007 work_decl.mode = dm_unit;
02008 DECL_UNIT (&work_decl)->name = name;
02009 entry = htab_find (decl_table, &work_decl);
02010 return (decl_t) entry;
02011 }
02012
02013
02014
02015
02016
02017 static void
02018 initiate_decl_table (void)
02019 {
02020 work_decl.mode = dm_unit;
02021 decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
02022 }
02023
02024
02025
02026
02027 static void
02028 finish_decl_table (void)
02029 {
02030 htab_delete (decl_table);
02031 }
02032
02033
02034
02035
02036
02037
02038
02039 static unit_set_el_t
02040 process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED)
02041 {
02042 unit_set_el_t el_list;
02043 unit_set_el_t last_el;
02044 unit_set_el_t new_el;
02045 decl_t decl_in_table;
02046 int i;
02047
02048 el_list = NULL;
02049 last_el = NULL;
02050 for (i = 0; i < num; i++)
02051 {
02052 decl_in_table = find_decl (names [i]);
02053 if (decl_in_table == NULL)
02054 error ("unit `%s' in exclusion is not declared", names [i]);
02055 else if (decl_in_table->mode != dm_unit)
02056 error ("`%s' in exclusion is not unit", names [i]);
02057 else
02058 {
02059 new_el = create_node (sizeof (struct unit_set_el));
02060 new_el->unit_decl = DECL_UNIT (decl_in_table);
02061 new_el->next_unit_set_el = NULL;
02062 if (last_el == NULL)
02063 el_list = last_el = new_el;
02064 else
02065 {
02066 last_el->next_unit_set_el = new_el;
02067 last_el = last_el->next_unit_set_el;
02068 }
02069 }
02070 }
02071 return el_list;
02072 }
02073
02074
02075
02076
02077 static void
02078 add_excls (unit_set_el_t dest_list, unit_set_el_t source_list,
02079 pos_t excl_pos ATTRIBUTE_UNUSED)
02080 {
02081 unit_set_el_t dst;
02082 unit_set_el_t src;
02083 unit_set_el_t curr_el;
02084 unit_set_el_t prev_el;
02085 unit_set_el_t copy;
02086
02087 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
02088 for (src = source_list; src != NULL; src = src->next_unit_set_el)
02089 {
02090 if (dst->unit_decl == src->unit_decl)
02091 {
02092 error ("unit `%s' excludes itself", src->unit_decl->name);
02093 continue;
02094 }
02095 if (dst->unit_decl->automaton_name != NULL
02096 && src->unit_decl->automaton_name != NULL
02097 && strcmp (dst->unit_decl->automaton_name,
02098 src->unit_decl->automaton_name) != 0)
02099 {
02100 error ("units `%s' and `%s' in exclusion set belong to different automata",
02101 src->unit_decl->name, dst->unit_decl->name);
02102 continue;
02103 }
02104 for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
02105 curr_el != NULL;
02106 prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
02107 if (curr_el->unit_decl == src->unit_decl)
02108 break;
02109 if (curr_el == NULL)
02110 {
02111
02112 copy = copy_node (src, sizeof (*src));
02113 copy->next_unit_set_el = NULL;
02114 if (prev_el == NULL)
02115 dst->unit_decl->excl_list = copy;
02116 else
02117 prev_el->next_unit_set_el = copy;
02118 }
02119 }
02120 }
02121
02122
02123
02124
02125 static unit_set_el_t
02126 process_presence_absence_names (char **names, int num,
02127 pos_t req_pos ATTRIBUTE_UNUSED,
02128 int presence_p, int final_p)
02129 {
02130 unit_set_el_t el_list;
02131 unit_set_el_t last_el;
02132 unit_set_el_t new_el;
02133 decl_t decl_in_table;
02134 int i;
02135
02136 el_list = NULL;
02137 last_el = NULL;
02138 for (i = 0; i < num; i++)
02139 {
02140 decl_in_table = find_decl (names [i]);
02141 if (decl_in_table == NULL)
02142 error ((presence_p
02143 ? (final_p
02144 ? "unit `%s' in final presence set is not declared"
02145 : "unit `%s' in presence set is not declared")
02146 : (final_p
02147 ? "unit `%s' in final absence set is not declared"
02148 : "unit `%s' in absence set is not declared")), names [i]);
02149 else if (decl_in_table->mode != dm_unit)
02150 error ((presence_p
02151 ? (final_p
02152 ? "`%s' in final presence set is not unit"
02153 : "`%s' in presence set is not unit")
02154 : (final_p
02155 ? "`%s' in final absence set is not unit"
02156 : "`%s' in absence set is not unit")), names [i]);
02157 else
02158 {
02159 new_el = create_node (sizeof (struct unit_set_el));
02160 new_el->unit_decl = DECL_UNIT (decl_in_table);
02161 new_el->next_unit_set_el = NULL;
02162 if (last_el == NULL)
02163 el_list = last_el = new_el;
02164 else
02165 {
02166 last_el->next_unit_set_el = new_el;
02167 last_el = last_el->next_unit_set_el;
02168 }
02169 }
02170 }
02171 return el_list;
02172 }
02173
02174
02175
02176
02177 static pattern_set_el_t
02178 process_presence_absence_patterns (char ***patterns, int num,
02179 pos_t req_pos ATTRIBUTE_UNUSED,
02180 int presence_p, int final_p)
02181 {
02182 pattern_set_el_t el_list;
02183 pattern_set_el_t last_el;
02184 pattern_set_el_t new_el;
02185 decl_t decl_in_table;
02186 int i, j;
02187
02188 el_list = NULL;
02189 last_el = NULL;
02190 for (i = 0; i < num; i++)
02191 {
02192 for (j = 0; patterns [i] [j] != NULL; j++)
02193 ;
02194 new_el = create_node (sizeof (struct pattern_set_el)
02195 + sizeof (struct unit_decl *) * j);
02196 new_el->unit_decls
02197 = (struct unit_decl **) ((char *) new_el
02198 + sizeof (struct pattern_set_el));
02199 new_el->next_pattern_set_el = NULL;
02200 if (last_el == NULL)
02201 el_list = last_el = new_el;
02202 else
02203 {
02204 last_el->next_pattern_set_el = new_el;
02205 last_el = last_el->next_pattern_set_el;
02206 }
02207 new_el->units_num = 0;
02208 for (j = 0; patterns [i] [j] != NULL; j++)
02209 {
02210 decl_in_table = find_decl (patterns [i] [j]);
02211 if (decl_in_table == NULL)
02212 error ((presence_p
02213 ? (final_p
02214 ? "unit `%s' in final presence set is not declared"
02215 : "unit `%s' in presence set is not declared")
02216 : (final_p
02217 ? "unit `%s' in final absence set is not declared"
02218 : "unit `%s' in absence set is not declared")),
02219 patterns [i] [j]);
02220 else if (decl_in_table->mode != dm_unit)
02221 error ((presence_p
02222 ? (final_p
02223 ? "`%s' in final presence set is not unit"
02224 : "`%s' in presence set is not unit")
02225 : (final_p
02226 ? "`%s' in final absence set is not unit"
02227 : "`%s' in absence set is not unit")),
02228 patterns [i] [j]);
02229 else
02230 {
02231 new_el->unit_decls [new_el->units_num]
02232 = DECL_UNIT (decl_in_table);
02233 new_el->units_num++;
02234 }
02235 }
02236 }
02237 return el_list;
02238 }
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248 static void
02249 add_presence_absence (unit_set_el_t dest_list,
02250 pattern_set_el_t pattern_list,
02251 pos_t req_pos ATTRIBUTE_UNUSED,
02252 int presence_p, int final_p)
02253 {
02254 unit_set_el_t dst;
02255 pattern_set_el_t pat;
02256 struct unit_decl *unit;
02257 unit_set_el_t curr_excl_el;
02258 pattern_set_el_t curr_pat_el;
02259 pattern_set_el_t prev_el;
02260 pattern_set_el_t copy;
02261 int i;
02262 int no_error_flag;
02263
02264 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
02265 for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el)
02266 {
02267 for (i = 0; i < pat->units_num; i++)
02268 {
02269 unit = pat->unit_decls [i];
02270 if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p)
02271 {
02272 error ("unit `%s' requires own absence", unit->name);
02273 continue;
02274 }
02275 if (dst->unit_decl->automaton_name != NULL
02276 && unit->automaton_name != NULL
02277 && strcmp (dst->unit_decl->automaton_name,
02278 unit->automaton_name) != 0)
02279 {
02280 error ((presence_p
02281 ? (final_p
02282 ? "units `%s' and `%s' in final presence set belong to different automata"
02283 : "units `%s' and `%s' in presence set belong to different automata")
02284 : (final_p
02285 ? "units `%s' and `%s' in final absence set belong to different automata"
02286 : "units `%s' and `%s' in absence set belong to different automata")),
02287 unit->name, dst->unit_decl->name);
02288 continue;
02289 }
02290 no_error_flag = 1;
02291 if (presence_p)
02292 for (curr_excl_el = dst->unit_decl->excl_list;
02293 curr_excl_el != NULL;
02294 curr_excl_el = curr_excl_el->next_unit_set_el)
02295 {
02296 if (unit == curr_excl_el->unit_decl && pat->units_num == 1)
02297 {
02298 if (!w_flag)
02299 {
02300 error ("unit `%s' excludes and requires presence of `%s'",
02301 dst->unit_decl->name, unit->name);
02302 no_error_flag = 0;
02303 }
02304 else
02305 warning
02306 (0, "unit `%s' excludes and requires presence of `%s'",
02307 dst->unit_decl->name, unit->name);
02308 }
02309 }
02310 else if (pat->units_num == 1)
02311 for (curr_pat_el = dst->unit_decl->presence_list;
02312 curr_pat_el != NULL;
02313 curr_pat_el = curr_pat_el->next_pattern_set_el)
02314 if (curr_pat_el->units_num == 1
02315 && unit == curr_pat_el->unit_decls [0])
02316 {
02317 if (!w_flag)
02318 {
02319 error
02320 ("unit `%s' requires absence and presence of `%s'",
02321 dst->unit_decl->name, unit->name);
02322 no_error_flag = 0;
02323 }
02324 else
02325 warning
02326 (0, "unit `%s' requires absence and presence of `%s'",
02327 dst->unit_decl->name, unit->name);
02328 }
02329 if (no_error_flag)
02330 {
02331 for (prev_el = (presence_p
02332 ? (final_p
02333 ? dst->unit_decl->final_presence_list
02334 : dst->unit_decl->final_presence_list)
02335 : (final_p
02336 ? dst->unit_decl->final_absence_list
02337 : dst->unit_decl->absence_list));
02338 prev_el != NULL && prev_el->next_pattern_set_el != NULL;
02339 prev_el = prev_el->next_pattern_set_el)
02340 ;
02341 copy = copy_node (pat, sizeof (*pat));
02342 copy->next_pattern_set_el = NULL;
02343 if (prev_el == NULL)
02344 {
02345 if (presence_p)
02346 {
02347 if (final_p)
02348 dst->unit_decl->final_presence_list = copy;
02349 else
02350 dst->unit_decl->presence_list = copy;
02351 }
02352 else if (final_p)
02353 dst->unit_decl->final_absence_list = copy;
02354 else
02355 dst->unit_decl->absence_list = copy;
02356 }
02357 else
02358 prev_el->next_pattern_set_el = copy;
02359 }
02360 }
02361 }
02362 }
02363
02364
02365
02366
02367 static struct bypass_decl *
02368 find_bypass (struct bypass_decl *bypass_list,
02369 struct insn_reserv_decl *in_insn_reserv)
02370 {
02371 struct bypass_decl *bypass;
02372
02373 for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
02374 if (bypass->in_insn_reserv == in_insn_reserv)
02375 break;
02376 return bypass;
02377 }
02378
02379
02380
02381 static void
02382 process_decls (void)
02383 {
02384 decl_t decl;
02385 decl_t automaton_decl;
02386 decl_t decl_in_table;
02387 decl_t out_insn_reserv;
02388 decl_t in_insn_reserv;
02389 struct bypass_decl *bypass;
02390 int automaton_presence;
02391 int i;
02392
02393
02394 automaton_presence = 0;
02395 for (i = 0; i < description->decls_num; i++)
02396 {
02397 decl = description->decls [i];
02398 if (decl->mode == dm_automaton)
02399 {
02400 automaton_presence = 1;
02401 decl_in_table = insert_automaton_decl (decl);
02402 if (decl_in_table != decl)
02403 {
02404 if (!w_flag)
02405 error ("repeated declaration of automaton `%s'",
02406 DECL_AUTOMATON (decl)->name);
02407 else
02408 warning (0, "repeated declaration of automaton `%s'",
02409 DECL_AUTOMATON (decl)->name);
02410 }
02411 }
02412 }
02413
02414
02415
02416 for (i = 0; i < description->decls_num; i++)
02417 {
02418 decl = description->decls [i];
02419 if (decl->mode == dm_insn_reserv)
02420 {
02421 if (DECL_INSN_RESERV (decl)->default_latency < 0)
02422 error ("define_insn_reservation `%s' has negative latency time",
02423 DECL_INSN_RESERV (decl)->name);
02424 DECL_INSN_RESERV (decl)->insn_num = description->insns_num;
02425 description->insns_num++;
02426 decl_in_table = insert_insn_decl (decl);
02427 if (decl_in_table != decl)
02428 error ("`%s' is already used as insn reservation name",
02429 DECL_INSN_RESERV (decl)->name);
02430 }
02431 else if (decl->mode == dm_bypass)
02432 {
02433 if (DECL_BYPASS (decl)->latency < 0)
02434 error ("define_bypass `%s - %s' has negative latency time",
02435 DECL_BYPASS (decl)->out_insn_name,
02436 DECL_BYPASS (decl)->in_insn_name);
02437 }
02438 else if (decl->mode == dm_unit || decl->mode == dm_reserv)
02439 {
02440 if (decl->mode == dm_unit)
02441 {
02442 DECL_UNIT (decl)->automaton_decl = NULL;
02443 if (DECL_UNIT (decl)->automaton_name != NULL)
02444 {
02445 automaton_decl
02446 = find_automaton_decl (DECL_UNIT (decl)->automaton_name);
02447 if (automaton_decl == NULL)
02448 error ("automaton `%s' is not declared",
02449 DECL_UNIT (decl)->automaton_name);
02450 else
02451 {
02452 DECL_AUTOMATON (automaton_decl)->automaton_is_used = 1;
02453 DECL_UNIT (decl)->automaton_decl
02454 = DECL_AUTOMATON (automaton_decl);
02455 }
02456 }
02457 else if (automaton_presence)
02458 error ("define_unit `%s' without automaton when one defined",
02459 DECL_UNIT (decl)->name);
02460 DECL_UNIT (decl)->unit_num = description->units_num;
02461 description->units_num++;
02462 if (strcmp (DECL_UNIT (decl)->name, NOTHING_NAME) == 0)
02463 {
02464 error ("`%s' is declared as cpu unit", NOTHING_NAME);
02465 continue;
02466 }
02467 decl_in_table = find_decl (DECL_UNIT (decl)->name);
02468 }
02469 else
02470 {
02471 if (strcmp (DECL_RESERV (decl)->name, NOTHING_NAME) == 0)
02472 {
02473 error ("`%s' is declared as cpu reservation", NOTHING_NAME);
02474 continue;
02475 }
02476 decl_in_table = find_decl (DECL_RESERV (decl)->name);
02477 }
02478 if (decl_in_table == NULL)
02479 decl_in_table = insert_decl (decl);
02480 else
02481 {
02482 if (decl->mode == dm_unit)
02483 error ("repeated declaration of unit `%s'",
02484 DECL_UNIT (decl)->name);
02485 else
02486 error ("repeated declaration of reservation `%s'",
02487 DECL_RESERV (decl)->name);
02488 }
02489 }
02490 }
02491
02492
02493 for (i = 0; i < description->decls_num; i++)
02494 {
02495 decl = description->decls [i];
02496 if (decl->mode == dm_bypass)
02497 {
02498 out_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->out_insn_name);
02499 in_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->in_insn_name);
02500 if (out_insn_reserv == NULL)
02501 error ("there is no insn reservation `%s'",
02502 DECL_BYPASS (decl)->out_insn_name);
02503 else if (in_insn_reserv == NULL)
02504 error ("there is no insn reservation `%s'",
02505 DECL_BYPASS (decl)->in_insn_name);
02506 else
02507 {
02508 DECL_BYPASS (decl)->out_insn_reserv
02509 = DECL_INSN_RESERV (out_insn_reserv);
02510 DECL_BYPASS (decl)->in_insn_reserv
02511 = DECL_INSN_RESERV (in_insn_reserv);
02512 bypass
02513 = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list,
02514 DECL_BYPASS (decl)->in_insn_reserv);
02515 if (bypass != NULL)
02516 {
02517 if (DECL_BYPASS (decl)->latency == bypass->latency)
02518 {
02519 if (!w_flag)
02520 error
02521 ("the same bypass `%s - %s' is already defined",
02522 DECL_BYPASS (decl)->out_insn_name,
02523 DECL_BYPASS (decl)->in_insn_name);
02524 else
02525 warning
02526 (0, "the same bypass `%s - %s' is already defined",
02527 DECL_BYPASS (decl)->out_insn_name,
02528 DECL_BYPASS (decl)->in_insn_name);
02529 }
02530 else
02531 error ("bypass `%s - %s' is already defined",
02532 DECL_BYPASS (decl)->out_insn_name,
02533 DECL_BYPASS (decl)->in_insn_name);
02534 }
02535 else
02536 {
02537 DECL_BYPASS (decl)->next
02538 = DECL_INSN_RESERV (out_insn_reserv)->bypass_list;
02539 DECL_INSN_RESERV (out_insn_reserv)->bypass_list
02540 = DECL_BYPASS (decl);
02541 }
02542 }
02543 }
02544 }
02545
02546
02547 for (i = 0; i < description->decls_num; i++)
02548 {
02549 decl = description->decls [i];
02550 if (decl->mode == dm_excl)
02551 {
02552 unit_set_el_t unit_set_el_list;
02553 unit_set_el_t unit_set_el_list_2;
02554
02555 unit_set_el_list
02556 = process_excls (DECL_EXCL (decl)->names,
02557 DECL_EXCL (decl)->first_list_length, decl->pos);
02558 unit_set_el_list_2
02559 = process_excls (&DECL_EXCL (decl)->names
02560 [DECL_EXCL (decl)->first_list_length],
02561 DECL_EXCL (decl)->all_names_num
02562 - DECL_EXCL (decl)->first_list_length,
02563 decl->pos);
02564 add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
02565 add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos);
02566 }
02567 }
02568
02569
02570 for (i = 0; i < description->decls_num; i++)
02571 {
02572 decl = description->decls [i];
02573 if (decl->mode == dm_presence)
02574 {
02575 unit_set_el_t unit_set_el_list;
02576 pattern_set_el_t pattern_set_el_list;
02577
02578 unit_set_el_list
02579 = process_presence_absence_names
02580 (DECL_PRESENCE (decl)->names, DECL_PRESENCE (decl)->names_num,
02581 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
02582 pattern_set_el_list
02583 = process_presence_absence_patterns
02584 (DECL_PRESENCE (decl)->patterns,
02585 DECL_PRESENCE (decl)->patterns_num,
02586 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
02587 add_presence_absence (unit_set_el_list, pattern_set_el_list,
02588 decl->pos, TRUE,
02589 DECL_PRESENCE (decl)->final_p);
02590 }
02591 }
02592
02593
02594 for (i = 0; i < description->decls_num; i++)
02595 {
02596 decl = description->decls [i];
02597 if (decl->mode == dm_absence)
02598 {
02599 unit_set_el_t unit_set_el_list;
02600 pattern_set_el_t pattern_set_el_list;
02601
02602 unit_set_el_list
02603 = process_presence_absence_names
02604 (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
02605 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
02606 pattern_set_el_list
02607 = process_presence_absence_patterns
02608 (DECL_ABSENCE (decl)->patterns,
02609 DECL_ABSENCE (decl)->patterns_num,
02610 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
02611 add_presence_absence (unit_set_el_list, pattern_set_el_list,
02612 decl->pos, FALSE,
02613 DECL_ABSENCE (decl)->final_p);
02614 }
02615 }
02616 }
02617
02618
02619
02620
02621 static void
02622 check_automaton_usage (void)
02623 {
02624 decl_t decl;
02625 int i;
02626
02627 for (i = 0; i < description->decls_num; i++)
02628 {
02629 decl = description->decls [i];
02630 if (decl->mode == dm_automaton
02631 && !DECL_AUTOMATON (decl)->automaton_is_used)
02632 {
02633 if (!w_flag)
02634 error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
02635 else
02636 warning (0, "automaton `%s' is not used",
02637 DECL_AUTOMATON (decl)->name);
02638 }
02639 }
02640 }
02641
02642
02643
02644
02645
02646
02647 static regexp_t
02648 process_regexp (regexp_t regexp)
02649 {
02650 decl_t decl_in_table;
02651 regexp_t new_regexp;
02652 int i;
02653
02654 switch (regexp->mode)
02655 {
02656 case rm_unit:
02657 decl_in_table = find_decl (REGEXP_UNIT (regexp)->name);
02658 if (decl_in_table == NULL)
02659 error ("undeclared unit or reservation `%s'",
02660 REGEXP_UNIT (regexp)->name);
02661 else
02662 switch (decl_in_table->mode)
02663 {
02664 case dm_unit:
02665 DECL_UNIT (decl_in_table)->unit_is_used = 1;
02666 REGEXP_UNIT (regexp)->unit_decl = DECL_UNIT (decl_in_table);
02667 break;
02668
02669 case dm_reserv:
02670 DECL_RESERV (decl_in_table)->reserv_is_used = 1;
02671 new_regexp = create_node (sizeof (struct regexp));
02672 new_regexp->mode = rm_reserv;
02673 new_regexp->pos = regexp->pos;
02674 REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
02675 REGEXP_RESERV (new_regexp)->reserv_decl
02676 = DECL_RESERV (decl_in_table);
02677 regexp = new_regexp;
02678 break;
02679
02680 default:
02681 gcc_unreachable ();
02682 }
02683 break;
02684 case rm_sequence:
02685 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
02686 REGEXP_SEQUENCE (regexp)->regexps [i]
02687 = process_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
02688 break;
02689 case rm_allof:
02690 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
02691 REGEXP_ALLOF (regexp)->regexps [i]
02692 = process_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
02693 break;
02694 case rm_oneof:
02695 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
02696 REGEXP_ONEOF (regexp)->regexps [i]
02697 = process_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
02698 break;
02699 case rm_repeat:
02700 REGEXP_REPEAT (regexp)->regexp
02701 = process_regexp (REGEXP_REPEAT (regexp)->regexp);
02702 break;
02703 case rm_nothing:
02704 break;
02705 default:
02706 gcc_unreachable ();
02707 }
02708 return regexp;
02709 }
02710
02711
02712
02713
02714 static void
02715 process_regexp_decls (void)
02716 {
02717 decl_t decl;
02718 int i;
02719
02720 for (i = 0; i < description->decls_num; i++)
02721 {
02722 decl = description->decls [i];
02723 if (decl->mode == dm_reserv)
02724 DECL_RESERV (decl)->regexp
02725 = process_regexp (DECL_RESERV (decl)->regexp);
02726 else if (decl->mode == dm_insn_reserv)
02727 DECL_INSN_RESERV (decl)->regexp
02728 = process_regexp (DECL_INSN_RESERV (decl)->regexp);
02729 }
02730 }
02731
02732
02733
02734
02735
02736 static void
02737 check_usage (void)
02738 {
02739 decl_t decl;
02740 int i;
02741
02742 for (i = 0; i < description->decls_num; i++)
02743 {
02744 decl = description->decls [i];
02745 if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used)
02746 {
02747 if (!w_flag)
02748 error ("unit `%s' is not used", DECL_UNIT (decl)->name);
02749 else
02750 warning (0, "unit `%s' is not used", DECL_UNIT (decl)->name);
02751 }
02752 else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
02753 {
02754 if (!w_flag)
02755 error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
02756 else
02757 warning (0, "reservation `%s' is not used", DECL_RESERV (decl)->name);
02758 }
02759 }
02760 }
02761
02762
02763
02764 static int curr_loop_pass_num;
02765
02766
02767
02768
02769 static int
02770 loop_in_regexp (regexp_t regexp, decl_t start_decl)
02771 {
02772 int i;
02773
02774 if (regexp == NULL)
02775 return 0;
02776 switch (regexp->mode)
02777 {
02778 case rm_unit:
02779 return 0;
02780
02781 case rm_reserv:
02782 if (start_decl->mode == dm_reserv
02783 && REGEXP_RESERV (regexp)->reserv_decl == DECL_RESERV (start_decl))
02784 return 1;
02785 else if (REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
02786 == curr_loop_pass_num)
02787
02788 return 0;
02789 else
02790 {
02791 REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
02792 = curr_loop_pass_num;
02793 return loop_in_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp,
02794 start_decl);
02795 }
02796
02797 case rm_sequence:
02798 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
02799 if (loop_in_regexp (REGEXP_SEQUENCE (regexp)->regexps [i], start_decl))
02800 return 1;
02801 return 0;
02802
02803 case rm_allof:
02804 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
02805 if (loop_in_regexp (REGEXP_ALLOF (regexp)->regexps [i], start_decl))
02806 return 1;
02807 return 0;
02808
02809 case rm_oneof:
02810 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
02811 if (loop_in_regexp (REGEXP_ONEOF (regexp)->regexps [i], start_decl))
02812 return 1;
02813 return 0;
02814
02815 case rm_repeat:
02816 return loop_in_regexp (REGEXP_REPEAT (regexp)->regexp, start_decl);
02817
02818 case rm_nothing:
02819 return 0;
02820
02821 default:
02822 gcc_unreachable ();
02823 }
02824 }
02825
02826
02827
02828 static void
02829 check_loops_in_regexps (void)
02830 {
02831 decl_t decl;
02832 int i;
02833
02834 for (i = 0; i < description->decls_num; i++)
02835 {
02836 decl = description->decls [i];
02837 if (decl->mode == dm_reserv)
02838 DECL_RESERV (decl)->loop_pass_num = 0;
02839 }
02840 for (i = 0; i < description->decls_num; i++)
02841 {
02842 decl = description->decls [i];
02843 curr_loop_pass_num = i;
02844
02845 if (decl->mode == dm_reserv)
02846 {
02847 DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num;
02848 if (loop_in_regexp (DECL_RESERV (decl)->regexp, decl))
02849 {
02850 gcc_assert (DECL_RESERV (decl)->regexp);
02851 error ("cycle in definition of reservation `%s'",
02852 DECL_RESERV (decl)->name);
02853 }
02854 }
02855 }
02856 }
02857
02858
02859
02860 static void
02861 process_regexp_cycles (regexp_t regexp, int max_start_cycle,
02862 int min_start_cycle, int *max_finish_cycle,
02863 int *min_finish_cycle)
02864 {
02865 int i;
02866
02867 switch (regexp->mode)
02868 {
02869 case rm_unit:
02870 if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle)
02871 REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle;
02872 if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle
02873 || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1)
02874 REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle;
02875 *max_finish_cycle = max_start_cycle;
02876 *min_finish_cycle = min_start_cycle;
02877 break;
02878
02879 case rm_reserv:
02880 process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
02881 max_start_cycle, min_start_cycle,
02882 max_finish_cycle, min_finish_cycle);
02883 break;
02884
02885 case rm_repeat:
02886 for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++)
02887 {
02888 process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
02889 max_start_cycle, min_start_cycle,
02890 max_finish_cycle, min_finish_cycle);
02891 max_start_cycle = *max_finish_cycle + 1;
02892 min_start_cycle = *min_finish_cycle + 1;
02893 }
02894 break;
02895
02896 case rm_sequence:
02897 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
02898 {
02899 process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
02900 max_start_cycle, min_start_cycle,
02901 max_finish_cycle, min_finish_cycle);
02902 max_start_cycle = *max_finish_cycle + 1;
02903 min_start_cycle = *min_finish_cycle + 1;
02904 }
02905 break;
02906
02907 case rm_allof:
02908 {
02909 int max_cycle = 0;
02910 int min_cycle = 0;
02911
02912 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
02913 {
02914 process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
02915 max_start_cycle, min_start_cycle,
02916 max_finish_cycle, min_finish_cycle);
02917 if (max_cycle < *max_finish_cycle)
02918 max_cycle = *max_finish_cycle;
02919 if (i == 0 || min_cycle > *min_finish_cycle)
02920 min_cycle = *min_finish_cycle;
02921 }
02922 *max_finish_cycle = max_cycle;
02923 *min_finish_cycle = min_cycle;
02924 }
02925 break;
02926
02927 case rm_oneof:
02928 {
02929 int max_cycle = 0;
02930 int min_cycle = 0;
02931
02932 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
02933 {
02934 process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
02935 max_start_cycle, min_start_cycle,
02936 max_finish_cycle, min_finish_cycle);
02937 if (max_cycle < *max_finish_cycle)
02938 max_cycle = *max_finish_cycle;
02939 if (i == 0 || min_cycle > *min_finish_cycle)
02940 min_cycle = *min_finish_cycle;
02941 }
02942 *max_finish_cycle = max_cycle;
02943 *min_finish_cycle = min_cycle;
02944 }
02945 break;
02946
02947 case rm_nothing:
02948 *max_finish_cycle = max_start_cycle;
02949 *min_finish_cycle = min_start_cycle;
02950 break;
02951
02952 default:
02953 gcc_unreachable ();
02954 }
02955 }
02956
02957
02958
02959 static void
02960 evaluate_max_reserv_cycles (void)
02961 {
02962 int max_insn_cycles_num;
02963 int min_insn_cycles_num;
02964 decl_t decl;
02965 int i;
02966
02967 description->max_insn_reserv_cycles = 0;
02968 for (i = 0; i < description->decls_num; i++)
02969 {
02970 decl = description->decls [i];
02971 if (decl->mode == dm_insn_reserv)
02972 {
02973 process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0,
02974 &max_insn_cycles_num, &min_insn_cycles_num);
02975 if (description->max_insn_reserv_cycles < max_insn_cycles_num)
02976 description->max_insn_reserv_cycles = max_insn_cycles_num;
02977 }
02978 }
02979 description->max_insn_reserv_cycles++;
02980 }
02981
02982
02983
02984 static void
02985 check_all_description (void)
02986 {
02987 process_decls ();
02988 check_automaton_usage ();
02989 process_regexp_decls ();
02990 check_usage ();
02991 check_loops_in_regexps ();
02992 if (!have_error)
02993 evaluate_max_reserv_cycles ();
02994 }
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004 static ticker_t
03005 create_ticker (void)
03006 {
03007 ticker_t ticker;
03008
03009 ticker.modified_creation_time = get_run_time ();
03010 ticker.incremented_off_time = 0;
03011 return ticker;
03012 }
03013
03014
03015 static void
03016 ticker_off (ticker_t *ticker)
03017 {
03018 if (ticker->incremented_off_time == 0)
03019 ticker->incremented_off_time = get_run_time () + 1;
03020 }
03021
03022
03023 static void
03024 ticker_on (ticker_t *ticker)
03025 {
03026 if (ticker->incremented_off_time != 0)
03027 {
03028 ticker->modified_creation_time
03029 += get_run_time () - ticker->incremented_off_time + 1;
03030 ticker->incremented_off_time = 0;
03031 }
03032 }
03033
03034
03035
03036 static int
03037 active_time (ticker_t ticker)
03038 {
03039 if (ticker.incremented_off_time != 0)
03040 return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
03041 else
03042 return get_run_time () - ticker.modified_creation_time;
03043 }
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061 static void
03062 print_active_time (FILE *f, ticker_t ticker)
03063 {
03064 int msecs;
03065
03066 msecs = active_time (ticker);
03067 fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000);
03068 }
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079 static int automata_num;
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089 static ticker_t transform_time;
03090 static ticker_t NDFA_time;
03091 static ticker_t NDFA_to_DFA_time;
03092 static ticker_t minimize_time;
03093 static ticker_t equiv_time;
03094 static ticker_t automaton_generation_time;
03095 static ticker_t output_time;
03096
03097
03098
03099
03100
03101 static ticker_t check_time;
03102 static ticker_t generation_time;
03103 static ticker_t all_time;
03104
03105
03106
03107
03108 static decl_t advance_cycle_insn_decl;
03109 static void
03110 add_advance_cycle_insn_decl (void)
03111 {
03112 advance_cycle_insn_decl = create_node (sizeof (struct decl));
03113 advance_cycle_insn_decl->mode = dm_insn_reserv;
03114 advance_cycle_insn_decl->pos = no_pos;
03115 DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL;
03116 DECL_INSN_RESERV (advance_cycle_insn_decl)->name = "$advance_cycle";
03117 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num
03118 = description->insns_num;
03119 description->decls [description->decls_num] = advance_cycle_insn_decl;
03120 description->decls_num++;
03121 description->insns_num++;
03122 }
03123
03124
03125
03126
03127
03128
03129
03130 static alt_state_t first_free_alt_state;
03131
03132 #ifndef NDEBUG
03133
03134
03135 static int allocated_alt_states_num = 0;
03136 #endif
03137
03138
03139
03140 static alt_state_t
03141 get_free_alt_state (void)
03142 {
03143 alt_state_t result;
03144
03145 if (first_free_alt_state != NULL)
03146 {
03147 result = first_free_alt_state;
03148 first_free_alt_state = first_free_alt_state->next_alt_state;
03149 }
03150 else
03151 {
03152 #ifndef NDEBUG
03153 allocated_alt_states_num++;
03154 #endif
03155 result = create_node (sizeof (struct alt_state));
03156 }
03157 result->state = NULL;
03158 result->next_alt_state = NULL;
03159 result->next_sorted_alt_state = NULL;
03160 return result;
03161 }
03162
03163
03164 static void
03165 free_alt_state (alt_state_t alt_state)
03166 {
03167 if (alt_state == NULL)
03168 return;
03169 alt_state->next_alt_state = first_free_alt_state;
03170 first_free_alt_state = alt_state;
03171 }
03172
03173
03174 static void
03175 free_alt_states (alt_state_t alt_states_list)
03176 {
03177 alt_state_t curr_alt_state;
03178 alt_state_t next_alt_state;
03179
03180 for (curr_alt_state = alt_states_list;
03181 curr_alt_state != NULL;
03182 curr_alt_state = next_alt_state)
03183 {
03184 next_alt_state = curr_alt_state->next_alt_state;
03185 free_alt_state (curr_alt_state);
03186 }
03187 }
03188
03189
03190 static int
03191 alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2)
03192 {
03193 if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
03194 == (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
03195 return 0;
03196 else if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
03197 < (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
03198 return -1;
03199 else
03200 return 1;
03201 }
03202
03203
03204
03205
03206
03207 static alt_state_t
03208 uniq_sort_alt_states (alt_state_t alt_states_list)
03209 {
03210 alt_state_t curr_alt_state;
03211 VEC(alt_state_t,heap) *alt_states;
03212 size_t i;
03213 size_t prev_unique_state_ind;
03214 alt_state_t result;
03215
03216 if (alt_states_list == 0)
03217 return 0;
03218 if (alt_states_list->next_alt_state == 0)
03219 return alt_states_list;
03220
03221 alt_states = VEC_alloc (alt_state_t,heap, 150);
03222 for (curr_alt_state = alt_states_list;
03223 curr_alt_state != NULL;
03224 curr_alt_state = curr_alt_state->next_alt_state)
03225 VEC_safe_push (alt_state_t,heap, alt_states, curr_alt_state);
03226
03227 qsort (VEC_address (alt_state_t, alt_states),
03228 VEC_length (alt_state_t, alt_states),
03229 sizeof (alt_state_t), alt_state_cmp);
03230
03231 prev_unique_state_ind = 0;
03232 for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
03233 if (VEC_index (alt_state_t, alt_states, prev_unique_state_ind)->state
03234 != VEC_index (alt_state_t, alt_states, i)->state)
03235 {
03236 prev_unique_state_ind++;
03237 VEC_replace (alt_state_t, alt_states, prev_unique_state_ind,
03238 VEC_index (alt_state_t, alt_states, i));
03239 }
03240 VEC_truncate (alt_state_t, alt_states, prev_unique_state_ind + 1);
03241
03242 for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
03243 VEC_index (alt_state_t, alt_states, i-1)->next_sorted_alt_state
03244 = VEC_index (alt_state_t, alt_states, i);
03245 VEC_last (alt_state_t, alt_states)->next_sorted_alt_state = 0;
03246
03247 result = VEC_index (alt_state_t, alt_states, 0);
03248
03249 VEC_free (alt_state_t,heap, alt_states);
03250 return result;
03251 }
03252
03253
03254
03255 static int
03256 alt_states_eq (alt_state_t alt_states_1, alt_state_t alt_states_2)
03257 {
03258 while (alt_states_1 != NULL && alt_states_2 != NULL
03259 && alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
03260 {
03261 alt_states_1 = alt_states_1->next_sorted_alt_state;
03262 alt_states_2 = alt_states_2->next_sorted_alt_state;
03263 }
03264 return alt_states_1 == alt_states_2;
03265 }
03266
03267
03268 static void
03269 initiate_alt_states (void)
03270 {
03271 first_free_alt_state = NULL;
03272 }
03273
03274
03275 static void
03276 finish_alt_states (void)
03277 {
03278 }
03279
03280
03281
03282
03283
03284
03285
03286
03287
03288 #define SET_BIT(bitstring, bitno) \
03289 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
03290
03291 #define CLEAR_BIT(bitstring, bitno) \
03292 (((char *) (bitstring)) [(bitno) / CHAR_BIT] &= ~(1 << (bitno) % CHAR_BIT))
03293
03294
03295
03296 #define TEST_BIT(bitstring, bitno) \
03297 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
03298
03299
03300
03301
03302
03303
03304 static int max_cycles_num;
03305
03306
03307
03308
03309 static int els_in_cycle_reserv;
03310
03311
03312
03313
03314
03315 static int els_in_reservs;
03316
03317
03318 static unit_decl_t *units_array;
03319
03320
03321 static reserv_sets_t temp_reserv;
03322
03323
03324 static htab_t state_table;
03325
03326
03327
03328 static state_t first_free_state;
03329
03330 static int curr_unique_state_num;
03331
03332 #ifndef NDEBUG
03333
03334
03335 static int allocated_states_num = 0;
03336 #endif
03337
03338
03339 static reserv_sets_t
03340 alloc_empty_reserv_sets (void)
03341 {
03342 reserv_sets_t result;
03343
03344 obstack_blank (&irp, els_in_reservs * sizeof (set_el_t));
03345 result = (reserv_sets_t) obstack_base (&irp);
03346 obstack_finish (&irp);
03347 memset (result, 0, els_in_reservs * sizeof (set_el_t));
03348 return result;
03349 }
03350
03351
03352 static unsigned
03353 reserv_sets_hash_value (reserv_sets_t reservs)
03354 {
03355 set_el_t hash_value;
03356 unsigned result;
03357 int reservs_num, i;
03358 set_el_t *reserv_ptr;
03359
03360 hash_value = 0;
03361 reservs_num = els_in_reservs;
03362 reserv_ptr = reservs;
03363 i = 0;
03364 while (reservs_num != 0)
03365 {
03366 reservs_num--;
03367 hash_value += ((*reserv_ptr >> i)
03368 | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
03369 i++;
03370 if (i == sizeof (set_el_t) * CHAR_BIT)
03371 i = 0;
03372 reserv_ptr++;
03373 }
03374 if (sizeof (set_el_t) <= sizeof (unsigned))
03375 return hash_value;
03376 result = 0;
03377 for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1)
03378 {
03379 result += (unsigned) hash_value;
03380 hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT;
03381 }
03382 return result;
03383 }
03384
03385
03386 static int
03387 reserv_sets_cmp (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
03388 {
03389 int reservs_num;
03390 set_el_t *reserv_ptr_1;
03391 set_el_t *reserv_ptr_2;
03392
03393 gcc_assert (reservs_1 && reservs_2);
03394 reservs_num = els_in_reservs;
03395 reserv_ptr_1 = reservs_1;
03396 reserv_ptr_2 = reservs_2;
03397 while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
03398 {
03399 reservs_num--;
03400 reserv_ptr_1++;
03401 reserv_ptr_2++;
03402 }
03403 if (reservs_num == 0)
03404 return 0;
03405 else if (*reserv_ptr_1 < *reserv_ptr_2)
03406 return -1;
03407 else
03408 return 1;
03409 }
03410
03411
03412 static int
03413 reserv_sets_eq (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
03414 {
03415 return reserv_sets_cmp (reservs_1, reservs_2) == 0;
03416 }
03417
03418
03419
03420 static void
03421 set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
03422 {
03423 gcc_assert (cycle_num < max_cycles_num);
03424 SET_BIT (reservs, cycle_num * els_in_cycle_reserv
03425 * sizeof (set_el_t) * CHAR_BIT + unit_num);
03426 }
03427
03428
03429
03430 static int
03431 test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
03432 {
03433 gcc_assert (cycle_num < max_cycles_num);
03434 return TEST_BIT (reservs, cycle_num * els_in_cycle_reserv
03435 * sizeof (set_el_t) * CHAR_BIT + unit_num);
03436 }
03437
03438
03439
03440
03441 static int
03442 reserv_sets_are_intersected (reserv_sets_t operand_1,
03443 reserv_sets_t operand_2)
03444 {
03445 set_el_t *el_ptr_1;
03446 set_el_t *el_ptr_2;
03447 set_el_t *cycle_ptr_1;
03448 set_el_t *cycle_ptr_2;
03449
03450 gcc_assert (operand_1 && operand_2);
03451 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
03452 el_ptr_1 < operand_1 + els_in_reservs;
03453 el_ptr_1++, el_ptr_2++)
03454 if (*el_ptr_1 & *el_ptr_2)
03455 return 1;
03456 reserv_sets_or (temp_reserv, operand_1, operand_2);
03457 for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
03458 cycle_ptr_1 < operand_1 + els_in_reservs;
03459 cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
03460 {
03461 for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
03462 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
03463 el_ptr_1++, el_ptr_2++)
03464 if (*el_ptr_1 & *el_ptr_2)
03465 return 1;
03466 if (!check_presence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
03467 return 1;
03468 if (!check_presence_pattern_sets (temp_reserv + (cycle_ptr_2
03469 - operand_2),
03470 cycle_ptr_2, TRUE))
03471 return 1;
03472 if (!check_absence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
03473 return 1;
03474 if (!check_absence_pattern_sets (temp_reserv + (cycle_ptr_2 - operand_2),
03475 cycle_ptr_2, TRUE))
03476 return 1;
03477 }
03478 return 0;
03479 }
03480
03481
03482
03483
03484 static void
03485 reserv_sets_shift (reserv_sets_t result, reserv_sets_t operand)
03486 {
03487 int i;
03488
03489 gcc_assert (result && operand && result != operand);
03490 for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
03491 result [i - els_in_cycle_reserv] = operand [i];
03492 }
03493
03494
03495 static void
03496 reserv_sets_or (reserv_sets_t result, reserv_sets_t operand_1,
03497 reserv_sets_t operand_2)
03498 {
03499 set_el_t *el_ptr_1;
03500 set_el_t *el_ptr_2;
03501 set_el_t *result_set_el_ptr;
03502
03503 gcc_assert (result && operand_1 && operand_2);
03504 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
03505 el_ptr_1 < operand_1 + els_in_reservs;
03506 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
03507 *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
03508 }
03509
03510
03511 static void
03512 reserv_sets_and (reserv_sets_t result, reserv_sets_t operand_1,
03513 reserv_sets_t operand_2)
03514 {
03515 set_el_t *el_ptr_1;
03516 set_el_t *el_ptr_2;
03517 set_el_t *result_set_el_ptr;
03518
03519 gcc_assert (result && operand_1 && operand_2);
03520 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
03521 el_ptr_1 < operand_1 + els_in_reservs;
03522 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
03523 *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
03524 }
03525
03526
03527
03528
03529 static void
03530 output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
03531 int repetition_num)
03532 {
03533 int unit_num;
03534 int reserved_units_num;
03535
03536 reserved_units_num = 0;
03537 for (unit_num = 0; unit_num < description->units_num; unit_num++)
03538 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
03539 * sizeof (set_el_t) * CHAR_BIT + unit_num))
03540 reserved_units_num++;
03541 gcc_assert (repetition_num > 0);
03542 if (repetition_num != 1 && reserved_units_num > 1)
03543 fprintf (f, "(");
03544 reserved_units_num = 0;
03545 for (unit_num = 0;
03546 unit_num < description->units_num;
03547 unit_num++)
03548 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
03549 * sizeof (set_el_t) * CHAR_BIT + unit_num))
03550 {
03551 if (reserved_units_num != 0)
03552 fprintf (f, "+");
03553 reserved_units_num++;
03554 fprintf (f, "%s", units_array [unit_num]->name);
03555 }
03556 if (reserved_units_num == 0)
03557 fprintf (f, NOTHING_NAME);
03558 gcc_assert (repetition_num > 0);
03559 if (repetition_num != 1 && reserved_units_num > 1)
03560 fprintf (f, ")");
03561 if (repetition_num != 1)
03562 fprintf (f, "*%d", repetition_num);
03563 }
03564
03565
03566
03567 static void
03568 output_reserv_sets (FILE *f, reserv_sets_t reservs)
03569 {
03570 int start_cycle = 0;
03571 int cycle;
03572 int repetition_num;
03573
03574 repetition_num = 0;
03575 for (cycle = 0; cycle < max_cycles_num; cycle++)
03576 if (repetition_num == 0)
03577 {
03578 repetition_num++;
03579 start_cycle = cycle;
03580 }
03581 else if (memcmp
03582 ((char *) reservs + start_cycle * els_in_cycle_reserv
03583 * sizeof (set_el_t),
03584 (char *) reservs + cycle * els_in_cycle_reserv
03585 * sizeof (set_el_t),
03586 els_in_cycle_reserv * sizeof (set_el_t)) == 0)
03587 repetition_num++;
03588 else
03589 {
03590 if (start_cycle != 0)
03591 fprintf (f, ", ");
03592 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
03593 repetition_num = 1;
03594 start_cycle = cycle;
03595 }
03596 if (start_cycle < max_cycles_num)
03597 {
03598 if (start_cycle != 0)
03599 fprintf (f, ", ");
03600 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
03601 }
03602 }
03603
03604
03605
03606
03607 static state_t
03608 get_free_state (int with_reservs, automaton_t automaton)
03609 {
03610 state_t result;
03611
03612 gcc_assert (max_cycles_num > 0 && automaton);
03613 if (first_free_state)
03614 {
03615 result = first_free_state;
03616 first_free_state = result->next_equiv_class_state;
03617
03618 result->next_equiv_class_state = NULL;
03619 result->automaton = automaton;
03620 result->first_out_arc = NULL;
03621 result->it_was_placed_in_stack_for_NDFA_forming = 0;
03622 result->it_was_placed_in_stack_for_DFA_forming = 0;
03623 result->component_states = NULL;
03624 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
03625 }
03626 else
03627 {
03628 #ifndef NDEBUG
03629 allocated_states_num++;
03630 #endif
03631 result = create_node (sizeof (struct state));
03632 result->automaton = automaton;
03633 result->first_out_arc = NULL;
03634 result->unique_num = curr_unique_state_num;
03635 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
03636 curr_unique_state_num++;
03637 }
03638 if (with_reservs)
03639 {
03640 if (result->reservs == NULL)
03641 result->reservs = alloc_empty_reserv_sets ();
03642 else
03643 memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
03644 }
03645 return result;
03646 }
03647
03648
03649 static void
03650 free_state (state_t state)
03651 {
03652 free_alt_states (state->component_states);
03653 state->next_equiv_class_state = first_free_state;
03654 first_free_state = state;
03655 }
03656
03657
03658
03659
03660
03661 static hashval_t
03662 state_hash (const void *state)
03663 {
03664 unsigned int hash_value;
03665 alt_state_t alt_state;
03666
03667 if (((state_t) state)->component_states == NULL)
03668 hash_value = reserv_sets_hash_value (((state_t) state)->reservs);
03669 else
03670 {
03671 hash_value = 0;
03672 for (alt_state = ((state_t) state)->component_states;
03673 alt_state != NULL;
03674 alt_state = alt_state->next_sorted_alt_state)
03675 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
03676 | (hash_value << CHAR_BIT))
03677 + alt_state->state->unique_num);
03678 }
03679 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
03680 | (hash_value << CHAR_BIT))
03681 + ((state_t) state)->automaton->automaton_order_num);
03682 return hash_value;
03683 }
03684
03685
03686 static int
03687 state_eq_p (const void *state_1, const void *state_2)
03688 {
03689 alt_state_t alt_state_1;
03690 alt_state_t alt_state_2;
03691
03692 if (((state_t) state_1)->automaton != ((state_t) state_2)->automaton)
03693 return 0;
03694 else if (((state_t) state_1)->component_states == NULL
03695 && ((state_t) state_2)->component_states == NULL)
03696 return reserv_sets_eq (((state_t) state_1)->reservs,
03697 ((state_t) state_2)->reservs);
03698 else if (((state_t) state_1)->component_states != NULL
03699 && ((state_t) state_2)->component_states != NULL)
03700 {
03701 for (alt_state_1 = ((state_t) state_1)->component_states,
03702 alt_state_2 = ((state_t) state_2)->component_states;
03703 alt_state_1 != NULL && alt_state_2 != NULL;
03704 alt_state_1 = alt_state_1->next_sorted_alt_state,
03705 alt_state_2 = alt_state_2->next_sorted_alt_state)
03706
03707
03708 if (alt_state_1->state != alt_state_2->state)
03709 return 0;
03710 return alt_state_1 == alt_state_2;
03711 }
03712 else
03713 return 0;
03714 }
03715
03716
03717 static state_t
03718 insert_state (state_t state)
03719 {
03720 void **entry_ptr;
03721
03722 entry_ptr = htab_find_slot (state_table, (void *) state, 1);
03723 if (*entry_ptr == NULL)
03724 *entry_ptr = (void *) state;
03725 return (state_t) *entry_ptr;
03726 }
03727
03728
03729
03730 static void
03731 set_state_reserv (state_t state, int cycle_num, int unit_num)
03732 {
03733 set_unit_reserv (state->reservs, cycle_num, unit_num);
03734 }
03735
03736
03737
03738 static int
03739 intersected_state_reservs_p (state_t state1, state_t state2)
03740 {
03741 gcc_assert (state1->automaton == state2->automaton);
03742 return reserv_sets_are_intersected (state1->reservs, state2->reservs);
03743 }
03744
03745
03746
03747
03748 static state_t
03749 states_union (state_t state1, state_t state2, reserv_sets_t reservs)
03750 {
03751 state_t result;
03752 state_t state_in_table;
03753
03754 gcc_assert (state1->automaton == state2->automaton);
03755 result = get_free_state (1, state1->automaton);
03756 reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
03757 reserv_sets_and (result->reservs, result->reservs, reservs);
03758 state_in_table = insert_state (result);
03759 if (result != state_in_table)
03760 {
03761 free_state (result);
03762 result = state_in_table;
03763 }
03764 return result;
03765 }
03766
03767
03768
03769
03770 static state_t
03771 state_shift (state_t state, reserv_sets_t reservs)
03772 {
03773 state_t result;
03774 state_t state_in_table;
03775
03776 result = get_free_state (1, state->automaton);
03777 reserv_sets_shift (result->reservs, state->reservs);
03778 reserv_sets_and (result->reservs, result->reservs, reservs);
03779 state_in_table = insert_state (result);
03780 if (result != state_in_table)
03781 {
03782 free_state (result);
03783 result = state_in_table;
03784 }
03785 return result;
03786 }
03787
03788
03789 static void
03790 initiate_states (void)
03791 {
03792 decl_t decl;
03793 int i;
03794
03795 if (description->units_num)
03796 units_array = XNEWVEC (unit_decl_t, description->units_num);
03797 else
03798 units_array = 0;
03799
03800 for (i = 0; i < description->decls_num; i++)
03801 {
03802 decl = description->decls [i];
03803 if (decl->mode == dm_unit)
03804 units_array [DECL_UNIT (decl)->unit_num] = DECL_UNIT (decl);
03805 }
03806 max_cycles_num = description->max_insn_reserv_cycles;
03807 els_in_cycle_reserv
03808 = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
03809 / (sizeof (set_el_t) * CHAR_BIT));
03810 els_in_reservs = els_in_cycle_reserv * max_cycles_num;
03811 curr_unique_state_num = 0;
03812 initiate_alt_states ();
03813 state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
03814 temp_reserv = alloc_empty_reserv_sets ();
03815 }
03816
03817
03818 static void
03819 finish_states (void)
03820 {
03821 free (units_array);
03822 units_array = 0;
03823 htab_delete (state_table);
03824 first_free_state = NULL;
03825 finish_alt_states ();
03826 }
03827
03828
03829
03830
03831
03832
03833 static arc_t first_free_arc;
03834
03835 #ifndef NDEBUG
03836
03837
03838 static int allocated_arcs_num = 0;
03839 #endif
03840
03841
03842 static void
03843 free_arc (arc_t arc)
03844 {
03845 arc->next_out_arc = first_free_arc;
03846 first_free_arc = arc;
03847 }
03848
03849
03850 static void
03851 remove_arc (state_t from_state, arc_t arc)
03852 {
03853 arc_t prev_arc;
03854 arc_t curr_arc;
03855
03856 gcc_assert (arc);
03857 for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
03858 curr_arc != NULL;
03859 prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
03860 if (curr_arc == arc)
03861 break;
03862 gcc_assert (curr_arc);
03863 if (prev_arc == NULL)
03864 from_state->first_out_arc = arc->next_out_arc;
03865 else
03866 prev_arc->next_out_arc = arc->next_out_arc;
03867 from_state->num_out_arcs--;
03868 free_arc (arc);
03869 }
03870
03871
03872
03873 static arc_t
03874 find_arc (state_t from_state, state_t to_state, ainsn_t insn)
03875 {
03876 arc_t arc;
03877
03878 for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
03879 if (arc->to_state == to_state && arc->insn == insn)
03880 return arc;
03881 return NULL;
03882 }
03883
03884
03885
03886 static arc_t
03887 add_arc (state_t from_state, state_t to_state, ainsn_t ainsn)
03888 {
03889 arc_t new_arc;
03890
03891 new_arc = find_arc (from_state, to_state, ainsn);
03892 if (new_arc != NULL)
03893 return new_arc;
03894 if (first_free_arc == NULL)
03895 {
03896 #ifndef NDEBUG
03897 allocated_arcs_num++;
03898 #endif
03899 new_arc = create_node (sizeof (struct arc));
03900 new_arc->to_state = NULL;
03901 new_arc->insn = NULL;
03902 new_arc->next_out_arc = NULL;
03903 }
03904 else
03905 {
03906 new_arc = first_free_arc;
03907 first_free_arc = first_free_arc->next_out_arc;
03908 }
03909 new_arc->to_state = to_state;
03910 new_arc->insn = ainsn;
03911 ainsn->arc_exists_p = 1;
03912 new_arc->next_out_arc = from_state->first_out_arc;
03913 from_state->first_out_arc = new_arc;
03914 from_state->num_out_arcs++;
03915 new_arc->next_arc_marked_by_insn = NULL;
03916 return new_arc;
03917 }
03918
03919
03920 static arc_t
03921 first_out_arc (state_t state)
03922 {
03923 return state->first_out_arc;
03924 }
03925
03926
03927 static arc_t
03928 next_out_arc (arc_t arc)
03929 {
03930 return arc->next_out_arc;
03931 }
03932
03933
03934 static void
03935 initiate_arcs (void)
03936 {
03937 first_free_arc = NULL;
03938 }
03939
03940
03941 static void
03942 finish_arcs (void)
03943 {
03944 }
03945
03946
03947
03948
03949
03950
03951 static automata_list_el_t first_free_automata_list_el;
03952
03953
03954 static automata_list_el_t current_automata_list;
03955
03956
03957 static htab_t automata_list_table;
03958
03959
03960
03961 static automata_list_el_t
03962 get_free_automata_list_el (void)
03963 {
03964 automata_list_el_t result;
03965
03966 if (first_free_automata_list_el != NULL)
03967 {
03968 result = first_free_automata_list_el;
03969 first_free_automata_list_el
03970 = first_free_automata_list_el->next_automata_list_el;
03971 }
03972 else
03973 result = create_node (sizeof (struct automata_list_el));
03974 result->automaton = NULL;
03975 result->next_automata_list_el = NULL;
03976 return result;
03977 }
03978
03979
03980 static void
03981 free_automata_list_el (automata_list_el_t automata_list_el)
03982 {
03983 if (automata_list_el == NULL)
03984 return;
03985 automata_list_el->next_automata_list_el = first_free_automata_list_el;
03986 first_free_automata_list_el = automata_list_el;
03987 }
03988
03989
03990 static void
03991 free_automata_list (automata_list_el_t automata_list)
03992 {
03993 automata_list_el_t curr_automata_list_el;
03994 automata_list_el_t next_automata_list_el;
03995
03996 for (curr_automata_list_el = automata_list;
03997 curr_automata_list_el != NULL;
03998 curr_automata_list_el = next_automata_list_el)
03999 {
04000 next_automata_list_el = curr_automata_list_el->next_automata_list_el;
04001 free_automata_list_el (curr_automata_list_el);
04002 }
04003 }
04004
04005
04006 static hashval_t
04007 automata_list_hash (const void *automata_list)
04008 {
04009 unsigned int hash_value;
04010 automata_list_el_t curr_automata_list_el;
04011
04012 hash_value = 0;
04013 for (curr_automata_list_el = (automata_list_el_t) automata_list;
04014 curr_automata_list_el != NULL;
04015 curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
04016 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
04017 | (hash_value << CHAR_BIT))
04018 + curr_automata_list_el->automaton->automaton_order_num);
04019 return hash_value;
04020 }
04021
04022
04023 static int
04024 automata_list_eq_p (const void *automata_list_1, const void *automata_list_2)
04025 {
04026 automata_list_el_t automata_list_el_1;
04027 automata_list_el_t automata_list_el_2;
04028
04029 for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
04030 automata_list_el_2 = (automata_list_el_t) automata_list_2;
04031 automata_list_el_1 != NULL && automata_list_el_2 != NULL;
04032 automata_list_el_1 = automata_list_el_1->next_automata_list_el,
04033 automata_list_el_2 = automata_list_el_2->next_automata_list_el)
04034 if (automata_list_el_1->automaton != automata_list_el_2->automaton)
04035 return 0;
04036 return automata_list_el_1 == automata_list_el_2;
04037 }
04038
04039
04040 static void
04041 initiate_automata_lists (void)
04042 {
04043 first_free_automata_list_el = NULL;
04044 automata_list_table = htab_create (1500, automata_list_hash,
04045 automata_list_eq_p, (htab_del) 0);
04046 }
04047
04048
04049
04050 static void
04051 automata_list_start (void)
04052 {
04053 current_automata_list = NULL;
04054 }
04055
04056
04057 static void
04058 automata_list_add (automaton_t automaton)
04059 {
04060 automata_list_el_t el;
04061
04062 el = get_free_automata_list_el ();
04063 el->automaton = automaton;
04064 el->next_automata_list_el = current_automata_list;
04065 current_automata_list = el;
04066 }
04067
04068
04069
04070 static automata_list_el_t
04071 automata_list_finish (void)
04072 {
04073 void **entry_ptr;
04074
04075 if (current_automata_list == NULL)
04076 return NULL;
04077 entry_ptr = htab_find_slot (automata_list_table,
04078 (void *) current_automata_list, 1);
04079 if (*entry_ptr == NULL)
04080 *entry_ptr = (void *) current_automata_list;
04081 else
04082 free_automata_list (current_automata_list);
04083 current_automata_list = NULL;
04084 return (automata_list_el_t) *entry_ptr;
04085 }
04086
04087
04088 static void
04089 finish_automata_lists (void)
04090 {
04091 htab_delete (automata_list_table);
04092 }
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103 static reserv_sets_t excl_set;
04104
04105
04106 static reserv_sets_t *unit_excl_set_table;
04107
04108
04109
04110 static void
04111 initiate_excl_sets (void)
04112 {
04113 decl_t decl;
04114 reserv_sets_t unit_excl_set;
04115 unit_set_el_t el;
04116 int i;
04117
04118 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
04119 excl_set = (reserv_sets_t) obstack_base (&irp);
04120 obstack_finish (&irp);
04121 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
04122 unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
04123 obstack_finish (&irp);
04124
04125 for (i = 0; i < description->decls_num; i++)
04126 {
04127 decl = description->decls [i];
04128 if (decl->mode == dm_unit)
04129 {
04130 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
04131 unit_excl_set = (reserv_sets_t) obstack_base (&irp);
04132 obstack_finish (&irp);
04133 memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
04134 for (el = DECL_UNIT (decl)->excl_list;
04135 el != NULL;
04136 el = el->next_unit_set_el)
04137 {
04138 SET_BIT (unit_excl_set, el->unit_decl->unit_num);
04139 el->unit_decl->in_set_p = TRUE;
04140 }
04141 unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set;
04142 }
04143 }
04144 }
04145
04146
04147
04148 static reserv_sets_t
04149 get_excl_set (reserv_sets_t in_set)
04150 {
04151 int excl_char_num;
04152 int chars_num;
04153 int i;
04154 int start_unit_num;
04155 int unit_num;
04156
04157 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
04158 memset (excl_set, 0, chars_num);
04159 for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
04160 if (((unsigned char *) in_set) [excl_char_num])
04161 for (i = CHAR_BIT - 1; i >= 0; i--)
04162 if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
04163 {
04164 start_unit_num = excl_char_num * CHAR_BIT + i;
04165 if (start_unit_num >= description->units_num)
04166 return excl_set;
04167 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
04168 {
04169 excl_set [unit_num]
04170 |= unit_excl_set_table [start_unit_num] [unit_num];
04171 }
04172 }
04173 return excl_set;
04174 }
04175
04176
04177
04178
04179
04180
04181
04182
04183 static pattern_reserv_t *unit_presence_set_table;
04184 static pattern_reserv_t *unit_final_presence_set_table;
04185 static pattern_reserv_t *unit_absence_set_table;
04186 static pattern_reserv_t *unit_final_absence_set_table;
04187
04188
04189
04190 static pattern_reserv_t
04191 form_reserv_sets_list (pattern_set_el_t pattern_list)
04192 {
04193 pattern_set_el_t el;
04194 pattern_reserv_t first, curr, prev;
04195 int i;
04196
04197 prev = first = NULL;
04198 for (el = pattern_list; el != NULL; el = el->next_pattern_set_el)
04199 {
04200 curr = create_node (sizeof (struct pattern_reserv));
04201 curr->reserv = alloc_empty_reserv_sets ();
04202 curr->next_pattern_reserv = NULL;
04203 for (i = 0; i < el->units_num; i++)
04204 {
04205 SET_BIT (curr->reserv, el->unit_decls [i]->unit_num);
04206 el->unit_decls [i]->in_set_p = TRUE;
04207 }
04208 if (prev != NULL)
04209 prev->next_pattern_reserv = curr;
04210 else
04211 first = curr;
04212 prev = curr;
04213 }
04214 return first;
04215 }
04216
04217
04218
04219 static void
04220 initiate_presence_absence_pattern_sets (void)
04221 {
04222 decl_t decl;
04223 int i;
04224
04225 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
04226 unit_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
04227 obstack_finish (&irp);
04228 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
04229 unit_final_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
04230 obstack_finish (&irp);
04231 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
04232 unit_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
04233 obstack_finish (&irp);
04234 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
04235 unit_final_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
04236 obstack_finish (&irp);
04237
04238 for (i = 0; i < description->decls_num; i++)
04239 {
04240 decl = description->decls [i];
04241 if (decl->mode == dm_unit)
04242 {
04243 unit_presence_set_table [DECL_UNIT (decl)->unit_num]
04244 = form_reserv_sets_list (DECL_UNIT (decl)->presence_list);
04245 unit_final_presence_set_table [DECL_UNIT (decl)->unit_num]
04246 = form_reserv_sets_list (DECL_UNIT (decl)->final_presence_list);
04247 unit_absence_set_table [DECL_UNIT (decl)->unit_num]
04248 = form_reserv_sets_list (DECL_UNIT (decl)->absence_list);
04249 unit_final_absence_set_table [DECL_UNIT (decl)->unit_num]
04250 = form_reserv_sets_list (DECL_UNIT (decl)->final_absence_list);
04251 }
04252 }
04253 }
04254
04255
04256
04257
04258 static int
04259 check_presence_pattern_sets (reserv_sets_t checked_set,
04260 reserv_sets_t origional_set,
04261 int final_p)
04262 {
04263 int char_num;
04264 int chars_num;
04265 int i;
04266 int start_unit_num;
04267 int unit_num;
04268 int presence_p;
04269 pattern_reserv_t pat_reserv;
04270
04271 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
04272 for (char_num = 0; char_num < chars_num; char_num++)
04273 if (((unsigned char *) origional_set) [char_num])
04274 for (i = CHAR_BIT - 1; i >= 0; i--)
04275 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
04276 {
04277 start_unit_num = char_num * CHAR_BIT + i;
04278 if (start_unit_num >= description->units_num)
04279 break;
04280 if ((final_p
04281 && unit_final_presence_set_table [start_unit_num] == NULL)
04282 || (!final_p
04283 && unit_presence_set_table [start_unit_num] == NULL))
04284 continue;
04285 presence_p = FALSE;
04286 for (pat_reserv = (final_p
04287 ? unit_final_presence_set_table [start_unit_num]
04288 : unit_presence_set_table [start_unit_num]);
04289 pat_reserv != NULL;
04290 pat_reserv = pat_reserv->next_pattern_reserv)
04291 {
04292 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
04293 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
04294 != pat_reserv->reserv [unit_num])
04295 break;
04296 presence_p = presence_p || unit_num >= els_in_cycle_reserv;
04297 }
04298 if (!presence_p)
04299 return FALSE;
04300 }
04301 return TRUE;
04302 }
04303
04304
04305
04306
04307 static int
04308 check_absence_pattern_sets (reserv_sets_t checked_set,
04309 reserv_sets_t origional_set,
04310 int final_p)
04311 {
04312 int char_num;
04313 int chars_num;
04314 int i;
04315 int start_unit_num;
04316 int unit_num;
04317 pattern_reserv_t pat_reserv;
04318
04319 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
04320 for (char_num = 0; char_num < chars_num; char_num++)
04321 if (((unsigned char *) origional_set) [char_num])
04322 for (i = CHAR_BIT - 1; i >= 0; i--)
04323 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
04324 {
04325 start_unit_num = char_num * CHAR_BIT + i;
04326 if (start_unit_num >= description->units_num)
04327 break;
04328 for (pat_reserv = (final_p
04329 ? unit_final_absence_set_table [start_unit_num]
04330 : unit_absence_set_table [start_unit_num]);
04331 pat_reserv != NULL;
04332 pat_reserv = pat_reserv->next_pattern_reserv)
04333 {
04334 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
04335 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
04336 != pat_reserv->reserv [unit_num]
04337 && pat_reserv->reserv [unit_num])
04338 break;
04339 if (unit_num >= els_in_cycle_reserv)
04340 return FALSE;
04341 }
04342 }
04343 return TRUE;
04344 }
04345
04346
04347
04348
04349
04350
04351
04352
04353
04354
04355
04356
04357
04358 static regexp_t
04359 copy_insn_regexp (regexp_t regexp)
04360 {
04361 regexp_t result;
04362 int i;
04363
04364 switch (regexp->mode)
04365 {
04366 case rm_reserv:
04367 result = copy_insn_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp);
04368 break;
04369
04370 case rm_unit:
04371 result = copy_node (regexp, sizeof (struct regexp));
04372 break;
04373
04374 case rm_repeat:
04375 result = copy_node (regexp, sizeof (struct regexp));
04376 REGEXP_REPEAT (result)->regexp
04377 = copy_insn_regexp (REGEXP_REPEAT (regexp)->regexp);
04378 break;
04379
04380 case rm_sequence:
04381 result = copy_node (regexp,
04382 sizeof (struct regexp) + sizeof (regexp_t)
04383 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
04384 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
04385 REGEXP_SEQUENCE (result)->regexps [i]
04386 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
04387 break;
04388
04389 case rm_allof:
04390 result = copy_node (regexp,
04391 sizeof (struct regexp) + sizeof (regexp_t)
04392 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
04393 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
04394 REGEXP_ALLOF (result)->regexps [i]
04395 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
04396 break;
04397
04398 case rm_oneof:
04399 result = copy_node (regexp,
04400 sizeof (struct regexp) + sizeof (regexp_t)
04401 * (REGEXP_ONEOF (regexp)->regexps_num - 1));
04402 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
04403 REGEXP_ONEOF (result)->regexps [i]
04404 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
04405 break;
04406
04407 case rm_nothing:
04408 result = copy_node (regexp, sizeof (struct regexp));
04409 break;
04410
04411 default:
04412 gcc_unreachable ();
04413 }
04414 return result;
04415 }
04416
04417
04418
04419 static int regexp_transformed_p;
04420
04421
04422
04423 static regexp_t
04424 transform_1 (regexp_t regexp)
04425 {
04426 int i;
04427 int repeat_num;
04428 regexp_t operand;
04429 pos_t pos;
04430
04431 if (regexp->mode == rm_repeat)
04432 {
04433 repeat_num = REGEXP_REPEAT (regexp)->repeat_num;
04434 gcc_assert (repeat_num > 1);
04435 operand = REGEXP_REPEAT (regexp)->regexp;
04436 pos = regexp->mode;
04437 regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t)
04438 * (repeat_num - 1));
04439 regexp->mode = rm_sequence;
04440 regexp->pos = pos;
04441 REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num;
04442 for (i = 0; i < repeat_num; i++)
04443 REGEXP_SEQUENCE (regexp)->regexps [i] = copy_insn_regexp (operand);
04444 regexp_transformed_p = 1;
04445 }
04446 return regexp;
04447 }
04448
04449
04450
04451
04452
04453 static regexp_t
04454 transform_2 (regexp_t regexp)
04455 {
04456 if (regexp->mode == rm_sequence)
04457 {
04458 regexp_t sequence = NULL;
04459 regexp_t result;
04460 int sequence_index = 0;
04461 int i, j;
04462
04463 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
04464 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_sequence)
04465 {
04466 sequence_index = i;
04467 sequence = REGEXP_SEQUENCE (regexp)->regexps [i];
04468 break;
04469 }
04470 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
04471 {
04472 gcc_assert (REGEXP_SEQUENCE (sequence)->regexps_num > 1
04473 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
04474 result = create_node (sizeof (struct regexp)
04475 + sizeof (regexp_t)
04476 * (REGEXP_SEQUENCE (regexp)->regexps_num
04477 + REGEXP_SEQUENCE (sequence)->regexps_num
04478 - 2));
04479 result->mode = rm_sequence;
04480 result->pos = regexp->pos;
04481 REGEXP_SEQUENCE (result)->regexps_num
04482 = (REGEXP_SEQUENCE (regexp)->regexps_num
04483 + REGEXP_SEQUENCE (sequence)->regexps_num - 1);
04484 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
04485 if (i < sequence_index)
04486 REGEXP_SEQUENCE (result)->regexps [i]
04487 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
04488 else if (i > sequence_index)
04489 REGEXP_SEQUENCE (result)->regexps
04490 [i + REGEXP_SEQUENCE (sequence)->regexps_num - 1]
04491 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
04492 else
04493 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
04494 REGEXP_SEQUENCE (result)->regexps [i + j]
04495 = copy_insn_regexp (REGEXP_SEQUENCE (sequence)->regexps [j]);
04496 regexp_transformed_p = 1;
04497 regexp = result;
04498 }
04499 }
04500 else if (regexp->mode == rm_allof)
04501 {
04502 regexp_t allof = NULL;
04503 regexp_t result;
04504 int allof_index = 0;
04505 int i, j;
04506
04507 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
04508 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_allof)
04509 {
04510 allof_index = i;
04511 allof = REGEXP_ALLOF (regexp)->regexps [i];
04512 break;
04513 }
04514 if (i < REGEXP_ALLOF (regexp)->regexps_num)
04515 {
04516 gcc_assert (REGEXP_ALLOF (allof)->regexps_num > 1
04517 && REGEXP_ALLOF (regexp)->regexps_num > 1);
04518 result = create_node (sizeof (struct regexp)
04519 + sizeof (regexp_t)
04520 * (REGEXP_ALLOF (regexp)->regexps_num
04521 + REGEXP_ALLOF (allof)->regexps_num - 2));
04522 result->mode = rm_allof;
04523 result->pos = regexp->pos;
04524 REGEXP_ALLOF (result)->regexps_num
04525 = (REGEXP_ALLOF (regexp)->regexps_num
04526 + REGEXP_ALLOF (allof)->regexps_num - 1);
04527 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
04528 if (i < allof_index)
04529 REGEXP_ALLOF (result)->regexps [i]
04530 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
04531 else if (i > allof_index)
04532 REGEXP_ALLOF (result)->regexps
04533 [i + REGEXP_ALLOF (allof)->regexps_num - 1]
04534 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
04535 else
04536 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
04537 REGEXP_ALLOF (result)->regexps [i + j]
04538 = copy_insn_regexp (REGEXP_ALLOF (allof)->regexps [j]);
04539 regexp_transformed_p = 1;
04540 regexp = result;
04541 }
04542 }
04543 else if (regexp->mode == rm_oneof)
04544 {
04545 regexp_t oneof = NULL;
04546 regexp_t result;
04547 int oneof_index = 0;
04548 int i, j;
04549
04550 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
04551 if (REGEXP_ONEOF (regexp)->regexps [i]->mode == rm_oneof)
04552 {
04553 oneof_index = i;
04554 oneof = REGEXP_ONEOF (regexp)->regexps [i];
04555 break;
04556 }
04557 if (i < REGEXP_ONEOF (regexp)->regexps_num)
04558 {
04559 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
04560 && REGEXP_ONEOF (regexp)->regexps_num > 1);
04561 result = create_node (sizeof (struct regexp)
04562 + sizeof (regexp_t)
04563 * (REGEXP_ONEOF (regexp)->regexps_num
04564 + REGEXP_ONEOF (oneof)->regexps_num - 2));
04565 result->mode = rm_oneof;
04566 result->pos = regexp->pos;
04567 REGEXP_ONEOF (result)->regexps_num
04568 = (REGEXP_ONEOF (regexp)->regexps_num
04569 + REGEXP_ONEOF (oneof)->regexps_num - 1);
04570 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
04571 if (i < oneof_index)
04572 REGEXP_ONEOF (result)->regexps [i]
04573 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
04574 else if (i > oneof_index)
04575 REGEXP_ONEOF (result)->regexps
04576 [i + REGEXP_ONEOF (oneof)->regexps_num - 1]
04577 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
04578 else
04579 for (j = 0; j < REGEXP_ONEOF (oneof)->regexps_num; j++)
04580 REGEXP_ONEOF (result)->regexps [i + j]
04581 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [j]);
04582 regexp_transformed_p = 1;
04583 regexp = result;
04584 }
04585 }
04586 return regexp;
04587 }
04588
04589
04590
04591
04592
04593
04594 static regexp_t
04595 transform_3 (regexp_t regexp)
04596 {
04597 if (regexp->mode == rm_sequence)
04598 {
04599 regexp_t oneof = NULL;
04600 int oneof_index = 0;
04601 regexp_t result;
04602 regexp_t sequence;
04603 int i, j;
04604
04605 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
04606 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_oneof)
04607 {
04608 oneof_index = i;
04609 oneof = REGEXP_SEQUENCE (regexp)->regexps [i];
04610 break;
04611 }
04612 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
04613 {
04614 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
04615 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
04616 result = create_node (sizeof (struct regexp)
04617 + sizeof (regexp_t)
04618 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
04619 result->mode = rm_oneof;
04620 result->pos = regexp->pos;
04621 REGEXP_ONEOF (result)->regexps_num
04622 = REGEXP_ONEOF (oneof)->regexps_num;
04623 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
04624 {
04625 sequence
04626 = create_node (sizeof (struct regexp)
04627 + sizeof (regexp_t)
04628 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
04629 sequence->mode = rm_sequence;
04630 sequence->pos = regexp->pos;
04631 REGEXP_SEQUENCE (sequence)->regexps_num
04632 = REGEXP_SEQUENCE (regexp)->regexps_num;
04633 REGEXP_ONEOF (result)->regexps [i] = sequence;
04634 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
04635 if (j != oneof_index)
04636 REGEXP_SEQUENCE (sequence)->regexps [j]
04637 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [j]);
04638 else
04639 REGEXP_SEQUENCE (sequence)->regexps [j]
04640 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
04641 }
04642 regexp_transformed_p = 1;
04643 regexp = result;
04644 }
04645 }
04646 else if (regexp->mode == rm_allof)
04647 {
04648 regexp_t oneof = NULL;
04649 regexp_t seq;
04650 int oneof_index = 0;
04651 int max_seq_length, allof_length;
04652 regexp_t result;
04653 regexp_t allof = NULL;
04654 regexp_t allof_op = NULL;
04655 int i, j;
04656
04657 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
04658 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_oneof)
04659 {
04660 oneof_index = i;
04661 oneof = REGEXP_ALLOF (regexp)->regexps [i];
04662 break;
04663 }
04664 if (i < REGEXP_ALLOF (regexp)->regexps_num)
04665 {
04666 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
04667 && REGEXP_ALLOF (regexp)->regexps_num > 1);
04668 result = create_node (sizeof (struct regexp)
04669 + sizeof (regexp_t)
04670 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
04671 result->mode = rm_oneof;
04672 result->pos = regexp->pos;
04673 REGEXP_ONEOF (result)->regexps_num
04674 = REGEXP_ONEOF (oneof)->regexps_num;
04675 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
04676 {
04677 allof
04678 = create_node (sizeof (struct regexp)
04679 + sizeof (regexp_t)
04680 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
04681 allof->mode = rm_allof;
04682 allof->pos = regexp->pos;
04683 REGEXP_ALLOF (allof)->regexps_num
04684 = REGEXP_ALLOF (regexp)->regexps_num;
04685 REGEXP_ONEOF (result)->regexps [i] = allof;
04686 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
04687 if (j != oneof_index)
04688 REGEXP_ALLOF (allof)->regexps [j]
04689 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [j]);
04690 else
04691 REGEXP_ALLOF (allof)->regexps [j]
04692 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
04693 }
04694 regexp_transformed_p = 1;
04695 regexp = result;
04696 }
04697 max_seq_length = 0;
04698 if (regexp->mode == rm_allof)
04699 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
04700 {
04701 switch (REGEXP_ALLOF (regexp)->regexps [i]->mode)
04702 {
04703 case rm_sequence:
04704 seq = REGEXP_ALLOF (regexp)->regexps [i];
04705 if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)
04706 max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;
04707 break;
04708
04709 case rm_unit:
04710 case rm_nothing:
04711 break;
04712
04713 default:
04714 max_seq_length = 0;
04715 goto break_for;
04716 }
04717 }
04718 break_for:
04719 if (max_seq_length != 0)
04720 {
04721 gcc_assert (max_seq_length != 1
04722 && REGEXP_ALLOF (regexp)->regexps_num > 1);
04723 result = create_node (sizeof (struct regexp)
04724 + sizeof (regexp_t) * (max_seq_length - 1));
04725 result->mode = rm_sequence;
04726 result->pos = regexp->pos;
04727 REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
04728 for (i = 0; i < max_seq_length; i++)
04729 {
04730 allof_length = 0;
04731 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
04732 switch (REGEXP_ALLOF (regexp)->regexps [j]->mode)
04733 {
04734 case rm_sequence:
04735 if (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
04736 ->regexps [j])->regexps_num))
04737 {
04738 allof_op
04739 = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
04740 ->regexps [j])
04741 ->regexps [i]);
04742 allof_length++;
04743 }
04744 break;
04745 case rm_unit:
04746 case rm_nothing:
04747 if (i == 0)
04748 {
04749 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
04750 allof_length++;
04751 }
04752 break;
04753 default:
04754 break;
04755 }
04756
04757 if (allof_length == 1)
04758 REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
04759 else
04760 {
04761 allof = create_node (sizeof (struct regexp)
04762 + sizeof (regexp_t)
04763 * (allof_length - 1));
04764 allof->mode = rm_allof;
04765 allof->pos = regexp->pos;
04766 REGEXP_ALLOF (allof)->regexps_num = allof_length;
04767 REGEXP_SEQUENCE (result)->regexps [i] = allof;
04768 allof_length = 0;
04769 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
04770 if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
04771 && (i <
04772 (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
04773 ->regexps [j])->regexps_num)))
04774 {
04775 allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
04776 ->regexps [j])
04777 ->regexps [i]);
04778 REGEXP_ALLOF (allof)->regexps [allof_length]
04779 = allof_op;
04780 allof_length++;
04781 }
04782 else if (i == 0
04783 && (REGEXP_ALLOF (regexp)->regexps [j]->mode
04784 == rm_unit
04785 || (REGEXP_ALLOF (regexp)->regexps [j]->mode
04786 == rm_nothing)))
04787 {
04788 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
04789 REGEXP_ALLOF (allof)->regexps [allof_length]
04790 = allof_op;
04791 allof_length++;
04792 }
04793 }
04794 }
04795 regexp_transformed_p = 1;
04796 regexp = result;
04797 }
04798 }
04799 return regexp;
04800 }
04801
04802
04803
04804 static regexp_t
04805 regexp_transform_func (regexp_t regexp, regexp_t (*func) (regexp_t regexp))
04806 {
04807 int i;
04808
04809 switch (regexp->mode)
04810 {
04811 case rm_sequence:
04812 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
04813 REGEXP_SEQUENCE (regexp)->regexps [i]
04814 = regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i],
04815 func);
04816 break;
04817
04818 case rm_allof:
04819 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
04820 REGEXP_ALLOF (regexp)->regexps [i]
04821 = regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func);
04822 break;
04823
04824 case rm_oneof:
04825 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
04826 REGEXP_ONEOF (regexp)->regexps [i]
04827 = regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func);
04828 break;
04829
04830 case rm_repeat:
04831 REGEXP_REPEAT (regexp)->regexp
04832 = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func);
04833 break;
04834
04835 case rm_nothing:
04836 case rm_unit:
04837 break;
04838
04839 default:
04840 gcc_unreachable ();
04841 }
04842 return (*func) (regexp);
04843 }
04844
04845
04846
04847 static regexp_t
04848 transform_regexp (regexp_t regexp)
04849 {
04850 regexp = regexp_transform_func (regexp, transform_1);
04851 do
04852 {
04853 regexp_transformed_p = 0;
04854 regexp = regexp_transform_func (regexp, transform_2);
04855 regexp = regexp_transform_func (regexp, transform_3);
04856 }
04857 while (regexp_transformed_p);
04858 return regexp;
04859 }
04860
04861
04862
04863 static void
04864 transform_insn_regexps (void)
04865 {
04866 decl_t decl;
04867 int i;
04868
04869 transform_time = create_ticker ();
04870 add_advance_cycle_insn_decl ();
04871 if (progress_flag)
04872 fprintf (stderr, "Reservation transformation...");
04873 for (i = 0; i < description->decls_num; i++)
04874 {
04875 decl = description->decls [i];
04876 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
04877 DECL_INSN_RESERV (decl)->transformed_regexp
04878 = transform_regexp (copy_insn_regexp
04879 (DECL_INSN_RESERV (decl)->regexp));
04880 }
04881 if (progress_flag)
04882 fprintf (stderr, "done\n");
04883 ticker_off (&transform_time);
04884 }
04885
04886
04887
04888
04889
04890 static int annotation_message_reported_p;
04891
04892
04893 struct unit_usage
04894 {
04895 unit_decl_t unit_decl;
04896
04897
04898 struct unit_usage *next;
04899 };
04900 typedef struct unit_usage *unit_usage_t;
04901
04902 DEF_VEC_P(unit_usage_t);
04903 DEF_VEC_ALLOC_P(unit_usage_t,heap);
04904
04905
04906 static struct obstack unit_usages;
04907
04908
04909
04910
04911
04912
04913
04914 static VEC(unit_usage_t,heap) *cycle_alt_unit_usages;
04915
04916
04917
04918
04919 static void
04920 store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
04921 int alt_num)
04922 {
04923 size_t length;
04924 unit_decl_t unit_decl;
04925 unit_usage_t unit_usage_ptr;
04926 int index;
04927
04928 gcc_assert (regexp && regexp->mode == rm_oneof
04929 && alt_num < REGEXP_ONEOF (regexp)->regexps_num);
04930 unit_decl = REGEXP_UNIT (unit)->unit_decl;
04931
04932 length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
04933 while (VEC_length (unit_usage_t, cycle_alt_unit_usages) < length)
04934 VEC_safe_push (unit_usage_t,heap, cycle_alt_unit_usages, 0);
04935
04936 obstack_blank (&unit_usages, sizeof (struct unit_usage));
04937 unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages);
04938 obstack_finish (&unit_usages);
04939 unit_usage_ptr->unit_decl = unit_decl;
04940 index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
04941 unit_usage_ptr->next = VEC_index (unit_usage_t, cycle_alt_unit_usages, index);
04942 VEC_replace (unit_usage_t, cycle_alt_unit_usages, index, unit_usage_ptr);
04943 unit_decl->last_distribution_check_cycle = -1;
04944 }
04945
04946
04947
04948 static void
04949 check_regexp_units_distribution (const char *insn_reserv_name,
04950 regexp_t regexp)
04951 {
04952 int i, j, k, cycle;
04953 regexp_t seq, allof, unit;
04954 struct unit_usage *unit_usage_ptr, *other_unit_usage_ptr;
04955
04956 if (regexp == NULL || regexp->mode != rm_oneof)
04957 return;
04958
04959 obstack_init (&unit_usages);
04960 cycle_alt_unit_usages = 0;
04961
04962 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
04963 {
04964 seq = REGEXP_ONEOF (regexp)->regexps [i];
04965 switch (seq->mode)
04966 {
04967 case rm_sequence:
04968 for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++)
04969 {
04970 allof = REGEXP_SEQUENCE (seq)->regexps [j];
04971 switch (allof->mode)
04972 {
04973 case rm_allof:
04974 for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
04975 {
04976 unit = REGEXP_ALLOF (allof)->regexps [k];
04977 if (unit->mode == rm_unit)
04978 store_alt_unit_usage (regexp, unit, j, i);
04979 else
04980 gcc_assert (unit->mode == rm_nothing);
04981 }
04982 break;
04983
04984 case rm_unit:
04985 store_alt_unit_usage (regexp, allof, j, i);
04986 break;
04987
04988 case rm_nothing:
04989 break;
04990
04991 default:
04992 gcc_unreachable ();
04993 }
04994 }
04995 break;
04996
04997 case rm_allof:
04998 for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
04999 {
05000 unit = REGEXP_ALLOF (seq)->regexps [k];
05001 switch (unit->mode)
05002 {
05003 case rm_unit:
05004 store_alt_unit_usage (regexp, unit, 0, i);
05005 break;
05006
05007 case rm_nothing:
05008 break;
05009
05010 default:
05011 gcc_unreachable ();
05012 }
05013 }
05014 break;
05015
05016 case rm_unit:
05017 store_alt_unit_usage (regexp, seq, 0, i);
05018 break;
05019
05020 case rm_nothing:
05021 break;
05022
05023 default:
05024 gcc_unreachable ();
05025 }
05026 }
05027
05028 for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++)
05029 {
05030 cycle = i / REGEXP_ONEOF (regexp)->regexps_num;
05031 for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i);
05032 unit_usage_ptr != NULL;
05033 unit_usage_ptr = unit_usage_ptr->next)
05034 if (cycle != unit_usage_ptr->unit_decl->last_distribution_check_cycle)
05035 {
05036 unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
05037 for (k = cycle * REGEXP_ONEOF (regexp)->regexps_num;
05038 k < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages)
05039 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num;
05040 k++)
05041 {
05042 for (other_unit_usage_ptr
05043 = VEC_index (unit_usage_t, cycle_alt_unit_usages, k);
05044 other_unit_usage_ptr != NULL;
05045 other_unit_usage_ptr = other_unit_usage_ptr->next)
05046 if (unit_usage_ptr->unit_decl->automaton_decl
05047 == other_unit_usage_ptr->unit_decl->automaton_decl)
05048 break;
05049 if (other_unit_usage_ptr == NULL
05050 && (VEC_index (unit_usage_t, cycle_alt_unit_usages, k)
05051 != NULL))
05052 break;
05053 }
05054 if (k < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages)
05055 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num)
05056 {
05057 if (!annotation_message_reported_p)
05058 {
05059 fprintf (stderr, "\n");
05060 error ("The following units do not satisfy units-automata distribution rule");
05061 error (" (A unit of given unit automaton should be on each reserv. altern.)");
05062 annotation_message_reported_p = TRUE;
05063 }
05064 error ("Unit %s, reserv. %s, cycle %d",
05065 unit_usage_ptr->unit_decl->name, insn_reserv_name,
05066 cycle);
05067 }
05068 }
05069 }
05070 VEC_free (unit_usage_t,heap, cycle_alt_unit_usages);
05071 obstack_free (&unit_usages, NULL);
05072 }
05073
05074
05075
05076 static void
05077 check_unit_distributions_to_automata (void)
05078 {
05079 decl_t decl;
05080 int i;
05081
05082 if (progress_flag)
05083 fprintf (stderr, "Check unit distributions to automata...");
05084 annotation_message_reported_p = FALSE;
05085 for (i = 0; i < description->decls_num; i++)
05086 {
05087 decl = description->decls [i];
05088 if (decl->mode == dm_insn_reserv)
05089 check_regexp_units_distribution
05090 (DECL_INSN_RESERV (decl)->name,
05091 DECL_INSN_RESERV (decl)->transformed_regexp);
05092 }
05093 if (progress_flag)
05094 fprintf (stderr, "done\n");
05095 }
05096
05097
05098
05099
05100
05101
05102
05103
05104 static state_t state_being_formed;
05105
05106
05107 static alt_state_t alt_state_being_formed;
05108
05109
05110
05111
05112 static int
05113 process_seq_for_forming_states (regexp_t regexp, automaton_t automaton,
05114 int curr_cycle)
05115 {
05116 int i;
05117
05118 if (regexp == NULL)
05119 return curr_cycle;
05120
05121 switch (regexp->mode)
05122 {
05123 case rm_unit:
05124 if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num
05125 == automaton->automaton_order_num)
05126 set_state_reserv (state_being_formed, curr_cycle,
05127 REGEXP_UNIT (regexp)->unit_decl->unit_num);
05128 return curr_cycle;
05129
05130 case rm_sequence:
05131 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
05132 curr_cycle
05133 = process_seq_for_forming_states
05134 (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1;
05135 return curr_cycle;
05136
05137 case rm_allof:
05138 {
05139 int finish_cycle = 0;
05140 int cycle;
05141
05142 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
05143 {
05144 cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
05145 ->regexps [i],
05146 automaton, curr_cycle);
05147 if (finish_cycle < cycle)
05148 finish_cycle = cycle;
05149 }
05150 return finish_cycle;
05151 }
05152
05153 case rm_nothing:
05154 return curr_cycle;
05155
05156 default:
05157 gcc_unreachable ();
05158 }
05159 }
05160
05161
05162
05163 static void
05164 finish_forming_alt_state (alt_state_t alt_state,
05165 automaton_t automaton ATTRIBUTE_UNUSED)
05166 {
05167 state_t state_in_table;
05168 state_t corresponding_state;
05169
05170 corresponding_state = alt_state->state;
05171 state_in_table = insert_state (corresponding_state);
05172 if (state_in_table != corresponding_state)
05173 {
05174 free_state (corresponding_state);
05175 alt_state->state = state_in_table;
05176 }
05177 }
05178
05179
05180
05181 static ainsn_t curr_ainsn;
05182
05183
05184
05185
05186 static void
05187 process_alts_for_forming_states (regexp_t regexp, automaton_t automaton,
05188 int inside_oneof_p)
05189 {
05190 int i;
05191
05192 if (regexp->mode != rm_oneof)
05193 {
05194 alt_state_being_formed = get_free_alt_state ();
05195 state_being_formed = get_free_state (1, automaton);
05196 alt_state_being_formed->state = state_being_formed;
05197
05198
05199
05200 alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
05201 curr_ainsn->alt_states = alt_state_being_formed;
05202 (void) process_seq_for_forming_states (regexp, automaton, 0);
05203 finish_forming_alt_state (alt_state_being_formed, automaton);
05204 }
05205 else
05206 {
05207 gcc_assert (!inside_oneof_p);
05208
05209
05210
05211 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
05212 process_alts_for_forming_states (REGEXP_ONEOF (regexp)->regexps [i],
05213 automaton, 1);
05214 }
05215 }
05216
05217
05218 static void
05219 create_alt_states (automaton_t automaton)
05220 {
05221 struct insn_reserv_decl *reserv_decl;
05222
05223 for (curr_ainsn = automaton->ainsn_list;
05224 curr_ainsn != NULL;
05225 curr_ainsn = curr_ainsn->next_ainsn)
05226 {
05227 reserv_decl = curr_ainsn->insn_reserv_decl;
05228 if (reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
05229 {
05230 curr_ainsn->alt_states = NULL;
05231 process_alts_for_forming_states (reserv_decl->transformed_regexp,
05232 automaton, 0);
05233 curr_ainsn->sorted_alt_states
05234 = uniq_sort_alt_states (curr_ainsn->alt_states);
05235 }
05236 }
05237 }
05238
05239
05240
05241
05242
05243
05244
05245
05246
05247 static void
05248 form_ainsn_with_same_reservs (automaton_t automaton)
05249 {
05250 ainsn_t curr_ainsn;
05251 size_t i;
05252 VEC(ainsn_t,heap) *last_insns = VEC_alloc (ainsn_t,heap, 150);
05253
05254 for (curr_ainsn = automaton->ainsn_list;
05255 curr_ainsn != NULL;
05256 curr_ainsn = curr_ainsn->next_ainsn)
05257 if (curr_ainsn->insn_reserv_decl
05258 == DECL_INSN_RESERV (advance_cycle_insn_decl))
05259 {
05260 curr_ainsn->next_same_reservs_insn = NULL;
05261 curr_ainsn->first_insn_with_same_reservs = 1;
05262 }
05263 else
05264 {
05265 for (i = 0; i < VEC_length (ainsn_t, last_insns); i++)
05266 if (alt_states_eq
05267 (curr_ainsn->sorted_alt_states,
05268 VEC_index (ainsn_t, last_insns, i)->sorted_alt_states))
05269 break;
05270 curr_ainsn->next_same_reservs_insn = NULL;
05271 if (i < VEC_length (ainsn_t, last_insns))
05272 {
05273 curr_ainsn->first_insn_with_same_reservs = 0;
05274 VEC_index (ainsn_t, last_insns, i)->next_same_reservs_insn
05275 = curr_ainsn;
05276 VEC_replace (ainsn_t, last_insns, i, curr_ainsn);
05277 }
05278 else
05279 {
05280 VEC_safe_push (ainsn_t, heap, last_insns, curr_ainsn);
05281 curr_ainsn->first_insn_with_same_reservs = 1;
05282 }
05283 }
05284 VEC_free (ainsn_t,heap, last_insns);
05285 }
05286
05287
05288
05289
05290
05291
05292
05293
05294 static reserv_sets_t
05295 form_reservs_matter (automaton_t automaton)
05296 {
05297 int cycle, unit;
05298 reserv_sets_t reservs_matter = alloc_empty_reserv_sets();
05299
05300 for (cycle = 0; cycle < max_cycles_num; cycle++)
05301 for (unit = 0; unit < description->units_num; unit++)
05302 if (units_array [unit]->automaton_decl
05303 == automaton->corresponding_automaton_decl
05304 && (cycle >= units_array [unit]->min_occ_cycle_num
05305
05306 || units_array [unit]->query_p
05307
05308
05309
05310
05311 || units_array [unit]->in_set_p))
05312 set_unit_reserv (reservs_matter, cycle, unit);
05313 return reservs_matter;
05314 }
05315
05316
05317 static void
05318 make_automaton (automaton_t automaton)
05319 {
05320 ainsn_t ainsn;
05321 struct insn_reserv_decl *insn_reserv_decl;
05322 alt_state_t alt_state;
05323 state_t state;
05324 state_t start_state;
05325 state_t state2;
05326 ainsn_t advance_cycle_ainsn;
05327 arc_t added_arc;
05328 VEC(state_t,heap) *state_stack = VEC_alloc(state_t,heap, 150);
05329 int states_n;
05330 reserv_sets_t reservs_matter = form_reservs_matter (automaton);
05331
05332
05333 start_state = insert_state (get_free_state (1, automaton));
05334 automaton->start_state = start_state;
05335 start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
05336 VEC_safe_push (state_t,heap, state_stack, start_state);
05337 states_n = 1;
05338 while (VEC_length (state_t, state_stack) != 0)
05339 {
05340 state = VEC_pop (state_t, state_stack);
05341 advance_cycle_ainsn = NULL;
05342 for (ainsn = automaton->ainsn_list;
05343 ainsn != NULL;
05344 ainsn = ainsn->next_ainsn)
05345 if (ainsn->first_insn_with_same_reservs)
05346 {
05347 insn_reserv_decl = ainsn->insn_reserv_decl;
05348 if (insn_reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
05349 {
05350
05351
05352 added_arc = NULL;
05353 for (alt_state = ainsn->alt_states;
05354 alt_state != NULL;
05355 alt_state = alt_state->next_alt_state)
05356 {
05357 state2 = alt_state->state;
05358 if (!intersected_state_reservs_p (state, state2))
05359 {
05360 state2 = states_union (state, state2, reservs_matter);
05361 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
05362 {
05363 state2->it_was_placed_in_stack_for_NDFA_forming
05364 = 1;
05365 VEC_safe_push (state_t,heap, state_stack, state2);
05366 states_n++;
05367 if (progress_flag && states_n % 100 == 0)
05368 fprintf (stderr, ".");
05369 }
05370 added_arc = add_arc (state, state2, ainsn);
05371 if (!ndfa_flag)
05372 break;
05373 }
05374 }
05375 if (!ndfa_flag && added_arc != NULL)
05376 {
05377 for (alt_state = ainsn->alt_states;
05378 alt_state != NULL;
05379 alt_state = alt_state->next_alt_state)
05380 state2 = alt_state->state;
05381 }
05382 }
05383 else
05384 advance_cycle_ainsn = ainsn;
05385 }
05386
05387 state2 = state_shift (state, reservs_matter);
05388 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
05389 {
05390 state2->it_was_placed_in_stack_for_NDFA_forming = 1;
05391 VEC_safe_push (state_t,heap, state_stack, state2);
05392 states_n++;
05393 if (progress_flag && states_n % 100 == 0)
05394 fprintf (stderr, ".");
05395 }
05396 gcc_assert (advance_cycle_ainsn);
05397 add_arc (state, state2, advance_cycle_ainsn);
05398 }
05399 VEC_free (state_t,heap, state_stack);
05400 }
05401
05402
05403 static void
05404 form_arcs_marked_by_insn (state_t state)
05405 {
05406 decl_t decl;
05407 arc_t arc;
05408 int i;
05409
05410 for (i = 0; i < description->decls_num; i++)
05411 {
05412 decl = description->decls [i];
05413 if (decl->mode == dm_insn_reserv)
05414 DECL_INSN_RESERV (decl)->arcs_marked_by_insn = NULL;
05415 }
05416 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
05417 {
05418 gcc_assert (arc->insn);
05419 arc->next_arc_marked_by_insn
05420 = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
05421 arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
05422 }
05423 }
05424
05425
05426
05427
05428
05429
05430 static int
05431 create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
05432 VEC(state_t,heap) **state_stack)
05433 {
05434 state_t state;
05435 alt_state_t alt_state, curr_alt_state;
05436 alt_state_t new_alt_state;
05437 arc_t curr_arc;
05438 arc_t next_arc;
05439 state_t state_in_table;
05440 state_t temp_state;
05441 alt_state_t canonical_alt_states_list;
05442 int alts_number;
05443 int new_state_p = 0;
05444
05445 if (arcs_marked_by_insn == NULL)
05446 return new_state_p;
05447 if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
05448 state = arcs_marked_by_insn->to_state;
05449 else
05450 {
05451 gcc_assert (ndfa_flag);
05452
05453 state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
05454 curr_alt_state = NULL;
05455 for (curr_arc = arcs_marked_by_insn;
05456 curr_arc != NULL;
05457 curr_arc = curr_arc->next_arc_marked_by_insn)
05458 if (curr_arc->to_state->component_states == NULL)
05459 {
05460 new_alt_state = get_free_alt_state ();
05461 new_alt_state->next_alt_state = curr_alt_state;
05462 new_alt_state->state = curr_arc->to_state;
05463 curr_alt_state = new_alt_state;
05464 }
05465 else
05466 for (alt_state = curr_arc->to_state->component_states;
05467 alt_state != NULL;
05468 alt_state = alt_state->next_sorted_alt_state)
05469 {
05470 new_alt_state = get_free_alt_state ();
05471 new_alt_state->next_alt_state = curr_alt_state;
05472 new_alt_state->state = alt_state->state;
05473 gcc_assert (!alt_state->state->component_states);
05474 curr_alt_state = new_alt_state;
05475 }
05476
05477 canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
05478 if (canonical_alt_states_list->next_sorted_alt_state == NULL)
05479 {
05480 temp_state = state;
05481 state = canonical_alt_states_list->state;
05482 free_state (temp_state);
05483 }
05484 else
05485 {
05486 state->component_states = canonical_alt_states_list;
05487 state_in_table = insert_state (state);
05488 if (state_in_table != state)
05489 {
05490 gcc_assert
05491 (state_in_table->it_was_placed_in_stack_for_DFA_forming);
05492 free_state (state);
05493 state = state_in_table;
05494 }
05495 else
05496 {
05497 gcc_assert (!state->it_was_placed_in_stack_for_DFA_forming);
05498 new_state_p = 1;
05499 for (curr_alt_state = state->component_states;
05500 curr_alt_state != NULL;
05501 curr_alt_state = curr_alt_state->next_sorted_alt_state)
05502 for (curr_arc = first_out_arc (curr_alt_state->state);
05503 curr_arc != NULL;
05504 curr_arc = next_out_arc (curr_arc))
05505 add_arc (state, curr_arc->to_state, curr_arc->insn);
05506 }
05507 arcs_marked_by_insn->to_state = state;
05508 for (alts_number = 0,
05509 curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
05510 curr_arc != NULL;
05511 curr_arc = next_arc)
05512 {
05513 next_arc = curr_arc->next_arc_marked_by_insn;
05514 remove_arc (original_state, curr_arc);
05515 alts_number++;
05516 }
05517 }
05518 }
05519 if (!state->it_was_placed_in_stack_for_DFA_forming)
05520 {
05521 state->it_was_placed_in_stack_for_DFA_forming = 1;
05522 VEC_safe_push (state_t,heap, *state_stack, state);
05523 }
05524 return new_state_p;
05525 }
05526
05527
05528
05529
05530 static void
05531 NDFA_to_DFA (automaton_t automaton)
05532 {
05533 state_t start_state;
05534 state_t state;
05535 decl_t decl;
05536 VEC(state_t,heap) *state_stack;
05537 int i;
05538 int states_n;
05539
05540 state_stack = VEC_alloc (state_t,heap, 0);
05541
05542
05543 start_state = automaton->start_state;
05544 start_state->it_was_placed_in_stack_for_DFA_forming = 1;
05545 VEC_safe_push (state_t,heap, state_stack, start_state);
05546 states_n = 1;
05547 while (VEC_length (state_t, state_stack) != 0)
05548 {
05549 state = VEC_pop (state_t, state_stack);
05550 form_arcs_marked_by_insn (state);
05551 for (i = 0; i < description->decls_num; i++)
05552 {
05553 decl = description->decls [i];
05554 if (decl->mode == dm_insn_reserv
05555 && create_composed_state
05556 (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
05557 &state_stack))
05558 {
05559 states_n++;
05560 if (progress_flag && states_n % 100 == 0)
05561 fprintf (stderr, ".");
05562 }
05563 }
05564 }
05565 VEC_free (state_t,heap, state_stack);
05566 }
05567
05568
05569
05570 static int curr_state_graph_pass_num;
05571
05572
05573
05574 static void
05575 pass_state_graph (state_t start_state, void (*applied_func) (state_t state))
05576 {
05577 arc_t arc;
05578
05579 if (start_state->pass_num == curr_state_graph_pass_num)
05580 return;
05581 start_state->pass_num = curr_state_graph_pass_num;
05582 (*applied_func) (start_state);
05583 for (arc = first_out_arc (start_state);
05584 arc != NULL;
05585 arc = next_out_arc (arc))
05586 pass_state_graph (arc->to_state, applied_func);
05587 }
05588
05589
05590
05591 static void
05592 pass_states (automaton_t automaton, void (*applied_func) (state_t state))
05593 {
05594 curr_state_graph_pass_num++;
05595 pass_state_graph (automaton->start_state, applied_func);
05596 }
05597
05598
05599 static void
05600 initiate_pass_states (void)
05601 {
05602 curr_state_graph_pass_num = 0;
05603 }
05604
05605
05606
05607 static VEC(state_t,heap) *all_achieved_states;
05608
05609
05610
05611 static void
05612 add_achieved_state (state_t state)
05613 {
05614 VEC_safe_push (state_t,heap, all_achieved_states, state);
05615 }
05616
05617
05618
05619
05620
05621 static void
05622 set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
05623 {
05624 arc_t arc;
05625
05626 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
05627 {
05628 gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num);
05629 arc->insn->insn_reserv_decl->equiv_class_num
05630 = (odd_iteration_flag
05631 ? arc->to_state->equiv_class_num_1
05632 : arc->to_state->equiv_class_num_2);
05633 gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num);
05634 }
05635 }
05636
05637
05638
05639 static void
05640 clear_arc_insns_equiv_num (state_t state)
05641 {
05642 arc_t arc;
05643
05644 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
05645 arc->insn->insn_reserv_decl->equiv_class_num = 0;
05646 }
05647
05648
05649
05650
05651 static int
05652 first_cycle_unit_presence (state_t state, int unit_num)
05653 {
05654 alt_state_t alt_state;
05655
05656 if (state->component_states == NULL)
05657 return test_unit_reserv (state->reservs, 0, unit_num);
05658 else
05659 {
05660 for (alt_state = state->component_states;
05661 alt_state != NULL;
05662 alt_state = alt_state->next_sorted_alt_state)
05663 if (test_unit_reserv (alt_state->state->reservs, 0, unit_num))
05664 return true;
05665 }
05666 return false;
05667 }
05668
05669
05670 static void
05671 cache_presence (state_t state)
05672 {
05673 int i, num = 0;
05674 unsigned int sz;
05675 sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
05676 / (sizeof (int) * CHAR_BIT);
05677
05678 state->presence_signature = create_node (sz * sizeof (int));
05679 for (i = 0; i < description->units_num; i++)
05680 if (units_array [i]->query_p)
05681 {
05682 int presence1_p = first_cycle_unit_presence (state, i);
05683 state->presence_signature[num / (sizeof (int) * CHAR_BIT)]
05684 |= (!!presence1_p) << (num % (sizeof (int) * CHAR_BIT));
05685 num++;
05686 }
05687 }
05688
05689
05690
05691
05692
05693
05694 static int
05695 state_is_differed (state_t state, state_t another_state,
05696 int odd_iteration_flag)
05697 {
05698 arc_t arc;
05699 unsigned int sz, si;
05700
05701 gcc_assert (state->num_out_arcs == another_state->num_out_arcs);
05702
05703 sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
05704 / (sizeof (int) * CHAR_BIT);
05705
05706 for (si = 0; si < sz; si++)
05707 gcc_assert (state->presence_signature[si]
05708 == another_state->presence_signature[si]);
05709
05710 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
05711 {
05712 if ((odd_iteration_flag
05713 ? arc->to_state->equiv_class_num_1
05714 : arc->to_state->equiv_class_num_2)
05715 != arc->insn->insn_reserv_decl->equiv_class_num)
05716 return 1;
05717 }
05718
05719 return 0;
05720 }
05721
05722
05723
05724
05725
05726 static int
05727 compare_states_for_equiv (const void *state_ptr_1,
05728 const void *state_ptr_2)
05729 {
05730 state_t s1 = *(state_t *)state_ptr_1;
05731 state_t s2 = *(state_t *)state_ptr_2;
05732 unsigned int sz, si;
05733 if (s1->num_out_arcs < s2->num_out_arcs)
05734 return -1;
05735 else if (s1->num_out_arcs > s2->num_out_arcs)
05736 return 1;
05737
05738 sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
05739 / (sizeof (int) * CHAR_BIT);
05740
05741 for (si = 0; si < sz; si++)
05742 if (s1->presence_signature[si] < s2->presence_signature[si])
05743 return -1;
05744 else if (s1->presence_signature[si] > s2->presence_signature[si])
05745 return 1;
05746 return 0;
05747 }
05748
05749
05750
05751
05752 static int
05753 init_equiv_class (VEC(state_t,heap) *states, VEC (state_t,heap) **classes)
05754 {
05755 size_t i;
05756 state_t prev = 0;
05757 int class_num = 1;
05758
05759 *classes = VEC_alloc (state_t,heap, 150);
05760 for (i = 0; i < VEC_length (state_t, states); i++)
05761 {
05762 state_t state = VEC_index (state_t, states, i);
05763 if (prev)
05764 {
05765 if (compare_states_for_equiv (&prev, &state) != 0)
05766 {
05767 VEC_safe_push (state_t,heap, *classes, prev);
05768 class_num++;
05769 prev = NULL;
05770 }
05771 }
05772 state->equiv_class_num_1 = class_num;
05773 state->next_equiv_class_state = prev;
05774 prev = state;
05775 }
05776 if (prev)
05777 VEC_safe_push (state_t,heap, *classes, prev);
05778 return class_num;
05779 }
05780
05781
05782
05783 static void
05784 copy_equiv_class (VEC(state_t,heap) **to, VEC(state_t,heap) *from)
05785 {
05786 VEC_free (state_t,heap, *to);
05787 *to = VEC_copy (state_t,heap, from);
05788 }
05789
05790
05791
05792
05793
05794
05795
05796
05797 static int
05798 partition_equiv_class (state_t first_state, int odd_iteration_flag,
05799 VEC(state_t,heap) **next_iteration_classes,
05800 int *new_equiv_class_num_ptr)
05801 {
05802 state_t new_equiv_class;
05803 int partition_p;
05804 state_t curr_state;
05805 state_t prev_state;
05806 state_t next_state;
05807
05808 partition_p = 0;
05809
05810 while (first_state != NULL)
05811 {
05812 new_equiv_class = NULL;
05813 if (first_state->next_equiv_class_state != NULL)
05814 {
05815
05816 set_out_arc_insns_equiv_num (first_state, odd_iteration_flag);
05817 for (prev_state = first_state,
05818 curr_state = first_state->next_equiv_class_state;
05819 curr_state != NULL;
05820 curr_state = next_state)
05821 {
05822 next_state = curr_state->next_equiv_class_state;
05823 if (state_is_differed (curr_state, first_state,
05824 odd_iteration_flag))
05825 {
05826
05827 prev_state->next_equiv_class_state = next_state;
05828
05829 curr_state->next_equiv_class_state = new_equiv_class;
05830 if (new_equiv_class == NULL)
05831 (*new_equiv_class_num_ptr)++;
05832 if (odd_iteration_flag)
05833 curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
05834 else
05835 curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
05836 new_equiv_class = curr_state;
05837 partition_p = 1;
05838 }
05839 else
05840 prev_state = curr_state;
05841 }
05842 clear_arc_insns_equiv_num (first_state);
05843 }
05844 if (new_equiv_class != NULL)
05845 VEC_safe_push (state_t,heap, *next_iteration_classes, new_equiv_class);
05846 first_state = new_equiv_class;
05847 }
05848 return partition_p;
05849 }
05850
05851
05852 static void
05853 evaluate_equiv_classes (automaton_t automaton,
05854 VEC(state_t,heap) **equiv_classes)
05855 {
05856 int new_equiv_class_num;
05857 int odd_iteration_flag;
05858 int finish_flag;
05859 VEC (state_t,heap) *next_iteration_classes;
05860 size_t i;
05861
05862 all_achieved_states = VEC_alloc (state_t,heap, 1500);
05863 pass_states (automaton, add_achieved_state);
05864 pass_states (automaton, cache_presence);
05865 qsort (VEC_address (state_t, all_achieved_states),
05866 VEC_length (state_t, all_achieved_states),
05867 sizeof (state_t), compare_states_for_equiv);
05868
05869 odd_iteration_flag = 0;
05870 new_equiv_class_num = init_equiv_class (all_achieved_states,
05871 &next_iteration_classes);
05872
05873 do
05874 {
05875 odd_iteration_flag = !odd_iteration_flag;
05876 finish_flag = 1;
05877 copy_equiv_class (equiv_classes, next_iteration_classes);
05878
05879
05880 for (i = 0; i < VEC_length (state_t, all_achieved_states); i++)
05881 if (odd_iteration_flag)
05882 VEC_index (state_t, all_achieved_states, i)->equiv_class_num_2
05883 = VEC_index (state_t, all_achieved_states, i)->equiv_class_num_1;
05884 else
05885 VEC_index (state_t, all_achieved_states, i)->equiv_class_num_1
05886 = VEC_index (state_t, all_achieved_states, i)->equiv_class_num_2;
05887
05888 for (i = 0; i < VEC_length (state_t, *equiv_classes); i++)
05889 if (partition_equiv_class (VEC_index (state_t, *equiv_classes, i),
05890 odd_iteration_flag,
05891 &next_iteration_classes,
05892 &new_equiv_class_num))
05893 finish_flag = 0;
05894 }
05895 while (!finish_flag);
05896 VEC_free (state_t,heap, next_iteration_classes);
05897 VEC_free (state_t,heap, all_achieved_states);
05898 }
05899
05900
05901 static void
05902 merge_states (automaton_t automaton, VEC(state_t,heap) *equiv_classes)
05903 {
05904 state_t curr_state;
05905 state_t new_state;
05906 state_t first_class_state;
05907 alt_state_t alt_states;
05908 alt_state_t alt_state, new_alt_state;
05909 arc_t curr_arc;
05910 arc_t next_arc;
05911 size_t i;
05912
05913
05914
05915 for (i = 0; i < VEC_length (state_t, equiv_classes); i++)
05916 {
05917 curr_state = VEC_index (state_t, equiv_classes, i);
05918 if (curr_state->next_equiv_class_state != NULL)
05919 {
05920
05921
05922 new_state = get_free_state (0, automaton);
05923 alt_states = NULL;
05924 first_class_state = curr_state;
05925 for (curr_state = first_class_state;
05926 curr_state != NULL;
05927 curr_state = curr_state->next_equiv_class_state)
05928 {
05929 curr_state->equiv_class_state = new_state;
05930 if (curr_state->component_states == NULL)
05931 {
05932 new_alt_state = get_free_alt_state ();
05933 new_alt_state->state = curr_state;
05934 new_alt_state->next_alt_state = alt_states;
05935 alt_states = new_alt_state;
05936 }
05937 else
05938 for (alt_state = curr_state->component_states;
05939 alt_state != NULL;
05940 alt_state = alt_state->next_sorted_alt_state)
05941 {
05942 new_alt_state = get_free_alt_state ();
05943 new_alt_state->state = alt_state->state;
05944 new_alt_state->next_alt_state = alt_states;
05945 alt_states = new_alt_state;
05946 }
05947 }
05948
05949
05950 new_state->component_states = uniq_sort_alt_states (alt_states);
05951 }
05952 else
05953 curr_state->equiv_class_state = curr_state;
05954 }
05955
05956 for (i = 0; i < VEC_length (state_t, equiv_classes); i++)
05957 {
05958 curr_state = VEC_index (state_t, equiv_classes, i);
05959 if (curr_state->next_equiv_class_state != NULL)
05960 {
05961 first_class_state = curr_state;
05962
05963
05964 for (curr_arc = first_out_arc (first_class_state);
05965 curr_arc != NULL;
05966 curr_arc = next_out_arc (curr_arc))
05967 add_arc (first_class_state->equiv_class_state,
05968 curr_arc->to_state->equiv_class_state,
05969 curr_arc->insn);
05970
05971 for (curr_state = first_class_state;
05972 curr_state != NULL;
05973 curr_state = curr_state->next_equiv_class_state)
05974 {
05975 if (automaton->start_state == curr_state)
05976 automaton->start_state = curr_state->equiv_class_state;
05977
05978 for (curr_arc = first_out_arc (curr_state);
05979 curr_arc != NULL;
05980 curr_arc = next_arc)
05981 {
05982 next_arc = next_out_arc (curr_arc);
05983 free_arc (curr_arc);
05984 }
05985 }
05986 }
05987 else
05988 {
05989
05990
05991 for (curr_arc = first_out_arc (curr_state);
05992 curr_arc != NULL;
05993 curr_arc = next_out_arc (curr_arc))
05994 curr_arc->to_state = curr_arc->to_state->equiv_class_state;
05995 }
05996 }
05997 }
05998
05999
06000
06001 static void
06002 set_new_cycle_flags (state_t state)
06003 {
06004 arc_t arc;
06005
06006 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
06007 if (arc->insn->insn_reserv_decl
06008 == DECL_INSN_RESERV (advance_cycle_insn_decl))
06009 arc->to_state->new_cycle_p = 1;
06010 }
06011
06012
06013
06014 static void
06015 minimize_DFA (automaton_t automaton)
06016 {
06017 VEC(state_t,heap) *equiv_classes = 0;
06018
06019 evaluate_equiv_classes (automaton, &equiv_classes);
06020 merge_states (automaton, equiv_classes);
06021 pass_states (automaton, set_new_cycle_flags);
06022
06023 VEC_free (state_t,heap, equiv_classes);
06024 }
06025
06026
06027
06028 static int curr_counted_states_num;
06029 static int curr_counted_arcs_num;
06030
06031
06032
06033 static void
06034 incr_states_and_arcs_nums (state_t state)
06035 {
06036 arc_t arc;
06037
06038 curr_counted_states_num++;
06039 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
06040 curr_counted_arcs_num++;
06041 }
06042
06043
06044 static void
06045 count_states_and_arcs (automaton_t automaton, int *states_num,
06046 int *arcs_num)
06047 {
06048 curr_counted_states_num = 0;
06049 curr_counted_arcs_num = 0;
06050 pass_states (automaton, incr_states_and_arcs_nums);
06051 *states_num = curr_counted_states_num;
06052 *arcs_num = curr_counted_arcs_num;
06053 }
06054
06055
06056
06057
06058 static void
06059 build_automaton (automaton_t automaton)
06060 {
06061 int states_num;
06062 int arcs_num;
06063
06064 ticker_on (&NDFA_time);
06065 if (progress_flag)
06066 {
06067 if (automaton->corresponding_automaton_decl == NULL)
06068 fprintf (stderr, "Create anonymous automaton");
06069 else
06070 fprintf (stderr, "Create automaton `%s'",
06071 automaton->corresponding_automaton_decl->name);
06072 fprintf (stderr, " (1 dot is 100 new states):");
06073 }
06074 make_automaton (automaton);
06075 if (progress_flag)
06076 fprintf (stderr, " done\n");
06077 ticker_off (&NDFA_time);
06078 count_states_and_arcs (automaton, &states_num, &arcs_num);
06079 automaton->NDFA_states_num = states_num;
06080 automaton->NDFA_arcs_num = arcs_num;
06081 ticker_on (&NDFA_to_DFA_time);
06082 if (progress_flag)
06083 {
06084 if (automaton->corresponding_automaton_decl == NULL)
06085 fprintf (stderr, "Make anonymous DFA");
06086 else
06087 fprintf (stderr, "Make DFA `%s'",
06088 automaton->corresponding_automaton_decl->name);
06089 fprintf (stderr, " (1 dot is 100 new states):");
06090 }
06091 NDFA_to_DFA (automaton);
06092 if (progress_flag)
06093 fprintf (stderr, " done\n");
06094 ticker_off (&NDFA_to_DFA_time);
06095 count_states_and_arcs (automaton, &states_num, &arcs_num);
06096 automaton->DFA_states_num = states_num;
06097 automaton->DFA_arcs_num = arcs_num;
06098 if (!no_minimization_flag)
06099 {
06100 ticker_on (&minimize_time);
06101 if (progress_flag)
06102 {
06103 if (automaton->corresponding_automaton_decl == NULL)
06104 fprintf (stderr, "Minimize anonymous DFA...");
06105 else
06106 fprintf (stderr, "Minimize DFA `%s'...",
06107 automaton->corresponding_automaton_decl->name);
06108 }
06109 minimize_DFA (automaton);
06110 if (progress_flag)
06111 fprintf (stderr, "done\n");
06112 ticker_off (&minimize_time);
06113 count_states_and_arcs (automaton, &states_num, &arcs_num);
06114 automaton->minimal_DFA_states_num = states_num;
06115 automaton->minimal_DFA_arcs_num = arcs_num;
06116 }
06117 }
06118
06119
06120
06121
06122
06123
06124
06125 static int curr_state_order_num;
06126
06127
06128
06129 static void
06130 set_order_state_num (state_t state)
06131 {
06132 state->order_state_num = curr_state_order_num;
06133 curr_state_order_num++;
06134 }
06135
06136
06137 static void
06138 enumerate_states (automaton_t automaton)
06139 {
06140 curr_state_order_num = 0;
06141 pass_states (automaton, set_order_state_num);
06142 automaton->achieved_states_num = curr_state_order_num;
06143 }
06144
06145
06146
06147
06148
06149
06150
06151
06152 static ainsn_t
06153 insert_ainsn_into_equiv_class (ainsn_t ainsn,
06154 ainsn_t cyclic_equiv_class_insn_list)
06155 {
06156 if (cyclic_equiv_class_insn_list == NULL)
06157 ainsn->next_equiv_class_insn = ainsn;
06158 else
06159 {
06160 ainsn->next_equiv_class_insn
06161 = cyclic_equiv_class_insn_list->next_equiv_class_insn;
06162 cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
06163 }
06164 return ainsn;
06165 }
06166
06167
06168
06169 static void
06170 delete_ainsn_from_equiv_class (ainsn_t equiv_class_insn)
06171 {
06172 ainsn_t curr_equiv_class_insn;
06173 ainsn_t prev_equiv_class_insn;
06174
06175 prev_equiv_class_insn = equiv_class_insn;
06176 for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
06177 curr_equiv_class_insn != equiv_class_insn;
06178 curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
06179 prev_equiv_class_insn = curr_equiv_class_insn;
06180 if (prev_equiv_class_insn != equiv_class_insn)
06181 prev_equiv_class_insn->next_equiv_class_insn
06182 = equiv_class_insn->next_equiv_class_insn;
06183 }
06184
06185
06186
06187
06188 static void
06189 process_insn_equiv_class (ainsn_t ainsn, arc_t *insn_arcs_array)
06190 {
06191 ainsn_t next_insn;
06192 ainsn_t curr_insn;
06193 ainsn_t cyclic_insn_list;
06194 arc_t arc;
06195
06196 gcc_assert (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]);
06197 curr_insn = ainsn;
06198
06199 cyclic_insn_list = NULL;
06200 do
06201 {
06202 next_insn = curr_insn->next_equiv_class_insn;
06203 arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
06204 if (arc == NULL
06205 || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
06206 != arc->to_state))
06207 {
06208 delete_ainsn_from_equiv_class (curr_insn);
06209 cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
06210 cyclic_insn_list);
06211 }
06212 curr_insn = next_insn;
06213 }
06214 while (curr_insn != ainsn);
06215 }
06216
06217
06218 static void
06219 process_state_for_insn_equiv_partition (state_t state)
06220 {
06221 arc_t arc;
06222 arc_t *insn_arcs_array = XCNEWVEC (arc_t, description->insns_num);
06223
06224
06225 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
06226 insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
06227 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
06228 process_insn_equiv_class (arc->insn, insn_arcs_array);
06229
06230 free (insn_arcs_array);
06231 }
06232
06233
06234 static void
06235 set_insn_equiv_classes (automaton_t automaton)
06236 {
06237 ainsn_t ainsn;
06238 ainsn_t first_insn;
06239 ainsn_t curr_insn;
06240 ainsn_t cyclic_insn_list;
06241 ainsn_t insn_with_same_reservs;
06242 int equiv_classes_num;
06243
06244
06245 cyclic_insn_list = NULL;
06246 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
06247 if (ainsn->first_insn_with_same_reservs)
06248 cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
06249 cyclic_insn_list);
06250
06251 pass_states (automaton, process_state_for_insn_equiv_partition);
06252
06253 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
06254
06255 ainsn->insn_equiv_class_num = -1;
06256 equiv_classes_num = 0;
06257 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
06258 if (ainsn->insn_equiv_class_num < 0)
06259 {
06260 first_insn = ainsn;
06261 gcc_assert (first_insn->first_insn_with_same_reservs);
06262 first_insn->first_ainsn_with_given_equivalence_num = 1;
06263 curr_insn = first_insn;
06264 do
06265 {
06266 for (insn_with_same_reservs = curr_insn;
06267 insn_with_same_reservs != NULL;
06268 insn_with_same_reservs
06269 = insn_with_same_reservs->next_same_reservs_insn)
06270 insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
06271 curr_insn = curr_insn->next_equiv_class_insn;
06272 }
06273 while (curr_insn != first_insn);
06274 equiv_classes_num++;
06275 }
06276 automaton->insn_equiv_classes_num = equiv_classes_num;
06277 }
06278
06279
06280
06281
06282
06283
06284
06285
06286
06287
06288
06289
06290
06291 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
06292
06293
06294
06295 static double
06296 estimate_one_automaton_bound (void)
06297 {
06298 decl_t decl;
06299 double one_automaton_estimation_bound;
06300 double root_value;
06301 int i;
06302
06303 one_automaton_estimation_bound = 1.0;
06304 for (i = 0; i < description->decls_num; i++)
06305 {
06306 decl = description->decls [i];
06307 if (decl->mode == dm_unit)
06308 {
06309 root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num
06310 - DECL_UNIT (decl)->min_occ_cycle_num + 1.0)
06311 / automata_num);
06312 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
06313 > one_automaton_estimation_bound)
06314 one_automaton_estimation_bound *= root_value;
06315 }
06316 }
06317 return one_automaton_estimation_bound;
06318 }
06319
06320
06321
06322 static int
06323 compare_max_occ_cycle_nums (const void *unit_decl_1,
06324 const void *unit_decl_2)
06325 {
06326 if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
06327 < (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
06328 return 1;
06329 else if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
06330 == (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
06331 return 0;
06332 else
06333 return -1;
06334 }
06335
06336
06337
06338
06339 static void
06340 units_to_automata_heuristic_distr (void)
06341 {
06342 double estimation_bound;
06343 int automaton_num;
06344 int rest_units_num;
06345 double bound_value;
06346 unit_decl_t *unit_decls;
06347 int i, j;
06348
06349 if (description->units_num == 0)
06350 return;
06351 estimation_bound = estimate_one_automaton_bound ();
06352 unit_decls = XNEWVEC (unit_decl_t, description->units_num);
06353
06354 for (i = 0, j = 0; i < description->decls_num; i++)
06355 if (description->decls[i]->mode == dm_unit)
06356 unit_decls[j++] = DECL_UNIT (description->decls[i]);
06357 gcc_assert (j == description->units_num);
06358
06359 qsort (unit_decls, description->units_num,
06360 sizeof (unit_decl_t), compare_max_occ_cycle_nums);
06361
06362 automaton_num = 0;
06363 bound_value = unit_decls[0]->max_occ_cycle_num;
06364 unit_decls[0]->corresponding_automaton_num = automaton_num;
06365
06366 for (i = 1; i < description->units_num; i++)
06367 {
06368 rest_units_num = description->units_num - i + 1;
06369 gcc_assert (automata_num - automaton_num - 1 <= rest_units_num);
06370 if (automaton_num < automata_num - 1
06371 && ((automata_num - automaton_num - 1 == rest_units_num)
06372 || (bound_value
06373 > (estimation_bound
06374 / unit_decls[i]->max_occ_cycle_num))))
06375 {
06376 bound_value = unit_decls[i]->max_occ_cycle_num;
06377 automaton_num++;
06378 }
06379 else
06380 bound_value *= unit_decls[i]->max_occ_cycle_num;
06381 unit_decls[i]->corresponding_automaton_num = automaton_num;
06382 }
06383 gcc_assert (automaton_num == automata_num - 1);
06384 free (unit_decls);
06385 }
06386
06387
06388
06389
06390 static ainsn_t
06391 create_ainsns (void)
06392 {
06393 decl_t decl;
06394 ainsn_t first_ainsn;
06395 ainsn_t curr_ainsn;
06396 ainsn_t prev_ainsn;
06397 int i;
06398
06399 first_ainsn = NULL;
06400 prev_ainsn = NULL;
06401 for (i = 0; i < description->decls_num; i++)
06402 {
06403 decl = description->decls [i];
06404 if (decl->mode == dm_insn_reserv)
06405 {
06406 curr_ainsn = create_node (sizeof (struct ainsn));
06407 curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
06408 curr_ainsn->important_p = FALSE;
06409 curr_ainsn->next_ainsn = NULL;
06410 if (prev_ainsn == NULL)
06411 first_ainsn = curr_ainsn;
06412 else
06413 prev_ainsn->next_ainsn = curr_ainsn;
06414 prev_ainsn = curr_ainsn;
06415 }
06416 }
06417 return first_ainsn;
06418 }
06419
06420
06421
06422 static void
06423 units_to_automata_distr (void)
06424 {
06425 decl_t decl;
06426 int i;
06427
06428 for (i = 0; i < description->decls_num; i++)
06429 {
06430 decl = description->decls [i];
06431 if (decl->mode == dm_unit)
06432 {
06433 if (DECL_UNIT (decl)->automaton_decl == NULL
06434 || (DECL_UNIT (decl)->automaton_decl->corresponding_automaton
06435 == NULL))
06436
06437 DECL_UNIT (decl)->corresponding_automaton_num = 0;
06438 else
06439 DECL_UNIT (decl)->corresponding_automaton_num
06440 = (DECL_UNIT (decl)->automaton_decl
06441 ->corresponding_automaton->automaton_order_num);
06442 }
06443 }
06444 }
06445
06446
06447
06448 static void
06449 create_automata (void)
06450 {
06451 automaton_t curr_automaton;
06452 automaton_t prev_automaton;
06453 decl_t decl;
06454 int curr_automaton_num;
06455 int i;
06456
06457 if (automata_num != 0)
06458 {
06459 units_to_automata_heuristic_distr ();
06460 for (prev_automaton = NULL, curr_automaton_num = 0;
06461 curr_automaton_num < automata_num;
06462 curr_automaton_num++, prev_automaton = curr_automaton)
06463 {
06464 curr_automaton = create_node (sizeof (struct automaton));
06465 curr_automaton->ainsn_list = create_ainsns ();
06466 curr_automaton->corresponding_automaton_decl = NULL;
06467 curr_automaton->next_automaton = NULL;
06468 curr_automaton->automaton_order_num = curr_automaton_num;
06469 if (prev_automaton == NULL)
06470 description->first_automaton = curr_automaton;
06471 else
06472 prev_automaton->next_automaton = curr_automaton;
06473 }
06474 }
06475 else
06476 {
06477 curr_automaton_num = 0;
06478 prev_automaton = NULL;
06479 for (i = 0; i < description->decls_num; i++)
06480 {
06481 decl = description->decls [i];
06482 if (decl->mode == dm_automaton
06483 && DECL_AUTOMATON (decl)->automaton_is_used)
06484 {
06485 curr_automaton = create_node (sizeof (struct automaton));
06486 curr_automaton->ainsn_list = create_ainsns ();
06487 curr_automaton->corresponding_automaton_decl
06488 = DECL_AUTOMATON (decl);
06489 curr_automaton->next_automaton = NULL;
06490 DECL_AUTOMATON (decl)->corresponding_automaton = curr_automaton;
06491 curr_automaton->automaton_order_num = curr_automaton_num;
06492 if (prev_automaton == NULL)
06493 description->first_automaton = curr_automaton;
06494 else
06495 prev_automaton->next_automaton = curr_automaton;
06496 curr_automaton_num++;
06497 prev_automaton = curr_automaton;
06498 }
06499 }
06500 if (curr_automaton_num == 0)
06501 {
06502 curr_automaton = create_node (sizeof (struct automaton));
06503 curr_automaton->ainsn_list = create_ainsns ();
06504 curr_automaton->corresponding_automaton_decl = NULL;
06505 curr_automaton->next_automaton = NULL;
06506 description->first_automaton = curr_automaton;
06507 }
06508 units_to_automata_distr ();
06509 }
06510 NDFA_time = create_ticker ();
06511 ticker_off (&NDFA_time);
06512 NDFA_to_DFA_time = create_ticker ();
06513 ticker_off (&NDFA_to_DFA_time);
06514 minimize_time = create_ticker ();
06515 ticker_off (&minimize_time);
06516 equiv_time = create_ticker ();
06517 ticker_off (&equiv_time);
06518 for (curr_automaton = description->first_automaton;
06519 curr_automaton != NULL;
06520 curr_automaton = curr_automaton->next_automaton)
06521 {
06522 if (progress_flag)
06523 {
06524 if (curr_automaton->corresponding_automaton_decl == NULL)
06525 fprintf (stderr, "Prepare anonymous automaton creation ... ");
06526 else
06527 fprintf (stderr, "Prepare automaton `%s' creation...",
06528 curr_automaton->corresponding_automaton_decl->name);
06529 }
06530 create_alt_states (curr_automaton);
06531 form_ainsn_with_same_reservs (curr_automaton);
06532 if (progress_flag)
06533 fprintf (stderr, "done\n");
06534 build_automaton (curr_automaton);
06535 enumerate_states (curr_automaton);
06536 ticker_on (&equiv_time);
06537 set_insn_equiv_classes (curr_automaton);
06538 ticker_off (&equiv_time);
06539 }
06540 }
06541
06542
06543
06544
06545
06546
06547
06548
06549
06550
06551 static void
06552 form_regexp (regexp_t regexp)
06553 {
06554 int i;
06555
06556 switch (regexp->mode)
06557 {
06558 case rm_unit: case rm_reserv:
06559 {
06560 const char *name = (regexp->mode == rm_unit
06561 ? REGEXP_UNIT (regexp)->name
06562 : REGEXP_RESERV (regexp)->name);
06563
06564 obstack_grow (&irp, name, strlen (name));
06565 break;
06566 }
06567
06568 case rm_sequence:
06569 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
06570 {
06571 if (i != 0)
06572 obstack_1grow (&irp, ',');
06573 form_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
06574 }
06575 break;
06576
06577 case rm_allof:
06578 obstack_1grow (&irp, '(');
06579 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
06580 {
06581 if (i != 0)
06582 obstack_1grow (&irp, '+');
06583 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
06584 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
06585 obstack_1grow (&irp, '(');
06586 form_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
06587 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
06588 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
06589 obstack_1grow (&irp, ')');
06590 }
06591 obstack_1grow (&irp, ')');
06592 break;
06593
06594 case rm_oneof:
06595 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
06596 {
06597 if (i != 0)
06598 obstack_1grow (&irp, '|');
06599 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
06600 obstack_1grow (&irp, '(');
06601 form_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
06602 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
06603 obstack_1grow (&irp, ')');
06604 }
06605 break;
06606
06607 case rm_repeat:
06608 {
06609 char digits [30];
06610
06611 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
06612 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
06613 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
06614 obstack_1grow (&irp, '(');
06615 form_regexp (REGEXP_REPEAT (regexp)->regexp);
06616 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
06617 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
06618 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
06619 obstack_1grow (&irp, ')');
06620 sprintf (digits, "*%d", REGEXP_REPEAT (regexp)->repeat_num);
06621 obstack_grow (&irp, digits, strlen (digits));
06622 break;
06623 }
06624
06625 case rm_nothing:
06626 obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
06627 break;
06628
06629 default:
06630 gcc_unreachable ();
06631 }
06632 }
06633
06634
06635
06636 static const char *
06637 regexp_representation (regexp_t regexp)
06638 {
06639 form_regexp (regexp);
06640 obstack_1grow (&irp, '\0');
06641 return obstack_base (&irp);
06642 }
06643
06644
06645
06646 static void
06647 finish_regexp_representation (void)
06648 {
06649 int length = obstack_object_size (&irp);
06650
06651 obstack_blank_fast (&irp, -length);
06652 }
06653
06654
06655
06656
06657
06658
06659
06660
06661
06662
06663
06664
06665 static void
06666 output_range_type (FILE *f, long int min_range_value,
06667 long int max_range_value)
06668 {
06669 if (min_range_value >= 0 && max_range_value <= 255)
06670 fprintf (f, "unsigned char");
06671 else if (min_range_value >= -127 && max_range_value <= 127)
06672 fprintf (f, "signed char");
06673 else if (min_range_value >= 0 && max_range_value <= 65535)
06674 fprintf (f, "unsigned short");
06675 else if (min_range_value >= -32767 && max_range_value <= 32767)
06676 fprintf (f, "short");
06677 else
06678 fprintf (f, "int");
06679 }
06680
06681
06682
06683
06684
06685 #define ON_THE_PATH -2
06686
06687
06688
06689
06690
06691 static int
06692 longest_path_length (state_t state)
06693 {
06694 arc_t arc;
06695 int length, result;
06696
06697 if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
06698 {
06699
06700
06701
06702 gcc_assert (state->longest_path_length != ON_THE_PATH);
06703
06704
06705 return state->longest_path_length;
06706 }
06707
06708 result = 0;
06709 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
06710
06711 if (arc->to_state != state
06712 && (arc->insn->insn_reserv_decl
06713 != DECL_INSN_RESERV (advance_cycle_insn_decl)))
06714 {
06715 length = longest_path_length (arc->to_state);
06716 if (length > result)
06717 result = length;
06718 }
06719 state->longest_path_length = result + 1;
06720 return result;
06721 }
06722
06723
06724 static void
06725 output_vect (vla_hwint_t vect)
06726 {
06727 int els_on_line;
06728 size_t vect_length = VEC_length (vect_el_t, vect);
06729 size_t i;
06730
06731 els_on_line = 1;
06732 if (vect_length == 0)
06733 fputs ("0 /* This is dummy el because the vect is empty */", output_file);
06734 else
06735 for (i = 0; i < vect_length; i++)
06736 {
06737 fprintf (output_file, "%5ld", (long) VEC_index (vect_el_t, vect, i));
06738 if (els_on_line == 10)
06739 {
06740 els_on_line = 0;
06741 fputs (",\n", output_file);
06742 }
06743 else if (i < vect_length-1)
06744 fputs (", ", output_file);
06745 els_on_line++;
06746 }
06747 }
06748
06749
06750
06751 #define CHIP_NAME "DFA_chip"
06752
06753
06754
06755 static void
06756 output_chip_member_name (FILE *f, automaton_t automaton)
06757 {
06758 if (automaton->corresponding_automaton_decl == NULL)
06759 fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
06760 else
06761 fprintf (f, "%s_automaton_state",
06762 automaton->corresponding_automaton_decl->name);
06763 }
06764
06765
06766
06767 static void
06768 output_temp_chip_member_name (FILE *f, automaton_t automaton)
06769 {
06770 fprintf (f, "_");
06771 output_chip_member_name (f, automaton);
06772 }
06773
06774
06775
06776
06777 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
06778
06779
06780 static void
06781 output_translate_vect_name (FILE *f, automaton_t automaton)
06782 {
06783 if (automaton->corresponding_automaton_decl == NULL)
06784 fprintf (f, "translate_%d", automaton->automaton_order_num);
06785 else
06786 fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
06787 }
06788
06789
06790 static void
06791 output_trans_full_vect_name (FILE *f, automaton_t automaton)
06792 {
06793 if (automaton->corresponding_automaton_decl == NULL)
06794 fprintf (f, "transitions_%d", automaton->automaton_order_num);
06795 else
06796 fprintf (f, "%s_transitions",
06797 automaton->corresponding_automaton_decl->name);
06798 }
06799
06800
06801
06802 static void
06803 output_trans_comb_vect_name (FILE *f, automaton_t automaton)
06804 {
06805 if (automaton->corresponding_automaton_decl == NULL)
06806 fprintf (f, "transitions_%d", automaton->automaton_order_num);
06807 else
06808 fprintf (f, "%s_transitions",
06809 automaton->corresponding_automaton_decl->name);
06810 }
06811
06812
06813
06814 static void
06815 output_trans_check_vect_name (FILE *f, automaton_t automaton)
06816 {
06817 if (automaton->corresponding_automaton_decl == NULL)
06818 fprintf (f, "check_%d", automaton->automaton_order_num);
06819 else
06820 fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
06821 }
06822
06823
06824
06825 static void
06826 output_trans_base_vect_name (FILE *f, automaton_t automaton)
06827 {
06828 if (automaton->corresponding_automaton_decl == NULL)
06829 fprintf (f, "base_%d", automaton->automaton_order_num);
06830 else
06831 fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
06832 }
06833
06834
06835 static void
06836 output_min_issue_delay_vect_name (FILE *f, automaton_t automaton)
06837 {
06838 if (automaton->corresponding_automaton_decl == NULL)
06839 fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
06840 else
06841 fprintf (f, "%s_min_issue_delay",
06842 automaton->corresponding_automaton_decl->name);
06843 }
06844
06845
06846 static void
06847 output_dead_lock_vect_name (FILE *f, automaton_t automaton)
06848 {
06849 if (automaton->corresponding_automaton_decl == NULL)
06850 fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
06851 else
06852 fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
06853 }
06854
06855
06856 static void
06857 output_reserved_units_table_name (FILE *f, automaton_t automaton)
06858 {
06859 if (automaton->corresponding_automaton_decl == NULL)
06860 fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
06861 else
06862 fprintf (f, "%s_reserved_units",
06863 automaton->corresponding_automaton_decl->name);
06864 }
06865
06866
06867 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
06868
06869
06870 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
06871
06872
06873 #define STATE_TYPE_NAME "state_t"
06874
06875 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
06876
06877 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
06878
06879 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
06880
06881 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
06882
06883
06884 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
06885
06886
06887 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
06888
06889
06890 #define SIZE_FUNC_NAME "state_size"
06891
06892 #define TRANSITION_FUNC_NAME "state_transition"
06893
06894 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
06895
06896 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
06897
06898 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
06899
06900 #define RESET_FUNC_NAME "state_reset"
06901
06902 #define INSN_LATENCY_FUNC_NAME "insn_latency"
06903
06904 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
06905
06906 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
06907
06908 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
06909
06910 #define DFA_CLEAN_INSN_CACHE_FUNC_NAME "dfa_clean_insn_cache"
06911
06912 #define DFA_CLEAR_SINGLE_INSN_CACHE_FUNC_NAME "dfa_clear_single_insn_cache"
06913
06914 #define DFA_START_FUNC_NAME "dfa_start"
06915
06916 #define DFA_FINISH_FUNC_NAME "dfa_finish"
06917
06918
06919 #define STATE_NAME "state"
06920
06921 #define INSN_PARAMETER_NAME "insn"
06922
06923 #define INSN2_PARAMETER_NAME "insn2"
06924
06925 #define CHIP_PARAMETER_NAME "chip"
06926
06927 #define FILE_PARAMETER_NAME "f"
06928
06929 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
06930
06931 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
06932
06933
06934
06935 #define INTERNAL_INSN_CODE_NAME "insn_code"
06936
06937 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
06938
06939
06940 #define TEMPORARY_VARIABLE_NAME "temp"
06941
06942 #define I_VARIABLE_NAME "i"
06943
06944
06945 #define RESULT_VARIABLE_NAME "res"
06946
06947
06948
06949 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
06950
06951
06952
06953 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
06954
06955
06956
06957 static void
06958 output_state_member_type (FILE *f, automaton_t automaton)
06959 {
06960 output_range_type (f, 0, automaton->achieved_states_num);
06961 }
06962
06963
06964
06965 static void
06966 output_chip_definitions (void)
06967 {
06968 automaton_t automaton;
06969
06970 fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
06971 for (automaton = description->first_automaton;
06972 automaton != NULL;
06973 automaton = automaton->next_automaton)
06974 {
06975 fprintf (output_file, " ");
06976 output_state_member_type (output_file, automaton);
06977 fprintf (output_file, " ");
06978 output_chip_member_name (output_file, automaton);
06979 fprintf (output_file, ";\n");
06980 }
06981 fprintf (output_file, "};\n\n");
06982 #if 0
06983 fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
06984 #endif
06985 }
06986
06987
06988
06989
06990
06991 static void
06992 output_translate_vect (automaton_t automaton)
06993 {
06994 ainsn_t ainsn;
06995 int insn_value;
06996 vla_hwint_t translate_vect;
06997
06998 translate_vect = VEC_alloc (vect_el_t,heap, description->insns_num);
06999
07000 for (insn_value = 0; insn_value < description->insns_num; insn_value++)
07001
07002 VEC_quick_push (vect_el_t, translate_vect,
07003 automaton->insn_equiv_classes_num);
07004
07005 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
07006 VEC_replace (vect_el_t, translate_vect,
07007 ainsn->insn_reserv_decl->insn_num,
07008 ainsn->insn_equiv_class_num);
07009
07010 fprintf (output_file,
07011 "/* Vector translating external insn codes to internal ones.*/\n");
07012 fprintf (output_file, "static const ");
07013 output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
07014 fprintf (output_file, " ");
07015 output_translate_vect_name (output_file, automaton);
07016 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
07017 output_vect (translate_vect);
07018 fprintf (output_file, "};\n\n");
07019 VEC_free (vect_el_t,heap, translate_vect);
07020 }
07021
07022
07023
07024 static int undefined_vect_el_value;
07025
07026
07027
07028 static int
07029 comb_vect_p (state_ainsn_table_t tab)
07030 {
07031 return (2 * VEC_length (vect_el_t, tab->full_vect)
07032 > 5 * VEC_length (vect_el_t, tab->comb_vect));
07033 }
07034
07035
07036 static state_ainsn_table_t
07037 create_state_ainsn_table (automaton_t automaton)
07038 {
07039 state_ainsn_table_t tab;
07040 int full_vect_length;
07041 int i;
07042
07043 tab = create_node (sizeof (struct state_ainsn_table));
07044 tab->automaton = automaton;
07045
07046 tab->comb_vect = VEC_alloc (vect_el_t,heap, 10000);
07047 tab->check_vect = VEC_alloc (vect_el_t,heap, 10000);
07048
07049 tab->base_vect = 0;
07050 VEC_safe_grow (vect_el_t,heap, tab->base_vect,
07051 automaton->achieved_states_num);
07052
07053 full_vect_length = (automaton->insn_equiv_classes_num
07054 * automaton->achieved_states_num);
07055 tab->full_vect = VEC_alloc (vect_el_t,heap, full_vect_length);
07056 for (i = 0; i < full_vect_length; i++)
07057 VEC_quick_push (vect_el_t, tab->full_vect, undefined_vect_el_value);
07058
07059 tab->min_base_vect_el_value = 0;
07060 tab->max_base_vect_el_value = 0;
07061 tab->min_comb_vect_el_value = 0;
07062 tab->max_comb_vect_el_value = 0;
07063 return tab;
07064 }
07065
07066
07067
07068 static void
07069 output_state_ainsn_table (state_ainsn_table_t tab, const char *table_name,
07070 void (*output_full_vect_name_func) (FILE *, automaton_t),
07071 void (*output_comb_vect_name_func) (FILE *, automaton_t),
07072 void (*output_check_vect_name_func) (FILE *, automaton_t),
07073 void (*output_base_vect_name_func) (FILE *, automaton_t))
07074 {
07075 if (!comb_vect_p (tab))
07076 {
07077 fprintf (output_file, "/* Vector for %s. */\n", table_name);
07078 fprintf (output_file, "static const ");
07079 output_range_type (output_file, tab->min_comb_vect_el_value,
07080 tab->max_comb_vect_el_value);
07081 fprintf (output_file, " ");
07082 (*output_full_vect_name_func) (output_file, tab->automaton);
07083 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
07084 output_vect (tab->full_vect);
07085 fprintf (output_file, "};\n\n");
07086 }
07087 else
07088 {
07089 fprintf (output_file, "/* Comb vector for %s. */\n", table_name);
07090 fprintf (output_file, "static const ");
07091 output_range_type (output_file, tab->min_comb_vect_el_value,
07092 tab->max_comb_vect_el_value);
07093 fprintf (output_file, " ");
07094 (*output_comb_vect_name_func) (output_file, tab->automaton);
07095 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
07096 output_vect (tab->comb_vect);
07097 fprintf (output_file, "};\n\n");
07098 fprintf (output_file, "/* Check vector for %s. */\n", table_name);
07099 fprintf (output_file, "static const ");
07100 output_range_type (output_file, 0, tab->automaton->achieved_states_num);
07101 fprintf (output_file, " ");
07102 (*output_check_vect_name_func) (output_file, tab->automaton);
07103 fprintf (output_file, "[] = {\n");
07104 output_vect (tab->check_vect);
07105 fprintf (output_file, "};\n\n");
07106 fprintf (output_file, "/* Base vector for %s. */\n", table_name);
07107 fprintf (output_file, "static const ");
07108 output_range_type (output_file, tab->min_base_vect_el_value,
07109 tab->max_base_vect_el_value);
07110 fprintf (output_file, " ");
07111 (*output_base_vect_name_func) (output_file, tab->automaton);
07112 fprintf (output_file, "[] = {\n");
07113 output_vect (tab->base_vect);
07114 fprintf (output_file, "};\n\n");
07115 }
07116 }
07117
07118
07119
07120 static void
07121 add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
07122 {
07123 int vect_length;
07124 size_t real_vect_length;
07125 int comb_vect_index;
07126 int comb_vect_els_num;
07127 int vect_index;
07128 int first_unempty_vect_index;
07129 int additional_els_num;
07130 int no_state_value;
07131 vect_el_t vect_el;
07132 int i;
07133 unsigned long vect_mask, comb_vect_mask;
07134
07135 vect_length = VEC_length (vect_el_t, vect);
07136 gcc_assert (vect_length);
07137 gcc_assert (VEC_last (vect_el_t, vect) != undefined_vect_el_value);
07138 real_vect_length = tab->automaton->insn_equiv_classes_num;
07139
07140 {
07141 size_t full_base = tab->automaton->insn_equiv_classes_num * vect_num;
07142 if (VEC_length (vect_el_t, tab->full_vect) < full_base + vect_length)
07143 VEC_safe_grow (vect_el_t,heap, tab->full_vect,
07144 full_base + vect_length);
07145 for (i = 0; i < vect_length; i++)
07146 VEC_replace (vect_el_t, tab->full_vect, full_base + i,
07147 VEC_index (vect_el_t, vect, i));
07148 }
07149
07150 gcc_assert (VEC_length (vect_el_t, tab->comb_vect)
07151 == VEC_length (vect_el_t, tab->check_vect));
07152
07153 comb_vect_els_num = VEC_length (vect_el_t, tab->comb_vect);
07154 for (first_unempty_vect_index = 0;
07155 first_unempty_vect_index < vect_length;
07156 first_unempty_vect_index++)
07157 if (VEC_index (vect_el_t, vect, first_unempty_vect_index)
07158 != undefined_vect_el_value)
07159 break;
07160
07161
07162
07163
07164 if (vect_length - first_unempty_vect_index >= SIZEOF_LONG * CHAR_BIT)
07165 {
07166 for (comb_vect_index = 0;
07167 comb_vect_index < comb_vect_els_num;
07168 comb_vect_index++)
07169 {
07170 for (vect_index = first_unempty_vect_index;
07171 vect_index < vect_length
07172 && vect_index + comb_vect_index < comb_vect_els_num;
07173 vect_index++)
07174 if (VEC_index (vect_el_t, vect, vect_index)
07175 != undefined_vect_el_value
07176 && (VEC_index (vect_el_t, tab->comb_vect,
07177 vect_index + comb_vect_index)
07178 != undefined_vect_el_value))
07179 break;
07180 if (vect_index >= vect_length
07181 || vect_index + comb_vect_index >= comb_vect_els_num)
07182 break;
07183 }
07184 goto found;
07185 }
07186
07187
07188 vect_mask = 0;
07189 for (vect_index = first_unempty_vect_index;
07190 vect_index < vect_length;
07191 vect_index++)
07192 {
07193 vect_mask = vect_mask << 1;
07194 if (VEC_index (vect_el_t, vect, vect_index) != undefined_vect_el_value)
07195 vect_mask |= 1;
07196 }
07197
07198
07199 comb_vect_index = 0;
07200 if (comb_vect_els_num == 0)
07201 goto found;
07202
07203 comb_vect_mask = 0;
07204 for (vect_index = first_unempty_vect_index;
07205 vect_index < vect_length && vect_index < comb_vect_els_num;
07206 vect_index++)
07207 {
07208 comb_vect_mask <<= 1;
07209 if (vect_index + comb_vect_index < comb_vect_els_num
07210 && VEC_index (vect_el_t, tab->comb_vect, vect_index + comb_vect_index)
07211 != undefined_vect_el_value)
07212 comb_vect_mask |= 1;
07213 }
07214 if ((vect_mask & comb_vect_mask) == 0)
07215 goto found;
07216
07217 for (comb_vect_index = 1, i = vect_length; i < comb_vect_els_num;
07218 comb_vect_index++, i++)
07219 {
07220 comb_vect_mask = (comb_vect_mask << 1) | 1;
07221 comb_vect_mask ^= (VEC_index (vect_el_t, tab->comb_vect, i)
07222 == undefined_vect_el_value);
07223 if ((vect_mask & comb_vect_mask) == 0)
07224 goto found;
07225 }
07226 for ( ; comb_vect_index < comb_vect_els_num; comb_vect_index++)
07227 {
07228 comb_vect_mask <<= 1;
07229 if ((vect_mask & comb_vect_mask) == 0)
07230 goto found;
07231 }
07232
07233 found:
07234
07235 additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
07236 if (additional_els_num < 0)
07237 additional_els_num = 0;
07238
07239 vect_el = undefined_vect_el_value;
07240 no_state_value = tab->automaton->achieved_states_num;
07241 while (additional_els_num > 0)
07242 {
07243 VEC_safe_push (vect_el_t,heap, tab->comb_vect, vect_el);
07244 VEC_safe_push (vect_el_t,heap, tab->check_vect, no_state_value);
07245 additional_els_num--;
07246 }
07247 gcc_assert (VEC_length (vect_el_t, tab->comb_vect)
07248 >= comb_vect_index + real_vect_length);
07249
07250 for (vect_index = 0; vect_index < vect_length; vect_index++)
07251 if (VEC_index (vect_el_t, vect, vect_index) != undefined_vect_el_value)
07252 {
07253 vect_el_t x = VEC_index (vect_el_t, vect, vect_index);
07254 gcc_assert (VEC_index (vect_el_t, tab->comb_vect,
07255 comb_vect_index + vect_index)
07256 == undefined_vect_el_value);
07257 gcc_assert (x >= 0);
07258 if (tab->max_comb_vect_el_value < x)
07259 tab->max_comb_vect_el_value = x;
07260 if (tab->min_comb_vect_el_value > x)
07261 tab->min_comb_vect_el_value = x;
07262 VEC_replace (vect_el_t, tab->comb_vect,
07263 comb_vect_index + vect_index, x);
07264 VEC_replace (vect_el_t, tab->check_vect,
07265 comb_vect_index + vect_index, vect_num);
07266 }
07267 if (tab->max_comb_vect_el_value < undefined_vect_el_value)
07268 tab->max_comb_vect_el_value = undefined_vect_el_value;
07269 if (tab->min_comb_vect_el_value > undefined_vect_el_value)
07270 tab->min_comb_vect_el_value = undefined_vect_el_value;
07271 if (tab->max_base_vect_el_value < comb_vect_index)
07272 tab->max_base_vect_el_value = comb_vect_index;
07273 if (tab->min_base_vect_el_value > comb_vect_index)
07274 tab->min_base_vect_el_value = comb_vect_index;
07275
07276 VEC_replace (vect_el_t, tab->base_vect, vect_num, comb_vect_index);
07277 }
07278
07279
07280 static int
07281 out_state_arcs_num (state_t state)
07282 {
07283 int result;
07284 arc_t arc;
07285
07286 result = 0;
07287 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
07288 {
07289 gcc_assert (arc->insn);
07290 if (arc->insn->first_ainsn_with_given_equivalence_num)
07291 result++;
07292 }
07293 return result;
07294 }
07295
07296
07297 static int
07298 compare_transition_els_num (const void *state_ptr_1,
07299 const void *state_ptr_2)
07300 {
07301 int transition_els_num_1;
07302 int transition_els_num_2;
07303
07304 transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
07305 transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
07306 if (transition_els_num_1 < transition_els_num_2)
07307 return 1;
07308 else if (transition_els_num_1 == transition_els_num_2)
07309 return 0;
07310 else
07311 return -1;
07312 }
07313
07314
07315
07316 static void
07317 add_vect_el (vla_hwint_t *vect, ainsn_t ainsn, int el_value)
07318 {
07319 int equiv_class_num;
07320 int vect_index;
07321
07322 gcc_assert (ainsn);
07323 equiv_class_num = ainsn->insn_equiv_class_num;
07324 for (vect_index = VEC_length (vect_el_t, *vect);
07325 vect_index <= equiv_class_num;
07326 vect_index++)
07327 VEC_safe_push (vect_el_t,heap, *vect, undefined_vect_el_value);
07328 VEC_replace (vect_el_t, *vect, equiv_class_num, el_value);
07329 }
07330
07331
07332 static VEC(state_t,heap) *output_states_vect;
07333
07334
07335
07336 static void
07337 add_states_vect_el (state_t state)
07338 {
07339 VEC_safe_push (state_t,heap, output_states_vect, state);
07340 }
07341
07342
07343
07344 static void
07345 output_trans_table (automaton_t automaton)
07346 {
07347 size_t i;
07348 arc_t arc;
07349 vla_hwint_t transition_vect = 0;
07350
07351 undefined_vect_el_value = automaton->achieved_states_num;
07352 automaton->trans_table = create_state_ainsn_table (automaton);
07353
07354
07355 output_states_vect = 0;
07356 pass_states (automaton, add_states_vect_el);
07357 qsort (VEC_address (state_t, output_states_vect),
07358 VEC_length (state_t, output_states_vect),
07359 sizeof (state_t), compare_transition_els_num);
07360
07361 for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
07362 {
07363 VEC_truncate (vect_el_t, transition_vect, 0);
07364 for (arc = first_out_arc (VEC_index (state_t, output_states_vect, i));
07365 arc != NULL;
07366 arc = next_out_arc (arc))
07367 {
07368 gcc_assert (arc->insn);
07369 if (arc->insn->first_ainsn_with_given_equivalence_num)
07370 add_vect_el (&transition_vect, arc->insn,
07371 arc->to_state->order_state_num);
07372 }
07373 add_vect (automaton->trans_table,
07374 VEC_index (state_t, output_states_vect, i)->order_state_num,
07375 transition_vect);
07376 }
07377 output_state_ainsn_table
07378 (automaton->trans_table, "state transitions",
07379 output_trans_full_vect_name, output_trans_comb_vect_name,
07380 output_trans_check_vect_name, output_trans_base_vect_name);
07381
07382 VEC_free (state_t,heap, output_states_vect);
07383 VEC_free (vect_el_t,heap, transition_vect);
07384 }
07385
07386
07387
07388 static int curr_state_pass_num;
07389
07390
07391
07392
07393
07394 static int
07395 min_issue_delay_pass_states (state_t state, ainsn_t ainsn)
07396 {
07397 arc_t arc;
07398 int min_insn_issue_delay, insn_issue_delay;
07399
07400 if (state->state_pass_num == curr_state_pass_num
07401 || state->min_insn_issue_delay != -1)
07402
07403
07404 return state->min_insn_issue_delay;
07405 state->state_pass_num = curr_state_pass_num;
07406 min_insn_issue_delay = -1;
07407 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
07408 if (arc->insn == ainsn)
07409 {
07410 min_insn_issue_delay = 0;
07411 break;
07412 }
07413 else
07414 {
07415 insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
07416 if (insn_issue_delay != -1)
07417 {
07418 if (arc->insn->insn_reserv_decl
07419 == DECL_INSN_RESERV (advance_cycle_insn_decl))
07420 insn_issue_delay++;
07421 if (min_insn_issue_delay == -1
07422 || min_insn_issue_delay > insn_issue_delay)
07423 {
07424 min_insn_issue_delay = insn_issue_delay;
07425 if (insn_issue_delay == 0)
07426 break;
07427 }
07428 }
07429 }
07430 return min_insn_issue_delay;
07431 }
07432
07433
07434
07435
07436 static int
07437 min_issue_delay (state_t state, ainsn_t ainsn)
07438 {
07439 curr_state_pass_num++;
07440 state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
07441 return state->min_insn_issue_delay;
07442 }
07443
07444
07445
07446 static void
07447 initiate_min_issue_delay_pass_states (void)
07448 {
07449 curr_state_pass_num = 0;
07450 }
07451
07452
07453
07454
07455 static void
07456 output_min_issue_delay_table (automaton_t automaton)
07457 {
07458 vla_hwint_t min_issue_delay_vect;
07459 vla_hwint_t compressed_min_issue_delay_vect;
07460 vect_el_t min_delay;
07461 ainsn_t ainsn;
07462 size_t i, min_issue_delay_len;
07463 size_t compressed_min_issue_delay_len;
07464 size_t cfactor;
07465
07466
07467
07468 output_states_vect = 0;
07469 pass_states (automaton, add_states_vect_el);
07470
07471 min_issue_delay_len = (VEC_length (state_t, output_states_vect)
07472 * automaton->insn_equiv_classes_num);
07473 min_issue_delay_vect = VEC_alloc (vect_el_t,heap, min_issue_delay_len);
07474 for (i = 0; i < min_issue_delay_len; i++)
07475 VEC_quick_push (vect_el_t, min_issue_delay_vect, 0);
07476
07477 automaton->max_min_delay = 0;
07478 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
07479 if (ainsn->first_ainsn_with_given_equivalence_num)
07480 {
07481 for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
07482 VEC_index (state_t, output_states_vect, i)->min_insn_issue_delay = -1;
07483 for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
07484 {
07485 state_t s = VEC_index (state_t, output_states_vect, i);
07486 min_delay = min_issue_delay (s, ainsn);
07487 if (automaton->max_min_delay < min_delay)
07488 automaton->max_min_delay = min_delay;
07489 VEC_replace (vect_el_t, min_issue_delay_vect,
07490 s->order_state_num
07491 * automaton->insn_equiv_classes_num
07492 + ainsn->insn_equiv_class_num,
07493 min_delay);
07494 }
07495 }
07496 fprintf (output_file, "/* Vector of min issue delay of insns. */\n");
07497 fprintf (output_file, "static const ");
07498 output_range_type (output_file, 0, automaton->max_min_delay);
07499 fprintf (output_file, " ");
07500 output_min_issue_delay_vect_name (output_file, automaton);
07501 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
07502
07503 if (automaton->max_min_delay < 2)
07504 cfactor = 8;
07505 else if (automaton->max_min_delay < 4)
07506 cfactor = 4;
07507 else if (automaton->max_min_delay < 16)
07508 cfactor = 2;
07509 else
07510 cfactor = 1;
07511 automaton->min_issue_delay_table_compression_factor = cfactor;
07512
07513 compressed_min_issue_delay_len = (min_issue_delay_len+cfactor-1) / cfactor;
07514 compressed_min_issue_delay_vect
07515 = VEC_alloc (vect_el_t,heap, compressed_min_issue_delay_len);
07516
07517 for (i = 0; i < compressed_min_issue_delay_len; i++)
07518 VEC_quick_push (vect_el_t, compressed_min_issue_delay_vect, 0);
07519
07520 for (i = 0; i < min_issue_delay_len; i++)
07521 {
07522 size_t ci = i / cfactor;
07523 vect_el_t x = VEC_index (vect_el_t, min_issue_delay_vect, i);
07524 vect_el_t cx = VEC_index (vect_el_t, compressed_min_issue_delay_vect, ci);
07525
07526 cx |= x << (8 - (i % cfactor + 1) * (8 / cfactor));
07527 VEC_replace (vect_el_t, compressed_min_issue_delay_vect, ci, cx);
07528 }
07529 output_vect (compressed_min_issue_delay_vect);
07530 fprintf (output_file, "};\n\n");
07531 VEC_free (state_t,heap, output_states_vect);
07532 VEC_free (vect_el_t,heap, min_issue_delay_vect);
07533 VEC_free (vect_el_t,heap, compressed_min_issue_delay_vect);
07534 }
07535
07536
07537
07538 static void
07539 output_dead_lock_vect (automaton_t automaton)
07540 {
07541 size_t i;
07542 arc_t arc;
07543 vla_hwint_t dead_lock_vect = 0;
07544
07545
07546
07547
07548 automaton->locked_states = 0;
07549 output_states_vect = 0;
07550 pass_states (automaton, add_states_vect_el);
07551
07552 VEC_safe_grow (vect_el_t,heap, dead_lock_vect,
07553 VEC_length (state_t, output_states_vect));
07554 for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
07555 {
07556 state_t s = VEC_index (state_t, output_states_vect, i);
07557 arc = first_out_arc (s);
07558 gcc_assert (arc);
07559 if (next_out_arc (arc) == NULL
07560 && (arc->insn->insn_reserv_decl
07561 == DECL_INSN_RESERV (advance_cycle_insn_decl)))
07562 {
07563 VEC_replace (vect_el_t, dead_lock_vect, s->order_state_num, 1);
07564 automaton->locked_states++;
07565 }
07566 else
07567 VEC_replace (vect_el_t, dead_lock_vect, s->order_state_num, 0);
07568 }
07569 if (automaton->locked_states == 0)
07570 return;
07571
07572 fprintf (output_file, "/* Vector for locked state flags. */\n");
07573 fprintf (output_file, "static const ");
07574 output_range_type (output_file, 0, 1);
07575 fprintf (output_file, " ");
07576 output_dead_lock_vect_name (output_file, automaton);
07577 fprintf (output_file, "[] = {\n");
07578 output_vect (dead_lock_vect);
07579 fprintf (output_file, "};\n\n");
07580 VEC_free (state_t,heap, output_states_vect);
07581 VEC_free (vect_el_t,heap, dead_lock_vect);
07582 }
07583
07584
07585
07586 static void
07587 output_reserved_units_table (automaton_t automaton)
07588 {
07589 vla_hwint_t reserved_units_table = 0;
07590 int state_byte_size;
07591 int reserved_units_size;
07592 size_t n;
07593 int i;
07594
07595 if (description->query_units_num == 0)
07596 return;
07597
07598
07599 output_states_vect = 0;
07600 pass_states (automaton, add_states_vect_el);
07601
07602 state_byte_size = (description->query_units_num + 7) / 8;
07603 reserved_units_size = (VEC_length (state_t, output_states_vect)
07604 * state_byte_size);
07605
07606 reserved_units_table = VEC_alloc (vect_el_t,heap, reserved_units_size);
07607
07608 for (i = 0; i < reserved_units_size; i++)
07609 VEC_quick_push (vect_el_t, reserved_units_table, 0);
07610 for (n = 0; n < VEC_length (state_t, output_states_vect); n++)
07611 {
07612 state_t s = VEC_index (state_t, output_states_vect, n);
07613 for (i = 0; i < description->units_num; i++)
07614 if (units_array [i]->query_p
07615 && first_cycle_unit_presence (s, i))
07616 {
07617 int ri = (s->order_state_num * state_byte_size
07618 + units_array [i]->query_num / 8);
07619 vect_el_t x = VEC_index (vect_el_t, reserved_units_table, ri);
07620
07621 x += 1 << (units_array [i]->query_num % 8);
07622 VEC_replace (vect_el_t, reserved_units_table, ri, x);
07623 }
07624 }
07625 fprintf (output_file, "\n#if %s\n", CPU_UNITS_QUERY_MACRO_NAME);
07626 fprintf (output_file, "/* Vector for reserved units of states. */\n");
07627 fprintf (output_file, "static const ");
07628 output_range_type (output_file, 0, 255);
07629 fprintf (output_file, " ");
07630 output_reserved_units_table_name (output_file, automaton);
07631 fprintf (output_file, "[] = {\n");
07632 output_vect (reserved_units_table);
07633 fprintf (output_file, "};\n#endif /* #if %s */\n\n",
07634 CPU_UNITS_QUERY_MACRO_NAME);
07635
07636 VEC_free (state_t,heap, output_states_vect);
07637 VEC_free (vect_el_t