Home | History | Annotate | Line # | Download | only in aarch64
      1 // Early register allocation pass.
      2 // Copyright (C) 2023-2024 Free Software Foundation, Inc.
      3 //
      4 // This file is part of GCC.
      5 //
      6 // GCC is free software; you can redistribute it and/or modify it under
      7 // the terms of the GNU General Public License as published by the Free
      8 // Software Foundation; either version 3, or (at your option) any later
      9 // version.
     10 //
     11 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14 // for more details.
     15 //
     16 // You should have received a copy of the GNU General Public License
     17 // along with GCC; see the file COPYING3.  If not see
     18 // <http://www.gnu.org/licenses/>.
     19 
     20 // This pass implements a simple form of early register allocation.
     21 // It is restricted to FP/SIMD registers, and it only allocates
     22 // a region of FP/SIMD usage if it can do so without any spilling.
     23 // It punts on anything too complicated, leaving it to the real
     24 // register allocator.
     25 //
     26 // There are two main purposes:
     27 //
     28 // (1) The pass runs before scheduling.  It therefore has a chance to
     29 //     bag a spill-free allocation, if there is one, before scheduling
     30 //     moves things around.
     31 //
     32 // (2) The pass can make use of strided register operations, such as the
     33 //     strided forms of LD1 and ST1 in SME2.
     34 //
     35 // The allocator works at the level of individual FPRs, rather than whole
     36 // pseudo registers.  It is mostly intended to help optimize ACLE code.
     37 //
     38 // The pass is very simplistic.  There are many things that could be improved.
     39 #define IN_TARGET_CODE 1
     40 
     41 #define INCLUDE_ALGORITHM
     42 #define INCLUDE_FUNCTIONAL
     43 #include "config.h"
     44 #include "system.h"
     45 #include "coretypes.h"
     46 #include "backend.h"
     47 #include "rtl.h"
     48 #include "df.h"
     49 #include "rtl-ssa.h"
     50 #include "tree-pass.h"
     51 #include "target.h"
     52 #include "expr.h"
     53 #include "cfgrtl.h"
     54 #include "print-rtl.h"
     55 #include "insn-attr.h"
     56 #include "insn-opinit.h"
     57 #include "reload.h"
     58 
     59 template<typename T>
     60 class simple_iterator : public wrapper_iterator<T>
     61 {
     62 public:
     63   using wrapper_iterator<T>::wrapper_iterator;
     64 
     65   simple_iterator &operator-- () { --this->m_contents; return *this; }
     66   simple_iterator operator-- (int) { return this->m_contents--; }
     67   simple_iterator &operator++ () { ++this->m_contents; return *this; }
     68   simple_iterator operator++ (int) { return this->m_contents++; }
     69 };
     70 
     71 using namespace rtl_ssa;
     72 
     73 namespace {
     74 const pass_data pass_data_early_ra =
     75 {
     76   RTL_PASS, // type
     77   "early_ra", // name
     78   OPTGROUP_NONE, // optinfo_flags
     79   TV_NONE, // tv_id
     80   0, // properties_required
     81   0, // properties_provided
     82   0, // properties_destroyed
     83   0, // todo_flags_start
     84   TODO_df_finish, // todo_flags_finish
     85 };
     86 
     87 using allocno_iterator = simple_iterator<unsigned int>;
     88 
     89 // Class that represents one run of the pass.
     90 class early_ra
     91 {
     92 public:
     93   early_ra (function *fn);
     94   ~early_ra ();
     95   void execute ();
     96 
     97 private:
     98   // Whether to test only things that are required for correctness,
     99   // or whether to take optimization heuristics into account as well.
    100   enum test_strictness { CORRECTNESS_ONLY, ALL_REASONS };
    101 
    102   static_assert (MAX_RECOG_OPERANDS <= 32, "Operand mask is 32 bits");
    103   using operand_mask = uint32_t;
    104 
    105   // Points in the function are represented using "program points".
    106   // The program points are allocated in reverse order, with smaller
    107   // numbers indicating later points.  These special values indicate
    108   // the start and end of a region.
    109   static constexpr unsigned int START_OF_REGION = ~0U;
    110   static constexpr unsigned int END_OF_REGION = 0U;
    111 
    112   // An invalid allocno index, used to represent no allocno.
    113   static constexpr unsigned int INVALID_ALLOCNO = ~0U;
    114 
    115   // Enumerates the single FPR sizes that matter for register allocation.
    116   // Anything smaller than 64 bits is treated as FPR_D.
    117   enum fpr_size_info
    118   {
    119     FPR_D,
    120     FPR_Q,
    121     FPR_Z
    122   };
    123 
    124   // A live range for an FPR, containing program points [START_POINT,
    125   // END_POINT].  If ALLOCNO is not INVALID_ALLOCNO, the FPR is known
    126   // to be equal to ALLOCNO for the duration of the live range.
    127   struct fpr_range_info
    128   {
    129     unsigned int start_point;
    130     unsigned int end_point;
    131     unsigned int allocno;
    132   };
    133 
    134   // Flags used in pseudo_reg_info.
    135   //
    136   // Whether the pseudo register occurs in one instruction alternative that
    137   // matches (respectively) V0-V7, V0-V15, V0-V31 or a non-FP register.
    138   static constexpr unsigned int ALLOWS_FPR8 = 1U << 0;
    139   static constexpr unsigned int ALLOWS_FPR16 = 1U << 1;
    140   static constexpr unsigned int ALLOWS_FPR32 = 1U << 2;
    141   static constexpr unsigned int ALLOWS_NONFPR = 1U << 3;
    142   //
    143   // Likewise whether the register occurs in an instruction that requires
    144   // the associated register type.
    145   static constexpr unsigned int NEEDS_FPR8 = 1U << 4;
    146   static constexpr unsigned int NEEDS_FPR16 = 1U << 5;
    147   static constexpr unsigned int NEEDS_FPR32 = 1U << 6;
    148   static constexpr unsigned int NEEDS_NONFPR = 1U << 7;
    149   //
    150   // Whether the pseudo register is copied to or from a hard FP register.
    151   static constexpr unsigned int HAS_FPR_COPY = 1U << 8;
    152   //
    153   // Whether the pseudo register is copied to or from a hard non-FP register.
    154   static constexpr unsigned int HAS_NONFPR_COPY = 1U << 9;
    155   //
    156   // Whether the pseudo register is used as a multi-register vector operand
    157   // to an instruction that supports strided accesses, and whether it is used
    158   // as a multi-register vector operand in some other non-move instruction.
    159   static constexpr unsigned int HAS_FLEXIBLE_STRIDE = 1U << 10;
    160   static constexpr unsigned int HAS_FIXED_STRIDE = 1U << 11;
    161 
    162   // Flags that should be propagated across moves between pseudo registers.
    163   static constexpr unsigned int PSEUDO_COPY_FLAGS = ~(HAS_FLEXIBLE_STRIDE
    164 						      | HAS_FIXED_STRIDE);
    165 
    166   // Information about a copy between two registers.
    167   struct reg_copy_info
    168   {
    169     // The two registers, in order.
    170     unsigned int regnos[2];
    171 
    172     // Index I gives the index of the next reg_copy_info involving REGNOS[I],
    173     // or 0 if none.
    174     unsigned int next_copies[2];
    175   };
    176 
    177   // Information about a pseudo register.
    178   struct pseudo_reg_info
    179   {
    180     // Flags describing how the register is used, defined above.
    181     unsigned int flags : 16;
    182 
    183     // The mode of the pseudo register, cached for convenience.
    184     machine_mode mode : 16;
    185 
    186     // The index of the first copy, or 0 if none.
    187     unsigned int first_copy;
    188   };
    189 
    190   // Information about a group of allocnos that have a fixed offset
    191   // relative to each other.  The allocnos in each group must be allocated
    192   // together.
    193   //
    194   // Allocnos that can share the same hard register are eventually
    195   // chained together.  These chains represent edges on a graph of
    196   // allocnos, such that two allocnos joined by an edge use the same FPR.
    197   // These chains are formed between individual allocnos rather than
    198   // whole groups, although the system is required to be self-consistent.
    199   // Each clique in the graph has at least one "full-width" allocno group
    200   // that has one allocno for every FPR that needs to be allocated to
    201   // the clique.
    202   //
    203   // One group of allocnos is chosen as the "color representative" of
    204   // each clique in the graph.  This group will be a full-width group.
    205   struct allocno_info;
    206   struct allocno_group_info
    207   {
    208     array_slice<unsigned int> chain_heads ();
    209     array_slice<allocno_info> allocnos ();
    210     allocno_group_info *color_rep ();
    211     allocno_info *allocno (unsigned int);
    212 
    213     // The color representative of the containing clique.
    214     allocno_group_info *m_color_rep;
    215 
    216     // The pseudo register associated with this allocno, or INVALID_REGNUM
    217     // if none.
    218     unsigned int regno;
    219 
    220     // The offset of the first allocno (and thus this group) from the start
    221     // of color_rep.
    222     unsigned int color_rep_offset : 8;
    223 
    224     // The number of allocnos in the group, and thus the number of FPRs
    225     // that need to be allocated.
    226     unsigned int size : 8;
    227 
    228     // The gap between FPRs in the group.  This is normally 1, but can be
    229     // higher if we've decided to use strided multi-register accesses.
    230     unsigned int stride : 4;
    231 
    232     // Used temporarily while deciding which allocnos should have non-unit
    233     // strides; see find_strided_accesses for details.
    234     int consecutive_pref : 4;
    235     int strided_polarity : 2;
    236 
    237     // The largest size of FPR needed by references to the allocno group.
    238     fpr_size_info fpr_size : 2;
    239 
    240     // True if all non-move accesses can be converted to strided form.
    241     unsigned int has_flexible_stride : 1;
    242 
    243     // True if we've assigned a color index to this group.
    244     unsigned int has_color : 1;
    245 
    246     // The mask of FPRs that would make valid choices for the first allocno,
    247     // taking the requirements of all the allocnos in the group into account.
    248     unsigned int fpr_candidates;
    249 
    250     // The index of the color that has been assigned to the containing clique.
    251     unsigned int color;
    252   };
    253 
    254   // Represents a single FPR-sized quantity that needs to be allocated.
    255   // Each allocno is identified by index (for compactness).
    256   //
    257   // Quantities that span multiple FPRs are assigned groups of consecutive
    258   // allocnos.  Quantities that occupy a single FPR are assigned their own
    259   // group.
    260   struct allocno_info
    261   {
    262     allocno_group_info *group ();
    263     bool is_shared ();
    264     bool is_equiv_to (unsigned int);
    265 
    266     // The allocno's unique identifier.
    267     unsigned int id;
    268 
    269     // The offset of this allocno into the containing group.
    270     unsigned int offset : 8;
    271 
    272     // The number of allocnos in the containing group.
    273     unsigned int group_size : 8;
    274 
    275     // If the allocno has an affinity with at least one hard register
    276     // (so that choosing that hard register would avoid a copy), this is
    277     // the number of one such hard register, otherwise it is
    278     // FIRST_PSEUDO_REGISTER.
    279     unsigned int hard_regno : 8;
    280 
    281     // Set to 1 if the allocno has a single definition or 2 if it has more.
    282     unsigned int num_defs : 2;
    283 
    284     // True if, at START_POINT, another allocno is copied to this one.
    285     // See callers of record_copy for what counts as a copy.
    286     unsigned int is_copy_dest : 1;
    287 
    288     // True if, at START_POINT, another allocno is copied to this one,
    289     // and if the allocnos at both ends of the copy chain have an affinity
    290     // with the same hard register.
    291     unsigned int is_strong_copy_dest : 1;
    292 
    293     // True if, at END_POINT, this allocno is copied to another one,
    294     // and both allocnos have an affinity with the same hard register.
    295     unsigned int is_strong_copy_src : 1;
    296 
    297     // True if the allocno is subject to an earlyclobber at END_POINT,
    298     // so that it cannot be tied to the destination of the instruction.
    299     unsigned int is_earlyclobbered : 1;
    300 
    301     // True if this allocno is known to be equivalent to related_allocno
    302     // for the whole of this allocno's lifetime.
    303     unsigned int is_equiv : 1;
    304 
    305     // The inclusive range of program points spanned by the allocno.
    306     // START_POINT >= END_POINT.
    307     unsigned int start_point;
    308     unsigned int end_point;
    309 
    310     // If, at END_POINT, this allocno is copied to another allocno, this
    311     // is the index of that allocno, otherwise it is INVALID_ALLOCNO.
    312     // See callers of record_copy for what counts as a copy.
    313     unsigned int copy_dest;
    314 
    315     // If this field is not INVALID_ALLOCNO, it indicates one of two things:
    316     //
    317     // - if is_equiv, this allocno is equivalent to related_allocno for
    318     //   the whole of this allocno's lifetime.
    319     //
    320     // - if !is_equiv, this allocno's live range is a subrange of
    321     //   related_allocno's and we have committed to making this allocno
    322     //   share whatever register related_allocno uses.
    323     unsigned int related_allocno;
    324 
    325     union
    326     {
    327       // The program point at which the allocno was last defined,
    328       // or START_OF_REGION if none.  This is only used temporarily
    329       // while recording allocnos; after that, chain_next below is
    330       // used instead.
    331       unsigned int last_def_point;
    332 
    333       // The next chained allocno in program order (i.e. at lower program
    334       // points), or INVALID_ALLOCNO if none.
    335       unsigned int chain_next;
    336     };
    337 
    338     union
    339     {
    340       // The program point before start_point at which the allocno was
    341       // last used, or END_OF_REGION if none.  This is only used temporarily
    342       // while recording allocnos; after that, chain_prev below is used
    343       // instead.
    344       unsigned int last_use_point;
    345 
    346       // The previous chained allocno in program order (i.e. at higher
    347       // program points), or INVALID_ALLOCNO if none.
    348       unsigned int chain_prev;
    349     };
    350   };
    351 
    352   // Information about a full allocno group or a subgroup of it.
    353   // The subgroup can be empty to indicate "none".
    354   struct allocno_subgroup
    355   {
    356     array_slice<allocno_info> allocnos ();
    357     allocno_info *allocno (unsigned int);
    358 
    359     // True if a subgroup is present.
    360     operator bool () const { return count; }
    361 
    362     // The containing group.
    363     allocno_group_info *group;
    364 
    365     // The offset of the subgroup from the start of GROUP.
    366     unsigned int start;
    367 
    368     // The number of allocnos in the subgroup.
    369     unsigned int count;
    370   };
    371 
    372   // Represents information about a copy between an allocno and an FPR.
    373   // This establishes an affinity between the allocno and the FPR.
    374   struct allocno_copy_info
    375   {
    376     // The allocno involved in the copy.
    377     unsigned int allocno;
    378 
    379     // The FPR involved in the copy, relative to V0_REGNUM.
    380     unsigned int fpr : 16;
    381 
    382     // A measure of how strong the affinity between the allocno and FPR is.
    383     unsigned int weight : 16;
    384   };
    385 
    386   // Information about a possible allocno chain.
    387   struct chain_candidate_info
    388   {
    389     // The candidate target allocno.
    390     allocno_info *allocno;
    391 
    392     // A rating of the candidate (higher is better).
    393     int score;
    394   };
    395 
    396   // Information about an allocno color.
    397   struct color_info
    398   {
    399     // The color's unique identifier.
    400     int id;
    401 
    402     // The allocated hard register, when known.
    403     unsigned int hard_regno;
    404 
    405     // The clique's representative group.
    406     allocno_group_info *group;
    407 
    408     // The number of FPR preferences recorded in fpr_preferences.
    409     unsigned int num_fpr_preferences;
    410 
    411     // Weights in favor of choosing each FPR as the first register for GROUP.
    412     int8_t fpr_preferences[32];
    413   };
    414 
    415   template<typename T, typename... Ts>
    416   T *region_allocate (Ts...);
    417 
    418   allocno_info *chain_prev (allocno_info *);
    419   allocno_info *chain_next (allocno_info *);
    420 
    421   void dump_pseudo_regs ();
    422   void dump_fpr_ranges ();
    423   void dump_copies ();
    424   void dump_allocnos ();
    425   void dump_colors ();
    426 
    427   iterator_range<allocno_iterator> get_group_allocnos (unsigned int);
    428 
    429   void preprocess_move (rtx, rtx);
    430   void process_pseudo_reg_constraints (rtx_insn *);
    431   void preprocess_insns ();
    432 
    433   int fpr_preference (unsigned int);
    434   void propagate_pseudo_reg_info ();
    435 
    436   void choose_fpr_pseudos ();
    437 
    438   void start_new_region ();
    439 
    440   allocno_group_info *create_allocno_group (unsigned int, unsigned int);
    441   allocno_subgroup get_allocno_subgroup (rtx);
    442   void record_fpr_use (unsigned int);
    443   void record_fpr_def (unsigned int);
    444   void record_allocno_use (allocno_info *);
    445   void record_allocno_def (allocno_info *);
    446   allocno_info *find_related_start (allocno_info *, allocno_info *, bool);
    447   void accumulate_defs (allocno_info *, allocno_info *);
    448   void record_copy (rtx, rtx, bool = false);
    449   void record_constraints (rtx_insn *);
    450   void record_artificial_refs (unsigned int);
    451   void record_insn_refs (rtx_insn *);
    452 
    453   bool consider_strong_copy_src_chain (allocno_info *);
    454   int strided_polarity_pref (allocno_info *, allocno_info *);
    455   void find_strided_accesses ();
    456 
    457   template<unsigned int allocno_info::*field>
    458   static int cmp_increasing (const void *, const void *);
    459   bool is_chain_candidate (allocno_info *, allocno_info *, test_strictness);
    460   int rate_chain (allocno_info *, allocno_info *);
    461   static int cmp_chain_candidates (const void *, const void *);
    462   void chain_allocnos (unsigned int &, unsigned int &);
    463   void merge_fpr_info (allocno_group_info *, allocno_group_info *,
    464 		       unsigned int);
    465   void set_single_color_rep (allocno_info *, allocno_group_info *,
    466 			     unsigned int);
    467   void set_color_rep (allocno_group_info *, allocno_group_info *,
    468 		      unsigned int);
    469   bool try_to_chain_allocnos (allocno_info *, allocno_info *);
    470   void create_color (allocno_group_info *);
    471   void form_chains ();
    472 
    473   bool fpr_conflicts_with_allocno_p (unsigned int, allocno_info *);
    474   bool call_in_range_p (unsigned int, unsigned int, unsigned int);
    475   unsigned int partial_fpr_clobbers (unsigned int, fpr_size_info);
    476 
    477   void process_copies ();
    478 
    479   static int cmp_allocation_order (const void *, const void *);
    480   void allocate_colors ();
    481   allocno_info *find_independent_subchain (allocno_info *);
    482   color_info *find_oldest_color (unsigned int, unsigned int);
    483   void broaden_colors ();
    484   void finalize_allocation ();
    485 
    486   bool replace_regs (rtx_insn *, df_ref);
    487   int try_enforce_constraints (rtx_insn *, vec<std::pair<int, int>> &);
    488   void enforce_constraints (rtx_insn *);
    489   bool maybe_convert_to_strided_access (rtx_insn *);
    490   void apply_allocation ();
    491 
    492   void process_region ();
    493   bool is_dead_insn (rtx_insn *);
    494   void process_block (basic_block, bool);
    495   void process_blocks ();
    496 
    497   // ----------------------------------------------------------------------
    498 
    499   // The function we're operating on.
    500   function *m_fn;
    501 
    502   // Information about each pseudo register, indexed by REGNO.
    503   auto_vec<pseudo_reg_info> m_pseudo_regs;
    504 
    505   // All recorded register copies.
    506   auto_vec<reg_copy_info> m_pseudo_reg_copies;
    507 
    508   // The set of pseudos that we've decided to allocate an FPR to.
    509   auto_bitmap m_fpr_pseudos;
    510 
    511   // ----------------------------------------------------------------------
    512 
    513   // An obstack for allocating information that is referenced by the member
    514   // variables below.
    515   obstack m_region_obstack;
    516   void *m_region_alloc_start;
    517 
    518   // ----------------------------------------------------------------------
    519 
    520   // The basic block that we're currently processing.
    521   basic_block m_current_bb;
    522 
    523   // The lowest-numbered program point in the current basic block.
    524   unsigned int m_current_bb_point;
    525 
    526   // The program point that we're currently processing (described above).
    527   unsigned int m_current_point;
    528 
    529   // The set of allocnos that are currently live.
    530   auto_bitmap m_live_allocnos;
    531 
    532   // The set of FPRs that are currently live.
    533   unsigned int m_live_fprs;
    534 
    535   // A unique one-based identifier for the current region.
    536   unsigned int m_current_region;
    537 
    538   // The region in which each FPR was last used, or 0 if none.
    539   unsigned int m_fpr_recency[32];
    540 
    541   // ----------------------------------------------------------------------
    542 
    543   // A mask of the FPRs that have already been allocated.
    544   unsigned int m_allocated_fprs;
    545 
    546   // A mask of the FPRs that must be at least partially preserved by the
    547   // current function.
    548   unsigned int m_call_preserved_fprs;
    549 
    550   // True if we haven't yet failed to allocate the current region.
    551   bool m_allocation_successful;
    552 
    553   // A map from pseudo registers to the first allocno in their associated
    554   // allocno groups.
    555   hash_map<int_hash<unsigned int, INVALID_REGNUM>,
    556 	   allocno_group_info *> m_regno_to_group;
    557 
    558   // All recorded copies between allocnos and FPRs.
    559   auto_vec<allocno_copy_info> m_allocno_copies;
    560 
    561   // All allocnos, by index.
    562   auto_vec<allocno_info *> m_allocnos;
    563 
    564   // All allocnos, by increasing START_POINT.
    565   auto_vec<allocno_info *> m_sorted_allocnos;
    566 
    567   // Allocnos for which is_shared is true.
    568   auto_vec<allocno_info *> m_shared_allocnos;
    569 
    570   // All colors, by index.
    571   auto_vec<color_info *> m_colors;
    572 
    573   // The instruction ranges that make up the current region,
    574   // as half-open ranges [LAST, FIRST).
    575   auto_vec<std::pair<rtx_insn *, rtx_insn *>> m_insn_ranges;
    576 
    577   // The live ranges of each FPR, in order of increasing program point.
    578   auto_vec<fpr_range_info> m_fpr_ranges[32];
    579 
    580   // For each function call id, a list of program points at which a call
    581   // to such a function is made.  Each list is in order of increasing
    582   // program point.
    583   auto_vec<unsigned int> m_call_points[NUM_ABI_IDS];
    584 
    585   // A list of instructions that can be removed if allocation succeeds.
    586   auto_vec<rtx_insn *> m_dead_insns;
    587 };
    588 
    589 // True if PAT is something that would typically be treated as a move.
    590 static inline bool
    591 is_move_set (rtx pat)
    592 {
    593   if (GET_CODE (pat) != SET)
    594     return false;
    595 
    596   rtx dest = SET_DEST (pat);
    597   if (SUBREG_P (dest))
    598     dest = SUBREG_REG (dest);
    599   if (!OBJECT_P (dest))
    600     return false;
    601 
    602   rtx src = SET_SRC (pat);
    603   if (SUBREG_P (src))
    604     src = SUBREG_REG (src);
    605   if (!OBJECT_P (src) && !CONSTANT_P (src))
    606     return false;
    607 
    608   return true;
    609 }
    610 
    611 // Return true if operand OP is likely to match OP_ALT after register
    612 // allocation.
    613 static bool
    614 likely_operand_match_p (const operand_alternative &op_alt, rtx op)
    615 {
    616   // Empty constraints match everything.
    617   const char *constraint = op_alt.constraint;
    618   if (constraint[0] == 0 || constraint[0] == ',')
    619     return true;
    620 
    621   for (;;)
    622     {
    623       char c = *constraint;
    624       int len = CONSTRAINT_LEN (c, constraint);
    625       if (c == 0 || c == ',')
    626 	break;
    627 
    628       if (c == 'X')
    629 	return true;
    630 
    631       auto cn = lookup_constraint (constraint);
    632       switch (get_constraint_type (cn))
    633 	{
    634 	case CT_REGISTER:
    635 	  if (REG_P (op) || SUBREG_P (op))
    636 	    return true;
    637 	  break;
    638 
    639 	case CT_MEMORY:
    640 	case CT_SPECIAL_MEMORY:
    641 	case CT_RELAXED_MEMORY:
    642 	  if (MEM_P (op))
    643 	    return true;
    644 	  break;
    645 
    646 	case CT_CONST_INT:
    647 	case CT_ADDRESS:
    648 	case CT_FIXED_FORM:
    649 	  if (constraint_satisfied_p (op, cn))
    650 	    return true;
    651 	  break;
    652 	}
    653 
    654       constraint += len;
    655     }
    656 
    657   if (op_alt.matches >= 0)
    658     {
    659       rtx other = recog_data.operand[op_alt.matches];
    660       if ((REG_P (other) || SUBREG_P (other))
    661 	  && (REG_P (op) || SUBREG_P (op)))
    662 	return true;
    663     }
    664   return false;
    665 }
    666 
    667 // Return true if the operands of the current instruction are likely to
    668 // match OP_ALT.
    669 static bool
    670 likely_alternative_match_p (const operand_alternative *op_alt)
    671 {
    672   for (int i = 0; i < recog_data.n_operands; ++i)
    673     if (!likely_operand_match_p (op_alt[i], recog_data.operand[i]))
    674       return false;
    675   return true;
    676 }
    677 
    678 // Return the sum of how disparaged OP_ALT is.
    679 static int
    680 count_rejects (const operand_alternative *op_alt)
    681 {
    682   int reject = 0;
    683   for (int opno = 0; opno < recog_data.n_operands; ++opno)
    684     reject += op_alt[opno].reject;
    685   return reject;
    686 }
    687 
    688 // Allocate a T from the region obstack.
    689 template<typename T, typename... Ts>
    690 inline T *
    691 early_ra::region_allocate (Ts... args)
    692 {
    693   static_assert (std::is_trivially_destructible<T>::value,
    694 		 "destructor won't be called");
    695   void *addr = obstack_alloc (&m_region_obstack, sizeof (T));
    696   return new (addr) T (std::forward<Ts> (args)...);
    697 }
    698 
    699 early_ra::early_ra (function *fn) : m_fn (fn), m_live_fprs (0)
    700 {
    701   gcc_obstack_init (&m_region_obstack);
    702   m_region_alloc_start = obstack_alloc (&m_region_obstack, 0);
    703   bitmap_tree_view (m_live_allocnos);
    704 }
    705 
    706 early_ra::~early_ra ()
    707 {
    708   obstack_free (&m_region_obstack, nullptr);
    709 }
    710 
    711 // Return an array that, for each allocno A in the group, contains the index
    712 // of the allocno at the head of A's chain (that is, the one with the highest
    713 // START_POINT).  The index is INVALID_ALLOCNO if the chain is empty.
    714 inline array_slice<unsigned int>
    715 early_ra::allocno_group_info::chain_heads ()
    716 {
    717   auto *start = reinterpret_cast<unsigned int *> (this + 1);
    718   return { start, size };
    719 }
    720 
    721 // Return the array of allocnos in the group.
    722 inline array_slice<early_ra::allocno_info>
    723 early_ra::allocno_group_info::allocnos ()
    724 {
    725   gcc_checking_assert (regno != INVALID_REGNUM);
    726   auto *chain_end = reinterpret_cast<unsigned int *> (this + 1) + size;
    727   auto *allocno_start = reinterpret_cast<allocno_info *> (chain_end);
    728   return { allocno_start, size };
    729 }
    730 
    731 // Return the group's color representative.
    732 inline early_ra::allocno_group_info *
    733 early_ra::allocno_group_info::color_rep ()
    734 {
    735   gcc_checking_assert (m_color_rep->m_color_rep == m_color_rep);
    736   return m_color_rep;
    737 }
    738 
    739 // Return the group that contains the allocno.
    740 inline early_ra::allocno_group_info *
    741 early_ra::allocno_info::group ()
    742 {
    743   auto *chain_end = reinterpret_cast<unsigned int *> (this - offset);
    744   return reinterpret_cast<allocno_group_info *> (chain_end - group_size) - 1;
    745 }
    746 
    747 // Return true if this allocno's live range is a subrange of related_allocno's
    748 // and if we have committed to making this allocno share whatever register
    749 // related_allocno uses.
    750 inline bool
    751 early_ra::allocno_info::is_shared ()
    752 {
    753   return related_allocno != INVALID_ALLOCNO && !is_equiv;
    754 }
    755 
    756 // Return true if this allocno is known to be equivalent to ALLOCNO.
    757 inline bool
    758 early_ra::allocno_info::is_equiv_to (unsigned int allocno)
    759 {
    760   return is_equiv && related_allocno == allocno;
    761 }
    762 
    763 // Return the allocnos in the subgroup.
    764 inline array_slice<early_ra::allocno_info>
    765 early_ra::allocno_subgroup::allocnos ()
    766 {
    767   if (!count)
    768     return {};
    769   return { &group->allocnos ()[start], count };
    770 }
    771 
    772 // Return allocno I in the subgroup, with 0 being the first.
    773 inline early_ra::allocno_info *
    774 early_ra::allocno_subgroup::allocno (unsigned int i)
    775 {
    776   return &group->allocnos ()[start + i];
    777 }
    778 
    779 // Return the previous (earlier) allocno in ALLOCNO's chain, or null if none.
    780 inline early_ra::allocno_info *
    781 early_ra::chain_prev (allocno_info *allocno)
    782 {
    783   if (allocno->chain_prev != INVALID_ALLOCNO)
    784     return m_allocnos[allocno->chain_prev];
    785   return nullptr;
    786 }
    787 
    788 // Return the next (later) allocno in ALLOCNO's chain, or null if none.
    789 inline early_ra::allocno_info *
    790 early_ra::chain_next (allocno_info *allocno)
    791 {
    792   if (allocno->chain_next != INVALID_ALLOCNO)
    793     return m_allocnos[allocno->chain_next];
    794   return nullptr;
    795 }
    796 
    797 // Dump the information in m_pseudo_regs.
    798 void
    799 early_ra::dump_pseudo_regs ()
    800 {
    801   fprintf (dump_file, "\nPseudos:\n");
    802   fprintf (dump_file, "  %6s %6s %6s %6s %6s %6s %8s %s\n",
    803 	   "Id", "FPR8", "FPR16", "FPR32", "NONFPR", "Stride",
    804 	   "FPRness", "Copies");
    805   pseudo_reg_info unused_reg = {};
    806   for (unsigned int regno = FIRST_PSEUDO_REGISTER;
    807        regno < m_pseudo_regs.length (); ++regno)
    808     {
    809       const auto &reg = m_pseudo_regs[regno];
    810       if (memcmp (&reg, &unused_reg, sizeof (reg)) == 0)
    811 	continue;
    812 
    813       fprintf (dump_file, "  %6d %6s %6s %6s %6s %6s %8d", regno,
    814 	       reg.flags & NEEDS_FPR8 ? "Req"
    815 	       : reg.flags & ALLOWS_FPR8 ? "OK" : "-",
    816 	       reg.flags & NEEDS_FPR16 ? "Req"
    817 	       : reg.flags & ALLOWS_FPR16 ? "OK" : "-",
    818 	       reg.flags & NEEDS_FPR32 ? "Req"
    819 	       : reg.flags & ALLOWS_FPR32 ? "OK" : "-",
    820 	       reg.flags & NEEDS_NONFPR ? "Req"
    821 	       : reg.flags & ALLOWS_NONFPR ? "OK" : "-",
    822 	       ~reg.flags & HAS_FLEXIBLE_STRIDE ? "-"
    823 	       : reg.flags & HAS_FIXED_STRIDE ? "Some" : "All",
    824 	       fpr_preference (regno));
    825       if (reg.flags & HAS_FPR_COPY)
    826 	fprintf (dump_file, " FPR");
    827       if (reg.flags & HAS_NONFPR_COPY)
    828 	fprintf (dump_file, " Non-FPR");
    829       unsigned int copyi = reg.first_copy;
    830       while (copyi)
    831 	{
    832 	  const auto &copy = m_pseudo_reg_copies[copyi];
    833 	  if (copy.regnos[0] == regno)
    834 	    {
    835 	      fprintf (dump_file, " r%d", copy.regnos[1]);
    836 	      copyi = copy.next_copies[0];
    837 	    }
    838 	  else
    839 	    {
    840 	      fprintf (dump_file, " r%d", copy.regnos[0]);
    841 	      copyi = copy.next_copies[1];
    842 	    }
    843 	}
    844       fprintf (dump_file, "\n");
    845     }
    846 }
    847 
    848 // Dump the information in m_fpr_ranges.
    849 void
    850 early_ra::dump_fpr_ranges ()
    851 {
    852   fprintf (dump_file, "\nFPR live ranges:\n");
    853   for (unsigned int fpr = 0; fpr < 32; ++fpr)
    854     {
    855       auto &intervals = m_fpr_ranges[fpr];
    856       if (intervals.is_empty ())
    857 	continue;
    858 
    859       fprintf (dump_file, "  %2d", fpr);
    860       for (unsigned int i = 0; i < intervals.length (); ++i)
    861 	{
    862 	  auto &interval = intervals[i];
    863 	  if (i && (i % 4) == 0)
    864 	    fprintf (dump_file, "\n    ");
    865 	  fprintf (dump_file, " [ %6d %6d ]", interval.start_point,
    866 		   interval.end_point);
    867 	}
    868       fprintf (dump_file, "\n");
    869     }
    870 }
    871 
    872 // Dump the information in m_allocno_copies.
    873 void
    874 early_ra::dump_copies ()
    875 {
    876   fprintf (dump_file, "\nCopies:\n");
    877   fprintf (dump_file, "  %8s %3s %6s\n",
    878 	   "Allocno", "FPR", "Weight");
    879   for (const auto &copy : m_allocno_copies)
    880     fprintf (dump_file, "  %8d %3d %6d\n", copy.allocno,
    881 	     copy.fpr, copy.weight);
    882 }
    883 
    884 // Dump the information in m_allocnos.
    885 void
    886 early_ra::dump_allocnos ()
    887 {
    888   char buffer[sizeof ("r[:]") + 3 * 3 * sizeof (int) + 1];
    889   fprintf (dump_file, "\nAllocno groups:\n");
    890   fprintf (dump_file,
    891 	   "  %12s %12s %4s %6s %8s %s\n",
    892 	   "Ids", "Regno", "Size", "Stride", "Cands", "Heads");
    893   for (unsigned int ai = 0; ai < m_allocnos.length (); ++ai)
    894     {
    895       auto *allocno = m_allocnos[ai];
    896       if (allocno->offset != 0)
    897 	continue;
    898       auto *group = allocno->group ();
    899       snprintf (buffer, sizeof (buffer), "[%d:%d]", allocno->id,
    900 		allocno->id + group->size - 1);
    901       fprintf (dump_file, "  %12s", buffer);
    902       snprintf (buffer, sizeof (buffer), "r%d[0:%d]", group->regno,
    903 		group->size - 1);
    904       fprintf (dump_file, " %12s %4s %6d %08x", buffer,
    905 	       group->fpr_size == FPR_D ? "D"
    906 	       : group->fpr_size == FPR_Q ? "Q" : "Z",
    907 	       group->stride,
    908 	       group->fpr_candidates);
    909       for (auto head : group->chain_heads ())
    910 	if (head == INVALID_ALLOCNO)
    911 	  fprintf (dump_file, " -");
    912 	else
    913 	  fprintf (dump_file, " %d", head);
    914       fprintf (dump_file, "\n");
    915     }
    916 
    917   fprintf (dump_file, "\nAllocno chains:\n");
    918   fprintf (dump_file, "      %5s %12s %12s %6s %5s %5s %6s %5s\n",
    919 	   "Id", "Regno", "Range ", "Src", "Dest", "Equiv", "Shared", "FPR");
    920   for (unsigned int ai = 0; ai < m_allocnos.length (); ++ai)
    921     {
    922       auto *allocno = m_allocnos[ai];
    923       if (allocno->chain_prev != INVALID_ALLOCNO)
    924 	continue;
    925       const char *prefix = "=>";
    926       for (;;)
    927 	{
    928 	  auto *group = allocno->group ();
    929 	  fprintf (dump_file, "  %2s", prefix);
    930 	  fprintf (dump_file, "  %5d", allocno->id);
    931 	  snprintf (buffer, sizeof (buffer), "r%d[%d]", group->regno,
    932 		    allocno->offset);
    933 	  fprintf (dump_file, " %12s", buffer);
    934 	  snprintf (buffer, sizeof (buffer), "[%d,%d]",
    935 		    allocno->start_point, allocno->end_point);
    936 	  fprintf (dump_file, " %11s%s %6s", buffer,
    937 		   allocno->is_earlyclobbered ? "*" : " ",
    938 		   allocno->is_strong_copy_dest ? "Strong"
    939 		   : allocno->is_copy_dest ? "Yes" : "-");
    940 	  if (allocno->copy_dest == INVALID_ALLOCNO)
    941 	    fprintf (dump_file, " %5s", "-");
    942 	  else
    943 	    fprintf (dump_file, " %5d", allocno->copy_dest);
    944 	  if (allocno->is_equiv)
    945 	    fprintf (dump_file, " %5d", allocno->related_allocno);
    946 	  else
    947 	    fprintf (dump_file, " %5s", "-");
    948 	  if (allocno->is_shared ())
    949 	    fprintf (dump_file, " %6d", allocno->related_allocno);
    950 	  else
    951 	    fprintf (dump_file, " %6s", "-");
    952 	  if (allocno->hard_regno == FIRST_PSEUDO_REGISTER)
    953 	    fprintf (dump_file, " %5s", "-");
    954 	  else
    955 	    fprintf (dump_file, " %5s", reg_names[allocno->hard_regno]);
    956 	  fprintf (dump_file, "\n");
    957 	  if (allocno->chain_next == INVALID_ALLOCNO)
    958 	    break;
    959 	  allocno = m_allocnos[allocno->chain_next];
    960 	  prefix = "";
    961 	}
    962     }
    963 }
    964 
    965 // Dump the information in m_colors.
    966 void
    967 early_ra::dump_colors ()
    968 {
    969   fprintf (dump_file, "\nColors:\n");
    970   for (unsigned int i = 0; i < m_colors.length (); ++i)
    971     {
    972       auto *color = m_colors[i];
    973       if (!color->group)
    974 	continue;
    975 
    976       fprintf (dump_file, "  color %d:\n", i);
    977       fprintf (dump_file, "    chains:\n");
    978       auto heads = color->group->chain_heads ();
    979       for (unsigned int i = 0; i < color->group->size; ++i)
    980 	{
    981 	  fprintf (dump_file, "      %2d:", i);
    982 	  auto ai = heads[i];
    983 	  while (ai != INVALID_ALLOCNO)
    984 	    {
    985 	      auto *allocno = m_allocnos[ai];
    986 	      fprintf (dump_file, " r%d[%d]", allocno->group ()->regno,
    987 		       allocno->offset);
    988 	      ai = allocno->chain_next;
    989 	    }
    990 	  fprintf (dump_file, "\n");
    991 	}
    992       fprintf (dump_file, "    FPR candidates:");
    993       for (unsigned int fpr = 0; fpr < 32; ++fpr)
    994 	fprintf (dump_file, "%s%c", fpr % 8 ? "" : " ",
    995 		 color->group->fpr_candidates & (1U << fpr) ? 'Y' : '-');
    996       fprintf (dump_file, "\n");
    997       fprintf (dump_file, "    FPR preferences:");
    998       for (unsigned int fpr = 0; fpr < 32; ++fpr)
    999 	if (color->fpr_preferences[fpr])
   1000 	  fprintf (dump_file, " %d(%d)", fpr, color->fpr_preferences[fpr]);
   1001       fprintf (dump_file, "\n");
   1002     }
   1003 }
   1004 
   1005 // Record any necessary information about a move from SRC to DEST.
   1006 void
   1007 early_ra::preprocess_move (rtx dest, rtx src)
   1008 {
   1009   if (SUBREG_P (dest))
   1010     dest = SUBREG_REG (dest);
   1011   if (!REG_P (dest))
   1012     return;
   1013 
   1014   if (SUBREG_P (src))
   1015     src = SUBREG_REG (src);
   1016   if (!REG_P (src))
   1017     return;
   1018 
   1019   // Sort the registers by increasing REGNO.
   1020   rtx regs[] = { dest, src };
   1021   if (REGNO (dest) > REGNO (src))
   1022     std::swap (regs[0], regs[1]);
   1023   unsigned int regno0 = REGNO (regs[0]);
   1024   unsigned int regno1 = REGNO (regs[1]);
   1025 
   1026   // Ignore moves between hard registers.
   1027   if (HARD_REGISTER_NUM_P (regno1))
   1028     return;
   1029 
   1030   // For moves between hard registers and pseudos, just record the type
   1031   // of hard register involved.
   1032   auto &reg1 = m_pseudo_regs[regno1];
   1033   reg1.mode = GET_MODE (regs[1]);
   1034   if (HARD_REGISTER_NUM_P (regno0))
   1035     {
   1036       reg1.flags |= (FP_REGNUM_P (regno0) ? HAS_FPR_COPY : HAS_NONFPR_COPY);
   1037       return;
   1038     }
   1039 
   1040   // Record a move between two pseudo registers.
   1041   auto &reg0 = m_pseudo_regs[regno0];
   1042   reg0.mode = GET_MODE (regs[0]);
   1043 
   1044   reg_copy_info copy;
   1045   copy.regnos[0] = regno0;
   1046   copy.regnos[1] = regno1;
   1047   copy.next_copies[0] = reg0.first_copy;
   1048   copy.next_copies[1] = reg1.first_copy;
   1049 
   1050   reg0.first_copy = reg1.first_copy = m_pseudo_reg_copies.length ();
   1051   m_pseudo_reg_copies.safe_push (copy);
   1052 }
   1053 
   1054 // Return true if INSN has a multi-vector operand and if that operand
   1055 // could be converted to strided form.
   1056 static bool
   1057 is_stride_candidate (rtx_insn *insn)
   1058 {
   1059   if (recog_memoized (insn) < 0)
   1060     return false;
   1061 
   1062   auto stride_type = get_attr_stride_type (insn);
   1063   return (stride_type == STRIDE_TYPE_LD1_CONSECUTIVE
   1064 	  || stride_type == STRIDE_TYPE_ST1_CONSECUTIVE);
   1065 }
   1066 
   1067 // Go through the constraints of INSN, which has already been extracted,
   1068 // and record any relevant information about pseudo registers.
   1069 void
   1070 early_ra::process_pseudo_reg_constraints (rtx_insn *insn)
   1071 {
   1072   extract_insn (insn);
   1073   preprocess_constraints (insn);
   1074 
   1075   // Flags that describe any multi-register vector operands.
   1076   unsigned int insn_flags = (is_stride_candidate (insn)
   1077 			     ? HAS_FLEXIBLE_STRIDE
   1078 			     : HAS_FIXED_STRIDE);
   1079 
   1080   auto alts = get_preferred_alternatives (insn);
   1081 
   1082   int operand_matches[MAX_RECOG_OPERANDS];
   1083   unsigned int operand_flags[MAX_RECOG_OPERANDS];
   1084   for (int i = 0; i < recog_data.n_operands; ++i)
   1085     {
   1086       operand_matches[i] = -1;
   1087       operand_flags[i] = 0;
   1088     }
   1089 
   1090   // Extract information from the constraints, considering all plausible
   1091   // alternatives.
   1092   for (int altno = 0; altno < recog_data.n_alternatives; ++altno)
   1093     {
   1094       if (!(alts & ALTERNATIVE_BIT (altno)))
   1095 	continue;
   1096 
   1097       auto *op_alt = &recog_op_alt[altno * recog_data.n_operands];
   1098       if (!likely_alternative_match_p (op_alt))
   1099 	continue;
   1100 
   1101       // Use SRC_OPNO's constraints to derive information about DEST_OPNO.
   1102       auto record_operand = [&](int src_opno, int dest_opno)
   1103 	{
   1104 	  int matches = op_alt[src_opno].matches;
   1105 	  if (matches >= 0)
   1106 	    operand_matches[dest_opno] = matches;
   1107 
   1108 	  auto cl = alternative_class (op_alt, src_opno);
   1109 	  if (cl != NO_REGS)
   1110 	    {
   1111 	      if (reg_class_subset_p (cl, FP_REGS))
   1112 		operand_flags[dest_opno] |= ALLOWS_FPR32;
   1113 	      if (reg_class_subset_p (cl, FP_LO_REGS))
   1114 		operand_flags[dest_opno] |= ALLOWS_FPR16;
   1115 	      if (reg_class_subset_p (cl, FP_LO8_REGS))
   1116 		operand_flags[dest_opno] |= ALLOWS_FPR8;
   1117 	      if (!reg_classes_intersect_p (cl, FP_REGS))
   1118 		operand_flags[dest_opno] |= ALLOWS_NONFPR;
   1119 	    }
   1120 	};
   1121 
   1122       for (int i = 0; i < recog_data.n_operands; ++i)
   1123 	{
   1124 	  record_operand (i, i);
   1125 	  if (recog_data.constraints[i][0] == '%')
   1126 	    {
   1127 	      record_operand (i, i + 1);
   1128 	      record_operand (i + 1, i);
   1129 	    }
   1130 	}
   1131     }
   1132 
   1133   // Process the information we collected above.
   1134   for (int i = 0; i < recog_data.n_operands; ++i)
   1135     {
   1136       rtx op = recog_data.operand[i];
   1137       machine_mode orig_mode = GET_MODE (op);
   1138       if (SUBREG_P (op))
   1139 	op = SUBREG_REG (op);
   1140 
   1141       // Record the accumulated information in m_pseudo_regs.
   1142       if (REG_P (op) && !HARD_REGISTER_P (op))
   1143 	{
   1144 	  // The flags so far just describe what at least one alternative
   1145 	  // would accept.  Calculate the associated NEEDS_* information.
   1146 	  auto flags = operand_flags[i];
   1147 	  if (!(flags & ALLOWS_FPR32) && (flags & ALLOWS_NONFPR))
   1148 	    flags |= NEEDS_NONFPR;
   1149 	  else if ((flags & ALLOWS_FPR32) && !(flags & ALLOWS_NONFPR))
   1150 	    {
   1151 	      if (flags & ALLOWS_FPR8)
   1152 		flags |= NEEDS_FPR8;
   1153 	      if (flags & ALLOWS_FPR16)
   1154 		flags |= NEEDS_FPR16;
   1155 	      flags |= NEEDS_FPR32;
   1156 	    }
   1157 
   1158 	  // Look for multi-register vector operands.
   1159 	  if (VECTOR_MODE_P (orig_mode)
   1160 	      && targetm.hard_regno_mode_ok (V0_REGNUM, orig_mode)
   1161 	      && hard_regno_nregs (V0_REGNUM, orig_mode) > 1)
   1162 	    flags |= insn_flags;
   1163 
   1164 	  m_pseudo_regs[REGNO (op)].flags |= flags;
   1165 	  m_pseudo_regs[REGNO (op)].mode = GET_MODE (op);
   1166 	}
   1167 
   1168       // Treat matching constraints as equivalent to moves.
   1169       if (operand_matches[i] >= 0)
   1170 	preprocess_move (recog_data.operand[operand_matches[i]], op);
   1171     }
   1172 }
   1173 
   1174 // Make one pass through the instructions, collecting information that
   1175 // will be needed later.
   1176 void
   1177 early_ra::preprocess_insns ()
   1178 {
   1179   m_pseudo_regs.safe_grow_cleared (max_reg_num ());
   1180   m_pseudo_reg_copies.safe_push (reg_copy_info ());
   1181   for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
   1182     {
   1183       if (!NONDEBUG_INSN_P (insn))
   1184 	continue;
   1185 
   1186       // Mark all registers that occur in addresses as needing a GPR.
   1187       vec_rtx_properties properties;
   1188       properties.add_insn (insn, true);
   1189       for (rtx_obj_reference ref : properties.refs ())
   1190 	if (ref.is_reg ()
   1191 	    && ref.in_address ()
   1192 	    && !HARD_REGISTER_NUM_P (ref.regno))
   1193 	  m_pseudo_regs[ref.regno].flags |= ALLOWS_NONFPR | NEEDS_NONFPR;
   1194 
   1195       if (GET_CODE (PATTERN (insn)) == USE
   1196 	  || GET_CODE (PATTERN (insn)) == CLOBBER)
   1197 	continue;
   1198 
   1199       rtx set = single_set (insn);
   1200       if (set && is_move_set (set))
   1201 	preprocess_move (SET_DEST (set), SET_SRC (set));
   1202       else
   1203 	process_pseudo_reg_constraints (insn);
   1204     }
   1205 }
   1206 
   1207 // Return a signed integer that says (roughly) how strong an affinity
   1208 // pseudo register REGNO has with FPRs.  A positive value indicates
   1209 // that we should try to allocate an FPR, a negative value indicates
   1210 // that we shouldn't, and 0 indicates neutrality.
   1211 int
   1212 early_ra::fpr_preference (unsigned int regno)
   1213 {
   1214   auto mode = m_pseudo_regs[regno].mode;
   1215   auto flags = m_pseudo_regs[regno].flags;
   1216   if (mode == VOIDmode || !targetm.hard_regno_mode_ok (V0_REGNUM, mode))
   1217     return -3;
   1218   else if (flags & HAS_FLEXIBLE_STRIDE)
   1219     return 3;
   1220   else if (flags & NEEDS_FPR32)
   1221     return 2;
   1222   else if (!(flags & ALLOWS_FPR32) && (flags & ALLOWS_NONFPR))
   1223     return -2;
   1224   else if ((flags & HAS_FPR_COPY) && !(flags & HAS_NONFPR_COPY))
   1225     return 1;
   1226   else if ((flags & HAS_NONFPR_COPY) && !(flags & HAS_FPR_COPY))
   1227     return -1;
   1228   else
   1229     return 0;
   1230 }
   1231 
   1232 // Propagate information about pseudo-registers along copy edges,
   1233 // while doing so doesn't create conflicting FPR preferences.
   1234 void
   1235 early_ra::propagate_pseudo_reg_info ()
   1236 {
   1237   struct stack_entry { unsigned int regno, copyi; };
   1238 
   1239   auto_vec<stack_entry, 32> stack;
   1240   for (unsigned int i = FIRST_PSEUDO_REGISTER;
   1241        i < m_pseudo_regs.length (); ++i)
   1242     {
   1243       auto start = m_pseudo_regs[i].first_copy;
   1244       if (!start)
   1245 	continue;
   1246 
   1247       stack.quick_push ({ i, start });
   1248       while (!stack.is_empty ())
   1249 	{
   1250 	  auto entry = stack.pop ();
   1251 	  auto &copy = m_pseudo_reg_copies[entry.copyi];
   1252 	  auto src_regno = entry.regno;
   1253 	  auto dest_regno = (src_regno == copy.regnos[1]
   1254 			     ? copy.regnos[0]
   1255 			     : copy.regnos[1]);
   1256 	  auto next_copyi = (src_regno == copy.regnos[1]
   1257 			     ? copy.next_copies[1]
   1258 			     : copy.next_copies[0]);
   1259 	  if (next_copyi)
   1260 	    stack.safe_push ({ src_regno, next_copyi });
   1261 
   1262 	  auto &src_reg = m_pseudo_regs[src_regno];
   1263 	  auto &dest_reg = m_pseudo_regs[dest_regno];
   1264 
   1265 	  if (src_reg.flags & ~dest_reg.flags & PSEUDO_COPY_FLAGS)
   1266 	    {
   1267 	      auto src_preference = fpr_preference (src_regno);
   1268 	      auto dest_preference = fpr_preference (dest_regno);
   1269 	      if ((src_preference >= 0 && dest_preference >= 0)
   1270 		  || (src_preference <= 0 && dest_preference <= 0))
   1271 		{
   1272 		  dest_reg.flags |= (src_reg.flags & PSEUDO_COPY_FLAGS);
   1273 		  stack.safe_push ({ dest_regno, dest_reg.first_copy });
   1274 		}
   1275 	    }
   1276 	}
   1277     }
   1278 }
   1279 
   1280 // Decide which pseudos should be allocated an FPR, setting m_fpr_pseudos
   1281 // accordingly.
   1282 void
   1283 early_ra::choose_fpr_pseudos ()
   1284 {
   1285   for (unsigned int i = FIRST_PSEUDO_REGISTER;
   1286        i < m_pseudo_regs.length (); ++i)
   1287     if (fpr_preference (i) > 0)
   1288       bitmap_set_bit (m_fpr_pseudos, i);
   1289 }
   1290 
   1291 // Clear out information about the previous CFG region (if any)
   1292 // and set up the data for a new region.
   1293 void
   1294 early_ra::start_new_region ()
   1295 {
   1296   obstack_free (&m_region_obstack, m_region_alloc_start);
   1297   m_regno_to_group.empty ();
   1298   m_allocno_copies.truncate (0);
   1299   m_allocnos.truncate (0);
   1300   m_sorted_allocnos.truncate (0);
   1301   m_shared_allocnos.truncate (0);
   1302   m_colors.truncate (0);
   1303   m_insn_ranges.truncate (0);
   1304   for (auto &fpr_ranges : m_fpr_ranges)
   1305     fpr_ranges.truncate (0);
   1306   for (auto &call_points : m_call_points)
   1307     call_points.truncate (0);
   1308   gcc_assert (bitmap_empty_p (m_live_allocnos) && m_live_fprs == 0);
   1309   m_dead_insns.truncate (0);
   1310   m_allocated_fprs = 0;
   1311   m_call_preserved_fprs = 0;
   1312   m_allocation_successful = true;
   1313   m_current_region += 1;
   1314 }
   1315 
   1316 // Create and return an allocno group of size SIZE for register REGNO.
   1317 // REGNO can be INVALID_REGNUM if the group just exists to allow
   1318 // other groups to be chained together, and does not have any new
   1319 // allocnos of its own.
   1320 early_ra::allocno_group_info *
   1321 early_ra::create_allocno_group (unsigned int regno, unsigned int size)
   1322 {
   1323   static_assert (alignof (unsigned int) == alignof (allocno_info),
   1324 		 "allocno_info alignment");
   1325   unsigned int num_allocnos = (regno != INVALID_REGNUM ? size : 0);
   1326 
   1327   // Allocate an allocno_group_info, followed by an array of chain heads,
   1328   // followed by the allocnos themselves.
   1329   size_t alloc_size = (sizeof (allocno_group_info)
   1330 		       + size * sizeof (unsigned int)
   1331 		       + num_allocnos * sizeof (allocno_info));
   1332   void *data = obstack_alloc (&m_region_obstack, alloc_size);
   1333 
   1334   // Initialize the group.
   1335   auto *group = reinterpret_cast<allocno_group_info *> (data);
   1336   memset (group, 0, sizeof (*group));
   1337   group->m_color_rep = group;
   1338   group->regno = regno;
   1339   group->size = size;
   1340   group->stride = 1;
   1341   group->fpr_size = FPR_D;
   1342   group->fpr_candidates = ~0U;
   1343 
   1344   // Initialize the chain heads.
   1345   auto heads = group->chain_heads ();
   1346   for (unsigned int i = 0; i < heads.size (); ++i)
   1347     heads[i] = (i < num_allocnos ? m_allocnos.length () + i : INVALID_ALLOCNO);
   1348 
   1349   // Initialize the allocnos.
   1350   if (num_allocnos > 0)
   1351     {
   1352       auto allocnos = group->allocnos ();
   1353       memset (allocnos.begin (), 0, num_allocnos * sizeof (allocno_info));
   1354       for (unsigned int i = 0; i < num_allocnos; ++i)
   1355 	{
   1356 	  auto *allocno = &allocnos[i];
   1357 	  allocno->id = m_allocnos.length ();
   1358 	  allocno->offset = i;
   1359 	  allocno->group_size = size;
   1360 	  allocno->hard_regno = FIRST_PSEUDO_REGISTER;
   1361 	  allocno->start_point = END_OF_REGION;
   1362 	  allocno->end_point = START_OF_REGION;
   1363 	  allocno->copy_dest = INVALID_ALLOCNO;
   1364 	  allocno->related_allocno = INVALID_ALLOCNO;
   1365 	  allocno->chain_next = INVALID_ALLOCNO;
   1366 	  allocno->chain_prev = INVALID_ALLOCNO;
   1367 	  m_allocnos.safe_push (allocno);
   1368 	}
   1369     }
   1370   return group;
   1371 }
   1372 
   1373 // If REG refers to a pseudo register that might be allocated to FPRs,
   1374 // return the associated range of allocnos, creating new ones if necessary.
   1375 // Return an empty range otherwise.
   1376 early_ra::allocno_subgroup
   1377 early_ra::get_allocno_subgroup (rtx reg)
   1378 {
   1379   if (GET_CODE (reg) == SUBREG)
   1380     {
   1381       allocno_subgroup inner = get_allocno_subgroup (SUBREG_REG (reg));
   1382       if (!inner)
   1383 	return {};
   1384 
   1385       if (!targetm.modes_tieable_p (GET_MODE (SUBREG_REG (reg)),
   1386 				    GET_MODE (reg)))
   1387 	{
   1388 	  m_allocation_successful = false;
   1389 	  return {};
   1390 	}
   1391 
   1392       subreg_info info;
   1393       subreg_get_info (V0_REGNUM, GET_MODE (SUBREG_REG (reg)),
   1394 		       SUBREG_BYTE (reg), GET_MODE (reg), &info);
   1395       if (!info.representable_p)
   1396 	{
   1397 	  m_allocation_successful = false;
   1398 	  return {};
   1399 	}
   1400 
   1401       inner.start += info.offset;
   1402       inner.count = info.nregs;
   1403       return inner;
   1404     }
   1405 
   1406   if (!REG_P (reg) || HARD_REGISTER_P (reg))
   1407     return {};
   1408 
   1409   unsigned int regno = REGNO (reg);
   1410   if (fpr_preference (regno) <= 0)
   1411     return {};
   1412 
   1413   unsigned int count = hard_regno_nregs (V0_REGNUM, GET_MODE (reg));
   1414   bool existed;
   1415   auto &entry = m_regno_to_group.get_or_insert (regno, &existed);
   1416   if (!existed)
   1417     {
   1418       auto *group = create_allocno_group (regno, count);
   1419       if (dump_file && (dump_flags & TDF_DETAILS))
   1420 	{
   1421 	  auto allocnos = group->allocnos ();
   1422 	  fprintf (dump_file, "Creating allocnos [%d:%d] for r%d\n",
   1423 		   allocnos.front ().id, allocnos.back ().id, regno);
   1424 	}
   1425 
   1426       auto reg_bits = GET_MODE_BITSIZE (GET_MODE (reg));
   1427       auto fpr_bits = exact_div (reg_bits, count);
   1428       auto flags = m_pseudo_regs[regno].flags;
   1429 
   1430       // Punt for now if there is a choice to be made between using an
   1431       // FPR and a non-FPR.
   1432       if ((flags & NEEDS_NONFPR)
   1433 	  || ((flags & ALLOWS_NONFPR)
   1434 	      && !FLOAT_MODE_P (GET_MODE (reg))
   1435 	      && !VECTOR_MODE_P (GET_MODE (reg))))
   1436 	m_allocation_successful = false;
   1437 
   1438       if (flags & ALLOWS_FPR8)
   1439 	group->fpr_candidates &= 0xff;
   1440       else if (flags & ALLOWS_FPR16)
   1441 	group->fpr_candidates &= 0xffff;
   1442       group->fpr_candidates &= ~0U >> (count - 1);
   1443 
   1444       group->has_flexible_stride = ((flags & HAS_FLEXIBLE_STRIDE) != 0
   1445 				    && (flags & HAS_FIXED_STRIDE) == 0);
   1446 
   1447       group->fpr_size = (maybe_gt (fpr_bits, 128) ? FPR_Z
   1448 			 : maybe_gt (fpr_bits, 64) ? FPR_Q : FPR_D);
   1449 
   1450       entry = group;
   1451     }
   1452   return { entry, 0, count };
   1453 }
   1454 
   1455 // Record a use of FPR REGNO at the current program point, as part of
   1456 // a backwards walk over a block.
   1457 void
   1458 early_ra::record_fpr_use (unsigned int regno)
   1459 {
   1460   gcc_assert (IN_RANGE (regno, V0_REGNUM, V31_REGNUM));
   1461   unsigned int offset = regno - V0_REGNUM;
   1462   if (!(m_live_fprs & (1U << offset)))
   1463     {
   1464       m_fpr_ranges[offset].safe_push ({ START_OF_REGION, m_current_point,
   1465 					INVALID_ALLOCNO });
   1466       m_live_fprs |= 1U << offset;
   1467     }
   1468 }
   1469 
   1470 // Record a definition of FPR REGNO at the current program point, as part of
   1471 // a backwards walk over a block.
   1472 void
   1473 early_ra::record_fpr_def (unsigned int regno)
   1474 {
   1475   gcc_assert (IN_RANGE (regno, V0_REGNUM, V31_REGNUM));
   1476   unsigned int offset = regno - V0_REGNUM;
   1477 
   1478   // The definition completes the current live range.  If the result
   1479   // of the definition is used, the live range extends to the last use.
   1480   // Otherwise the live range is just a momentary blip at the current point.
   1481   auto &ranges = m_fpr_ranges[offset];
   1482   if (m_live_fprs & (1U << offset))
   1483     {
   1484       ranges.last ().start_point = m_current_point;
   1485       m_live_fprs &= ~(1U << offset);
   1486     }
   1487   else
   1488     ranges.safe_push ({ m_current_point, m_current_point, INVALID_ALLOCNO });
   1489 }
   1490 
   1491 // Record a use of allocno ALLOCNO at the current program point, as part
   1492 // of a backwards walk over a block.
   1493 void
   1494 early_ra::record_allocno_use (allocno_info *allocno)
   1495 {
   1496   if (allocno->start_point == m_current_point)
   1497     return;
   1498 
   1499   gcc_checking_assert (!allocno->is_shared ());
   1500   bitmap_set_bit (m_live_allocnos, allocno->id);
   1501   if (allocno->end_point > m_current_point)
   1502     {
   1503       allocno->end_point = m_current_point;
   1504       allocno->last_def_point = START_OF_REGION;
   1505       allocno->last_use_point = END_OF_REGION;
   1506     }
   1507   else
   1508     allocno->last_use_point = allocno->start_point;
   1509   allocno->start_point = m_current_point;
   1510   allocno->is_copy_dest = false;
   1511   allocno->is_strong_copy_src = false;
   1512   allocno->related_allocno = INVALID_ALLOCNO;
   1513   allocno->is_equiv = false;
   1514 }
   1515 
   1516 // Record a definition of the allocno with index AI at the current program
   1517 // point, as part of a backwards walk over a block.  The allocno is known
   1518 // to be live.
   1519 void
   1520 early_ra::record_allocno_def (allocno_info *allocno)
   1521 {
   1522   gcc_checking_assert (!allocno->is_shared ());
   1523   allocno->last_use_point = allocno->start_point;
   1524   allocno->last_def_point = m_current_point;
   1525   allocno->start_point = m_current_point;
   1526   allocno->num_defs = MIN (allocno->num_defs + 1, 2);
   1527   gcc_checking_assert (!allocno->is_copy_dest
   1528 		       && !allocno->is_strong_copy_src);
   1529   if (!bitmap_clear_bit (m_live_allocnos, allocno->id))
   1530     gcc_unreachable ();
   1531 }
   1532 
   1533 // SRC_ALLOCNO is copied or tied to DEST_ALLOCNO; IS_EQUIV is true if the
   1534 // two allocnos are known to be equal.  See whether we can mark a chain of
   1535 // allocnos ending at DEST_ALLOCNO as related to SRC_ALLOCNO.   Return the
   1536 // start of the chain if so, otherwise return null.
   1537 //
   1538 // If IS_EQUIV, a chain that contains just DEST_ALLOCNO should be treated
   1539 // as an equivalence.  Otherwise the chain should be shared with SRC_ALLOCNO.
   1540 //
   1541 // Sharing chains are a rather hacky workaround for the fact that we
   1542 // don't collect segmented live ranges, and that in the end we want to do
   1543 // simple interval graph coloring.
   1544 early_ra::allocno_info *
   1545 early_ra::find_related_start (allocno_info *dest_allocno,
   1546 			      allocno_info *src_allocno, bool is_equiv)
   1547 {
   1548   allocno_info *res = nullptr;
   1549   for (;;)
   1550     {
   1551       if (src_allocno->end_point > dest_allocno->end_point)
   1552 	// The src allocno dies first.
   1553 	return res;
   1554 
   1555       if (src_allocno->num_defs != 0)
   1556 	{
   1557 	  if (dest_allocno->end_point < m_current_bb_point)
   1558 	    // We don't currently track enough information to handle multiple
   1559 	    // definitions across basic block boundaries.
   1560 	    return res;
   1561 
   1562 	  if (src_allocno->last_def_point >= dest_allocno->end_point)
   1563 	    // There is another definition during the destination's live range.
   1564 	    return res;
   1565 	}
   1566       if (is_equiv)
   1567 	{
   1568 	  if (dest_allocno->num_defs == 1)
   1569 	    // dest_allocno is equivalent to src_allocno for dest_allocno's
   1570 	    // entire live range.  Fall back to that if we can't establish
   1571 	    // a sharing chain.
   1572 	    res = dest_allocno;
   1573 	}
   1574       else
   1575 	{
   1576 	  if (src_allocno->last_use_point >= dest_allocno->end_point)
   1577 	    // src_allocno is live during dest_allocno's live range,
   1578 	    // and the two allocnos do not necessarily have the same value.
   1579 	    return res;
   1580 	}
   1581 
   1582       if (dest_allocno->group_size != 1
   1583 	  // Account for definitions by shared registers.
   1584 	  || dest_allocno->num_defs > 1
   1585 	  || DF_REG_DEF_COUNT (dest_allocno->group ()->regno) != 1)
   1586 	// Currently only single allocnos that are defined once can
   1587 	// share registers with non-equivalent allocnos.  This could be
   1588 	// relaxed, but at the time of writing, aggregates are not valid
   1589 	// SSA names and so generally only use a single pseudo throughout
   1590 	// their lifetime.
   1591 	return res;
   1592 
   1593       if (dest_allocno->copy_dest == src_allocno->id)
   1594 	// We've found a complete and valid sharing chain.
   1595 	return dest_allocno;
   1596 
   1597       if (dest_allocno->copy_dest == INVALID_ALLOCNO)
   1598 	return res;
   1599 
   1600       auto *next_allocno = m_allocnos[dest_allocno->copy_dest];
   1601       if (!is_chain_candidate (dest_allocno, next_allocno, ALL_REASONS))
   1602 	return res;
   1603 
   1604       dest_allocno = next_allocno;
   1605       is_equiv = false;
   1606     }
   1607 }
   1608 
   1609 // Add FROM_ALLOCNO's definition information to TO_ALLOCNO's.
   1610 void
   1611 early_ra::accumulate_defs (allocno_info *to_allocno,
   1612 			   allocno_info *from_allocno)
   1613 {
   1614   if (from_allocno->num_defs > 0)
   1615     {
   1616       to_allocno->num_defs = MIN (from_allocno->num_defs
   1617 				  + to_allocno->num_defs, 2);
   1618       to_allocno->last_def_point = MAX (to_allocno->last_def_point,
   1619 					from_allocno->last_def_point);
   1620     }
   1621 }
   1622 
   1623 // Record any relevant allocno-related information for an actual or imagined
   1624 // copy from SRC to DEST.  FROM_MOVE_P is true if the copy was an explicit
   1625 // move instruction, false if it represents one way of satisfying the previous
   1626 // instruction's constraints.
   1627 void
   1628 early_ra::record_copy (rtx dest, rtx src, bool from_move_p)
   1629 {
   1630   auto dest_range = get_allocno_subgroup (dest);
   1631   auto src_range = get_allocno_subgroup (src);
   1632   if (from_move_p
   1633       && dest_range
   1634       && REG_P (src)
   1635       && FP_REGNUM_P (REGNO (src)))
   1636     {
   1637       // A copy from an FPR to an allocno group.
   1638       unsigned int fpr = REGNO (src) - V0_REGNUM;
   1639       m_allocno_copies.safe_push ({ dest_range.allocno (0)->id, fpr,
   1640 				    dest_range.count });
   1641 
   1642       // If the allocno at the other end of the chain of copies from DEST
   1643       // has a copy to the same FPR, record that all intervening copy chains
   1644       // could become "strong" ones.  This indicates that picking the FPR
   1645       // avoids a copy at both ends.
   1646       unsigned int hard_regno = REGNO (src);
   1647       for (auto &dest_allocno : dest_range.allocnos ())
   1648 	if (dest_allocno.hard_regno == hard_regno++)
   1649 	  dest_allocno.is_strong_copy_src = true;
   1650     }
   1651   else if (from_move_p
   1652 	   && src_range
   1653 	   && REG_P (dest)
   1654 	   && FP_REGNUM_P (REGNO (dest)))
   1655     {
   1656       // A copy from an allocno group to an FPR.
   1657       unsigned int fpr = REGNO (dest) - V0_REGNUM;
   1658       m_allocno_copies.safe_push ({ src_range.allocno (0)->id, fpr,
   1659 				    src_range.count });
   1660       for (auto &src_allocno : src_range.allocnos ())
   1661 	{
   1662 	  // If the copy comes from a move, see whether the destination
   1663 	  // FPR is known to be equal to the source allocno for the FPR's
   1664 	  // last live range.
   1665 	  if (from_move_p && src_allocno.num_defs == 0)
   1666 	    {
   1667 	      auto &last_range = m_fpr_ranges[fpr].last ();
   1668 	      if (last_range.end_point >= src_allocno.end_point)
   1669 		last_range.allocno = src_allocno.id;
   1670 	    }
   1671 	  src_allocno.hard_regno = V0_REGNUM + fpr;
   1672 	  fpr += 1;
   1673 	}
   1674     }
   1675   else if (src_range && dest_range)
   1676     {
   1677       // A copy between two allocno groups.  We can only have a mismatched
   1678       // number of FPRs for imaginary, non-move copies.  In that case
   1679       // the matching happens on the common lowparts.
   1680       gcc_assert (!from_move_p || src_range.count == dest_range.count);
   1681       unsigned int count = std::min (src_range.count, dest_range.count);
   1682       if (WORDS_BIG_ENDIAN)
   1683 	{
   1684 	  src_range.start += src_range.count - count;
   1685 	  dest_range.start += dest_range.count - count;
   1686 	}
   1687       src_range.count = count;
   1688       dest_range.count = count;
   1689 
   1690       // Ignore (imaginary non-move) copies if the destination is still live.
   1691       for (auto &dest_allocno : dest_range.allocnos ())
   1692 	if (bitmap_bit_p (m_live_allocnos, dest_allocno.id))
   1693 	  return;
   1694 
   1695       for (unsigned int i = 0; i < src_range.count; ++i)
   1696 	{
   1697 	  auto *dest_allocno = dest_range.allocno (i);
   1698 	  auto *src_allocno = src_range.allocno (i);
   1699 	  if (src_allocno->end_point > dest_allocno->start_point)
   1700 	    {
   1701 	      gcc_assert (src_allocno->copy_dest == INVALID_ALLOCNO
   1702 			  || src_allocno->copy_dest == dest_allocno->id);
   1703 	      src_allocno->copy_dest = dest_allocno->id;
   1704 	      src_allocno->hard_regno = dest_allocno->hard_regno;
   1705 	      dest_allocno->is_copy_dest = 1;
   1706 	    }
   1707 	  else if (auto *start_allocno = find_related_start (dest_allocno,
   1708 							     src_allocno,
   1709 							     from_move_p))
   1710 	    {
   1711 	      auto *next_allocno = dest_allocno;
   1712 	      for (;;)
   1713 		{
   1714 		  next_allocno->related_allocno = src_allocno->id;
   1715 		  next_allocno->is_equiv = (start_allocno == dest_allocno
   1716 					    && from_move_p);
   1717 		  // If we're sharing two allocnos that are not equivalent,
   1718 		  // carry across the definition information.  This is needed
   1719 		  // to prevent multiple incompatible attempts to share with
   1720 		  // the same register.
   1721 		  if (next_allocno->is_shared ())
   1722 		    accumulate_defs (src_allocno, next_allocno);
   1723 		  src_allocno->last_use_point
   1724 		    = MAX (src_allocno->last_use_point,
   1725 			   next_allocno->last_use_point);
   1726 
   1727 		  if (next_allocno == start_allocno)
   1728 		    break;
   1729 		  next_allocno = m_allocnos[next_allocno->copy_dest];
   1730 		}
   1731 	    }
   1732 	}
   1733     }
   1734 }
   1735 
   1736 // Record any relevant allocno-related information about the constraints
   1737 // on INSN, which has already been extracted.
   1738 void
   1739 early_ra::record_constraints (rtx_insn *insn)
   1740 {
   1741   preprocess_constraints (insn);
   1742 
   1743   int operand_matches[MAX_RECOG_OPERANDS];
   1744   for (int i = 0; i < recog_data.n_operands; ++i)
   1745     operand_matches[i] = -1;
   1746 
   1747   auto alts = get_preferred_alternatives (insn);
   1748   bool any_ok = recog_data.n_alternatives == 0;
   1749 
   1750   // The set of output operands that are earlyclobber in at least one
   1751   // alternative.
   1752   operand_mask earlyclobber_operands = 0;
   1753 
   1754   // The set of output operands that are matched to inputs in at least
   1755   // one alternative.
   1756   operand_mask matched_operands = 0;
   1757 
   1758   // The set of output operands that are not matched to inputs in at least
   1759   // one alternative.
   1760   operand_mask unmatched_operands = 0;
   1761 
   1762   // The set of input operands that are matched to outputs in at least one
   1763   // alternative, or that overlap with such an input if the output is not
   1764   // earlyclobber.  The latter part of the condition copes with things
   1765   // like y = x * x, where the first x is tied to the destination, and where
   1766   // y is not earlyclobber.
   1767   operand_mask matches_operands = 0;
   1768 
   1769   for (int altno = 0; altno < recog_data.n_alternatives; ++altno)
   1770     {
   1771       if (!(alts & ALTERNATIVE_BIT (altno)))
   1772 	continue;
   1773 
   1774       auto *op_alt = &recog_op_alt[altno * recog_data.n_operands];
   1775       if (!likely_alternative_match_p (op_alt))
   1776 	continue;
   1777 
   1778       any_ok = true;
   1779 
   1780       // Update the information for operand DEST_OPNO based on the constraint
   1781       // information for operand SRC_OPNO.  The numbers can be different for
   1782       // swapped commutative operands.
   1783       auto record_operand = [&](int src_opno, int dest_opno)
   1784 	{
   1785 	  int matches = op_alt[src_opno].matches;
   1786 	  // A matched earlyclobber cannot be used if the same operand value
   1787 	  // occurs in an unmatched operand.  E.g. for y = x * x, a matched
   1788 	  // earlyclobber on the first input does not cover the second input.
   1789 	  if (matches >= 0)
   1790 	    {
   1791 	      rtx op = recog_data.operand[dest_opno];
   1792 	      operand_mask overlaps = 0;
   1793 	      for (int i = 0; i < recog_data.n_operands; ++i)
   1794 		if (i != dest_opno
   1795 		    && !recog_data.is_operator[i]
   1796 		    && recog_data.operand_type[i] != OP_OUT
   1797 		    && reg_overlap_mentioned_p (op, recog_data.operand[i]))
   1798 		  overlaps |= 1U << i;
   1799 	      if (!op_alt[matches].earlyclobber || overlaps == 0)
   1800 		{
   1801 		  operand_matches[dest_opno] = matches;
   1802 		  matches_operands |= (1U << dest_opno) | overlaps;
   1803 		}
   1804 	    }
   1805 	};
   1806 
   1807       auto reject = count_rejects (op_alt);
   1808       for (int opno = 0; opno < recog_data.n_operands; ++opno)
   1809 	{
   1810 	  operand_mask op_mask = operand_mask (1) << opno;
   1811 
   1812 	  if (recog_data.operand_type[opno] != OP_IN)
   1813 	    {
   1814 	      if (reject == 0 && op_alt[opno].matched >= 0)
   1815 		matched_operands |= op_mask;
   1816 	      else
   1817 		unmatched_operands |= op_mask;
   1818 	    }
   1819 
   1820 	  if (op_alt[opno].earlyclobber)
   1821 	    earlyclobber_operands |= op_mask;
   1822 
   1823 	  // Punt for now on scratches.  If we wanted to handle them,
   1824 	  // we'd need to create allocnos for them, like IRA does.
   1825 	  rtx op = recog_data.operand[opno];
   1826 	  if (GET_CODE (op) == SCRATCH
   1827 	      && reg_classes_intersect_p (op_alt[opno].cl, FP_REGS))
   1828 	    m_allocation_successful = false;
   1829 
   1830 	  // Record filter information, which applies to the first register
   1831 	  // in the operand.
   1832 	  if (auto filters = alternative_register_filters (op_alt, opno))
   1833 	    if (auto range = get_allocno_subgroup (recog_data.operand[opno]))
   1834 	      for (unsigned int fpr = range.start; fpr < 32; ++fpr)
   1835 		if (!test_register_filters (filters, fpr))
   1836 		  range.group->fpr_candidates &= ~(1U << (fpr - range.start));
   1837 
   1838 	  if (reject == 0)
   1839 	    {
   1840 	      // Record possible matched operands.
   1841 	      record_operand (opno, opno);
   1842 	      if (recog_data.constraints[opno][0] == '%')
   1843 		{
   1844 		  record_operand (opno, opno + 1);
   1845 		  record_operand (opno + 1, opno);
   1846 		}
   1847 	    }
   1848 	}
   1849     }
   1850 
   1851   if (!any_ok)
   1852     {
   1853       if (dump_file && (dump_flags & TDF_DETAILS))
   1854 	fprintf (dump_file, "       -- no match\n");
   1855       m_allocation_successful = false;
   1856     }
   1857 
   1858   // Record if there is an output operand that is never earlyclobber and never
   1859   // matched to an input.  See the comment below for how this is used.
   1860   rtx dest_op = NULL_RTX;
   1861   for (int opno = 0; opno < recog_data.n_operands; ++opno)
   1862     {
   1863       auto op_mask = operand_mask (1) << opno;
   1864       if (recog_data.operand_type[opno] == OP_OUT
   1865 	  && (earlyclobber_operands & op_mask) == 0
   1866 	  && (matched_operands & op_mask) == 0)
   1867 	{
   1868 	  dest_op = recog_data.operand[opno];
   1869 	  break;
   1870 	}
   1871     }
   1872 
   1873   for (int opno = 0; opno < recog_data.n_operands; ++opno)
   1874     {
   1875       auto op_mask = operand_mask (1) << opno;
   1876       rtx op = recog_data.operand[opno];
   1877       int matches = operand_matches[opno];
   1878 
   1879       // Punt for now on operands that already have a fixed choice of
   1880       // register, since we don't have IRA's ability to find an alternative.
   1881       // It's better if earlier passes don't create this kind of situation.
   1882       if (REG_P (op) && FP_REGNUM_P (REGNO (op)))
   1883 	m_allocation_successful = false;
   1884 
   1885       // Treat input operands as being earlyclobbered if an output is
   1886       // sometimes earlyclobber and if the input never matches an output.
   1887       // Do the same if there is an output that is always matched to an
   1888       // input, and if this operand doesn't match that input.  In both
   1889       // cases, tying the input and the output would lead to an impossible
   1890       // combination (or at least one that is difficult to reload).
   1891       if (recog_data.operand_type[opno] != OP_OUT
   1892 	  && ((earlyclobber_operands && matches < 0)
   1893 	      || ((matched_operands & ~unmatched_operands)
   1894 		  && !(matches_operands & op_mask))))
   1895 	for (auto &allocno : get_allocno_subgroup (op).allocnos ())
   1896 	  if (allocno.end_point + 1 == m_current_point)
   1897 	    allocno.is_earlyclobbered = true;
   1898 
   1899       // Create copies between operands that can be tied.  This (deliberately)
   1900       // might add several copies to the same destination register; later code
   1901       // can then choose between them based on other criteria.
   1902       //
   1903       // If there is an output operand that is never matched or earlyclobber,
   1904       // and an input operand that never matches an output operand, create
   1905       // a tentative copy between them.  This allows hard register preferences
   1906       // to be transmitted along the copy chains.
   1907       if (matches >= 0)
   1908 	record_copy (recog_data.operand[matches], op);
   1909       else if (dest_op && recog_data.operand_type[opno] == OP_IN)
   1910 	record_copy (dest_op, op);
   1911     }
   1912 }
   1913 
   1914 // If FLAGS is DF_REF_AT_TOP, model the artificial uses and defs at the
   1915 // start of the current basic block, otherwise model the artificial uses
   1916 // and defs at the end of the basic block.  This is done as part of a
   1917 // backwards walk, so defs should be processed before uses.
   1918 void
   1919 early_ra::record_artificial_refs (unsigned int flags)
   1920 {
   1921   df_ref ref;
   1922 
   1923   FOR_EACH_ARTIFICIAL_DEF (ref, m_current_bb->index)
   1924     if ((DF_REF_FLAGS (ref) & DF_REF_AT_TOP) == flags
   1925 	&& IN_RANGE (DF_REF_REGNO (ref), V0_REGNUM, V31_REGNUM))
   1926       record_fpr_def (DF_REF_REGNO (ref));
   1927   m_current_point += 1;
   1928 
   1929   FOR_EACH_ARTIFICIAL_USE (ref, m_current_bb->index)
   1930     if ((DF_REF_FLAGS (ref) & DF_REF_AT_TOP) == flags
   1931 	&& IN_RANGE (DF_REF_REGNO (ref), V0_REGNUM, V31_REGNUM))
   1932       record_fpr_use (DF_REF_REGNO (ref));
   1933   m_current_point += 1;
   1934 }
   1935 
   1936 // Return true if:
   1937 //
   1938 // - X is a SUBREG, in which case it is a SUBREG of some REG Y
   1939 //
   1940 // - one 64-bit word of Y can be modified while preserving all other words
   1941 //
   1942 // - X refers to no more than one 64-bit word of Y
   1943 //
   1944 // - assigning FPRs to Y would put more than one 64-bit word in each FPR
   1945 //
   1946 // For example, this is true of:
   1947 //
   1948 // - (subreg:DI (reg:TI R) 0) and
   1949 // - (subreg:DI (reg:TI R) 8)
   1950 //
   1951 // but is not true of:
   1952 //
   1953 // - (subreg:V2SI (reg:V2x2SI R) 0) or
   1954 // - (subreg:V2SI (reg:V2x2SI R) 8).
   1955 static bool
   1956 allocno_assignment_is_rmw (rtx x)
   1957 {
   1958   if (partial_subreg_p (x))
   1959     {
   1960       auto outer_mode = GET_MODE (x);
   1961       auto inner_mode = GET_MODE (SUBREG_REG (x));
   1962       if (known_eq (REGMODE_NATURAL_SIZE (inner_mode), 0U + UNITS_PER_WORD)
   1963 	  && known_lt (GET_MODE_SIZE (outer_mode), UNITS_PER_VREG))
   1964 	{
   1965 	  auto nregs = targetm.hard_regno_nregs (V0_REGNUM, inner_mode);
   1966 	  if (maybe_ne (nregs * UNITS_PER_WORD, GET_MODE_SIZE (inner_mode)))
   1967 	    return true;
   1968 	}
   1969     }
   1970   return false;
   1971 }
   1972 
   1973 // Model the register references in INSN as part of a backwards walk.
   1974 void
   1975 early_ra::record_insn_refs (rtx_insn *insn)
   1976 {
   1977   df_ref ref;
   1978 
   1979   // Record all definitions, excluding partial call clobbers.
   1980   FOR_EACH_INSN_DEF (ref, insn)
   1981     if (IN_RANGE (DF_REF_REGNO (ref), V0_REGNUM, V31_REGNUM))
   1982       record_fpr_def (DF_REF_REGNO (ref));
   1983     else
   1984       {
   1985 	rtx reg = DF_REF_REG (ref);
   1986 	auto range = get_allocno_subgroup (reg);
   1987 	for (auto &allocno : range.allocnos ())
   1988 	  {
   1989 	    // Make sure that assigning to the DF_REF_REG clobbers the
   1990 	    // whole of this allocno, not just some of it.
   1991 	    if (allocno_assignment_is_rmw (reg))
   1992 	      {
   1993 		m_allocation_successful = false;
   1994 		if (dump_file && (dump_flags & TDF_DETAILS))
   1995 		  fprintf (dump_file, "read-modify-write of allocno %d",
   1996 			   allocno.id);
   1997 		break;
   1998 	      }
   1999 
   2000 	    // If the destination is unused, record a momentary blip
   2001 	    // in its live range.
   2002 	    if (!bitmap_bit_p (m_live_allocnos, allocno.id))
   2003 	      record_allocno_use (&allocno);
   2004 	    record_allocno_def (&allocno);
   2005 	  }
   2006       }
   2007   m_current_point += 1;
   2008 
   2009   // Model the call made by a call insn as a separate phase in the
   2010   // evaluation of the insn.  Any partial call clobbers happen at that
   2011   // point, rather than in the definition or use phase of the insn.
   2012   if (auto *call_insn = dyn_cast<rtx_call_insn *> (insn))
   2013     {
   2014       function_abi abi = insn_callee_abi (call_insn);
   2015       m_call_points[abi.id ()].safe_push (m_current_point);
   2016       m_current_point += 1;
   2017     }
   2018 
   2019   // Record all uses.  We can ignore READ_MODIFY_WRITE uses of plain subregs,
   2020   // since we track the FPR-sized parts of them individually.
   2021   FOR_EACH_INSN_USE (ref, insn)
   2022     if (IN_RANGE (DF_REF_REGNO (ref), V0_REGNUM, V31_REGNUM))
   2023       record_fpr_use (DF_REF_REGNO (ref));
   2024     else if (!DF_REF_FLAGS_IS_SET (ref, DF_REF_READ_WRITE)
   2025 	     || DF_REF_FLAGS_IS_SET (ref, DF_REF_STRICT_LOW_PART)
   2026 	     || DF_REF_FLAGS_IS_SET (ref, DF_REF_ZERO_EXTRACT))
   2027       {
   2028 	auto range = get_allocno_subgroup (DF_REF_REG (ref));
   2029 	for (auto &allocno : range.allocnos ())
   2030 	  record_allocno_use (&allocno);
   2031       }
   2032   m_current_point += 1;
   2033 }
   2034 
   2035 // ALLOCNO->is_strong_copy_src is true.  See whether ALLOCNO heads a
   2036 // natural chain that has an affinity with the same hard register at
   2037 // both ends.
   2038 bool
   2039 early_ra::consider_strong_copy_src_chain (allocno_info *allocno)
   2040 {
   2041   auto *src_allocno = allocno;
   2042   while (src_allocno->copy_dest != INVALID_ALLOCNO)
   2043     {
   2044       auto *dest_allocno = m_allocnos[src_allocno->copy_dest];
   2045       if (dest_allocno->start_point > src_allocno->end_point
   2046 	  || dest_allocno->hard_regno != src_allocno->hard_regno)
   2047 	return false;
   2048       gcc_checking_assert (dest_allocno->is_copy_dest);
   2049       src_allocno = dest_allocno;
   2050     }
   2051 
   2052   while (allocno->copy_dest != INVALID_ALLOCNO)
   2053     {
   2054       allocno->is_strong_copy_src = 1;
   2055       allocno = m_allocnos[allocno->copy_dest];
   2056       allocno->is_strong_copy_dest = 1;
   2057     }
   2058   return true;
   2059 }
   2060 
   2061 // ALLOCNO1 and ALLOCNO2 are linked in some way, and might end up being
   2062 // chained together.  See whether chaining them requires the containing
   2063 // groups to have the same stride, or whether it requires them to have
   2064 // different strides.  Return 1 if they should have the same stride,
   2065 // -1 if they should have different strides, or 0 if it doesn't matter.
   2066 int
   2067 early_ra::strided_polarity_pref (allocno_info *allocno1,
   2068 				 allocno_info *allocno2)
   2069 {
   2070   if (allocno1->offset + 1 < allocno1->group_size
   2071       && allocno2->offset + 1 < allocno2->group_size)
   2072     {
   2073       if (is_chain_candidate (allocno1 + 1, allocno2 + 1, ALL_REASONS))
   2074 	return 1;
   2075       else
   2076 	return -1;
   2077     }
   2078 
   2079   if (allocno1->offset > 0 && allocno2->offset > 0)
   2080     {
   2081       if (is_chain_candidate (allocno1 - 1, allocno2 - 1, ALL_REASONS))
   2082 	return 1;
   2083       else
   2084 	return -1;
   2085     }
   2086 
   2087   return 0;
   2088 }
   2089 
   2090 // Decide which groups should be strided.  Also complete "strong" copy chains.
   2091 void
   2092 early_ra::find_strided_accesses ()
   2093 {
   2094   // This function forms a graph of allocnos, linked by equivalences and
   2095   // natural copy chains.  It temporarily uses chain_next to record the
   2096   // reverse of equivalence edges (related_allocno) and chain_prev to record
   2097   // the reverse of copy edges (copy_dest).
   2098   unsigned int allocno_info::*links[] = {
   2099     &allocno_info::chain_next,
   2100     &allocno_info::chain_prev,
   2101     &allocno_info::copy_dest,
   2102     &allocno_info::related_allocno
   2103   };
   2104 
   2105   // Set up the temporary reverse edges.  Check for strong copy chains.
   2106   for (unsigned int i = m_allocnos.length (); i-- > 0; )
   2107     {
   2108       auto *allocno1 = m_allocnos[i];
   2109       if (allocno1->copy_dest != INVALID_ALLOCNO)
   2110 	m_allocnos[allocno1->copy_dest]->chain_prev = allocno1->id;
   2111       if (allocno1->related_allocno != INVALID_ALLOCNO)
   2112 	m_allocnos[allocno1->related_allocno]->chain_next = allocno1->id;
   2113 
   2114       if (allocno1->is_strong_copy_src
   2115 	  && !allocno1->is_copy_dest
   2116 	  && !consider_strong_copy_src_chain (allocno1))
   2117 	allocno1->is_strong_copy_src = false;
   2118     }
   2119 
   2120   // Partition the graph into cliques based on edges that have the following
   2121   // properties:
   2122   //
   2123   // - the edge joins two allocnos whose groups have a free choice between
   2124   //   consecutive and strided allocations.
   2125   //
   2126   // - the two groups have a relative strided polarity preference (that is
   2127   //   they should make the same choice between consecutive and strided,
   2128   //   or they should make opposite choices).
   2129   //
   2130   // Assign relative polarities to each group connected in this way.
   2131   //
   2132   // The aim is to discover natural move-free striding choices, which will
   2133   // often exist in carefully written ACLE code.
   2134   unsigned int num_edges = m_allocnos.length () * ARRAY_SIZE (links);
   2135   auto_sbitmap visited_edges (num_edges);
   2136   bitmap_clear (visited_edges);
   2137 
   2138   auto_vec<unsigned int, 32> worklist;
   2139   for (unsigned int i = 0; i < num_edges; ++i)
   2140     {
   2141       if (!bitmap_set_bit (visited_edges, i))
   2142 	continue;
   2143       worklist.quick_push (i);
   2144       while (!worklist.is_empty ())
   2145 	{
   2146 	  auto ei = worklist.pop ();
   2147 	  auto *allocno1 = m_allocnos[ei / ARRAY_SIZE (links)];
   2148 	  auto ai2 = allocno1->*links[ei % ARRAY_SIZE (links)];
   2149 	  if (ai2 == INVALID_ALLOCNO)
   2150 	    continue;
   2151 
   2152 	  auto *allocno2 = m_allocnos[ai2];
   2153 	  auto *group1 = allocno1->group ();
   2154 	  auto *group2 = allocno2->group ();
   2155 	  if (!group1->has_flexible_stride || !group2->has_flexible_stride)
   2156 	    continue;
   2157 
   2158 	  int pref = strided_polarity_pref (allocno1, allocno2);
   2159 	  if (pref == 0)
   2160 	    continue;
   2161 
   2162 	  for (auto *group : { group1, group2 })
   2163 	    for (auto &allocno : group->allocnos ())
   2164 	      for (unsigned int j = 0; j < ARRAY_SIZE (links); ++j)
   2165 		if (bitmap_set_bit (visited_edges, allocno.id * 4 + j))
   2166 		  worklist.safe_push (allocno.id * 4 + j);
   2167 
   2168 	  if (group1->strided_polarity)
   2169 	    group2->strided_polarity = group1->strided_polarity * pref;
   2170 	  else if (group2->strided_polarity)
   2171 	    group1->strided_polarity = group2->strided_polarity * pref;
   2172 	  else
   2173 	    {
   2174 	      group1->strided_polarity = 1;
   2175 	      group2->strided_polarity = pref;
   2176 	    }
   2177 	}
   2178     }
   2179 
   2180   // Now look for edges between allocnos in multi-register groups where:
   2181   //
   2182   // - the two groups have a relative strided polarity preference (as above).
   2183   //
   2184   // - one group (G1) has a free choice between consecutive and strided
   2185   //   allocations.
   2186   //
   2187   // - the other group (G2) must use consecutive allocations.
   2188   //
   2189   // Update G1's individual preference for strided or consecutive allocations
   2190   // based on G2.  If the previous loop chose a polarity for G1, work out
   2191   // whether it is better for polarity 1 or -1 to correspond to consecutive
   2192   // allocation.
   2193   int consecutive_pref = 0;
   2194   for (unsigned int i = m_allocnos.length (); i-- > 0; )
   2195     {
   2196       auto *allocno1 = m_allocnos[i];
   2197       for (auto link : links)
   2198 	{
   2199 	  auto ai2 = allocno1->*link;
   2200 	  if (ai2 == INVALID_ALLOCNO)
   2201 	    continue;
   2202 
   2203 	  auto *allocno2 = m_allocnos[ai2];
   2204 	  auto *group1 = allocno1->group ();
   2205 	  auto *group2 = allocno2->group ();
   2206 	  if (group1->has_flexible_stride == group2->has_flexible_stride)
   2207 	    continue;
   2208 
   2209 	  int pref = strided_polarity_pref (allocno1, allocno2);
   2210 	  if (pref == 0)
   2211 	    continue;
   2212 
   2213 	  auto *group = (group1->has_flexible_stride ? group1 : group2);
   2214 	  consecutive_pref += group->strided_polarity * pref;
   2215 	  group->consecutive_pref += pref;
   2216 	}
   2217     }
   2218 
   2219   // If it doesn't matter whether polarity 1 or -1 corresponds to consecutive
   2220   // allocation, arbitrarily pick 1.
   2221   if (consecutive_pref == 0)
   2222     consecutive_pref = 1;
   2223 
   2224   // Record which multi-register groups should use strided allocations.
   2225   // Clear out the temporary edges.
   2226   for (unsigned int ai = 0; ai < m_allocnos.length (); ++ai)
   2227     {
   2228       auto *allocno = m_allocnos[ai];
   2229       allocno->chain_prev = INVALID_ALLOCNO;
   2230       allocno->chain_next = INVALID_ALLOCNO;
   2231 
   2232       if (allocno->offset != 0)
   2233 	continue;
   2234 
   2235       auto *group = allocno->group ();
   2236       if (!group->has_flexible_stride)
   2237 	continue;
   2238 
   2239       bool make_strided = (group->strided_polarity
   2240 			   ? (consecutive_pref * group->strided_polarity) < 0
   2241 			   : group->consecutive_pref < 0);
   2242       if (dump_file && (dump_flags & TDF_DETAILS))
   2243 	fprintf (dump_file, "Allocno [%d:%d]: strided polarity %d,"
   2244 		 " consecutive pref %d, %s\n",
   2245 		 allocno->id, allocno->id + group->size - 1,
   2246 		 group->strided_polarity, group->consecutive_pref,
   2247 		 make_strided ? "making strided" : "keeping consecutive");
   2248       if (!make_strided)
   2249 	continue;
   2250 
   2251       // 2-register groups have a stride of 8 FPRs and must start in
   2252       // registers matching the mask 0x17.  4-register groups have a stride
   2253       // of 4 FPRs and must start in registers matching the mask 0x13.
   2254       group->stride = group->size == 2 ? 8 : 4;
   2255       gcc_checking_assert (group->fpr_candidates
   2256 			   == (group->size == 2 ? 0x55555555 : 0x11111111));
   2257       group->fpr_candidates = (group->size == 2 ? 0xff00ff : 0xf000f);
   2258     }
   2259 }
   2260 
   2261 // Compare the allocnos at *ALLOCNO1_PTR and *ALLOCNO2_PTR and return a <=>
   2262 // result that puts allocnos in order of increasing FIELD.
   2263 template<unsigned int early_ra::allocno_info::*field>
   2264 int
   2265 early_ra::cmp_increasing (const void *allocno1_ptr, const void *allocno2_ptr)
   2266 {
   2267   auto *allocno1 = *(allocno_info *const *) allocno1_ptr;
   2268   auto *allocno2 = *(allocno_info *const *) allocno2_ptr;
   2269 
   2270   if (allocno1->*field != allocno2->*field)
   2271     return allocno1->*field < allocno2->*field ? -1 : 1;
   2272   return (allocno1->id < allocno2->id ? -1
   2273 	  : allocno1->id == allocno2->id ? 0 : 1);
   2274 }
   2275 
   2276 // Return true if we should consider chaining ALLOCNO1 onto the head
   2277 // of ALLOCNO2.  STRICTNESS says whether we should take copy-elision
   2278 // heuristics into account, or whether we should just consider things
   2279 // that matter for correctness.
   2280 //
   2281 // This is just a local test of the two allocnos; it doesn't guarantee
   2282 // that chaining them would give a self-consistent system.
   2283 bool
   2284 early_ra::is_chain_candidate (allocno_info *allocno1, allocno_info *allocno2,
   2285 			      test_strictness strictness)
   2286 {
   2287   if (allocno2->is_shared ())
   2288     return false;
   2289 
   2290   while (allocno1->is_equiv)
   2291     allocno1 = m_allocnos[allocno1->related_allocno];
   2292 
   2293   if (allocno2->start_point >= allocno1->end_point
   2294       && !allocno2->is_equiv_to (allocno1->id))
   2295     return false;
   2296 
   2297   if (allocno1->is_earlyclobbered
   2298       && allocno1->end_point == allocno2->start_point + 1)
   2299     return false;
   2300 
   2301   if (strictness == ALL_REASONS && allocno2->is_copy_dest)
   2302     {
   2303       if (allocno1->copy_dest != allocno2->id)
   2304 	return false;
   2305       if (allocno2->is_strong_copy_dest && !allocno1->is_strong_copy_src)
   2306 	return false;
   2307     }
   2308   return true;
   2309 }
   2310 
   2311 // We're trying to chain allocno ALLOCNO1 to a later allocno.
   2312 // Rate how good a choice ALLOCNO2 would be, with higher being better.
   2313 int
   2314 early_ra::rate_chain (allocno_info *allocno1, allocno_info *allocno2)
   2315 {
   2316   int score = 0;
   2317   if (allocno2->is_strong_copy_dest)
   2318     score += 256;
   2319   else if (allocno2->is_copy_dest)
   2320     score += 128;
   2321 
   2322   // Prefer well-aligned matches.
   2323   auto *group1 = allocno1->group ();
   2324   auto *group2 = allocno2->group ();
   2325   if (group1->stride == 1 && group2->stride == 1)
   2326     {
   2327       unsigned int min_size = std::min (group1->color_rep ()->size,
   2328 					group2->color_rep ()->size);
   2329       if ((group1->color_rep_offset + allocno1->offset) % min_size
   2330 	  == (group2->color_rep_offset + allocno2->offset) % min_size)
   2331 	score += min_size;
   2332       else
   2333 	score -= min_size;
   2334     }
   2335   return score;
   2336 }
   2337 
   2338 // Sort the chain_candidate_infos at ARG1 and ARG2 in order of decreasing
   2339 // score.
   2340 int
   2341 early_ra::cmp_chain_candidates (const void *arg1, const void *arg2)
   2342 {
   2343   auto &candidate1 = *(const chain_candidate_info *) arg1;
   2344   auto &candidate2 = *(const chain_candidate_info *) arg2;
   2345   if (candidate1.score != candidate2.score)
   2346     return candidate1.score > candidate2.score ? -1 : 1;
   2347 
   2348   // Prefer to increase the gap between uses of the allocated register,
   2349   // to give the scheduler more freedom.
   2350   auto *allocno1 = candidate1.allocno;
   2351   auto *allocno2 = candidate2.allocno;
   2352   if (allocno1->start_point != allocno2->start_point)
   2353     return allocno1->start_point < allocno2->start_point ? -1 : 1;
   2354 
   2355   if (allocno1 != allocno2)
   2356     return allocno1->id < allocno2->id ? -1 : 1;
   2357 
   2358   return 0;
   2359 }
   2360 
   2361 // Join the chains of allocnos that start at HEADI1 and HEADI2.
   2362 // HEADI1 is either empty or a single allocno.
   2363 void
   2364 early_ra::chain_allocnos (unsigned int &headi1, unsigned int &headi2)
   2365 {
   2366   if (headi1 == INVALID_ALLOCNO)
   2367     headi1 = headi2;
   2368   else if (headi2 == INVALID_ALLOCNO)
   2369     headi2 = headi1;
   2370   else
   2371     {
   2372       auto *head1 = m_allocnos[headi1];
   2373       auto *head2 = m_allocnos[headi2];
   2374       gcc_checking_assert (head1->chain_next == INVALID_ALLOCNO
   2375 			   && head1->chain_prev == INVALID_ALLOCNO
   2376 			   && head2->chain_prev == INVALID_ALLOCNO);
   2377 
   2378       if (head1->is_equiv
   2379 	  && m_allocnos[head1->related_allocno]->copy_dest == headi2)
   2380 	{
   2381 	  head1->is_copy_dest = head2->is_copy_dest;
   2382 	  head1->is_strong_copy_dest = head2->is_strong_copy_dest;
   2383 	  m_allocnos[head1->related_allocno]->copy_dest = headi1;
   2384 	}
   2385       head1->chain_next = headi2;
   2386       head2->chain_prev = headi1;
   2387 
   2388       headi2 = headi1;
   2389     }
   2390 }
   2391 
   2392 // Add GROUP2's FPR information to GROUP1's, given that GROUP2 starts
   2393 // OFFSET allocnos into GROUP2.
   2394 void
   2395 early_ra::merge_fpr_info (allocno_group_info *group1,
   2396 			  allocno_group_info *group2,
   2397 			  unsigned int offset)
   2398 {
   2399   group1->fpr_size = std::max (group1->fpr_size, group2->fpr_size);
   2400   group1->fpr_candidates &= (group2->fpr_candidates
   2401 			     >> (offset * group1->stride));
   2402 }
   2403 
   2404 // Set the color representative of ALLOCNO's group to REP, such that ALLOCNO
   2405 // ends being at allocno offset REP_OFFSET from the start of REP.
   2406 void
   2407 early_ra::set_single_color_rep (allocno_info *allocno, allocno_group_info *rep,
   2408 				unsigned int rep_offset)
   2409 {
   2410   auto *group = allocno->group ();
   2411   if (group->m_color_rep == rep)
   2412     return;
   2413 
   2414   group->m_color_rep = rep;
   2415   gcc_checking_assert (multiple_p (group->stride, rep->stride));
   2416   unsigned int factor = group->stride / rep->stride;
   2417   gcc_checking_assert (rep_offset >= allocno->offset * factor);
   2418   group->color_rep_offset = rep_offset - allocno->offset * factor;
   2419   merge_fpr_info (rep, group, group->color_rep_offset);
   2420 }
   2421 
   2422 // REP1 and REP2 are color representatives.  Change REP1's color representative
   2423 // to REP2, with REP1 starting at allocno offset REP2_OFFSET into REP2.
   2424 void
   2425 early_ra::set_color_rep (allocno_group_info *rep1, allocno_group_info *rep2,
   2426 			 unsigned int rep2_offset)
   2427 {
   2428   gcc_checking_assert (rep1 != rep2
   2429 		       && rep2->m_color_rep == rep2
   2430 		       && multiple_p (rep1->stride, rep2->stride));
   2431 
   2432   auto heads1 = rep1->chain_heads ();
   2433   auto heads2 = rep2->chain_heads ();
   2434   for (unsigned int i1 = 0; i1 < heads1.size (); ++i1)
   2435     if (heads1[i1] != INVALID_ALLOCNO)
   2436       {
   2437 	unsigned int i2 = rep2_offset + i1 * rep1->stride / rep2->stride;
   2438 	if (heads2[i2] == INVALID_ALLOCNO)
   2439 	  heads2[i2] = heads1[i1];
   2440 	else
   2441 	  gcc_checking_assert (heads2[i2] == heads1[i1]);
   2442 	set_single_color_rep (m_allocnos[heads1[i1]], rep2, i2);
   2443       }
   2444 }
   2445 
   2446 // Try to chain ALLOCNO1 to the head of the chain starting at ALLOCNO2.
   2447 // Return true on success.
   2448 bool
   2449 early_ra::try_to_chain_allocnos (allocno_info *allocno1,
   2450 				 allocno_info *allocno2)
   2451 {
   2452   auto *group1 = allocno1->group ()->color_rep ();
   2453   auto *group2 = allocno2->group ()->color_rep ();
   2454 
   2455   // Avoid trying to tie different subgroups of the same group.  This can
   2456   // happen if the parts of a register are defined and used piecemeal.
   2457   if (group1 == group2)
   2458     return false;
   2459 
   2460   // The stride (in FPRs) between allocnos of each color representative.
   2461   auto fpr_stride1 = group1->stride;
   2462   auto fpr_stride2 = group2->stride;
   2463 
   2464   // The offset (in FPRs) of each allocno group from its color representative.
   2465   auto fpr_offset1 = allocno1->group ()->color_rep_offset * fpr_stride1;
   2466   auto fpr_offset2 = allocno2->group ()->color_rep_offset * fpr_stride2;
   2467 
   2468   // The offset (in FPRs) of each allocno from its color representative.
   2469   fpr_offset1 += allocno1->offset * allocno1->group ()->stride;
   2470   fpr_offset2 += allocno2->offset * allocno2->group ()->stride;
   2471 
   2472   // The FPR overlap is in multiples of the larger stride.
   2473   auto max_fpr_stride = std::max (fpr_stride1, fpr_stride2);
   2474   auto min_fpr_offset = std::min (fpr_offset1, fpr_offset2);
   2475   auto fpr_overlap_offset = ROUND_DOWN (min_fpr_offset, max_fpr_stride);
   2476 
   2477   // The offset (in FPRs) of the start of the overlapping region from
   2478   // each color representative.
   2479   fpr_offset1 -= fpr_overlap_offset;
   2480   fpr_offset2 -= fpr_overlap_offset;
   2481 
   2482   // The number of FPRs in each color representative after the start
   2483   // of the overlapping region.
   2484   auto fpr_after1 = (group1->size - 1) * fpr_stride1 - fpr_offset1;
   2485   auto fpr_after2 = (group2->size - 1) * fpr_stride2 - fpr_offset2;
   2486 
   2487   auto min_fpr_after = std::min (fpr_after1, fpr_after2);
   2488 
   2489   // The number of overlapping allocnos.
   2490   auto allocno_overlap_size = min_fpr_after / max_fpr_stride + 1;
   2491 
   2492   // The offset (in allocnos) of the overlapping region from the start
   2493   // of each color representative.
   2494   auto allocno_offset1 = fpr_offset1 / fpr_stride1;
   2495   auto allocno_offset2 = fpr_offset2 / fpr_stride2;
   2496 
   2497   // The stride (in allocnos) between overlapping allocnos.
   2498   auto allocno_stride1 = max_fpr_stride / fpr_stride1;
   2499   auto allocno_stride2 = max_fpr_stride / fpr_stride2;
   2500 
   2501   // Reject combinations that are impossible to allocate.
   2502   auto fprs1 = group1->fpr_candidates;
   2503   auto fprs2 = group2->fpr_candidates;
   2504   if (fpr_offset1 > fpr_offset2)
   2505     fprs2 >>= (fpr_offset1 - fpr_offset2);
   2506   else
   2507     fprs1 >>= (fpr_offset2 - fpr_offset1);
   2508   if ((fprs1 & fprs2) == 0)
   2509     {
   2510       if (dump_file && (dump_flags & TDF_DETAILS))
   2511 	fprintf (dump_file, "    - cannot chain %d->%d, no FPRs in common"
   2512 		 " (%08x@%d and %08x@%d)\n", allocno1->id, allocno2->id,
   2513 		 group1->fpr_candidates, fpr_offset1,
   2514 		 group2->fpr_candidates, fpr_offset2);
   2515       return false;
   2516     }
   2517 
   2518   // Check whether the chain can be formed.
   2519   auto heads1 = group1->chain_heads ();
   2520   auto heads2 = group2->chain_heads ();
   2521   for (unsigned int i = 0; i < allocno_overlap_size; ++i)
   2522     {
   2523       auto headi1 = heads1[allocno_offset1 + i * allocno_stride1];
   2524       auto headi2 = heads2[allocno_offset2 + i * allocno_stride2];
   2525       if (headi1 != INVALID_ALLOCNO && headi2 != INVALID_ALLOCNO)
   2526 	{
   2527 	  auto *head1 = m_allocnos[headi1];
   2528 	  auto *head2 = m_allocnos[headi2];
   2529 	  if (head1->chain_next != INVALID_ALLOCNO)
   2530 	    return false;
   2531 	  if (!is_chain_candidate (head1, head2, CORRECTNESS_ONLY))
   2532 	    return false;
   2533 	}
   2534     }
   2535 
   2536   if (dump_file && (dump_flags & TDF_DETAILS))
   2537     {
   2538       fprintf (dump_file, "    - chaining allocnos [");
   2539       for (unsigned int i = 0; i < allocno_overlap_size; ++i)
   2540 	fprintf (dump_file, "%s%d", i ? "," : "",
   2541 		 heads1[allocno_offset1 + i * allocno_stride1]);
   2542       fprintf (dump_file, "] and [");
   2543       for (unsigned int i = 0; i < allocno_overlap_size; ++i)
   2544 	fprintf (dump_file, "%s%d", i ? "," : "",
   2545 		 heads2[allocno_offset2 + i * allocno_stride2]);
   2546       fprintf (dump_file, "]\n");
   2547     }
   2548 
   2549   // Chain the allocnos, updating the chain heads.
   2550   for (unsigned int i = 0; i < allocno_overlap_size; ++i)
   2551     chain_allocnos (heads1[allocno_offset1 + i * allocno_stride1],
   2552 		    heads2[allocno_offset2 + i * allocno_stride2]);
   2553 
   2554   // Pick a color representative for the merged groups.
   2555   allocno_group_info *new_rep;
   2556   if (allocno_offset1 == 0
   2557       && group1->size == allocno_overlap_size * allocno_stride1
   2558       && multiple_p (fpr_stride1, fpr_stride2))
   2559     {
   2560       // The first group fits within the second.
   2561       set_color_rep (group1, group2, allocno_offset2);
   2562       new_rep = group2;
   2563     }
   2564   else if (allocno_offset2 == 0
   2565 	   && group2->size == allocno_overlap_size * allocno_stride2
   2566 	   && multiple_p (fpr_stride2, fpr_stride1))
   2567     {
   2568       // The second group fits within the first.
   2569       set_color_rep (group2, group1, allocno_offset1);
   2570       new_rep = group1;
   2571     }
   2572   else
   2573     {
   2574       // We need a new group that is big enough to span both groups.
   2575       // The new group always has an FPR stride of 1.
   2576       auto max_fpr_offset = std::max (fpr_offset1, fpr_offset2);
   2577       auto max_fpr_after = std::max (fpr_after1, fpr_after2);
   2578       auto new_size = max_fpr_offset + max_fpr_after + 1;
   2579       new_rep = create_allocno_group (INVALID_REGNUM, new_size);
   2580 
   2581       set_color_rep (group1, new_rep, max_fpr_offset - fpr_offset1);
   2582       set_color_rep (group2, new_rep, max_fpr_offset - fpr_offset2);
   2583     }
   2584 
   2585   if (dump_file && (dump_flags & TDF_DETAILS))
   2586     {
   2587       fprintf (dump_file, "    - new frontier [");
   2588       auto new_heads = new_rep->chain_heads ();
   2589       for (unsigned int i = 0; i < new_heads.size (); ++i)
   2590 	{
   2591 	  if (i)
   2592 	    fprintf (dump_file, ",");
   2593 	  if (new_heads[i] == INVALID_ALLOCNO)
   2594 	    fprintf (dump_file, "-");
   2595 	  else
   2596 	    fprintf (dump_file, "%d", new_heads[i]);
   2597 	}
   2598       fprintf (dump_file, "]\n");
   2599     }
   2600 
   2601   return true;
   2602 }
   2603 
   2604 // Create a color_info for color representative GROUP.
   2605 void
   2606 early_ra::create_color (allocno_group_info *group)
   2607 {
   2608   auto *color = region_allocate<color_info> ();
   2609   color->id = m_colors.length ();
   2610   color->hard_regno = FIRST_PSEUDO_REGISTER;
   2611   color->group = group;
   2612 
   2613   gcc_checking_assert (group->m_color_rep == group);
   2614   group->has_color = true;
   2615   group->color = m_colors.length ();
   2616 
   2617   m_colors.safe_push (color);
   2618 }
   2619 
   2620 // Form allocnos into chains.  Create colors for each resulting clique.
   2621 void
   2622 early_ra::form_chains ()
   2623 {
   2624   if (dump_file && (dump_flags & TDF_DETAILS))
   2625     fprintf (dump_file, "\nChaining allocnos:\n");
   2626 
   2627   // Perform (modified) interval graph coloring.  First sort by
   2628   // increasing start point.
   2629   m_sorted_allocnos.reserve (m_allocnos.length ());
   2630   m_sorted_allocnos.splice (m_allocnos);
   2631   m_sorted_allocnos.qsort (cmp_increasing<&allocno_info::start_point>);
   2632 
   2633   // During this phase, color representatives are only correct for
   2634   // unprocessed allocno groups (where the color representative is
   2635   // the group itself) and for groups that contain a current chain head.
   2636   unsigned int ti = 0;
   2637   auto_vec<chain_candidate_info> candidates;
   2638   for (unsigned int hi = 0; hi < m_sorted_allocnos.length (); ++hi)
   2639     {
   2640       auto *allocno1 = m_sorted_allocnos[hi];
   2641       if (allocno1->chain_next != INVALID_ALLOCNO)
   2642 	continue;
   2643 
   2644       // Record conflicts with direct uses for FPR hard registers.
   2645       auto *group1 = allocno1->group ();
   2646       for (unsigned int fpr = allocno1->offset; fpr < 32; ++fpr)
   2647 	if (fpr_conflicts_with_allocno_p (fpr, allocno1))
   2648 	  group1->fpr_candidates &= ~(1U << (fpr - allocno1->offset));
   2649 
   2650       // Record conflicts due to partially call-clobbered registers.
   2651       // (Full clobbers are handled by the previous loop.)
   2652       for (unsigned int abi_id = 0; abi_id < NUM_ABI_IDS; ++abi_id)
   2653 	if (call_in_range_p (abi_id, allocno1->start_point,
   2654 			     allocno1->end_point))
   2655 	  {
   2656 	    auto fprs = partial_fpr_clobbers (abi_id, group1->fpr_size);
   2657 	    group1->fpr_candidates &= ~fprs >> allocno1->offset;
   2658 	  }
   2659 
   2660       if (allocno1->is_shared ())
   2661 	{
   2662 	  if (dump_file && (dump_flags & TDF_DETAILS))
   2663 	    fprintf (dump_file, "  Allocno %d shares the same hard register"
   2664 		     " as allocno %d\n", allocno1->id,
   2665 		     allocno1->related_allocno);
   2666 	  auto *allocno2 = m_allocnos[allocno1->related_allocno];
   2667 	  merge_fpr_info (allocno2->group (), group1, allocno2->offset);
   2668 	  m_shared_allocnos.safe_push (allocno1);
   2669 	  continue;
   2670 	}
   2671 
   2672       // Find earlier allocnos (in processing order) that could be chained
   2673       // to this one.
   2674       candidates.truncate (0);
   2675       for (unsigned int sci = ti; sci < hi; ++sci)
   2676 	{
   2677 	  auto *allocno2 = m_sorted_allocnos[sci];
   2678 	  if (allocno2->chain_prev == INVALID_ALLOCNO)
   2679 	    {
   2680 	      if (!is_chain_candidate (allocno1, allocno2, ALL_REASONS))
   2681 		continue;
   2682 	      chain_candidate_info candidate;
   2683 	      candidate.allocno = allocno2;
   2684 	      candidate.score = rate_chain (allocno1, allocno2);
   2685 	      candidates.safe_push (candidate);
   2686 	    }
   2687 	  else if (sci == ti)
   2688 	    ++ti;
   2689 	}
   2690 
   2691       // Sort the candidates by decreasing score.
   2692       candidates.qsort (cmp_chain_candidates);
   2693       if (dump_file && (dump_flags & TDF_DETAILS))
   2694 	{
   2695 	  fprintf (dump_file, "  Chain candidates for %d:", allocno1->id);
   2696 	  for (auto &candidate : candidates)
   2697 	    fprintf (dump_file, " %d(%d)", candidate.allocno->id,
   2698 		     candidate.score);
   2699 	  fprintf (dump_file, "\n");
   2700 	}
   2701 
   2702       // Pick the first candidate that works.
   2703       for (auto &candidate : candidates)
   2704 	if (try_to_chain_allocnos (allocno1, candidate.allocno))
   2705 	  break;
   2706     }
   2707 
   2708   // Create color_infos for each group.  Make sure that each group's
   2709   // color representative is up to date.
   2710   for (unsigned int hi = m_sorted_allocnos.length (); hi-- > 0; )
   2711     {
   2712       auto *allocno = m_sorted_allocnos[hi];
   2713       if (allocno->is_shared ())
   2714 	continue;
   2715 
   2716       auto *rep = allocno->group ()->color_rep ();
   2717       if (rep->has_color)
   2718 	continue;
   2719 
   2720       create_color (rep);
   2721       auto heads = rep->chain_heads ();
   2722       for (unsigned int i = 0; i < heads.size (); ++i)
   2723 	{
   2724 	  unsigned int ai = heads[i];
   2725 	  while (ai != INVALID_ALLOCNO)
   2726 	    {
   2727 	      allocno = m_allocnos[ai];
   2728 	      set_single_color_rep (allocno, rep, i * rep->stride);
   2729 	      ai = allocno->chain_next;
   2730 	    }
   2731 	}
   2732     }
   2733 }
   2734 
   2735 // Return true if the given FPR (starting at 0) conflicts with allocno
   2736 // ALLOCNO.
   2737 bool
   2738 early_ra::fpr_conflicts_with_allocno_p (unsigned int fpr,
   2739 					allocno_info *allocno)
   2740 {
   2741   auto &ranges = m_fpr_ranges[fpr];
   2742   unsigned int start_i = 0;
   2743   unsigned int end_i = ranges.length ();
   2744   while (start_i < end_i)
   2745     {
   2746       unsigned int mid_i = (start_i + end_i) / 2;
   2747       auto &range = ranges[mid_i];
   2748       if (allocno->end_point > range.start_point)
   2749 	start_i = mid_i + 1;
   2750       else if (allocno->start_point < range.end_point)
   2751 	end_i = mid_i;
   2752       else
   2753 	{
   2754 	  if (range.allocno != allocno->id)
   2755 	    return true;
   2756 	  // The FPR is equivalent to ALLOCNO for this particular range.
   2757 	  // See whether ALLOCNO conflicts with a neighboring range.
   2758 	  if (mid_i > 0
   2759 	      && ranges[mid_i - 1].start_point >= allocno->end_point)
   2760 	    return true;
   2761 	  if (mid_i + 1 < ranges.length ()
   2762 	      && ranges[mid_i + 1].end_point <= allocno->start_point)
   2763 	    return true;
   2764 	  return false;
   2765 	}
   2766     }
   2767   return false;
   2768 }
   2769 
   2770 // Return true if there is a call with ABI identifier ABI_ID in the inclusive
   2771 // program point range [START_POINT, END_POINT].
   2772 bool
   2773 early_ra::call_in_range_p (unsigned int abi_id, unsigned int start_point,
   2774 			   unsigned int end_point)
   2775 {
   2776   auto &points = m_call_points[abi_id];
   2777   unsigned int start_i = 0;
   2778   unsigned int end_i = points.length ();
   2779   while (start_i < end_i)
   2780     {
   2781       unsigned int mid_i = (start_i + end_i) / 2;
   2782       auto point = points[mid_i];
   2783       if (end_point > point)
   2784 	start_i = mid_i + 1;
   2785       else if (start_point < point)
   2786 	end_i = mid_i;
   2787       else
   2788 	return true;
   2789     }
   2790   return false;
   2791 }
   2792 
   2793 // Return the set of FPRs for which a value of size SIZE will be clobbered
   2794 // by a call to a function with ABI identifier ABI_ID, but would not be
   2795 // for some smaller size.  The set therefore excludes FPRs that are
   2796 // fully-clobbered, like V0 in the base ABI.
   2797 unsigned int
   2798 early_ra::partial_fpr_clobbers (unsigned int abi_id, fpr_size_info size)
   2799 {
   2800   auto &abi = function_abis[abi_id];
   2801   unsigned int clobbers = 0;
   2802   machine_mode mode = (size == FPR_D ? V8QImode
   2803 		       : size == FPR_Q ? V16QImode : VNx16QImode);
   2804   for (unsigned int regno = V0_REGNUM; regno <= V31_REGNUM; ++regno)
   2805     if (!abi.clobbers_full_reg_p (regno)
   2806 	&& abi.clobbers_reg_p (mode, regno))
   2807       clobbers |= 1U << (regno - V0_REGNUM);
   2808   return clobbers;
   2809 }
   2810 
   2811 // Process copies between pseudo registers and hard registers and update
   2812 // the FPR preferences for the associated colors.
   2813 void
   2814 early_ra::process_copies ()
   2815 {
   2816   for (auto &copy : m_allocno_copies)
   2817     {
   2818       auto *allocno = m_allocnos[copy.allocno];
   2819       auto *group = allocno->group ();
   2820       auto offset = group->color_rep_offset + allocno->offset;
   2821       if (offset > copy.fpr)
   2822 	continue;
   2823 
   2824       unsigned int fpr = copy.fpr - offset;
   2825       auto *color = m_colors[group->color_rep ()->color];
   2826       color->fpr_preferences[fpr] = MIN (color->fpr_preferences[fpr]
   2827 					 + copy.weight, 127);
   2828       color->num_fpr_preferences += copy.weight;
   2829     }
   2830 }
   2831 
   2832 // Compare the colors at *COLOR1_PTR and *COLOR2_PTR and return a <=>
   2833 // result that puts colors in allocation order.
   2834 int
   2835 early_ra::cmp_allocation_order (const void *color1_ptr, const void *color2_ptr)
   2836 {
   2837   auto *color1 = *(color_info *const *) color1_ptr;
   2838   auto *color2 = *(color_info *const *) color2_ptr;
   2839 
   2840   // Allocate bigger groups before smaller groups.
   2841   if (color1->group->size != color2->group->size)
   2842     return color1->group->size > color2->group->size ? -1 : 1;
   2843 
   2844   // Allocate groups with stronger FPR preferences before groups with weaker
   2845   // FPR preferences.
   2846   if (color1->num_fpr_preferences != color2->num_fpr_preferences)
   2847     return color1->num_fpr_preferences > color2->num_fpr_preferences ? -1 : 1;
   2848 
   2849   return (color1->id < color2->id ? -1
   2850 	  : color1->id == color2->id ? 0 : 1);
   2851 }
   2852 
   2853 // Allocate a register to each color.  If we run out of registers,
   2854 // give up on doing a full allocation of the FPR-based pseudos in the
   2855 // region.
   2856 void
   2857 early_ra::allocate_colors ()
   2858 {
   2859   if (dump_file && (dump_flags & TDF_DETAILS))
   2860     fprintf (dump_file, "\nAllocating registers:\n");
   2861 
   2862   auto_vec<color_info *> sorted_colors;
   2863   sorted_colors.safe_splice (m_colors);
   2864   sorted_colors.qsort (cmp_allocation_order);
   2865 
   2866   for (unsigned int i = 0; i < 32; ++i)
   2867     if (!crtl->abi->clobbers_full_reg_p (V0_REGNUM + i))
   2868       m_call_preserved_fprs |= 1U << i;
   2869 
   2870   for (auto *color : sorted_colors)
   2871     {
   2872       unsigned int candidates = color->group->fpr_candidates;
   2873       for (unsigned int i = 0; i < color->group->size; ++i)
   2874 	candidates &= ~(m_allocated_fprs >> i);
   2875       unsigned int best = INVALID_REGNUM;
   2876       int best_weight = 0;
   2877       unsigned int best_recency = 0;
   2878       for (unsigned int fpr = 0; fpr <= 32U - color->group->size; ++fpr)
   2879 	{
   2880 	  if ((candidates & (1U << fpr)) == 0)
   2881 	    continue;
   2882 	  int weight = color->fpr_preferences[fpr];
   2883 	  unsigned int recency = 0;
   2884 	  // Account for registers that the current function must preserve.
   2885 	  for (unsigned int i = 0; i < color->group->size; ++i)
   2886 	    {
   2887 	      if (m_call_preserved_fprs & (1U << (fpr + i)))
   2888 		weight -= 1;
   2889 	      recency = MAX (recency, m_fpr_recency[fpr + i]);
   2890 	    }
   2891 	  // Prefer higher-numbered registers in the event of a tie.
   2892 	  // This should tend to keep lower-numbered registers free
   2893 	  // for allocnos that require V0-V7 or V0-V15.
   2894 	  if (best == INVALID_REGNUM
   2895 	      || best_weight < weight
   2896 	      || (best_weight == weight && recency <= best_recency))
   2897 	    {
   2898 	      best = fpr;
   2899 	      best_weight = weight;
   2900 	      best_recency = recency;
   2901 	    }
   2902 	}
   2903 
   2904       if (best == INVALID_REGNUM)
   2905 	{
   2906 	  m_allocation_successful = false;
   2907 	  return;
   2908 	}
   2909 
   2910       color->hard_regno = best + V0_REGNUM;
   2911       if (dump_file && (dump_flags & TDF_DETAILS))
   2912 	fprintf (dump_file, "  Allocating [v%d:v%d] to color %d\n",
   2913 		 best, best + color->group->size - 1, color->id);
   2914       m_allocated_fprs |= ((1U << color->group->size) - 1) << best;
   2915     }
   2916 }
   2917 
   2918 // See if ALLOCNO ends a subchain of single registers that can be split
   2919 // off without affecting the rest of the chain, and without introducing
   2920 // any moves.  Return the start of the chain if so (which might be ALLOCNO
   2921 // itself), otherwise return null.
   2922 early_ra::allocno_info *
   2923 early_ra::find_independent_subchain (allocno_info *allocno)
   2924 {
   2925   // Make sure ALLOCNO ends a natural subchain.
   2926   if (auto *next_allocno = chain_next (allocno))
   2927     if (next_allocno->start_point + 1 >= allocno->end_point)
   2928       return nullptr;
   2929 
   2930   // Check the allocnos in the purported subchain and find the other end.
   2931   for (;;)
   2932     {
   2933       auto *group = allocno->group ();
   2934       if (group->m_color_rep == group)
   2935 	return nullptr;
   2936       if (group->size != 1)
   2937 	return nullptr;
   2938 
   2939       auto *prev_allocno = chain_prev (allocno);
   2940       if (!prev_allocno || allocno->start_point + 1 < prev_allocno->end_point)
   2941 	return allocno;
   2942 
   2943       allocno = prev_allocno;
   2944     }
   2945 }
   2946 
   2947 // Search the colors starting at index FIRST_COLOR whose FPRs do not belong
   2948 // to FPR_CONFLICTS.  Return the first such color that has no group.  If all
   2949 // such colors have groups, instead return the color with the latest
   2950 // (smallest) start point.
   2951 early_ra::color_info *
   2952 early_ra::find_oldest_color (unsigned int first_color,
   2953 			     unsigned int fpr_conflicts)
   2954 {
   2955   color_info *best = nullptr;
   2956   unsigned int best_start_point = ~0U;
   2957   unsigned int best_recency = 0;
   2958   for (unsigned int ci = first_color; ci < m_colors.length (); ++ci)
   2959     {
   2960       auto *color = m_colors[ci];
   2961       unsigned int fpr = color->hard_regno - V0_REGNUM;
   2962       if (fpr_conflicts & (1U << fpr))
   2963 	continue;
   2964       unsigned int start_point = 0;
   2965       if (color->group)
   2966 	{
   2967 	  auto chain_head = color->group->chain_heads ()[0];
   2968 	  start_point = m_allocnos[chain_head]->start_point;
   2969 	}
   2970       unsigned int recency = m_fpr_recency[fpr];
   2971       if (!best
   2972 	  || best_start_point > start_point
   2973 	  || (best_start_point == start_point && recency < best_recency))
   2974 	{
   2975 	  best = color;
   2976 	  best_start_point = start_point;
   2977 	  best_recency = recency;
   2978 	}
   2979     }
   2980   return best;
   2981 }
   2982 
   2983 // If there are some spare FPRs that can be reused without introducing saves,
   2984 // restores, or moves, use them to "broaden" the allocation, in order to give
   2985 // the scheduler more freedom.  This is particularly useful for forming LDPs
   2986 // and STPs.
   2987 void
   2988 early_ra::broaden_colors ()
   2989 {
   2990   // Create dummy colors for every leftover FPR that can be used cheaply.
   2991   unsigned int first_color = m_colors.length ();
   2992   for (unsigned int fpr = 0; fpr < 32; ++fpr)
   2993     if (((m_allocated_fprs | m_call_preserved_fprs) & (1U << fpr)) == 0)
   2994       {
   2995 	auto *color = region_allocate<color_info> ();
   2996 	color->id = m_colors.length ();
   2997 	color->hard_regno = V0_REGNUM + fpr;
   2998 	color->group = nullptr;
   2999 	m_colors.safe_push (color);
   3000       }
   3001 
   3002   // Exit early if there are no spare FPRs.
   3003   if (first_color == m_colors.length ())
   3004     return;
   3005 
   3006   // Go through the allocnos in order, seeing if there is a subchain of
   3007   // single-FPR allocnos that can be split off from the containingg clique.
   3008   // Allocate such subchains to the new colors on an oldest-first basis.
   3009   for (auto *allocno : m_sorted_allocnos)
   3010     if (auto *start_allocno = find_independent_subchain (allocno))
   3011       {
   3012 	unsigned int fpr_conflicts = 0;
   3013 	auto *member = allocno;
   3014 	for (;;)
   3015 	  {
   3016 	    fpr_conflicts |= ~member->group ()->fpr_candidates;
   3017 	    if (member == start_allocno)
   3018 	      break;
   3019 	    member = m_allocnos[member->chain_prev];
   3020 	  }
   3021 
   3022 	auto *color = find_oldest_color (first_color, fpr_conflicts);
   3023 	if (!color)
   3024 	  continue;
   3025 
   3026 	if (!color->group)
   3027 	  {
   3028 	    auto *group = allocno->group ();
   3029 	    color->group = group;
   3030 	    group->color = color->id;
   3031 	    group->chain_heads ()[0] = INVALID_ALLOCNO;
   3032 	  }
   3033 	else
   3034 	  {
   3035 	    auto chain_head = color->group->chain_heads ()[0];
   3036 	    auto start_point = m_allocnos[chain_head]->start_point;
   3037 	    if (start_point >= allocno->end_point)
   3038 	      // Allocating to COLOR isn't viable, and it was the best
   3039 	      // option available.
   3040 	      continue;
   3041 
   3042 	    auto *next_allocno = chain_next (allocno);
   3043 	    if (!next_allocno || next_allocno->start_point <= start_point)
   3044 	      // The current allocation gives at least as much scheduling
   3045 	      // freedom as COLOR would.
   3046 	      continue;
   3047 	  }
   3048 
   3049 	// Unlink the chain.
   3050 	if (auto *next_allocno = chain_next (allocno))
   3051 	  next_allocno->chain_prev = start_allocno->chain_prev;
   3052 	if (auto *prev_allocno = chain_prev (start_allocno))
   3053 	  prev_allocno->chain_next = allocno->chain_next;
   3054 
   3055 	// Make the subchain use COLOR.
   3056 	allocno->chain_next = color->group->chain_heads ()[0];
   3057 	if (dump_file && (dump_flags & TDF_DETAILS))
   3058 	  fprintf (dump_file, "Moving to optional color %d (register %s):",
   3059 		   color->id, reg_names[color->hard_regno]);
   3060 	for (;;)
   3061 	  {
   3062 	    auto *group = allocno->group ();
   3063 	    if (dump_file && (dump_flags & TDF_DETAILS))
   3064 	      fprintf (dump_file, " r%d", group->regno);
   3065 	    group->m_color_rep = color->group;
   3066 	    group->color_rep_offset = 0;
   3067 	    if (allocno == start_allocno)
   3068 	      break;
   3069 	    allocno = m_allocnos[allocno->chain_prev];
   3070 	  }
   3071 	if (dump_file && (dump_flags & TDF_DETAILS))
   3072 	  fprintf (dump_file, "\n");
   3073 	color->group->chain_heads ()[0] = start_allocno->id;
   3074       }
   3075 }
   3076 
   3077 // Record the final choice of hard register for each allocno.
   3078 void
   3079 early_ra::finalize_allocation ()
   3080 {
   3081   for (auto *color : m_colors)
   3082     if (color->group)
   3083       {
   3084 	unsigned int fpr = color->hard_regno - V0_REGNUM;
   3085 	for (unsigned int i = 0; i < color->group->size; ++i)
   3086 	  m_fpr_recency[fpr + i] = m_current_region;
   3087       }
   3088   for (auto *allocno : m_allocnos)
   3089     {
   3090       if (allocno->is_shared ())
   3091 	continue;
   3092       auto *group = allocno->group ();
   3093       auto *rep = group->color_rep ();
   3094       auto rep_regno = m_colors[rep->color]->hard_regno;
   3095       auto group_regno = rep_regno + group->color_rep_offset;
   3096       allocno->hard_regno = group_regno + allocno->offset * group->stride;
   3097     }
   3098   for (auto *allocno : m_shared_allocnos)
   3099     allocno->hard_regno = m_allocnos[allocno->related_allocno]->hard_regno;
   3100 }
   3101 
   3102 // Replace any allocno references in REFS with the allocated register.
   3103 // INSN is the instruction that contains REFS.
   3104 bool
   3105 early_ra::replace_regs (rtx_insn *insn, df_ref refs)
   3106 {
   3107   bool changed = false;
   3108   for (df_ref ref = refs; ref; ref = DF_REF_NEXT_LOC (ref))
   3109     {
   3110       auto range = get_allocno_subgroup (DF_REF_REG (ref));
   3111       if (!range)
   3112 	continue;
   3113 
   3114       auto new_regno = range.allocno (0)->hard_regno;
   3115       if (new_regno == FIRST_PSEUDO_REGISTER)
   3116 	{
   3117 	  // Reset a debug instruction if, after DCE, the only remaining
   3118 	  // references to a register are in such instructions.
   3119 	  gcc_assert (DEBUG_INSN_P (insn));
   3120 	  INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
   3121 	  return true;
   3122 	}
   3123       *DF_REF_LOC (ref) = gen_rtx_REG (GET_MODE (DF_REF_REG (ref)), new_regno);
   3124       changed = true;
   3125     }
   3126   return changed;
   3127 }
   3128 
   3129 // Try to make INSN match its FPR-related constraints.  If this needs
   3130 // a source operand (SRC) to be copied to a destination operand (DEST)
   3131 // before INSN, add the associated (DEST, SRC) pairs to MOVES.
   3132 //
   3133 // Return -1 on failure, otherwise return a ?/!-style reject count.
   3134 // The reject count doesn't model the moves, just the internal alternative
   3135 // preferences.
   3136 int
   3137 early_ra::try_enforce_constraints (rtx_insn *insn,
   3138 				   vec<std::pair<int, int>> &moves)
   3139 {
   3140   if (!constrain_operands (0, get_preferred_alternatives (insn)))
   3141     return -1;
   3142 
   3143   // Pick the alternative with the lowest cost.
   3144   int best = -1;
   3145   auto alts = get_preferred_alternatives (insn);
   3146   for (int altno = 0; altno < recog_data.n_alternatives; ++altno)
   3147     {
   3148       if (!(alts & ALTERNATIVE_BIT (altno)))
   3149 	continue;
   3150 
   3151       auto *op_alt = &recog_op_alt[altno * recog_data.n_operands];
   3152       if (!likely_alternative_match_p (op_alt))
   3153 	continue;
   3154 
   3155       auto_vec<std::pair<int, int>, 4> new_moves;
   3156       for (int opno = 0; opno < recog_data.n_operands; ++opno)
   3157 	{
   3158 	  rtx op = recog_data.operand[opno];
   3159 	  if (REG_P (op)
   3160 	      && FP_REGNUM_P (REGNO (op))
   3161 	      && op_alt[opno].matched >= 0)
   3162 	    {
   3163 	      rtx old_src = recog_data.operand[op_alt[opno].matched];
   3164 	      if (!operands_match_p (op, old_src))
   3165 		{
   3166 		  for (int i = 0; i < recog_data.n_operands; ++i)
   3167 		    if (i != opno)
   3168 		      {
   3169 			rtx other = recog_data.operand[i];
   3170 			if (reg_overlap_mentioned_p (op, other))
   3171 			  {
   3172 			    old_src = NULL_RTX;
   3173 			    break;
   3174 			  }
   3175 		      }
   3176 		  if (!old_src)
   3177 		    continue;
   3178 		  new_moves.safe_push ({ opno, op_alt[opno].matched });
   3179 		}
   3180 	    }
   3181 	}
   3182       int cost = count_rejects (op_alt) + new_moves.length () * 7;
   3183       if (best < 0 || cost < best)
   3184 	{
   3185 	  best = cost;
   3186 	  moves.truncate (0);
   3187 	  moves.safe_splice (new_moves);
   3188 	}
   3189     }
   3190   return best;
   3191 }
   3192 
   3193 // Make INSN matches its FPR-related constraints.
   3194 void
   3195 early_ra::enforce_constraints (rtx_insn *insn)
   3196 {
   3197   extract_insn (insn);
   3198   preprocess_constraints (insn);
   3199 
   3200   // First try with the operands they are.
   3201   auto_vec<std::pair<int, int>, 4> moves;
   3202   int cost = try_enforce_constraints (insn, moves);
   3203 
   3204   // Next try taking advantage of commutativity.
   3205   for (int opno = 0; opno < recog_data.n_operands - 1; ++opno)
   3206     if (recog_data.constraints[opno][0] == '%')
   3207       {
   3208 	std::swap (*recog_data.operand_loc[opno],
   3209 		   *recog_data.operand_loc[opno + 1]);
   3210 	std::swap (recog_data.operand[opno],
   3211 		   recog_data.operand[opno + 1]);
   3212 	auto_vec<std::pair<int, int>, 4> swapped_moves;
   3213 	int swapped_cost = try_enforce_constraints (insn, swapped_moves);
   3214 	if (swapped_cost >= 0 && (cost < 0 || swapped_cost < cost))
   3215 	  {
   3216 	    cost = swapped_cost;
   3217 	    moves.truncate (0);
   3218 	    moves.safe_splice (swapped_moves);
   3219 	  }
   3220 	else
   3221 	  {
   3222 	    std::swap (*recog_data.operand_loc[opno],
   3223 		       *recog_data.operand_loc[opno + 1]);
   3224 	    std::swap (recog_data.operand[opno],
   3225 		       recog_data.operand[opno + 1]);
   3226 	  }
   3227       }
   3228 
   3229   // The allocation should ensure that there is at least one valid combination.
   3230   // It's too late to back out now if not.
   3231   gcc_assert (cost >= 0);
   3232   for (int i = 0; i < recog_data.n_dups; ++i)
   3233     {
   3234       int dup_of = recog_data.dup_num[i];
   3235       rtx new_op = *recog_data.operand_loc[dup_of];
   3236       if (new_op != recog_data.operand[dup_of])
   3237 	*recog_data.dup_loc[i] = copy_rtx (new_op);
   3238     }
   3239   for (auto move : moves)
   3240     {
   3241       int dest_opno = move.first;
   3242       int src_opno = move.second;
   3243       rtx dest = recog_data.operand[dest_opno];
   3244       rtx old_src = recog_data.operand[src_opno];
   3245       rtx new_src = lowpart_subreg (GET_MODE (old_src), dest, GET_MODE (dest));
   3246       emit_insn_before (gen_move_insn (new_src, old_src), insn);
   3247       *recog_data.operand_loc[src_opno] = new_src;
   3248     }
   3249 }
   3250 
   3251 // See whether INSN is an instruction that operates on multi-register vectors,
   3252 // and if we have decided to make it use strided rather than consecutive
   3253 // accesses.  Update the pattern and return true if so.
   3254 bool
   3255 early_ra::maybe_convert_to_strided_access (rtx_insn *insn)
   3256 {
   3257   if (!NONJUMP_INSN_P (insn) || recog_memoized (insn) < 0)
   3258     return false;
   3259 
   3260   auto stride_type = get_attr_stride_type (insn);
   3261   rtx pat = PATTERN (insn);
   3262   rtx op;
   3263   if (stride_type == STRIDE_TYPE_LD1_CONSECUTIVE)
   3264     op = SET_DEST (pat);
   3265   else if (stride_type == STRIDE_TYPE_ST1_CONSECUTIVE)
   3266     op = XVECEXP (SET_SRC (pat), 0, 1);
   3267   else
   3268     return false;
   3269 
   3270   auto range = get_allocno_subgroup (op);
   3271   if (!range || range.group->stride == 1)
   3272     return false;
   3273 
   3274   gcc_assert (range.start == 0 && range.count == range.group->size);
   3275   auto elt_mode = GET_MODE_INNER (GET_MODE (op));
   3276   auto single_mode = aarch64_full_sve_mode (elt_mode).require ();
   3277   auto_vec<rtx, 4> regs;
   3278   for (unsigned int i = 0; i < range.count; ++i)
   3279     regs.quick_push (gen_rtx_REG (single_mode, range.allocno (i)->hard_regno));
   3280 
   3281   extract_insn (insn);
   3282   if (stride_type == STRIDE_TYPE_LD1_CONSECUTIVE)
   3283     {
   3284       auto unspec = XINT (SET_SRC (pat), 1);
   3285       if (range.count == 2)
   3286 	pat = gen_aarch64_strided2 (unspec, GET_MODE (op), regs[0], regs[1],
   3287 				    recog_data.operand[1],
   3288 				    recog_data.operand[2]);
   3289       else
   3290 	pat = gen_aarch64_strided4 (unspec, GET_MODE (op),
   3291 				    regs[0], regs[1], regs[2], regs[3],
   3292 				    recog_data.operand[1],
   3293 				    recog_data.operand[2]);
   3294     }
   3295   else if (stride_type == STRIDE_TYPE_ST1_CONSECUTIVE)
   3296     {
   3297       auto unspec = XINT (SET_SRC (pat), 1);
   3298       if (range.count == 2)
   3299 	pat = gen_aarch64_strided2 (unspec, GET_MODE (op),
   3300 				    recog_data.operand[0],
   3301 				    recog_data.operand[2], regs[0], regs[1]);
   3302       else
   3303 	pat = gen_aarch64_strided4 (unspec, GET_MODE (op),
   3304 				    recog_data.operand[0],
   3305 				    recog_data.operand[2],
   3306 				    regs[0], regs[1], regs[2], regs[3]);
   3307       // Ensure correct sharing for the source memory.
   3308       //
   3309       // ??? Why doesn't the generator get this right?
   3310       XVECEXP (SET_SRC (pat), 0, XVECLEN (SET_SRC (pat), 0) - 1)
   3311 	= *recog_data.dup_loc[0];
   3312     }
   3313   else
   3314     gcc_unreachable ();
   3315   PATTERN (insn) = pat;
   3316   INSN_CODE (insn) = -1;
   3317   df_insn_rescan (insn);
   3318   return true;
   3319 }
   3320 
   3321 // We've successfully allocated the current region.  Apply the allocation
   3322 // to the instructions.
   3323 void
   3324 early_ra::apply_allocation ()
   3325 {
   3326   for (auto *insn : m_dead_insns)
   3327     set_insn_deleted (insn);
   3328 
   3329   rtx_insn *prev;
   3330   for (auto insn_range : m_insn_ranges)
   3331     for (rtx_insn *insn = insn_range.first;
   3332 	 insn != insn_range.second;
   3333 	 insn = prev)
   3334       {
   3335 	prev = PREV_INSN (insn);
   3336 	if (!INSN_P (insn))
   3337 	  continue;
   3338 
   3339 	bool changed = maybe_convert_to_strided_access (insn);
   3340 	changed |= replace_regs (insn, DF_INSN_DEFS (insn));
   3341 	changed |= replace_regs (insn, DF_INSN_USES (insn));
   3342 	if (changed && NONDEBUG_INSN_P (insn))
   3343 	  {
   3344 	    if (GET_CODE (PATTERN (insn)) != USE
   3345 		&& GET_CODE (PATTERN (insn)) != CLOBBER
   3346 		&& !is_move_set (PATTERN (insn)))
   3347 	      enforce_constraints (insn);
   3348 
   3349 	    // A REG_EQUIV note establishes an equivalence throughout
   3350 	    // the function, but here we're reusing hard registers for
   3351 	    // multiple pseudo registers.  We also no longer need REG_EQUIV
   3352 	    // notes that record potential spill locations, since we've
   3353 	    // allocated the pseudo register without spilling.
   3354 	    rtx *ptr = &REG_NOTES (insn);
   3355 	    while (*ptr)
   3356 	      if (REG_NOTE_KIND (*ptr) == REG_EQUIV)
   3357 		*ptr = XEXP (*ptr, 1);
   3358 	      else
   3359 		ptr = &XEXP (*ptr, 1);
   3360 	  }
   3361 	changed |= replace_regs (insn, DF_INSN_EQ_USES (insn));
   3362 	if (changed)
   3363 	  df_insn_rescan (insn);
   3364       }
   3365 
   3366   for (auto *insn : m_dead_insns)
   3367     delete_insn (insn);
   3368 }
   3369 
   3370 // Try to allocate the current region.  Update the instructions if successful.
   3371 void
   3372 early_ra::process_region ()
   3373 {
   3374   for (auto *allocno : m_allocnos)
   3375     {
   3376       allocno->chain_next = INVALID_ALLOCNO;
   3377       allocno->chain_prev = INVALID_ALLOCNO;
   3378     }
   3379 
   3380   if (dump_file && (dump_flags & TDF_DETAILS))
   3381     {
   3382       dump_fpr_ranges ();
   3383       dump_copies ();
   3384       dump_allocnos ();
   3385     }
   3386 
   3387   find_strided_accesses ();
   3388 
   3389   if (dump_file && (dump_flags & TDF_DETAILS))
   3390     dump_allocnos ();
   3391 
   3392   form_chains ();
   3393 
   3394   if (dump_file && (dump_flags & TDF_DETAILS))
   3395     dump_allocnos ();
   3396 
   3397   process_copies ();
   3398 
   3399   if (dump_file && (dump_flags & TDF_DETAILS))
   3400     dump_colors ();
   3401 
   3402   allocate_colors ();
   3403   if (!m_allocation_successful)
   3404     return;
   3405 
   3406   broaden_colors ();
   3407   finalize_allocation ();
   3408 
   3409   if (dump_file && (dump_flags & TDF_DETAILS))
   3410     {
   3411       fprintf (dump_file, "\nAllocation successful\nFinal allocation:\n");
   3412       dump_allocnos ();
   3413       dump_colors ();
   3414     }
   3415 
   3416   apply_allocation ();
   3417 }
   3418 
   3419 // Return true if INSN would become dead if we successfully allocate the
   3420 // current region.
   3421 bool
   3422 early_ra::is_dead_insn (rtx_insn *insn)
   3423 {
   3424   rtx set = single_set (insn);
   3425   if (!set)
   3426     return false;
   3427 
   3428   rtx dest = SET_DEST (set);
   3429   auto dest_range = get_allocno_subgroup (dest);
   3430   if (!dest_range)
   3431     return false;
   3432 
   3433   for (auto &allocno : dest_range.allocnos ())
   3434     if (bitmap_bit_p (m_live_allocnos, allocno.id))
   3435       return false;
   3436 
   3437   if (side_effects_p (set))
   3438     return false;
   3439 
   3440   /* If we can't delete dead exceptions and the insn throws,
   3441      then the instruction is not dead.  */
   3442   if (!cfun->can_delete_dead_exceptions
   3443       && !insn_nothrow_p (insn))
   3444     return false;
   3445 
   3446   return true;
   3447 }
   3448 
   3449 // Build up information about block BB.  IS_ISOLATED is true if the
   3450 // block is not part of a larger region.
   3451 void
   3452 early_ra::process_block (basic_block bb, bool is_isolated)
   3453 {
   3454   m_current_bb = bb;
   3455   m_current_point += 1;
   3456   m_current_bb_point = m_current_point;
   3457 
   3458   // Process live-out FPRs.
   3459   bitmap live_out = df_get_live_out (bb);
   3460   for (unsigned int regno = V0_REGNUM; regno <= V31_REGNUM; ++regno)
   3461     if (bitmap_bit_p (live_out, regno))
   3462       record_fpr_use (regno);
   3463 
   3464   // Process live-out allocnos.  We don't track individual FPR liveness
   3465   // across block boundaries, so we have to assume that the whole pseudo
   3466   // register is live.
   3467   bitmap_iterator bi;
   3468   unsigned int regno;
   3469   EXECUTE_IF_AND_IN_BITMAP (df_get_live_out (bb), m_fpr_pseudos,
   3470 			    FIRST_PSEUDO_REGISTER, regno, bi)
   3471     {
   3472       auto range = get_allocno_subgroup (regno_reg_rtx[regno]);
   3473       for (auto &allocno : range.allocnos ())
   3474 	record_allocno_use (&allocno);
   3475     }
   3476 
   3477   m_current_point += 1;
   3478 
   3479   record_artificial_refs (0);
   3480 
   3481   bool is_first = true;
   3482   rtx_insn *start_insn = BB_END (bb);
   3483   rtx_insn *insn;
   3484   FOR_BB_INSNS_REVERSE (bb, insn)
   3485     {
   3486       if (!NONDEBUG_INSN_P (insn))
   3487 	continue;
   3488 
   3489       // CLOBBERs are used to prevent pseudos from being upwards exposed.
   3490       // We can ignore them if allocation is successful.
   3491       if (GET_CODE (PATTERN (insn)) == CLOBBER)
   3492 	{
   3493 	  if (get_allocno_subgroup (XEXP (PATTERN (insn), 0)))
   3494 	    m_dead_insns.safe_push (insn);
   3495 	  continue;
   3496 	}
   3497 
   3498       if (dump_file && (dump_flags & TDF_DETAILS))
   3499 	{
   3500 	  if (is_first)
   3501 	    fprintf (dump_file, "\nBlock %d:\n", bb->index);
   3502 	  fprintf (dump_file, "%6d:", m_current_point);
   3503 	  pretty_printer rtl_slim_pp;
   3504 	  rtl_slim_pp.buffer->stream = dump_file;
   3505 	  print_insn (&rtl_slim_pp, insn, 1);
   3506 	  pp_flush (&rtl_slim_pp);
   3507 	  fprintf (dump_file, "\n");
   3508 	}
   3509       is_first = false;
   3510 
   3511       if (is_dead_insn (insn))
   3512 	{
   3513 	  if (dump_file && (dump_flags & TDF_DETAILS))
   3514 	    fprintf (dump_file, "%14s -- dead\n", "");
   3515 	  m_dead_insns.safe_push (insn);
   3516 	}
   3517       else
   3518 	{
   3519 	  record_insn_refs (insn);
   3520 	  rtx pat = PATTERN (insn);
   3521 	  if (is_move_set (pat))
   3522 	    record_copy (SET_DEST (pat), SET_SRC (pat), true);
   3523 	  else
   3524 	    {
   3525 	      extract_insn (insn);
   3526 	      record_constraints (insn);
   3527 	    }
   3528 	}
   3529 
   3530       // See whether we have a complete region, with no remaining live
   3531       // allocnos.
   3532       if (is_isolated
   3533 	  && bitmap_empty_p (m_live_allocnos)
   3534 	  && m_live_fprs == 0
   3535 	  && m_allocation_successful
   3536 	  && !m_allocnos.is_empty ())
   3537 	{
   3538 	  rtx_insn *prev_insn = PREV_INSN (insn);
   3539 	  m_insn_ranges.safe_push ({ start_insn, prev_insn });
   3540 	  process_region ();
   3541 	  start_new_region ();
   3542 	  is_first = true;
   3543 	  start_insn = prev_insn;
   3544 	}
   3545     }
   3546   m_insn_ranges.safe_push ({ start_insn, BB_HEAD (bb) });
   3547 
   3548   record_artificial_refs (DF_REF_AT_TOP);
   3549 
   3550   // Process live-in FPRs.
   3551   bitmap live_in = df_get_live_in (bb);
   3552   for (unsigned int regno = V0_REGNUM; regno <= V31_REGNUM; ++regno)
   3553     if (bitmap_bit_p (live_in, regno)
   3554 	&& (m_live_fprs & (1U << (regno - V0_REGNUM))))
   3555       record_fpr_def (regno);
   3556 
   3557   // Process live-in allocnos.
   3558   EXECUTE_IF_AND_IN_BITMAP (live_in, m_fpr_pseudos,
   3559 			    FIRST_PSEUDO_REGISTER, regno, bi)
   3560     {
   3561       auto range = get_allocno_subgroup (regno_reg_rtx[regno]);
   3562       for (auto &allocno : range.allocnos ())
   3563 	if (bitmap_bit_p (m_live_allocnos, allocno.id))
   3564 	  record_allocno_def (&allocno);
   3565     }
   3566 
   3567   m_current_point += 1;
   3568 
   3569   bitmap_clear (m_live_allocnos);
   3570   m_live_fprs = 0;
   3571 }
   3572 
   3573 // Divide the function into regions, such that there no edges into or out
   3574 // of the region have live "FPR pseudos".
   3575 void
   3576 early_ra::process_blocks ()
   3577 {
   3578   auto_sbitmap visited (last_basic_block_for_fn (m_fn));
   3579   auto_sbitmap fpr_pseudos_live_out (last_basic_block_for_fn (m_fn));
   3580   auto_sbitmap fpr_pseudos_live_in (last_basic_block_for_fn (m_fn));
   3581 
   3582   bitmap_clear (visited);
   3583   bitmap_clear (fpr_pseudos_live_out);
   3584   bitmap_clear (fpr_pseudos_live_in);
   3585 
   3586   // Record which blocks have live FPR pseudos on entry and exit.
   3587   basic_block bb;
   3588   FOR_EACH_BB_FN (bb, m_fn)
   3589     {
   3590       if (bitmap_intersect_p (df_get_live_out (bb), m_fpr_pseudos))
   3591 	bitmap_set_bit (fpr_pseudos_live_out, bb->index);
   3592       if (bitmap_intersect_p (df_get_live_in (bb), m_fpr_pseudos))
   3593 	bitmap_set_bit (fpr_pseudos_live_in, bb->index);
   3594     }
   3595 
   3596   // This is incremented by 1 at the start of each region.
   3597   m_current_region = 0;
   3598   memset (m_fpr_recency, 0, sizeof (m_fpr_recency));
   3599 
   3600   struct stack_node { edge_iterator ei; basic_block bb; };
   3601 
   3602   auto_vec<stack_node, 32> stack;
   3603   auto_vec<basic_block, 32> region;
   3604 
   3605   // Go through the function in reverse postorder and process the region
   3606   // containing each block.
   3607   unsigned int n_blocks = df_get_n_blocks (DF_FORWARD);
   3608   int *order = df_get_postorder (DF_FORWARD);
   3609   for (unsigned int bbi = 0; bbi < n_blocks; ++bbi)
   3610     {
   3611       basic_block bb = BASIC_BLOCK_FOR_FN (m_fn, order[bbi]);
   3612       if (bb->index < NUM_FIXED_BLOCKS)
   3613 	continue;
   3614 
   3615       if (!bitmap_set_bit (visited, bb->index))
   3616 	continue;
   3617 
   3618       // Process forward edges before backward edges (so push backward
   3619       // edges first).  Build the region in an approximation of reverse
   3620       // program order.
   3621       if (bitmap_bit_p (fpr_pseudos_live_in, bb->index))
   3622 	stack.quick_push ({ ei_start (bb->preds), nullptr });
   3623       if (bitmap_bit_p (fpr_pseudos_live_out, bb->index))
   3624 	stack.quick_push ({ ei_start (bb->succs), bb });
   3625       else
   3626 	region.safe_push (bb);
   3627       while (!stack.is_empty ())
   3628 	{
   3629 	  auto &node = stack.last ();
   3630 	  if (ei_end_p (node.ei))
   3631 	    {
   3632 	      if (node.bb)
   3633 		region.safe_push (node.bb);
   3634 	      stack.pop ();
   3635 	      continue;
   3636 	    }
   3637 	  edge e = ei_edge (node.ei);
   3638 	  if (node.bb)
   3639 	    {
   3640 	      // A forward edge from a node that has not yet been added
   3641 	      // to region.
   3642 	      if (bitmap_bit_p (fpr_pseudos_live_in, e->dest->index)
   3643 		  && bitmap_set_bit (visited, e->dest->index))
   3644 		{
   3645 		  stack.safe_push ({ ei_start (e->dest->preds), nullptr });
   3646 		  if (bitmap_bit_p (fpr_pseudos_live_out, e->dest->index))
   3647 		    stack.safe_push ({ ei_start (e->dest->succs), e->dest });
   3648 		  else
   3649 		    region.safe_push (e->dest);
   3650 		}
   3651 	      else
   3652 		ei_next (&node.ei);
   3653 	    }
   3654 	  else
   3655 	    {
   3656 	      // A backward edge from a node that has already been added
   3657 	      // to the region.
   3658 	      if (bitmap_bit_p (fpr_pseudos_live_out, e->src->index)
   3659 		  && bitmap_set_bit (visited, e->src->index))
   3660 		{
   3661 		  if (bitmap_bit_p (fpr_pseudos_live_in, e->src->index))
   3662 		    stack.safe_push ({ ei_start (e->src->preds), nullptr });
   3663 		  stack.safe_push ({ ei_start (e->src->succs), e->src });
   3664 		}
   3665 	      else
   3666 		ei_next (&node.ei);
   3667 	    }
   3668 	}
   3669 
   3670       m_current_point = 2;
   3671       start_new_region ();
   3672 
   3673       if (region.is_empty ())
   3674 	process_block (bb, true);
   3675       else
   3676 	{
   3677 	  if (dump_file && (dump_flags & TDF_DETAILS))
   3678 	    {
   3679 	      fprintf (dump_file, "\nRegion (from %d):", bb->index);
   3680 	      for (unsigned int j = 0; j < region.length (); ++j)
   3681 		fprintf (dump_file, " %d", region[j]->index);
   3682 	      fprintf (dump_file, "\n");
   3683 	    }
   3684 	  for (unsigned int j = 0; j < region.length (); ++j)
   3685 	    {
   3686 	      basic_block bb = region[j];
   3687 	      bool is_isolated
   3688 		= ((j == 0 && !bitmap_bit_p (fpr_pseudos_live_out, bb->index))
   3689 		   || (j == region.length () - 1
   3690 		       && !bitmap_bit_p (fpr_pseudos_live_in, bb->index)));
   3691 	      process_block (bb, is_isolated);
   3692 	    }
   3693 	}
   3694       region.truncate (0);
   3695 
   3696       if (!m_allocnos.is_empty () && m_allocation_successful)
   3697 	process_region ();
   3698     }
   3699 }
   3700 
   3701 // Run the pass on the current function.
   3702 void
   3703 early_ra::execute ()
   3704 {
   3705   df_analyze ();
   3706 
   3707   preprocess_insns ();
   3708   propagate_pseudo_reg_info ();
   3709   choose_fpr_pseudos ();
   3710   if (bitmap_empty_p (m_fpr_pseudos))
   3711     return;
   3712 
   3713   if (dump_file && (dump_flags & TDF_DETAILS))
   3714     dump_pseudo_regs ();
   3715 
   3716   process_blocks ();
   3717   df_verify ();
   3718 }
   3719 
   3720 class pass_early_ra : public rtl_opt_pass
   3721 {
   3722 public:
   3723   pass_early_ra (gcc::context *ctxt)
   3724     : rtl_opt_pass (pass_data_early_ra, ctxt)
   3725   {}
   3726 
   3727   // opt_pass methods:
   3728   virtual bool gate (function *);
   3729   virtual unsigned int execute (function *);
   3730 };
   3731 
   3732 bool
   3733 pass_early_ra::gate (function *)
   3734 {
   3735   // Require a vector ISA to be enabled.
   3736   if (!TARGET_SIMD && !TARGET_SVE)
   3737     return false;
   3738 
   3739   if (aarch64_early_ra == AARCH64_EARLY_RA_NONE)
   3740     return false;
   3741 
   3742   if (aarch64_early_ra == AARCH64_EARLY_RA_STRIDED
   3743       && !TARGET_STREAMING_SME2)
   3744     return false;
   3745 
   3746   return true;
   3747 }
   3748 
   3749 unsigned int
   3750 pass_early_ra::execute (function *fn)
   3751 {
   3752   early_ra (fn).execute ();
   3753   return 0;
   3754 }
   3755 
   3756 } // end namespace
   3757 
   3758 // Create a new instance of the pass.
   3759 rtl_opt_pass *
   3760 make_pass_aarch64_early_ra (gcc::context *ctxt)
   3761 {
   3762   return new pass_early_ra (ctxt);
   3763 }
   3764