diff options
author | Vladimir Makarov <vmakarov@redhat.com> | 2006-05-19 18:48:32 +0000 |
---|---|---|
committer | Vladimir Makarov <vmakarov@redhat.com> | 2006-05-19 18:48:32 +0000 |
commit | cd8af4a4513cb7e87226de7b464f339d62213fe7 (patch) | |
tree | 8b3b4da24779ba5829ad7738724ec5c10b7acda2 | |
parent | 79ec9fcbbfd5e580aa67a7fae99b2b26e1b80baa (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/ChangeLog | 72 | ||||
-rw-r--r-- | gcc/common.opt | 2 | ||||
-rw-r--r-- | gcc/yara-color.c | 107 | ||||
-rw-r--r-- | gcc/yara-final.c | 160 | ||||
-rw-r--r-- | gcc/yara-insn.c | 208 | ||||
-rw-r--r-- | gcc/yara-int.h | 88 | ||||
-rw-r--r-- | gcc/yara-ir.c | 67 | ||||
-rw-r--r-- | gcc/yara-trans.c | 430 |
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, ©_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" |