Commit b6bbd675 by Michael Matz Committed by Michael Matz

genautomata.c (<struct state>, [...]): New members.

	* 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.

From-SVN: r112252
parent fae2b46b
2006-03-21 Michael Matz <matz@suse.de>
* 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.
2006-03-21 Bernd Schmidt <bernd.schmidt@analog.com> 2006-03-21 Bernd Schmidt <bernd.schmidt@analog.com>
* config/bfin/bfin-protos.h (bfin_dsp_memref_p): Declare. * config/bfin/bfin-protos.h (bfin_dsp_memref_p): Declare.
......
...@@ -677,6 +677,7 @@ struct state ...@@ -677,6 +677,7 @@ struct state
/* The following field value is the first arc output from given /* The following field value is the first arc output from given
state. */ state. */
arc_t first_out_arc; arc_t first_out_arc;
unsigned int num_out_arcs;
/* The following field is used to form NDFA. */ /* The following field is used to form NDFA. */
char it_was_placed_in_stack_for_NDFA_forming; char it_was_placed_in_stack_for_NDFA_forming;
/* The following field is used to form DFA. */ /* The following field is used to form DFA. */
...@@ -700,6 +701,7 @@ struct state ...@@ -700,6 +701,7 @@ struct state
automaton. The field value is state corresponding to equivalence automaton. The field value is state corresponding to equivalence
class to which given state belongs. */ class to which given state belongs. */
state_t equiv_class_state; state_t equiv_class_state;
unsigned int *presence_signature;
/* The following field value is the order number of given state. /* The following field value is the order number of given state.
The states in final DFA is enumerated with the aid of the The states in final DFA is enumerated with the aid of the
following field. */ following field. */
...@@ -3862,6 +3864,7 @@ remove_arc (state_t from_state, arc_t arc) ...@@ -3862,6 +3864,7 @@ remove_arc (state_t from_state, arc_t arc)
from_state->first_out_arc = arc->next_out_arc; from_state->first_out_arc = arc->next_out_arc;
else else
prev_arc->next_out_arc = arc->next_out_arc; prev_arc->next_out_arc = arc->next_out_arc;
from_state->num_out_arcs--;
free_arc (arc); free_arc (arc);
} }
...@@ -3908,6 +3911,7 @@ add_arc (state_t from_state, state_t to_state, ainsn_t ainsn) ...@@ -3908,6 +3911,7 @@ add_arc (state_t from_state, state_t to_state, ainsn_t ainsn)
ainsn->arc_exists_p = 1; ainsn->arc_exists_p = 1;
new_arc->next_out_arc = from_state->first_out_arc; new_arc->next_out_arc = from_state->first_out_arc;
from_state->first_out_arc = new_arc; from_state->first_out_arc = new_arc;
from_state->num_out_arcs++;
new_arc->next_arc_marked_by_insn = NULL; new_arc->next_arc_marked_by_insn = NULL;
return new_arc; return new_arc;
} }
...@@ -5614,24 +5618,20 @@ add_achieved_state (state_t state) ...@@ -5614,24 +5618,20 @@ add_achieved_state (state_t state)
out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has 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. nonzero value) or by equiv_class_num_2 of the destination state.
The function returns number of out arcs of 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) set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
{ {
int state_out_arcs_num;
arc_t arc; arc_t arc;
state_out_arcs_num = 0;
for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc)) for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
{ {
gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num); gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num);
state_out_arcs_num++;
arc->insn->insn_reserv_decl->equiv_class_num arc->insn->insn_reserv_decl->equiv_class_num
= (odd_iteration_flag = (odd_iteration_flag
? arc->to_state->equiv_class_num_1 ? arc->to_state->equiv_class_num_1
: arc->to_state->equiv_class_num_2); : arc->to_state->equiv_class_num_2);
gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num); 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 /* 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) ...@@ -5666,6 +5666,26 @@ first_cycle_unit_presence (state_t state, int unit_num)
return false; 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 /* The function returns nonzero value if STATE is not equivalent to
ANOTHER_STATE from the same current partition on equivalence ANOTHER_STATE from the same current partition on equivalence
classes. Another state has ANOTHER_STATE_OUT_ARCS_NUM number of 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) ...@@ -5673,52 +5693,89 @@ first_cycle_unit_presence (state_t state, int unit_num)
by ODD_ITERATION_FLAG. */ by ODD_ITERATION_FLAG. */
static int static int
state_is_differed (state_t state, state_t another_state, 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; arc_t arc;
int state_out_arcs_num; unsigned int sz, si;
int i, presence1_p, presence2_p;
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)) for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
{ {
state_out_arcs_num++;
if ((odd_iteration_flag if ((odd_iteration_flag
? arc->to_state->equiv_class_num_1 ? arc->to_state->equiv_class_num_1
: arc->to_state->equiv_class_num_2) : arc->to_state->equiv_class_num_2)
!= arc->insn->insn_reserv_decl->equiv_class_num) != arc->insn->insn_reserv_decl->equiv_class_num)
return 1; 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; return 1;
/* Now we are looking at the states with the point of view of query
units. */ sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
for (i = 0; i < description->units_num; i++) / (sizeof (int) * CHAR_BIT);
if (units_array [i]->query_p)
{ for (si = 0; si < sz; si++)
presence1_p = first_cycle_unit_presence (state, i); if (s1->presence_signature[si] < s2->presence_signature[si])
presence2_p = first_cycle_unit_presence (another_state, i); return -1;
if ((presence1_p && !presence2_p) || (!presence1_p && presence2_p)) else if (s1->presence_signature[si] > s2->presence_signature[si])
return 1; return 1;
}
return 0; return 0;
} }
/* The function makes initial partition of STATES on equivalent /* The function makes initial partition of STATES on equivalent
classes. */ classes and saves it into *CLASSES. This function requires the input
static state_t to be sorted via compare_states_for_equiv(). */
init_equiv_class (VEC(state_t,heap) *states) static int
init_equiv_class (VEC(state_t,heap) *states, VEC (state_t,heap) **classes)
{ {
size_t i; size_t i;
state_t prev = 0; 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++) for (i = 0; i < VEC_length (state_t, states); i++)
{ {
VEC_index (state_t, states, i)->equiv_class_num_1 = 1; state_t state = VEC_index (state_t, states, i);
VEC_index (state_t, states, i)->next_equiv_class_state = prev; if (prev)
prev = VEC_index (state_t, states, i); {
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 /* 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) ...@@ -5729,6 +5786,7 @@ copy_equiv_class (VEC(state_t,heap) **to, VEC(state_t,heap) *from)
VEC_free (state_t,heap, *to); VEC_free (state_t,heap, *to);
*to = VEC_copy (state_t,heap, from); *to = VEC_copy (state_t,heap, from);
} }
/* The function processes equivalence class given by its first state, /* The function processes equivalence class given by its first state,
FIRST_STATE, on odd iteration if ODD_ITERATION_FLAG. If there FIRST_STATE, on odd iteration if ODD_ITERATION_FLAG. If there
are not equivalent states, the function partitions the class are not equivalent states, the function partitions the class
...@@ -5746,7 +5804,6 @@ partition_equiv_class (state_t first_state, int odd_iteration_flag, ...@@ -5746,7 +5804,6 @@ partition_equiv_class (state_t first_state, int odd_iteration_flag,
state_t curr_state; state_t curr_state;
state_t prev_state; state_t prev_state;
state_t next_state; state_t next_state;
int out_arcs_num;
partition_p = 0; partition_p = 0;
...@@ -5756,15 +5813,14 @@ partition_equiv_class (state_t first_state, int odd_iteration_flag, ...@@ -5756,15 +5813,14 @@ partition_equiv_class (state_t first_state, int odd_iteration_flag,
if (first_state->next_equiv_class_state != NULL) if (first_state->next_equiv_class_state != NULL)
{ {
/* There are more one states in the class equivalence. */ /* There are more one states in the class equivalence. */
out_arcs_num = set_out_arc_insns_equiv_num (first_state, set_out_arc_insns_equiv_num (first_state, odd_iteration_flag);
odd_iteration_flag);
for (prev_state = first_state, for (prev_state = first_state,
curr_state = first_state->next_equiv_class_state; curr_state = first_state->next_equiv_class_state;
curr_state != NULL; curr_state != NULL;
curr_state = next_state) curr_state = next_state)
{ {
next_state = curr_state->next_equiv_class_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)) odd_iteration_flag))
{ {
/* Remove curr state from the class equivalence. */ /* Remove curr state from the class equivalence. */
...@@ -5797,7 +5853,6 @@ static void ...@@ -5797,7 +5853,6 @@ static void
evaluate_equiv_classes (automaton_t automaton, evaluate_equiv_classes (automaton_t automaton,
VEC(state_t,heap) **equiv_classes) VEC(state_t,heap) **equiv_classes)
{ {
state_t new_equiv_class;
int new_equiv_class_num; int new_equiv_class_num;
int odd_iteration_flag; int odd_iteration_flag;
int finish_flag; int finish_flag;
...@@ -5806,12 +5861,14 @@ evaluate_equiv_classes (automaton_t automaton, ...@@ -5806,12 +5861,14 @@ evaluate_equiv_classes (automaton_t automaton,
all_achieved_states = VEC_alloc (state_t,heap, 1500); all_achieved_states = VEC_alloc (state_t,heap, 1500);
pass_states (automaton, add_achieved_state); pass_states (automaton, add_achieved_state);
new_equiv_class = init_equiv_class (all_achieved_states); pass_states (automaton, cache_presence);
odd_iteration_flag = 0; qsort (VEC_address (state_t, all_achieved_states),
new_equiv_class_num = 1; VEC_length (state_t, all_achieved_states),
sizeof (state_t), compare_states_for_equiv);
next_iteration_classes = VEC_alloc (state_t,heap, 150); odd_iteration_flag = 0;
VEC_quick_push (state_t, next_iteration_classes, new_equiv_class); new_equiv_class_num = init_equiv_class (all_achieved_states,
&next_iteration_classes);
do do
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment