Mercurial > hg > CbC > CbC_gcc
comparison gcc/genautomata.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
1 /* Pipeline hazard description translator. | 1 /* Pipeline hazard description translator. |
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 | 2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 |
3 Free Software Foundation, Inc. | 3 Free Software Foundation, Inc. |
4 | 4 |
5 Written by Vladimir Makarov <vmakarov@redhat.com> | 5 Written by Vladimir Makarov <vmakarov@redhat.com> |
6 | 6 |
7 This file is part of GCC. | 7 This file is part of GCC. |
20 along with GCC; see the file COPYING3. If not see | 20 along with GCC; see the file COPYING3. If not see |
21 <http://www.gnu.org/licenses/>. */ | 21 <http://www.gnu.org/licenses/>. */ |
22 | 22 |
23 /* References: | 23 /* References: |
24 | 24 |
25 1. Detecting pipeline structural hazards quickly. T. Proebsting, | 25 1. The finite state automaton based pipeline hazard recognizer and |
26 instruction scheduler in GCC. V. Makarov. Proceedings of GCC | |
27 summit, 2003. | |
28 | |
29 2. Detecting pipeline structural hazards quickly. T. Proebsting, | |
26 C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on | 30 C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on |
27 Principles of Programming Languages, pages 280--286, 1994. | 31 Principles of Programming Languages, pages 280--286, 1994. |
28 | 32 |
29 This article is a good start point to understand usage of finite | 33 This article is a good start point to understand usage of finite |
30 state automata for pipeline hazard recognizers. But I'd | 34 state automata for pipeline hazard recognizers. But I'd |
31 recommend the 2nd article for more deep understanding. | 35 recommend the 1st and 3rd article for more deep understanding. |
32 | 36 |
33 2. Efficient Instruction Scheduling Using Finite State Automata: | 37 3. Efficient Instruction Scheduling Using Finite State Automata: |
34 V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best | 38 V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best |
35 article about usage of finite state automata for pipeline hazard | 39 article about usage of finite state automata for pipeline hazard |
36 recognizers. | 40 recognizers. |
37 | 41 |
38 The current implementation is different from the 2nd article in the | 42 The current implementation is described in the 1st article and it |
39 following: | 43 is different from the 3rd article in the following: |
40 | 44 |
41 1. New operator `|' (alternative) is permitted in functional unit | 45 1. New operator `|' (alternative) is permitted in functional unit |
42 reservation which can be treated deterministically and | 46 reservation which can be treated deterministically and |
43 non-deterministically. | 47 non-deterministically. |
44 | 48 |
207 | 211 |
208 | 212 |
209 /* Declare vector types for various data structures: */ | 213 /* Declare vector types for various data structures: */ |
210 | 214 |
211 DEF_VEC_P(alt_state_t); | 215 DEF_VEC_P(alt_state_t); |
212 DEF_VEC_ALLOC_P(alt_state_t,heap); | 216 DEF_VEC_ALLOC_P(alt_state_t, heap); |
213 DEF_VEC_P(ainsn_t); | 217 DEF_VEC_P(ainsn_t); |
214 DEF_VEC_ALLOC_P(ainsn_t,heap); | 218 DEF_VEC_ALLOC_P(ainsn_t, heap); |
215 DEF_VEC_P(state_t); | 219 DEF_VEC_P(state_t); |
216 DEF_VEC_ALLOC_P(state_t,heap); | 220 DEF_VEC_ALLOC_P(state_t, heap); |
217 DEF_VEC_P(decl_t); | 221 DEF_VEC_P(decl_t); |
218 DEF_VEC_ALLOC_P(decl_t,heap); | 222 DEF_VEC_ALLOC_P(decl_t, heap); |
219 DEF_VEC_P(reserv_sets_t); | 223 DEF_VEC_P(reserv_sets_t); |
220 DEF_VEC_ALLOC_P(reserv_sets_t,heap); | 224 DEF_VEC_ALLOC_P(reserv_sets_t, heap); |
221 | 225 |
222 DEF_VEC_I(vect_el_t); | 226 DEF_VEC_I(vect_el_t); |
223 DEF_VEC_ALLOC_I(vect_el_t, heap); | 227 DEF_VEC_ALLOC_I(vect_el_t, heap); |
224 typedef VEC(vect_el_t,heap) *vla_hwint_t; | 228 typedef VEC(vect_el_t, heap) *vla_hwint_t; |
225 | 229 |
226 /* Forward declarations of functions used before their definitions, only. */ | 230 /* Forward declarations of functions used before their definitions, only. */ |
227 static regexp_t gen_regexp_sequence (const char *); | 231 static regexp_t gen_regexp_sequence (const char *); |
228 static void reserv_sets_or (reserv_sets_t, reserv_sets_t, | 232 static void reserv_sets_or (reserv_sets_t, reserv_sets_t, |
229 reserv_sets_t); | 233 reserv_sets_t); |
461 | 465 |
462 /* The following field value is order number (0, 1, ...) of given | 466 /* The following field value is order number (0, 1, ...) of given |
463 insn. */ | 467 insn. */ |
464 int insn_num; | 468 int insn_num; |
465 /* The following field value is list of bypasses in which given insn | 469 /* The following field value is list of bypasses in which given insn |
466 is output insn. */ | 470 is output insn. Bypasses with the same input insn stay one after |
471 another in the list in the same order as their occurrences in the | |
472 description but the bypass without a guard stays always the last | |
473 in a row of bypasses with the same input insn. */ | |
467 struct bypass_decl *bypass_list; | 474 struct bypass_decl *bypass_list; |
468 | 475 |
469 /* The following fields are defined by automaton generator. */ | 476 /* The following fields are defined by automaton generator. */ |
470 | 477 |
471 /* The following field is the insn regexp transformed that | 478 /* The following field is the insn regexp transformed that |
1128 return name; | 1135 return name; |
1129 } | 1136 } |
1130 | 1137 |
1131 /* Pointers to all declarations during IR generation are stored in the | 1138 /* Pointers to all declarations during IR generation are stored in the |
1132 following. */ | 1139 following. */ |
1133 static VEC(decl_t,heap) *decls; | 1140 static VEC(decl_t, heap) *decls; |
1134 | 1141 |
1135 /* Given a pointer to a (char *) and a separator, return an alloc'ed | 1142 /* Given a pointer to a (char *) and a separator, return an alloc'ed |
1136 string containing the next separated element, taking parentheses | 1143 string containing the next separated element, taking parentheses |
1137 into account if PAR_FLAG has nonzero value. Advance the pointer to | 1144 into account if PAR_FLAG has nonzero value. Advance the pointer to |
1138 after the string scanned, or the end-of-string. Return NULL if at | 1145 after the string scanned, or the end-of-string. Return NULL if at |
1256 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos); | 1263 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos); |
1257 DECL_UNIT (decl)->automaton_name = XSTR (def, 1); | 1264 DECL_UNIT (decl)->automaton_name = XSTR (def, 1); |
1258 DECL_UNIT (decl)->query_p = 0; | 1265 DECL_UNIT (decl)->query_p = 0; |
1259 DECL_UNIT (decl)->min_occ_cycle_num = -1; | 1266 DECL_UNIT (decl)->min_occ_cycle_num = -1; |
1260 DECL_UNIT (decl)->in_set_p = 0; | 1267 DECL_UNIT (decl)->in_set_p = 0; |
1261 VEC_safe_push (decl_t,heap, decls, decl); | 1268 VEC_safe_push (decl_t, heap, decls, decl); |
1262 } | 1269 } |
1263 } | 1270 } |
1264 | 1271 |
1265 /* Process a DEFINE_QUERY_CPU_UNIT. | 1272 /* Process a DEFINE_QUERY_CPU_UNIT. |
1266 | 1273 |
1284 decl->mode = dm_unit; | 1291 decl->mode = dm_unit; |
1285 decl->pos = 0; | 1292 decl->pos = 0; |
1286 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos); | 1293 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos); |
1287 DECL_UNIT (decl)->automaton_name = XSTR (def, 1); | 1294 DECL_UNIT (decl)->automaton_name = XSTR (def, 1); |
1288 DECL_UNIT (decl)->query_p = 1; | 1295 DECL_UNIT (decl)->query_p = 1; |
1289 VEC_safe_push (decl_t,heap, decls, decl); | 1296 VEC_safe_push (decl_t, heap, decls, decl); |
1290 } | 1297 } |
1291 } | 1298 } |
1292 | 1299 |
1293 /* Process a DEFINE_BYPASS. | 1300 /* Process a DEFINE_BYPASS. |
1294 | 1301 |
1319 decl->pos = 0; | 1326 decl->pos = 0; |
1320 DECL_BYPASS (decl)->latency = XINT (def, 0); | 1327 DECL_BYPASS (decl)->latency = XINT (def, 0); |
1321 DECL_BYPASS (decl)->out_insn_name = out_insns [i]; | 1328 DECL_BYPASS (decl)->out_insn_name = out_insns [i]; |
1322 DECL_BYPASS (decl)->in_insn_name = in_insns [j]; | 1329 DECL_BYPASS (decl)->in_insn_name = in_insns [j]; |
1323 DECL_BYPASS (decl)->bypass_guard_name = XSTR (def, 3); | 1330 DECL_BYPASS (decl)->bypass_guard_name = XSTR (def, 3); |
1324 VEC_safe_push (decl_t,heap, decls, decl); | 1331 VEC_safe_push (decl_t, heap, decls, decl); |
1325 } | 1332 } |
1326 } | 1333 } |
1327 | 1334 |
1328 /* Process an EXCLUSION_SET. | 1335 /* Process an EXCLUSION_SET. |
1329 | 1336 |
1358 if (i < first_vect_length) | 1365 if (i < first_vect_length) |
1359 DECL_EXCL (decl)->names [i] = first_str_cpu_units [i]; | 1366 DECL_EXCL (decl)->names [i] = first_str_cpu_units [i]; |
1360 else | 1367 else |
1361 DECL_EXCL (decl)->names [i] | 1368 DECL_EXCL (decl)->names [i] |
1362 = second_str_cpu_units [i - first_vect_length]; | 1369 = second_str_cpu_units [i - first_vect_length]; |
1363 VEC_safe_push (decl_t,heap, decls, decl); | 1370 VEC_safe_push (decl_t, heap, decls, decl); |
1364 } | 1371 } |
1365 | 1372 |
1366 /* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET, | 1373 /* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET, |
1367 FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P). | 1374 FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P). |
1368 | 1375 |
1427 DECL_ABSENCE (decl)->names = str_cpu_units; | 1434 DECL_ABSENCE (decl)->names = str_cpu_units; |
1428 DECL_ABSENCE (decl)->patterns = str_patterns; | 1435 DECL_ABSENCE (decl)->patterns = str_patterns; |
1429 DECL_ABSENCE (decl)->patterns_num = patterns_length; | 1436 DECL_ABSENCE (decl)->patterns_num = patterns_length; |
1430 DECL_ABSENCE (decl)->final_p = final_p; | 1437 DECL_ABSENCE (decl)->final_p = final_p; |
1431 } | 1438 } |
1432 VEC_safe_push (decl_t,heap, decls, decl); | 1439 VEC_safe_push (decl_t, heap, decls, decl); |
1433 } | 1440 } |
1434 | 1441 |
1435 /* Process a PRESENCE_SET. | 1442 /* Process a PRESENCE_SET. |
1436 | 1443 |
1437 This gives information about a cpu unit reservation requirements. | 1444 This gives information about a cpu unit reservation requirements. |
1496 { | 1503 { |
1497 decl = XCREATENODE (struct decl); | 1504 decl = XCREATENODE (struct decl); |
1498 decl->mode = dm_automaton; | 1505 decl->mode = dm_automaton; |
1499 decl->pos = 0; | 1506 decl->pos = 0; |
1500 DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos); | 1507 DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos); |
1501 VEC_safe_push (decl_t,heap, decls, decl); | 1508 VEC_safe_push (decl_t, heap, decls, decl); |
1502 } | 1509 } |
1503 } | 1510 } |
1504 | 1511 |
1505 /* Process an AUTOMATA_OPTION. | 1512 /* Process an AUTOMATA_OPTION. |
1506 | 1513 |
1697 decl = XCREATENODE (struct decl); | 1704 decl = XCREATENODE (struct decl); |
1698 decl->mode = dm_reserv; | 1705 decl->mode = dm_reserv; |
1699 decl->pos = 0; | 1706 decl->pos = 0; |
1700 DECL_RESERV (decl)->name = check_name (XSTR (def, 0), decl->pos); | 1707 DECL_RESERV (decl)->name = check_name (XSTR (def, 0), decl->pos); |
1701 DECL_RESERV (decl)->regexp = gen_regexp (XSTR (def, 1)); | 1708 DECL_RESERV (decl)->regexp = gen_regexp (XSTR (def, 1)); |
1702 VEC_safe_push (decl_t,heap, decls, decl); | 1709 VEC_safe_push (decl_t, heap, decls, decl); |
1703 } | 1710 } |
1704 | 1711 |
1705 /* Process a DEFINE_INSN_RESERVATION. | 1712 /* Process a DEFINE_INSN_RESERVATION. |
1706 | 1713 |
1707 This gives information about the reservation of cpu units by an | 1714 This gives information about the reservation of cpu units by an |
1718 DECL_INSN_RESERV (decl)->name | 1725 DECL_INSN_RESERV (decl)->name |
1719 = check_name (XSTR (def, 0), decl->pos); | 1726 = check_name (XSTR (def, 0), decl->pos); |
1720 DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1); | 1727 DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1); |
1721 DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2); | 1728 DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2); |
1722 DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3)); | 1729 DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3)); |
1723 VEC_safe_push (decl_t,heap, decls, decl); | 1730 VEC_safe_push (decl_t, heap, decls, decl); |
1724 } | 1731 } |
1725 | 1732 |
1726 | 1733 |
1727 | 1734 |
1728 /* The function evaluates hash value (0..UINT_MAX) of string. */ | 1735 /* The function evaluates hash value (0..UINT_MAX) of string. */ |
1787 static decl_t | 1794 static decl_t |
1788 insert_automaton_decl (decl_t automaton_decl) | 1795 insert_automaton_decl (decl_t automaton_decl) |
1789 { | 1796 { |
1790 void **entry_ptr; | 1797 void **entry_ptr; |
1791 | 1798 |
1792 entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1); | 1799 entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, INSERT); |
1793 if (*entry_ptr == NULL) | 1800 if (*entry_ptr == NULL) |
1794 *entry_ptr = (void *) automaton_decl; | 1801 *entry_ptr = (void *) automaton_decl; |
1795 return (decl_t) *entry_ptr; | 1802 return (decl_t) *entry_ptr; |
1796 } | 1803 } |
1797 | 1804 |
1886 static decl_t | 1893 static decl_t |
1887 insert_insn_decl (decl_t insn_decl) | 1894 insert_insn_decl (decl_t insn_decl) |
1888 { | 1895 { |
1889 void **entry_ptr; | 1896 void **entry_ptr; |
1890 | 1897 |
1891 entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1); | 1898 entry_ptr = htab_find_slot (insn_decl_table, insn_decl, INSERT); |
1892 if (*entry_ptr == NULL) | 1899 if (*entry_ptr == NULL) |
1893 *entry_ptr = (void *) insn_decl; | 1900 *entry_ptr = (void *) insn_decl; |
1894 return (decl_t) *entry_ptr; | 1901 return (decl_t) *entry_ptr; |
1895 } | 1902 } |
1896 | 1903 |
1987 static decl_t | 1994 static decl_t |
1988 insert_decl (decl_t decl) | 1995 insert_decl (decl_t decl) |
1989 { | 1996 { |
1990 void **entry_ptr; | 1997 void **entry_ptr; |
1991 | 1998 |
1992 entry_ptr = htab_find_slot (decl_table, decl, 1); | 1999 entry_ptr = htab_find_slot (decl_table, decl, INSERT); |
1993 if (*entry_ptr == NULL) | 2000 if (*entry_ptr == NULL) |
1994 *entry_ptr = (void *) decl; | 2001 *entry_ptr = (void *) decl; |
1995 return (decl_t) *entry_ptr; | 2002 return (decl_t) *entry_ptr; |
1996 } | 2003 } |
1997 | 2004 |
2305 error ("unit `%s' excludes and requires presence of `%s'", | 2312 error ("unit `%s' excludes and requires presence of `%s'", |
2306 dst->unit_decl->name, unit->name); | 2313 dst->unit_decl->name, unit->name); |
2307 no_error_flag = 0; | 2314 no_error_flag = 0; |
2308 } | 2315 } |
2309 else | 2316 else |
2310 warning | 2317 warning ("unit `%s' excludes and requires presence of `%s'", |
2311 (0, "unit `%s' excludes and requires presence of `%s'", | |
2312 dst->unit_decl->name, unit->name); | 2318 dst->unit_decl->name, unit->name); |
2313 } | 2319 } |
2314 } | 2320 } |
2315 else if (pat->units_num == 1) | 2321 else if (pat->units_num == 1) |
2316 for (curr_pat_el = dst->unit_decl->presence_list; | 2322 for (curr_pat_el = dst->unit_decl->presence_list; |
2319 if (curr_pat_el->units_num == 1 | 2325 if (curr_pat_el->units_num == 1 |
2320 && unit == curr_pat_el->unit_decls [0]) | 2326 && unit == curr_pat_el->unit_decls [0]) |
2321 { | 2327 { |
2322 if (!w_flag) | 2328 if (!w_flag) |
2323 { | 2329 { |
2324 error | 2330 error ("unit `%s' requires absence and presence of `%s'", |
2325 ("unit `%s' requires absence and presence of `%s'", | 2331 dst->unit_decl->name, unit->name); |
2326 dst->unit_decl->name, unit->name); | |
2327 no_error_flag = 0; | 2332 no_error_flag = 0; |
2328 } | 2333 } |
2329 else | 2334 else |
2330 warning | 2335 warning ("unit `%s' requires absence and presence of `%s'", |
2331 (0, "unit `%s' requires absence and presence of `%s'", | 2336 dst->unit_decl->name, unit->name); |
2332 dst->unit_decl->name, unit->name); | |
2333 } | 2337 } |
2334 if (no_error_flag) | 2338 if (no_error_flag) |
2335 { | 2339 { |
2336 for (prev_el = (presence_p | 2340 for (prev_el = (presence_p |
2337 ? (final_p | 2341 ? (final_p |
2365 } | 2369 } |
2366 } | 2370 } |
2367 } | 2371 } |
2368 | 2372 |
2369 | 2373 |
2370 /* The function searches for bypass with given IN_INSN_RESERV in given | 2374 /* The function inserts BYPASS in the list of bypasses of the |
2371 BYPASS_LIST. */ | 2375 corresponding output insn. The order of bypasses in the list is |
2372 static struct bypass_decl * | 2376 decribed in a comment for member `bypass_list' (see above). If |
2373 find_bypass (struct bypass_decl *bypass_list, | 2377 there is already the same bypass in the list the function reports |
2374 struct insn_reserv_decl *in_insn_reserv) | 2378 this and does nothing. */ |
2375 { | 2379 static void |
2376 struct bypass_decl *bypass; | 2380 insert_bypass (struct bypass_decl *bypass) |
2377 | 2381 { |
2378 for (bypass = bypass_list; bypass != NULL; bypass = bypass->next) | 2382 struct bypass_decl *curr, *last; |
2379 if (bypass->in_insn_reserv == in_insn_reserv) | 2383 struct insn_reserv_decl *out_insn_reserv = bypass->out_insn_reserv; |
2380 break; | 2384 struct insn_reserv_decl *in_insn_reserv = bypass->in_insn_reserv; |
2381 return bypass; | 2385 |
2386 for (curr = out_insn_reserv->bypass_list, last = NULL; | |
2387 curr != NULL; | |
2388 last = curr, curr = curr->next) | |
2389 if (curr->in_insn_reserv == in_insn_reserv) | |
2390 { | |
2391 if ((bypass->bypass_guard_name != NULL | |
2392 && curr->bypass_guard_name != NULL | |
2393 && ! strcmp (bypass->bypass_guard_name, curr->bypass_guard_name)) | |
2394 || bypass->bypass_guard_name == curr->bypass_guard_name) | |
2395 { | |
2396 if (bypass->bypass_guard_name == NULL) | |
2397 { | |
2398 if (!w_flag) | |
2399 error ("the same bypass `%s - %s' is already defined", | |
2400 bypass->out_insn_name, bypass->in_insn_name); | |
2401 else | |
2402 warning ("the same bypass `%s - %s' is already defined", | |
2403 bypass->out_insn_name, bypass->in_insn_name); | |
2404 } | |
2405 else if (!w_flag) | |
2406 error ("the same bypass `%s - %s' (guard %s) is already defined", | |
2407 bypass->out_insn_name, bypass->in_insn_name, | |
2408 bypass->bypass_guard_name); | |
2409 else | |
2410 warning | |
2411 ("the same bypass `%s - %s' (guard %s) is already defined", | |
2412 bypass->out_insn_name, bypass->in_insn_name, | |
2413 bypass->bypass_guard_name); | |
2414 return; | |
2415 } | |
2416 if (curr->bypass_guard_name == NULL) | |
2417 break; | |
2418 if (curr->next == NULL || curr->next->in_insn_reserv != in_insn_reserv) | |
2419 { | |
2420 last = curr; | |
2421 break; | |
2422 } | |
2423 | |
2424 } | |
2425 if (last == NULL) | |
2426 { | |
2427 bypass->next = out_insn_reserv->bypass_list; | |
2428 out_insn_reserv->bypass_list = bypass; | |
2429 } | |
2430 else | |
2431 { | |
2432 bypass->next = last->next; | |
2433 last->next = bypass; | |
2434 } | |
2382 } | 2435 } |
2383 | 2436 |
2384 /* The function processes pipeline description declarations, checks | 2437 /* The function processes pipeline description declarations, checks |
2385 their correctness, and forms exclusion/presence/absence sets. */ | 2438 their correctness, and forms exclusion/presence/absence sets. */ |
2386 static void | 2439 static void |
2389 decl_t decl; | 2442 decl_t decl; |
2390 decl_t automaton_decl; | 2443 decl_t automaton_decl; |
2391 decl_t decl_in_table; | 2444 decl_t decl_in_table; |
2392 decl_t out_insn_reserv; | 2445 decl_t out_insn_reserv; |
2393 decl_t in_insn_reserv; | 2446 decl_t in_insn_reserv; |
2394 struct bypass_decl *bypass; | |
2395 int automaton_presence; | 2447 int automaton_presence; |
2396 int i; | 2448 int i; |
2397 | 2449 |
2398 /* Checking repeated automata declarations. */ | 2450 /* Checking repeated automata declarations. */ |
2399 automaton_presence = 0; | 2451 automaton_presence = 0; |
2408 { | 2460 { |
2409 if (!w_flag) | 2461 if (!w_flag) |
2410 error ("repeated declaration of automaton `%s'", | 2462 error ("repeated declaration of automaton `%s'", |
2411 DECL_AUTOMATON (decl)->name); | 2463 DECL_AUTOMATON (decl)->name); |
2412 else | 2464 else |
2413 warning (0, "repeated declaration of automaton `%s'", | 2465 warning ("repeated declaration of automaton `%s'", |
2414 DECL_AUTOMATON (decl)->name); | 2466 DECL_AUTOMATON (decl)->name); |
2415 } | 2467 } |
2416 } | 2468 } |
2417 } | 2469 } |
2418 /* Checking undeclared automata, repeated declarations (except for | 2470 /* Checking undeclared automata, repeated declarations (except for |
2512 { | 2564 { |
2513 DECL_BYPASS (decl)->out_insn_reserv | 2565 DECL_BYPASS (decl)->out_insn_reserv |
2514 = DECL_INSN_RESERV (out_insn_reserv); | 2566 = DECL_INSN_RESERV (out_insn_reserv); |
2515 DECL_BYPASS (decl)->in_insn_reserv | 2567 DECL_BYPASS (decl)->in_insn_reserv |
2516 = DECL_INSN_RESERV (in_insn_reserv); | 2568 = DECL_INSN_RESERV (in_insn_reserv); |
2517 bypass | 2569 insert_bypass (DECL_BYPASS (decl)); |
2518 = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list, | |
2519 DECL_BYPASS (decl)->in_insn_reserv); | |
2520 if (bypass != NULL) | |
2521 { | |
2522 if (DECL_BYPASS (decl)->latency == bypass->latency) | |
2523 { | |
2524 if (!w_flag) | |
2525 error | |
2526 ("the same bypass `%s - %s' is already defined", | |
2527 DECL_BYPASS (decl)->out_insn_name, | |
2528 DECL_BYPASS (decl)->in_insn_name); | |
2529 else | |
2530 warning | |
2531 (0, "the same bypass `%s - %s' is already defined", | |
2532 DECL_BYPASS (decl)->out_insn_name, | |
2533 DECL_BYPASS (decl)->in_insn_name); | |
2534 } | |
2535 else | |
2536 error ("bypass `%s - %s' is already defined", | |
2537 DECL_BYPASS (decl)->out_insn_name, | |
2538 DECL_BYPASS (decl)->in_insn_name); | |
2539 } | |
2540 else | |
2541 { | |
2542 DECL_BYPASS (decl)->next | |
2543 = DECL_INSN_RESERV (out_insn_reserv)->bypass_list; | |
2544 DECL_INSN_RESERV (out_insn_reserv)->bypass_list | |
2545 = DECL_BYPASS (decl); | |
2546 } | |
2547 } | 2570 } |
2548 } | 2571 } |
2549 } | 2572 } |
2550 | 2573 |
2551 /* Check exclusion set declarations and form exclusion sets. */ | 2574 /* Check exclusion set declarations and form exclusion sets. */ |
2636 && !DECL_AUTOMATON (decl)->automaton_is_used) | 2659 && !DECL_AUTOMATON (decl)->automaton_is_used) |
2637 { | 2660 { |
2638 if (!w_flag) | 2661 if (!w_flag) |
2639 error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name); | 2662 error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name); |
2640 else | 2663 else |
2641 warning (0, "automaton `%s' is not used", | 2664 warning ("automaton `%s' is not used", |
2642 DECL_AUTOMATON (decl)->name); | 2665 DECL_AUTOMATON (decl)->name); |
2643 } | 2666 } |
2644 } | 2667 } |
2645 } | 2668 } |
2646 | 2669 |
2750 if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used) | 2773 if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used) |
2751 { | 2774 { |
2752 if (!w_flag) | 2775 if (!w_flag) |
2753 error ("unit `%s' is not used", DECL_UNIT (decl)->name); | 2776 error ("unit `%s' is not used", DECL_UNIT (decl)->name); |
2754 else | 2777 else |
2755 warning (0, "unit `%s' is not used", DECL_UNIT (decl)->name); | 2778 warning ("unit `%s' is not used", DECL_UNIT (decl)->name); |
2756 } | 2779 } |
2757 else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used) | 2780 else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used) |
2758 { | 2781 { |
2759 if (!w_flag) | 2782 if (!w_flag) |
2760 error ("reservation `%s' is not used", DECL_RESERV (decl)->name); | 2783 error ("reservation `%s' is not used", DECL_RESERV (decl)->name); |
2761 else | 2784 else |
2762 warning (0, "reservation `%s' is not used", DECL_RESERV (decl)->name); | 2785 warning ("reservation `%s' is not used", DECL_RESERV (decl)->name); |
2763 } | 2786 } |
2764 } | 2787 } |
2765 } | 2788 } |
2766 | 2789 |
2767 /* The following variable value is number of reservation being | 2790 /* The following variable value is number of reservation being |
2911 | 2934 |
2912 case rm_allof: | 2935 case rm_allof: |
2913 { | 2936 { |
2914 int max_cycle = 0; | 2937 int max_cycle = 0; |
2915 int min_cycle = 0; | 2938 int min_cycle = 0; |
2916 | 2939 |
2917 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) | 2940 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) |
2918 { | 2941 { |
2919 process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i], | 2942 process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i], |
2920 max_start_cycle, min_start_cycle, | 2943 max_start_cycle, min_start_cycle, |
2921 max_finish_cycle, min_finish_cycle); | 2944 max_finish_cycle, min_finish_cycle); |
2931 | 2954 |
2932 case rm_oneof: | 2955 case rm_oneof: |
2933 { | 2956 { |
2934 int max_cycle = 0; | 2957 int max_cycle = 0; |
2935 int min_cycle = 0; | 2958 int min_cycle = 0; |
2936 | 2959 |
2937 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++) | 2960 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++) |
2938 { | 2961 { |
2939 process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i], | 2962 process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i], |
2940 max_start_cycle, min_start_cycle, | 2963 max_start_cycle, min_start_cycle, |
2941 max_finish_cycle, min_finish_cycle); | 2964 max_finish_cycle, min_finish_cycle); |
3211 | 3234 |
3212 static alt_state_t | 3235 static alt_state_t |
3213 uniq_sort_alt_states (alt_state_t alt_states_list) | 3236 uniq_sort_alt_states (alt_state_t alt_states_list) |
3214 { | 3237 { |
3215 alt_state_t curr_alt_state; | 3238 alt_state_t curr_alt_state; |
3216 VEC(alt_state_t,heap) *alt_states; | 3239 VEC(alt_state_t, heap) *alt_states; |
3217 size_t i; | 3240 size_t i; |
3218 size_t prev_unique_state_ind; | 3241 size_t prev_unique_state_ind; |
3219 alt_state_t result; | 3242 alt_state_t result; |
3220 | 3243 |
3221 if (alt_states_list == 0) | 3244 if (alt_states_list == 0) |
3222 return 0; | 3245 return 0; |
3223 if (alt_states_list->next_alt_state == 0) | 3246 if (alt_states_list->next_alt_state == 0) |
3224 return alt_states_list; | 3247 return alt_states_list; |
3225 | 3248 |
3226 alt_states = VEC_alloc (alt_state_t,heap, 150); | 3249 alt_states = VEC_alloc (alt_state_t, heap, 150); |
3227 for (curr_alt_state = alt_states_list; | 3250 for (curr_alt_state = alt_states_list; |
3228 curr_alt_state != NULL; | 3251 curr_alt_state != NULL; |
3229 curr_alt_state = curr_alt_state->next_alt_state) | 3252 curr_alt_state = curr_alt_state->next_alt_state) |
3230 VEC_safe_push (alt_state_t,heap, alt_states, curr_alt_state); | 3253 VEC_safe_push (alt_state_t, heap, alt_states, curr_alt_state); |
3231 | 3254 |
3232 qsort (VEC_address (alt_state_t, alt_states), | 3255 qsort (VEC_address (alt_state_t, alt_states), |
3233 VEC_length (alt_state_t, alt_states), | 3256 VEC_length (alt_state_t, alt_states), |
3234 sizeof (alt_state_t), alt_state_cmp); | 3257 sizeof (alt_state_t), alt_state_cmp); |
3235 | 3258 |
3249 = VEC_index (alt_state_t, alt_states, i); | 3272 = VEC_index (alt_state_t, alt_states, i); |
3250 VEC_last (alt_state_t, alt_states)->next_sorted_alt_state = 0; | 3273 VEC_last (alt_state_t, alt_states)->next_sorted_alt_state = 0; |
3251 | 3274 |
3252 result = VEC_index (alt_state_t, alt_states, 0); | 3275 result = VEC_index (alt_state_t, alt_states, 0); |
3253 | 3276 |
3254 VEC_free (alt_state_t,heap, alt_states); | 3277 VEC_free (alt_state_t, heap, alt_states); |
3255 return result; | 3278 return result; |
3256 } | 3279 } |
3257 | 3280 |
3258 /* The function checks equality of alt state lists. Remember that the | 3281 /* The function checks equality of alt state lists. Remember that the |
3259 lists must be already sorted by the previous function. */ | 3282 lists must be already sorted by the previous function. */ |
3720 static state_t | 3743 static state_t |
3721 insert_state (state_t state) | 3744 insert_state (state_t state) |
3722 { | 3745 { |
3723 void **entry_ptr; | 3746 void **entry_ptr; |
3724 | 3747 |
3725 entry_ptr = htab_find_slot (state_table, (void *) state, 1); | 3748 entry_ptr = htab_find_slot (state_table, (void *) state, INSERT); |
3726 if (*entry_ptr == NULL) | 3749 if (*entry_ptr == NULL) |
3727 *entry_ptr = (void *) state; | 3750 *entry_ptr = (void *) state; |
3728 return (state_t) *entry_ptr; | 3751 return (state_t) *entry_ptr; |
3729 } | 3752 } |
3730 | 3753 |
4076 void **entry_ptr; | 4099 void **entry_ptr; |
4077 | 4100 |
4078 if (current_automata_list == NULL) | 4101 if (current_automata_list == NULL) |
4079 return NULL; | 4102 return NULL; |
4080 entry_ptr = htab_find_slot (automata_list_table, | 4103 entry_ptr = htab_find_slot (automata_list_table, |
4081 (void *) current_automata_list, 1); | 4104 (void *) current_automata_list, INSERT); |
4082 if (*entry_ptr == NULL) | 4105 if (*entry_ptr == NULL) |
4083 *entry_ptr = (void *) current_automata_list; | 4106 *entry_ptr = (void *) current_automata_list; |
4084 else | 4107 else |
4085 free_automata_list (current_automata_list); | 4108 free_automata_list (current_automata_list); |
4086 current_automata_list = NULL; | 4109 current_automata_list = NULL; |
4754 } | 4777 } |
4755 break; | 4778 break; |
4756 default: | 4779 default: |
4757 break; | 4780 break; |
4758 } | 4781 } |
4759 | 4782 |
4760 if (allof_length == 1) | 4783 if (allof_length == 1) |
4761 REGEXP_SEQUENCE (result)->regexps [i] = allof_op; | 4784 REGEXP_SEQUENCE (result)->regexps [i] = allof_op; |
4762 else | 4785 else |
4763 { | 4786 { |
4764 allof = XCREATENODEVAR (struct regexp, sizeof (struct regexp) | 4787 allof = XCREATENODEVAR (struct regexp, sizeof (struct regexp) |
4890 | 4913 |
4891 /* The following variable value is TRUE if the first annotated message | 4914 /* The following variable value is TRUE if the first annotated message |
4892 about units to automata distribution has been output. */ | 4915 about units to automata distribution has been output. */ |
4893 static int annotation_message_reported_p; | 4916 static int annotation_message_reported_p; |
4894 | 4917 |
4918 /* The vector contains all decls which are automata. */ | |
4919 static VEC(decl_t, heap) *automaton_decls; | |
4920 | |
4895 /* The following structure describes usage of a unit in a reservation. */ | 4921 /* The following structure describes usage of a unit in a reservation. */ |
4896 struct unit_usage | 4922 struct unit_usage |
4897 { | 4923 { |
4898 unit_decl_t unit_decl; | 4924 unit_decl_t unit_decl; |
4899 /* The following forms a list of units used on the same cycle in the | 4925 /* The following forms a list of units used on the same cycle in the |
4900 same alternative. */ | 4926 same alternative. The list is ordered by the correspdoning unit |
4927 declarations and there is no unit declaration duplication in the | |
4928 list. */ | |
4901 struct unit_usage *next; | 4929 struct unit_usage *next; |
4902 }; | 4930 }; |
4903 typedef struct unit_usage *unit_usage_t; | 4931 typedef struct unit_usage *unit_usage_t; |
4904 | 4932 |
4905 DEF_VEC_P(unit_usage_t); | 4933 DEF_VEC_P(unit_usage_t); |
4906 DEF_VEC_ALLOC_P(unit_usage_t,heap); | 4934 DEF_VEC_ALLOC_P(unit_usage_t, heap); |
4907 | 4935 |
4908 /* Obstack for unit_usage structures. */ | 4936 /* Obstack for unit_usage structures. */ |
4909 static struct obstack unit_usages; | 4937 static struct obstack unit_usages; |
4910 | 4938 |
4911 /* VLA for representation of array of pointers to unit usage | 4939 /* VLA for representation of array of pointers to unit usage |
4912 structures. There is an element for each combination of | 4940 structures. There is an element for each combination of |
4913 (alternative number, cycle). Unit usages on given cycle in | 4941 (alternative number, cycle). Unit usages on given cycle in |
4914 alternative with given number are referred through element with | 4942 alternative with given number are referred through element with |
4915 index equals to the cycle * number of all alternatives in the regexp | 4943 index equals to the cycle * number of all alternatives in the |
4916 + the alternative number. */ | 4944 regexp + the alternative number. */ |
4917 static VEC(unit_usage_t,heap) *cycle_alt_unit_usages; | 4945 static VEC(unit_usage_t, heap) *cycle_alt_unit_usages; |
4918 | 4946 |
4919 /* The following function creates the structure unit_usage for UNIT on | 4947 /* The following function creates the structure unit_usage for UNIT on |
4920 CYCLE in REGEXP alternative with ALT_NUM. The structure is made | 4948 CYCLE in REGEXP alternative with ALT_NUM. The structure is made |
4921 accessed through cycle_alt_unit_usages. */ | 4949 accessed through cycle_alt_unit_usages. */ |
4922 static void | 4950 static void |
4923 store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle, | 4951 store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle, |
4924 int alt_num) | 4952 int alt_num) |
4925 { | 4953 { |
4926 size_t length; | 4954 size_t length; |
4927 unit_decl_t unit_decl; | 4955 unit_decl_t unit_decl; |
4928 unit_usage_t unit_usage_ptr; | 4956 unit_usage_t unit_usage_ptr, curr, prev; |
4929 int index; | 4957 int index; |
4930 | 4958 |
4931 gcc_assert (regexp && regexp->mode == rm_oneof | 4959 gcc_assert (regexp && regexp->mode == rm_oneof |
4932 && alt_num < REGEXP_ONEOF (regexp)->regexps_num); | 4960 && alt_num < REGEXP_ONEOF (regexp)->regexps_num); |
4933 unit_decl = REGEXP_UNIT (unit)->unit_decl; | 4961 unit_decl = REGEXP_UNIT (unit)->unit_decl; |
4934 | 4962 |
4935 length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num; | 4963 length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num; |
4936 while (VEC_length (unit_usage_t, cycle_alt_unit_usages) < length) | 4964 while (VEC_length (unit_usage_t, cycle_alt_unit_usages) < length) |
4937 VEC_safe_push (unit_usage_t,heap, cycle_alt_unit_usages, 0); | 4965 VEC_safe_push (unit_usage_t, heap, cycle_alt_unit_usages, 0); |
4938 | 4966 |
4967 index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num; | |
4968 prev = NULL; | |
4969 for (curr = VEC_index (unit_usage_t, cycle_alt_unit_usages, index); | |
4970 curr != NULL; | |
4971 prev = curr, curr = curr->next) | |
4972 if (curr->unit_decl >= unit_decl) | |
4973 break; | |
4974 if (curr != NULL && curr->unit_decl == unit_decl) | |
4975 return; | |
4939 obstack_blank (&unit_usages, sizeof (struct unit_usage)); | 4976 obstack_blank (&unit_usages, sizeof (struct unit_usage)); |
4940 unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages); | 4977 unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages); |
4941 obstack_finish (&unit_usages); | 4978 obstack_finish (&unit_usages); |
4942 unit_usage_ptr->unit_decl = unit_decl; | 4979 unit_usage_ptr->unit_decl = unit_decl; |
4943 index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num; | |
4944 unit_usage_ptr->next = VEC_index (unit_usage_t, cycle_alt_unit_usages, index); | |
4945 VEC_replace (unit_usage_t, cycle_alt_unit_usages, index, unit_usage_ptr); | |
4946 unit_decl->last_distribution_check_cycle = -1; /* undefined */ | 4980 unit_decl->last_distribution_check_cycle = -1; /* undefined */ |
4947 } | 4981 unit_usage_ptr->next = curr; |
4982 if (prev == NULL) | |
4983 VEC_replace (unit_usage_t, cycle_alt_unit_usages, index, unit_usage_ptr); | |
4984 else | |
4985 prev->next = unit_usage_ptr; | |
4986 } | |
4987 | |
4988 /* Return true if unit UNIT_DECL is present on the LIST. */ | |
4989 static bool | |
4990 unit_present_on_list_p (unit_usage_t list, unit_decl_t unit_decl) | |
4991 { | |
4992 while (list != NULL) | |
4993 { | |
4994 if (list->unit_decl == unit_decl) | |
4995 return true; | |
4996 list = list->next; | |
4997 } | |
4998 return false; | |
4999 } | |
5000 | |
5001 /* The function returns true if reservations of alternatives ALT1 and | |
5002 ALT2 are equal after excluding reservations of units of | |
5003 EXCLUDED_AUTOMATON_DECL. */ | |
5004 static bool | |
5005 equal_alternatives_p (int alt1, int alt2, int n_alts, | |
5006 struct automaton_decl *excluded_automaton_decl) | |
5007 { | |
5008 int i; | |
5009 unit_usage_t list1, list2; | |
5010 | |
5011 for (i = 0; | |
5012 i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); | |
5013 i += n_alts) | |
5014 { | |
5015 for (list1 = VEC_index (unit_usage_t, cycle_alt_unit_usages, i + alt1), | |
5016 list2 = VEC_index (unit_usage_t, cycle_alt_unit_usages, i + alt2);; | |
5017 list1 = list1->next, list2 = list2->next) | |
5018 { | |
5019 while (list1 != NULL | |
5020 && list1->unit_decl->automaton_decl == excluded_automaton_decl) | |
5021 list1 = list1->next; | |
5022 while (list2 != NULL | |
5023 && list2->unit_decl->automaton_decl == excluded_automaton_decl) | |
5024 list2 = list2->next; | |
5025 if (list1 == NULL || list2 == NULL) | |
5026 { | |
5027 if (list1 != list2) | |
5028 return false; | |
5029 else | |
5030 break; | |
5031 } | |
5032 if (list1->unit_decl != list2->unit_decl) | |
5033 return false; | |
5034 } | |
5035 } | |
5036 return true; | |
5037 } | |
5038 | |
5039 DEF_VEC_I(int); | |
5040 DEF_VEC_ALLOC_I(int, heap); | |
4948 | 5041 |
4949 /* The function processes given REGEXP to find units with the wrong | 5042 /* The function processes given REGEXP to find units with the wrong |
4950 distribution. */ | 5043 distribution. */ |
4951 static void | 5044 static void |
4952 check_regexp_units_distribution (const char *insn_reserv_name, | 5045 check_regexp_units_distribution (const char *insn_reserv_name, |
4953 regexp_t regexp) | 5046 regexp_t regexp) |
4954 { | 5047 { |
4955 int i, j, k, cycle; | 5048 int i, j, k, cycle, start, n_alts, alt, alt2; |
5049 bool annotation_reservation_message_reported_p; | |
4956 regexp_t seq, allof, unit; | 5050 regexp_t seq, allof, unit; |
4957 struct unit_usage *unit_usage_ptr, *other_unit_usage_ptr; | 5051 struct unit_usage *unit_usage_ptr; |
5052 VEC(int, heap) *marked; | |
4958 | 5053 |
4959 if (regexp == NULL || regexp->mode != rm_oneof) | 5054 if (regexp == NULL || regexp->mode != rm_oneof) |
4960 return; | 5055 return; |
4961 /* Store all unit usages in the regexp: */ | 5056 /* Store all unit usages in the regexp: */ |
4962 obstack_init (&unit_usages); | 5057 obstack_init (&unit_usages); |
4963 cycle_alt_unit_usages = 0; | 5058 cycle_alt_unit_usages = VEC_alloc (unit_usage_t, heap, 10); |
4964 | 5059 |
4965 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--) | 5060 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--) |
4966 { | 5061 { |
4967 seq = REGEXP_ONEOF (regexp)->regexps [i]; | 5062 seq = REGEXP_ONEOF (regexp)->regexps [i]; |
4968 switch (seq->mode) | 5063 switch (seq->mode) |
4981 store_alt_unit_usage (regexp, unit, j, i); | 5076 store_alt_unit_usage (regexp, unit, j, i); |
4982 else | 5077 else |
4983 gcc_assert (unit->mode == rm_nothing); | 5078 gcc_assert (unit->mode == rm_nothing); |
4984 } | 5079 } |
4985 break; | 5080 break; |
4986 | 5081 |
4987 case rm_unit: | 5082 case rm_unit: |
4988 store_alt_unit_usage (regexp, allof, j, i); | 5083 store_alt_unit_usage (regexp, allof, j, i); |
4989 break; | 5084 break; |
4990 | 5085 |
4991 case rm_nothing: | 5086 case rm_nothing: |
4992 break; | 5087 break; |
4993 | 5088 |
4994 default: | 5089 default: |
4995 gcc_unreachable (); | 5090 gcc_unreachable (); |
4996 } | 5091 } |
4997 } | 5092 } |
4998 break; | 5093 break; |
5004 switch (unit->mode) | 5099 switch (unit->mode) |
5005 { | 5100 { |
5006 case rm_unit: | 5101 case rm_unit: |
5007 store_alt_unit_usage (regexp, unit, 0, i); | 5102 store_alt_unit_usage (regexp, unit, 0, i); |
5008 break; | 5103 break; |
5009 | 5104 |
5010 case rm_nothing: | 5105 case rm_nothing: |
5011 break; | 5106 break; |
5012 | 5107 |
5013 default: | 5108 default: |
5014 gcc_unreachable (); | 5109 gcc_unreachable (); |
5015 } | 5110 } |
5016 } | 5111 } |
5017 break; | 5112 break; |
5027 gcc_unreachable (); | 5122 gcc_unreachable (); |
5028 } | 5123 } |
5029 } | 5124 } |
5030 /* Check distribution: */ | 5125 /* Check distribution: */ |
5031 for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++) | 5126 for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++) |
5032 { | 5127 for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i); |
5033 cycle = i / REGEXP_ONEOF (regexp)->regexps_num; | 5128 unit_usage_ptr != NULL; |
5129 unit_usage_ptr = unit_usage_ptr->next) | |
5130 unit_usage_ptr->unit_decl->last_distribution_check_cycle = -1; | |
5131 n_alts = REGEXP_ONEOF (regexp)->regexps_num; | |
5132 marked = VEC_alloc (int, heap, n_alts); | |
5133 for (i = 0; i < n_alts; i++) | |
5134 VEC_safe_push (int, heap, marked, 0); | |
5135 annotation_reservation_message_reported_p = false; | |
5136 for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++) | |
5137 { | |
5138 cycle = i / n_alts; | |
5139 start = cycle * n_alts; | |
5034 for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i); | 5140 for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i); |
5035 unit_usage_ptr != NULL; | 5141 unit_usage_ptr != NULL; |
5036 unit_usage_ptr = unit_usage_ptr->next) | 5142 unit_usage_ptr = unit_usage_ptr->next) |
5037 if (cycle != unit_usage_ptr->unit_decl->last_distribution_check_cycle) | 5143 { |
5038 { | 5144 if (unit_usage_ptr->unit_decl->last_distribution_check_cycle == cycle) |
5039 unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle; | 5145 continue; |
5040 for (k = cycle * REGEXP_ONEOF (regexp)->regexps_num; | 5146 unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle; |
5041 k < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages) | 5147 for (alt = 0; alt < n_alts; alt++) |
5042 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num; | 5148 if (! unit_present_on_list_p (VEC_index (unit_usage_t, |
5043 k++) | 5149 cycle_alt_unit_usages, |
5044 { | 5150 start + alt), |
5045 for (other_unit_usage_ptr | 5151 unit_usage_ptr->unit_decl)) |
5046 = VEC_index (unit_usage_t, cycle_alt_unit_usages, k); | 5152 break; |
5047 other_unit_usage_ptr != NULL; | 5153 if (alt >= n_alts) |
5048 other_unit_usage_ptr = other_unit_usage_ptr->next) | 5154 continue; |
5049 if (unit_usage_ptr->unit_decl->automaton_decl | 5155 memset (VEC_address (int, marked), 0, n_alts * sizeof (int)); |
5050 == other_unit_usage_ptr->unit_decl->automaton_decl) | 5156 for (alt = 0; alt < n_alts; alt++) |
5051 break; | 5157 { |
5052 if (other_unit_usage_ptr == NULL | 5158 if (! unit_present_on_list_p (VEC_index (unit_usage_t, |
5053 && (VEC_index (unit_usage_t, cycle_alt_unit_usages, k) | 5159 cycle_alt_unit_usages, |
5054 != NULL)) | 5160 start + alt), |
5055 break; | 5161 unit_usage_ptr->unit_decl)) |
5056 } | 5162 continue; |
5057 if (k < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages) | 5163 for (j = 0; |
5058 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num) | 5164 j < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); |
5059 { | 5165 j++) |
5060 if (!annotation_message_reported_p) | 5166 { |
5061 { | 5167 alt2 = j % n_alts; |
5062 fprintf (stderr, "\n"); | 5168 if (! unit_present_on_list_p |
5063 error ("The following units do not satisfy units-automata distribution rule"); | 5169 (VEC_index (unit_usage_t, cycle_alt_unit_usages, |
5064 error (" (A unit of given unit automaton should be on each reserv. altern.)"); | 5170 start + alt2), |
5065 annotation_message_reported_p = TRUE; | 5171 unit_usage_ptr->unit_decl) |
5066 } | 5172 && equal_alternatives_p (alt, alt2, n_alts, |
5067 error ("Unit %s, reserv. %s, cycle %d", | 5173 unit_usage_ptr |
5068 unit_usage_ptr->unit_decl->name, insn_reserv_name, | 5174 ->unit_decl->automaton_decl)) |
5069 cycle); | 5175 { |
5070 } | 5176 VEC_replace (int, marked, alt, 1); |
5071 } | 5177 VEC_replace (int, marked, alt2, 1); |
5072 } | 5178 } |
5073 VEC_free (unit_usage_t,heap, cycle_alt_unit_usages); | 5179 } |
5180 } | |
5181 for (alt = 0; alt < n_alts && VEC_index (int, marked, alt); alt++) | |
5182 ; | |
5183 if (alt < n_alts && 0) | |
5184 { | |
5185 if (! annotation_message_reported_p) | |
5186 { | |
5187 fprintf (stderr, "\n"); | |
5188 error ("The following units do not satisfy units-automata distribution rule"); | |
5189 error ("(Unit presence on one alt and its absence on other alt\n"); | |
5190 error (" result in different other automata reservations)"); | |
5191 annotation_message_reported_p = TRUE; | |
5192 } | |
5193 if (! annotation_reservation_message_reported_p) | |
5194 { | |
5195 error ("Reserv %s:", insn_reserv_name); | |
5196 annotation_reservation_message_reported_p = true; | |
5197 } | |
5198 error (" Unit %s, cycle %d, alt %d, another alt %d", | |
5199 unit_usage_ptr->unit_decl->name, cycle, i % n_alts, alt); | |
5200 } | |
5201 } | |
5202 } | |
5203 VEC_free (int, heap, marked); | |
5204 VEC_free (unit_usage_t, heap, cycle_alt_unit_usages); | |
5074 obstack_free (&unit_usages, NULL); | 5205 obstack_free (&unit_usages, NULL); |
5075 } | 5206 } |
5076 | 5207 |
5077 /* The function finds units which violates units to automata | 5208 /* The function finds units which violates units to automata |
5078 distribution rule. If the units exist, report about them. */ | 5209 distribution rule. If the units exist, report about them. */ |
5082 decl_t decl; | 5213 decl_t decl; |
5083 int i; | 5214 int i; |
5084 | 5215 |
5085 if (progress_flag) | 5216 if (progress_flag) |
5086 fprintf (stderr, "Check unit distributions to automata..."); | 5217 fprintf (stderr, "Check unit distributions to automata..."); |
5087 annotation_message_reported_p = FALSE; | 5218 automaton_decls = NULL; |
5088 for (i = 0; i < description->decls_num; i++) | 5219 for (i = 0; i < description->decls_num; i++) |
5089 { | 5220 { |
5090 decl = description->decls [i]; | 5221 decl = description->decls [i]; |
5091 if (decl->mode == dm_insn_reserv) | 5222 if (decl->mode == dm_automaton) |
5092 check_regexp_units_distribution | 5223 VEC_safe_push (decl_t, heap, automaton_decls, decl); |
5093 (DECL_INSN_RESERV (decl)->name, | 5224 } |
5094 DECL_INSN_RESERV (decl)->transformed_regexp); | 5225 if (VEC_length (decl_t, automaton_decls) > 1) |
5095 } | 5226 { |
5227 annotation_message_reported_p = FALSE; | |
5228 for (i = 0; i < description->decls_num; i++) | |
5229 { | |
5230 decl = description->decls [i]; | |
5231 if (decl->mode == dm_insn_reserv) | |
5232 check_regexp_units_distribution | |
5233 (DECL_INSN_RESERV (decl)->name, | |
5234 DECL_INSN_RESERV (decl)->transformed_regexp); | |
5235 } | |
5236 } | |
5237 VEC_free (decl_t, heap, automaton_decls); | |
5096 if (progress_flag) | 5238 if (progress_flag) |
5097 fprintf (stderr, "done\n"); | 5239 fprintf (stderr, "done\n"); |
5098 } | 5240 } |
5099 | 5241 |
5100 | 5242 |
5127 if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num | 5269 if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num |
5128 == automaton->automaton_order_num) | 5270 == automaton->automaton_order_num) |
5129 set_state_reserv (state_being_formed, curr_cycle, | 5271 set_state_reserv (state_being_formed, curr_cycle, |
5130 REGEXP_UNIT (regexp)->unit_decl->unit_num); | 5272 REGEXP_UNIT (regexp)->unit_decl->unit_num); |
5131 return curr_cycle; | 5273 return curr_cycle; |
5132 | 5274 |
5133 case rm_sequence: | 5275 case rm_sequence: |
5134 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++) | 5276 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++) |
5135 curr_cycle | 5277 curr_cycle |
5136 = process_seq_for_forming_states | 5278 = process_seq_for_forming_states |
5137 (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1; | 5279 (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1; |
5139 | 5281 |
5140 case rm_allof: | 5282 case rm_allof: |
5141 { | 5283 { |
5142 int finish_cycle = 0; | 5284 int finish_cycle = 0; |
5143 int cycle; | 5285 int cycle; |
5144 | 5286 |
5145 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) | 5287 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) |
5146 { | 5288 { |
5147 cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp) | 5289 cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp) |
5148 ->regexps [i], | 5290 ->regexps [i], |
5149 automaton, curr_cycle); | 5291 automaton, curr_cycle); |
5250 static void | 5392 static void |
5251 form_ainsn_with_same_reservs (automaton_t automaton) | 5393 form_ainsn_with_same_reservs (automaton_t automaton) |
5252 { | 5394 { |
5253 ainsn_t curr_ainsn; | 5395 ainsn_t curr_ainsn; |
5254 size_t i; | 5396 size_t i; |
5255 VEC(ainsn_t,heap) *last_insns = VEC_alloc (ainsn_t,heap, 150); | 5397 VEC(ainsn_t, heap) *last_insns = VEC_alloc (ainsn_t, heap, 150); |
5256 | 5398 |
5257 for (curr_ainsn = automaton->ainsn_list; | 5399 for (curr_ainsn = automaton->ainsn_list; |
5258 curr_ainsn != NULL; | 5400 curr_ainsn != NULL; |
5259 curr_ainsn = curr_ainsn->next_ainsn) | 5401 curr_ainsn = curr_ainsn->next_ainsn) |
5260 if (curr_ainsn->insn_reserv_decl | 5402 if (curr_ainsn->insn_reserv_decl |
5282 { | 5424 { |
5283 VEC_safe_push (ainsn_t, heap, last_insns, curr_ainsn); | 5425 VEC_safe_push (ainsn_t, heap, last_insns, curr_ainsn); |
5284 curr_ainsn->first_insn_with_same_reservs = 1; | 5426 curr_ainsn->first_insn_with_same_reservs = 1; |
5285 } | 5427 } |
5286 } | 5428 } |
5287 VEC_free (ainsn_t,heap, last_insns); | 5429 VEC_free (ainsn_t, heap, last_insns); |
5288 } | 5430 } |
5289 | 5431 |
5290 /* Forming unit reservations which can affect creating the automaton | 5432 /* Forming unit reservations which can affect creating the automaton |
5291 states achieved from a given state. It permits to build smaller | 5433 states achieved from a given state. It permits to build smaller |
5292 automata in many cases. We would have the same automata after | 5434 automata in many cases. We would have the same automata after |
5326 state_t state; | 5468 state_t state; |
5327 state_t start_state; | 5469 state_t start_state; |
5328 state_t state2; | 5470 state_t state2; |
5329 ainsn_t advance_cycle_ainsn; | 5471 ainsn_t advance_cycle_ainsn; |
5330 arc_t added_arc; | 5472 arc_t added_arc; |
5331 VEC(state_t,heap) *state_stack = VEC_alloc(state_t,heap, 150); | 5473 VEC(state_t, heap) *state_stack = VEC_alloc(state_t, heap, 150); |
5332 int states_n; | 5474 int states_n; |
5333 reserv_sets_t reservs_matter = form_reservs_matter (automaton); | 5475 reserv_sets_t reservs_matter = form_reservs_matter (automaton); |
5334 | 5476 |
5335 /* Create the start state (empty state). */ | 5477 /* Create the start state (empty state). */ |
5336 start_state = insert_state (get_free_state (1, automaton)); | 5478 start_state = insert_state (get_free_state (1, automaton)); |
5337 automaton->start_state = start_state; | 5479 automaton->start_state = start_state; |
5338 start_state->it_was_placed_in_stack_for_NDFA_forming = 1; | 5480 start_state->it_was_placed_in_stack_for_NDFA_forming = 1; |
5339 VEC_safe_push (state_t,heap, state_stack, start_state); | 5481 VEC_safe_push (state_t, heap, state_stack, start_state); |
5340 states_n = 1; | 5482 states_n = 1; |
5341 while (VEC_length (state_t, state_stack) != 0) | 5483 while (VEC_length (state_t, state_stack) != 0) |
5342 { | 5484 { |
5343 state = VEC_pop (state_t, state_stack); | 5485 state = VEC_pop (state_t, state_stack); |
5344 advance_cycle_ainsn = NULL; | 5486 advance_cycle_ainsn = NULL; |
5363 state2 = states_union (state, state2, reservs_matter); | 5505 state2 = states_union (state, state2, reservs_matter); |
5364 if (!state2->it_was_placed_in_stack_for_NDFA_forming) | 5506 if (!state2->it_was_placed_in_stack_for_NDFA_forming) |
5365 { | 5507 { |
5366 state2->it_was_placed_in_stack_for_NDFA_forming | 5508 state2->it_was_placed_in_stack_for_NDFA_forming |
5367 = 1; | 5509 = 1; |
5368 VEC_safe_push (state_t,heap, state_stack, state2); | 5510 VEC_safe_push (state_t, heap, state_stack, state2); |
5369 states_n++; | 5511 states_n++; |
5370 if (progress_flag && states_n % 100 == 0) | 5512 if (progress_flag && states_n % 100 == 0) |
5371 fprintf (stderr, "."); | 5513 fprintf (stderr, "."); |
5372 } | 5514 } |
5373 added_arc = add_arc (state, state2, ainsn); | 5515 added_arc = add_arc (state, state2, ainsn); |
5389 /* Add transition to advance cycle. */ | 5531 /* Add transition to advance cycle. */ |
5390 state2 = state_shift (state, reservs_matter); | 5532 state2 = state_shift (state, reservs_matter); |
5391 if (!state2->it_was_placed_in_stack_for_NDFA_forming) | 5533 if (!state2->it_was_placed_in_stack_for_NDFA_forming) |
5392 { | 5534 { |
5393 state2->it_was_placed_in_stack_for_NDFA_forming = 1; | 5535 state2->it_was_placed_in_stack_for_NDFA_forming = 1; |
5394 VEC_safe_push (state_t,heap, state_stack, state2); | 5536 VEC_safe_push (state_t, heap, state_stack, state2); |
5395 states_n++; | 5537 states_n++; |
5396 if (progress_flag && states_n % 100 == 0) | 5538 if (progress_flag && states_n % 100 == 0) |
5397 fprintf (stderr, "."); | 5539 fprintf (stderr, "."); |
5398 } | 5540 } |
5399 gcc_assert (advance_cycle_ainsn); | 5541 gcc_assert (advance_cycle_ainsn); |
5400 add_arc (state, state2, advance_cycle_ainsn); | 5542 add_arc (state, state2, advance_cycle_ainsn); |
5401 } | 5543 } |
5402 VEC_free (state_t,heap, state_stack); | 5544 VEC_free (state_t, heap, state_stack); |
5403 } | 5545 } |
5404 | 5546 |
5405 /* Form lists of all arcs of STATE marked by the same ainsn. */ | 5547 /* Form lists of all arcs of STATE marked by the same ainsn. */ |
5406 static void | 5548 static void |
5407 form_arcs_marked_by_insn (state_t state) | 5549 form_arcs_marked_by_insn (state_t state) |
5430 same insn. If the composed state is not in STATE_STACK yet, it is | 5572 same insn. If the composed state is not in STATE_STACK yet, it is |
5431 pushed into STATE_STACK. */ | 5573 pushed into STATE_STACK. */ |
5432 | 5574 |
5433 static int | 5575 static int |
5434 create_composed_state (state_t original_state, arc_t arcs_marked_by_insn, | 5576 create_composed_state (state_t original_state, arc_t arcs_marked_by_insn, |
5435 VEC(state_t,heap) **state_stack) | 5577 VEC(state_t, heap) **state_stack) |
5436 { | 5578 { |
5437 state_t state; | 5579 state_t state; |
5438 alt_state_t alt_state, curr_alt_state; | 5580 alt_state_t alt_state, curr_alt_state; |
5439 alt_state_t new_alt_state; | 5581 alt_state_t new_alt_state; |
5440 arc_t curr_arc; | 5582 arc_t curr_arc; |
5520 } | 5662 } |
5521 } | 5663 } |
5522 if (!state->it_was_placed_in_stack_for_DFA_forming) | 5664 if (!state->it_was_placed_in_stack_for_DFA_forming) |
5523 { | 5665 { |
5524 state->it_was_placed_in_stack_for_DFA_forming = 1; | 5666 state->it_was_placed_in_stack_for_DFA_forming = 1; |
5525 VEC_safe_push (state_t,heap, *state_stack, state); | 5667 VEC_safe_push (state_t, heap, *state_stack, state); |
5526 } | 5668 } |
5527 return new_state_p; | 5669 return new_state_p; |
5528 } | 5670 } |
5529 | 5671 |
5530 /* The function transforms nondeterministic AUTOMATON into | 5672 /* The function transforms nondeterministic AUTOMATON into |
5534 NDFA_to_DFA (automaton_t automaton) | 5676 NDFA_to_DFA (automaton_t automaton) |
5535 { | 5677 { |
5536 state_t start_state; | 5678 state_t start_state; |
5537 state_t state; | 5679 state_t state; |
5538 decl_t decl; | 5680 decl_t decl; |
5539 VEC(state_t,heap) *state_stack; | 5681 VEC(state_t, heap) *state_stack; |
5540 int i; | 5682 int i; |
5541 int states_n; | 5683 int states_n; |
5542 | 5684 |
5543 state_stack = VEC_alloc (state_t,heap, 0); | 5685 state_stack = VEC_alloc (state_t, heap, 0); |
5544 | 5686 |
5545 /* Create the start state (empty state). */ | 5687 /* Create the start state (empty state). */ |
5546 start_state = automaton->start_state; | 5688 start_state = automaton->start_state; |
5547 start_state->it_was_placed_in_stack_for_DFA_forming = 1; | 5689 start_state->it_was_placed_in_stack_for_DFA_forming = 1; |
5548 VEC_safe_push (state_t,heap, state_stack, start_state); | 5690 VEC_safe_push (state_t, heap, state_stack, start_state); |
5549 states_n = 1; | 5691 states_n = 1; |
5550 while (VEC_length (state_t, state_stack) != 0) | 5692 while (VEC_length (state_t, state_stack) != 0) |
5551 { | 5693 { |
5552 state = VEC_pop (state_t, state_stack); | 5694 state = VEC_pop (state_t, state_stack); |
5553 form_arcs_marked_by_insn (state); | 5695 form_arcs_marked_by_insn (state); |
5563 if (progress_flag && states_n % 100 == 0) | 5705 if (progress_flag && states_n % 100 == 0) |
5564 fprintf (stderr, "."); | 5706 fprintf (stderr, "."); |
5565 } | 5707 } |
5566 } | 5708 } |
5567 } | 5709 } |
5568 VEC_free (state_t,heap, state_stack); | 5710 VEC_free (state_t, heap, state_stack); |
5569 } | 5711 } |
5570 | 5712 |
5571 /* The following variable value is current number (1, 2, ...) of passing | 5713 /* The following variable value is current number (1, 2, ...) of passing |
5572 graph of states. */ | 5714 graph of states. */ |
5573 static int curr_state_graph_pass_num; | 5715 static int curr_state_graph_pass_num; |
5605 curr_state_graph_pass_num = 0; | 5747 curr_state_graph_pass_num = 0; |
5606 } | 5748 } |
5607 | 5749 |
5608 /* The following vla is used for storing pointers to all achieved | 5750 /* The following vla is used for storing pointers to all achieved |
5609 states. */ | 5751 states. */ |
5610 static VEC(state_t,heap) *all_achieved_states; | 5752 static VEC(state_t, heap) *all_achieved_states; |
5611 | 5753 |
5612 /* This function is called by function pass_states to add an achieved | 5754 /* This function is called by function pass_states to add an achieved |
5613 STATE. */ | 5755 STATE. */ |
5614 static void | 5756 static void |
5615 add_achieved_state (state_t state) | 5757 add_achieved_state (state_t state) |
5616 { | 5758 { |
5617 VEC_safe_push (state_t,heap, all_achieved_states, state); | 5759 VEC_safe_push (state_t, heap, all_achieved_states, state); |
5618 } | 5760 } |
5619 | 5761 |
5620 /* The function sets up equivalence numbers of insns which mark all | 5762 /* The function sets up equivalence numbers of insns which mark all |
5621 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has | 5763 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has |
5622 nonzero value) or by equiv_class_num_2 of the destination state. | 5764 nonzero value) or by equiv_class_num_2 of the destination state. |
5675 { | 5817 { |
5676 int i, num = 0; | 5818 int i, num = 0; |
5677 unsigned int sz; | 5819 unsigned int sz; |
5678 sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1) | 5820 sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1) |
5679 / (sizeof (int) * CHAR_BIT); | 5821 / (sizeof (int) * CHAR_BIT); |
5680 | 5822 |
5681 state->presence_signature = XCREATENODEVEC (unsigned int, sz); | 5823 state->presence_signature = XCREATENODEVEC (unsigned int, sz); |
5682 for (i = 0; i < description->units_num; i++) | 5824 for (i = 0; i < description->units_num; i++) |
5683 if (units_array [i]->query_p) | 5825 if (units_array [i]->query_p) |
5684 { | 5826 { |
5685 int presence1_p = first_cycle_unit_presence (state, i); | 5827 int presence1_p = first_cycle_unit_presence (state, i); |
5751 | 5893 |
5752 /* The function makes initial partition of STATES on equivalent | 5894 /* The function makes initial partition of STATES on equivalent |
5753 classes and saves it into *CLASSES. This function requires the input | 5895 classes and saves it into *CLASSES. This function requires the input |
5754 to be sorted via compare_states_for_equiv(). */ | 5896 to be sorted via compare_states_for_equiv(). */ |
5755 static int | 5897 static int |
5756 init_equiv_class (VEC(state_t,heap) *states, VEC (state_t,heap) **classes) | 5898 init_equiv_class (VEC(state_t, heap) *states, VEC (state_t, heap) **classes) |
5757 { | 5899 { |
5758 size_t i; | 5900 size_t i; |
5759 state_t prev = 0; | 5901 state_t prev = 0; |
5760 int class_num = 1; | 5902 int class_num = 1; |
5761 | 5903 |
5762 *classes = VEC_alloc (state_t,heap, 150); | 5904 *classes = VEC_alloc (state_t, heap, 150); |
5763 for (i = 0; i < VEC_length (state_t, states); i++) | 5905 for (i = 0; i < VEC_length (state_t, states); i++) |
5764 { | 5906 { |
5765 state_t state = VEC_index (state_t, states, i); | 5907 state_t state = VEC_index (state_t, states, i); |
5766 if (prev) | 5908 if (prev) |
5767 { | 5909 { |
5768 if (compare_states_for_equiv (&prev, &state) != 0) | 5910 if (compare_states_for_equiv (&prev, &state) != 0) |
5769 { | 5911 { |
5770 VEC_safe_push (state_t,heap, *classes, prev); | 5912 VEC_safe_push (state_t, heap, *classes, prev); |
5771 class_num++; | 5913 class_num++; |
5772 prev = NULL; | 5914 prev = NULL; |
5773 } | 5915 } |
5774 } | 5916 } |
5775 state->equiv_class_num_1 = class_num; | 5917 state->equiv_class_num_1 = class_num; |
5776 state->next_equiv_class_state = prev; | 5918 state->next_equiv_class_state = prev; |
5777 prev = state; | 5919 prev = state; |
5778 } | 5920 } |
5779 if (prev) | 5921 if (prev) |
5780 VEC_safe_push (state_t,heap, *classes, prev); | 5922 VEC_safe_push (state_t, heap, *classes, prev); |
5781 return class_num; | 5923 return class_num; |
5782 } | 5924 } |
5783 | 5925 |
5784 /* The function copies pointers to equivalent states from vla FROM | 5926 /* The function copies pointers to equivalent states from vla FROM |
5785 into vla TO. */ | 5927 into vla TO. */ |
5786 static void | 5928 static void |
5787 copy_equiv_class (VEC(state_t,heap) **to, VEC(state_t,heap) *from) | 5929 copy_equiv_class (VEC(state_t, heap) **to, VEC(state_t, heap) *from) |
5788 { | 5930 { |
5789 VEC_free (state_t,heap, *to); | 5931 VEC_free (state_t, heap, *to); |
5790 *to = VEC_copy (state_t,heap, from); | 5932 *to = VEC_copy (state_t, heap, from); |
5791 } | 5933 } |
5792 | 5934 |
5793 /* The function processes equivalence class given by its first state, | 5935 /* The function processes equivalence class given by its first state, |
5794 FIRST_STATE, on odd iteration if ODD_ITERATION_FLAG. If there | 5936 FIRST_STATE, on odd iteration if ODD_ITERATION_FLAG. If there |
5795 are not equivalent states, the function partitions the class | 5937 are not equivalent states, the function partitions the class |
5797 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans | 5939 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans |
5798 assigns it to the state equivalence number. If the class has been | 5940 assigns it to the state equivalence number. If the class has been |
5799 partitioned, the function returns nonzero value. */ | 5941 partitioned, the function returns nonzero value. */ |
5800 static int | 5942 static int |
5801 partition_equiv_class (state_t first_state, int odd_iteration_flag, | 5943 partition_equiv_class (state_t first_state, int odd_iteration_flag, |
5802 VEC(state_t,heap) **next_iteration_classes, | 5944 VEC(state_t, heap) **next_iteration_classes, |
5803 int *new_equiv_class_num_ptr) | 5945 int *new_equiv_class_num_ptr) |
5804 { | 5946 { |
5805 state_t new_equiv_class; | 5947 state_t new_equiv_class; |
5806 int partition_p; | 5948 int partition_p; |
5807 state_t curr_state; | 5949 state_t curr_state; |
5821 curr_state = first_state->next_equiv_class_state; | 5963 curr_state = first_state->next_equiv_class_state; |
5822 curr_state != NULL; | 5964 curr_state != NULL; |
5823 curr_state = next_state) | 5965 curr_state = next_state) |
5824 { | 5966 { |
5825 next_state = curr_state->next_equiv_class_state; | 5967 next_state = curr_state->next_equiv_class_state; |
5826 if (state_is_differed (curr_state, first_state, | 5968 if (state_is_differed (curr_state, first_state, |
5827 odd_iteration_flag)) | 5969 odd_iteration_flag)) |
5828 { | 5970 { |
5829 /* Remove curr state from the class equivalence. */ | 5971 /* Remove curr state from the class equivalence. */ |
5830 prev_state->next_equiv_class_state = next_state; | 5972 prev_state->next_equiv_class_state = next_state; |
5831 /* Add curr state to the new class equivalence. */ | 5973 /* Add curr state to the new class equivalence. */ |
5843 prev_state = curr_state; | 5985 prev_state = curr_state; |
5844 } | 5986 } |
5845 clear_arc_insns_equiv_num (first_state); | 5987 clear_arc_insns_equiv_num (first_state); |
5846 } | 5988 } |
5847 if (new_equiv_class != NULL) | 5989 if (new_equiv_class != NULL) |
5848 VEC_safe_push (state_t,heap, *next_iteration_classes, new_equiv_class); | 5990 VEC_safe_push (state_t, heap, *next_iteration_classes, new_equiv_class); |
5849 first_state = new_equiv_class; | 5991 first_state = new_equiv_class; |
5850 } | 5992 } |
5851 return partition_p; | 5993 return partition_p; |
5852 } | 5994 } |
5853 | 5995 |
5854 /* The function finds equivalent states of AUTOMATON. */ | 5996 /* The function finds equivalent states of AUTOMATON. */ |
5855 static void | 5997 static void |
5856 evaluate_equiv_classes (automaton_t automaton, | 5998 evaluate_equiv_classes (automaton_t automaton, |
5857 VEC(state_t,heap) **equiv_classes) | 5999 VEC(state_t, heap) **equiv_classes) |
5858 { | 6000 { |
5859 int new_equiv_class_num; | 6001 int new_equiv_class_num; |
5860 int odd_iteration_flag; | 6002 int odd_iteration_flag; |
5861 int finish_flag; | 6003 int finish_flag; |
5862 VEC (state_t,heap) *next_iteration_classes; | 6004 VEC (state_t, heap) *next_iteration_classes; |
5863 size_t i; | 6005 size_t i; |
5864 | 6006 |
5865 all_achieved_states = VEC_alloc (state_t,heap, 1500); | 6007 all_achieved_states = VEC_alloc (state_t, heap, 1500); |
5866 pass_states (automaton, add_achieved_state); | 6008 pass_states (automaton, add_achieved_state); |
5867 pass_states (automaton, cache_presence); | 6009 pass_states (automaton, cache_presence); |
5868 qsort (VEC_address (state_t, all_achieved_states), | 6010 qsort (VEC_address (state_t, all_achieved_states), |
5869 VEC_length (state_t, all_achieved_states), | 6011 VEC_length (state_t, all_achieved_states), |
5870 sizeof (state_t), compare_states_for_equiv); | 6012 sizeof (state_t), compare_states_for_equiv); |
5894 &next_iteration_classes, | 6036 &next_iteration_classes, |
5895 &new_equiv_class_num)) | 6037 &new_equiv_class_num)) |
5896 finish_flag = 0; | 6038 finish_flag = 0; |
5897 } | 6039 } |
5898 while (!finish_flag); | 6040 while (!finish_flag); |
5899 VEC_free (state_t,heap, next_iteration_classes); | 6041 VEC_free (state_t, heap, next_iteration_classes); |
5900 VEC_free (state_t,heap, all_achieved_states); | 6042 VEC_free (state_t, heap, all_achieved_states); |
5901 } | 6043 } |
5902 | 6044 |
5903 /* The function merges equivalent states of AUTOMATON. */ | 6045 /* The function merges equivalent states of AUTOMATON. */ |
5904 static void | 6046 static void |
5905 merge_states (automaton_t automaton, VEC(state_t,heap) *equiv_classes) | 6047 merge_states (automaton_t automaton, VEC(state_t, heap) *equiv_classes) |
5906 { | 6048 { |
5907 state_t curr_state; | 6049 state_t curr_state; |
5908 state_t new_state; | 6050 state_t new_state; |
5909 state_t first_class_state; | 6051 state_t first_class_state; |
5910 alt_state_t alt_states; | 6052 alt_state_t alt_states; |
6015 /* The top level function for minimization of deterministic | 6157 /* The top level function for minimization of deterministic |
6016 AUTOMATON. */ | 6158 AUTOMATON. */ |
6017 static void | 6159 static void |
6018 minimize_DFA (automaton_t automaton) | 6160 minimize_DFA (automaton_t automaton) |
6019 { | 6161 { |
6020 VEC(state_t,heap) *equiv_classes = 0; | 6162 VEC(state_t, heap) *equiv_classes = 0; |
6021 | 6163 |
6022 evaluate_equiv_classes (automaton, &equiv_classes); | 6164 evaluate_equiv_classes (automaton, &equiv_classes); |
6023 merge_states (automaton, equiv_classes); | 6165 merge_states (automaton, equiv_classes); |
6024 pass_states (automaton, set_new_cycle_flags); | 6166 pass_states (automaton, set_new_cycle_flags); |
6025 | 6167 |
6026 VEC_free (state_t,heap, equiv_classes); | 6168 VEC_free (state_t, heap, equiv_classes); |
6027 } | 6169 } |
6028 | 6170 |
6029 /* Values of two variables are counted number of states and arcs in an | 6171 /* Values of two variables are counted number of states and arcs in an |
6030 automaton. */ | 6172 automaton. */ |
6031 static int curr_counted_states_num; | 6173 static int curr_counted_states_num; |
6561 case rm_unit: case rm_reserv: | 6703 case rm_unit: case rm_reserv: |
6562 { | 6704 { |
6563 const char *name = (regexp->mode == rm_unit | 6705 const char *name = (regexp->mode == rm_unit |
6564 ? REGEXP_UNIT (regexp)->name | 6706 ? REGEXP_UNIT (regexp)->name |
6565 : REGEXP_RESERV (regexp)->name); | 6707 : REGEXP_RESERV (regexp)->name); |
6566 | 6708 |
6567 obstack_grow (&irp, name, strlen (name)); | 6709 obstack_grow (&irp, name, strlen (name)); |
6568 break; | 6710 break; |
6569 } | 6711 } |
6570 | 6712 |
6571 case rm_sequence: | 6713 case rm_sequence: |
6572 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++) | 6714 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++) |
6573 { | 6715 { |
6574 if (i != 0) | 6716 if (i != 0) |
6575 obstack_1grow (&irp, ','); | 6717 obstack_1grow (&irp, ','); |
6591 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof) | 6733 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof) |
6592 obstack_1grow (&irp, ')'); | 6734 obstack_1grow (&irp, ')'); |
6593 } | 6735 } |
6594 obstack_1grow (&irp, ')'); | 6736 obstack_1grow (&irp, ')'); |
6595 break; | 6737 break; |
6596 | 6738 |
6597 case rm_oneof: | 6739 case rm_oneof: |
6598 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++) | 6740 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++) |
6599 { | 6741 { |
6600 if (i != 0) | 6742 if (i != 0) |
6601 obstack_1grow (&irp, '|'); | 6743 obstack_1grow (&irp, '|'); |
6604 form_regexp (REGEXP_ONEOF (regexp)->regexps [i]); | 6746 form_regexp (REGEXP_ONEOF (regexp)->regexps [i]); |
6605 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence) | 6747 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence) |
6606 obstack_1grow (&irp, ')'); | 6748 obstack_1grow (&irp, ')'); |
6607 } | 6749 } |
6608 break; | 6750 break; |
6609 | 6751 |
6610 case rm_repeat: | 6752 case rm_repeat: |
6611 { | 6753 { |
6612 char digits [30]; | 6754 char digits [30]; |
6613 | 6755 |
6614 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence | 6756 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence |
6615 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof | 6757 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof |
6616 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof) | 6758 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof) |
6617 obstack_1grow (&irp, '('); | 6759 obstack_1grow (&irp, '('); |
6618 form_regexp (REGEXP_REPEAT (regexp)->regexp); | 6760 form_regexp (REGEXP_REPEAT (regexp)->regexp); |
6956 { | 7098 { |
6957 ainsn_t ainsn; | 7099 ainsn_t ainsn; |
6958 int insn_value; | 7100 int insn_value; |
6959 vla_hwint_t translate_vect; | 7101 vla_hwint_t translate_vect; |
6960 | 7102 |
6961 translate_vect = VEC_alloc (vect_el_t,heap, description->insns_num); | 7103 translate_vect = VEC_alloc (vect_el_t, heap, description->insns_num); |
6962 | 7104 |
6963 for (insn_value = 0; insn_value < description->insns_num; insn_value++) | 7105 for (insn_value = 0; insn_value < description->insns_num; insn_value++) |
6964 /* Undefined value */ | 7106 /* Undefined value */ |
6965 VEC_quick_push (vect_el_t, translate_vect, | 7107 VEC_quick_push (vect_el_t, translate_vect, |
6966 automaton->insn_equiv_classes_num); | 7108 automaton->insn_equiv_classes_num); |
6977 fprintf (output_file, " "); | 7119 fprintf (output_file, " "); |
6978 output_translate_vect_name (output_file, automaton); | 7120 output_translate_vect_name (output_file, automaton); |
6979 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n"); | 7121 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n"); |
6980 output_vect (translate_vect); | 7122 output_vect (translate_vect); |
6981 fprintf (output_file, "};\n\n"); | 7123 fprintf (output_file, "};\n\n"); |
6982 VEC_free (vect_el_t,heap, translate_vect); | 7124 VEC_free (vect_el_t, heap, translate_vect); |
6983 } | 7125 } |
6984 | 7126 |
6985 /* The value in a table state x ainsn -> something which represents | 7127 /* The value in a table state x ainsn -> something which represents |
6986 undefined value. */ | 7128 undefined value. */ |
6987 static int undefined_vect_el_value; | 7129 static int undefined_vect_el_value; |
7004 int i; | 7146 int i; |
7005 | 7147 |
7006 tab = XCREATENODE (struct state_ainsn_table); | 7148 tab = XCREATENODE (struct state_ainsn_table); |
7007 tab->automaton = automaton; | 7149 tab->automaton = automaton; |
7008 | 7150 |
7009 tab->comb_vect = VEC_alloc (vect_el_t,heap, 10000); | 7151 tab->comb_vect = VEC_alloc (vect_el_t, heap, 10000); |
7010 tab->check_vect = VEC_alloc (vect_el_t,heap, 10000); | 7152 tab->check_vect = VEC_alloc (vect_el_t, heap, 10000); |
7011 | 7153 |
7012 tab->base_vect = 0; | 7154 tab->base_vect = 0; |
7013 VEC_safe_grow (vect_el_t,heap, tab->base_vect, | 7155 VEC_safe_grow (vect_el_t, heap, tab->base_vect, |
7014 automaton->achieved_states_num); | 7156 automaton->achieved_states_num); |
7015 | 7157 |
7016 full_vect_length = (automaton->insn_equiv_classes_num | 7158 full_vect_length = (automaton->insn_equiv_classes_num |
7017 * automaton->achieved_states_num); | 7159 * automaton->achieved_states_num); |
7018 tab->full_vect = VEC_alloc (vect_el_t,heap, full_vect_length); | 7160 tab->full_vect = VEC_alloc (vect_el_t, heap, full_vect_length); |
7019 for (i = 0; i < full_vect_length; i++) | 7161 for (i = 0; i < full_vect_length; i++) |
7020 VEC_quick_push (vect_el_t, tab->full_vect, undefined_vect_el_value); | 7162 VEC_quick_push (vect_el_t, tab->full_vect, undefined_vect_el_value); |
7021 | 7163 |
7022 tab->min_base_vect_el_value = 0; | 7164 tab->min_base_vect_el_value = 0; |
7023 tab->max_base_vect_el_value = 0; | 7165 tab->max_base_vect_el_value = 0; |
7101 real_vect_length = tab->automaton->insn_equiv_classes_num; | 7243 real_vect_length = tab->automaton->insn_equiv_classes_num; |
7102 /* Form full vector in the table: */ | 7244 /* Form full vector in the table: */ |
7103 { | 7245 { |
7104 size_t full_base = tab->automaton->insn_equiv_classes_num * vect_num; | 7246 size_t full_base = tab->automaton->insn_equiv_classes_num * vect_num; |
7105 if (VEC_length (vect_el_t, tab->full_vect) < full_base + vect_length) | 7247 if (VEC_length (vect_el_t, tab->full_vect) < full_base + vect_length) |
7106 VEC_safe_grow (vect_el_t,heap, tab->full_vect, | 7248 VEC_safe_grow (vect_el_t, heap, tab->full_vect, |
7107 full_base + vect_length); | 7249 full_base + vect_length); |
7108 for (i = 0; i < vect_length; i++) | 7250 for (i = 0; i < vect_length; i++) |
7109 VEC_replace (vect_el_t, tab->full_vect, full_base + i, | 7251 VEC_replace (vect_el_t, tab->full_vect, full_base + i, |
7110 VEC_index (vect_el_t, vect, i)); | 7252 VEC_index (vect_el_t, vect, i)); |
7111 } | 7253 } |
7201 /* Expand comb and check vectors. */ | 7343 /* Expand comb and check vectors. */ |
7202 vect_el = undefined_vect_el_value; | 7344 vect_el = undefined_vect_el_value; |
7203 no_state_value = tab->automaton->achieved_states_num; | 7345 no_state_value = tab->automaton->achieved_states_num; |
7204 while (additional_els_num > 0) | 7346 while (additional_els_num > 0) |
7205 { | 7347 { |
7206 VEC_safe_push (vect_el_t,heap, tab->comb_vect, vect_el); | 7348 VEC_safe_push (vect_el_t, heap, tab->comb_vect, vect_el); |
7207 VEC_safe_push (vect_el_t,heap, tab->check_vect, no_state_value); | 7349 VEC_safe_push (vect_el_t, heap, tab->check_vect, no_state_value); |
7208 additional_els_num--; | 7350 additional_els_num--; |
7209 } | 7351 } |
7210 gcc_assert (VEC_length (vect_el_t, tab->comb_vect) | 7352 gcc_assert (VEC_length (vect_el_t, tab->comb_vect) |
7211 >= comb_vect_index + real_vect_length); | 7353 >= comb_vect_index + real_vect_length); |
7212 /* Fill comb and check vectors. */ | 7354 /* Fill comb and check vectors. */ |
7285 gcc_assert (ainsn); | 7427 gcc_assert (ainsn); |
7286 equiv_class_num = ainsn->insn_equiv_class_num; | 7428 equiv_class_num = ainsn->insn_equiv_class_num; |
7287 for (vect_index = VEC_length (vect_el_t, *vect); | 7429 for (vect_index = VEC_length (vect_el_t, *vect); |
7288 vect_index <= equiv_class_num; | 7430 vect_index <= equiv_class_num; |
7289 vect_index++) | 7431 vect_index++) |
7290 VEC_safe_push (vect_el_t,heap, *vect, undefined_vect_el_value); | 7432 VEC_safe_push (vect_el_t, heap, *vect, undefined_vect_el_value); |
7291 VEC_replace (vect_el_t, *vect, equiv_class_num, el_value); | 7433 VEC_replace (vect_el_t, *vect, equiv_class_num, el_value); |
7292 } | 7434 } |
7293 | 7435 |
7294 /* This is for forming vector of states of an automaton. */ | 7436 /* This is for forming vector of states of an automaton. */ |
7295 static VEC(state_t,heap) *output_states_vect; | 7437 static VEC(state_t, heap) *output_states_vect; |
7296 | 7438 |
7297 /* The function is called by function pass_states. The function adds | 7439 /* The function is called by function pass_states. The function adds |
7298 STATE to `output_states_vect'. */ | 7440 STATE to `output_states_vect'. */ |
7299 static void | 7441 static void |
7300 add_states_vect_el (state_t state) | 7442 add_states_vect_el (state_t state) |
7301 { | 7443 { |
7302 VEC_safe_push (state_t,heap, output_states_vect, state); | 7444 VEC_safe_push (state_t, heap, output_states_vect, state); |
7303 } | 7445 } |
7304 | 7446 |
7305 /* Form and output vectors (comb, check, base or full vector) | 7447 /* Form and output vectors (comb, check, base or full vector) |
7306 representing transition table of AUTOMATON. */ | 7448 representing transition table of AUTOMATON. */ |
7307 static void | 7449 static void |
7340 output_state_ainsn_table | 7482 output_state_ainsn_table |
7341 (automaton->trans_table, "state transitions", | 7483 (automaton->trans_table, "state transitions", |
7342 output_trans_full_vect_name, output_trans_comb_vect_name, | 7484 output_trans_full_vect_name, output_trans_comb_vect_name, |
7343 output_trans_check_vect_name, output_trans_base_vect_name); | 7485 output_trans_check_vect_name, output_trans_base_vect_name); |
7344 | 7486 |
7345 VEC_free (state_t,heap, output_states_vect); | 7487 VEC_free (state_t, heap, output_states_vect); |
7346 VEC_free (vect_el_t,heap, transition_vect); | 7488 VEC_free (vect_el_t, heap, transition_vect); |
7347 } | 7489 } |
7348 | 7490 |
7349 /* The current number of passing states to find minimal issue delay | 7491 /* The current number of passing states to find minimal issue delay |
7350 value for an ainsn and state. */ | 7492 value for an ainsn and state. */ |
7351 static int curr_state_pass_num; | 7493 static int curr_state_pass_num; |
7431 output_states_vect = 0; | 7573 output_states_vect = 0; |
7432 pass_states (automaton, add_states_vect_el); | 7574 pass_states (automaton, add_states_vect_el); |
7433 | 7575 |
7434 min_issue_delay_len = (VEC_length (state_t, output_states_vect) | 7576 min_issue_delay_len = (VEC_length (state_t, output_states_vect) |
7435 * automaton->insn_equiv_classes_num); | 7577 * automaton->insn_equiv_classes_num); |
7436 min_issue_delay_vect = VEC_alloc (vect_el_t,heap, min_issue_delay_len); | 7578 min_issue_delay_vect = VEC_alloc (vect_el_t, heap, min_issue_delay_len); |
7437 for (i = 0; i < min_issue_delay_len; i++) | 7579 for (i = 0; i < min_issue_delay_len; i++) |
7438 VEC_quick_push (vect_el_t, min_issue_delay_vect, 0); | 7580 VEC_quick_push (vect_el_t, min_issue_delay_vect, 0); |
7439 | 7581 |
7440 automaton->max_min_delay = 0; | 7582 automaton->max_min_delay = 0; |
7441 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn) | 7583 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn) |
7473 cfactor = 1; | 7615 cfactor = 1; |
7474 automaton->min_issue_delay_table_compression_factor = cfactor; | 7616 automaton->min_issue_delay_table_compression_factor = cfactor; |
7475 | 7617 |
7476 compressed_min_issue_delay_len = (min_issue_delay_len+cfactor-1) / cfactor; | 7618 compressed_min_issue_delay_len = (min_issue_delay_len+cfactor-1) / cfactor; |
7477 compressed_min_issue_delay_vect | 7619 compressed_min_issue_delay_vect |
7478 = VEC_alloc (vect_el_t,heap, compressed_min_issue_delay_len); | 7620 = VEC_alloc (vect_el_t, heap, compressed_min_issue_delay_len); |
7479 | 7621 |
7480 for (i = 0; i < compressed_min_issue_delay_len; i++) | 7622 for (i = 0; i < compressed_min_issue_delay_len; i++) |
7481 VEC_quick_push (vect_el_t, compressed_min_issue_delay_vect, 0); | 7623 VEC_quick_push (vect_el_t, compressed_min_issue_delay_vect, 0); |
7482 | 7624 |
7483 for (i = 0; i < min_issue_delay_len; i++) | 7625 for (i = 0; i < min_issue_delay_len; i++) |
7489 cx |= x << (8 - (i % cfactor + 1) * (8 / cfactor)); | 7631 cx |= x << (8 - (i % cfactor + 1) * (8 / cfactor)); |
7490 VEC_replace (vect_el_t, compressed_min_issue_delay_vect, ci, cx); | 7632 VEC_replace (vect_el_t, compressed_min_issue_delay_vect, ci, cx); |
7491 } | 7633 } |
7492 output_vect (compressed_min_issue_delay_vect); | 7634 output_vect (compressed_min_issue_delay_vect); |
7493 fprintf (output_file, "};\n\n"); | 7635 fprintf (output_file, "};\n\n"); |
7494 VEC_free (state_t,heap, output_states_vect); | 7636 VEC_free (state_t, heap, output_states_vect); |
7495 VEC_free (vect_el_t,heap, min_issue_delay_vect); | 7637 VEC_free (vect_el_t, heap, min_issue_delay_vect); |
7496 VEC_free (vect_el_t,heap, compressed_min_issue_delay_vect); | 7638 VEC_free (vect_el_t, heap, compressed_min_issue_delay_vect); |
7497 } | 7639 } |
7498 | 7640 |
7499 /* Form and output vector representing the locked states of | 7641 /* Form and output vector representing the locked states of |
7500 AUTOMATON. */ | 7642 AUTOMATON. */ |
7501 static void | 7643 static void |
7510 first). */ | 7652 first). */ |
7511 automaton->locked_states = 0; | 7653 automaton->locked_states = 0; |
7512 output_states_vect = 0; | 7654 output_states_vect = 0; |
7513 pass_states (automaton, add_states_vect_el); | 7655 pass_states (automaton, add_states_vect_el); |
7514 | 7656 |
7515 VEC_safe_grow (vect_el_t,heap, dead_lock_vect, | 7657 VEC_safe_grow (vect_el_t, heap, dead_lock_vect, |
7516 VEC_length (state_t, output_states_vect)); | 7658 VEC_length (state_t, output_states_vect)); |
7517 for (i = 0; i < VEC_length (state_t, output_states_vect); i++) | 7659 for (i = 0; i < VEC_length (state_t, output_states_vect); i++) |
7518 { | 7660 { |
7519 state_t s = VEC_index (state_t, output_states_vect, i); | 7661 state_t s = VEC_index (state_t, output_states_vect, i); |
7520 arc = first_out_arc (s); | 7662 arc = first_out_arc (s); |
7538 fprintf (output_file, " "); | 7680 fprintf (output_file, " "); |
7539 output_dead_lock_vect_name (output_file, automaton); | 7681 output_dead_lock_vect_name (output_file, automaton); |
7540 fprintf (output_file, "[] = {\n"); | 7682 fprintf (output_file, "[] = {\n"); |
7541 output_vect (dead_lock_vect); | 7683 output_vect (dead_lock_vect); |
7542 fprintf (output_file, "};\n\n"); | 7684 fprintf (output_file, "};\n\n"); |
7543 VEC_free (state_t,heap, output_states_vect); | 7685 VEC_free (state_t, heap, output_states_vect); |
7544 VEC_free (vect_el_t,heap, dead_lock_vect); | 7686 VEC_free (vect_el_t, heap, dead_lock_vect); |
7545 } | 7687 } |
7546 | 7688 |
7547 /* Form and output vector representing reserved units of the states of | 7689 /* Form and output vector representing reserved units of the states of |
7548 AUTOMATON. */ | 7690 AUTOMATON. */ |
7549 static void | 7691 static void |
7564 /* Create vector. */ | 7706 /* Create vector. */ |
7565 state_byte_size = (description->query_units_num + 7) / 8; | 7707 state_byte_size = (description->query_units_num + 7) / 8; |
7566 reserved_units_size = (VEC_length (state_t, output_states_vect) | 7708 reserved_units_size = (VEC_length (state_t, output_states_vect) |
7567 * state_byte_size); | 7709 * state_byte_size); |
7568 | 7710 |
7569 reserved_units_table = VEC_alloc (vect_el_t,heap, reserved_units_size); | 7711 reserved_units_table = VEC_alloc (vect_el_t, heap, reserved_units_size); |
7570 | 7712 |
7571 for (i = 0; i < reserved_units_size; i++) | 7713 for (i = 0; i < reserved_units_size; i++) |
7572 VEC_quick_push (vect_el_t, reserved_units_table, 0); | 7714 VEC_quick_push (vect_el_t, reserved_units_table, 0); |
7573 for (n = 0; n < VEC_length (state_t, output_states_vect); n++) | 7715 for (n = 0; n < VEC_length (state_t, output_states_vect); n++) |
7574 { | 7716 { |
7575 state_t s = VEC_index (state_t, output_states_vect, n); | 7717 state_t s = VEC_index (state_t, output_states_vect, n); |
7594 fprintf (output_file, "[] = {\n"); | 7736 fprintf (output_file, "[] = {\n"); |
7595 output_vect (reserved_units_table); | 7737 output_vect (reserved_units_table); |
7596 fprintf (output_file, "};\n#endif /* #if %s */\n\n", | 7738 fprintf (output_file, "};\n#endif /* #if %s */\n\n", |
7597 CPU_UNITS_QUERY_MACRO_NAME); | 7739 CPU_UNITS_QUERY_MACRO_NAME); |
7598 | 7740 |
7599 VEC_free (state_t,heap, output_states_vect); | 7741 VEC_free (state_t, heap, output_states_vect); |
7600 VEC_free (vect_el_t,heap, reserved_units_table); | 7742 VEC_free (vect_el_t, heap, reserved_units_table); |
7601 } | 7743 } |
7602 | 7744 |
7603 /* The function outputs all tables representing DFA(s) used for fast | 7745 /* The function outputs all tables representing DFA(s) used for fast |
7604 pipeline hazards recognition. */ | 7746 pipeline hazards recognition. */ |
7605 static void | 7747 static void |
8074 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME, | 8216 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME, |
8075 CHIP_NAME); | 8217 CHIP_NAME); |
8076 fprintf (output_file, "}\n\n"); | 8218 fprintf (output_file, "}\n\n"); |
8077 } | 8219 } |
8078 | 8220 |
8079 /* Output the array holding default latency values. These are used in | 8221 /* Output the array holding default latency values. These are used in |
8080 insn_latency and maximal_insn_latency function implementations. */ | 8222 insn_latency and maximal_insn_latency function implementations. */ |
8081 static void | 8223 static void |
8082 output_default_latencies (void) | 8224 output_default_latencies (void) |
8083 { | 8225 { |
8084 int i, j, col; | 8226 int i, j, col; |
8157 gcc_assert (bypass->in_insn_reserv->insn_num | 8299 gcc_assert (bypass->in_insn_reserv->insn_num |
8158 != (DECL_INSN_RESERV | 8300 != (DECL_INSN_RESERV |
8159 (advance_cycle_insn_decl)->insn_num)); | 8301 (advance_cycle_insn_decl)->insn_num)); |
8160 fprintf (output_file, " case %d:\n", | 8302 fprintf (output_file, " case %d:\n", |
8161 bypass->in_insn_reserv->insn_num); | 8303 bypass->in_insn_reserv->insn_num); |
8162 if (bypass->bypass_guard_name == NULL) | 8304 for (;;) |
8163 fprintf (output_file, " return %d;\n", | |
8164 bypass->latency); | |
8165 else | |
8166 { | 8305 { |
8167 fprintf (output_file, | 8306 if (bypass->bypass_guard_name == NULL) |
8168 " if (%s (%s, %s))\n", | 8307 { |
8169 bypass->bypass_guard_name, INSN_PARAMETER_NAME, | 8308 gcc_assert (bypass->next == NULL |
8170 INSN2_PARAMETER_NAME); | 8309 || (bypass->in_insn_reserv |
8171 fprintf (output_file, | 8310 != bypass->next->in_insn_reserv)); |
8172 " return %d;\n break;\n", | 8311 fprintf (output_file, " return %d;\n", |
8173 bypass->latency); | 8312 bypass->latency); |
8313 } | |
8314 else | |
8315 { | |
8316 fprintf (output_file, | |
8317 " if (%s (%s, %s))\n", | |
8318 bypass->bypass_guard_name, INSN_PARAMETER_NAME, | |
8319 INSN2_PARAMETER_NAME); | |
8320 fprintf (output_file, " return %d;\n", | |
8321 bypass->latency); | |
8322 } | |
8323 if (bypass->next == NULL | |
8324 || bypass->in_insn_reserv != bypass->next->in_insn_reserv) | |
8325 break; | |
8326 bypass = bypass->next; | |
8174 } | 8327 } |
8328 if (bypass->bypass_guard_name != NULL) | |
8329 fprintf (output_file, " break;\n"); | |
8175 } | 8330 } |
8176 fputs (" }\n break;\n", output_file); | 8331 fputs (" }\n break;\n", output_file); |
8177 } | 8332 } |
8178 | 8333 |
8179 fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n", | 8334 fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n", |
8285 decl = description->decls [i]; | 8440 decl = description->decls [i]; |
8286 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl) | 8441 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl) |
8287 { | 8442 { |
8288 gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num); | 8443 gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num); |
8289 j++; | 8444 j++; |
8290 | 8445 |
8291 fprintf (output_file, "\n \"%s\",", | 8446 fprintf (output_file, "\n \"%s\",", |
8292 regexp_representation (DECL_INSN_RESERV (decl)->regexp)); | 8447 regexp_representation (DECL_INSN_RESERV (decl)->regexp)); |
8293 finish_regexp_representation (); | 8448 finish_regexp_representation (); |
8294 } | 8449 } |
8295 } | 8450 } |
8687 fprintf (output_description_file, "\n\n"); | 8842 fprintf (output_description_file, "\n\n"); |
8688 } | 8843 } |
8689 | 8844 |
8690 /* The following variable is used for forming array of all possible cpu unit | 8845 /* The following variable is used for forming array of all possible cpu unit |
8691 reservations described by the current DFA state. */ | 8846 reservations described by the current DFA state. */ |
8692 static VEC(reserv_sets_t,heap) *state_reservs; | 8847 static VEC(reserv_sets_t, heap) *state_reservs; |
8693 | 8848 |
8694 /* The function forms `state_reservs' for STATE. */ | 8849 /* The function forms `state_reservs' for STATE. */ |
8695 static void | 8850 static void |
8696 add_state_reservs (state_t state) | 8851 add_state_reservs (state_t state) |
8697 { | 8852 { |
8701 for (curr_alt_state = state->component_states; | 8856 for (curr_alt_state = state->component_states; |
8702 curr_alt_state != NULL; | 8857 curr_alt_state != NULL; |
8703 curr_alt_state = curr_alt_state->next_sorted_alt_state) | 8858 curr_alt_state = curr_alt_state->next_sorted_alt_state) |
8704 add_state_reservs (curr_alt_state->state); | 8859 add_state_reservs (curr_alt_state->state); |
8705 else | 8860 else |
8706 VEC_safe_push (reserv_sets_t,heap, state_reservs, state->reservs); | 8861 VEC_safe_push (reserv_sets_t, heap, state_reservs, state->reservs); |
8707 } | 8862 } |
8708 | 8863 |
8709 /* The function outputs readable representation of all out arcs of | 8864 /* The function outputs readable representation of all out arcs of |
8710 STATE. */ | 8865 STATE. */ |
8711 static void | 8866 static void |
8799 add_state_reservs (state); | 8954 add_state_reservs (state); |
8800 qsort (VEC_address (reserv_sets_t, state_reservs), | 8955 qsort (VEC_address (reserv_sets_t, state_reservs), |
8801 VEC_length (reserv_sets_t, state_reservs), | 8956 VEC_length (reserv_sets_t, state_reservs), |
8802 sizeof (reserv_sets_t), state_reservs_cmp); | 8957 sizeof (reserv_sets_t), state_reservs_cmp); |
8803 remove_state_duplicate_reservs (); | 8958 remove_state_duplicate_reservs (); |
8804 for (i = 1; i < VEC_length (reserv_sets_t, state_reservs); i++) | 8959 for (i = 0; i < VEC_length (reserv_sets_t, state_reservs); i++) |
8805 { | 8960 { |
8806 fprintf (output_description_file, " "); | 8961 fprintf (output_description_file, " "); |
8807 output_reserv_sets (output_description_file, | 8962 output_reserv_sets (output_description_file, |
8808 VEC_index (reserv_sets_t, state_reservs, i)); | 8963 VEC_index (reserv_sets_t, state_reservs, i)); |
8809 fprintf (output_description_file, "\n"); | 8964 fprintf (output_description_file, "\n"); |
8810 } | 8965 } |
8811 fprintf (output_description_file, "\n"); | 8966 fprintf (output_description_file, "\n"); |
8812 output_state_arcs (state); | 8967 output_state_arcs (state); |
8813 VEC_free (reserv_sets_t,heap, state_reservs); | 8968 VEC_free (reserv_sets_t, heap, state_reservs); |
8814 } | 8969 } |
8815 | 8970 |
8816 /* The following function output readable representation of | 8971 /* The following function output readable representation of |
8817 DFAs used for fast recognition of pipeline hazards. */ | 8972 DFAs used for fast recognition of pipeline hazards. */ |
8818 static void | 8973 static void |
9073 if (!w_flag) | 9228 if (!w_flag) |
9074 error ("Automaton `%s': Insn `%s' will never be issued", | 9229 error ("Automaton `%s': Insn `%s' will never be issued", |
9075 automaton->corresponding_automaton_decl->name, | 9230 automaton->corresponding_automaton_decl->name, |
9076 reserv_ainsn->insn_reserv_decl->name); | 9231 reserv_ainsn->insn_reserv_decl->name); |
9077 else | 9232 else |
9078 warning | 9233 warning ("Automaton `%s': Insn `%s' will never be issued", |
9079 (0, "Automaton `%s': Insn `%s' will never be issued", | 9234 automaton->corresponding_automaton_decl->name, |
9080 automaton->corresponding_automaton_decl->name, | 9235 reserv_ainsn->insn_reserv_decl->name); |
9081 reserv_ainsn->insn_reserv_decl->name); | |
9082 } | 9236 } |
9083 else | 9237 else |
9084 { | 9238 { |
9085 if (!w_flag) | 9239 if (!w_flag) |
9086 error ("Insn `%s' will never be issued", | 9240 error ("Insn `%s' will never be issued", |
9087 reserv_ainsn->insn_reserv_decl->name); | 9241 reserv_ainsn->insn_reserv_decl->name); |
9088 else | 9242 else |
9089 warning (0, "Insn `%s' will never be issued", | 9243 warning ("Insn `%s' will never be issued", |
9090 reserv_ainsn->insn_reserv_decl->name); | 9244 reserv_ainsn->insn_reserv_decl->name); |
9091 } | 9245 } |
9092 } | 9246 } |
9093 } | 9247 } |
9094 } | 9248 } |
9095 | 9249 |
9096 /* The following vla is used for storing pointers to all achieved | 9250 /* The following vla is used for storing pointers to all achieved |
9097 states. */ | 9251 states. */ |
9098 static VEC(state_t,heap) *automaton_states; | 9252 static VEC(state_t, heap) *automaton_states; |
9099 | 9253 |
9100 /* This function is called by function pass_states to add an achieved | 9254 /* This function is called by function pass_states to add an achieved |
9101 STATE. */ | 9255 STATE. */ |
9102 static void | 9256 static void |
9103 add_automaton_state (state_t state) | 9257 add_automaton_state (state_t state) |
9104 { | 9258 { |
9105 VEC_safe_push (state_t,heap, automaton_states, state); | 9259 VEC_safe_push (state_t, heap, automaton_states, state); |
9106 } | 9260 } |
9107 | 9261 |
9108 /* The following function forms list of important automata (whose | 9262 /* The following function forms list of important automata (whose |
9109 states may be changed after the insn issue) for each insn. */ | 9263 states may be changed after the insn issue) for each insn. */ |
9110 static void | 9264 static void |
9139 ainsn = ainsn->next_same_reservs_insn) | 9293 ainsn = ainsn->next_same_reservs_insn) |
9140 ainsn->important_p = TRUE; | 9294 ainsn->important_p = TRUE; |
9141 } | 9295 } |
9142 } | 9296 } |
9143 } | 9297 } |
9144 VEC_free (state_t,heap, automaton_states); | 9298 VEC_free (state_t, heap, automaton_states); |
9145 | 9299 |
9146 /* Create automata sets for the insns. */ | 9300 /* Create automata sets for the insns. */ |
9147 for (i = 0; i < description->decls_num; i++) | 9301 for (i = 0; i < description->decls_num; i++) |
9148 { | 9302 { |
9149 decl = description->decls [i]; | 9303 decl = description->decls [i]; |
9393 } | 9547 } |
9394 | 9548 |
9395 if (have_error) | 9549 if (have_error) |
9396 return FATAL_EXIT_CODE; | 9550 return FATAL_EXIT_CODE; |
9397 | 9551 |
9398 puts ("/* Generated automatically by the program `genautomata'\n" | |
9399 " from the machine description file `md'. */\n\n" | |
9400 "#include \"config.h\"\n" | |
9401 "#include \"system.h\"\n" | |
9402 "#include \"coretypes.h\"\n" | |
9403 "#include \"tm.h\"\n" | |
9404 "#include \"rtl.h\"\n" | |
9405 "#include \"tm_p.h\"\n" | |
9406 "#include \"insn-config.h\"\n" | |
9407 "#include \"recog.h\"\n" | |
9408 "#include \"regs.h\"\n" | |
9409 "#include \"real.h\"\n" | |
9410 "#include \"output.h\"\n" | |
9411 "#include \"insn-attr.h\"\n" | |
9412 "#include \"toplev.h\"\n" | |
9413 "#include \"flags.h\"\n" | |
9414 "#include \"function.h\"\n"); | |
9415 | |
9416 if (VEC_length (decl_t, decls) > 0) | 9552 if (VEC_length (decl_t, decls) > 0) |
9417 { | 9553 { |
9418 expand_automata (); | 9554 expand_automata (); |
9419 write_automata (); | 9555 if (!have_error) |
9556 { | |
9557 puts ("/* Generated automatically by the program `genautomata'\n" | |
9558 " from the machine description file `md'. */\n\n" | |
9559 "#include \"config.h\"\n" | |
9560 "#include \"system.h\"\n" | |
9561 "#include \"coretypes.h\"\n" | |
9562 "#include \"tm.h\"\n" | |
9563 "#include \"rtl.h\"\n" | |
9564 "#include \"tm_p.h\"\n" | |
9565 "#include \"insn-config.h\"\n" | |
9566 "#include \"recog.h\"\n" | |
9567 "#include \"regs.h\"\n" | |
9568 "#include \"real.h\"\n" | |
9569 "#include \"output.h\"\n" | |
9570 "#include \"insn-attr.h\"\n" | |
9571 "#include \"toplev.h\"\n" | |
9572 "#include \"flags.h\"\n" | |
9573 "#include \"function.h\"\n"); | |
9574 | |
9575 write_automata (); | |
9576 } | |
9420 } | 9577 } |
9421 | 9578 |
9422 fflush (stdout); | 9579 fflush (stdout); |
9423 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); | 9580 return (ferror (stdout) != 0 || have_error |
9424 } | 9581 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); |
9582 } |