This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[yara-branch] patch for speeding YARA up, fix eon for x86_64.
- From: Vladimir Makarov <vmakarov at redhat dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 19 Apr 2006 12:33:55 -0400
- Subject: [yara-branch] patch for speeding YARA up, fix eon for x86_64.
The following patch speeds YARA up (about 10%), fixes SPECINT2000 eon
freezing on x86_64. The speedup is achieved:
o by rewriting code to choose CAN for spill during global allocator.
o calling some functions only once during whole file compilation.
o rewriting code to find possible insn alternatives for insn allocnos
representing operands.
o speeding up a code making exchange of allocnos representing
commutative operands.
2006-04-19 Vladimir Makarov <vmakarov@redhat.com>
* yara-color.c (update_min_alt_costs): Save and restore possible
alternatives after commutative exchanges.
(process_op_insn_allocno_for_can_classes): Rename to
process_insn_op_allocno_for_can_classes.
(global_can_compare): Remove.
(push_globals_to_stack): Use one pass scan instead of sorting.
* yara-final.c (add_copy_list): Use control_flow_insn_p instead of
JUMP_P.
* yara-insn.c (get_first_operand_allocno,
change_other_allocno_container_loc): Remove.
(setup_possible_allocno_alternatives): Use switches.
(change_other_allocno_container_loc): Rename to
change_other_op_allocno_container_loc.
(make_commutative_exchange): Remove calls of
setup_possible_allocno_alternatives.
(find_best_alt_allocation): Save and restore possible
alternatives after commutative exchanges.
(allocate_insn_allocnos): Set up possible
alternatives after commutative exchange.
* yara-int.h (single_allocno_class): Remove the prototype.
* yara-ir.c (set_call_info, set_single_hard_reg_allocno_info,
single_alt_reg_class): New prototypes.
(single_allocno_class): Rename to single_reg_allocno_class. Add
prototype. Make the function static.
(create_block_allocnos): Move abnormal_edge_p calls out of the
loops.
(yara_ir_init_once): Call setup_mode_multi_reg_p.
(yara_ir_init): Remove setup_mode_multi_reg_p call.
* yara-trans.c (set_base_index_reg_sets): Save and restore
reg_renumber.
(copy_rtx_and_substitute): Remove.
(yara_trans_init_once): Call set_base_index_reg_sets.
(yara_trans_init): Remove set_base_index_reg_sets call.
Index: yara-color.c
===================================================================
--- yara-color.c (revision 113053)
+++ yara-color.c (working copy)
@@ -721,6 +721,7 @@ update_min_alt_costs (void)
allocno_t a, a2;
can_t can;
struct insn_op_info *info;
+ alt_set_t saved_alt_set, saved_alt_set2;
for (a2 = NULL, a = insn_allocnos [INSN_UID (curr_preference_insn)];
a != NULL;
@@ -750,9 +751,16 @@ update_min_alt_costs (void)
yara_assert (a2 != NULL);
op_num = INSN_ALLOCNO_TYPE (a2) - OPERAND_BASE;
yara_assert (op_num >= 0);
+ a = INSN_ALLOCNO_COMMUTATIVE (a2);
+ COPY_ALT_SET (saved_alt_set, INSN_ALLOCNO_POSSIBLE_ALTS (a));
+ COPY_ALT_SET (saved_alt_set2, INSN_ALLOCNO_POSSIBLE_ALTS (a2));
make_commutative_exchange (a2);
+ setup_possible_allocno_alternatives (info, a, false);
+ setup_possible_allocno_alternatives (info, a2, false);
process_insn_allocno_for_costs (true);
make_commutative_exchange (a2);
+ COPY_ALT_SET (INSN_ALLOCNO_POSSIBLE_ALTS (a), saved_alt_set);
+ COPY_ALT_SET (INSN_ALLOCNO_POSSIBLE_ALTS (a2), saved_alt_set2);
}
}
@@ -784,7 +792,7 @@ add_can_class_for_check (int can_num, en
insn with given INFO for alternative N_ALT to find all classes
which should be checked for cover classes and register costs. */
static void
-process_op_insn_allocno_for_can_classes (allocno_t a,
+process_insn_op_allocno_for_can_classes (allocno_t a,
struct insn_op_info *info,
int n_alt, const char *constraint)
{
@@ -841,7 +849,7 @@ process_op_insn_allocno_for_can_classes
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
- process_op_insn_allocno_for_can_classes
+ process_insn_op_allocno_for_can_classes
(a, info, n_alt,
info->op_constraints [(c - '0') * info->n_alts + n_alt]);
break;
@@ -915,7 +923,7 @@ setup_can_classes (void)
}
else
{
- process_op_insn_allocno_for_can_classes
+ process_insn_op_allocno_for_can_classes
(a, info, curr_alt,
info->op_constraints [op_num * info->n_alts
+ curr_alt]);
@@ -1577,42 +1585,14 @@ delete_can_from_bucket (can_t can, can_t
colouring. */
static varray_type global_stack_varray;
-/* Function used to sort cans according to their priorities to choose
- one for spilling. */
-static int
-global_can_compare (const void *c1p, const void *c2p)
-{
- can_t c1 = *(can_t *) c1p;
- can_t c2 = *(can_t *) c2p;
- int diff, size1, size2;
-
- if (CAN_IN_GRAPH_P (c1) && ! CAN_IN_GRAPH_P (c2))
- return -1;
- else if (! CAN_IN_GRAPH_P (c1) && CAN_IN_GRAPH_P (c2))
- return 1;
- else
- {
- yara_assert (CAN_COVER_CLASS (c1) == CAN_COVER_CLASS (c2));
- size1 = reg_class_nregs [CAN_COVER_CLASS (c1)] [CAN_MODE (c1)];
- size2 = reg_class_nregs [CAN_COVER_CLASS (c2)] [CAN_MODE (c2)];
- diff = ((CAN_MEMORY_COST (c1) - CAN_COVER_CLASS_COST (c1))
- / (CAN_LEFT_CONFLICTS_NUM (c1) + 1) * size1
- - (CAN_MEMORY_COST (c2) - CAN_COVER_CLASS_COST (c2))
- / (CAN_LEFT_CONFLICTS_NUM (c2) + 1) * size2);
- if (diff != 0)
- return diff;
- return CAN_NUM (c1) - CAN_NUM (c2);
- }
-}
-
/* Push global cans on the stack. The order of cans in the stack
defines the order for the subsequent colouring. */
static void
push_globals_to_stack (void)
{
- int i, size = 0, conflicts_num, conflict_size;
+ int i, j, can_pri, i_can_pri, size = 0, conflicts_num, conflict_size;
int first_non_empty_bucket_num;
- can_t can, conflict_can;
+ can_t can, i_can, conflict_can;
can_t *can_vec, *sorted_global_cans, *bucket_ptr;
enum reg_class cover_class;
int num, cover_class_cans_num [N_REG_CLASSES];
@@ -1682,13 +1662,40 @@ push_globals_to_stack (void)
num = cover_class_cans_num [cover_class];
yara_assert (num > 0);
can_vec = cover_class_cans [cover_class];
- qsort (can_vec, num, sizeof (can_t), global_can_compare);
- for (num--; ! CAN_IN_GRAPH_P (can_vec [num]); num--)
- ;
- yara_assert (num >= 0);
- cover_class_cans_num [cover_class] = num;
- can = can_vec [0];
- cover_class_cans [cover_class]++;
+ can = NULL;
+ can_pri = 0;
+ for (i = 0, j = num - 1; i <= j;)
+ {
+ i_can = can_vec [i];
+ if (! CAN_IN_GRAPH_P (i_can)
+ && CAN_IN_GRAPH_P (can_vec [j]))
+ {
+ i_can = can_vec [j];
+ can_vec [j] = can_vec [i];
+ can_vec [i] = i_can;
+ }
+ if (CAN_IN_GRAPH_P (i_can))
+ {
+ i++;
+ i_can_pri
+ = ((CAN_MEMORY_COST (i_can)
+ - CAN_COVER_CLASS_COST (i_can))
+ / (CAN_LEFT_CONFLICTS_NUM (i_can) + 1)
+ * reg_class_nregs [CAN_COVER_CLASS (i_can)]
+ [CAN_MODE (i_can)]);
+ if (can == NULL || can_pri > i_can_pri
+ || (can_pri == i_can_pri
+ && CAN_NUM (can) > CAN_NUM (i_can)))
+ {
+ can = i_can;
+ can_pri = i_can_pri;
+ }
+ }
+ if (! CAN_IN_GRAPH_P (can_vec [j]))
+ j--;
+ }
+ yara_assert (can != NULL && j >= 0);
+ cover_class_cans_num [cover_class] = j + 1;
size = reg_class_nregs [cover_class] [CAN_MODE (can)];
yara_assert (CAN_IN_GRAPH_P (can)
&& CAN_COVER_CLASS (can) == cover_class
@@ -3228,7 +3235,8 @@ pseudo_reg_copy_cost (copy_t cp)
[REGNO_REG_CLASS (dst_hard_regno)];
}
}
- return cost * COPY_FREQ (cp) * COST_FACTOR;
+ cost *= COPY_FREQ (cp) * COST_FACTOR;
+ return cost;
}
Index: yara-final.c
===================================================================
--- yara-final.c (revision 113053)
+++ yara-final.c (working copy)
@@ -2272,6 +2272,8 @@ emit_insns_at_bb_end (rtx insns, basic_b
}
}
+/* The function generates insns representing copies of the list given
+ by CP. */
static void
add_copy_list (copy_t cp)
{
@@ -2284,7 +2286,7 @@ add_copy_list (copy_t cp)
return;
p = COPY_POINT (cp);
pt = p.point_type;
- jmp = (pt == AT_BB_END && JUMP_P (BB_END (p.u.bb))
+ jmp = (pt == AT_BB_END && control_flow_insn_p (BB_END (p.u.bb))
? BB_END (p.u.bb) : NULL_RTX);
before_jump_p = true;
start_sequence ();
Index: yara-insn.c
===================================================================
--- yara-insn.c (revision 113053)
+++ yara-insn.c (working copy)
@@ -44,7 +44,6 @@ Software Foundation, 51 Franklin Street,
static bool check_alternative_possibility (allocno_t, const char *, bool);
-static allocno_t get_first_operand_allocno (allocno_t);
static void setup_possible_operand_alternatives (rtx, bool);
static bool try_hard_regno_from_connected_allocno (allocno_t, enum reg_class,
@@ -53,8 +52,6 @@ static bool assign_hard_regno_to_pseudo_
enum reg_class,
HARD_REG_SET);
static bool assign_constraint (allocno_t, const char *);
-static void change_other_allocno_container_loc (allocno_t, allocno_t,
- rtx *, rtx *);
static void find_best_alt_allocation_1 (void);
static void find_best_alt_allocation (void);
static int get_duplication_number (const char *);
@@ -65,6 +62,9 @@ static bool assign_insn_allocnos_without
+/* The function checks that constraint *P is possible (in strict sense
+ if STRICT_P) for allocno A. The function returns true for the
+ successful try. */
static bool
check_alternative_possibility (allocno_t a, const char *p, bool strict_p)
{
@@ -251,6 +251,9 @@ check_alternative_possibility (allocno_t
return false;
}
+/* The function sets up possible alternatives (in strict sense if
+ STRICT_P) for allocno A representing an operand of insn given by
+ INFO. */
void
setup_possible_allocno_alternatives (struct insn_op_info *info, allocno_t a,
bool strict_p)
@@ -277,61 +280,69 @@ setup_possible_allocno_alternatives (str
for (;
(c = *constraints);
constraints += CONSTRAINT_LEN (c, constraints))
- if (c == ' ' || c == '\t' || c == '=' || c == '+' || c == '*'
- || c == '&' || c == '%' || c == '?' || c == '!')
- ;
- else if ('0' <= c && c <= '9')
- {
- allocno_t a1;
- const char *str;
- int n = c - '0';
-
- yara_assert (op_num > n);
- a1 = (insn_op_allocnos [INSN_UID (INSN_ALLOCNO_INSN (a))] [n]);
- if (! strict_p)
- SET_ALT (set, n_alt);
- else if (INSN_ALLOCNO_TIED_ALLOCNO (a) == a1
- && TEST_ALT (INSN_ALLOCNO_POSSIBLE_ALTS (a1), n_alt))
+ {
+ switch (c)
+ {
+ case ' ': case '\t': case '=': case '+': case '*':
+ case '&': case '%': case '?': case '!':
+ continue;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
{
- /* ???!!! We have after allocation duplication
- first. */
- str = info->op_constraints [(n) * alts_num + n_alt];
- for (; (c = *str); str += CONSTRAINT_LEN (c, str))
- if (c == ' ' || c == '\t' || c == '=' || c == '+'
- || c == '*' || c == '&' || c == '%'
- || c == '?' || c == '!')
- ;
- else
- {
- yara_assert (c != '#');
- if (check_alternative_possibility (a, str, true))
- {
- SET_ALT (set, n_alt);
+ allocno_t a1;
+ const char *str;
+ int n = c - '0';
+
+ yara_assert (op_num > n);
+ a1 = insn_op_allocnos [INSN_UID (INSN_ALLOCNO_INSN (a))]
+ [n];
+ if (! strict_p)
+ SET_ALT (set, n_alt);
+ else if (INSN_ALLOCNO_TIED_ALLOCNO (a) == a1
+ && TEST_ALT (INSN_ALLOCNO_POSSIBLE_ALTS (a1),
+ n_alt))
+ {
+ /* ???!!! We have after allocation duplication
+ first. */
+ str = info->op_constraints [(n) * alts_num + n_alt];
+ for (; (c = *str); str += CONSTRAINT_LEN (c, str))
+ {
+ switch (c)
+ {
+ case ' ': case '\t': case '=': case '+':
+ case '*': case '&': case '%': case '?': case '!':
+ break;
+ default:
+ yara_assert (c != '#');
+ if (check_alternative_possibility (a, str,
+ true))
+ SET_ALT (set, n_alt);
+ break;
+ }
+ if (TEST_ALT (set, n_alt))
break;
- }
- }
+ }
+ }
+ break;
}
- }
- else
- {
- yara_assert (c != '#');
- if (check_alternative_possibility (a, constraints, strict_p))
- SET_ALT (set, n_alt);
- }
+
+ default:
+ yara_assert (c != '#');
+ if (check_alternative_possibility (a, constraints, strict_p))
+ SET_ALT (set, n_alt);
+ break;
+ }
+ if (TEST_ALT (set, n_alt))
+ break;
+ }
}
}
INSN_ALLOCNO_POSSIBLE_ALTS (a) = set;
}
-static allocno_t
-get_first_operand_allocno (allocno_t start)
-{
- for (;start != NULL; start = INSN_ALLOCNO_NEXT (start))
- if (INSN_ALLOCNO_TYPE (start) >= OPERAND_BASE)
- break;
- return start;
-}
-
+/* The function sets up possible alternatives (in strict sense if
+ STRICT_P) for allocnos representing operands of INSN. */
static void
setup_possible_operand_alternatives (rtx insn, bool strict_p)
{
@@ -339,10 +350,11 @@ setup_possible_operand_alternatives (rtx
struct insn_op_info *info;
info = insn_infos [INSN_UID (insn)];
- for (op = get_first_operand_allocno (insn_allocnos [INSN_UID (insn)]);
+ for (op = insn_allocnos [INSN_UID (insn)];
op != NULL;
- op = get_first_operand_allocno (INSN_ALLOCNO_NEXT (op)))
- setup_possible_allocno_alternatives (info, op, strict_p);
+ op = INSN_ALLOCNO_NEXT (op))
+ if (INSN_ALLOCNO_TYPE (op) >= OPERAND_BASE)
+ setup_possible_allocno_alternatives (info, op, strict_p);
}
void
@@ -794,9 +806,12 @@ static const char *curr_alt_constraints
current alternative. */
static allocno_t curr_alt_exchange_allocno;
+/* The function exchange container locations of commutative allocnos A
+ and A2 with the corresponding locations OLD_LOC and OLD_LOC2 if
+ they coincide with container locs. */
static void
-change_other_allocno_container_loc (allocno_t a, allocno_t a2,
- rtx *old_loc, rtx *old_loc2)
+change_other_op_allocno_container_loc (allocno_t a, allocno_t a2,
+ rtx *old_loc, rtx *old_loc2)
{
allocno_t a1;
@@ -813,8 +828,8 @@ change_other_allocno_container_loc (allo
INSN_ALLOCNO_CONTAINER_LOC (a1) = INSN_ALLOCNO_LOC (a2);
}
-/* The function exchanges insn allocno A with corresponding
- commutative allocno. */
+/* The function exchanges insn allocno A with the corresponding
+ commutative allocno without changing possible alternatives. */
void
make_commutative_exchange (allocno_t a)
{
@@ -822,7 +837,6 @@ make_commutative_exchange (allocno_t a)
int temp, uid;
bool temp_bool;
rtx *op_loc, *op_loc2;
- struct insn_op_info *info;
allocno_t tied_allocno, tied_allocno2;
allocno_t a2 = INSN_ALLOCNO_COMMUTATIVE (a);
@@ -859,7 +873,7 @@ make_commutative_exchange (allocno_t a)
INSN_ALLOCNO_LOC (a2) = op_loc;
INSN_ALLOCNO_CONTAINER_LOC (a2)
= get_container_loc (op_loc, &PATTERN (INSN_ALLOCNO_INSN (a2)));
- change_other_allocno_container_loc (a, a2, op_loc, op_loc2);
+ change_other_op_allocno_container_loc (a, a2, op_loc, op_loc2);
tied_allocno = INSN_ALLOCNO_TIED_ALLOCNO (a);
tied_allocno2 = INSN_ALLOCNO_TIED_ALLOCNO (a2);
if (tied_allocno == NULL)
@@ -876,9 +890,6 @@ make_commutative_exchange (allocno_t a)
INSN_ALLOCNO_TIED_ALLOCNO (a) = tied_allocno2;
INSN_ALLOCNO_TIED_ALLOCNO (tied_allocno2) = a;
}
- info = insn_infos [INSN_UID (INSN_ALLOCNO_INSN (a))];
- setup_possible_allocno_alternatives (info, a, false);
- setup_possible_allocno_alternatives (info, a2, false);
}
/* Cost of all allocation before allocating insn allocnos of the
@@ -1101,6 +1112,7 @@ find_best_alt_allocation (void)
{
int i, j, op_num;
allocno_t a, a2;
+ alt_set_t saved_alt_set, saved_alt_set2;
curr_alt_exchange_allocno = NULL;
find_best_alt_allocation_1 ();
@@ -1121,12 +1133,20 @@ find_best_alt_allocation (void)
yara_assert (j < (int) VARRAY_ACTIVE_SIZE (insn_allocno_varray));
op_num = INSN_ALLOCNO_TYPE (a) - OPERAND_BASE;
yara_assert (op_num >= 0);
+ COPY_ALT_SET (saved_alt_set, INSN_ALLOCNO_POSSIBLE_ALTS (a));
+ COPY_ALT_SET (saved_alt_set2, INSN_ALLOCNO_POSSIBLE_ALTS (a2));
make_commutative_exchange (a);
+ setup_possible_allocno_alternatives
+ (curr_allocation_insn_info, a, false);
+ setup_possible_allocno_alternatives
+ (curr_allocation_insn_info, a2, false);
VARRAY_GENERIC_PTR (insn_allocno_varray, i) = a2;
VARRAY_GENERIC_PTR (insn_allocno_varray, j) = a;
curr_alt_exchange_allocno = a;
find_best_alt_allocation_1 ();
make_commutative_exchange (a);
+ COPY_ALT_SET (INSN_ALLOCNO_POSSIBLE_ALTS (a), saved_alt_set);
+ COPY_ALT_SET (INSN_ALLOCNO_POSSIBLE_ALTS (a2), saved_alt_set2);
VARRAY_GENERIC_PTR (insn_allocno_varray, i) = a;
VARRAY_GENERIC_PTR (insn_allocno_varray, j) = a2;
}
@@ -1335,6 +1355,13 @@ assign_insn_allocnos_without_copy (rtx i
return true;
}
+/* Function makes assignment for all allocnos of INSN. It may spill
+ allocnos living through the insn by calling hook
+ PROVIDE_ALLOCNO_CLASS_HARD_REG. It also may use hook
+ CALL_CROSS_HINT to define that given allocno lives through a call.
+ The insn allocnos are processed in order provided by hook
+ INSN_ALLOCNO_SORT (e.g. to process allocnos with bigger constraints
+ first). */
void
allocate_insn_allocnos (rtx insn, bool (*call_cross_hint) (allocno_t),
void (*insn_allocno_sort) (allocno_t *, int, rtx, int),
@@ -1356,7 +1383,14 @@ allocate_insn_allocnos (rtx insn, bool (
if (! find_best_allocation (insn))
gcc_unreachable ();
if (best_insn_exchange_allocno != NULL)
- make_commutative_exchange (best_insn_exchange_allocno);
+ {
+ make_commutative_exchange (best_insn_exchange_allocno);
+ setup_possible_allocno_alternatives
+ (curr_allocation_insn_info, best_insn_exchange_allocno, false);
+ setup_possible_allocno_alternatives
+ (curr_allocation_insn_info,
+ INSN_ALLOCNO_COMMUTATIVE (best_insn_exchange_allocno), false);
+ }
for (i = 0; i < (int) VARRAY_ACTIVE_SIZE (best_insn_allocno_varray); i++)
{
a = VARRAY_GENERIC_PTR (best_insn_allocno_varray, i);
Index: yara-int.h
===================================================================
--- yara-int.h (revision 113053)
+++ yara-int.h (working copy)
@@ -883,7 +883,6 @@ extern void make_canon_plus (rtx **, rtx
extern bool decode_address (rtx *, rtx **, rtx **, rtx **, rtx **,
HOST_WIDE_INT *, bool);
extern copy_t find_post_insn_allocno_copy (allocno_t, rtx);
-extern enum reg_class single_allocno_class (allocno_t);
extern rtx *get_container_loc (rtx *, rtx *);
extern allocno_t insn_allocno (rtx, rtx);
Index: yara-ir.c
===================================================================
--- yara-ir.c (revision 113053)
+++ yara-ir.c (working copy)
@@ -187,6 +187,13 @@ static void set_allocno_conflict (allocn
static void mark_allocno_live (allocno_t, bool);
static void mark_allocno_death (allocno_t);
static void process_non_operand_hard_regs (rtx *, bool);
+
+static void set_call_info (allocno_t, void *, int);
+static void set_single_hard_reg_allocno_info (allocno_t, void *, int);
+static enum reg_class single_alt_reg_class (const char *,
+ struct insn_op_info *, int);
+static enum reg_class single_reg_allocno_class (allocno_t);
+
#ifdef HAVE_ANY_SECONDARY_MOVES
static void set_copy_conflict (allocno_t, void *, int);
#endif
@@ -3137,6 +3144,9 @@ process_non_operand_hard_regs (rtx *loc,
}
}
+/* The function sets up call_p and increment call_freq for allocno
+ LIVE_A living through call insn given by DATA. The function is
+ called by generic traverse function process_live_allocnos. */
static void
set_call_info (allocno_t live_a, void *data,
int local_live_index ATTRIBUTE_UNUSED)
@@ -3147,6 +3157,10 @@ set_call_info (allocno_t live_a, void *d
ALLOCNO_CALL_FREQ (live_a) += BLOCK_FOR_INSN (insn)->frequency;
}
+/* The function sets up hard registers conflicting with allocno
+ LIVE_A. The hard registers are given by their class passed through
+ DATA. The function is called by generic traverse function
+ process_live_allocnos. */
static void
set_single_hard_reg_allocno_info (allocno_t live_a, void *data,
int local_live_index ATTRIBUTE_UNUSED)
@@ -3159,6 +3173,10 @@ set_single_hard_reg_allocno_info (allocn
reg_class_contents [cl]);
}
+/* The function checks that CONSTRAINTS of alternative ALT_NUM of insn
+ with INFO permits to use only one hard register. If it is so, the
+ function returns the class of the hard register. Otherwise it
+ returns NO_REGS. */
static enum reg_class
single_alt_reg_class (const char *constraints, struct insn_op_info *info,
int alt_num)
@@ -3217,8 +3235,11 @@ single_alt_reg_class (const char *constr
return cl;
}
-enum reg_class
-single_allocno_class (allocno_t a)
+/* The function checks that insn allocno A can use only one hard
+ register. If it is so, the function returns the class of the hard
+ register. Otherwise it returns NO_REGS. */
+static enum reg_class
+single_reg_allocno_class (allocno_t a)
{
enum reg_class cl, next_cl;
struct insn_op_info *info;
@@ -3281,7 +3302,7 @@ build_insn_allocno_conflicts (rtx insn)
{
enum reg_class cl;
- cl = single_allocno_class (a);
+ cl = single_reg_allocno_class (a);
if (cl != NO_REGS)
process_live_allocnos (set_single_hard_reg_allocno_info,
(void *) cl);
@@ -3338,7 +3359,7 @@ build_insn_allocno_conflicts (rtx insn)
{
enum reg_class cl;
- cl = single_allocno_class (a);
+ cl = single_reg_allocno_class (a);
if (cl != NO_REGS)
process_live_allocnos (set_single_hard_reg_allocno_info,
(void *) cl);
@@ -3993,11 +4014,14 @@ abnormal_edge_p (VEC(edge,gc) *edges)
return false;
}
+/* The function create copies and allocnos for registers living in
+ basic block represented by node LOOP. */
static void
create_block_allocnos (struct yara_loop_tree_node *loop)
{
basic_block bb = loop->bb;
bitmap_iterator bi;
+ bool abnormal_p;
int i;
unsigned int k;
edge_iterator ei;
@@ -4033,15 +4057,16 @@ create_block_allocnos (struct yara_loop_
temp_live_through_abnormal);
}
}
+ abnormal_p = abnormal_edge_p (bb->preds);
for (i = 0; i < live_pseudo_regs_num; i++)
create_bb_allocno (live_pseudo_regs [i], loop, true,
- live_through_abnormal, abnormal_edge_p (bb->preds));
+ live_through_abnormal, abnormal_p);
create_bb_insn_allocnos (loop);
+ abnormal_p = abnormal_edge_p (bb->succs);
EXECUTE_IF_SET_IN_REG_SET (bb->il.rtl->global_live_at_end,
FIRST_PSEUDO_REGISTER, k, bi)
{
- create_bb_allocno (k, loop, false,
- live_through_abnormal, abnormal_edge_p (bb->succs));
+ create_bb_allocno (k, loop, false, live_through_abnormal, abnormal_p);
}
if (live_through_abnormal != NULL)
yara_free_bitmap (live_through_abnormal);
@@ -5945,14 +5970,18 @@ setup_slotno_max_ref_align_size (void)
+/* The function is called once for each compilation file. It does
+ initialization of data common for all RTL functions. */
void
yara_ir_init_once (void)
{
- /* setup_mode_multi_reg_p ??? */
+ setup_mode_multi_reg_p ();
setup_reg_class_nregs ();
setup_spill_class_mode ();
}
+/* The function builds IR of the allocator (alocnos, copies, CANs) and
+ initializes local file data used for each RTL function. */
void
yara_ir_init (void)
{
@@ -5977,7 +6006,6 @@ yara_ir_init (void)
live_pseudo_reg_indexes [i] = -1;
create_regno_allocno_maps ();
allocate_loop_regno_allocno_map (yara_loop_tree_root);
- setup_mode_multi_reg_p ();
VARRAY_GENERIC_PTR_NOGC_INIT
(live_through_allocnos_varray, max_regno * 2 * n_basic_blocks,
"allocno living through basic blocks and egdes");
@@ -6026,6 +6054,8 @@ yara_ir_init (void)
}
+/* The function frees the allocator IR and local file data used for
+ each RTL function. */
void
yara_ir_finish (void)
{
Index: yara-trans.c
===================================================================
--- yara-trans.c (revision 113053)
+++ yara-trans.c (working copy)
@@ -1371,11 +1371,21 @@ get_temp_stack_memory_slot_rtx (enum mac
#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
#endif
+/* The function sets up sets of hard registers which can be used for
+ base and index registers. */
static void
set_base_index_reg_sets (void)
{
int i, mode;
+ short *saved_reg_renumber;
+ short temp_array [FIRST_PSEUDO_REGISTER];
+ /* REGNO_OK_FOR_INDEX_P and REGNO_MODE_OK_FOR_BASE_P can use
+ reg_renumber so we need to define it temporarily. */
+ saved_reg_renumber = reg_renumber;
+ reg_renumber = temp_array;
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ temp_array [i] = -1;
CLEAR_HARD_REG_SET (index_regs);
for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
CLEAR_HARD_REG_SET (base_regs [mode]);
@@ -1388,6 +1398,7 @@ set_base_index_reg_sets (void)
if (REGNO_MODE_OK_FOR_BASE_P (i, mode))
SET_HARD_REG_BIT (base_regs [mode], i);
}
+ saved_reg_renumber = reg_renumber;
}
int minimal_memory_load_cost [MAX_MACHINE_MODE];
@@ -2372,75 +2383,6 @@ check_insns_added_since (rtx last)
return insn == NULL_RTX;
}
-static rtx
-copy_rtx_and_substitute (rtx x, allocno_t a)
-{
- int i, hard_regno;
- bool copy_p;
- const char *fmt;
- rtx subst;
- allocno_t insn_a;
- enum rtx_code code = GET_CODE (x);
-
- /* Ignore registers in memory. */
- if (code == REG)
- {
- if (HARD_REGISTER_P (x))
- return NULL_RTX;
- for (insn_a = insn_allocnos [INSN_UID (INSN_ALLOCNO_INSN (a))];
- insn_a != NULL;
- insn_a = INSN_ALLOCNO_NEXT (insn_a))
- if (INSN_ALLOCNO_CONTAINER_LOC (insn_a) == INSN_ALLOCNO_LOC (a))
- break;
- yara_assert (insn_a != NULL
- && (INSN_ALLOCNO_TYPE (insn_a) == BASE_REG
- || INSN_ALLOCNO_TYPE (insn_a) == INDEX_REG));
- hard_regno = ALLOCNO_HARD_REGNO (insn_a);
- if (hard_regno < 0)
- hard_regno =
- class_hard_regs [(INSN_ALLOCNO_TYPE (a) == BASE_REG
- ? BASE_REG_CLASS : INDEX_REG_CLASS)] [0];
- return gen_rtx_REG (ALLOCNO_MODE (insn_a), hard_regno);
- }
- fmt = GET_RTX_FORMAT (code);
- copy_p = false;
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'e')
- {
- subst = copy_rtx_and_substitute (XEXP (x, i), a);
- if (subst != NULL_RTX)
- {
- if (! copy_p)
- {
- copy_p = true;
- x = shallow_copy_rtx (x);
- }
- XEXP (x, i) = subst;
- }
- }
- else if (fmt[i] == 'E')
- {
- int j;
-
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- {
- subst = copy_rtx_and_substitute (XVECEXP (x, i, j), a);
- if (subst != NULL_RTX)
- {
- if (! copy_p)
- {
- copy_p = true;
- x = shallow_copy_rtx (x);
- }
- XVECEXP (x, i, j) = subst;
- }
- }
- }
- }
- return (copy_p ? x : NULL_RTX);
-}
-
/* HARD_REGNO should be tried as hard regno for A. */
static bool
assign_allocno_hard_regno (allocno_t a, int hard_regno,
@@ -3791,13 +3733,18 @@ eliminate_virtual_registers (int (*func)
+/* The function is called once for each compilation file. It does
+ initialization of data common for all RTL functions. */
void
yara_trans_init_once (void)
{
setup_temp_mems_and_addresses ();
setup_move_costs ();
+ set_base_index_reg_sets ();
}
+/* The function initializes local file data used for each RTL
+ function. */
void
yara_trans_init (void)
{
@@ -3807,9 +3754,9 @@ yara_trans_init (void)
#endif
initiate_memory_slots ();
initiate_transactions ();
- set_base_index_reg_sets ();
}
+/* The function frees local file data used for each RTL function. */
void
yara_trans_finish (void)
{