9.6.4.1.3. Outputtable(s) for state alternatives
In 9.5.8 Automata generation,it is possible that instruction of different equivalent class can trigger thesame state transition from certain states. These instructions are defined asstate alternatives. To minimize the size of automaton, tegother withtransforming NDFA to DFA, these states will be combined into a compound state,and field state_altsrecords the number of these states. The table and function state alternativesrelated are debugging purpose.
7779 static void
7780 output_state_alts_table (automaton_t automaton) ingenautomata.c
7781 {
7782 state_t *state_ptr;
7783 arc_t arc;
7784 vla_hwint_t state_alts_vect;
7785
7786 undefined_vect_el_value = 0; /* no alts when transition is not possible */
7787 automaton->state_alts_table = create_state_ainsn_table (automaton);
7788 /* Create vect ofpointers to states ordered by num of transitions
7789 from the state (state with the maximum numis the first). */
7790 VLA_PTR_CREATE (output_states_vect, 1500,"output states vector");
7791 pass_states(automaton, add_states_vect_el);
7792 qsort (VLA_PTR_BEGIN (output_states_vect),
7793 VLA_PTR_LENGTH (output_states_vect),
7794 sizeof (state_t), compare_transition_els_num);
7795 /* Create base,comb, and check vectors. */
7796 VLA_HWINT_CREATE (state_alts_vect, 500,"state alts vector");
7797 for(state_ptr = VLA_PTR_BEGIN (output_states_vect);
7798 state_ptr <= (state_t*) VLA_PTR_LAST (output_states_vect);
7799 state_ptr++)
7800 {
7801 VLA_HWINT_NULLIFY (state_alts_vect);
7802 for (arc = first_out_arc (*state_ptr);
7803 arc != NULL;
7804 arc = next_out_arc (arc))
7805 {
7806 if (arc->insn == NULL)
7807 abort ();
7808 if(arc->insn->first_ainsn_with_given_equialence_num)
7809 add_vect_el(&state_alts_vect, arc->insn, arc->state_alts);
7810 }
7811 add_vect(automaton->state_alts_table, (*state_ptr)->order_state_num,
7812 VLA_HWINT_BEGIN (state_alts_vect),
7813 VLA_HWINT_LENGTH(state_alts_vect));
7814 }
7816 (automaton->state_alts_table, (char *)"state insn alternatives",
7817 output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
7818 output_state_alts_check_vect_name, output_state_alts_base_vect_name);
7819 VLA_PTR_DELETE (output_states_vect);
7820 VLA_HWINT_DELETE (state_alts_vect);
7821 }
At line 7809, state_alts records the number of alternativereservations which can be used for transition from given state by giveninstruction. The handling of state_alts is very similar with that of asinsnwe have seen previous. Then after outputting code for state_alts, we get following, assumingthis timefull_vect in state_ainsn_table is used, and we have lessthan 2568256 (256*256) effective states.
/*Vector translating external insn codes to internal ones.*/
static const unsigned char translate_0 []ATTRIBUTE_UNUSED = {
`equivalent class number` //indescription order
};
/*Comb vector for state transitions */
staticconst unsigned char transitions_0 [] ATTRIBUTE_UNUSED = {
`content of comb_vect` //for ainsn, referto add_vect
};
/*Check vector for state transitions */
staticconst unsigned char check_0 [] ATTRIBUTE_UNUSED = {
`content of check_vect` //for ainsn, refer to add_vect
};
/* Basevector for state transitions */
staticconst unsigned char base_0 [] ATTRIBUTE_UNUSED = {
`content of base_vect` //for ainsn, referto add_vect
};
#if AUTOMATON_STATE_ALTS
/* Vector for state insn alternatives */
staticconst unsigned short state_alts_0 [] ATTRIBUTE_UNUSED = {
`content of full_vect` // forstate_alts, refer to add_vect
};
#endif
9.6.4.1.4. Outputtable for issue delay
To issue instruction with efficiency, we must know the issue delayamong instructions upon certain function unit. In define_function_unit pattern,the issue delay is encoded into the pattern declaration. However, for theautomaton based description, during the generation, we have built all statesand bound them with instruction associated. By traversing the states, we cancollect information for issue delay instead needing encoded into thedeclaration. Obviously, this way is more flexible and powerful.
Here is the function.
7892 static void
7893 output_min_issue_delay_table (automaton_t automaton) ingenautomata.c
7894 {
7895 vla_hwint_t min_issue_delay_vect;
7896 vla_hwint_t compressed_min_issue_delay_vect;
7897 vect_el_t min_delay;
7898 ainsn_t ainsn;
7899 state_t *state_ptr;
7900 int i;
7901
7902 /* Create vect ofpointers to states ordered by num of transitions
7903 from the state (state with the maximum numis the first). */
7904 VLA_PTR_CREATE (output_states_vect, 1500,"output states vector");
7905 pass_states(automaton, add_states_vect_el);
7906 VLA_HWINT_CREATE (min_issue_delay_vect, 1500,"min issue delay vector");
7907 VLA_HWINT_EXPAND (min_issue_delay_vect,
7908 VLA_HWINT_LENGTH (output_states_vect)
7909 *automaton->insn_equiv_classes_num);
7910 for (i = 0;
7911 i < ((int) VLA_HWINT_LENGTH (output_states_vect)
7912 *automaton->insn_equiv_classes_num);
7913 i++)
7914 VLA_HWINT (min_issue_delay_vect, i) = 0;
7915 automaton->max_min_delay = 0;
7916 for (ainsn =automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7917 if(ainsn->first_ainsn_with_given_equialence_num)
7918 {
7919 for (state_ptr =VLA_PTR_BEGIN (output_states_vect);
7920 state_ptr <= (state_t*) VLA_PTR_LAST (output_states_vect);
7921 state_ptr++)
7922 (*state_ptr)->min_insn_issue_delay =-1;
7923 for (state_ptr =VLA_PTR_BEGIN (output_states_vect);
7924 state_ptr <= (state_t*) VLA_PTR_LAST (output_states_vect);
7925 state_ptr++)
7926 {
7927 min_delay = min_issue_delay(*state_ptr, ainsn);
7928 if (automaton->max_min_delay <min_delay)
7929 automaton->max_min_delay =min_delay;
7930 VLA_HWINT (min_issue_delay_vect,
7931 (*state_ptr)->order_state_num
7932 *automaton->insn_equiv_classes_num
7933 +ainsn->insn_equiv_class_num) = min_delay;
7934 }
7935 }
7936 fprintf (output_file, "/* Vector of min issue delayof insns. */\n");
7937 fprintf (output_file, "static const ");
7938 output_range_type(output_file,0, automaton->max_min_delay);
7939 fprintf (output_file, " ");
7940 output_min_issue_delay_vect_name (output_file,automaton);
7941 fprintf (output_file, "[] ATTRIBUTE_UNUSED ={\n");
7942 /* Compress thevector. */
7943 if (automaton->max_min_delay < 2)
7944 automaton->min_issue_delay_table_compression_factor = 8;
7945 else if (automaton->max_min_delay < 4)
7946 automaton->min_issue_delay_table_compression_factor= 4;
7947 else if (automaton->max_min_delay < 16)
7948 automaton->min_issue_delay_table_compression_factor = 2;
7949 else
7950 automaton->min_issue_delay_table_compression_factor = 1;
7951 VLA_HWINT_CREATE (compressed_min_issue_delay_vect,1500,
7952 "compressed minissue delay vector");
7953 VLA_HWINT_EXPAND(compressed_min_issue_delay_vect,
7954 (VLA_HWINT_LENGTH(min_issue_delay_vect)
7955 + automaton->min_issue_delay_table_compression_factor
7956 - 1)
7957 /automaton->min_issue_delay_table_compression_factor);
7958 for (i = 0;
7959 i < (int) VLA_HWINT_LENGTH(compressed_min_issue_delay_vect);
7960 i++)
7961 VLA_HWINT (compressed_min_issue_delay_vect,i) = 0;
7962 for (i = 0; i< (int) VLA_HWINT_LENGTH (min_issue_delay_vect); i++)
7963 VLA_HWINT (compressed_min_issue_delay_vect,
7964 i / automaton->min_issue_delay_table_compression_factor)
7965 |= (VLA_HWINT(min_issue_delay_vect, i)
7966 << (8 - (i %automaton->min_issue_delay_table_compression_factor
7967 + 1)
7968 * (8 / automaton->min_issue_delay_table_compression_factor)));
7969 output_vect(VLA_HWINT_BEGIN (compressed_min_issue_delay_vect),
7970 VLA_HWINT_LENGTH(compressed_min_issue_delay_vect));
7971 fprintf (output_file, "};\n\n");
7972 VLA_PTR_DELETE (output_states_vect);
7973 VLA_HWINT_DELETE (min_issue_delay_vect);
7974 VLA_HWINT_DELETE(compressed_min_issue_delay_vect);
7975 }
As we know instructions are grouped according to the resourcereserved, and only the first instruction found in one group, has field first_ainsn_with_given_equialence_numbeen set. For instructions belong to same equivalent class, their can be issuedfrom the same states, that is if one of them can be issued from certain state,so the other.
Then FOR loop at line7916, tries to find out the minimum issue delays to specified state amonginstruction groups.
7873 static int
7874 min_issue_delay (state_tstate, ainsn_t ainsn) ingenautomata.c
7875 {
7876 curr_state_pass_num++;
7877 state->min_insn_issue_delay = min_issue_delay_pass_states (state,ainsn);
7878 returnstate->min_insn_issue_delay;
7879 }
See parameter state firstly has min_insn_issue_delay set as -1 toprevent muliple process.
7831 static int
7832 min_issue_delay_pass_states (state_t state, ainsn_t ainsn)
7833 {
7834 arc_t arc;
7835 int min_insn_issue_delay, insn_issue_delay;
7836
7837 if (state->state_pass_num == curr_state_pass_num
7838 || state->min_insn_issue_delay != -1)
7839 /* We've enteredinto a loop or already have the correct value for
7840 given state and ainsn. */
7841 returnstate->min_insn_issue_delay;
7842 state->state_pass_num = curr_state_pass_num;
7843 min_insn_issue_delay = -1;
7844 for (arc =first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7845 if (arc->insn == ainsn)
7846 {
7847 min_insn_issue_delay = 0;
7848 break;
7849 }
7850 else
7851 {
7852 insn_issue_delay = min_issue_delay_pass_states(arc->to_state, ainsn);
7853 if (insn_issue_delay != -1)
7854 {
7855 if (arc->insn->insn_reserv_decl
7856 == DECL_INSN_RESERV (advance_cycle_insn_decl))
7857 insn_issue_delay++;
7858 if (min_insn_issue_delay == -1
7859 || min_insn_issue_delay >insn_issue_delay)
7860 {
7861 min_insn_issue_delay = insn_issue_delay;
7862 if (insn_issue_delay == 0)
7863 break;
7864 }
7865 }
7866 }
7867 returnmin_insn_issue_delay;
7868 }
At line 7847, the function is recursed until the target instructionis found, then during returning from the nested invocation, every advance_cycle_insn_declencountered causes the delay increased. Notice that other instructions in thesame group except the first one have no effect on the searching, they willalways return -1.
Back to output_min_issue_delay_table,at line 7929, max_min_delayrecords the max value of the whole states set. According to this value we cancompress the vector of issue delay by saving several values teogther into adata of int type.
Then we get output code as following (content in red is not output by tool).
/* Vector translating external insn codes tointernal ones.*/
static const unsigned char translate_0 []ATTRIBUTE_UNUSED = {
`equivalent class number` // descriptionorder
};
/*Comb vector for state transitions */
staticconst unsigned char transitions_0 [] ATTRIBUTE_UNUSED = {
`content of comb_vect` // for ainsn,refer to add_vect
};
/*Check vector for state transitions */
static constunsigned char check_0 [] ATTRIBUTE_UNUSED = {
`content of check_vect` // for ainsn, refer to add_vect
};
/* Basevector for state transitions */
staticconst unsigned char base_0 [] ATTRIBUTE_UNUSED = {
`content of base_vect` //for ainsn, referto add_vect
};
#if AUTOMATON_STATE_ALTS
/* Vector for state insn alternatives */
staticconst unsigned short state_alts_0 [] ATTRIBUTE_UNUSED = {
`content of full_vect` // forstate_alts, refer to add_vect
};
#endif
/* Vector of min issue delay of insns. */
staticconst unsigned char min_issue_delay_0 = []ATTRIBUTE_UNUSED = {
`content of compressed_min_issue_delay_vect` // refer to output_min_issue_delay_table
};
9.6.4.1.5. Outputtable for locked states
There may be states that no other instruction can be issued except advance_cycle_insn_decl– that is CPU heading for next cycle. output_dead_lock_vectfinds out these states and create table for them. At line 8007 ~8009, see the judgmentof these states.
7985 static void
7986 output_dead_lock_vect (automaton_t automaton) ingenautomata.c
7987 {
7988 state_t *state_ptr;
7989 arc_t arc;
7990 vla_hwint_t dead_lock_vect;
7991
7992 /* Create vect ofpointers to states ordered by num of
7993 transitions from the state (state with themaximum num is the
7994 first). */
7995 VLA_PTR_CREATE (output_states_vect, 1500,"output states vector");
7996 pass_states(automaton, add_states_vect_el);
7997 VLA_HWINT_CREATE (dead_lock_vect, 1500,"is dead locked vector");
7998 VLA_HWINT_EXPAND (dead_lock_vect,VLA_HWINT_LENGTH (output_states_vect));
7999 for(state_ptr = VLA_PTR_BEGIN (output_states_vect);
8000 state_ptr <= (state_t*) VLA_PTR_LAST (output_states_vect);
8001 state_ptr++)
8002 {
8003 arc = first_out_arc (*state_ptr);
8004 if (arc == NULL)
8005 abort ();
8006 VLA_HWINT (dead_lock_vect,(*state_ptr)->order_state_num)
8007 = (next_out_arc (arc) == NULL
8008 &&(arc->insn->insn_reserv_decl
8009 == DECL_INSN_RESERV (advance_cycle_insn_decl))? 1 : 0);
8010 #ifndef NDEBUG
8011 if (VLA_HWINT (dead_lock_vect,(*state_ptr)->order_state_num))
8012 locked_states_num++;
8013 #endif
8014 }
8015 fprintf (output_file, "/* Vector for locked stateflags. */\n");
8016 fprintf (output_file, "static const ");
8017 output_range_type(output_file,0, 1);
8018 fprintf (output_file, " ");
8019 output_dead_lock_vect_name (output_file,automaton);
8020 fprintf (output_file, "[] = {\n");
8021 output_vect(VLA_HWINT_BEGIN (dead_lock_vect),
8022 VLA_HWINT_LENGTH (dead_lock_vect));
8023 fprintf (output_file, "};\n\n");
8024 VLA_HWINT_DELETE (dead_lock_vect);
8025 VLA_PTR_DELETE (output_states_vect);
8026 }
From line 8009 above, we can see that the content of dead_lock_vectis only 1 or 0, with 1 indicates no meaningful instruction can be issued, with0 vice versa.
Then output_tableswill output table for define_query_cpu_unit. We omit it here. However, theproducing very resembles that of other tables. Now in output file we getfollowing (content in red is not output by the tool).And assuming we don’t have the reserved unit for automaton (i.e., nodefine_query_cpu_unit)
/* Vector translating external insn codes tointernal ones.*/
static const unsigned char translate_0 []ATTRIBUTE_UNUSED = {
`equivalent class number` // indescription order
};
/*Comb vector for state transitions */
staticconst unsigned char transitions_0 [] ATTRIBUTE_UNUSED = {
`content of comb_vect` // for ainsn,refer to add_vect
};
/*Check vector for state transitions */
staticconst unsigned char check_0 [] ATTRIBUTE_UNUSED = {
`content of check_vect` // for ainsn, refer to add_vect
};
/* Basevector for state transitions */
staticconst unsigned char base_0 [] ATTRIBUTE_UNUSED = {
`content of base_vect` // for ainsn, referto add_vect
};
#if AUTOMATON_STATE_ALTS
/* Vector for state insn alternatives */
staticconst unsigned short state_alts_0 [] ATTRIBUTE_UNUSED = {
`content of full_vect` // forstate_alts, refer to add_vect
};
#endif
/* Vector of min issue delay of insns. */
staticconst unsigned char min_issue_delay_0 = []ATTRIBUTE_UNUSED = {
`content of compressed_min_issue_delay_vect` // refer to output_min_issue_delay_table
};
/* Vector for locked state flags. */
staticconst unsigned char dead_lock_0 = []ATTRIBUTE_UNUSED = {
`content of dead_lock_vect` // refer to output_dead_lock_vect
}