diff options
author | matz <matz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-21 17:27:56 +0000 |
---|---|---|
committer | matz <matz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-21 17:27:56 +0000 |
commit | c72f0286a78e0b6b4d2a1663933612dcf970f980 (patch) | |
tree | 1658aad3a2b53d9f3b50fbf5308eb57a90459789 /gcc/genautomata.c | |
parent | 2f2c591f241c00a0d962363cdd5671fe99e21ec6 (diff) | |
download | gcc-c72f0286a78e0b6b4d2a1663933612dcf970f980.tar.gz |
* genautomata.c (<struct state>, num_out_arcs, presence_signature):
New members.
(remove_arc, add_arc): Update num_out_arcs member.
(set_out_arc_insns_equiv_num): Returns nothing instead of number
of out arcs.
(cache_presence): New function.
(compare_states_for_equiv): New function.
(state_is_differed): Don't take number of outargs, adjust callers.
Use new invariant for speeding up.
(init_equiv_class): Create initial classes based on sorted
input.
(partition_equiv_class): Don't track out_arcs_num.
(evaluate_equiv_classes): Call cache_presence on all states and
sort them.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@112252 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/genautomata.c')
-rw-r--r-- | gcc/genautomata.c | 133 |
1 files changed, 95 insertions, 38 deletions
diff --git a/gcc/genautomata.c b/gcc/genautomata.c index eb06e6ccff8..fd8edebcea8 100644 --- a/gcc/genautomata.c +++ b/gcc/genautomata.c @@ -677,6 +677,7 @@ struct state /* The following field value is the first arc output from given state. */ arc_t first_out_arc; + unsigned int num_out_arcs; /* The following field is used to form NDFA. */ char it_was_placed_in_stack_for_NDFA_forming; /* The following field is used to form DFA. */ @@ -700,6 +701,7 @@ struct state automaton. The field value is state corresponding to equivalence class to which given state belongs. */ state_t equiv_class_state; + unsigned int *presence_signature; /* The following field value is the order number of given state. The states in final DFA is enumerated with the aid of the following field. */ @@ -3862,6 +3864,7 @@ remove_arc (state_t from_state, arc_t arc) from_state->first_out_arc = arc->next_out_arc; else prev_arc->next_out_arc = arc->next_out_arc; + from_state->num_out_arcs--; free_arc (arc); } @@ -3908,6 +3911,7 @@ add_arc (state_t from_state, state_t to_state, ainsn_t ainsn) ainsn->arc_exists_p = 1; new_arc->next_out_arc = from_state->first_out_arc; from_state->first_out_arc = new_arc; + from_state->num_out_arcs++; new_arc->next_arc_marked_by_insn = NULL; return new_arc; } @@ -5614,24 +5618,20 @@ add_achieved_state (state_t state) out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has nonzero value) or by equiv_class_num_2 of the destination state. The function returns number of out arcs of STATE. */ -static int +static void set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag) { - int state_out_arcs_num; arc_t arc; - state_out_arcs_num = 0; for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc)) { gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num); - state_out_arcs_num++; arc->insn->insn_reserv_decl->equiv_class_num = (odd_iteration_flag ? arc->to_state->equiv_class_num_1 : arc->to_state->equiv_class_num_2); gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num); } - return state_out_arcs_num; } /* The function clears equivalence numbers and alt_states in all insns @@ -5666,6 +5666,26 @@ first_cycle_unit_presence (state_t state, int unit_num) return false; } +/* This fills in the presence_signature[] member of STATE. */ +static void +cache_presence (state_t state) +{ + int i, num = 0; + unsigned int sz; + sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1) + / (sizeof (int) * CHAR_BIT); + + state->presence_signature = create_node (sz * sizeof (int)); + for (i = 0; i < description->units_num; i++) + if (units_array [i]->query_p) + { + int presence1_p = first_cycle_unit_presence (state, i); + state->presence_signature[num / (sizeof (int) * CHAR_BIT)] + |= (!!presence1_p) << (num % (sizeof (int) * CHAR_BIT)); + num++; + } +} + /* The function returns nonzero value if STATE is not equivalent to ANOTHER_STATE from the same current partition on equivalence classes. Another state has ANOTHER_STATE_OUT_ARCS_NUM number of @@ -5673,52 +5693,89 @@ first_cycle_unit_presence (state_t state, int unit_num) by ODD_ITERATION_FLAG. */ static int state_is_differed (state_t state, state_t another_state, - int another_state_out_arcs_num, int odd_iteration_flag) + int odd_iteration_flag) { arc_t arc; - int state_out_arcs_num; - int i, presence1_p, presence2_p; + unsigned int sz, si; + + gcc_assert (state->num_out_arcs == another_state->num_out_arcs); + + sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1) + / (sizeof (int) * CHAR_BIT); + + for (si = 0; si < sz; si++) + gcc_assert (state->presence_signature[si] + == another_state->presence_signature[si]); - state_out_arcs_num = 0; for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc)) { - state_out_arcs_num++; if ((odd_iteration_flag ? arc->to_state->equiv_class_num_1 : arc->to_state->equiv_class_num_2) != arc->insn->insn_reserv_decl->equiv_class_num) return 1; } - if (state_out_arcs_num != another_state_out_arcs_num) + + return 0; +} + +/* Compares two states pointed to by STATE_PTR_1 and STATE_PTR_2 + and return -1, 0 or 1. This function can be used as predicate for + qsort(). It requires the member presence_signature[] of both + states be filled. */ +static int +compare_states_for_equiv (const void *state_ptr_1, + const void *state_ptr_2) +{ + state_t s1 = *(state_t *)state_ptr_1; + state_t s2 = *(state_t *)state_ptr_2; + unsigned int sz, si; + if (s1->num_out_arcs < s2->num_out_arcs) + return -1; + else if (s1->num_out_arcs > s2->num_out_arcs) return 1; - /* Now we are looking at the states with the point of view of query - units. */ - for (i = 0; i < description->units_num; i++) - if (units_array [i]->query_p) - { - presence1_p = first_cycle_unit_presence (state, i); - presence2_p = first_cycle_unit_presence (another_state, i); - if ((presence1_p && !presence2_p) || (!presence1_p && presence2_p)) - return 1; - } + + sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1) + / (sizeof (int) * CHAR_BIT); + + for (si = 0; si < sz; si++) + if (s1->presence_signature[si] < s2->presence_signature[si]) + return -1; + else if (s1->presence_signature[si] > s2->presence_signature[si]) + return 1; return 0; } /* The function makes initial partition of STATES on equivalent - classes. */ -static state_t -init_equiv_class (VEC(state_t,heap) *states) + classes and saves it into *CLASSES. This function requires the input + to be sorted via compare_states_for_equiv(). */ +static int +init_equiv_class (VEC(state_t,heap) *states, VEC (state_t,heap) **classes) { size_t i; state_t prev = 0; + int class_num = 1; + *classes = VEC_alloc (state_t,heap, 150); for (i = 0; i < VEC_length (state_t, states); i++) { - VEC_index (state_t, states, i)->equiv_class_num_1 = 1; - VEC_index (state_t, states, i)->next_equiv_class_state = prev; - prev = VEC_index (state_t, states, i); + state_t state = VEC_index (state_t, states, i); + if (prev) + { + if (compare_states_for_equiv (&prev, &state) != 0) + { + VEC_safe_push (state_t,heap, *classes, prev); + class_num++; + prev = NULL; + } + } + state->equiv_class_num_1 = class_num; + state->next_equiv_class_state = prev; + prev = state; } - return prev; + if (prev) + VEC_safe_push (state_t,heap, *classes, prev); + return class_num; } /* The function copies pointers to equivalent states from vla FROM @@ -5729,6 +5786,7 @@ copy_equiv_class (VEC(state_t,heap) **to, VEC(state_t,heap) *from) VEC_free (state_t,heap, *to); *to = VEC_copy (state_t,heap, from); } + /* The function processes equivalence class given by its first state, FIRST_STATE, on odd iteration if ODD_ITERATION_FLAG. If there are not equivalent states, the function partitions the class @@ -5746,7 +5804,6 @@ partition_equiv_class (state_t first_state, int odd_iteration_flag, state_t curr_state; state_t prev_state; state_t next_state; - int out_arcs_num; partition_p = 0; @@ -5756,15 +5813,14 @@ partition_equiv_class (state_t first_state, int odd_iteration_flag, if (first_state->next_equiv_class_state != NULL) { /* There are more one states in the class equivalence. */ - out_arcs_num = set_out_arc_insns_equiv_num (first_state, - odd_iteration_flag); + set_out_arc_insns_equiv_num (first_state, odd_iteration_flag); for (prev_state = first_state, curr_state = first_state->next_equiv_class_state; curr_state != NULL; curr_state = next_state) { next_state = curr_state->next_equiv_class_state; - if (state_is_differed (curr_state, first_state, out_arcs_num, + if (state_is_differed (curr_state, first_state, odd_iteration_flag)) { /* Remove curr state from the class equivalence. */ @@ -5797,7 +5853,6 @@ static void evaluate_equiv_classes (automaton_t automaton, VEC(state_t,heap) **equiv_classes) { - state_t new_equiv_class; int new_equiv_class_num; int odd_iteration_flag; int finish_flag; @@ -5806,12 +5861,14 @@ evaluate_equiv_classes (automaton_t automaton, all_achieved_states = VEC_alloc (state_t,heap, 1500); pass_states (automaton, add_achieved_state); - new_equiv_class = init_equiv_class (all_achieved_states); - odd_iteration_flag = 0; - new_equiv_class_num = 1; + pass_states (automaton, cache_presence); + qsort (VEC_address (state_t, all_achieved_states), + VEC_length (state_t, all_achieved_states), + sizeof (state_t), compare_states_for_equiv); - next_iteration_classes = VEC_alloc (state_t,heap, 150); - VEC_quick_push (state_t, next_iteration_classes, new_equiv_class); + odd_iteration_flag = 0; + new_equiv_class_num = init_equiv_class (all_achieved_states, + &next_iteration_classes); do { |