These two functions provide a wrapper for dead_lock_x table (refer to 9.6.4.1.4 Output table for locked states).
8568 static void
8569 output_internal_dead_lock_func (void) ingenautomata.c
8570 {
8571 automaton_tautomaton;
8572
8573 fprintf (output_file, "static int\n%s (struct %s*%s)\n",
8574 INTERNAL_DEAD_LOCK_FUNC_NAME,CHIP_NAME, CHIP_PARAMETER_NAME);
8575 fprintf (output_file, "{\n");
8576 for(automaton = description->first_automaton;
8577 automaton != NULL;
8578 automaton = automaton->next_automaton)
8579 {
8580 fprintf (output_file, " if (");
8581 output_dead_lock_vect_name (output_file,automaton);
8582 fprintf (output_file, " [%s->",CHIP_PARAMETER_NAME);
8583 output_chip_member_name (output_file,automaton);
8584 fprintf (output_file, "])\n return 1/* TRUE */;\n");
8585 }
8586 fprintf (output_file, " return 0/* FALSE */;\n}\n\n");
8587 }
1 static int
2 internal_state_dead_lock_p (structDFA_chip *chip)
3 {
4 if(dead_lock_0 [chip->automaton_state_0])
5 return 1/*TRUE */;
6 return0/* FALSE */;
7 }
8590 static void
8591 output_dead_lock_func (void) ingenautomata.c
8592 {
8593 fprintf (output_file, "int\n%s (%s %s)\n",
8594 DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8595 fprintf (output_file, "{\n return %s (%s);\n}\n\n",
8596 INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
8597 }
1 int
2 state_dead_lock_p (state_t state)
3 {
4 return internal_state_dead_lock_p (state);
5 }
These are helper functions for DFA_chip (refer to 9.6.4.2.1 Pseudo chip definition)
8610 static void
8611 output_size_func (void) ingenautomata.c
8612 {
8613 fprintf (output_file, "int\n%s (void)\n",SIZE_FUNC_NAME);
8614 fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n",CHIP_NAME);
8615 }
1 int
2 state_size (void)
3 {
4 returnsizeof (struct DFA_chip));
5 }
8600 static void
8601 output_internal_reset_func (void) ingenautomata.c
8602 {
8603 fprintf (output_file, "static inline void\n%s (struct%s *%s)\n",
8604 INTERNAL_RESET_FUNC_NAME, CHIP_NAME,CHIP_PARAMETER_NAME);
8605 fprintf (output_file, "{\n memset (%s, 0, sizeof (struct%s));\n}\n\n",
8606 CHIP_PARAMETER_NAME, CHIP_NAME);
8607 }
1 static inline void
2 internal_reset (structDFA_chip *chip)
3 {
4 memset(chip, 0, sizeof (struct DFA_chip));
5 }
8618 static void
8619 output_reset_func (void) ingenautomata.c
8620 {
8621 fprintf (output_file, "void\n%s (%s %s)\n",
8622 RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8623 fprintf (output_file, "{\n %s (%s);\n}\n\n",INTERNAL_RESET_FUNC_NAME,
8624 STATE_NAME);
8625 }
1 void
2 state_reset (state_t state)
3 {
4 internal_reset(state);
5 }
min_insn_conflict_delay finds out the minimum conflict delays between two giveninstruction.
8628 static void
8629 output_min_insn_conflict_delay_func (void) ingenautomata.c
8630 {
8631 fprintf (output_file,
8632 "int\n%s (%s %s, rtx %s, rtx %s)\n",
8633 MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME,
8634 STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8635 fprintf (output_file, "{\n struct %s %s;\n int %s, %s;\n",
8636 CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
8637 INTERNAL_INSN2_CODE_NAME);
8638 output_internal_insn_code_evaluation(INSN_PARAMETER_NAME,
8639 INTERNAL_INSN_CODE_NAME,0);
8640 output_internal_insn_code_evaluation(INSN2_PARAMETER_NAME,
8641 INTERNAL_INSN2_CODE_NAME,0);
8642 fprintf (output_file, " memcpy (&%s, %s, sizeof (%s));\n",
8643 CHIP_NAME, STATE_NAME, CHIP_NAME);
8644 fprintf (output_file, " %s (&%s);\n",INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8645 fprintf (output_file, " if (%s (%s, &%s) > 0)\n abort ();\n",
8646 INTERNAL_TRANSITION_FUNC_NAME,INTERNAL_INSN_CODE_NAME, CHIP_NAME);
8647 fprintf (output_file, " return %s (%s, &%s);\n",
8648 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME,INTERNAL_INSN2_CODE_NAME,
8649 CHIP_NAME);
8650 fprintf (output_file, "}\n\n");
8651 }
1 int
2 min_insn_conflict_delay(state_t state, rtx insn, rtx insn2)
3 {
4 structDFA_chip DFA_chip;
5 int insn_code, insn2_code;
6 if (insn!= 0)
7 {
8 insn_code = dfa_insn_code (insn);
9 if(insn_code > DFA__ADVANCE_CYCLE)
10 return 0;
11 }
12 else
13 insn_code = DFA__ADVANCE_CYCLE;
14
15 if (insn2 != 0)
16 {
17 insn2_code = dfa_insn_code(insn2);
18 if (insn2_code > DFA__ADVANCE_CYCLE)
19 return 0;
20 }
21 else
22 insn2_code = DFA__ADVANCE_CYCLE;
23
24 memcpy (&DFA_chip, state, sizeof(DFA_chip));
25 internal_reset(&DFA_chip);
26 if (internal_state_transition(insn_code, &DFA_chip) > 0)
27 abort ();
28 return internal_min_issue_delay(insn2_code, &DFA_chip);
29 }
See that at line 25, the automatons’ states inside DFA_chip havebeen cleaned as 0, which indicate the starting state for all automatons. So internal_state_transition atline 26 should return -1 as result of capable issuing instruction insn.Inside this function, automatons’ states are updated accordingly, and internal_min_issue_delay isinvoked to find the issue cost of insn2 following insn.
Latency indicates the delay of the result of the instruction can beavailable after it starts. Besides the default_latency field indefine_insn_reservation describes the latency for common cases, there aredefine_bypass definitions defining the latencies for special cases.
8654 static void
8655 output_internal_insn_latency_func (void) ingenautomata.c
8656 {
8657 decl_t decl;
8658 struct bypass_decl *bypass;
8659 int i, j, col;
8660 const char*tabletype = "unsigned char";
8661
8662 /* Find thesmallest integer type that can hold all the default
8663 latency values. */
8664 for (i = 0; i< description->decls_num;i++)
8665 if (description->decls[i]->mode ==dm_insn_reserv)
8666 {
8667 decl = description->decls[i];
8668 if (DECL_INSN_RESERV(decl)->default_latency > UCHAR_MAX
8669 && tabletype[0] != 'i') /* Don't shrinkit. */
8670 tabletype = "unsigned short";
8671 if (DECL_INSN_RESERV(decl)->default_latency > USHRT_MAX)
8672 tabletype = "int";
8673 }
8674
8675 fprintf (output_file,"static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %sATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %sATTRIBUTE_UNUSED)\n",
8676 INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8677 INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
8678 INSN2_PARAMETER_NAME);
8679 fprintf (output_file, "{\n");
8680
8681 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num== 0)
8682 {
8683 fputs (" return 0;\n}\n\n", output_file);
8684 return;
8685 }
8686
8687 fprintf (output_file, " static const %s default_latencies[] =\n {",
8688 tabletype);
8689
8690 for (i = 0, j= 0, col = 7; i < description->decls_num; i++)
8691 if (description->decls[i]->mode ==dm_insn_reserv
8692 && description->decls[i] != advance_cycle_insn_decl)
8693 {
8694 if ((col = (col+1) % 8) == 0)
8695 fputs ("\n ", output_file);
8696 decl = description->decls[i];
8697 if (j++ != DECL_INSN_RESERV(decl)->insn_num)
8698 abort ();
8699 fprintf (output_file, "% 4d,",
8700 DECL_INSN_RESERV(decl)->default_latency);
8701 }
8702 if (j != DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num)
8703 abort ();
8704 fputs ("\n };\n", output_file);
8705
8706 fprintf (output_file, " if (%s >= %s || %s >= %s)\n return 0;\n",
8707 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8708 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8709
8710 fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8711 for (i = 0; i < description->decls_num; i++)
8712 if (description->decls[i]->mode ==dm_insn_reserv
8713 && DECL_INSN_RESERV (description->decls[i])->bypass_list)
8714 {
8715 decl = description->decls [i];
8716 fprintf (output_file,
8717 " case %d:\n switch (%s)\n {\n",
8718 DECL_INSN_RESERV(decl)->insn_num,
8719 INTERNAL_INSN2_CODE_NAME);
8720 for(bypass = DECL_INSN_RESERV (decl)->bypass_list;
8721 bypass != NULL;
8722 bypass = bypass->next)
8723 {
8724 if(bypass->in_insn_reserv->insn_num
8725 == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num)
8726 abort ();
8727 fprintf (output_file, " case %d:\n",
8728 bypass->in_insn_reserv->insn_num);
8729 if (bypass->bypass_guard_name ==NULL)
8730 fprintf (output_file, " return %d;\n",
8731 bypass->latency);
8732 else
8733 {
8734 fprintf (output_file,
8735 " if (%s (%s, %s))\n",
8736 bypass->bypass_guard_name,INSN_PARAMETER_NAME,
8737 INSN2_PARAMETER_NAME);
8738 fprintf (output_file,
8739 " return %d;\n break;\n",
8740 bypass->latency);
8741 }
8742 }
8743 fputs (" }\n break;\n", output_file);
8744 }
8745
8746 fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n",
8747 INTERNAL_INSN_CODE_NAME);
8748 }
define_bypass defines special latency between specified instructionpair, otherwise we should use default_latency given in thedefine_insn_reservation pattern as indicated by the generated function (contentin red is not output by the tool). The relationbetween define_bypass and define_insn_reservation can refer to 9.5.7.3rd Loop of Processing Decls – DECL_BYPASS.
1 static int
2 internal_insn_latency (intinsn_code ATTRIBUTE_UNUSED,
3 int insn2_code ATTRIBUTE_UNUSED,
4 rtx insn ATTRIBUTE_UNUSED,
5 rtx insn2 ATTRIBUTE_UNUSED)
6 {
7 staticconst unsigned char default_latencies[] =
8 {
9 `default_latency` // default latency defined by insn reserv pattern
10 }
11
12 if (insn_code > DFA__ADVANCE_CYCLE ||insn2_code > DFA__ADVANCE_CYCLE)
13 return 0;
14 switch (insn_code)
15 {
16 case `insn_num`:
17 switch (insn2_code)
18 {
19 case `bypass1-insn-num`: // insn num of in_insn_reserv of bypass
20 return `bypass1-latency`; // latency defined by bypass
21 case `bypass2-insn-num`:
22 if (`bypass2-guard (insn, insn2)) // if guard is define in bypass
23 return `bypass2-latency;
24 … // other bypass
25 }
26 break;
27 }
28 return default_latency [insn_code];
29 }
internal_insn_latency is a helper function. We need an interface accepts twoinstructions, one is the candidate and the other is executing, and returns thelatency between these two instructions. It is the output insn_latency.
8751 static void
8752 output_insn_latency_func (void) ingenautomata.c
8753 {
8754 fprintf (output_file, "int\n%s (rtx %s, rtx%s)\n",
8755 INSN_LATENCY_FUNC_NAME,INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8756 fprintf (output_file, "{\n int %s, %s;\n",
8757 INTERNAL_INSN_CODE_NAME,INTERNAL_INSN2_CODE_NAME);
8758 output_internal_insn_code_evaluation(INSN_PARAMETER_NAME,
8759 INTERNAL_INSN_CODE_NAME, 0);
8760 output_internal_insn_code_evaluation(INSN2_PARAMETER_NAME,
8761 INTERNAL_INSN2_CODE_NAME,0);
8762 fprintf (output_file, " return %s (%s, %s, %s, %s);\n}\n\n",
8763 INTERNAL_INSN_LATENCY_FUNC_NAME,
8764 INTERNAL_INSN_CODE_NAME,INTERNAL_INSN2_CODE_NAME,
8765 INSN_PARAMETER_NAME,INSN2_PARAMETER_NAME);
8766 }
The output insn_latency has following definition.
1 int
2 insn_latency (rtx insn, rtx insn2)
3 {
4 int insn_code, insn2_code;
5 if (insn!= 0)
6 {
7 insn_code = dfa_insn_code (insn);
8 if(insn_code > DFA__ADVANCE_CYCLE)
9 return 0;
10 }
11 else
12 insn_code = DFA__ADVANCE_CYCLE;
13
14 if (insn2 != 0)
15 {
16 insn2_code = dfa_insn_code(insn2);
17 if (insn2_code > DFA__ADVANCE_CYCLE)
18 return 0;
19 }
20 else
21 insn2_code = DFA__ADVANCE_CYCLE;
22
23 return internal_insn_latency(insn_code, insn2_code, insn, insn2));
24 }
print_reservation is just for debugging/information purpose.
8769 static void
8770 output_print_reservation_func (void) ingenautomata.c
8771 {
8772 decl_t decl;
8773 int i, j;
8774
8775 fprintf (output_file,
8776 "void\n%s (FILE *%s, rtx %s ATTRIBUTE_UNUSED)\n{\n",
8777 PRINT_RESERVATION_FUNC_NAME,FILE_PARAMETER_NAME,
8778 INSN_PARAMETER_NAME);
8779
8780 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num== 0)
8781 {
8782 fprintf (output_file, " fputs (\"%s\", %s);\n}\n\n",
8783 NOTHING_NAME, FILE_PARAMETER_NAME);
8784 return;
8785 }
8786
8787
8788 fputs (" static const char *const reservation_names[] =\n {",
8789 output_file);
8790
8791 for (i = 0, j= 0; i < description->decls_num;i++)
8792 {
8793 decl = description->decls [i];
8794 if (decl->mode == dm_insn_reserv&& decl != advance_cycle_insn_decl)
8795 {
8796 if (j++ != DECL_INSN_RESERV(decl)->insn_num)
8797 abort ();
8798 fprintf (output_file, "\n \"%s\",",
8799 regexp_representation(DECL_INSN_RESERV (decl)->regexp));
8800 finish_regexp_representation ();
8801 }
8802 }
8803 if (j != DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num)
8804 abort ();
8805
8806 fprintf (output_file, "\n \"%s\"\n };\n int %s;\n\n",
8807 NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
8808
8809 fprintf (output_file, " if (%s == 0)\n %s = %s;\n",
8810 INSN_PARAMETER_NAME,
8811 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8812 fprintf (output_file, " else\n\
8813 {\n\
8814 %s = %s (%s);\n\
8815 if (%s > %s)\n\
8816 %s = %s;\n\
8817 }\n",
8818 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8819 INSN_PARAMETER_NAME,
8820 INTERNAL_INSN_CODE_NAME,ADVANCE_CYCLE_VALUE_NAME,
8821 INTERNAL_INSN_CODE_NAME,ADVANCE_CYCLE_VALUE_NAME);
8822
8823 fprintf (output_file, " fputs (reservation_names[%s],%s);\n}\n\n",
8824 INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME);
8825 }
At line 8799, regexp_representation does the dirty job.
6979 static const char *
6980 regexp_representation (regexp_t regexp) ingenautomata.c
6981 {
6982 form_regexp(regexp);
6983 obstack_1grow (&irp, '\0');
6984 returnobstack_base (&irp);
6985 }
6907 static void
6908 form_regexp (regexp_tregexp) ingenautomata.c
6909 {
6910 int i;
6911
6912 if (regexp->mode == rm_unit ||regexp->mode == rm_reserv)
6913 {
6914 const char *name = (regexp->mode ==rm_unit
6915 ? REGEXP_UNIT(regexp)->name
6916 : REGEXP_RESERV(regexp)->name);
6917
6918 obstack_grow (&irp, name, strlen (name));
6919 }
6920 else if (regexp->mode == rm_sequence)
6921 for (i = 0; i < REGEXP_SEQUENCE(regexp)->regexps_num; i++)
6922 {
6923 if (i != 0)
6924 obstack_1grow (&irp,',');
6925 form_regexp(REGEXP_SEQUENCE (regexp)->regexps [i]);
6926 }
6927 else if (regexp->mode == rm_allof)
6928 {
6929 obstack_1grow (&irp, '(');
6930 for (i = 0; i < REGEXP_ALLOF(regexp)->regexps_num; i++)
6931 {
6932 if (i != 0)
6933 obstack_1grow (&irp,'+');
6934 if (REGEXP_ALLOF(regexp)->regexps[i]->mode == rm_sequence
6935 || REGEXP_ALLOF(regexp)->regexps[i]->mode == rm_oneof)
6936 obstack_1grow (&irp,'(');
6937 form_regexp(REGEXP_ALLOF (regexp)->regexps [i]);
6938 if (REGEXP_ALLOF(regexp)->regexps[i]->mode == rm_sequence
6939 || REGEXP_ALLOF(regexp)->regexps[i]->mode == rm_oneof)
6940 obstack_1grow (&irp,')');
6941 }
6942 obstack_1grow (&irp, ')');
6943 }
6944 else if (regexp->mode == rm_oneof)
6945 for (i = 0; i < REGEXP_ONEOF(regexp)->regexps_num; i++)
6946 {
6947 if (i != 0)
6948 obstack_1grow (&irp,'|');
6949 if (REGEXP_ONEOF(regexp)->regexps[i]->mode == rm_sequence)
6950 obstack_1grow (&irp,'(');
6951 form_regexp(REGEXP_ONEOF (regexp)->regexps [i]);
6952 if (REGEXP_ONEOF(regexp)->regexps[i]->mode == rm_sequence)
6953 obstack_1grow (&irp,')');
6954 }
6955 else if (regexp->mode == rm_repeat)
6956 {
6957 char digits [30];
6958
6959 if (REGEXP_REPEAT(regexp)->regexp->mode == rm_sequence
6960 || REGEXP_REPEAT (regexp)->regexp->mode== rm_allof
6961 || REGEXP_REPEAT(regexp)->regexp->mode == rm_oneof)
6962 obstack_1grow (&irp, '(');
6963 form_regexp(REGEXP_REPEAT (regexp)->regexp);
6964 if (REGEXP_REPEAT (regexp)->regexp->mode== rm_sequence
6965 || REGEXP_REPEAT(regexp)->regexp->mode == rm_allof
6966 || REGEXP_REPEAT(regexp)->regexp->mode == rm_oneof)
6967 obstack_1grow (&irp, ')');
6968 sprintf (digits, "*%d",REGEXP_REPEAT (regexp)->repeat_num);
6969 obstack_grow (&irp, digits, strlen (digits));
6970 }
6971 else if (regexp->mode == rm_nothing)
6972 obstack_grow (&irp, NOTHING_NAME, strlen(NOTHING_NAME));
6973 else
6974 abort ();
6975 }
Obvioulsy, form_regexp justs put the regexpinto its original form (not exactly maybe, with extra parenthesises removed)which is given in define_insn_reservation pattern (content in red belwo is not output by the tool).
1 void
2 print_reservation (FILE*f, rtx insn ATTRIBUTE_UNUSED)
3 {
4 staticconst char *const reservation_names[] =
5 {
6 `regexp` // in original readable form
7 nothing
8 };
9 intinsn_code;
10
11 if (insn == 0)
12 insn_code = DFA__ADVANCE_CYCLE;
13 else
14 {
15 insn_code = dfa_insn_code(insn);
16 if (insn_code > DFA__ADVANCE_CYCLE)
17 insn_code = DFA__ADVANCE_CYCLE;
18 }
19 fputs (reservation_names [insn_code], f);
20 }
These functions are relate with define_query_cpu pattern. We omitthem here.
dfa_start is the starting function invoked by the scheduler to begin the dryrun of program upon the pseudo chip. Instructions will be re-ordered accordingto the result generated. To finish the dry-run, dfa_finish is invoked torelease resource occupied.
8937 static void
8938 output_dfa_clean_insn_cache_func (void) in genautomata.c
8939 {
8940 fprintf (output_file,
8941 "void\n%s (void)\n{\n int%s;\n\n",
8942 DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME);
8943 fprintf (output_file,
8944 " for (%s = 0; %s < %s;%s++)\n %s [%s] = -1;\n}\n\n",
8945 I_VARIABLE_NAME, I_VARIABLE_NAME,
8946 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
8947 DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
8948 }
1 void
2 dfa_clean_insn_cache (void)
3 {
4 int i;
5
6 for (i =0; i < dfa_insn_codes_length; i++)
7 dfa_insn_codes [i] = -1;
8 }
8951 static void
8952 output_dfa_start_func (void) in genautomata.c
8953 {
8954 fprintf (output_file,
8955 "void\n%s (void)\n{\n %s = get_max_uid ();\n",
8956 DFA_START_FUNC_NAME,DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8957 fprintf (output_file, " %s = xmalloc (%s * sizeof (int));\n",
8958 DFA_INSN_CODES_VARIABLE_NAME,DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8959 fprintf (output_file, " %s ();\n}\n\n",DFA_CLEAN_INSN_CACHE_FUNC_NAME);
8960 }
1 void
2 dfa_start (void)
3 {
4 dfa_insn_codes_length= get_max_uid ();
5 dfa_insn_codes= xmalloc (dfa_insn_codes_length * sizeof (int));
6 dfa_clean_insn_cache ();
7 }
8963 static void
8964 output_dfa_finish_func (void) ingenautomata.c
8965 {
8966 fprintf (output_file, "void\n%s (void)\n{\n free (%s);\n}\n\n",
8967 DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8968 }
1 void
2 dfa_finish (void)
3 {
4 free (dfa_insn_codes);
5 }
Rest code of write_automata is for purpose of statistics,debug, informative. We skip it as it is not related to our intention.
write_automata (continued)
9919 if (progress_flag)
9920 fprintf (stderr, "done\n");
9921 if (v_flag)
9922 {
9923 output_description_file = fopen (output_description_file_name,"w");
9924 if (output_description_file == NULL)
9925 {
9926 perror (output_description_file_name);
9927 exit (FATAL_EXIT_CODE);
9928 }
9929 if (progress_flag)
9930 fprintf (stderr, "Output automatadescription...");
9931 output_description ();
9932 output_automaton_descriptions ();
9933 if (progress_flag)
9934 fprintf (stderr, "done\n");
9935 output_statistics (output_description_file);
9936 }
9937 output_statistics (stderr);
9938 ticker_off (&output_time);
9939 output_time_statistics (stderr);
9940 finish_states ();
9941 finish_arcs ();
9942 finish_automata_lists ();
9943 if (time_flag)
9944 {
9945 fprintf (stderr, "Summary:\n");
9946 fprintf (stderr, " check time ");
9947 print_active_time (stderr, check_time);
9948 fprintf (stderr, ", generation time");
9949 print_active_time (stderr, generation_time);
9950 fprintf (stderr, ", all time ");
9951 print_active_time (stderr, all_time);
9952 fprintf (stderr, "\n");
9953 }
9954 /* Finish allwork. */
9955 if (output_description_file != NULL)
9956 {
9957 fflush (output_description_file);
9958 if (ferror (stdout) != 0)
9959 fatal ("Error in writing DFA descriptionfile %s",
9960 output_description_file_name);
9961 fclose (output_description_file);
9962 }
9963 finish_automaton_decl_table ();
9964 finish_insn_decl_table ();
9965 finish_decl_table ();
9966 obstack_free (&irp, NULL);
9967 if (have_error && output_description_file!= NULL)
9968 remove (output_description_file_name);
9969 }
main (continued)
6233 /* Write outconstant delay slot info. */
6234 write_const_num_delay_slots();
6235
6236 write_length_unit_log ();
6237
6238 fflush (stdout);
6239 return(ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
6240 }
Delay slot scheduling differs from instruction scheduling in thatdetermining whether an instruction needs a delay slot is dependent only on thetype of instruction being generated, not on data flow between the instructions(detail refer to 8.1.1 Overview of DEFINE_DELAYpattern). Now the information of the delay slots have been saved intoattribute *num_delay_slots, and the function num_delay_slots fetchingthis attribute has been output in section 9.6.1.4Output attributes.
Quite often, the number of delay slots is not a function of thelength of the instruction. const_num_delay_slots tellsout these instructions.
5955 static void
5956 write_const_num_delay_slots (void) in genattrtab.c
5957 {
5958 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
5959 struct attr_value *av;
5960 struct insn_ent *ie;
5961
5962 if (attr)
5963 {
5964 printf ("int\nconst_num_delay_slots(rtx insn)\n");
5965 printf ("{\n");
5966 printf (" switch (recog_memoized (insn))\n");
5967 printf (" {\n");
5968
5969 for (av =attr->first_value; av; av = av->next)
5970 {
5971 length_used = 0;
5972 walk_attr_value(av->value);
5973 if (length_used)
5974 {
5975 for (ie= av->first_insn; ie; ie = ie->next)
5976 if (ie->insn_code != -1)
5977 printf (" case %d:\n", ie->insn_code);
5978 printf (" return 0;\n");
5979 }
5980 }
5981
5982 printf (" default:\n");
5983 printf (" return 1;\n");
5984 printf (" }\n}\n\n");
5985 }
5986 }
length_used is set if attribute of “length” used as condition to filter out thetarget instruction.