LCOV - code coverage report
Current view: top level - gcc - ira-conflicts.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.3 % 457 422
Test Date: 2026-07-11 15:47:05 Functions: 89.5 % 19 17
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* IRA conflict builder.
       2              :    Copyright (C) 2006-2026 Free Software Foundation, Inc.
       3              :    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it under
       8              : the terms of the GNU General Public License as published by the Free
       9              : Software Foundation; either version 3, or (at your option) any later
      10              : version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15              : for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "backend.h"
      25              : #include "target.h"
      26              : #include "rtl.h"
      27              : #include "predict.h"
      28              : #include "memmodel.h"
      29              : #include "tm_p.h"
      30              : #include "insn-config.h"
      31              : #include "regs.h"
      32              : #include "ira.h"
      33              : #include "ira-int.h"
      34              : #include "sparseset.h"
      35              : #include "addresses.h"
      36              : 
      37              : /* This file contains code responsible for allocno conflict creation,
      38              :    allocno copy creation and allocno info accumulation on upper level
      39              :    regions.  */
      40              : 
      41              : /* ira_allocnos_num array of arrays of bits, recording whether two
      42              :    allocno's conflict (can't go in the same hardware register).
      43              : 
      44              :    Some arrays will be used as conflict bit vector of the
      45              :    corresponding allocnos see function build_object_conflicts.  */
      46              : static IRA_INT_TYPE **conflicts;
      47              : 
      48              : /* Macro to test a conflict of C1 and C2 in `conflicts'.  */
      49              : #define OBJECTS_CONFLICT_P(C1, C2)                                      \
      50              :   (OBJECT_MIN (C1) <= OBJECT_CONFLICT_ID (C2)                                \
      51              :    && OBJECT_CONFLICT_ID (C2) <= OBJECT_MAX (C1)                     \
      52              :    && TEST_MINMAX_SET_BIT (conflicts[OBJECT_CONFLICT_ID (C1)],          \
      53              :                            OBJECT_CONFLICT_ID (C2),                     \
      54              :                            OBJECT_MIN (C1), OBJECT_MAX (C1)))
      55              : 
      56              : 
      57              : /* Record a conflict between objects OBJ1 and OBJ2.  If necessary,
      58              :    canonicalize the conflict by recording it for lower-order subobjects
      59              :    of the corresponding allocnos.  */
      60              : static void
      61    217742838 : record_object_conflict (ira_object_t obj1, ira_object_t obj2)
      62              : {
      63    217742838 :   ira_allocno_t a1 = OBJECT_ALLOCNO (obj1);
      64    217742838 :   ira_allocno_t a2 = OBJECT_ALLOCNO (obj2);
      65    217742838 :   int w1 = OBJECT_SUBWORD (obj1);
      66    217742838 :   int w2 = OBJECT_SUBWORD (obj2);
      67    217742838 :   int id1, id2;
      68              : 
      69              :   /* Canonicalize the conflict.  If two identically-numbered words
      70              :      conflict, always record this as a conflict between words 0.  That
      71              :      is the only information we need, and it is easier to test for if
      72              :      it is collected in each allocno's lowest-order object.  */
      73    217742838 :   if (w1 == w2 && w1 > 0)
      74              :     {
      75      1273951 :       obj1 = ALLOCNO_OBJECT (a1, 0);
      76      1273951 :       obj2 = ALLOCNO_OBJECT (a2, 0);
      77              :     }
      78    217742838 :   id1 = OBJECT_CONFLICT_ID (obj1);
      79    217742838 :   id2 = OBJECT_CONFLICT_ID (obj2);
      80              : 
      81    217742838 :   SET_MINMAX_SET_BIT (conflicts[id1], id2, OBJECT_MIN (obj1),
      82              :                       OBJECT_MAX (obj1));
      83    217742838 :   SET_MINMAX_SET_BIT (conflicts[id2], id1, OBJECT_MIN (obj2),
      84              :                       OBJECT_MAX (obj2));
      85    217742838 : }
      86              : 
      87              : /* Build allocno conflict table by processing allocno live ranges.
      88              :    Return true if the table was built.  The table is not built if it
      89              :    is too big.  */
      90              : static bool
      91      1057059 : build_conflict_bit_table (void)
      92              : {
      93      1057059 :   int i;
      94      1057059 :   unsigned int j;
      95      1057059 :   enum reg_class aclass;
      96      1057059 :   int object_set_words, allocated_words_num, conflict_bit_vec_words_num;
      97      1057059 :   live_range_t r;
      98      1057059 :   ira_allocno_t allocno;
      99      1057059 :   ira_allocno_iterator ai;
     100      1057059 :   sparseset objects_live;
     101      1057059 :   ira_object_t obj;
     102      1057059 :   ira_allocno_object_iterator aoi;
     103              : 
     104      1057059 :   allocated_words_num = 0;
     105     27417551 :   FOR_EACH_ALLOCNO (allocno, ai)
     106     52143639 :     FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
     107              :       {
     108     25783147 :         if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
     109       909901 :           continue;
     110     24873246 :         conflict_bit_vec_words_num
     111     24873246 :           = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
     112              :              / IRA_INT_BITS);
     113     24873246 :         allocated_words_num += conflict_bit_vec_words_num;
     114     24873246 :         if ((uint64_t) allocated_words_num * sizeof (IRA_INT_TYPE)
     115     24873246 :             > (uint64_t) param_ira_max_conflict_table_size * 1024 * 1024)
     116              :           {
     117            0 :             if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
     118            0 :               fprintf (ira_dump_file,
     119              :                        "+++Conflict table will be too big(>%dMB) "
     120              :                        "-- don't use it\n",
     121              :                        param_ira_max_conflict_table_size);
     122            0 :             return false;
     123              :           }
     124              :       }
     125              : 
     126      2114118 :   conflicts = (IRA_INT_TYPE **) ira_allocate (sizeof (IRA_INT_TYPE *)
     127      1057059 :                                               * ira_objects_num);
     128      1057059 :   allocated_words_num = 0;
     129     27417551 :   FOR_EACH_ALLOCNO (allocno, ai)
     130     52143639 :     FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
     131              :       {
     132     25783147 :         int id = OBJECT_CONFLICT_ID (obj);
     133     25783147 :         if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
     134              :           {
     135       909901 :             conflicts[id] = NULL;
     136       909901 :             continue;
     137              :           }
     138     24873246 :         conflict_bit_vec_words_num
     139     24873246 :           = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
     140              :              / IRA_INT_BITS);
     141     24873246 :         allocated_words_num += conflict_bit_vec_words_num;
     142     24873246 :         conflicts[id]
     143     49746492 :           = (IRA_INT_TYPE *) ira_allocate (sizeof (IRA_INT_TYPE)
     144     24873246 :                                            * conflict_bit_vec_words_num);
     145     24873246 :         memset (conflicts[id], 0,
     146              :                 sizeof (IRA_INT_TYPE) * conflict_bit_vec_words_num);
     147              :       }
     148              : 
     149      1057059 :   object_set_words = (ira_objects_num + IRA_INT_BITS - 1) / IRA_INT_BITS;
     150      1057059 :   if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
     151           39 :     fprintf (ira_dump_file,
     152              :              "+++Allocating " HOST_SIZE_T_PRINT_UNSIGNED
     153              :              " bytes for conflict table (uncompressed size "
     154              :              HOST_SIZE_T_PRINT_UNSIGNED ")\n",
     155           39 :              (fmt_size_t) (sizeof (IRA_INT_TYPE) * allocated_words_num),
     156           39 :              (fmt_size_t) (sizeof (IRA_INT_TYPE) * object_set_words
     157           39 :                            * ira_objects_num));
     158              : 
     159      1057059 :   objects_live = sparseset_alloc (ira_objects_num);
     160     30786151 :   for (i = 0; i < ira_max_point; i++)
     161              :     {
     162     57011298 :       for (r = ira_start_point_ranges[i]; r != NULL; r = r->start_next)
     163              :         {
     164     27282206 :           ira_object_t obj = r->object;
     165     27282206 :           ira_allocno_t allocno = OBJECT_ALLOCNO (obj);
     166     27282206 :           int id = OBJECT_CONFLICT_ID (obj);
     167              : 
     168     27282206 :           gcc_assert (id < ira_objects_num);
     169              : 
     170     27282206 :           aclass = ALLOCNO_CLASS (allocno);
     171    531625136 :           EXECUTE_IF_SET_IN_SPARSESET (objects_live, j)
     172              :             {
     173    286076381 :               ira_object_t live_obj = ira_object_id_map[j];
     174    286076381 :               ira_allocno_t live_a = OBJECT_ALLOCNO (live_obj);
     175    286076381 :               enum reg_class live_aclass = ALLOCNO_CLASS (live_a);
     176              : 
     177    286076381 :               if (ira_reg_classes_intersect_p[aclass][live_aclass]
     178              :                   /* Don't set up conflict for the allocno with itself.  */
     179    218266549 :                   && live_a != allocno)
     180              :                 {
     181    217742838 :                   record_object_conflict (obj, live_obj);
     182              :                 }
     183              :             }
     184     27282206 :           sparseset_set_bit (objects_live, id);
     185              :         }
     186              : 
     187     57011298 :       for (r = ira_finish_point_ranges[i]; r != NULL; r = r->finish_next)
     188     27282206 :         sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (r->object));
     189              :     }
     190      1057059 :   sparseset_free (objects_live);
     191      1057059 :   return true;
     192              : }
     193              : 
     194              : /* Return true iff allocnos A1 and A2 cannot be allocated to the same
     195              :    register due to conflicts.  */
     196              : 
     197              : static bool
     198      8022408 : allocnos_conflict_for_copy_p (ira_allocno_t a1, ira_allocno_t a2)
     199              : {
     200              :   /* Due to the fact that we canonicalize conflicts (see
     201              :      record_object_conflict), we only need to test for conflicts of
     202              :      the lowest order words.  */
     203      8022408 :   ira_object_t obj1 = ALLOCNO_OBJECT (a1, 0);
     204      8022408 :   ira_object_t obj2 = ALLOCNO_OBJECT (a2, 0);
     205              : 
     206      8022408 :   return OBJECTS_CONFLICT_P (obj1, obj2);
     207              : }
     208              : 
     209              : /* Check that X is REG or SUBREG of REG.  */
     210              : #define REG_SUBREG_P(x)                                                 \
     211              :    (REG_P (x) || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))))
     212              : 
     213              : /* Return X if X is a REG, otherwise it should be SUBREG of REG and
     214              :    the function returns the reg in this case.  *OFFSET will be set to
     215              :    0 in the first case or the regno offset in the first case.  */
     216              : static rtx
     217     25161334 : go_through_subreg (rtx x, int *offset)
     218              : {
     219     25161334 :   rtx reg;
     220              : 
     221     25161334 :   *offset = 0;
     222     25161334 :   if (REG_P (x))
     223              :     return x;
     224      1066079 :   ira_assert (GET_CODE (x) == SUBREG);
     225      1066079 :   reg = SUBREG_REG (x);
     226      1066079 :   ira_assert (REG_P (reg));
     227      1066079 :   if (REGNO (reg) < FIRST_PSEUDO_REGISTER)
     228            0 :     *offset = subreg_regno_offset (REGNO (reg), GET_MODE (reg),
     229            0 :                                    SUBREG_BYTE (x), GET_MODE (x));
     230              :   /* The offset is always 0 for paradoxical subregs.  */
     231      1066079 :   else if (!can_div_trunc_p (SUBREG_BYTE (x),
     232      1066079 :                              REGMODE_NATURAL_SIZE (GET_MODE (reg)), offset))
     233              :     /* Checked by validate_subreg.  We must know at compile time which
     234              :        inner hard registers are being accessed.  */
     235              :     gcc_unreachable ();
     236              :   return reg;
     237              : }
     238              : 
     239              : /* Return the recomputed frequency for this shuffle copy or its similar
     240              :    case, since it's not for a real move insn, make it smaller.  */
     241              : 
     242              : static int
     243     11620296 : get_freq_for_shuffle_copy (int freq)
     244              : {
     245      9813947 :   return freq < 8 ? 1 : freq / 8;
     246              : }
     247              : 
     248              : /* Process registers REG1 and REG2 in move INSN with execution
     249              :    frequency FREQ.  The function also processes the registers in a
     250              :    potential move insn (INSN == NULL in this case) with frequency
     251              :    FREQ.  The function can modify hard register costs of the
     252              :    corresponding allocnos or create a copy involving the corresponding
     253              :    allocnos.  The function does nothing if the both registers are hard
     254              :    registers.  When nothing is changed, the function returns FALSE.
     255              :    SINGLE_INPUT_OP_HAS_CSTR_P is only meaningful when constraint_p
     256              :    is true, see function ira_get_dup_out_num for its meaning.  */
     257              : static bool
     258     12580667 : process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p, rtx_insn *insn,
     259              :                        int freq, bool single_input_op_has_cstr_p = true)
     260              : {
     261     12580667 :   int allocno_preferenced_hard_regno, index, offset1, offset2;
     262     12580667 :   int cost, conflict_cost, move_cost;
     263     12580667 :   bool only_regs_p;
     264     12580667 :   ira_allocno_t a;
     265     12580667 :   reg_class_t rclass, aclass;
     266     12580667 :   machine_mode mode;
     267     12580667 :   ira_copy_t cp;
     268              : 
     269     12580667 :   gcc_assert (REG_SUBREG_P (reg1) && REG_SUBREG_P (reg2));
     270     12580667 :   only_regs_p = REG_P (reg1) && REG_P (reg2);
     271     12580667 :   reg1 = go_through_subreg (reg1, &offset1);
     272     12580667 :   reg2 = go_through_subreg (reg2, &offset2);
     273              :   /* Set up hard regno preferenced by allocno.  If allocno gets the
     274              :      hard regno the copy (or potential move) insn will be removed.  */
     275     12580667 :   if (HARD_REGISTER_P (reg1))
     276              :     {
     277      3025193 :       if (HARD_REGISTER_P (reg2))
     278              :         return false;
     279      3025193 :       allocno_preferenced_hard_regno = REGNO (reg1) + offset1 - offset2;
     280      3025193 :       a = ira_curr_regno_allocno_map[REGNO (reg2)];
     281              :     }
     282      9555474 :   else if (HARD_REGISTER_P (reg2))
     283              :     {
     284      3269430 :       allocno_preferenced_hard_regno = REGNO (reg2) + offset2 - offset1;
     285      3269430 :       a = ira_curr_regno_allocno_map[REGNO (reg1)];
     286              :     }
     287              :   else
     288              :     {
     289      6286044 :       ira_allocno_t a1 = ira_curr_regno_allocno_map[REGNO (reg1)];
     290      6286044 :       ira_allocno_t a2 = ira_curr_regno_allocno_map[REGNO (reg2)];
     291              : 
     292      6286044 :       if (!allocnos_conflict_for_copy_p (a1, a2)
     293      5783559 :           && offset1 == offset2
     294      6286044 :           && ordered_p (GET_MODE_PRECISION (ALLOCNO_MODE (a1)),
     295      5711142 :                         GET_MODE_PRECISION (ALLOCNO_MODE (a2))))
     296              :         {
     297      5711142 :           cp = ira_add_allocno_copy (a1, a2, freq, constraint_p, insn,
     298              :                                      ira_curr_loop_tree_node);
     299      5711142 :           bitmap_set_bit (ira_curr_loop_tree_node->local_copies, cp->num);
     300      5711142 :           return true;
     301              :         }
     302              :       else
     303              :         return false;
     304              :     }
     305              : 
     306      6294623 :   if (! IN_RANGE (allocno_preferenced_hard_regno,
     307              :                   0, FIRST_PSEUDO_REGISTER - 1))
     308              :     /* Cannot be tied.  */
     309              :     return false;
     310      6294623 :   rclass = REGNO_REG_CLASS (allocno_preferenced_hard_regno);
     311      6294623 :   mode = ALLOCNO_MODE (a);
     312      6294623 :   aclass = ALLOCNO_CLASS (a);
     313      6294623 :   if (only_regs_p && insn != NULL_RTX
     314      6224962 :       && reg_class_size[rclass] <= ira_reg_class_max_nregs [rclass][mode])
     315              :     /* It is already taken into account in ira-costs.cc.  */
     316              :     return false;
     317       376785 :   index = ira_class_hard_reg_index[aclass][allocno_preferenced_hard_regno];
     318       376785 :   if (index < 0)
     319              :     /* Cannot be tied.  It is not in the allocno class.  */
     320              :     return false;
     321       365083 :   ira_init_register_move_cost_if_necessary (mode);
     322       365083 :   if (HARD_REGISTER_P (reg1))
     323       180125 :     move_cost = ira_register_move_cost[mode][aclass][rclass];
     324              :   else
     325       184958 :     move_cost = ira_register_move_cost[mode][rclass][aclass];
     326              : 
     327       365083 :   if (!single_input_op_has_cstr_p)
     328              :     {
     329              :       /* When this is a constraint copy and the matching constraint
     330              :          doesn't only exist for this given operand but also for some
     331              :          other operand(s), it means saving the possible move cost does
     332              :          NOT need to require reg1 and reg2 to use the same hardware
     333              :          register, so this hardware preference isn't required to be
     334              :          fixed.  To avoid it to over prefer this hardware register,
     335              :          and over disparage this hardware register on conflicted
     336              :          objects, we need some cost tweaking here, similar to what
     337              :          we do for shuffle copy.  */
     338            0 :       gcc_assert (constraint_p);
     339            0 :       int reduced_freq = get_freq_for_shuffle_copy (freq);
     340            0 :       if (HARD_REGISTER_P (reg1))
     341              :         /* For reg2 = opcode(reg1, reg3 ...), assume that reg3 is a
     342              :            pseudo register which has matching constraint on reg2,
     343              :            even if reg2 isn't assigned by reg1, it's still possible
     344              :            not to have register moves if reg2 and reg3 use the same
     345              :            hardware register.  So to avoid the allocation to over
     346              :            prefer reg1, we can just take it as a shuffle copy.  */
     347            0 :         cost = conflict_cost = move_cost * reduced_freq;
     348              :       else
     349              :         {
     350              :           /* For reg1 = opcode(reg2, reg3 ...), assume that reg3 is a
     351              :              pseudo register which has matching constraint on reg2,
     352              :              to save the register move, it's better to assign reg1
     353              :              to either of reg2 and reg3 (or one of other pseudos like
     354              :              reg3), it's reasonable to use freq for the cost.  But
     355              :              for conflict_cost, since reg2 and reg3 conflicts with
     356              :              each other, both of them has the chance to be assigned
     357              :              by reg1, assume reg3 has one copy which also conflicts
     358              :              with reg2, we shouldn't make it less preferred on reg1
     359              :              since reg3 has the same chance to be assigned by reg1.
     360              :              So it adjusts the conflic_cost to make it same as what
     361              :              we use for shuffle copy.  */
     362            0 :           cost = move_cost * freq;
     363            0 :           conflict_cost = move_cost * reduced_freq;
     364              :         }
     365              :     }
     366              :   else
     367       365083 :     cost = conflict_cost = move_cost * freq;
     368              : 
     369       408697 :   do
     370              :     {
     371       408697 :       ira_allocate_and_set_costs
     372       408697 :         (&ALLOCNO_HARD_REG_COSTS (a), aclass,
     373              :          ALLOCNO_CLASS_COST (a));
     374       408697 :       ira_allocate_and_set_costs
     375       408697 :         (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), aclass, 0);
     376       408697 :       ALLOCNO_HARD_REG_COSTS (a)[index] -= cost;
     377       408697 :       ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index] -= conflict_cost;
     378       408697 :       if (ALLOCNO_HARD_REG_COSTS (a)[index] < ALLOCNO_CLASS_COST (a))
     379       367070 :         ALLOCNO_CLASS_COST (a) = ALLOCNO_HARD_REG_COSTS (a)[index];
     380       408697 :       ira_add_allocno_pref (a, allocno_preferenced_hard_regno, freq);
     381       408697 :       a = ira_parent_or_cap_allocno (a);
     382              :     }
     383       408697 :   while (a != NULL);
     384              :   return true;
     385              : }
     386              : 
     387              : /* Go through all of OP's dependent filters, check if they reference
     388              :    REF, and if so, check for all eligible hard regs in its class
     389              :    whether the filter allows the same regno for both (dependent) operand,
     390              :    as well as referenced operand.  Return true if all filters allow that,
     391              :    or false otherwise.  */
     392              : 
     393              : static bool
     394            0 : dependent_filter_same_reg_ok_p (const operand_alternative *op_alt,
     395              :                                 int op, int ref)
     396              : {
     397            0 :   unsigned mask = alternative_dependent_filters (op_alt, op);
     398            0 :   if (!mask)
     399              :     return true;
     400              : 
     401            0 :   enum reg_class cl
     402            0 :     = ira_reg_class_intersect[op_alt[op].cl][op_alt[ref].cl];
     403              : 
     404            0 :   machine_mode mode = recog_data.operand_mode[op];
     405            0 :   machine_mode ref_mode = recog_data.operand_mode[ref];
     406              : 
     407            0 :   for (int id = 0; id < NUM_DEPENDENT_FILTERS; ++id)
     408              :     {
     409              :       if (!(mask & (1U << id)))
     410              :         continue;
     411              :       if (get_dependent_filter_ref (id) != ref)
     412              :         continue;
     413              : 
     414              :       bool ok = false;
     415              :       for (int i = 0; i < ira_class_hard_regs_num[cl]; ++i)
     416              :         {
     417              :           unsigned regno = ira_class_hard_regs[cl][i];
     418              :           ok = eval_dependent_filter (id, regno, mode, regno, ref_mode);
     419              :           if (ok)
     420              :             break;
     421              :         }
     422              :       if (!ok)
     423              :         return false;
     424              :     }
     425            0 :   return true;
     426              : }
     427              : 
     428              : /* Return true if output operand OUTPUT and input operand INPUT of
     429              :    INSN can use the same register class for at least one alternative.
     430              :    INSN is already described in recog_data and recog_op_alt.  */
     431              : static bool
     432      2729072 : can_use_same_reg_p (rtx_insn *insn, int output, int input)
     433              : {
     434      2729072 :   alternative_mask preferred = get_preferred_alternatives (insn);
     435      3934750 :   for (int nalt = 0; nalt < recog_data.n_alternatives; nalt++)
     436              :     {
     437      3711029 :       if (!TEST_BIT (preferred, nalt))
     438       821771 :         continue;
     439              : 
     440      2889258 :       const operand_alternative *op_alt
     441      2889258 :         = &recog_op_alt[nalt * recog_data.n_operands];
     442      2889258 :       if (op_alt[input].matches == output)
     443              :         return true;
     444              : 
     445      1775585 :       if (op_alt[output].earlyclobber)
     446        76470 :         continue;
     447              : 
     448      1699115 :       if (ira_reg_class_intersect[op_alt[input].cl][op_alt[output].cl]
     449              :           == NO_REGS)
     450       307437 :         continue;
     451              : 
     452              :       if (NUM_DEPENDENT_FILTERS
     453              :           && (!dependent_filter_same_reg_ok_p (op_alt, input, output)
     454              :               || !dependent_filter_same_reg_ok_p (op_alt, output, input)))
     455              :         continue;
     456              : 
     457              :       return true;
     458              :     }
     459              :   return false;
     460              : }
     461              : 
     462              : /* Process all of the output registers of the current insn (INSN) which
     463              :    are not bound (BOUND_P) and the input register REG (its operand number
     464              :    OP_NUM) which dies in the insn as if there were a move insn between
     465              :    them with frequency FREQ.  */
     466              : static void
     467     11620296 : process_reg_shuffles (rtx_insn *insn, rtx reg, int op_num, int freq,
     468              :                       bool *bound_p)
     469              : {
     470     11620296 :   int i;
     471     11620296 :   rtx another_reg;
     472              : 
     473     11620296 :   gcc_assert (REG_SUBREG_P (reg));
     474     41909808 :   for (i = 0; i < recog_data.n_operands; i++)
     475              :     {
     476     30289512 :       another_reg = recog_data.operand[i];
     477              : 
     478     30289512 :       if (!REG_SUBREG_P (another_reg) || op_num == i
     479     10376537 :           || recog_data.operand_type[i] != OP_OUT
     480      5774296 :           || bound_p[i]
     481     32995731 :           || (!can_use_same_reg_p (insn, i, op_num)
     482       208941 :               && (recog_data.constraints[op_num][0] != '%'
     483        12779 :                   || !can_use_same_reg_p (insn, i, op_num + 1))
     484       200868 :               && (op_num == 0
     485       200868 :                   || recog_data.constraints[op_num - 1][0] != '%'
     486        10074 :                   || !can_use_same_reg_p (insn, i, op_num - 1))))
     487     27784161 :         continue;
     488              : 
     489      2505351 :       process_regs_for_copy (reg, another_reg, false, NULL, freq);
     490              :     }
     491     11620296 : }
     492              : 
     493              : /* Process INSN and create allocno copies if necessary.  For example,
     494              :    it might be because INSN is a pseudo-register move or INSN is two
     495              :    operand insn.  */
     496              : static void
     497     59373850 : add_insn_allocno_copies (rtx_insn *insn)
     498              : {
     499     59373850 :   rtx set = single_set (insn), operand, dup;
     500     59373850 :   bool bound_p[MAX_RECOG_OPERANDS];
     501     59373850 :   int i, n, freq;
     502     59373850 :   alternative_mask alts;
     503              : 
     504     59373850 :   freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
     505     49320452 :   if (freq == 0)
     506      7910326 :     freq = 1;
     507              : 
     508              :   /* Tie output register operands of two consecutive single_sets
     509              :      marked as a fused pair.  */
     510     59373850 :   if (single_output_fused_pair_p (insn))
     511            0 :     process_regs_for_copy (SET_DEST (set),
     512            0 :                    SET_DEST (single_set (prev_nonnote_nondebug_insn (insn))),
     513              :                    true, NULL, freq);
     514              : 
     515            0 :   if (set != NULL_RTX
     516     55440234 :       && REG_SUBREG_P (SET_DEST (set)) && REG_SUBREG_P (SET_SRC (set))
     517      9845972 :       && ! side_effects_p (set)
     518     69219822 :       && find_reg_note (insn, REG_DEAD,
     519      9845972 :                         REG_P (SET_SRC (set))
     520              :                         ? SET_SRC (set)
     521              :                         : SUBREG_REG (SET_SRC (set))) != NULL_RTX)
     522              :     {
     523      7538113 :       process_regs_for_copy (SET_SRC (set), SET_DEST (set),
     524              :                              false, insn, freq);
     525     46654569 :       return;
     526              :     }
     527              :   /* Fast check of possibility of constraint or shuffle copies.  If
     528              :      there are no dead registers, there will be no such copies.  */
     529     51835737 :   if (! find_reg_note (insn, REG_DEAD, NULL_RTX))
     530              :     return;
     531     20257394 :   alts = ira_setup_alts (insn);
     532     87974907 :   for (i = 0; i < recog_data.n_operands; i++)
     533     47460119 :     bound_p[i] = false;
     534     67717513 :   for (i = 0; i < recog_data.n_operands; i++)
     535              :     {
     536     47460119 :       operand = recog_data.operand[i];
     537     47460119 :       if (! REG_SUBREG_P (operand))
     538     26605960 :         continue;
     539     20854159 :       bool single_input_op_has_cstr_p;
     540     20854159 :       if ((n = ira_get_dup_out_num (i, alts, single_input_op_has_cstr_p)) >= 0)
     541              :         {
     542      3090649 :           bound_p[n] = true;
     543      3090649 :           dup = recog_data.operand[n];
     544       138841 :           if (REG_SUBREG_P (dup)
     545      6168580 :               && find_reg_note (insn, REG_DEAD,
     546      3077931 :                                 REG_P (operand)
     547              :                                 ? operand
     548              :                                 : SUBREG_REG (operand)) != NULL_RTX)
     549      2537203 :             process_regs_for_copy (operand, dup, true, NULL, freq,
     550              :                                    single_input_op_has_cstr_p);
     551              :         }
     552              :     }
     553     67717513 :   for (i = 0; i < recog_data.n_operands; i++)
     554              :     {
     555     47460119 :       operand = recog_data.operand[i];
     556     27452400 :       if (REG_SUBREG_P (operand)
     557     48306559 :           && find_reg_note (insn, REG_DEAD,
     558              :                             REG_P (operand)
     559              :                             ? operand : SUBREG_REG (operand)) != NULL_RTX)
     560              :         {
     561              :           /* If an operand dies, prefer its hard register for the output
     562              :              operands by decreasing the hard register cost or creating
     563              :              the corresponding allocno copies.  The cost will not
     564              :              correspond to a real move insn cost, so make the frequency
     565              :              smaller.  */
     566     11620296 :           int new_freq = get_freq_for_shuffle_copy (freq);
     567     11620296 :           process_reg_shuffles (insn, operand, i, new_freq, bound_p);
     568              :         }
     569              :     }
     570              : }
     571              : 
     572              : /* Add copies originated from BB given by LOOP_TREE_NODE.  */
     573              : static void
     574     12350481 : add_copies (ira_loop_tree_node_t loop_tree_node)
     575              : {
     576     12350481 :   basic_block bb;
     577     12350481 :   rtx_insn *insn;
     578              : 
     579     12350481 :   bb = loop_tree_node->bb;
     580     12350481 :   if (bb == NULL)
     581              :     return;
     582    143779512 :   FOR_BB_INSNS (bb, insn)
     583    132652009 :     if (NONDEBUG_INSN_P (insn))
     584     59373850 :       add_insn_allocno_copies (insn);
     585              : }
     586              : 
     587              : /* Propagate copies the corresponding allocnos on upper loop tree
     588              :    level.  */
     589              : static void
     590      1010507 : propagate_copies (void)
     591              : {
     592      1010507 :   ira_copy_t cp;
     593      1010507 :   ira_copy_iterator ci;
     594      1010507 :   ira_allocno_t a1, a2, parent_a1, parent_a2;
     595              : 
     596      8258815 :   FOR_EACH_COPY (cp, ci)
     597              :     {
     598      7248308 :       a1 = cp->first;
     599      7248308 :       a2 = cp->second;
     600      7248308 :       if (ALLOCNO_LOOP_TREE_NODE (a1) == ira_loop_tree_root)
     601      5511944 :         continue;
     602      1736364 :       ira_assert ((ALLOCNO_LOOP_TREE_NODE (a2) != ira_loop_tree_root));
     603      1736364 :       parent_a1 = ira_parent_or_cap_allocno (a1);
     604      1736364 :       parent_a2 = ira_parent_or_cap_allocno (a2);
     605      1736364 :       ira_assert (parent_a1 != NULL && parent_a2 != NULL);
     606      1736364 :       if (! allocnos_conflict_for_copy_p (parent_a1, parent_a2))
     607      1736060 :         ira_add_allocno_copy (parent_a1, parent_a2, cp->freq,
     608      1736060 :                               cp->constraint_p, cp->insn, cp->loop_tree_node);
     609              :     }
     610      1010507 : }
     611              : 
     612              : /* Array used to collect all conflict allocnos for given allocno.  */
     613              : static ira_object_t *collected_conflict_objects;
     614              : 
     615              : /* Build conflict vectors or bit conflict vectors (whatever is more
     616              :    profitable) for object OBJ from the conflict table.  */
     617              : static void
     618     25783147 : build_object_conflicts (ira_object_t obj)
     619              : {
     620     25783147 :   int i, px, parent_num;
     621     25783147 :   ira_allocno_t parent_a, another_parent_a;
     622     25783147 :   ira_object_t parent_obj;
     623     25783147 :   ira_allocno_t a = OBJECT_ALLOCNO (obj);
     624     25783147 :   IRA_INT_TYPE *object_conflicts;
     625     25783147 :   minmax_set_iterator asi;
     626     25783147 :   int parent_min, parent_max ATTRIBUTE_UNUSED;
     627              : 
     628     25783147 :   object_conflicts = conflicts[OBJECT_CONFLICT_ID (obj)];
     629     25783147 :   px = 0;
     630    634877174 :   FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
     631              :                               OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
     632              :     {
     633    583310880 :       ira_object_t another_obj = ira_object_id_map[i];
     634    583310880 :       ira_allocno_t another_a = OBJECT_ALLOCNO (another_obj);
     635              : 
     636    583310880 :       ira_assert (ira_reg_classes_intersect_p
     637              :                   [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
     638    583310880 :       collected_conflict_objects[px++] = another_obj;
     639              :     }
     640     25783147 :   if (ira_conflict_vector_profitable_p (obj, px))
     641              :     {
     642      5019937 :       ira_object_t *vec;
     643      5019937 :       ira_allocate_conflict_vec (obj, px);
     644      5019937 :       vec = OBJECT_CONFLICT_VEC (obj);
     645      5019937 :       memcpy (vec, collected_conflict_objects, sizeof (ira_object_t) * px);
     646      5019937 :       vec[px] = NULL;
     647      5019937 :       OBJECT_NUM_CONFLICTS (obj) = px;
     648              :     }
     649              :   else
     650              :     {
     651     20763210 :       int conflict_bit_vec_words_num;
     652              : 
     653     20763210 :       OBJECT_CONFLICT_ARRAY (obj) = object_conflicts;
     654     20763210 :       if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
     655              :         conflict_bit_vec_words_num = 0;
     656              :       else
     657     19853309 :         conflict_bit_vec_words_num
     658     19853309 :           = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
     659              :              / IRA_INT_BITS);
     660     20763210 :       OBJECT_CONFLICT_ARRAY_SIZE (obj)
     661     20763210 :         = conflict_bit_vec_words_num * sizeof (IRA_INT_TYPE);
     662              :     }
     663              : 
     664     25783147 :   parent_a = ira_parent_or_cap_allocno (a);
     665     25783147 :   if (parent_a == NULL)
     666     18913835 :     return;
     667      6869312 :   ira_assert (ALLOCNO_CLASS (a) == ALLOCNO_CLASS (parent_a));
     668      6869312 :   ira_assert (ALLOCNO_NUM_OBJECTS (a) == ALLOCNO_NUM_OBJECTS (parent_a));
     669      6869312 :   parent_obj = ALLOCNO_OBJECT (parent_a, OBJECT_SUBWORD (obj));
     670      6869312 :   parent_num = OBJECT_CONFLICT_ID (parent_obj);
     671      6869312 :   parent_min = OBJECT_MIN (parent_obj);
     672      6869312 :   parent_max = OBJECT_MAX (parent_obj);
     673    339905442 :   FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
     674              :                               OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
     675              :     {
     676    326166818 :       ira_object_t another_obj = ira_object_id_map[i];
     677    326166818 :       ira_allocno_t another_a = OBJECT_ALLOCNO (another_obj);
     678    326166818 :       int another_word = OBJECT_SUBWORD (another_obj);
     679              : 
     680    326166818 :       ira_assert (ira_reg_classes_intersect_p
     681              :                   [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
     682              : 
     683    326166818 :       another_parent_a = ira_parent_or_cap_allocno (another_a);
     684    326166818 :       if (another_parent_a == NULL)
     685            0 :         continue;
     686    326166818 :       ira_assert (ALLOCNO_NUM (another_parent_a) >= 0);
     687    326166818 :       ira_assert (ALLOCNO_CLASS (another_a)
     688              :                   == ALLOCNO_CLASS (another_parent_a));
     689    326166818 :       ira_assert (ALLOCNO_NUM_OBJECTS (another_a)
     690              :                   == ALLOCNO_NUM_OBJECTS (another_parent_a));
     691    326166818 :       SET_MINMAX_SET_BIT (conflicts[parent_num],
     692              :                           OBJECT_CONFLICT_ID (ALLOCNO_OBJECT (another_parent_a,
     693              :                                                               another_word)),
     694              :                           parent_min, parent_max);
     695              :     }
     696              : }
     697              : 
     698              : /* Build conflict vectors or bit conflict vectors (whatever is more
     699              :    profitable) of all allocnos from the conflict table.  */
     700              : static void
     701      1057059 : build_conflicts (void)
     702              : {
     703      1057059 :   int i;
     704      1057059 :   ira_allocno_t a, cap;
     705              : 
     706      1057059 :   collected_conflict_objects
     707      2114118 :     = (ira_object_t *) ira_allocate (sizeof (ira_object_t)
     708      1057059 :                                           * ira_objects_num);
     709     52838788 :   for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
     710     51781729 :     for (a = ira_regno_allocno_map[i];
     711     73442675 :          a != NULL;
     712     21660946 :          a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
     713              :       {
     714     21660946 :         int j, nregs = ALLOCNO_NUM_OBJECTS (a);
     715     43758465 :         for (j = 0; j < nregs; j++)
     716              :           {
     717     22097519 :             ira_object_t obj = ALLOCNO_OBJECT (a, j);
     718     22097519 :             build_object_conflicts (obj);
     719     25783147 :             for (cap = ALLOCNO_CAP (a); cap != NULL; cap = ALLOCNO_CAP (cap))
     720              :               {
     721      3685628 :                 ira_object_t cap_obj = ALLOCNO_OBJECT (cap, j);
     722      3685628 :                 gcc_assert (ALLOCNO_NUM_OBJECTS (cap) == ALLOCNO_NUM_OBJECTS (a));
     723      3685628 :                 build_object_conflicts (cap_obj);
     724              :               }
     725              :           }
     726              :       }
     727      1057059 :   ira_free (collected_conflict_objects);
     728      1057059 : }
     729              : 
     730              : 
     731              : 
     732              : /* Print hard reg set SET with TITLE to FILE.  */
     733              : static void
     734          836 : print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set)
     735              : {
     736          836 :   int i, start, end;
     737              : 
     738          836 :   fputs (title, file);
     739        77748 :   for (start = end = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     740              :     {
     741        76912 :       bool reg_included = TEST_HARD_REG_BIT (set, i);
     742              : 
     743        76912 :       if (reg_included)
     744              :         {
     745          782 :           if (start == -1)
     746          450 :             start = i;
     747              :           end = i;
     748              :         }
     749        76912 :       if (start >= 0 && (!reg_included || i == FIRST_PSEUDO_REGISTER - 1))
     750              :         {
     751          450 :           if (start == end)
     752          142 :             fprintf (file, " %d", start);
     753          308 :           else if (start == end + 1)
     754            0 :             fprintf (file, " %d %d", start, end);
     755              :           else
     756          308 :             fprintf (file, " %d-%d", start, end);
     757              :           start = -1;
     758              :         }
     759              :     }
     760          836 :   putc ('\n', file);
     761          836 : }
     762              : 
     763              : static void
     764          451 : print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
     765              : {
     766          451 :   HARD_REG_SET conflicting_hard_regs;
     767          451 :   basic_block bb;
     768          451 :   int n, i;
     769              : 
     770          451 :   if (reg_p)
     771            0 :     fprintf (file, ";; r%d", ALLOCNO_REGNO (a));
     772              :   else
     773              :     {
     774          451 :       fprintf (file, ";; a%d(r%d,", ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
     775          451 :       if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
     776            0 :         fprintf (file, "b%d", bb->index);
     777              :       else
     778          451 :         fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
     779          451 :       putc (')', file);
     780              :     }
     781              : 
     782          451 :   fputs (" conflicts:", file);
     783          451 :   n = ALLOCNO_NUM_OBJECTS (a);
     784          902 :   for (i = 0; i < n; i++)
     785              :     {
     786          451 :       ira_object_t obj = ALLOCNO_OBJECT (a, i);
     787          451 :       ira_object_t conflict_obj;
     788          451 :       ira_object_conflict_iterator oci;
     789              : 
     790          451 :       if (OBJECT_CONFLICT_ARRAY (obj) == NULL)
     791              :         {
     792           33 :           fprintf (file, "\n;;     total conflict hard regs:\n");
     793           33 :           fprintf (file, ";;     conflict hard regs:\n\n");
     794           33 :           continue;
     795              :         }
     796              : 
     797          418 :       if (n > 1)
     798            0 :         fprintf (file, "\n;;   subobject %d:", i);
     799         3578 :       FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
     800              :         {
     801         3160 :           ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
     802         3160 :           if (reg_p)
     803            0 :             fprintf (file, " r%d,", ALLOCNO_REGNO (conflict_a));
     804              :           else
     805              :             {
     806         3160 :               fprintf (file, " a%d(r%d", ALLOCNO_NUM (conflict_a),
     807              :                        ALLOCNO_REGNO (conflict_a));
     808         3160 :               if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
     809            0 :                 fprintf (file, ",w%d", OBJECT_SUBWORD (conflict_obj));
     810         3160 :               if ((bb = ALLOCNO_LOOP_TREE_NODE (conflict_a)->bb) != NULL)
     811            0 :                 fprintf (file, ",b%d", bb->index);
     812              :               else
     813         3160 :                 fprintf (file, ",l%d",
     814              :                          ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop_num);
     815         3160 :               putc (')', file);
     816              :             }
     817              :         }
     818          418 :       conflicting_hard_regs = (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)
     819          418 :                                & ~ira_no_alloc_regs
     820          418 :                                & reg_class_contents[ALLOCNO_CLASS (a)]);
     821          418 :       print_hard_reg_set (file, "\n;;     total conflict hard regs:",
     822              :                           conflicting_hard_regs);
     823              : 
     824          418 :       conflicting_hard_regs = (OBJECT_CONFLICT_HARD_REGS (obj)
     825          418 :                                & ~ira_no_alloc_regs
     826          418 :                                & reg_class_contents[ALLOCNO_CLASS (a)]);
     827          418 :       print_hard_reg_set (file, ";;     conflict hard regs:",
     828              :                           conflicting_hard_regs);
     829          418 :       putc ('\n', file);
     830              :     }
     831              : 
     832          451 : }
     833              : 
     834              : /* Print information about allocno or only regno (if REG_P) conflicts
     835              :    to FILE.  */
     836              : static void
     837           39 : print_conflicts (FILE *file, bool reg_p)
     838              : {
     839           39 :   ira_allocno_t a;
     840           39 :   ira_allocno_iterator ai;
     841              : 
     842          490 :   FOR_EACH_ALLOCNO (a, ai)
     843          451 :     print_allocno_conflicts (file, reg_p, a);
     844           39 :   putc ('\n', file);
     845           39 : }
     846              : 
     847              : /* Print information about allocno or only regno (if REG_P) conflicts
     848              :    to stderr.  */
     849              : void
     850            0 : ira_debug_conflicts (bool reg_p)
     851              : {
     852            0 :   print_conflicts (stderr, reg_p);
     853            0 : }
     854              : 
     855              : 
     856              : 
     857              : /* Entry function which builds allocno conflicts and allocno copies
     858              :    and accumulate some allocno info on upper level regions.  */
     859              : void
     860      1504950 : ira_build_conflicts (void)
     861              : {
     862      1504950 :   enum reg_class base;
     863      1504950 :   ira_allocno_t a;
     864      1504950 :   ira_allocno_iterator ai;
     865      1504950 :   HARD_REG_SET temp_hard_reg_set;
     866              : 
     867      1504950 :   if (ira_conflicts_p)
     868              :     {
     869      1057059 :       ira_conflicts_p = build_conflict_bit_table ();
     870      1057059 :       if (ira_conflicts_p)
     871              :         {
     872      1057059 :           ira_object_t obj;
     873      1057059 :           ira_object_iterator oi;
     874              : 
     875      1057059 :           build_conflicts ();
     876      1057059 :           ira_traverse_loop_tree (true, ira_loop_tree_root, add_copies, NULL);
     877              :           /* We need finished conflict table for the subsequent call.  */
     878      1057059 :           if (flag_ira_region == IRA_REGION_ALL
     879      1057059 :               || flag_ira_region == IRA_REGION_MIXED)
     880      1010507 :             propagate_copies ();
     881              : 
     882              :           /* Now we can free memory for the conflict table (see function
     883              :              build_object_conflicts for details).  */
     884     27897265 :           FOR_EACH_OBJECT (obj, oi)
     885              :             {
     886     25783147 :               if (OBJECT_CONFLICT_ARRAY (obj) != conflicts[OBJECT_CONFLICT_ID (obj)])
     887      5019937 :                 ira_free (conflicts[OBJECT_CONFLICT_ID (obj)]);
     888              :             }
     889      1057059 :           ira_free (conflicts);
     890              :         }
     891              :     }
     892      1504950 :   base = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH);
     893      1504950 :   if (! targetm.class_likely_spilled_p (base))
     894      1504950 :     CLEAR_HARD_REG_SET (temp_hard_reg_set);
     895              :   else
     896            0 :     temp_hard_reg_set = reg_class_contents[base] & ~ira_no_alloc_regs;
     897     38438235 :   FOR_EACH_ALLOCNO (a, ai)
     898              :     {
     899     36933285 :       int i, n = ALLOCNO_NUM_OBJECTS (a);
     900              : 
     901     75187808 :       for (i = 0; i < n; i++)
     902              :         {
     903     38254523 :           ira_object_t obj = ALLOCNO_OBJECT (a, i);
     904     38254523 :           rtx allocno_reg = regno_reg_rtx [ALLOCNO_REGNO (a)];
     905              : 
     906              :           /* For debugging purposes don't put user defined variables in
     907              :              callee-clobbered registers.  However, do allow parameters
     908              :              in callee-clobbered registers to improve debugging.  This
     909              :              is a bit of a fragile hack.  */
     910     38254523 :           if (optimize == 0
     911     12471376 :               && REG_USERVAR_P (allocno_reg)
     912     38265458 :               && ! reg_is_parm_p (allocno_reg))
     913              :             {
     914        10796 :               HARD_REG_SET new_conflict_regs = crtl->abi->full_reg_clobbers ();
     915        43184 :               OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
     916        10796 :               OBJECT_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
     917              :             }
     918              : 
     919     38254523 :           if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
     920              :             {
     921      4034494 :               HARD_REG_SET new_conflict_regs = ira_need_caller_save_regs (a);
     922      4034494 :               if (flag_caller_saves)
     923      7243818 :                 new_conflict_regs &= (~savable_regs | temp_hard_reg_set);
     924     16137976 :               OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
     925      4034494 :               OBJECT_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
     926              :             }
     927              : 
     928              :           /* Now we deal with paradoxical subreg cases where certain registers
     929              :              cannot be accessed in the widest mode.  */
     930     38254523 :           machine_mode outer_mode = ALLOCNO_WMODE (a);
     931     38254523 :           machine_mode inner_mode = ALLOCNO_MODE (a);
     932     38254523 :           if (paradoxical_subreg_p (outer_mode, inner_mode))
     933              :             {
     934       646767 :               enum reg_class aclass = ALLOCNO_CLASS (a);
     935      7226336 :               for (int j = ira_class_hard_regs_num[aclass] - 1; j >= 0; --j)
     936              :                 {
     937      6579569 :                    int inner_regno = ira_class_hard_regs[aclass][j];
     938      6579569 :                    int outer_regno = simplify_subreg_regno (inner_regno,
     939              :                                                             inner_mode, 0,
     940              :                                                             outer_mode);
     941      6579569 :                    if (outer_regno < 0
     942      6579569 :                        || !in_hard_reg_set_p (reg_class_contents[aclass],
     943              :                                               outer_mode, outer_regno))
     944              :                      {
     945         3218 :                        SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
     946              :                                          inner_regno);
     947         3218 :                        SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj),
     948              :                                          inner_regno);
     949              :                      }
     950              :                 }
     951              :             }
     952              :         }
     953              :     }
     954      1504950 :   if (optimize && ira_conflicts_p
     955      1057059 :       && internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
     956           39 :     print_conflicts (ira_dump_file, false);
     957      1504950 : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.