aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2006-05-19 18:48:32 +0000
committerVladimir Makarov <vmakarov@redhat.com>2006-05-19 18:48:32 +0000
commitcd8af4a4513cb7e87226de7b464f339d62213fe7 (patch)
tree8b3b4da24779ba5829ad7738724ec5c10b7acda2
parent79ec9fcbbfd5e580aa67a7fae99b2b26e1b80baa (diff)
2006-05-19 Vladimir Makarov <vmakarov@redhat.com>
* yara-int.h (HAVE_ANY_SECONDARY_MOVES): Remove. (secondary_copy_change): Rename to copy_change. Add new fields interm_equiv_const_regno and interm_equiv_const_mode. (COPY_SECONDARY_CHANGE_ADDR): Rename to COPY_CHANGE_ADDR. (COPY_INTERM_EQUIV_CONST_REGNO, COPY_INTERM_EQUIV_CONST_MODE): New macros. (unassign_copy_secondary): Rename to unassign_copy. (check_elimination_in_addr, get_equiv_const_addr_info, get_equiv_const_elimination_info): New prototypes. * yara-insn.c (check_alternative_possibility): Check allocation of the plus constant of the constant address with eliminated register. (assign_constraint): Ditto. (find_best_alt_allocation_1): Check base and index register with equivalent constant address. (allocate_insn_allocnos): Ditto. * yara-color.c (setup_minimal_op_costs): Take equivalent constant into account. (update_min_op_costs): Ditto. (assign_global_can_allocnos): Ditto. (assign_dst_if_necessary): Ditto. (try_change_allocno): Ditto. * common.opt (frematerialize): Switch it on by default for -O2. * yara-final.c: Rename COPY_SECONDARY_CHANGE_ADDR to COPY_CHANGE_ADDR. Rename unassign_copy_secondary to unassign_copy. Remove HAVE_ANY_SECONDARY_MOVES. (unnecessary_copy_p): Take equivalent constant into account. (process_allocno_locs): Ditto. (emit_copy): Ditto. (eliminate_reg_allocno): New function. (modify_insn): Use the function. Take equivalent constant into account. * yara-trans.c: Rename COPY_SECONDARY_CHANGE_ADDR to COPY_CHANGE_ADDR. Remove HAVE_ANY_SECONDARY_MOVES. (initiate_secondary_copy_changes, free_secondary_copy_change, get_free_secondary_copy_change, finish_secondary_copy_changes, assign_copy_secondary, assign_secondary, unassign_copy_secondary, unassign_secondary, free_secondary_copy_changes, secondary_copy_change_varray): Rename to correspondingly initiate_copy_changes, free_copy_change, get_free_copy_change, finish_copy_changes, assign_copy, assign_allocno_copies, unassign_copy, unassign_allocno_copies, free_copy_changes, copy_change_varray. (get_free_copy_change): Initialize interm_equiv_const_regno and interm_equiv_const_mode. (assign_copy_interm_equiv_const_hard_reg, unassign_copy_interm_equiv_const_hard_reg): New functions. (assign_copy, unassign_copy): Take equivalent constant into account. (unassign_one_allocno): Call unassign_allocno_copies when the equivalent constant is used. (check_elimination_in_addr): New parameters. (get_equiv_const_addr_info, get_equiv_const_elimination_info): New functions. (undo_copy_change): Process interm_equiv_const_regno. (check_hard_regno_memory_on_constraint): Take equivalent constant into account. * yara-ir.c: Rename COPY_SECONDARY_CHANGE_ADDR to COPY_CHANGE_ADDR. Remove HAVE_ANY_SECONDARY_MOVES. (print_copy): Print new fields interm_equiv_const_regno and interm_equiv_const_mode. (make_aggressive_coalescing): Prevent coalescing cans with equivalent constants. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/yara-branch@113912 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog72
-rw-r--r--gcc/common.opt2
-rw-r--r--gcc/yara-color.c107
-rw-r--r--gcc/yara-final.c160
-rw-r--r--gcc/yara-insn.c208
-rw-r--r--gcc/yara-int.h88
-rw-r--r--gcc/yara-ir.c67
-rw-r--r--gcc/yara-trans.c430
8 files changed, 752 insertions, 382 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 20807ec0082..1ea3fa4e262 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,75 @@
+2006-05-19 Vladimir Makarov <vmakarov@redhat.com>
+
+ * yara-int.h (HAVE_ANY_SECONDARY_MOVES): Remove.
+ (secondary_copy_change): Rename to copy_change. Add new fields
+ interm_equiv_const_regno and interm_equiv_const_mode.
+ (COPY_SECONDARY_CHANGE_ADDR): Rename to COPY_CHANGE_ADDR.
+ (COPY_INTERM_EQUIV_CONST_REGNO, COPY_INTERM_EQUIV_CONST_MODE): New
+ macros.
+ (unassign_copy_secondary): Rename to unassign_copy.
+ (check_elimination_in_addr, get_equiv_const_addr_info,
+ get_equiv_const_elimination_info): New prototypes.
+
+ * yara-insn.c (check_alternative_possibility): Check allocation of
+ the plus constant of the constant address with eliminated
+ register.
+ (assign_constraint): Ditto.
+ (find_best_alt_allocation_1): Check base and index register with
+ equivalent constant address.
+ (allocate_insn_allocnos): Ditto.
+
+ * yara-color.c (setup_minimal_op_costs): Take equivalent constant
+ into account.
+ (update_min_op_costs): Ditto.
+ (assign_global_can_allocnos): Ditto.
+ (assign_dst_if_necessary): Ditto.
+ (try_change_allocno): Ditto.
+
+ * common.opt (frematerialize): Switch it on by default for -O2.
+
+ * yara-final.c: Rename COPY_SECONDARY_CHANGE_ADDR to
+ COPY_CHANGE_ADDR. Rename unassign_copy_secondary to
+ unassign_copy. Remove HAVE_ANY_SECONDARY_MOVES.
+ (unnecessary_copy_p): Take equivalent constant into account.
+ (process_allocno_locs): Ditto.
+ (emit_copy): Ditto.
+ (eliminate_reg_allocno): New function.
+ (modify_insn): Use the function. Take equivalent constant into
+ account.
+
+ * yara-trans.c: Rename COPY_SECONDARY_CHANGE_ADDR to
+ COPY_CHANGE_ADDR. Remove HAVE_ANY_SECONDARY_MOVES.
+ (initiate_secondary_copy_changes, free_secondary_copy_change,
+ get_free_secondary_copy_change, finish_secondary_copy_changes,
+ assign_copy_secondary, assign_secondary, unassign_copy_secondary,
+ unassign_secondary, free_secondary_copy_changes,
+ secondary_copy_change_varray): Rename to correspondingly
+ initiate_copy_changes, free_copy_change, get_free_copy_change,
+ finish_copy_changes, assign_copy, assign_allocno_copies,
+ unassign_copy, unassign_allocno_copies, free_copy_changes,
+ copy_change_varray.
+ (get_free_copy_change): Initialize interm_equiv_const_regno and
+ interm_equiv_const_mode.
+ (assign_copy_interm_equiv_const_hard_reg,
+ unassign_copy_interm_equiv_const_hard_reg): New functions.
+ (assign_copy, unassign_copy): Take equivalent constant into
+ account.
+ (unassign_one_allocno): Call unassign_allocno_copies when the
+ equivalent constant is used.
+ (check_elimination_in_addr): New parameters.
+ (get_equiv_const_addr_info, get_equiv_const_elimination_info): New
+ functions.
+ (undo_copy_change): Process interm_equiv_const_regno.
+ (check_hard_regno_memory_on_constraint): Take equivalent constant
+ into account.
+
+ * yara-ir.c: Rename COPY_SECONDARY_CHANGE_ADDR to
+ COPY_CHANGE_ADDR. Remove HAVE_ANY_SECONDARY_MOVES.
+ (print_copy): Print new fields interm_equiv_const_regno and
+ interm_equiv_const_mode.
+ (make_aggressive_coalescing): Prevent coalescing cans with
+ equivalent constants.
+
2006-05-10 Vladimir Makarov <vmakarov@redhat.com>
* common.opt (fsplit): Remove.
diff --git a/gcc/common.opt b/gcc/common.opt
index d9a5b989686..7dc5caf9a12 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -714,7 +714,7 @@ Common Report Var(flag_relief)
Register pressure relief
frematerialize
-Common Report Var(flag_rematerialize)
+Common Report Var(flag_rematerialize) Init(2)
Perform a register rematerialization
frename-registers
diff --git a/gcc/yara-color.c b/gcc/yara-color.c
index 16886821b7f..af99305e6ec 100644
--- a/gcc/yara-color.c
+++ b/gcc/yara-color.c
@@ -288,8 +288,12 @@ find_reg_class_closure (void)
/* Minimal costs of usage the current insn alternative operand placed
- in memory or register of given class. */
+ in memory or, if it has equivalent constant, the cost of usage of
+ the constant. */
static int min_op_memory_cost [MAX_RECOG_OPERANDS];
+
+/* Minimal costs of usage the current insn alternative operand placed
+ in register of given class. */
static int min_op_class_cost [MAX_RECOG_OPERANDS] [N_REG_CLASSES];
/* Classes for each can which we should check for finding cover
@@ -301,6 +305,7 @@ static void
setup_minimal_op_costs (allocno_t a)
{
int op_num, i;
+ bool equiv_const_p;
enum reg_class cl, *classes;
can_t can;
@@ -313,10 +318,23 @@ setup_minimal_op_costs (allocno_t a)
classes = &can_classes [CAN_NUM (can) * N_REG_CLASSES];
/* ??? If we have insn alt cost infrastructure we could just set it
to 0. */
- /* We still need read it from memory which is usually slower than
- register. */
if (min_op_memory_cost [op_num] > 1)
- min_op_memory_cost [op_num] = 1;
+ {
+ equiv_const_p = (ALLOCNO_REGNO (a) >= 0
+ && reg_equiv_constant [ALLOCNO_REGNO (a)] != NULL_RTX);
+ /* ??? If we have insn alt cost infrastructure we could set it to 0. */
+ if (equiv_const_p)
+ /* ??? constant loading or reg plus constant: make more
+ accurate costs. */
+ min_op_memory_cost [op_num]
+ = (register_move_cost [ALLOCNO_MODE (a)]
+ [BASE_REG_CLASS] [BASE_REG_CLASS]);
+ else
+ /* We still need read it from memory which is usually slower
+ than register. */
+ min_op_memory_cost [op_num]
+ = memory_move_cost [ALLOCNO_MODE (a)] [BASE_REG_CLASS] [1];
+ }
for (i = 0; (cl = classes [i]) != NO_REGS; i++)
min_op_class_cost [op_num] [cl] = 0;
}
@@ -327,6 +345,7 @@ static void
update_min_op_costs (allocno_t a, enum reg_class class, bool mem_p)
{
int op_num, cost, i;
+ bool equiv_const_p;
enum reg_class cl, *classes;
enum machine_mode mode;
enum op_type op_mode;
@@ -341,10 +360,25 @@ update_min_op_costs (allocno_t a, enum reg_class class, bool mem_p)
classes = &can_classes [CAN_NUM (can) * N_REG_CLASSES];
op_mode = INSN_ALLOCNO_OP_MODE (a);
mode = ALLOCNO_MODE (a);
+ equiv_const_p = (ALLOCNO_REGNO (a) >= 0
+ && reg_equiv_constant [ALLOCNO_REGNO (a)] != NULL_RTX);
/* ??? If we have insn alt cost infrastructure we could set it to 0. */
if (mem_p)
- cost = 1; /* We still need read it from memory which is usually
- slower than register. */
+ {
+ if (equiv_const_p)
+ /* ??? constant loading or reg plus constant: make more
+ accurate costs. */
+ cost = (register_move_cost [mode] [BASE_REG_CLASS] [BASE_REG_CLASS]
+ + memory_move_cost [mode] [BASE_REG_CLASS] [0]);
+ else
+ /* We still need read it from memory which is usually slower
+ than register. */
+ cost = memory_move_cost [mode] [BASE_REG_CLASS] [1];
+ }
+ else if (equiv_const_p)
+ /* ??? constant loading or reg plus constant: make more accurate
+ costs. */
+ cost = register_move_cost [mode] [BASE_REG_CLASS] [class];
else
cost = ((op_mode == OP_IN || op_mode == OP_INOUT
? memory_move_cost [mode] [class] [1] : 0)
@@ -2424,6 +2458,7 @@ assign_global_can_allocnos (void)
allocno_t a, *can_allocnos;
can_t can;
bool ok_p;
+ rtx equiv_const;
sorted_cans = yara_allocate (sizeof (can_t) * cans_num);
memcpy (sorted_cans, cans, cans_num * sizeof (can_t));
@@ -2446,17 +2481,28 @@ assign_global_can_allocnos (void)
|| (ALLOCNO_CALL_CROSS_P (a)
&& ! hard_reg_not_in_set_p (hard_regno, CAN_MODE (can),
call_used_reg_set)))
- ok_p = assign_allocno (a, NO_REGS, reg_class_contents [NO_REGS],
- -1);
+ {
+ equiv_const = (ALLOCNO_REGNO (a) >= 0
+ ? reg_equiv_constant [ALLOCNO_REGNO (a)]
+ : NULL_RTX);
+ if (equiv_const != NULL)
+ ok_p = assign_allocno (a, LIM_REG_CLASSES,
+ reg_class_contents [NO_REGS], -1);
+ else
+ ok_p = assign_allocno (a, NO_REGS,
+ reg_class_contents [NO_REGS], -1);
+ }
else
- ok_p = assign_allocno (a, cover_class,
- reg_class_contents [cover_class],
- hard_regno);
+ {
+ ok_p = assign_allocno (a, cover_class,
+ reg_class_contents [cover_class],
+ hard_regno);
#if 1
- if (! ok_p)
- ok_p = assign_allocno (a, NO_REGS, reg_class_contents [NO_REGS],
- -1);
+ if (! ok_p)
+ ok_p = assign_allocno (a, NO_REGS,
+ reg_class_contents [NO_REGS], -1);
#endif
+ }
yara_assert (ok_p);
}
}
@@ -2509,7 +2555,8 @@ assign_dst_if_necessary (copy_t cp)
yara_assert (ALLOCNO_REGNO (dst) >= 0
&& ! HARD_REGISTER_NUM_P (ALLOCNO_REGNO (dst)));
hard_regno = ALLOCNO_HARD_REGNO (src);
- if (ALLOCNO_HARD_REGNO (dst) >= 0 || ALLOCNO_MEMORY_SLOT (dst) != NULL)
+ if (ALLOCNO_HARD_REGNO (dst) >= 0 || ALLOCNO_MEMORY_SLOT (dst) != NULL
+ || ALLOCNO_USE_EQUIV_CONST_P (dst))
return;
can = ALLOCNO_CAN (dst);
cover_class = CAN_COVER_CLASS (can);
@@ -3135,8 +3182,10 @@ try_change_allocno (allocno_t old, bool use_equiv_const_p,
{
HARD_REG_SET regs;
int old_reg_hard_regno, new_allocno_hard_regno;
+ bool old_use_equiv_const_p;
enum reg_class cl;
+ old_use_equiv_const_p = ALLOCNO_USE_EQUIV_CONST_P (old);
old_reg_hard_regno = ALLOCNO_HARD_REGNO (old);
if (old_reg_hard_regno >= 0)
old_reg_hard_regno = get_allocno_reg_hard_regno (old, old_reg_hard_regno);
@@ -3145,10 +3194,13 @@ try_change_allocno (allocno_t old, bool use_equiv_const_p,
new_allocno_hard_regno
= (new_reg_hard_regno < 0
? -1 : get_allocno_hard_regno (old, new_reg_hard_regno));
- if (new_reg_hard_regno == old_reg_hard_regno
+ if ((new_reg_hard_regno >= 0 && new_reg_hard_regno == old_reg_hard_regno)
+ || (new_reg_hard_regno < 0 && old_reg_hard_regno < 0
+ && ! old_use_equiv_const_p)
+ || (use_equiv_const_p && old_use_equiv_const_p)
|| (ALLOCNO_TYPE (old) == INSN_ALLOCNO
- && ! check_hard_regno_memory_on_contraint (old, use_equiv_const_p,
- new_allocno_hard_regno)))
+ && ! check_hard_regno_memory_on_constraint (old, use_equiv_const_p,
+ new_allocno_hard_regno)))
return;
start_transaction ();
unassign_allocno (old); /* ??? implement breaking ties. */
@@ -3165,7 +3217,12 @@ try_change_allocno (allocno_t old, bool use_equiv_const_p,
AND_COMPL_HARD_REG_SET (regs, no_alloc_regs);
cl = smallest_superset_class (regs);
}
- if ((use_equiv_const_p && assign_allocno (old, LIM_REG_CLASSES, regs, -1))
+ /* ??? Check constaints and legitimate address for
+ equiv_const_p. */
+ if ((use_equiv_const_p
+ /* Allocnos with different regno can be connected. */
+ && reg_equiv_constant [ALLOCNO_REGNO (old)] != NULL_RTX
+ && assign_allocno (old, LIM_REG_CLASSES, regs, -1))
|| (new_reg_hard_regno < 0 && assign_allocno (old, NO_REGS, regs, -1))
|| (new_reg_hard_regno >= 0 && cl != NO_REGS
&& assign_allocno (old, cl, regs, new_allocno_hard_regno)))
@@ -3491,6 +3548,12 @@ pseudo_reg_copy_cost (copy_t cp)
else if (src_hard_regno >= 0)
cost = memory_move_cost [src_mode]
[REGNO_REG_CLASS (src_hard_regno)] [0];
+ else if (ALLOCNO_USE_EQUIV_CONST_P (src))
+ {
+ /* ??? Change class when interm reg will be added. */
+ cost = (memory_move_cost [dst_mode] [BASE_REG_CLASS] [0]
+ + memory_move_cost [dst_mode] [BASE_REG_CLASS] [1]);
+ }
else if (src_regno != dst_regno
&& (src_memory_slot->mem != dst_memory_slot->mem
|| src_memory_slot->start != dst_memory_slot->start
@@ -3517,14 +3580,16 @@ pseudo_reg_copy_cost (copy_t cp)
cost = memory_move_cost [dst_mode]
[REGNO_REG_CLASS (dst_hard_regno)] [1];
else
- /* ??? constant loading */
+ /* ??? constant loading or reg plus constant: make more
+ accurate costs. */
cost = register_move_cost [dst_mode]
[REGNO_REG_CLASS (dst_hard_regno)]
[REGNO_REG_CLASS (dst_hard_regno)];
}
else
{
- yara_assert (src_hard_regno >= 0);
+ yara_assert (src_hard_regno >= 0
+ && ! ALLOCNO_USE_EQUIV_CONST_P (dst));
/* ??? Subregs to get real hard regs. */
if (src_hard_regno != dst_hard_regno)
cost = register_move_cost [dst_mode]
diff --git a/gcc/yara-final.c b/gcc/yara-final.c
index 10686b50335..dae5d215ebe 100644
--- a/gcc/yara-final.c
+++ b/gcc/yara-final.c
@@ -63,6 +63,7 @@ static rtx copy_insns (rtx);
static void emit_insns_at_bb_start (rtx, basic_block);
static void emit_insns_at_bb_end (rtx, basic_block, rtx, bool);
static void add_copy_list (copy_t);
+static void eliminate_reg_allocno (allocno_t, int, int, HOST_WIDE_INT);
static void modify_insn (rtx, bool);
static void clean_insn (rtx);
@@ -122,7 +123,12 @@ unnecessary_copy_p (copy_t cp)
dst_hard_regno = get_allocno_hard_regno (src, dst_hard_regno);
if (src_hard_regno >= 0 && ALLOCNO_TYPE (dst) == INSN_ALLOCNO)
src_hard_regno = get_allocno_hard_regno (dst, src_hard_regno);
- return src_hard_regno == dst_hard_regno;
+ if (src_hard_regno != dst_hard_regno)
+ return false;
+ if (dst_hard_regno < 0)
+ return ! ALLOCNO_USE_EQUIV_CONST_P (src);
+ else
+ return true;
}
}
@@ -255,6 +261,14 @@ process_allocno_locs (allocno_t dst, allocno_t src, copy_t cp, rtx insn)
(*process_reg_loc_set_func) (dst_hard_regno + i);
}
}
+ else if (src != NULL && ALLOCNO_USE_EQUIV_CONST_P (src))
+ {
+ yara_assert ((cp == NULL && ALLOCNO_USE_EQUIV_CONST_P (dst))
+ || dst_memory_slot != NULL);
+ if (! ALLOCNO_USE_EQUIV_CONST_P (dst))
+ (*process_mem_loc_set_func)
+ (dst_memory_slot, 0, GET_MODE_SIZE (cp_mode));
+ }
else
gcc_unreachable ();
if (process_post_copy_func != NULL)
@@ -273,8 +287,7 @@ process_copy_locs (copy_t copy_list)
{
process_allocno_locs (COPY_DST (cp), COPY_SRC (cp), cp, NULL_RTX);
#ifdef HAVE_SECONDARY_RELOADS
- if (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL
- && process_reg_loc_set_func != NULL)
+ if (COPY_CHANGE_ADDR (cp) != NULL && process_reg_loc_set_func != NULL)
{
if ((hard_regno = COPY_INTERM_REGNO (cp)) >= 0)
for (i = hard_regno_nregs [hard_regno]
@@ -291,7 +304,7 @@ process_copy_locs (copy_t copy_list)
}
#endif
#ifdef SECONDARY_MEMORY_NEEDED
- if (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL)
+ if (COPY_CHANGE_ADDR (cp) != NULL)
{
if ((memory_slot = COPY_MEMORY_SLOT (cp)) != NULL)
(*process_mem_loc_set_func)
@@ -1203,9 +1216,7 @@ process_post_copy_for_sync (rtx insn, copy_t cp)
fprintf (yara_dump_file, " memory is changed by %d\n",
subst_hard_regno);
}
-#ifdef HAVE_ANY_SECONDARY_MOVES
- unassign_copy_secondary (cp);
-#endif
+ unassign_copy (cp);
COPY_SUBST_SRC_HARD_REGNO (cp) = subst_hard_regno;
}
}
@@ -1474,15 +1485,13 @@ get_reg_set_and_memory_slots (copy_t cp, HARD_REG_SET *regs,
}
}
}
-#ifdef HAVE_SECONDARY_RELOADS
- if (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL)
+ if (COPY_CHANGE_ADDR (cp) != NULL)
IOR_HARD_REG_SET (*regs, COPY_INTERM_SCRATCH_HARD_REGSET (cp));
-#endif
*slot1 = (src == NULL ? NULL : ALLOCNO_MEMORY_SLOT (src));
*slot2 = (dst == NULL ? NULL : ALLOCNO_MEMORY_SLOT (dst));
*slot3 = NULL;
#ifdef SECONDARY_MEMORY_NEEDED
- if (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL)
+ if (COPY_CHANGE_ADDR (cp) != NULL)
*slot3 = COPY_MEMORY_SLOT (cp);
#endif
}
@@ -1498,8 +1507,7 @@ copy_can_be_moved_through_copy (copy_t cp, copy_t another_cp)
#ifdef SECONDARY_MEMORY_NEEDED
/* It is rare case -- don't worry about improving the code for
that. */
- if (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL
- || COPY_USER_DEFINED_MEMORY(cp) != NULL)
+ if (COPY_CHANGE_ADDR (cp) == NULL || COPY_USER_DEFINED_MEMORY(cp) != NULL)
return false;
#endif
get_reg_set_and_memory_slots (another_cp, &another_regs, &another_slot1,
@@ -1816,7 +1824,7 @@ emit_secondary_memory_mode_move (rtx dst_rtx, rtx src_rtx, copy_t cp,
{
rtx mem;
- yara_assert (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL);
+ yara_assert (COPY_CHANGE_ADDR (cp) != NULL);
if (COPY_USER_DEFINED_MEMORY (cp) != NULL_RTX)
mem = COPY_USER_DEFINED_MEMORY (cp);
else if (COPY_MEMORY_SLOT (cp) != NULL)
@@ -2005,12 +2013,12 @@ emit_copy (copy_t cp)
{
yara_assert (ALLOCNO_MEMORY_SLOT (dst) == NULL);
#ifdef HAVE_SECONDARY_RELOADS
- yara_assert (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL
+ yara_assert (COPY_CHANGE_ADDR (cp) == NULL
|| (COPY_INTERM_REGNO (cp) < 0
&& COPY_SCRATCH_REGNO (cp) < 0));
#endif
#ifdef SECONDARY_MEMORY_NEEDED
- yara_assert (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL
+ yara_assert (COPY_CHANGE_ADDR (cp) == NULL
|| (COPY_MEMORY_SLOT (cp) == NULL
&& COPY_USER_DEFINED_MEMORY (cp) == NULL_RTX));
#endif
@@ -2123,25 +2131,46 @@ emit_copy (copy_t cp)
}
else
{
- int hard_regno, offset;
+ int hard_regno, to, offset;
+ HOST_WIDE_INT elim_offset;
struct memory_slot *memory_slot;
enum machine_mode cp_mode;
+ rtx x;
try_spill_mode_p = true;
yara_assert (ALLOCNO_REGNO (src) >= 0
&& ! HARD_REGISTER_NUM_P (ALLOCNO_REGNO (src))
&& ALLOCNO_REGNO (dst) >= 0
&& ! HARD_REGISTER_NUM_P (ALLOCNO_REGNO (dst)));
+ yara_assert (! ALLOCNO_USE_EQUIV_CONST_P (dst));
if (ALLOCNO_USE_EQUIV_CONST_P (src))
- abort ();
- get_copy_loc (cp, true, &cp_mode, &hard_regno, &memory_slot, &offset);
- if (hard_regno >= 0)
- src_rtx = gen_allocno_reg_rtx (cp_mode, hard_regno, src);
- else if (memory_slot != NULL)
- src_rtx = get_allocno_memory_slot_rtx (memory_slot, offset, cp_mode,
- src);
+ {
+ x = reg_equiv_constant [ALLOCNO_REGNO (dst)];
+ if (CONSTANT_P (x))
+ src_rtx = x;
+ else
+ {
+ yara_assert (GET_MODE_SIZE (GET_MODE (x))
+ == GET_MODE_SIZE (Pmode));
+ get_equiv_const_elimination_info (x, &to, &elim_offset);
+ src_rtx
+ = gen_rtx_PLUS (GET_MODE (x),
+ gen_allocno_reg_rtx (GET_MODE (x), to, dst),
+ gen_rtx_CONST_INT (VOIDmode, elim_offset));
+ }
+ }
else
- gcc_unreachable ();
+ {
+ get_copy_loc (cp, true, &cp_mode, &hard_regno,
+ &memory_slot, &offset);
+ if (hard_regno >= 0)
+ src_rtx = gen_allocno_reg_rtx (cp_mode, hard_regno, src);
+ else if (memory_slot != NULL)
+ src_rtx = get_allocno_memory_slot_rtx (memory_slot, offset,
+ cp_mode, src);
+ else
+ gcc_unreachable ();
+ }
get_copy_loc (cp, false, &cp_mode, &hard_regno, &memory_slot, &offset);
if (hard_regno >= 0)
dst_rtx = gen_allocno_reg_rtx (cp_mode, hard_regno, dst);
@@ -2152,7 +2181,7 @@ emit_copy (copy_t cp)
gcc_unreachable ();
}
#ifdef HAVE_SECONDARY_RELOADS
- if (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL || COPY_INTERM_REGNO (cp) < 0)
+ if (COPY_CHANGE_ADDR (cp) == NULL || COPY_INTERM_REGNO (cp) < 0)
emit_secondary_memory_move (dst_rtx, src_rtx, cp, alt_mode_1, alt_mode_2,
try_spill_mode_p);
else
@@ -2767,6 +2796,41 @@ yara_eliminate_regs (rtx x, enum machine_mode mem_mode)
return x;
}
+/* The function does elimination of register FROM to register TO for
+ allocno A with an addition OFFSET (beside the usual elimination
+ offset). */
+static void
+eliminate_reg_allocno (allocno_t a, int from, int to, HOST_WIDE_INT offset)
+{
+ rtx *container_loc;
+
+ container_loc = INSN_ALLOCNO_CONTAINER_LOC (a);
+ if (INSN_ALLOCNO_TYPE (a) == BASE_REG
+ || INSN_ALLOCNO_TYPE (a) == INDEX_REG)
+ {
+ /* ??? Another register allocno */
+ if (GET_CODE (*container_loc) == MEM)
+ XEXP (*container_loc, 0)
+ = get_eliminate_subst_rtx (&XEXP (*container_loc, 0),
+ from, to, offset);
+ else
+ *container_loc
+ = get_eliminate_subst_rtx (container_loc, from, to, offset);
+ }
+ else
+ {
+ yara_assert
+ (GET_CODE (*container_loc) == PLUS
+ && REG_P (XEXP (*container_loc, 0))
+ && (int) REGNO (XEXP (*container_loc, 0)) == from
+ && GET_CODE (XEXP (*container_loc, 1)) == CONST_INT);
+ XEXP (*container_loc, 0) = gen_rtx_REG (Pmode, to);
+ XEXP (*container_loc, 1)
+ = gen_rtx_CONST_INT (VOIDmode,
+ INTVAL (XEXP (*container_loc, 1)) + offset);
+ }
+}
+
static void
modify_insn (rtx insn, bool non_operand_p)
{
@@ -2823,10 +2887,21 @@ modify_insn (rtx insn, bool non_operand_p)
}
else if (ALLOCNO_USE_EQUIV_CONST_P (a))
{
+ int to;
+ HOST_WIDE_INT offset;
+ rtx x;
+
yara_assert (ALLOCNO_REGNO (a) >= 0
&& ! HARD_REGISTER_NUM_P (ALLOCNO_REGNO (a)));
yara_assert (REG_P (*INSN_ALLOCNO_LOC (a)));
- *loc = reg_equiv_constant [ALLOCNO_REGNO (a)];
+ x = reg_equiv_constant [ALLOCNO_REGNO (a)];
+ if (CONSTANT_P (x))
+ *loc = x;
+ else
+ {
+ get_equiv_const_elimination_info (x, &to, &offset);
+ eliminate_reg_allocno (a, regno, to, offset);
+ }
if (yara_dump_file != NULL)
{
fprintf (yara_dump_file, "Using equiv constant %d:",
@@ -2845,7 +2920,6 @@ modify_insn (rtx insn, bool non_operand_p)
struct reg_eliminate *elim;
int interm_regno, to;
HOST_WIDE_INT offset;
- rtx *container_loc;
if ((elim = INSN_ALLOCNO_ELIMINATION (a)) == NULL)
{
@@ -2866,35 +2940,7 @@ modify_insn (rtx insn, bool non_operand_p)
register. */
*loc = get_eliminate_subst_rtx (loc, elim->from, to, offset);
else
- {
- container_loc = INSN_ALLOCNO_CONTAINER_LOC (a);
- if (INSN_ALLOCNO_TYPE (a) == BASE_REG
- || INSN_ALLOCNO_TYPE (a) == INDEX_REG)
- {
- /* ??? Another register allocno */
- if (GET_CODE (*container_loc) == MEM)
- XEXP (*container_loc, 0)
- = get_eliminate_subst_rtx (&XEXP (*container_loc, 0),
- elim->from, to, offset);
- else
- *container_loc
- = get_eliminate_subst_rtx (container_loc,
- elim->from, to, offset);
- }
- else
- {
- yara_assert
- (GET_CODE (*container_loc) == PLUS
- && REG_P (XEXP (*container_loc, 0))
- && (int) REGNO (XEXP (*container_loc, 0)) == elim->from
- && GET_CODE (XEXP (*container_loc, 1)) == CONST_INT);
- XEXP (*container_loc, 0) = gen_rtx_REG (Pmode, to);
- XEXP (*container_loc, 1)
- = gen_rtx_CONST_INT (VOIDmode,
- INTVAL (XEXP (*container_loc, 1))
- + offset);
- }
- }
+ eliminate_reg_allocno (a, elim->from, to, offset);
}
else
{
diff --git a/gcc/yara-insn.c b/gcc/yara-insn.c
index c68164b2e7d..ed4ab5edc93 100644
--- a/gcc/yara-insn.c
+++ b/gcc/yara-insn.c
@@ -68,7 +68,8 @@ static bool assign_insn_allocnos_without_copy (rtx insn);
static bool
check_alternative_possibility (allocno_t a, const char *p, bool strict_p)
{
- rtx op, no_subreg_op, equiv_const;
+ rtx x, op, no_subreg_op, equiv_const;
+ allocno_t another_a;
int c = *p;
op = *INSN_ALLOCNO_LOC (a);
@@ -164,15 +165,27 @@ check_alternative_possibility (allocno_t a, const char *p, bool strict_p)
((MEM_P (no_subreg_op) && c == 'm')
|| (c == 'o'
&& offsettable_nonstrict_memref_p (no_subreg_op)))));
+ else if ((MEM_P (no_subreg_op) && c == 'm')
+ || (c == 'o' && offsettable_nonstrict_memref_p (no_subreg_op)))
+ return true;
+ /* Accept a register which might be placed in memory. */
+ else if (REG_P (no_subreg_op)
+ && (! strict_p || ALLOCNO_MEMORY_SLOT (a) != NULL))
+ return true;
+ /* Accept a register which might be placed in memory. */
+ else if (CONST_POOL_OK_P (op)
+ || (equiv_const != NULL_RTX && CONST_POOL_OK_P (equiv_const)))
+ {
+ if (! INSN_ALLOCNO_ELIMINATION_PART_CONST_P (a))
+ return true;
+ x = *INSN_ALLOCNO_CONTAINER_LOC (a);
+ yara_assert (GET_CODE (x) == PLUS && XEXP (x, 1) == op);
+ another_a = insn_allocno (XEXP (x, 0), INSN_ALLOCNO_INSN (a));
+ yara_assert (another_a != NULL);
+ return ! ALLOCNO_USE_EQUIV_CONST_P (another_a);
+ }
else
- return ((MEM_P (no_subreg_op) && c == 'm')
- || (c == 'o' && offsettable_nonstrict_memref_p (no_subreg_op))
- /* We could accept a constant that can be turned into
- memory. */
- || CONST_POOL_OK_P (op)
- || (equiv_const != NULL_RTX && CONST_POOL_OK_P (equiv_const))
- /* Accept a register which might be placed in memory. */
- || REG_P (no_subreg_op));
+ return false;
case 'V':
if (strict_p && ! INSN_ALLOCNO_USE_WITHOUT_CHANGE_P (a))
@@ -234,6 +247,33 @@ check_alternative_possibility (allocno_t a, const char *p, bool strict_p)
&& hard_reg_in_set_p (hard_regno, mode,
reg_class_contents [cl]))
return true;
+ if (INSN_ALLOCNO_ELIMINATION_PART_CONST_P (a))
+ {
+ x = *INSN_ALLOCNO_CONTAINER_LOC (a);
+ yara_assert (GET_CODE (x) == PLUS && XEXP (x, 1) == op);
+ another_a = insn_allocno (XEXP (x, 0),
+ INSN_ALLOCNO_INSN (a));
+ yara_assert (another_a != NULL);
+ if (! ALLOCNO_USE_EQUIV_CONST_P (another_a))
+ return true;
+ }
+ else if (equiv_const != NULL_RTX && op == no_subreg_op
+ && ! CONSTANT_P (equiv_const))
+ {
+ x = *INSN_ALLOCNO_CONTAINER_LOC (a);
+ if (GET_CODE (x) == PLUS)
+ {
+ another_a
+ = insn_allocno (XEXP (x, 1), INSN_ALLOCNO_INSN (a));
+ if (INSN_ALLOCNO_ELIMINATION_PART_CONST_P (another_a)
+ && ALLOCNO_HARD_REGNO (another_a) < 0
+ && ALLOCNO_MEMORY_SLOT (another_a) == NULL
+ && hard_reg_in_set_p (REGNO (XEXP (equiv_const, 0)),
+ ALLOCNO_MODE (a),
+ reg_class_contents [cl]))
+ return true;
+ }
+ }
}
#ifdef EXTRA_CONSTRAINT_STR
else if (EXTRA_CONSTRAINT_STR (op, c, p))
@@ -473,7 +513,8 @@ assign_hard_regno_to_pseudo_reg_insn_allocno (allocno_t a, enum reg_class cl,
static bool
assign_constraint (allocno_t a, const char *p)
{
- rtx op, no_subreg_op, equiv_const;
+ rtx x, op, no_subreg_op, equiv_const;
+ allocno_t another_a;
bool success_p;
int before;
int c = *p;
@@ -616,15 +657,27 @@ assign_constraint (allocno_t a, const char *p)
}
/* We could accept a constant that can be turned into mem. */
else if (CONST_POOL_OK_P (op)
- || (0 && equiv_const != NULL_RTX
+ || (equiv_const != NULL_RTX
&& CONST_POOL_OK_P (equiv_const)))
{
+ rtx x;
+
yara_assert (equiv_const != NULL_RTX
|| (ALLOCNO_SRC_COPIES (a) == NULL
&& INSN_ALLOCNO_TIED_ALLOCNO (a) == NULL));
- success_p = (! INSN_ALLOCNO_ELIMINATION_PART_CONST_P (a)
- && assign_allocno (a, NO_REGS,
- reg_class_contents [NO_REGS], -1));
+ if (! INSN_ALLOCNO_ELIMINATION_PART_CONST_P (a))
+ success_p = true;
+ else
+ {
+ x = *INSN_ALLOCNO_CONTAINER_LOC (a);
+ yara_assert (GET_CODE (x) == PLUS && XEXP (x, 1) == op);
+ another_a = insn_allocno (XEXP (x, 0), INSN_ALLOCNO_INSN (a));
+ yara_assert (another_a != NULL);
+ success_p = ! ALLOCNO_USE_EQUIV_CONST_P (another_a);
+ }
+ success_p
+ = success_p && assign_allocno (a, NO_REGS,
+ reg_class_contents [NO_REGS], -1);
}
/* Accept a register which might be placed in memory. */
else if (REG_P (no_subreg_op))
@@ -722,15 +775,51 @@ assign_constraint (allocno_t a, const char *p)
(a, cl, reg_class_contents [cl]))
success_p = true;
}
- else if (! INSN_ALLOCNO_ELIMINATION_PART_CONST_P (a)
- && assign_hard_regno_to_pseudo_reg_insn_allocno
- (a, cl, reg_class_contents [cl]))
- success_p = true;
- /* Accept a register which might be placed in memory. */
- else if (c == 'g' && REG_P (no_subreg_op))
- success_p = assign_allocno (a, NO_REGS,
- reg_class_contents [NO_REGS], -1);
- /* We can fail here because a wrong copy is active. */
+ else
+ {
+ if (INSN_ALLOCNO_ELIMINATION_PART_CONST_P (a))
+ {
+ x = *INSN_ALLOCNO_CONTAINER_LOC (a);
+ yara_assert (GET_CODE (x) == PLUS && XEXP (x, 1) == op);
+ another_a = insn_allocno (XEXP (x, 0),
+ INSN_ALLOCNO_INSN (a));
+ yara_assert (another_a != NULL);
+ if (ALLOCNO_USE_EQUIV_CONST_P (another_a))
+ break;
+ }
+ else if (equiv_const != NULL_RTX && op == no_subreg_op
+ && ! CONSTANT_P (equiv_const))
+ {
+ x = *INSN_ALLOCNO_CONTAINER_LOC (a);
+ if (GET_CODE (x) == PLUS)
+ {
+ another_a
+ = insn_allocno (XEXP (x, 1), INSN_ALLOCNO_INSN (a));
+ if (INSN_ALLOCNO_ELIMINATION_PART_CONST_P (another_a)
+ && ALLOCNO_HARD_REGNO (another_a) < 0
+ && ALLOCNO_MEMORY_SLOT (another_a) == NULL
+ && hard_reg_in_set_p (REGNO (XEXP (equiv_const,
+ 0)),
+ ALLOCNO_MODE (a),
+ reg_class_contents [cl])
+ && assign_allocno (a, LIM_REG_CLASSES,
+ reg_class_contents [NO_REGS],
+ -1))
+ {
+ success_p = true;
+ break;
+ }
+ }
+ }
+ if (assign_hard_regno_to_pseudo_reg_insn_allocno
+ (a, cl, reg_class_contents [cl]))
+ success_p = true;
+ /* Accept a register which might be placed in memory. */
+ else if (c == 'g' && REG_P (no_subreg_op))
+ success_p
+ = assign_allocno (a, NO_REGS,
+ reg_class_contents [NO_REGS], -1);
+ }
break;
}
#ifdef EXTRA_CONSTRAINT_STR
@@ -749,8 +838,6 @@ assign_constraint (allocno_t a, const char *p)
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
- allocno_t another_a;
-
another_a = (insn_op_allocnos
[INSN_UID (INSN_ALLOCNO_INSN (a))] [c - '0']);
yara_assert ((INSN_ALLOCNO_OP_MODE (a) == OP_IN
@@ -977,9 +1064,38 @@ find_best_alt_allocation_1 (void)
reg_class_contents [NO_REGS], -1))
gcc_unreachable ();
}
- else if (! assign_hard_regno_to_pseudo_reg_insn_allocno
- (a, cl, temp_set))
- break;
+ else
+ {
+ int to;
+ bool base_p;
+ HOST_WIDE_INT offset;
+ bool cont_p = true;
+ rtx x, *address_loc, *container_loc;
+
+ if ((x = reg_equiv_constant [ALLOCNO_REGNO (a)]) != NULL_RTX
+ && ! CONSTANT_P (x))
+ {
+ get_equiv_const_elimination_info (x, &to, &offset);
+ get_equiv_const_addr_info (x, &to, &offset);
+ container_loc = INSN_ALLOCNO_CONTAINER_LOC (a);
+ address_loc = (GET_CODE (*container_loc) == MEM
+ ? &XEXP (*container_loc, 0)
+ : container_loc);
+ /* ??? Allocate interm equiv constant register. Do
+ we need this? */
+ if (check_elimination_in_addr (ALLOCNO_REGNO (a), to,
+ offset, address_loc,
+ container_loc,
+ &base_p) != NULL
+ && assign_allocno (a, LIM_REG_CLASSES,
+ reg_class_contents [NO_REGS], -1))
+ cont_p = false;
+ }
+ if (cont_p
+ && ! assign_hard_regno_to_pseudo_reg_insn_allocno
+ (a, cl, temp_set))
+ break;
+ }
}
else if (INSN_ALLOCNO_TYPE (a) == NON_OPERAND)
{
@@ -1319,6 +1435,8 @@ assign_insn_allocnos_without_copy (rtx insn)
{
if ((regno = ALLOCNO_REGNO (a)) >= 0 && ! HARD_REGISTER_NUM_P (regno))
{
+ /* If connected allocnos use equiv. constants we try them in
+ find_best_allocation. */
if (! assign_pseudo_allocno_from_connected_allocno (a))
break;
if (INSN_ALLOCNO_TYPE (a) == BASE_REG
@@ -1336,6 +1454,8 @@ assign_insn_allocnos_without_copy (rtx insn)
}
else if (! assign_allocno (a, LIM_REG_CLASSES,
reg_class_contents [NO_REGS], -1))
+ /* We assume that if hard register is used as a base or index
+ register it already has a right class. */
break;
if (INSN_ALLOCNO_TYPE (a) >= OPERAND_BASE)
{
@@ -1440,9 +1560,35 @@ allocate_insn_allocnos (rtx insn, bool (*call_cross_hint) (allocno_t),
reg_class_contents [NO_REGS], -1))
gcc_unreachable ();
}
- else if (! assign_hard_regno_to_pseudo_reg_insn_allocno (a, cl,
- temp_set))
- gcc_unreachable ();
+ else
+ {
+ int to;
+ bool base_p;
+ HOST_WIDE_INT offset;
+ bool cont_p = true;
+ rtx x, *address_loc, *container_loc;
+
+ if ((x = reg_equiv_constant [ALLOCNO_REGNO (a)]) != NULL_RTX
+ && ! CONSTANT_P (x))
+ {
+ get_equiv_const_addr_info (x, &to, &offset);
+ container_loc = INSN_ALLOCNO_CONTAINER_LOC (a);
+ address_loc = (GET_CODE (*container_loc) == MEM
+ ? &XEXP (*container_loc, 0) : container_loc);
+ /* ??? Allocate interm equiv constant register. Do
+ we need this? */
+ if (check_elimination_in_addr (ALLOCNO_REGNO (a), to, offset,
+ address_loc, container_loc,
+ &base_p) != NULL
+ && assign_allocno (a, LIM_REG_CLASSES,
+ reg_class_contents [NO_REGS], -1))
+ cont_p = false;
+ }
+ if (cont_p
+ && ! assign_hard_regno_to_pseudo_reg_insn_allocno (a, cl,
+ temp_set))
+ gcc_unreachable ();
+ }
}
else
{
diff --git a/gcc/yara-int.h b/gcc/yara-int.h
index 29b8824bbce..4b0bfbbb4c0 100644
--- a/gcc/yara-int.h
+++ b/gcc/yara-int.h
@@ -46,10 +46,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#define yara_assert(c)
#endif
-#if defined (HAVE_SECONDARY_RELOADS) || defined (SECONDARY_MEMORY_NEEDED)
-#define HAVE_ANY_SECONDARY_MOVES 1
-#endif
-
/* True if X is a constant that can be forced into the constant pool. */
#define CONST_POOL_OK_P(X) \
(CONSTANT_P (X) \
@@ -335,13 +331,11 @@ struct allocno_common
int conflict_vec_len;
/* Vector of conflicting allocnos with NULL end marker. */
allocno_t *conflict_vec;
-#ifdef HAVE_ANY_SECONDARY_MOVES
/* The field value is allocated length without one of the subsequent
vector. */
int copy_conflict_vec_len;
/* Vector of conflicting copies with NULL end marker. */
copy_t *copy_conflict_vec;
-#endif
/* Set of hard regs conflicting with allocno N. */
HARD_REG_SET hard_reg_conflicts;
@@ -485,10 +479,8 @@ union allocno_node
#define ALLOCNO_CONFLICT_VEC(A) ((A)->common.conflict_vec)
#define ALLOCNO_CONFLICT_VEC_LEN(A) ((A)->common.conflict_vec_len)
-#ifdef HAVE_ANY_SECONDARY_MOVES
#define ALLOCNO_COPY_CONFLICT_VEC(A) ((A)->common.copy_conflict_vec)
#define ALLOCNO_COPY_CONFLICT_VEC_LEN(A) ((A)->common.copy_conflict_vec_len)
-#endif
#define ALLOCNO_HARD_REG_CONFLICTS(A) ((A)->common.hard_reg_conflicts)
#define ALLOCNO_CALL_CROSS_P(A) ((A)->common.call_cross_p)
#define ALLOCNO_CALL_FREQ(A) ((A)->common.call_freq)
@@ -578,12 +570,9 @@ extern allocno_t *insn_allocnos;
number -> allocno corresponding the insn operand. */
extern allocno_t **insn_op_allocnos;
-
-#ifdef HAVE_ANY_SECONDARY_MOVES
-
/* The following structure contains copy attributes which should be
logged during transactions. */
-struct secondary_copy_change
+struct copy_change
{
#ifdef HAVE_SECONDARY_RELOADS
/* The following true value means that we use icode insn with src as
@@ -601,6 +590,10 @@ struct secondary_copy_change
the value is -1. */
short scratch_regno;
#endif
+ /* The following hard register (in given mode) might be needed to
+ load equivalent constant into the destination allocno. */
+ short interm_equiv_const_regno;
+ enum machine_mode interm_equiv_const_mode : 8;
/* The following two member values are used only when secondary
memory is needed. We don't need secondary memory if the two
values are NULL. */
@@ -611,28 +604,16 @@ struct secondary_copy_change
/* Allocated memory used only the previous value is NULL. */
struct memory_slot *memory_slot;
#endif
-#ifdef HAVE_SECONDARY_RELOADS
- /* The following set contains all hard regnos of intermediate and
- scratch registers. */
+ /* The following set contains all hard regnos of intermediate,
+ scratch and intermidiate equiv const registers. */
HARD_REG_SET interm_scratch_hard_regset;
-#endif
-};
-
-#endif /* #ifdef HAVE_ANY_SECONDARY_MOVES */
-
-struct copy_change
-{
-#ifdef HAVE_ANY_SECONDARY_MOVES
- struct secondary_copy_change *secondary_change;
-#endif
};
-
/* The following describes change log entry for copy. */
struct copy_log_entry
{
copy_t copy;
- struct copy_change change;
+ struct copy_change *copy_change;
};
/* The following structure describes allocno connection. If the
@@ -661,21 +642,16 @@ struct copy
location. */
short subst_src_hard_regno : 15;
-#ifdef HAVE_ANY_SECONDARY_MOVES
- /* ??? */
-#ifdef HAVE_SECONDARY_RELOADS
/* Set of hard regs conflicting with the copy. */
HARD_REG_SET hard_reg_conflicts;
-#endif
/* The field value is allocated length without one of the subsequent
vector. */
int allocno_conflict_vec_len;
/* Vector of conflicting allocnos with NULL end marker. */
allocno_t *allocno_conflict_vec;
-#endif
/* Copy attributes should be logged. */
- struct copy_change change;
+ struct copy_change *copy_change;
};
/* Array of references to copies after forming all of them. */
@@ -693,37 +669,35 @@ extern int copies_num;
#define COPY_POINT(C) ((C)->point)
-#ifdef HAVE_SECONDARY_RELOADS
-#define COPY_SECONDARY_CHANGE_ADDR(C) ((C)->change.secondary_change)
-#endif
+#define COPY_CHANGE_ADDR(C) ((C)->copy_change)
-#ifdef HAVE_ANY_SECONDARY_MOVES
#define COPY_ALLOCNO_CONFLICT_VEC(C) ((C)->allocno_conflict_vec)
#define COPY_ALLOCNO_CONFLICT_VEC_LEN(C) ((C)->allocno_conflict_vec_len)
-#endif
-#ifdef HAVE_SECONDARY_RELOADS
#define COPY_HARD_REG_CONFLICTS(C) ((C)->hard_reg_conflicts)
-#endif
#define COPY_FREQ(C) ((C)->freq)
#define COPY_SYNC_P(C) ((C)->sync_p)
#define COPY_SUBST_SRC_HARD_REGNO(C) ((C)->subst_src_hard_regno)
#define COPY_CHANGE(C) ((C)->change)
#ifdef HAVE_SECONDARY_RELOADS
-#define COPY_ICODE(C) (COPY_SECONDARY_CHANGE_ADDR (C)->icode)
-#define COPY_INTERM_MODE(C) (COPY_SECONDARY_CHANGE_ADDR (C)->interm_mode)
-#define COPY_SCRATCH_MODE(C) (COPY_SECONDARY_CHANGE_ADDR (C)->scratch_mode)
-#define COPY_INTERM_REGNO(C) (COPY_SECONDARY_CHANGE_ADDR (C)->interm_regno)
-#define COPY_SCRATCH_REGNO(C) (COPY_SECONDARY_CHANGE_ADDR (C)->scratch_regno)
-#define COPY_INTERM_SCRATCH_HARD_REGSET(C) \
- (COPY_SECONDARY_CHANGE_ADDR (C)->interm_scratch_hard_regset)
-#define COPY_IN_P(C) (COPY_SECONDARY_CHANGE_ADDR (C)->in_p)
+#define COPY_ICODE(C) (COPY_CHANGE_ADDR (C)->icode)
+#define COPY_INTERM_MODE(C) (COPY_CHANGE_ADDR (C)->interm_mode)
+#define COPY_SCRATCH_MODE(C) (COPY_CHANGE_ADDR (C)->scratch_mode)
+#define COPY_INTERM_REGNO(C) (COPY_CHANGE_ADDR (C)->interm_regno)
+#define COPY_SCRATCH_REGNO(C) (COPY_CHANGE_ADDR (C)->scratch_regno)
+#define COPY_IN_P(C) (COPY_CHANGE_ADDR (C)->in_p)
#endif
+#define COPY_INTERM_SCRATCH_HARD_REGSET(C) \
+ (COPY_CHANGE_ADDR (C)->interm_scratch_hard_regset)
+#define COPY_INTERM_EQUIV_CONST_REGNO(C) \
+ (COPY_CHANGE_ADDR (C)->interm_equiv_const_regno)
+#define COPY_INTERM_EQUIV_CONST_MODE(C) \
+ (COPY_CHANGE_ADDR (C)->interm_equiv_const_mode)
#ifdef SECONDARY_MEMORY_NEEDED
-#define COPY_MEMORY_MODE(C) (COPY_SECONDARY_CHANGE_ADDR (C)->memory_mode)
+#define COPY_MEMORY_MODE(C) (COPY_CHANGE_ADDR (C)->memory_mode)
#define COPY_USER_DEFINED_MEMORY(C) \
- (COPY_SECONDARY_CHANGE_ADDR (C)->user_defined_memory)
-#define COPY_MEMORY_SLOT(C) (COPY_SECONDARY_CHANGE_ADDR (C)->memory_slot)
+ (COPY_CHANGE_ADDR (C)->user_defined_memory)
+#define COPY_MEMORY_SLOT(C) (COPY_CHANGE_ADDR (C)->memory_slot)
#endif
/* Copies attached to the insns, basic blocks, edges in the same order
@@ -967,9 +941,7 @@ extern bool hard_reg_in_set_p (int, enum machine_mode, HARD_REG_SET);
extern bool hard_reg_not_in_set_p (int, enum machine_mode, HARD_REG_SET);
extern int allocno_copy_cost (allocno_t);
-#ifdef HAVE_ANY_SECONDARY_MOVES
-extern void unassign_copy_secondary (copy_t);
-#endif
+extern void unassign_copy (copy_t);
extern enum machine_mode get_allocation_mode (allocno_t);
extern int get_allocno_hard_regno (allocno_t, int);
extern int get_allocno_reg_hard_regno (allocno_t, int);
@@ -995,10 +967,16 @@ extern bool assign_hard_regno_to_allocno_with_unassign (allocno_t,
extern bool assign_class_allocno_with_unassign (allocno_t, enum reg_class,
HARD_REG_SET);
-extern bool check_hard_regno_memory_on_contraint (allocno_t, bool, int);
+extern bool check_hard_regno_memory_on_constraint (allocno_t, bool, int);
+extern struct reg_eliminate *check_elimination_in_addr (int, int,
+ HOST_WIDE_INT,
+ rtx *, rtx *, bool *);
extern bool eliminate_reg (allocno_t);
extern void uneliminate_reg (allocno_t a);
+extern void get_equiv_const_addr_info (rtx, int *, HOST_WIDE_INT *);
+
+extern void get_equiv_const_elimination_info (rtx, int *, HOST_WIDE_INT *);
extern void eliminate_virtual_registers (int (*) (allocno_t, enum reg_class,
HARD_REG_SET));
diff --git a/gcc/yara-ir.c b/gcc/yara-ir.c
index e60200e4297..94db2fb348c 100644
--- a/gcc/yara-ir.c
+++ b/gcc/yara-ir.c
@@ -158,9 +158,7 @@ static void setup_mode_multi_reg_p (void);
static void initiate_conflicts (void);
static void create_conflict (allocno_t, allocno_t);
-#ifdef HAVE_ANY_SECONDARY_MOVES
static void create_copy_conflict (allocno_t, copy_t);
-#endif
static void finish_conflicts (void);
static void create_regno_allocno_maps (void);
@@ -194,9 +192,7 @@ static enum reg_class single_alt_reg_class (const char *,
struct insn_op_info *, int);
static enum reg_class single_reg_operand_class (rtx insn, int);
-#ifdef HAVE_ANY_SECONDARY_MOVES
static void set_copy_conflict (allocno_t, void *, int);
-#endif
static void build_insn_allocno_copy_conflicts (copy_t, rtx, bool);
static void set_call_info (allocno_t, void *, int);
static void build_insn_allocno_conflicts (rtx, op_set_t);
@@ -1181,7 +1177,6 @@ scan_insn_for_reg_equivs (rtx insn)
int i;
rtx set = single_set (insn);
bool eliminable_invariant_p;
-
eliminable_invariant_p = false;
if (set != 0 && REG_P (SET_DEST (set)))
{
@@ -1447,10 +1442,8 @@ create_allocno (enum allocno_type type, int regno, enum machine_mode mode)
ALLOCNO_DST_COPIES (a) = ALLOCNO_SRC_COPIES (a) = NULL;
ALLOCNO_CONFLICT_VEC (a) = NULL;
ALLOCNO_CONFLICT_VEC_LEN (a) = 0;
-#ifdef HAVE_ANY_SECONDARY_MOVES
ALLOCNO_COPY_CONFLICT_VEC_LEN (a) = 0;
ALLOCNO_COPY_CONFLICT_VEC (a) = NULL;
-#endif
#ifdef CONFLICT_CACHE
CLEAR_HARD_REG_SET (ALLOCNO_CACHED_CONFLICT_HARD_REGS (a));
ALLOCNO_CACHE_VALID_P (a) = true;
@@ -1466,9 +1459,7 @@ print_copy (FILE *f, copy_t cp, bool dst_p)
int i;
allocno_t a = (dst_p ? COPY_DST (cp) : COPY_SRC (cp));
bool new_line_p = false;
-#ifdef HAVE_ANY_SECONDARY_MOVES
allocno_t *vec;
-#endif
fprintf (f, "%5d:", COPY_NUM (cp));
if (a == NULL)
@@ -1477,7 +1468,7 @@ print_copy (FILE *f, copy_t cp, bool dst_p)
fprintf (f, "%5d(", ALLOCNO_NUM (a));
print_point (f, &COPY_POINT (cp));
#ifdef HAVE_SECONDARY_RELOADS
- if (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL)
+ if (COPY_CHANGE_ADDR (cp) != NULL)
{
if (COPY_INTERM_REGNO (cp) >= 0)
fprintf (f, ", interm. %d(%s)", COPY_INTERM_REGNO (cp),
@@ -1490,8 +1481,11 @@ print_copy (FILE *f, copy_t cp, bool dst_p)
new_line_p = true;
}
#endif
+ if (COPY_CHANGE_ADDR (cp) != NULL && COPY_INTERM_EQUIV_CONST_REGNO (cp) >= 0)
+ fprintf (f, ", equiv interm. %d(%s)", COPY_INTERM_EQUIV_CONST_REGNO (cp),
+ GET_MODE_NAME (COPY_INTERM_EQUIV_CONST_MODE (cp)));
#ifdef SECONDARY_MEMORY_NEEDED
- if (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL)
+ if (COPY_CHANGE_ADDR (cp) != NULL)
{
if (COPY_USER_DEFINED_MEMORY (cp) != NULL_RTX)
{
@@ -1505,14 +1499,12 @@ print_copy (FILE *f, copy_t cp, bool dst_p)
}
#endif
fprintf (f, new_line_p ? ")\n" : ")");
-#ifdef HAVE_ANY_SECONDARY_MOVES
fprintf (f, " Copy conflicts:");
vec = COPY_ALLOCNO_CONFLICT_VEC (cp);
if (vec != NULL)
for (i = 0; (a = vec [i]) != NULL; i++)
fprintf (f, "%5d", ALLOCNO_NUM (a));
fprintf (f, "\n");
-#endif
}
const char *
@@ -1653,10 +1645,8 @@ free_allocno (allocno_t a)
{
if (ALLOCNO_CONFLICT_VEC (a) != NULL)
yara_free (ALLOCNO_CONFLICT_VEC (a));
-#ifdef HAVE_ANY_SECONDARY_MOVES
if (ALLOCNO_COPY_CONFLICT_VEC (a) != NULL)
yara_free (ALLOCNO_COPY_CONFLICT_VEC (a));
-#endif
yara_free (a);
}
@@ -1735,17 +1725,11 @@ create_copy (allocno_t dst, allocno_t src, struct point point, rtx insn)
ALLOCNO_SRC_COPIES (src) = cp;
}
COPY_POINT (cp) = point;
-#ifdef HAVE_ANY_SECONDARY_MOVES
COPY_ALLOCNO_CONFLICT_VEC (cp) = NULL;
COPY_ALLOCNO_CONFLICT_VEC_LEN (cp) = 0;
-#endif
-#ifdef HAVE_SECONDARY_RELOADS
CLEAR_HARD_REG_SET (COPY_HARD_REG_CONFLICTS (cp));
-#endif
-#ifdef HAVE_SECONDARY_RELOADS
- COPY_SECONDARY_CHANGE_ADDR (cp) = NULL;
-#endif
+ COPY_CHANGE_ADDR (cp) = NULL;
COPY_FREQ (cp) = point_freq (&point);
COPY_SYNC_P (cp) = false;
@@ -1853,10 +1837,8 @@ sort_copy_list (copy_t list,
static void
free_copy (copy_t cp)
{
-#ifdef HAVE_ANY_SECONDARY_MOVES
if (COPY_ALLOCNO_CONFLICT_VEC (cp) != NULL)
yara_free (COPY_ALLOCNO_CONFLICT_VEC (cp));
-#endif
yara_free (cp);
}
@@ -1917,11 +1899,9 @@ initiate_conflicts (void)
VARRAY_GENERIC_PTR_NOGC_INIT (pending_allocno_conflict_varray,
yara_max_uid * 100,
"pending allocno conflicts");
-#ifdef HAVE_ANY_SECONDARY_MOVES
VARRAY_GENERIC_PTR_NOGC_INIT (pending_allocno_copy_conflict_varray,
yara_max_uid * 100,
"pending allocno copy conflicts");
-#endif
}
bool
@@ -2049,24 +2029,9 @@ commit_conflicts (void)
VARRAY_FREE (pending_allocno_conflict_varray);
}
-#ifdef HAVE_ANY_SECONDARY_MOVES
-
static void
create_copy_conflict (allocno_t a, copy_t cp)
{
-#if 0
-#ifdef SECONDARY_RELOAD_MODE_P
- {
- enum machine_mode mode;
-
- if ((COPY_SRC (cp) == NULL
- || ! SECONDARY_RELOAD_MODE_P (ALLOCNO_MODE (COPY_SRC (cp))))
- && (COPY_DST (cp) == NULL
- || ! SECONDARY_RELOAD_MODE_P (ALLOCNO_MODE (COPY_DST (cp)))))
- return;
- }
-#endif
-#endif
VARRAY_PUSH_GENERIC_PTR (pending_allocno_copy_conflict_varray, a);
VARRAY_PUSH_GENERIC_PTR (pending_allocno_copy_conflict_varray, cp);
ALLOCNO_COPY_CONFLICT_VEC_LEN (a)++;
@@ -2118,8 +2083,6 @@ commit_copy_conflicts (void)
VARRAY_FREE (pending_allocno_copy_conflict_varray);
}
-#endif
-
static void
finish_conflicts (void)
{
@@ -3006,8 +2969,6 @@ mark_allocno_death (allocno_t a)
}
}
-#ifdef HAVE_ANY_SECONDARY_MOVES
-
static void
set_copy_conflict (allocno_t live_a, void *data,
int local_live_index ATTRIBUTE_UNUSED)
@@ -3017,8 +2978,6 @@ set_copy_conflict (allocno_t live_a, void *data,
create_copy_conflict (live_a, cp);
}
-#endif
-
static bool
copy_src_p (copy_t list, allocno_t src)
{
@@ -3092,12 +3051,8 @@ build_insn_allocno_copy_conflicts (copy_t list, rtx insn, bool after_insn_p)
}
}
-#ifdef HAVE_ANY_SECONDARY_MOVES
process_live_allocnos (set_copy_conflict, cp);
-#ifdef HAVE_SECONDARY_RELOADS
COPY_HARD_REG_SET (COPY_HARD_REG_CONFLICTS (cp), live_hard_regs);
-#endif
-#endif
if (COPY_DST (cp) != NULL)
mark_allocno_live (COPY_DST (cp), no_map_change_p);
@@ -5560,6 +5515,14 @@ make_aggressive_coalescing (void)
&src_copy, &dst_copy);
src = COPY_SRC (src_copy);
dst = COPY_DST (dst_copy);
+ if (reg_equiv_constant [ALLOCNO_REGNO (src)] != NULL_RTX
+ && reg_equiv_constant [ALLOCNO_REGNO (dst)] == NULL_RTX)
+ /* Coalescing cans with allocnos which have equiv
+ constant can create problem during global
+ allocations because such move might need an
+ intermediate register. Even if we fix that I
+ believe it will not generate a better code. */
+ continue;
move = get_move (src, dst, BLOCK_FOR_INSN (insn)->frequency);
VARRAY_PUSH_GENERIC_PTR (move_varray, move);
VARRAY_PUSH_RTX (move_insn_varray, insn);
@@ -6061,9 +6024,7 @@ yara_ir_init (void)
copies = (copy_t *) &VARRAY_GENERIC_PTR (copy_varray, 0);
copies_num = VARRAY_ACTIVE_SIZE (copy_varray);
commit_conflicts ();
-#ifdef HAVE_ANY_SECONDARY_MOVES
commit_copy_conflicts ();
-#endif
#ifdef ENABLE_YARA_CHECKING
check_abnormal_edges ();
#endif
diff --git a/gcc/yara-trans.c b/gcc/yara-trans.c
index 3babb3593e1..33bb658e7bf 100644
--- a/gcc/yara-trans.c
+++ b/gcc/yara-trans.c
@@ -76,6 +76,11 @@ static void reserve_stack_memory (int, int);
static int find_free_stack_memory (int, int);
static void finish_stack_memory (void);
+static void initiate_copy_changes (void);
+static void free_copy_change (struct copy_change *);
+static struct copy_change *get_free_copy_change (void);
+static void finish_copy_changes (void);
+
static struct memory_slot *get_free_memory_slot_structure (void);
static void free_memory_slot_structure (struct memory_slot *);
static void switch_on_pending_memory_slot_structures (void);
@@ -114,11 +119,11 @@ static int find_hard_reg_for_mode (enum reg_class, enum machine_mode,
static bool allocate_copy_secondary_memory (bool, copy_t, int, enum reg_class,
enum reg_class, enum machine_mode);
#endif
-#ifdef HAVE_ANY_SECONDARY_MOVES
-static bool assign_copy_secondary (copy_t);
-static bool assign_secondary (allocno_t);
-static void unassign_secondary (allocno_t a);
-#endif
+static bool assign_copy_interm_equiv_const_hard_reg (copy_t);
+static void unassign_copy_interm_equiv_const_hard_reg (copy_t);
+static bool assign_copy (copy_t);
+static bool assign_allocno_copies (allocno_t);
+static void unassign_allocno_copies (allocno_t a);
static bool check_hard_regno_for_a (allocno_t, int, HARD_REG_SET);
static bool collect_conflict_hard_regs (allocno_t, HARD_REG_SET *);
static bool assign_allocno_hard_regno (allocno_t, int, HARD_REG_SET);
@@ -131,8 +136,6 @@ static void possible_alt_reg_intersection (allocno_t, HARD_REG_SET *);
static bool all_alt_offset_ok_p (allocno_t, HOST_WIDE_INT);
static bool find_interm_elimination_reg (allocno_t, enum reg_class,
HARD_REG_SET);
-static struct reg_eliminate *check_elimination_in_addr (rtx *, rtx *, bool *);
-
static struct log_entry *get_free_log_entry (void);
static void free_log_entry (struct log_entry *);
static void free_all_log_entries (void);
@@ -311,71 +314,67 @@ finish_stack_memory (void)
-#ifdef HAVE_ANY_SECONDARY_MOVES
-
-static struct secondary_copy_change *free_secondary_copy_changes;
-static varray_type secondary_copy_change_varray;
+static struct copy_change *free_copy_changes;
+static varray_type copy_change_varray;
static void
-initiate_secondary_copy_changes (void)
+initiate_copy_changes (void)
{
- free_secondary_copy_changes = NULL;
- VARRAY_GENERIC_PTR_NOGC_INIT (secondary_copy_change_varray, 2000,
- "all secondary copy changes");
+ free_copy_changes = NULL;
+ VARRAY_GENERIC_PTR_NOGC_INIT (copy_change_varray, 2000, "all copy changes");
}
static void
-free_secondary_copy_change (struct secondary_copy_change *change)
+free_copy_change (struct copy_change *change)
{
- *(struct secondary_copy_change **) change = free_secondary_copy_changes;
- free_secondary_copy_changes = change;
+ *(struct copy_change **) change = free_copy_changes;
+ free_copy_changes = change;
}
-static struct secondary_copy_change *
-get_free_secondary_copy_change (void)
+static struct copy_change *
+get_free_copy_change (void)
{
- struct secondary_copy_change *result;
+ struct copy_change *result;
- if (free_secondary_copy_changes == NULL)
+ if (free_copy_changes == NULL)
{
- result = yara_allocate (sizeof (struct secondary_copy_change));
- VARRAY_PUSH_GENERIC_PTR (secondary_copy_change_varray, result);
+ result = yara_allocate (sizeof (struct copy_change));
+ VARRAY_PUSH_GENERIC_PTR (copy_change_varray, result);
}
else
{
- result = free_secondary_copy_changes;
- free_secondary_copy_changes
- = *(struct secondary_copy_change **) free_secondary_copy_changes;
+ result = free_copy_changes;
+ free_copy_changes
+ = *(struct copy_change **) free_copy_changes;
}
#ifdef HAVE_SECONDARY_RELOADS
result->icode = CODE_FOR_nothing;
result->interm_mode = result->scratch_mode = VOIDmode;
result->interm_regno = result->scratch_regno = -1;
- CLEAR_HARD_REG_SET (result->interm_scratch_hard_regset);
#endif
+ result->interm_equiv_const_regno = -1;
+ result->interm_equiv_const_mode = VOIDmode;
#ifdef SECONDARY_MEMORY_NEEDED
result->memory_mode = VOIDmode;
result->user_defined_memory = NULL_RTX;
result->memory_slot = NULL;
#endif
+ CLEAR_HARD_REG_SET (result->interm_scratch_hard_regset);
return result;
}
-
static void
-finish_secondary_copy_changes (void)
+finish_copy_changes (void)
{
int i;
- for (i = VARRAY_ACTIVE_SIZE (secondary_copy_change_varray) - 1;
+ for (i = VARRAY_ACTIVE_SIZE (copy_change_varray) - 1;
i >= 0;
i--)
- yara_free (VARRAY_GENERIC_PTR (secondary_copy_change_varray, i));
- VARRAY_FREE (secondary_copy_change_varray);
+ yara_free (VARRAY_GENERIC_PTR (copy_change_varray, i));
+ VARRAY_FREE (copy_change_varray);
}
-#endif /* HAVE_ANY_SECONDARY_MOVES */
-
/* This page contains functions to allocate/deallocate memory slots for
@@ -970,8 +969,7 @@ allocate_allocno_memory_slot (allocno_t a)
{
if (can_copy_conflict_p (can, copies [i]))
{
- yara_assert (COPY_SECONDARY_CHANGE_ADDR (copies [i])
- != NULL);
+ yara_assert (COPY_CHANGE_ADDR (copies [i]) != NULL);
conflict_slot = COPY_MEMORY_SLOT (copies [i]);
yara_assert (conflict_slot != NULL);
reserve_stack_memory (conflict_slot->start,
@@ -1043,8 +1041,7 @@ allocate_copy_memory_slot (copy_t cp)
struct memory_slot *slot, *conflict_slot;
allocno_t *vec;
- yara_assert (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL
- && COPY_MEMORY_SLOT (cp) == NULL);
+ yara_assert (COPY_CHANGE_ADDR (cp) != NULL && COPY_MEMORY_SLOT (cp) == NULL);
slot = COPY_MEMORY_SLOT (cp) = get_free_memory_slot_structure ();
bitmap_set_bit (secondary_memory_copies, COPY_NUM (cp));
slot->size = GET_MODE_SIZE (COPY_MEMORY_MODE (cp));
@@ -1071,7 +1068,7 @@ deallocate_copy_memory_slot (copy_t cp)
struct memory_slot *slot;
int align;
- yara_assert (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL);
+ yara_assert (COPY_CHANGE_ADDR (cp) != NULL);
slot = COPY_MEMORY_SLOT (cp);
align = get_stack_align (COPY_MEMORY_MODE (cp)) / BITS_PER_UNIT;
yara_assert (slot->mem == NULL_RTX);
@@ -1150,7 +1147,7 @@ compact_stack (void)
{
if (can_copy_conflict_p (can, copies [j]))
{
- yara_assert (COPY_SECONDARY_CHANGE_ADDR (copies [j]) != NULL);
+ yara_assert (COPY_CHANGE_ADDR (copies [j]) != NULL);
conflict_slot = COPY_MEMORY_SLOT (copies [j]);
yara_assert (conflict_slot != NULL
&& conflict_slot->mem == NULL_RTX);
@@ -1672,8 +1669,8 @@ allocate_copy_secondary_memory (bool in_p, copy_t cp, int hard_regno,
if (COPY_DST (cp) != NULL && ALLOCNO_TYPE (COPY_DST (cp)) == INSN_ALLOCNO
&& INSN_ALLOCNO_ELIMINATION_P (COPY_DST (cp)))
return false;
- if (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL)
- COPY_SECONDARY_CHANGE_ADDR (cp) = get_free_secondary_copy_change ();
+ if (COPY_CHANGE_ADDR (cp) == NULL)
+ COPY_CHANGE_ADDR (cp) = get_free_copy_change ();
COPY_MEMORY_MODE (cp) = mode;
allocate_copy_memory_slot (cp);
}
@@ -1682,10 +1679,45 @@ allocate_copy_secondary_memory (bool in_p, copy_t cp, int hard_regno,
#endif
-#ifdef HAVE_ANY_SECONDARY_MOVES
+/* The function checks (and returns true in case of success) that copy
+ CP with source allocno using equivalent constant can be successfully
+ generated and, if necessary, assigns an intermediate hard register
+ will be used to assign the constant to the copy destination. */
+static bool
+assign_copy_interm_equiv_const_hard_reg (copy_t cp)
+{
+ allocno_t src, dst;
+
+ src = COPY_SRC (cp);
+ dst = COPY_DST (cp);
+ yara_assert (src != NULL && dst != NULL);
+ if (ALLOCNO_USE_EQUIV_CONST_P (dst))
+ return true;
+ yara_assert (ALLOCNO_USE_EQUIV_CONST_P (src));
+ /* ??? We need better code for all possible cases including usage of
+ an intermediate register.*/
+ if (ALLOCNO_MEMORY_SLOT (dst) != NULL)
+ return false;
+ return true;
+}
+
+/* The function frees an intermediate hard register (if any) used to
+ assign the constant to the copy destination. */
+static void
+unassign_copy_interm_equiv_const_hard_reg (copy_t cp)
+{
+ allocno_t src, dst;
+
+ src = COPY_SRC (cp);
+ dst = COPY_DST (cp);
+ yara_assert (src != NULL && dst != NULL);
+ if (ALLOCNO_USE_EQUIV_CONST_P (dst))
+ return;
+ yara_assert (ALLOCNO_USE_EQUIV_CONST_P (src));
+}
static bool
-assign_copy_secondary (copy_t cp)
+assign_copy (copy_t cp)
{
bool in_p;
enum reg_class cl;
@@ -1697,6 +1729,9 @@ assign_copy_secondary (copy_t cp)
in_p = false;
a = COPY_SRC (cp);
a2 = COPY_DST (cp);
+ if (a != NULL && ALLOCNO_USE_EQUIV_CONST_P (a)
+ && ! assign_copy_interm_equiv_const_hard_reg (cp))
+ return false;
if (a == NULL)
{
a = COPY_DST (cp);
@@ -1854,7 +1889,7 @@ assign_copy_secondary (copy_t cp)
#endif
if (ALLOCNO_TYPE (a) == INSN_ALLOCNO && INSN_ALLOCNO_ELIMINATION_P (a))
return false;
- yara_assert (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL);
+ yara_assert (COPY_CHANGE_ADDR (cp) == NULL);
logged_p = true;
log_copy (cp);
vec = COPY_ALLOCNO_CONFLICT_VEC (cp);
@@ -1929,7 +1964,7 @@ assign_copy_secondary (copy_t cp)
}
}
#ifdef ENABLE_YARA_CHECKING
- if (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL)
+ if (COPY_CHANGE_ADDR (cp) != NULL)
{
GO_IF_HARD_REG_EQUAL (COPY_INTERM_SCRATCH_HARD_REGSET (cp),
zero_hard_reg_set, ok);
@@ -1938,7 +1973,7 @@ assign_copy_secondary (copy_t cp)
ok:
#endif
interm_hard_regno = scratch_hard_regno = -1;
- COPY_SECONDARY_CHANGE_ADDR (cp) = get_free_secondary_copy_change ();
+ COPY_CHANGE_ADDR (cp) = get_free_copy_change ();
if (interm_class != NO_REGS)
{
interm_hard_regno = find_hard_reg_for_mode (interm_class,
@@ -1999,52 +2034,52 @@ assign_copy_secondary (copy_t cp)
}
static bool
-assign_secondary (allocno_t a)
+assign_allocno_copies (allocno_t a)
{
copy_t cp;
bool succ_p = true;
for (cp = ALLOCNO_DST_COPIES (a); cp != NULL; cp = COPY_NEXT_DST_COPY (cp))
- if (! (succ_p = assign_copy_secondary (cp)))
+ if (! (succ_p = assign_copy (cp)))
break;
if (succ_p)
for (cp = ALLOCNO_SRC_COPIES (a); cp != NULL; cp = COPY_NEXT_SRC_COPY (cp))
- if (! (succ_p = assign_copy_secondary (cp)))
+ if (! (succ_p = assign_copy (cp)))
break;
if (succ_p)
return true;
/* Fail: restore the allocation state. */
for (cp = ALLOCNO_DST_COPIES (a); cp != NULL; cp = COPY_NEXT_DST_COPY (cp))
{
- if (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL)
+ if (COPY_CHANGE_ADDR (cp) == NULL)
continue;
log_copy (cp);
#ifdef SECONDARY_MEMORY_NEEDED
if (COPY_MEMORY_SLOT (cp) != NULL)
deallocate_copy_memory_slot (cp);
#endif
- COPY_SECONDARY_CHANGE_ADDR (cp) = NULL;
+ COPY_CHANGE_ADDR (cp) = NULL;
}
for (cp = ALLOCNO_SRC_COPIES (a); cp != NULL; cp = COPY_NEXT_SRC_COPY (cp))
{
- if (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL)
+ if (COPY_CHANGE_ADDR (cp) == NULL)
continue;
log_copy (cp);
#ifdef SECONDARY_MEMORY_NEEDED
if (COPY_MEMORY_SLOT (cp) != NULL)
deallocate_copy_memory_slot (cp);
#endif
- COPY_SECONDARY_CHANGE_ADDR (cp) = NULL;
+ COPY_CHANGE_ADDR (cp) = NULL;
}
return false;
}
void
-unassign_copy_secondary (copy_t cp)
+unassign_copy (copy_t cp)
{
- if (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL)
+ if (COPY_CHANGE_ADDR (cp) == NULL)
return;
- log_copy (cp);
+ log_copy (cp);
#ifdef HAVE_SECONDARY_RELOADS
if (COPY_INTERM_REGNO (cp) >= 0)
mark_regno_release (COPY_INTERM_REGNO (cp), COPY_INTERM_MODE (cp));
@@ -2055,24 +2090,24 @@ unassign_copy_secondary (copy_t cp)
if (COPY_MEMORY_SLOT (cp) != NULL)
deallocate_copy_memory_slot (cp);
#endif
- free_secondary_copy_change (COPY_SECONDARY_CHANGE_ADDR (cp));
- COPY_SECONDARY_CHANGE_ADDR (cp) = NULL;
+ if (COPY_SRC (cp) != NULL && ALLOCNO_USE_EQUIV_CONST_P (COPY_SRC (cp)))
+ unassign_copy_interm_equiv_const_hard_reg (cp);
+ free_copy_change (COPY_CHANGE_ADDR (cp));
+ COPY_CHANGE_ADDR (cp) = NULL;
}
static void
-unassign_secondary (allocno_t a)
+unassign_allocno_copies (allocno_t a)
{
copy_t cp;
yara_assert (ALLOCNO_HARD_REGNO (a) >= 0 || ALLOCNO_MEMORY_SLOT (a) != NULL);
for (cp = ALLOCNO_DST_COPIES (a); cp != NULL; cp = COPY_NEXT_DST_COPY (cp))
- unassign_copy_secondary (cp);
+ unassign_copy (cp);
for (cp = ALLOCNO_SRC_COPIES (a); cp != NULL; cp = COPY_NEXT_SRC_COPY (cp))
- unassign_copy_secondary (cp);
+ unassign_copy (cp);
}
-#endif
-
static bool
check_hard_regno_for_a (allocno_t a, int hard_regno,
HARD_REG_SET possible_regs)
@@ -2153,19 +2188,15 @@ check_hard_regno_for_a (allocno_t a, int hard_regno,
return false;
}
}
-#ifdef HAVE_ANY_SECONDARY_MOVES
-#ifdef HAVE_SECONDARY_RELOADS
copy_vec = ALLOCNO_COPY_CONFLICT_VEC (a);
for (i = 0; (cp = copy_vec [i]) != NULL; i++)
{
- if (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL)
+ if (COPY_CHANGE_ADDR (cp) == NULL)
continue;
if (! hard_reg_not_in_set_p (start, allocation_mode,
COPY_INTERM_SCRATCH_HARD_REGSET (cp)))
return false;
}
-#endif
-#endif
return true;
}
@@ -2251,13 +2282,11 @@ collect_conflict_hard_regs (allocno_t a, HARD_REG_SET *prohibited_hard_regs)
if (possible_hard_regnos_num == 0)
return false;
}
-#ifdef HAVE_ANY_SECONDARY_MOVES
-#ifdef HAVE_SECONDARY_RELOADS
CLEAR_HARD_REG_SET (temp_set);
copy_vec = ALLOCNO_COPY_CONFLICT_VEC (a);
for (i = 0; (cp = copy_vec [i]) != NULL; i++)
{
- if (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL)
+ if (COPY_CHANGE_ADDR (cp) == NULL)
continue;
IOR_HARD_REG_SET (temp_set, COPY_INTERM_SCRATCH_HARD_REGSET (cp));
}
@@ -2276,8 +2305,6 @@ collect_conflict_hard_regs (allocno_t a, HARD_REG_SET *prohibited_hard_regs)
}
}
IOR_HARD_REG_SET (conflict_set, temp_set);
-#endif
-#endif
COPY_HARD_REG_SET (*prohibited_hard_regs, conflict_set);
return true;
}
@@ -2403,9 +2430,7 @@ assign_allocno_hard_regno (allocno_t a, int hard_regno,
log_allocno (a);
INSN_ALLOCNO_USE_WITHOUT_CHANGE_P (a) = true;
global_allocation_cost += allocno_copy_cost (a);
-#ifdef HAVE_ANY_SECONDARY_MOVES
- yara_assert (assign_secondary (a));
-#endif
+ yara_assert (assign_allocno_copies (a));
return true;
}
}
@@ -2413,13 +2438,11 @@ assign_allocno_hard_regno (allocno_t a, int hard_regno,
return false;
log_allocno (a);
ALLOCNO_HARD_REGNO (a) = hard_regno;
-#ifdef HAVE_ANY_SECONDARY_MOVES
- if (! assign_secondary (a))
+ if (! assign_allocno_copies (a))
{
ALLOCNO_HARD_REGNO (a) = -1;
return false;
}
-#endif
allocation_mode = get_allocation_mode (a);
start = get_maximal_part_start_hard_regno (hard_regno, a);
yara_assert (start >= 0);
@@ -2452,8 +2475,7 @@ assign_one_allocno (allocno_t a, enum reg_class cl, HARD_REG_SET possible_regs)
else
ALLOCNO_USE_EQUIV_CONST_P (a) = true;
global_allocation_cost += allocno_copy_cost (a);
-#ifdef HAVE_ANY_SECONDARY_MOVES
- if (! assign_secondary (a))
+ if (! assign_allocno_copies (a))
{
if (equiv_const == NULL_RTX)
INSN_ALLOCNO_USE_WITHOUT_CHANGE_P (a) = false;
@@ -2461,7 +2483,6 @@ assign_one_allocno (allocno_t a, enum reg_class cl, HARD_REG_SET possible_regs)
ALLOCNO_USE_EQUIV_CONST_P (a) = false;
return false;
}
-#endif
return true;
}
else if (cl == NO_REGS)
@@ -2482,8 +2503,7 @@ assign_one_allocno (allocno_t a, enum reg_class cl, HARD_REG_SET possible_regs)
INSN_ALLOCNO_CONST_POOL_P (a) = true;
}
global_allocation_cost += allocno_copy_cost (a);
-#ifdef HAVE_ANY_SECONDARY_MOVES
- if (! assign_secondary (a))
+ if (! assign_allocno_copies (a))
{
if (ALLOCNO_MEMORY_SLOT (a) != NULL)
deallocate_allocno_memory_slot (a);
@@ -2491,7 +2511,6 @@ assign_one_allocno (allocno_t a, enum reg_class cl, HARD_REG_SET possible_regs)
INSN_ALLOCNO_CONST_POOL_P (a) = false;
return false;
}
-#endif
return true;
}
yara_assert (ALLOCNO_HARD_REGNO (a) < 0);
@@ -2513,13 +2532,11 @@ assign_one_allocno (allocno_t a, enum reg_class cl, HARD_REG_SET possible_regs)
return false;
log_allocno (a);
ALLOCNO_HARD_REGNO (a) = hard_regno;
-#ifdef HAVE_ANY_SECONDARY_MOVES
- if (! assign_secondary (a))
+ if (! assign_allocno_copies (a))
{
ALLOCNO_HARD_REGNO (a) = -1;
return false;
}
-#endif
allocation_mode = get_allocation_mode (a);
start = get_maximal_part_start_hard_regno (hard_regno, a);
yara_assert (start >= 0);
@@ -2537,9 +2554,7 @@ unassign_one_allocno (allocno_t a)
global_allocation_cost -= allocno_copy_cost (a);
if (ALLOCNO_HARD_REGNO (a) >= 0)
{
-#ifdef HAVE_ANY_SECONDARY_MOVES
- unassign_secondary (a);
-#endif
+ unassign_allocno_copies (a);
mark_regno_release
(get_maximal_part_start_hard_regno (ALLOCNO_HARD_REGNO (a), a),
get_allocation_mode (a));
@@ -2548,13 +2563,14 @@ unassign_one_allocno (allocno_t a)
}
else if (ALLOCNO_MEMORY_SLOT (a) != NULL)
{
-#ifdef HAVE_ANY_SECONDARY_MOVES
- unassign_secondary (a);
-#endif
+ unassign_allocno_copies (a);
deallocate_allocno_memory_slot (a);
}
else if (ALLOCNO_USE_EQUIV_CONST_P (a))
- ALLOCNO_USE_EQUIV_CONST_P (a) = false;
+ {
+ unassign_allocno_copies (a);
+ ALLOCNO_USE_EQUIV_CONST_P (a) = false;
+ }
else if (ALLOCNO_TYPE (a) == INSN_ALLOCNO)
{
if (INSN_ALLOCNO_CONST_POOL_P (a))
@@ -3018,8 +3034,14 @@ find_interm_elimination_reg (allocno_t a, enum reg_class cl,
return hard_regno >= 0;
}
-static struct reg_eliminate *
-check_elimination_in_addr (rtx *address_loc, rtx *container_loc, bool *base_p)
+/* The function checks that address *ADDRESS_LOC of CONTAINER_LOC can
+ be eliminated and return elimination info and what should be
+ eliminated through BASE_REG_P. The function do substitution of
+ register CHANGE in the address by SUBST_REGNO before the check.
+ ADDITION is an additional offset after the elimination. */
+struct reg_eliminate *
+check_elimination_in_addr (int change, int subst_regno, HOST_WIDE_INT addition,
+ rtx *address_loc, rtx *container_loc, bool *base_p)
{
bool ok_p;
int base_regno, index_regno, saved_regno;
@@ -3036,9 +3058,17 @@ check_elimination_in_addr (rtx *address_loc, rtx *container_loc, bool *base_p)
yara_assert (temp_container_loc == container_loc);
base_regno = index_regno = -1;
if (base_reg_loc != NULL)
- base_regno = REGNO (*base_reg_loc);
+ {
+ base_regno = REGNO (*base_reg_loc);
+ if (base_regno == change)
+ base_regno = subst_regno;
+ }
if (index_reg_loc != NULL)
- index_regno = REGNO (*index_reg_loc);
+ {
+ index_regno = REGNO (*index_reg_loc);
+ if (index_regno == change)
+ index_regno = subst_regno;
+ }
yara_assert (base_regno >= 0 || index_regno >= 0);
if (base_regno >= 0 && HARD_REGISTER_NUM_P (base_regno)
&& reg_eliminate [base_regno] != NULL)
@@ -3061,17 +3091,17 @@ check_elimination_in_addr (rtx *address_loc, rtx *container_loc, bool *base_p)
elim != NULL;
elim = elim->next)
{
- offset = elim->offset;
+ offset = elim->offset + addition;
if (elim->to == STACK_POINTER_REGNUM)
offset += slot_memory_size;
if (*base_p)
{
- saved_regno = base_regno;
+ saved_regno = REGNO (*base_reg_loc);
REGNO (*base_reg_loc) = elim->to;
}
else
{
- saved_regno = index_regno;
+ saved_regno = REGNO (*index_reg_loc);
REGNO (*index_reg_loc) = elim->to;
offset *= scale;
}
@@ -3115,6 +3145,7 @@ bool
eliminate_reg (allocno_t a)
{
int regno = ALLOCNO_REGNO (a);
+ allocno_t disp_a;
HOST_WIDE_INT offset;
rtx *container_loc;
struct reg_eliminate *elim;
@@ -3137,8 +3168,8 @@ eliminate_reg (allocno_t a)
{
/* It is a non-register allocno. */
base_p = true;
- elim = check_elimination_in_addr (INSN_ALLOCNO_LOC (a), container_loc,
- &base_p);
+ elim = check_elimination_in_addr (-1, -1, 0, INSN_ALLOCNO_LOC (a),
+ container_loc, &base_p);
possible_alt_reg_intersection (a, &possible_regs);
if (base_p)
{
@@ -3168,7 +3199,8 @@ eliminate_reg (allocno_t a)
address_loc = (GET_CODE (*container_loc) == MEM
? &XEXP (*container_loc, 0) : container_loc);
- elim = check_elimination_in_addr (address_loc, container_loc, &base_p);
+ elim = check_elimination_in_addr (-1, -1, 0,
+ address_loc, container_loc, &base_p);
yara_assert ((base_p && INSN_ALLOCNO_TYPE (a) == BASE_REG)
|| (! base_p && INSN_ALLOCNO_TYPE (a) == INDEX_REG));
if (elim != NULL)
@@ -3190,8 +3222,12 @@ eliminate_reg (allocno_t a)
}
else
{
+ rtx insn = INSN_ALLOCNO_INSN (a);
+
if (GET_CODE (*container_loc) == PLUS
- && GET_CODE (XEXP (*container_loc, 1)) == CONST_INT)
+ && GET_CODE (XEXP (*container_loc, 1)) == CONST_INT
+ && ((disp_a = insn_allocno (XEXP (*container_loc, 1), insn)) == NULL
+ || INSN_ALLOCNO_USE_WITHOUT_CHANGE_P (disp_a)))
{
/* The register is in operator PLUS. */
rtx temp_const_int;
@@ -3229,6 +3265,54 @@ uneliminate_reg (allocno_t a ATTRIBUTE_UNUSED)
|| ALLOCNO_REGNO (a) > LAST_VIRTUAL_REGISTER);
}
+/* The function returns hard register and offset through paarmeters TO
+ and OFFSET of function invariant address X. */
+void
+get_equiv_const_addr_info (rtx x, int *to, HOST_WIDE_INT *offset)
+{
+ if (GET_CODE (x) != PLUS)
+ *offset = 0;
+ else
+ {
+ /* ??? Fixme: In general it should be a general constant. */
+ yara_assert (GET_CODE (XEXP (x, 1)) == CONST_INT);
+ *offset = INTVAL (XEXP (x, 1));
+ x = XEXP (x, 0);
+ }
+ yara_assert (x == frame_pointer_rtx || x == arg_pointer_rtx);
+ *to = REGNO (x);
+}
+
+/* The function returns final hard register and final offset through
+ paarmeters TO and OFFSET of function invariant address X after
+ elimination of virtual register in X. */
+void
+get_equiv_const_elimination_info (rtx x, int *to, HOST_WIDE_INT *offset)
+{
+ struct reg_eliminate *elim;
+
+ if (GET_CODE (x) != PLUS)
+ *offset = 0;
+ else
+ {
+ /* ??? Fixme: In general it should be a constant. */
+ yara_assert (GET_CODE (XEXP (x, 1)) == CONST_INT);
+ *offset = INTVAL (XEXP (x, 1));
+ x = XEXP (x, 0);
+ }
+ yara_assert (x == frame_pointer_rtx || x == arg_pointer_rtx);
+ if ((elim = reg_eliminate [REGNO (x)]) == NULL)
+ *to = REGNO (x);
+ else
+ {
+ /* ??? only 1st elimination. */
+ *to = elim->to;
+ *offset += elim->offset;
+ if (*to == STACK_POINTER_REGNUM)
+ *offset += slot_memory_size;
+ }
+}
+
enum log_type {ALLOCNO_LOG, COPY_LOG, MEMORY_SLOT_LOG};
@@ -3451,15 +3535,13 @@ log_copy (copy_t cp)
l = get_free_log_entry ();
l->type = COPY_LOG;
l->u.c.copy = cp;
- l->u.c.change = COPY_CHANGE (cp);
-#ifdef HAVE_ANY_SECONDARY_MOVES
- if (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL)
+ l->u.c.copy_change = COPY_CHANGE_ADDR (cp);
+ if (COPY_CHANGE_ADDR (cp) != NULL)
{
- l->u.c.change.secondary_change = get_free_secondary_copy_change ();
- memcpy (l->u.c.change.secondary_change, COPY_SECONDARY_CHANGE_ADDR (cp),
- sizeof (struct secondary_copy_change));
+ l->u.c.copy_change = get_free_copy_change ();
+ memcpy (l->u.c.copy_change, COPY_CHANGE_ADDR (cp),
+ sizeof (struct copy_change));
}
-#endif
VARRAY_PUSH_GENERIC_PTR (log_varray, l);
}
@@ -3472,10 +3554,8 @@ undo_copy_change (struct copy_log_entry *cl)
bool new_p;
#ifdef SECONDARY_MEMORY_NEEDED
- copy_slot = (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL
- ? NULL : COPY_MEMORY_SLOT (cp));
- log_slot = (cl->change.secondary_change == NULL
- ? NULL : cl->change.secondary_change->memory_slot);
+ copy_slot = (COPY_CHANGE_ADDR (cp) == NULL ? NULL : COPY_MEMORY_SLOT (cp));
+ log_slot = (cl->copy_change == NULL ? NULL : cl->copy_change->memory_slot);
if (copy_slot != log_slot)
{
int align;
@@ -3489,7 +3569,7 @@ undo_copy_change (struct copy_log_entry *cl)
}
if (log_slot != NULL)
{
- align = (get_stack_align (cl->change.secondary_change->memory_mode)
+ align = (get_stack_align (cl->copy_change->memory_mode)
/ BITS_PER_UNIT);
yara_assert (log_slot->mem == NULL_RTX);
register_memory_slot_usage (log_slot, align);
@@ -3498,51 +3578,53 @@ undo_copy_change (struct copy_log_entry *cl)
}
#endif
#ifdef HAVE_SECONDARY_RELOADS
- copy_regno = (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL
- ? -1 : COPY_INTERM_REGNO (cp));
- log_regno = (cl->change.secondary_change == NULL
- ? -1 : cl->change.secondary_change->interm_regno);
+ copy_regno = (COPY_CHANGE_ADDR (cp) == NULL ? -1 : COPY_INTERM_REGNO (cp));
+ log_regno = (cl->copy_change == NULL ? -1 : cl->copy_change->interm_regno);
if (copy_regno != log_regno)
{
if (log_regno < 0)
mark_regno_release (copy_regno, COPY_INTERM_MODE (cp));
else if (copy_regno < 0)
- mark_regno_allocation (log_regno,
- cl->change.secondary_change->interm_mode);
+ mark_regno_allocation (log_regno, cl->copy_change->interm_mode);
else
gcc_unreachable ();
}
- copy_regno = (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL
- ? -1 : COPY_SCRATCH_REGNO (cp));
- log_regno = (cl->change.secondary_change == NULL
- ? -1 : cl->change.secondary_change->scratch_regno);
+ copy_regno = (COPY_CHANGE_ADDR (cp) == NULL ? -1 : COPY_SCRATCH_REGNO (cp));
+ log_regno = (cl->copy_change == NULL ? -1 : cl->copy_change->scratch_regno);
if (copy_regno != log_regno)
{
if (log_regno < 0)
mark_regno_release (copy_regno, COPY_SCRATCH_MODE (cp));
else if (copy_regno < 0)
- mark_regno_allocation (log_regno,
- cl->change.secondary_change->scratch_mode);
+ mark_regno_allocation (log_regno, cl->copy_change->scratch_mode);
else
gcc_unreachable ();
}
#endif
-#ifdef HAVE_ANY_SECONDARY_MOVES
- if (COPY_SECONDARY_CHANGE_ADDR (cp) != NULL
- && cl->change.secondary_change == NULL)
- free_secondary_copy_change (COPY_SECONDARY_CHANGE_ADDR (cp));
- new_p = (COPY_SECONDARY_CHANGE_ADDR (cp) == NULL
- && cl->change.secondary_change != NULL);
-#endif
- COPY_CHANGE (cp) = cl->change;
-#ifdef HAVE_ANY_SECONDARY_MOVES
+ copy_regno = (COPY_CHANGE_ADDR (cp) == NULL
+ ? -1 : COPY_INTERM_EQUIV_CONST_REGNO (cp));
+ log_regno = (cl->copy_change == NULL
+ ? -1 : cl->copy_change->interm_equiv_const_regno);
+ if (copy_regno != log_regno)
+ {
+ if (log_regno < 0)
+ mark_regno_release (copy_regno, COPY_INTERM_EQUIV_CONST_MODE (cp));
+ else if (copy_regno < 0)
+ mark_regno_allocation
+ (log_regno, cl->copy_change->interm_equiv_const_mode);
+ else
+ gcc_unreachable ();
+ }
+ if (COPY_CHANGE_ADDR (cp) != NULL && cl->copy_change == NULL)
+ free_copy_change (COPY_CHANGE_ADDR (cp));
+ new_p = (COPY_CHANGE_ADDR (cp) == NULL && cl->copy_change != NULL);
+ COPY_CHANGE_ADDR (cp) = cl->copy_change;
if (new_p)
{
- COPY_SECONDARY_CHANGE_ADDR (cp) = get_free_secondary_copy_change ();
- memcpy (COPY_SECONDARY_CHANGE_ADDR (cp), cl->change.secondary_change,
- sizeof (struct secondary_copy_change));
+ COPY_CHANGE_ADDR (cp) = get_free_copy_change ();
+ memcpy (COPY_CHANGE_ADDR (cp), cl->copy_change,
+ sizeof (struct copy_change));
}
-#endif
}
static void
@@ -3591,8 +3673,8 @@ undo_change (struct log_entry *l, bool accept_change_p)
else
gcc_unreachable ();
}
- if (l->type == COPY_LOG && l->u.c.change.secondary_change != NULL)
- free_secondary_copy_change (l->u.c.change.secondary_change);
+ if (l->type == COPY_LOG && l->u.c.copy_change != NULL)
+ free_copy_change (l->u.c.copy_change);
free_log_entry (l);
}
@@ -3652,8 +3734,8 @@ finish_transactions (void)
bool
-check_hard_regno_memory_on_contraint (allocno_t a, bool use_equiv_const_p,
- int hard_regno)
+check_hard_regno_memory_on_constraint (allocno_t a, bool use_equiv_const_p,
+ int hard_regno)
{
alt_set_t temp_alt_set, saved_alt_set;
bool saved_use_equiv_const_p;
@@ -3667,15 +3749,39 @@ check_hard_regno_memory_on_contraint (allocno_t a, bool use_equiv_const_p,
if (INSN_ALLOCNO_TYPE (a) == NON_OPERAND)
/* ???? */
return hard_regno >= 0;
- if (INSN_ALLOCNO_TYPE (a) == BASE_REG)
- /* ??? use_equiv_const_p */
- return (hard_regno >= 0
- && TEST_HARD_REG_BIT (base_regs
- [GET_MODE (*INSN_ALLOCNO_CONTAINER_LOC (a))],
- hard_regno));
- if (INSN_ALLOCNO_TYPE (a) == INDEX_REG)
- /* ??? use_equiv_const_p */
- return hard_regno >= 0 && TEST_HARD_REG_BIT (index_regs, hard_regno);
+ if (INSN_ALLOCNO_TYPE (a) == BASE_REG || INSN_ALLOCNO_TYPE (a) == INDEX_REG)
+ {
+ HARD_REG_SET temp;
+
+ if (INSN_ALLOCNO_TYPE (a) == BASE_REG)
+ COPY_HARD_REG_SET
+ (temp, base_regs [GET_MODE (*INSN_ALLOCNO_CONTAINER_LOC (a))]);
+ else
+ COPY_HARD_REG_SET (temp, index_regs);
+ if (! use_equiv_const_p)
+ return hard_regno >= 0 && TEST_HARD_REG_BIT (temp, hard_regno);
+ else
+ {
+ rtx equiv_const, *container_loc, *address_loc;
+ int to;
+ HOST_WIDE_INT offset;
+ bool base_p;
+
+ equiv_const = reg_equiv_constant [ALLOCNO_REGNO (a)];
+ yara_assert (equiv_cosnt != NULL_RTX);
+ if (CONSTANT_P (equiv_const))
+ return false;
+ get_equiv_const_addr_info (equiv_const, &to, &offset);
+ container_loc = INSN_ALLOCNO_CONTAINER_LOC (a);
+ address_loc = (GET_CODE (*container_loc) == MEM
+ ? &XEXP (*container_loc, 0) : container_loc);
+ /* ??? Allocate interm equiv constant register. Do we need
+ this? */
+ return check_elimination_in_addr (ALLOCNO_REGNO (a), to, offset,
+ address_loc, container_loc,
+ &base_p) != NULL;
+ }
+ }
op_num = INSN_ALLOCNO_TYPE (a) - OPERAND_BASE;
yara_assert (op_num >= 0);
info = insn_infos [INSN_UID (INSN_ALLOCNO_INSN (a))];
@@ -3749,9 +3855,7 @@ void
yara_trans_init (void)
{
set_ever_live_regs ();
-#ifdef HAVE_ANY_SECONDARY_MOVES
- initiate_secondary_copy_changes ();
-#endif
+ initiate_copy_changes ();
initiate_memory_slots ();
initiate_transactions ();
}
@@ -3762,9 +3866,7 @@ yara_trans_finish (void)
{
finish_memory_slots ();
finish_transactions ();
-#ifdef HAVE_ANY_SECONDARY_MOVES
- finish_secondary_copy_changes ();
-#endif
+ finish_copy_changes ();
}
#include "gt-yara-trans.h"