summaryrefslogtreecommitdiff
path: root/gcc/lra-int.h
diff options
context:
space:
mode:
authorvmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-23 15:51:41 +0000
committervmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-23 15:51:41 +0000
commitc6a6cdaaea571860c94f9a9fe0f98c597fef7c81 (patch)
tree915ce489d01a05653371ff4f7770258ffacab1b4 /gcc/lra-int.h
parentd9459f6b9e27edcf999b5c06b87e21f8f24fd26f (diff)
downloadgcc-c6a6cdaaea571860c94f9a9fe0f98c597fef7c81.tar.gz
2012-10-23 Vladimir Makarov <vmakarov@redhat.com>
* dbxout.c (dbxout_symbol_location): Pass new argument to alter_subreg. * dwarf2out.c: Include ira.h and lra.h. (based_loc_descr, compute_frame_pointer_to_fb_displacement): Use lra_eliminate_regs for LRA instead of eliminate_regs. * expr.c (emit_move_insn_1): Pass an additional argument to emit_move_via_integer. Use emit_move_via_integer for LRA only if the insn is recognized. * emit-rtl.c (gen_rtx_REG): Add lra_in_progress. (validate_subreg): Don't check offset for LRA and floating point modes. * final.c (final_scan_insn, cleanup_subreg_operands): Pass new argument to alter_subreg. (walk_alter_subreg, output_operand): Ditto. (alter_subreg): Add new argument. * gcse.c (calculate_bb_reg_pressure): Add parameter to ira_setup_eliminable_regset call. * ira.c: Include lra.h. (ira_init_once, ira_init, ira_finish_once): Call lra_start_once, lra_init, lra_finish_once in anyway. (ira_setup_eliminable_regset): Add parameter. Remove need_fp. Call lra_init_elimination and mark HARD_FRAME_POINTER_REGNUM as living forever if frame_pointer_needed. (setup_reg_class_relations): Set up ira_reg_class_subset. (ira_reg_equiv_invariant_p, ira_reg_equiv_const): Remove. (find_reg_equiv_invariant_const): Ditto. (setup_reg_renumber): Use ira_equiv_no_lvalue_p instead of ira_reg_equiv_invariant_p. Skip caps for LRA. (setup_reg_equiv_init, ira_update_equiv_info_by_shuffle_insn): New functions. (ira_reg_equiv_len, ira_reg_equiv): New externals. (ira_reg_equiv): New. (ira_expand_reg_equiv, init_reg_equiv, finish_reg_equiv): New functions. (no_equiv, update_equiv_regs): Use ira_reg_equiv instead of reg_equiv_init. (setup_reg_equiv): New function. (ira_use_lra_p): New global. (ira): Set up lra_simple_p and ira_conflicts_p. Set up and restore flag_caller_saves and flag_ira_region. Move initialization of ira_obstack and ira_bitmap_obstack upper. Call init_reg_equiv, setup_reg_equiv, and setup_reg_equiv_init instead of initialization of ira_reg_equiv_len, ira_reg_equiv_invariant_p, and ira_reg_equiv_const. Call ira_setup_eliminable_regset with a new argument. Don't flatten IRA IRA for LRA. Don't reassign conflict allocnos for LRA. Call finish_reg_equiv. (do_reload): Prepare code for LRA call. Call LRA. * ira.h (ira_use_lra_p): New external. (struct target_ira): Add members x_ira_class_subset_p x_ira_reg_class_subset, and x_ira_reg_classes_intersect_p. (ira_class_subset_p, ira_reg_class_subset): New macros. (ira_reg_classes_intersect_p): New macro. (struct ira_reg_equiv): New. (ira_setup_eliminable_regset): Add an argument. (ira_expand_reg_equiv, ira_update_equiv_info_by_shuffle_insn): New prototypes. * ira-color.c (color_pass, move_spill_restore, coalesce_allocnos): Use ira_equiv_no_lvalue_p. (coalesce_spill_slots, ira_sort_regnos_for_alter_reg): Ditto. * ira-emit.c (ira_create_new_reg): Call ira_expand_reg_equiv. (generate_edge_moves, change_loop) Use ira_equiv_no_lvalue_p. (emit_move_list): Simplify code. Call ira_update_equiv_info_by_shuffle_insn. Use ira_reg_equiv instead of ira_reg_equiv_invariant_p and ira_reg_equiv_const. Change assert. * ira-int.h (struct target_ira_int): Remove x_ira_class_subset_p and x_ira_reg_classes_intersect_p. (ira_class_subset_p, ira_reg_classes_intersect_p): Remove. (ira_reg_equiv_len, ira_reg_equiv_invariant_p): Ditto. (ira_reg_equiv_const): Ditto. (ira_equiv_no_lvalue_p): New function. * jump.c (true_regnum): Always use hard_regno for subreg_get_info when lra is in progress. * haifa-sched.c (sched_init): Pass new argument to ira_setup_eliminable_regset. * loop-invariant.c (calculate_loop_reg_pressure): Pass new argument to ira_setup_eliminable_regset. * lra.h: New. * lra-int.h: Ditto. * lra.c: Ditto. * lra-assigns.c: Ditto. * lra-constraints.c: Ditto. * lra-coalesce.c: Ditto. * lra-eliminations.c: Ditto. * lra-lives.c: Ditto. * lra-spills.c: Ditto. * Makefile.in (LRA_INT_H): New. (OBJS): Add lra.o, lra-assigns.o, lra-coalesce.o, lra-constraints.o, lra-eliminations.o, lra-lives.o, and lra-spills.o. (dwarf2out.o): Add dependence on ira.h and lra.h. (ira.o): Add dependence on lra.h. (lra.o, lra-assigns.o, lra-coalesce.o, lra-constraints.o): New entries. (lra-eliminations.o, lra-lives.o, lra-spills.o): Ditto. * output.h (alter_subreg): Add new argument. * rtlanal.c (simplify_subreg_regno): Permit mode changes for LRA. Permit ARG_POINTER_REGNUM and STACK_POINTER_REGNUM for LRA. * recog.c (general_operand, register_operand): Accept paradoxical FLOAT_MODE subregs for LRA. (scratch_operand): Accept pseudos for LRA. * rtl.h (lra_in_progress): New external. (debug_bb_n_slim, debug_bb_slim, print_value_slim): New prototypes. (debug_rtl_slim, debug_insn_slim): Ditto. * sdbout.c (sdbout_symbol): Pass new argument to alter_subreg. * sched-vis.c (print_value_slim): New. * target.def (lra_p): New hook. (register_priority): Ditto. (different_addr_displacement_p): Ditto. (spill_class): Ditto. * target-globals.h (this_target_lra_int): New external. (target_globals): New member lra_int. (restore_target_globals): Restore this_target_lra_int. * target-globals.c: Include lra-int.h. (default_target_globals): Add &default_target_lra_int. * targhooks.c (default_lra_p): New function. (default_register_priority): Ditto. (default_different_addr_displacement_p): Ditto. * targhooks.h (default_lra_p): Declare. (default_register_priority): Ditto. (default_different_addr_displacement_p): Ditto. * timevar.def (TV_LRA, TV_LRA_ELIMINATE, TV_LRA_INHERITANCE): New. (TV_LRA_CREATE_LIVE_RANGES, TV_LRA_ASSIGN, TV_LRA_COALESCE): New. * config/arm/arm.c (load_multiple_sequence): Pass new argument toOB alter_subreg. (store_multiple_sequence): Ditto. * config/i386/i386.h (enum ix86_tune_indices): Add X86_TUNE_GENERAL_REGS_SSE_SPILL. (TARGET_GENERAL_REGS_SSE_SPILL): New macro. * config/i386/i386.c (initial_ix86_tune_features): Set up X86_TUNE_GENERAL_REGS_SSE_SPILL for m_COREI7 and m_CORE2I7. (ix86_lra_p, ix86_register_priority): New functions. (ix86_secondary_reload): Add NON_Q_REGS, SIREG, DIREG. (inline_secondary_memory_needed): Change assert. (ix86_spill_class): New function. (TARGET_LRA_P, TARGET_REGISTER_BANK, TARGET_SPILL_CLASS): New macros. * config/m68k/m68k.c (emit_move_sequence): Pass new argument to alter_subreg. * config/m32r/m32r.c (gen_split_move_double): Ditto. * config/pa/pa.c (pa_emit_move_sequence): Ditto. * config/sh/sh.md: Ditto. * config/v850/v850.c (v850_reorg): Ditto. * config/xtensa/xtensa.c (fixup_subreg_mem): Ditto. * doc/md.texi: Add new interpretation of hint * for LRA. * doc/passes.texi: Describe LRA pass. * doc/tm.texi.in: Add TARGET_LRA_P, TARGET_REGISTER_PRIORITY, TARGET_DIFFERENT_ADDR_DISPLACEMENT_P, and TARGET_SPILL_CLASS. * doc/tm.texi: Update. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@192719 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/lra-int.h')
-rw-r--r--gcc/lra-int.h438
1 files changed, 438 insertions, 0 deletions
diff --git a/gcc/lra-int.h b/gcc/lra-int.h
new file mode 100644
index 00000000000..d00cc12feff
--- /dev/null
+++ b/gcc/lra-int.h
@@ -0,0 +1,438 @@
+/* Local Register Allocator (LRA) intercommunication header file.
+ Copyright (C) 2010, 2011, 2012
+ Free Software Foundation, Inc.
+ Contributed by Vladimir Makarov <vmakarov@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "lra.h"
+#include "bitmap.h"
+#include "recog.h"
+#include "insn-attr.h"
+#include "insn-codes.h"
+
+#ifdef ENABLE_CHECKING
+#define lra_assert(c) gcc_assert (c)
+#else
+/* Always define and include C, so that warnings for empty body in an
+ ‘if’ statement and unused variable do not occur. */
+#define lra_assert(c) ((void)(0 && (c)))
+#endif
+
+/* The parameter used to prevent infinite reloading for an insn. Each
+ insn operands might require a reload and, if it is a memory, its
+ base and index registers might require a reload too. */
+#define LRA_MAX_INSN_RELOADS (MAX_RECOG_OPERANDS * 3)
+
+/* Return the hard register which given pseudo REGNO assigned to.
+ Negative value means that the register got memory or we don't know
+ allocation yet. */
+static inline int
+lra_get_regno_hard_regno (int regno)
+{
+ resize_reg_info ();
+ return reg_renumber[regno];
+}
+
+typedef struct lra_live_range *lra_live_range_t;
+
+/* The structure describes program points where a given pseudo lives.
+ The live ranges can be used to find conflicts with other pseudos.
+ If the live ranges of two pseudos are intersected, the pseudos are
+ in conflict. */
+struct lra_live_range
+{
+ /* Pseudo regno whose live range is described by given
+ structure. */
+ int regno;
+ /* Program point range. */
+ int start, finish;
+ /* Next structure describing program points where the pseudo
+ lives. */
+ lra_live_range_t next;
+ /* Pointer to structures with the same start. */
+ lra_live_range_t start_next;
+};
+
+typedef struct lra_copy *lra_copy_t;
+
+/* Copy between pseudos which affects assigning hard registers. */
+struct lra_copy
+{
+ /* True if regno1 is the destination of the copy. */
+ bool regno1_dest_p;
+ /* Execution frequency of the copy. */
+ int freq;
+ /* Pseudos connected by the copy. REGNO1 < REGNO2. */
+ int regno1, regno2;
+ /* Next copy with correspondingly REGNO1 and REGNO2. */
+ lra_copy_t regno1_next, regno2_next;
+};
+
+/* Common info about a register (pseudo or hard register). */
+struct lra_reg
+{
+ /* Bitmap of UIDs of insns (including debug insns) referring the
+ reg. */
+ bitmap_head insn_bitmap;
+ /* The following fields are defined only for pseudos. */
+ /* Hard registers with which the pseudo conflicts. */
+ HARD_REG_SET conflict_hard_regs;
+ /* We assign hard registers to reload pseudos which can occur in few
+ places. So two hard register preferences are enough for them.
+ The following fields define the preferred hard registers. If
+ there are no such hard registers the first field value is
+ negative. If there is only one preferred hard register, the 2nd
+ field is negative. */
+ int preferred_hard_regno1, preferred_hard_regno2;
+ /* Profits to use the corresponding preferred hard registers. If
+ the both hard registers defined, the first hard register has not
+ less profit than the second one. */
+ int preferred_hard_regno_profit1, preferred_hard_regno_profit2;
+#ifdef STACK_REGS
+ /* True if the pseudo should not be assigned to a stack register. */
+ bool no_stack_p;
+#endif
+#ifdef ENABLE_CHECKING
+ /* True if the pseudo crosses a call. It is setup in lra-lives.c
+ and used to check that the pseudo crossing a call did not get a
+ call used hard register. */
+ bool call_p;
+#endif
+ /* Number of references and execution frequencies of the register in
+ *non-debug* insns. */
+ int nrefs, freq;
+ int last_reload;
+ /* Regno used to undo the inheritance. It can be non-zero only
+ between couple of inheritance and undo inheritance passes. */
+ int restore_regno;
+ /* Value holding by register. If the pseudos have the same value
+ they do not conflict. */
+ int val;
+ /* These members are set up in lra-lives.c and updated in
+ lra-coalesce.c. */
+ /* The biggest size mode in which each pseudo reg is referred in
+ whole function (possibly via subreg). */
+ enum machine_mode biggest_mode;
+ /* Live ranges of the pseudo. */
+ lra_live_range_t live_ranges;
+ /* This member is set up in lra-lives.c for subsequent
+ assignments. */
+ lra_copy_t copies;
+};
+
+/* References to the common info about each register. */
+extern struct lra_reg *lra_reg_info;
+
+/* Static info about each insn operand (common for all insns with the
+ same ICODE). Warning: if the structure definition is changed, the
+ initializer for debug_operand_data in lra.c should be changed
+ too. */
+struct lra_operand_data
+{
+ /* The machine description constraint string of the operand. */
+ const char *constraint;
+ /* It is taken only from machine description (which is different
+ from recog_data.operand_mode) and can be of VOIDmode. */
+ ENUM_BITFIELD(machine_mode) mode : 16;
+ /* The type of the operand (in/out/inout). */
+ ENUM_BITFIELD (op_type) type : 8;
+ /* Through if accessed through STRICT_LOW. */
+ unsigned int strict_low : 1;
+ /* True if the operand is an operator. */
+ unsigned int is_operator : 1;
+ /* True if there is an early clobber alternative for this operand.
+ This field is set up every time when corresponding
+ operand_alternative in lra_static_insn_data is set up. */
+ unsigned int early_clobber : 1;
+ /* True if the operand is an address. */
+ unsigned int is_address : 1;
+};
+
+/* Info about register occurrence in an insn. */
+struct lra_insn_reg
+{
+ /* The biggest mode through which the insn refers to the register
+ occurrence (remember the register can be accessed through a
+ subreg in the insn). */
+ ENUM_BITFIELD(machine_mode) biggest_mode : 16;
+ /* The type of the corresponding operand which is the register. */
+ ENUM_BITFIELD (op_type) type : 8;
+ /* True if the reg is accessed through a subreg and the subreg is
+ just a part of the register. */
+ unsigned int subreg_p : 1;
+ /* True if there is an early clobber alternative for this
+ operand. */
+ unsigned int early_clobber : 1;
+ /* The corresponding regno of the register. */
+ int regno;
+ /* Next reg info of the same insn. */
+ struct lra_insn_reg *next;
+};
+
+/* Static part (common info for insns with the same ICODE) of LRA
+ internal insn info. It exists in at most one exemplar for each
+ non-negative ICODE. There is only one exception. Each asm insn has
+ own structure. Warning: if the structure definition is changed,
+ the initializer for debug_insn_static_data in lra.c should be
+ changed too. */
+struct lra_static_insn_data
+{
+ /* Static info about each insn operand. */
+ struct lra_operand_data *operand;
+ /* Each duplication refers to the number of the corresponding
+ operand which is duplicated. */
+ int *dup_num;
+ /* The number of an operand marked as commutative, -1 otherwise. */
+ int commutative;
+ /* Number of operands, duplications, and alternatives of the
+ insn. */
+ char n_operands;
+ char n_dups;
+ char n_alternatives;
+ /* Insns in machine description (or clobbers in asm) may contain
+ explicit hard regs which are not operands. The following list
+ describes such hard registers. */
+ struct lra_insn_reg *hard_regs;
+ /* Array [n_alternatives][n_operand] of static constraint info for
+ given operand in given alternative. This info can be changed if
+ the target reg info is changed. */
+ struct operand_alternative *operand_alternative;
+};
+
+/* LRA internal info about an insn (LRA internal insn
+ representation). */
+struct lra_insn_recog_data
+{
+ /* The insn code. */
+ int icode;
+ /* The insn itself. */
+ rtx insn;
+ /* Common data for insns with the same ICODE. Asm insns (their
+ ICODE is negative) do not share such structures. */
+ struct lra_static_insn_data *insn_static_data;
+ /* Two arrays of size correspondingly equal to the operand and the
+ duplication numbers: */
+ rtx **operand_loc; /* The operand locations, NULL if no operands. */
+ rtx **dup_loc; /* The dup locations, NULL if no dups. */
+ /* Number of hard registers implicitly used in given call insn. The
+ value can be NULL or points to array of the hard register numbers
+ ending with a negative value. */
+ int *arg_hard_regs;
+#ifdef HAVE_ATTR_enabled
+ /* Alternative enabled for the insn. NULL for debug insns. */
+ bool *alternative_enabled_p;
+#endif
+ /* The alternative should be used for the insn, -1 if invalid, or we
+ should try to use any alternative, or the insn is a debug
+ insn. */
+ int used_insn_alternative;
+ /* The following member value is always NULL for a debug insn. */
+ struct lra_insn_reg *regs;
+};
+
+typedef struct lra_insn_recog_data *lra_insn_recog_data_t;
+
+/* lra.c: */
+
+extern FILE *lra_dump_file;
+
+extern bool lra_reg_spill_p;
+
+extern HARD_REG_SET lra_no_alloc_regs;
+
+extern int lra_insn_recog_data_len;
+extern lra_insn_recog_data_t *lra_insn_recog_data;
+
+extern int lra_curr_reload_num;
+
+extern void lra_push_insn (rtx);
+extern void lra_push_insn_by_uid (unsigned int);
+extern void lra_push_insn_and_update_insn_regno_info (rtx);
+extern rtx lra_pop_insn (void);
+extern unsigned int lra_insn_stack_length (void);
+
+extern rtx lra_create_new_reg_with_unique_value (enum machine_mode, rtx,
+ enum reg_class, const char *);
+extern void lra_set_regno_unique_value (int);
+extern void lra_invalidate_insn_data (rtx);
+extern void lra_set_insn_deleted (rtx);
+extern void lra_delete_dead_insn (rtx);
+extern void lra_emit_add (rtx, rtx, rtx);
+extern void lra_emit_move (rtx, rtx);
+extern void lra_update_dups (lra_insn_recog_data_t, signed char *);
+
+extern void lra_process_new_insns (rtx, rtx, rtx, const char *);
+
+extern lra_insn_recog_data_t lra_set_insn_recog_data (rtx);
+extern lra_insn_recog_data_t lra_update_insn_recog_data (rtx);
+extern void lra_set_used_insn_alternative (rtx, int);
+extern void lra_set_used_insn_alternative_by_uid (int, int);
+
+extern void lra_invalidate_insn_regno_info (rtx);
+extern void lra_update_insn_regno_info (rtx);
+extern struct lra_insn_reg *lra_get_insn_regs (int);
+
+extern void lra_free_copies (void);
+extern void lra_create_copy (int, int, int);
+extern lra_copy_t lra_get_copy (int);
+extern bool lra_former_scratch_p (int);
+extern bool lra_former_scratch_operand_p (rtx, int);
+
+extern int lra_constraint_new_regno_start;
+extern bitmap_head lra_inheritance_pseudos;
+extern bitmap_head lra_split_regs;
+extern bitmap_head lra_optional_reload_pseudos;
+extern int lra_constraint_new_insn_uid_start;
+
+/* lra-constraints.c: */
+
+extern int lra_constraint_offset (int, enum machine_mode);
+
+extern int lra_constraint_iter;
+extern int lra_constraint_iter_after_spill;
+extern bool lra_risky_transformations_p;
+extern int lra_inheritance_iter;
+extern int lra_undo_inheritance_iter;
+extern bool lra_constraints (bool);
+extern void lra_constraints_init (void);
+extern void lra_constraints_finish (void);
+extern void lra_inheritance (void);
+extern bool lra_undo_inheritance (void);
+
+/* lra-lives.c: */
+
+extern int lra_live_max_point;
+extern int *lra_point_freq;
+
+extern int lra_hard_reg_usage[FIRST_PSEUDO_REGISTER];
+
+extern int lra_live_range_iter;
+extern void lra_create_live_ranges (bool);
+extern lra_live_range_t lra_copy_live_range_list (lra_live_range_t);
+extern lra_live_range_t lra_merge_live_ranges (lra_live_range_t,
+ lra_live_range_t);
+extern bool lra_intersected_live_ranges_p (lra_live_range_t,
+ lra_live_range_t);
+extern void lra_print_live_range_list (FILE *, lra_live_range_t);
+extern void lra_debug_live_range_list (lra_live_range_t);
+extern void lra_debug_pseudo_live_ranges (int);
+extern void lra_debug_live_ranges (void);
+extern void lra_clear_live_ranges (void);
+extern void lra_live_ranges_init (void);
+extern void lra_live_ranges_finish (void);
+extern void lra_setup_reload_pseudo_preferenced_hard_reg (int, int, int);
+
+/* lra-assigns.c: */
+
+extern void lra_setup_reg_renumber (int, int, bool);
+extern bool lra_assign (void);
+
+
+/* lra-coalesce.c: */
+
+extern int lra_coalesce_iter;
+extern bool lra_coalesce (void);
+
+/* lra-spills.c: */
+
+extern bool lra_need_for_spills_p (void);
+extern void lra_spill (void);
+extern void lra_hard_reg_substitution (void);
+
+
+/* lra-elimination.c: */
+
+extern void lra_debug_elim_table (void);
+extern int lra_get_elimination_hard_regno (int);
+extern rtx lra_eliminate_regs_1 (rtx, enum machine_mode, bool, bool, bool);
+extern void lra_eliminate (bool);
+
+extern void lra_eliminate_reg_if_possible (rtx *);
+
+
+
+/* Update insn operands which are duplication of NOP operand. The
+ insn is represented by its LRA internal representation ID. */
+static inline void
+lra_update_dup (lra_insn_recog_data_t id, int nop)
+{
+ int i;
+ struct lra_static_insn_data *static_id = id->insn_static_data;
+
+ for (i = 0; i < static_id->n_dups; i++)
+ if (static_id->dup_num[i] == nop)
+ *id->dup_loc[i] = *id->operand_loc[nop];
+}
+
+/* Process operator duplications in insn with ID. We do it after the
+ operands processing. Generally speaking, we could do this probably
+ simultaneously with operands processing because a common practice
+ is to enumerate the operators after their operands. */
+static inline void
+lra_update_operator_dups (lra_insn_recog_data_t id)
+{
+ int i;
+ struct lra_static_insn_data *static_id = id->insn_static_data;
+
+ for (i = 0; i < static_id->n_dups; i++)
+ {
+ int ndup = static_id->dup_num[i];
+
+ if (static_id->operand[ndup].is_operator)
+ *id->dup_loc[i] = *id->operand_loc[ndup];
+ }
+}
+
+/* Return info about INSN. Set up the info if it is not done yet. */
+static inline lra_insn_recog_data_t
+lra_get_insn_recog_data (rtx insn)
+{
+ lra_insn_recog_data_t data;
+ unsigned int uid = INSN_UID (insn);
+
+ if (lra_insn_recog_data_len > (int) uid
+ && (data = lra_insn_recog_data[uid]) != NULL)
+ {
+ /* Check that we did not change insn without updating the insn
+ info. */
+ lra_assert (data->insn == insn
+ && (INSN_CODE (insn) < 0
+ || data->icode == INSN_CODE (insn)));
+ return data;
+ }
+ return lra_set_insn_recog_data (insn);
+}
+
+
+
+struct target_lra_int
+{
+ /* Map INSN_UID -> the operand alternative data (NULL if unknown).
+ We assume that this data is valid until register info is changed
+ because classes in the data can be changed. */
+ struct operand_alternative *x_op_alt_data[LAST_INSN_CODE];
+};
+
+extern struct target_lra_int default_target_lra_int;
+#if SWITCHABLE_TARGET
+extern struct target_lra_int *this_target_lra_int;
+#else
+#define this_target_lra_int (&default_target_lra_int)
+#endif
+
+#define op_alt_data (this_target_lra_int->x_op_alt_data)