LCOV - code coverage report
Current view: top level - gcc - ira-conflicts.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 409 428 95.6 %
Date: 2020-05-30 12:51:24 Functions: 16 17 94.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* IRA conflict builder.
       2                 :            :    Copyright (C) 2006-2020 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                 :  174900000 : record_object_conflict (ira_object_t obj1, ira_object_t obj2)
      62                 :            : {
      63                 :  174900000 :   ira_allocno_t a1 = OBJECT_ALLOCNO (obj1);
      64                 :  174900000 :   ira_allocno_t a2 = OBJECT_ALLOCNO (obj2);
      65                 :  174900000 :   int w1 = OBJECT_SUBWORD (obj1);
      66                 :  174900000 :   int w2 = OBJECT_SUBWORD (obj2);
      67                 :  174900000 :   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                 :  174900000 :   if (w1 == w2 && w1 > 0)
      74                 :            :     {
      75                 :    1259030 :       obj1 = ALLOCNO_OBJECT (a1, 0);
      76                 :    1259030 :       obj2 = ALLOCNO_OBJECT (a2, 0);
      77                 :            :     }
      78                 :  174900000 :   id1 = OBJECT_CONFLICT_ID (obj1);
      79                 :  174900000 :   id2 = OBJECT_CONFLICT_ID (obj2);
      80                 :            : 
      81                 :  174900000 :   SET_MINMAX_SET_BIT (conflicts[id1], id2, OBJECT_MIN (obj1),
      82                 :            :                       OBJECT_MAX (obj1));
      83                 :  174900000 :   SET_MINMAX_SET_BIT (conflicts[id2], id1, OBJECT_MIN (obj2),
      84                 :            :                       OBJECT_MAX (obj2));
      85                 :  174900000 : }
      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                 :     687986 : build_conflict_bit_table (void)
      92                 :            : {
      93                 :     687986 :   int i;
      94                 :     687986 :   unsigned int j;
      95                 :     687986 :   enum reg_class aclass;
      96                 :     687986 :   int object_set_words, allocated_words_num, conflict_bit_vec_words_num;
      97                 :     687986 :   live_range_t r;
      98                 :     687986 :   ira_allocno_t allocno;
      99                 :     687986 :   ira_allocno_iterator ai;
     100                 :     687986 :   sparseset objects_live;
     101                 :     687986 :   ira_object_t obj;
     102                 :     687986 :   ira_allocno_object_iterator aoi;
     103                 :            : 
     104                 :     687986 :   allocated_words_num = 0;
     105                 :     687986 :   FOR_EACH_ALLOCNO (allocno, ai)
     106                 :   34915000 :     FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
     107                 :            :       {
     108                 :   17248300 :         if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
     109                 :     841690 :           continue;
     110                 :   16406600 :         conflict_bit_vec_words_num
     111                 :   16406600 :           = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
     112                 :            :              / IRA_INT_BITS);
     113                 :   16406600 :         allocated_words_num += conflict_bit_vec_words_num;
     114                 :   16406600 :         if ((uint64_t) allocated_words_num * sizeof (IRA_INT_TYPE)
     115                 :   16406600 :             > (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
     119                 :          0 :                 (ira_dump_file,
     120                 :            :                  "+++Conflict table will be too big(>%dMB) -- don't use it\n",
     121                 :            :                  param_ira_max_conflict_table_size);
     122                 :          0 :             return false;
     123                 :            :           }
     124                 :            :       }
     125                 :            : 
     126                 :    1375970 :   conflicts = (IRA_INT_TYPE **) ira_allocate (sizeof (IRA_INT_TYPE *)
     127                 :     687986 :                                               * ira_objects_num);
     128                 :     687986 :   allocated_words_num = 0;
     129                 :     687986 :   FOR_EACH_ALLOCNO (allocno, ai)
     130                 :   34915000 :     FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
     131                 :            :       {
     132                 :   17248300 :         int id = OBJECT_CONFLICT_ID (obj);
     133                 :   17248300 :         if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
     134                 :            :           {
     135                 :     841690 :             conflicts[id] = NULL;
     136                 :     841690 :             continue;
     137                 :            :           }
     138                 :   16406600 :         conflict_bit_vec_words_num
     139                 :   16406600 :           = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
     140                 :            :              / IRA_INT_BITS);
     141                 :   16406600 :         allocated_words_num += conflict_bit_vec_words_num;
     142                 :   16406600 :         conflicts[id]
     143                 :   32813200 :           = (IRA_INT_TYPE *) ira_allocate (sizeof (IRA_INT_TYPE)
     144                 :   16406600 :                                            * conflict_bit_vec_words_num);
     145                 :   16406600 :         memset (conflicts[id], 0,
     146                 :            :                 sizeof (IRA_INT_TYPE) * conflict_bit_vec_words_num);
     147                 :            :       }
     148                 :            : 
     149                 :     687986 :   object_set_words = (ira_objects_num + IRA_INT_BITS - 1) / IRA_INT_BITS;
     150                 :     687986 :   if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
     151                 :         39 :     fprintf
     152                 :         39 :       (ira_dump_file,
     153                 :            :        "+++Allocating %ld bytes for conflict table (uncompressed size %ld)\n",
     154                 :         39 :        (long) allocated_words_num * sizeof (IRA_INT_TYPE),
     155                 :         39 :        (long) object_set_words * ira_objects_num * sizeof (IRA_INT_TYPE));
     156                 :            : 
     157                 :     687986 :   objects_live = sparseset_alloc (ira_objects_num);
     158                 :   20135700 :   for (i = 0; i < ira_max_point; i++)
     159                 :            :     {
     160                 :   36885200 :       for (r = ira_start_point_ranges[i]; r != NULL; r = r->start_next)
     161                 :            :         {
     162                 :   17437500 :           ira_object_t obj = r->object;
     163                 :   17437500 :           ira_allocno_t allocno = OBJECT_ALLOCNO (obj);
     164                 :   17437500 :           int id = OBJECT_CONFLICT_ID (obj);
     165                 :            : 
     166                 :   17437500 :           gcc_assert (id < ira_objects_num);
     167                 :            : 
     168                 :   17437500 :           aclass = ALLOCNO_CLASS (allocno);
     169                 :  412790000 :           EXECUTE_IF_SET_IN_SPARSESET (objects_live, j)
     170                 :            :             {
     171                 :  220158000 :               ira_object_t live_obj = ira_object_id_map[j];
     172                 :  220158000 :               ira_allocno_t live_a = OBJECT_ALLOCNO (live_obj);
     173                 :  220158000 :               enum reg_class live_aclass = ALLOCNO_CLASS (live_a);
     174                 :            : 
     175                 :  220158000 :               if (ira_reg_classes_intersect_p[aclass][live_aclass]
     176                 :            :                   /* Don't set up conflict for the allocno with itself.  */
     177                 :  175195000 :                   && live_a != allocno)
     178                 :            :                 {
     179                 :  174900000 :                   record_object_conflict (obj, live_obj);
     180                 :            :                 }
     181                 :            :             }
     182                 :   17437500 :           sparseset_set_bit (objects_live, id);
     183                 :            :         }
     184                 :            : 
     185                 :   36885200 :       for (r = ira_finish_point_ranges[i]; r != NULL; r = r->finish_next)
     186                 :   17437500 :         sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (r->object));
     187                 :            :     }
     188                 :     687986 :   sparseset_free (objects_live);
     189                 :     687986 :   return true;
     190                 :            : }
     191                 :            : 
     192                 :            : /* Return true iff allocnos A1 and A2 cannot be allocated to the same
     193                 :            :    register due to conflicts.  */
     194                 :            : 
     195                 :            : static bool
     196                 :    5628590 : allocnos_conflict_for_copy_p (ira_allocno_t a1, ira_allocno_t a2)
     197                 :            : {
     198                 :            :   /* Due to the fact that we canonicalize conflicts (see
     199                 :            :      record_object_conflict), we only need to test for conflicts of
     200                 :            :      the lowest order words.  */
     201                 :    5628590 :   ira_object_t obj1 = ALLOCNO_OBJECT (a1, 0);
     202                 :    5628590 :   ira_object_t obj2 = ALLOCNO_OBJECT (a2, 0);
     203                 :            : 
     204                 :    5628590 :   return OBJECTS_CONFLICT_P (obj1, obj2);
     205                 :            : }
     206                 :            : 
     207                 :            : /* Check that X is REG or SUBREG of REG.  */
     208                 :            : #define REG_SUBREG_P(x)                                                 \
     209                 :            :    (REG_P (x) || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))))
     210                 :            : 
     211                 :            : /* Return X if X is a REG, otherwise it should be SUBREG of REG and
     212                 :            :    the function returns the reg in this case.  *OFFSET will be set to
     213                 :            :    0 in the first case or the regno offset in the first case.  */
     214                 :            : static rtx
     215                 :   16230800 : go_through_subreg (rtx x, int *offset)
     216                 :            : {
     217                 :   16230800 :   rtx reg;
     218                 :            : 
     219                 :   16230800 :   *offset = 0;
     220                 :   16230800 :   if (REG_P (x))
     221                 :            :     return x;
     222                 :     467017 :   ira_assert (GET_CODE (x) == SUBREG);
     223                 :     467017 :   reg = SUBREG_REG (x);
     224                 :     467017 :   ira_assert (REG_P (reg));
     225                 :     467017 :   if (REGNO (reg) < FIRST_PSEUDO_REGISTER)
     226                 :          0 :     *offset = subreg_regno_offset (REGNO (reg), GET_MODE (reg),
     227                 :          0 :                                    SUBREG_BYTE (x), GET_MODE (x));
     228                 :     467017 :   else if (!can_div_trunc_p (SUBREG_BYTE (x),
     229                 :     467017 :                              REGMODE_NATURAL_SIZE (GET_MODE (x)), offset))
     230                 :            :     /* Checked by validate_subreg.  We must know at compile time which
     231                 :            :        inner hard registers are being accessed.  */
     232                 :            :     gcc_unreachable ();
     233                 :            :   return reg;
     234                 :            : }
     235                 :            : 
     236                 :            : /* Process registers REG1 and REG2 in move INSN with execution
     237                 :            :    frequency FREQ.  The function also processes the registers in a
     238                 :            :    potential move insn (INSN == NULL in this case) with frequency
     239                 :            :    FREQ.  The function can modify hard register costs of the
     240                 :            :    corresponding allocnos or create a copy involving the corresponding
     241                 :            :    allocnos.  The function does nothing if the both registers are hard
     242                 :            :    registers.  When nothing is changed, the function returns
     243                 :            :    FALSE.  */
     244                 :            : static bool
     245                 :    8115380 : process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
     246                 :            :                        rtx_insn *insn, int freq)
     247                 :            : {
     248                 :    8115380 :   int allocno_preferenced_hard_regno, cost, index, offset1, offset2;
     249                 :    8115380 :   bool only_regs_p;
     250                 :    8115380 :   ira_allocno_t a;
     251                 :    8115380 :   reg_class_t rclass, aclass;
     252                 :    8115380 :   machine_mode mode;
     253                 :    8115380 :   ira_copy_t cp;
     254                 :            : 
     255                 :    8115380 :   gcc_assert (REG_SUBREG_P (reg1) && REG_SUBREG_P (reg2));
     256                 :    8115380 :   only_regs_p = REG_P (reg1) && REG_P (reg2);
     257                 :    8115380 :   reg1 = go_through_subreg (reg1, &offset1);
     258                 :    8115380 :   reg2 = go_through_subreg (reg2, &offset2);
     259                 :            :   /* Set up hard regno preferenced by allocno.  If allocno gets the
     260                 :            :      hard regno the copy (or potential move) insn will be removed.  */
     261                 :    8115380 :   if (HARD_REGISTER_P (reg1))
     262                 :            :     {
     263                 :    1905270 :       if (HARD_REGISTER_P (reg2))
     264                 :            :         return false;
     265                 :    1905270 :       allocno_preferenced_hard_regno = REGNO (reg1) + offset1 - offset2;
     266                 :    1905270 :       a = ira_curr_regno_allocno_map[REGNO (reg2)];
     267                 :            :     }
     268                 :    6210110 :   else if (HARD_REGISTER_P (reg2))
     269                 :            :     {
     270                 :    1965070 :       allocno_preferenced_hard_regno = REGNO (reg2) + offset2 - offset1;
     271                 :    1965070 :       a = ira_curr_regno_allocno_map[REGNO (reg1)];
     272                 :            :     }
     273                 :            :   else
     274                 :            :     {
     275                 :    4245040 :       ira_allocno_t a1 = ira_curr_regno_allocno_map[REGNO (reg1)];
     276                 :    4245040 :       ira_allocno_t a2 = ira_curr_regno_allocno_map[REGNO (reg2)];
     277                 :            : 
     278                 :    4245040 :       if (!allocnos_conflict_for_copy_p (a1, a2) && offset1 == offset2)
     279                 :            :         {
     280                 :    3911990 :           cp = ira_add_allocno_copy (a1, a2, freq, constraint_p, insn,
     281                 :            :                                      ira_curr_loop_tree_node);
     282                 :    3911990 :           bitmap_set_bit (ira_curr_loop_tree_node->local_copies, cp->num);
     283                 :    3911990 :           return true;
     284                 :            :         }
     285                 :            :       else
     286                 :            :         return false;
     287                 :            :     }
     288                 :            : 
     289                 :    3870340 :   if (! IN_RANGE (allocno_preferenced_hard_regno,
     290                 :            :                   0, FIRST_PSEUDO_REGISTER - 1))
     291                 :            :     /* Cannot be tied.  */
     292                 :            :     return false;
     293                 :    3870340 :   rclass = REGNO_REG_CLASS (allocno_preferenced_hard_regno);
     294                 :    3870340 :   mode = ALLOCNO_MODE (a);
     295                 :    3870340 :   aclass = ALLOCNO_CLASS (a);
     296                 :    3870340 :   if (only_regs_p && insn != NULL_RTX
     297                 :    3823390 :       && reg_class_size[rclass] <= ira_reg_class_max_nregs [rclass][mode])
     298                 :            :     /* It is already taken into account in ira-costs.c.  */
     299                 :            :     return false;
     300                 :     196123 :   index = ira_class_hard_reg_index[aclass][allocno_preferenced_hard_regno];
     301                 :     196123 :   if (index < 0)
     302                 :            :     /* Cannot be tied.  It is not in the allocno class.  */
     303                 :            :     return false;
     304                 :     183600 :   ira_init_register_move_cost_if_necessary (mode);
     305                 :     183600 :   if (HARD_REGISTER_P (reg1))
     306                 :      82963 :     cost = ira_register_move_cost[mode][aclass][rclass] * freq;
     307                 :            :   else
     308                 :     100637 :     cost = ira_register_move_cost[mode][rclass][aclass] * freq;
     309                 :     228871 :   do
     310                 :            :     {
     311                 :     228871 :       ira_allocate_and_set_costs
     312                 :     228871 :         (&ALLOCNO_HARD_REG_COSTS (a), aclass,
     313                 :            :          ALLOCNO_CLASS_COST (a));
     314                 :     228871 :       ira_allocate_and_set_costs
     315                 :     228871 :         (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), aclass, 0);
     316                 :     228871 :       ALLOCNO_HARD_REG_COSTS (a)[index] -= cost;
     317                 :     228871 :       ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index] -= cost;
     318                 :     228871 :       if (ALLOCNO_HARD_REG_COSTS (a)[index] < ALLOCNO_CLASS_COST (a))
     319                 :     207363 :         ALLOCNO_CLASS_COST (a) = ALLOCNO_HARD_REG_COSTS (a)[index];
     320                 :     228871 :       ira_add_allocno_pref (a, allocno_preferenced_hard_regno, freq);
     321                 :     228871 :       a = ira_parent_or_cap_allocno (a);
     322                 :            :     }
     323                 :     228871 :   while (a != NULL);
     324                 :            :   return true;
     325                 :            : }
     326                 :            : 
     327                 :            : /* Return true if output operand OUTPUT and input operand INPUT of
     328                 :            :    INSN can use the same register class for at least one alternative.
     329                 :            :    INSN is already described in recog_data and recog_op_alt.  */
     330                 :            : static bool
     331                 :    1437300 : can_use_same_reg_p (rtx_insn *insn, int output, int input)
     332                 :            : {
     333                 :    1437300 :   alternative_mask preferred = get_preferred_alternatives (insn);
     334                 :    2000050 :   for (int nalt = 0; nalt < recog_data.n_alternatives; nalt++)
     335                 :            :     {
     336                 :    1876160 :       if (!TEST_BIT (preferred, nalt))
     337                 :     342548 :         continue;
     338                 :            : 
     339                 :    1533620 :       const operand_alternative *op_alt
     340                 :    1533620 :         = &recog_op_alt[nalt * recog_data.n_operands];
     341                 :    1533620 :       if (op_alt[input].matches == output)
     342                 :            :         return true;
     343                 :            : 
     344                 :     898068 :       if (ira_reg_class_intersect[op_alt[input].cl][op_alt[output].cl]
     345                 :            :           != NO_REGS)
     346                 :            :         return true;
     347                 :            :     }
     348                 :            :   return false;
     349                 :            : }
     350                 :            : 
     351                 :            : /* Process all of the output registers of the current insn (INSN) which
     352                 :            :    are not bound (BOUND_P) and the input register REG (its operand number
     353                 :            :    OP_NUM) which dies in the insn as if there were a move insn between
     354                 :            :    them with frequency FREQ.  */
     355                 :            : static void
     356                 :    6889340 : process_reg_shuffles (rtx_insn *insn, rtx reg, int op_num, int freq,
     357                 :            :                       bool *bound_p)
     358                 :            : {
     359                 :    6889340 :   int i;
     360                 :    6889340 :   rtx another_reg;
     361                 :            : 
     362                 :    6889340 :   gcc_assert (REG_SUBREG_P (reg));
     363                 :   24441700 :   for (i = 0; i < recog_data.n_operands; i++)
     364                 :            :     {
     365                 :   17552300 :       another_reg = recog_data.operand[i];
     366                 :            : 
     367                 :   17552300 :       if (!REG_SUBREG_P (another_reg) || op_num == i
     368                 :    5562220 :           || recog_data.operand_type[i] != OP_OUT
     369                 :    2998050 :           || bound_p[i]
     370                 :   18986400 :           || (!can_use_same_reg_p (insn, i, op_num)
     371                 :     123510 :               && (recog_data.constraints[op_num][0] != '%'
     372                 :       3060 :                   || !can_use_same_reg_p (insn, i, op_num + 1))
     373                 :     120643 :               && (op_num == 0
     374                 :     120643 :                   || recog_data.constraints[op_num - 1][0] != '%'
     375                 :        180 :                   || !can_use_same_reg_p (insn, i, op_num - 1))))
     376                 :   16238900 :         continue;
     377                 :            : 
     378                 :    1313420 :       process_regs_for_copy (reg, another_reg, false, NULL, freq);
     379                 :            :     }
     380                 :    6889340 : }
     381                 :            : 
     382                 :            : /* Process INSN and create allocno copies if necessary.  For example,
     383                 :            :    it might be because INSN is a pseudo-register move or INSN is two
     384                 :            :    operand insn.  */
     385                 :            : static void
     386                 :   38569500 : add_insn_allocno_copies (rtx_insn *insn)
     387                 :            : {
     388                 :   38569500 :   rtx set, operand, dup;
     389                 :   38569500 :   bool bound_p[MAX_RECOG_OPERANDS];
     390                 :   38569500 :   int i, n, freq;
     391                 :   38569500 :   alternative_mask alts;
     392                 :            : 
     393                 :   38569500 :   freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
     394                 :   32894000 :   if (freq == 0)
     395                 :          0 :     freq = 1;
     396                 :   38569500 :   if ((set = single_set (insn)) != NULL_RTX
     397                 :   35824600 :       && REG_SUBREG_P (SET_DEST (set)) && REG_SUBREG_P (SET_SRC (set))
     398                 :    6873860 :       && ! side_effects_p (set)
     399                 :   45443300 :       && find_reg_note (insn, REG_DEAD,
     400                 :    6873860 :                         REG_P (SET_SRC (set))
     401                 :            :                         ? SET_SRC (set)
     402                 :            :                         : SUBREG_REG (SET_SRC (set))) != NULL_RTX)
     403                 :            :     {
     404                 :    5523000 :       process_regs_for_copy (SET_SRC (set), SET_DEST (set),
     405                 :            :                              false, insn, freq);
     406                 :   31724100 :       return;
     407                 :            :     }
     408                 :            :   /* Fast check of possibility of constraint or shuffle copies.  If
     409                 :            :      there are no dead registers, there will be no such copies.  */
     410                 :   33046500 :   if (! find_reg_note (insn, REG_DEAD, NULL_RTX))
     411                 :            :     return;
     412                 :   12368400 :   alts = ira_setup_alts (insn);
     413                 :   40934500 :   for (i = 0; i < recog_data.n_operands; i++)
     414                 :   28566100 :     bound_p[i] = false;
     415                 :   40934500 :   for (i = 0; i < recog_data.n_operands; i++)
     416                 :            :     {
     417                 :   28566100 :       operand = recog_data.operand[i];
     418                 :   28566100 :       if (! REG_SUBREG_P (operand))
     419                 :   16560100 :         continue;
     420                 :   12006000 :       if ((n = ira_get_dup_out_num (i, alts)) >= 0)
     421                 :            :         {
     422                 :    1624010 :           bound_p[n] = true;
     423                 :    1624010 :           dup = recog_data.operand[n];
     424                 :     115321 :           if (REG_SUBREG_P (dup)
     425                 :    3167540 :               && find_reg_note (insn, REG_DEAD,
     426                 :    1543530 :                                 REG_P (operand)
     427                 :            :                                 ? operand
     428                 :            :                                 : SUBREG_REG (operand)) != NULL_RTX)
     429                 :    1278970 :             process_regs_for_copy (operand, dup, true, NULL,
     430                 :            :                                    freq);
     431                 :            :         }
     432                 :            :     }
     433                 :   40934500 :   for (i = 0; i < recog_data.n_operands; i++)
     434                 :            :     {
     435                 :   28566100 :       operand = recog_data.operand[i];
     436                 :   17011000 :       if (REG_SUBREG_P (operand)
     437                 :   29016900 :           && find_reg_note (insn, REG_DEAD,
     438                 :            :                             REG_P (operand)
     439                 :            :                             ? operand : SUBREG_REG (operand)) != NULL_RTX)
     440                 :            :         /* If an operand dies, prefer its hard register for the output
     441                 :            :            operands by decreasing the hard register cost or creating
     442                 :            :            the corresponding allocno copies.  The cost will not
     443                 :            :            correspond to a real move insn cost, so make the frequency
     444                 :            :            smaller.  */
     445                 :    6889340 :         process_reg_shuffles (insn, operand, i, freq < 8 ? 1 : freq / 8,
     446                 :            :                               bound_p);
     447                 :            :     }
     448                 :            : }
     449                 :            : 
     450                 :            : /* Add copies originated from BB given by LOOP_TREE_NODE.  */
     451                 :            : static void
     452                 :    7769920 : add_copies (ira_loop_tree_node_t loop_tree_node)
     453                 :            : {
     454                 :    7769920 :   basic_block bb;
     455                 :    7769920 :   rtx_insn *insn;
     456                 :            : 
     457                 :    7769920 :   bb = loop_tree_node->bb;
     458                 :    7769920 :   if (bb == NULL)
     459                 :            :     return;
     460                 :  164224000 :   FOR_BB_INSNS (bb, insn)
     461                 :   78623100 :     if (NONDEBUG_INSN_P (insn))
     462                 :   38569500 :       add_insn_allocno_copies (insn);
     463                 :            : }
     464                 :            : 
     465                 :            : /* Propagate copies the corresponding allocnos on upper loop tree
     466                 :            :    level.  */
     467                 :            : static void
     468                 :     660062 : propagate_copies (void)
     469                 :            : {
     470                 :     660062 :   ira_copy_t cp;
     471                 :     660062 :   ira_copy_iterator ci;
     472                 :     660062 :   ira_allocno_t a1, a2, parent_a1, parent_a2;
     473                 :            : 
     474                 :    5811670 :   FOR_EACH_COPY (cp, ci)
     475                 :            :     {
     476                 :    5151600 :       a1 = cp->first;
     477                 :    5151600 :       a2 = cp->second;
     478                 :    5151600 :       if (ALLOCNO_LOOP_TREE_NODE (a1) == ira_loop_tree_root)
     479                 :    3768050 :         continue;
     480                 :    1383560 :       ira_assert ((ALLOCNO_LOOP_TREE_NODE (a2) != ira_loop_tree_root));
     481                 :    1383560 :       parent_a1 = ira_parent_or_cap_allocno (a1);
     482                 :    1383560 :       parent_a2 = ira_parent_or_cap_allocno (a2);
     483                 :    1383560 :       ira_assert (parent_a1 != NULL && parent_a2 != NULL);
     484                 :    1383560 :       if (! allocnos_conflict_for_copy_p (parent_a1, parent_a2))
     485                 :    1383540 :         ira_add_allocno_copy (parent_a1, parent_a2, cp->freq,
     486                 :    1383540 :                               cp->constraint_p, cp->insn, cp->loop_tree_node);
     487                 :            :     }
     488                 :     660062 : }
     489                 :            : 
     490                 :            : /* Array used to collect all conflict allocnos for given allocno.  */
     491                 :            : static ira_object_t *collected_conflict_objects;
     492                 :            : 
     493                 :            : /* Build conflict vectors or bit conflict vectors (whatever is more
     494                 :            :    profitable) for object OBJ from the conflict table.  */
     495                 :            : static void
     496                 :   17248300 : build_object_conflicts (ira_object_t obj)
     497                 :            : {
     498                 :   17248300 :   int i, px, parent_num;
     499                 :   17248300 :   ira_allocno_t parent_a, another_parent_a;
     500                 :   17248300 :   ira_object_t parent_obj;
     501                 :   17248300 :   ira_allocno_t a = OBJECT_ALLOCNO (obj);
     502                 :   17248300 :   IRA_INT_TYPE *object_conflicts;
     503                 :   17248300 :   minmax_set_iterator asi;
     504                 :   17248300 :   int parent_min, parent_max ATTRIBUTE_UNUSED;
     505                 :            : 
     506                 :   17248300 :   object_conflicts = conflicts[OBJECT_CONFLICT_ID (obj)];
     507                 :   17248300 :   px = 0;
     508                 :  546260000 :   FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
     509                 :            :                               OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
     510                 :            :     {
     511                 :  511763000 :       ira_object_t another_obj = ira_object_id_map[i];
     512                 :  511763000 :       ira_allocno_t another_a = OBJECT_ALLOCNO (obj);
     513                 :            : 
     514                 :  511763000 :       ira_assert (ira_reg_classes_intersect_p
     515                 :            :                   [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
     516                 :  511763000 :       collected_conflict_objects[px++] = another_obj;
     517                 :            :     }
     518                 :   17248300 :   if (ira_conflict_vector_profitable_p (obj, px))
     519                 :            :     {
     520                 :    4453670 :       ira_object_t *vec;
     521                 :    4453670 :       ira_allocate_conflict_vec (obj, px);
     522                 :    4453670 :       vec = OBJECT_CONFLICT_VEC (obj);
     523                 :    4453670 :       memcpy (vec, collected_conflict_objects, sizeof (ira_object_t) * px);
     524                 :    4453670 :       vec[px] = NULL;
     525                 :    4453670 :       OBJECT_NUM_CONFLICTS (obj) = px;
     526                 :            :     }
     527                 :            :   else
     528                 :            :     {
     529                 :   12794600 :       int conflict_bit_vec_words_num;
     530                 :            : 
     531                 :   12794600 :       OBJECT_CONFLICT_ARRAY (obj) = object_conflicts;
     532                 :   12794600 :       if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
     533                 :            :         conflict_bit_vec_words_num = 0;
     534                 :            :       else
     535                 :   11952900 :         conflict_bit_vec_words_num
     536                 :   11952900 :           = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
     537                 :            :              / IRA_INT_BITS);
     538                 :   12794600 :       OBJECT_CONFLICT_ARRAY_SIZE (obj)
     539                 :   12794600 :         = conflict_bit_vec_words_num * sizeof (IRA_INT_TYPE);
     540                 :            :     }
     541                 :            : 
     542                 :   17248300 :   parent_a = ira_parent_or_cap_allocno (a);
     543                 :   17248300 :   if (parent_a == NULL)
     544                 :   12223700 :     return;
     545                 :    5024640 :   ira_assert (ALLOCNO_CLASS (a) == ALLOCNO_CLASS (parent_a));
     546                 :    5024640 :   ira_assert (ALLOCNO_NUM_OBJECTS (a) == ALLOCNO_NUM_OBJECTS (parent_a));
     547                 :    5024640 :   parent_obj = ALLOCNO_OBJECT (parent_a, OBJECT_SUBWORD (obj));
     548                 :    5024640 :   parent_num = OBJECT_CONFLICT_ID (parent_obj);
     549                 :    5024640 :   parent_min = OBJECT_MIN (parent_obj);
     550                 :    5024640 :   parent_max = OBJECT_MAX (parent_obj);
     551                 :  327487000 :   FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
     552                 :            :                               OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
     553                 :            :     {
     554                 :  317438000 :       ira_object_t another_obj = ira_object_id_map[i];
     555                 :  317438000 :       ira_allocno_t another_a = OBJECT_ALLOCNO (another_obj);
     556                 :  317438000 :       int another_word = OBJECT_SUBWORD (another_obj);
     557                 :            : 
     558                 :  317438000 :       ira_assert (ira_reg_classes_intersect_p
     559                 :            :                   [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
     560                 :            : 
     561                 :  317438000 :       another_parent_a = ira_parent_or_cap_allocno (another_a);
     562                 :  317438000 :       if (another_parent_a == NULL)
     563                 :          0 :         continue;
     564                 :  317438000 :       ira_assert (ALLOCNO_NUM (another_parent_a) >= 0);
     565                 :  317438000 :       ira_assert (ALLOCNO_CLASS (another_a)
     566                 :            :                   == ALLOCNO_CLASS (another_parent_a));
     567                 :  317438000 :       ira_assert (ALLOCNO_NUM_OBJECTS (another_a)
     568                 :            :                   == ALLOCNO_NUM_OBJECTS (another_parent_a));
     569                 :  317438000 :       SET_MINMAX_SET_BIT (conflicts[parent_num],
     570                 :            :                           OBJECT_CONFLICT_ID (ALLOCNO_OBJECT (another_parent_a,
     571                 :            :                                                               another_word)),
     572                 :            :                           parent_min, parent_max);
     573                 :            :     }
     574                 :            : }
     575                 :            : 
     576                 :            : /* Build conflict vectors or bit conflict vectors (whatever is more
     577                 :            :    profitable) of all allocnos from the conflict table.  */
     578                 :            : static void
     579                 :     687986 : build_conflicts (void)
     580                 :            : {
     581                 :     687986 :   int i;
     582                 :     687986 :   ira_allocno_t a, cap;
     583                 :            : 
     584                 :     687986 :   collected_conflict_objects
     585                 :    1375970 :     = (ira_object_t *) ira_allocate (sizeof (ira_object_t)
     586                 :     687986 :                                           * ira_objects_num);
     587                 :   32899500 :   for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
     588                 :   32211500 :     for (a = ira_regno_allocno_map[i];
     589                 :   46376200 :          a != NULL;
     590                 :   14164700 :          a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
     591                 :            :       {
     592                 :   14164700 :         int j, nregs = ALLOCNO_NUM_OBJECTS (a);
     593                 :   28578300 :         for (j = 0; j < nregs; j++)
     594                 :            :           {
     595                 :   14413600 :             ira_object_t obj = ALLOCNO_OBJECT (a, j);
     596                 :   14413600 :             build_object_conflicts (obj);
     597                 :   17248300 :             for (cap = ALLOCNO_CAP (a); cap != NULL; cap = ALLOCNO_CAP (cap))
     598                 :            :               {
     599                 :    2834680 :                 ira_object_t cap_obj = ALLOCNO_OBJECT (cap, j);
     600                 :    2834680 :                 gcc_assert (ALLOCNO_NUM_OBJECTS (cap) == ALLOCNO_NUM_OBJECTS (a));
     601                 :    2834680 :                 build_object_conflicts (cap_obj);
     602                 :            :               }
     603                 :            :           }
     604                 :            :       }
     605                 :     687986 :   ira_free (collected_conflict_objects);
     606                 :     687986 : }
     607                 :            : 
     608                 :            : 
     609                 :            : 
     610                 :            : /* Print hard reg set SET with TITLE to FILE.  */
     611                 :            : static void
     612                 :        982 : print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set)
     613                 :            : {
     614                 :        982 :   int i, start, end;
     615                 :            : 
     616                 :        982 :   fputs (title, file);
     617                 :      75614 :   for (start = end = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     618                 :            :     {
     619                 :      74632 :       bool reg_included = TEST_HARD_REG_BIT (set, i);
     620                 :            : 
     621                 :      74632 :       if (reg_included)
     622                 :            :         {
     623                 :       1090 :           if (start == -1)
     624                 :        634 :             start = i;
     625                 :            :           end = i;
     626                 :            :         }
     627                 :      74632 :       if (start >= 0 && (!reg_included || i == FIRST_PSEUDO_REGISTER - 1))
     628                 :            :         {
     629                 :        634 :           if (start == end)
     630                 :        202 :             fprintf (file, " %d", start);
     631                 :        432 :           else if (start == end + 1)
     632                 :          0 :             fprintf (file, " %d %d", start, end);
     633                 :            :           else
     634                 :        432 :             fprintf (file, " %d-%d", start, end);
     635                 :            :           start = -1;
     636                 :            :         }
     637                 :            :     }
     638                 :        982 :   putc ('\n', file);
     639                 :        982 : }
     640                 :            : 
     641                 :            : static void
     642                 :        531 : print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
     643                 :            : {
     644                 :        531 :   HARD_REG_SET conflicting_hard_regs;
     645                 :        531 :   basic_block bb;
     646                 :        531 :   int n, i;
     647                 :            : 
     648                 :        531 :   if (reg_p)
     649                 :          0 :     fprintf (file, ";; r%d", ALLOCNO_REGNO (a));
     650                 :            :   else
     651                 :            :     {
     652                 :        531 :       fprintf (file, ";; a%d(r%d,", ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
     653                 :        531 :       if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
     654                 :          0 :         fprintf (file, "b%d", bb->index);
     655                 :            :       else
     656                 :        531 :         fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
     657                 :        531 :       putc (')', file);
     658                 :            :     }
     659                 :            : 
     660                 :        531 :   fputs (" conflicts:", file);
     661                 :        531 :   n = ALLOCNO_NUM_OBJECTS (a);
     662                 :       1062 :   for (i = 0; i < n; i++)
     663                 :            :     {
     664                 :        531 :       ira_object_t obj = ALLOCNO_OBJECT (a, i);
     665                 :        531 :       ira_object_t conflict_obj;
     666                 :        531 :       ira_object_conflict_iterator oci;
     667                 :            : 
     668                 :        531 :       if (OBJECT_CONFLICT_ARRAY (obj) == NULL)
     669                 :            :         {
     670                 :         40 :           fprintf (file, "\n;;     total conflict hard regs:\n");
     671                 :         40 :           fprintf (file, ";;     conflict hard regs:\n\n");
     672                 :         40 :           continue;
     673                 :            :         }
     674                 :            : 
     675                 :        491 :       if (n > 1)
     676                 :          0 :         fprintf (file, "\n;;   subobject %d:", i);
     677                 :       4101 :       FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
     678                 :            :         {
     679                 :       3610 :           ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
     680                 :       3610 :           if (reg_p)
     681                 :          0 :             fprintf (file, " r%d,", ALLOCNO_REGNO (conflict_a));
     682                 :            :           else
     683                 :            :             {
     684                 :       3610 :               fprintf (file, " a%d(r%d", ALLOCNO_NUM (conflict_a),
     685                 :            :                        ALLOCNO_REGNO (conflict_a));
     686                 :       3610 :               if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
     687                 :          0 :                 fprintf (file, ",w%d", OBJECT_SUBWORD (conflict_obj));
     688                 :       3610 :               if ((bb = ALLOCNO_LOOP_TREE_NODE (conflict_a)->bb) != NULL)
     689                 :          0 :                 fprintf (file, ",b%d", bb->index);
     690                 :            :               else
     691                 :       3610 :                 fprintf (file, ",l%d",
     692                 :            :                          ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop_num);
     693                 :       3610 :               putc (')', file);
     694                 :            :             }
     695                 :            :         }
     696                 :        491 :       conflicting_hard_regs = (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)
     697                 :        982 :                                & ~ira_no_alloc_regs
     698                 :        491 :                                & reg_class_contents[ALLOCNO_CLASS (a)]);
     699                 :        491 :       print_hard_reg_set (file, "\n;;     total conflict hard regs:",
     700                 :            :                           conflicting_hard_regs);
     701                 :            : 
     702                 :        491 :       conflicting_hard_regs = (OBJECT_CONFLICT_HARD_REGS (obj)
     703                 :        982 :                                & ~ira_no_alloc_regs
     704                 :        491 :                                & reg_class_contents[ALLOCNO_CLASS (a)]);
     705                 :        491 :       print_hard_reg_set (file, ";;     conflict hard regs:",
     706                 :            :                           conflicting_hard_regs);
     707                 :        491 :       putc ('\n', file);
     708                 :            :     }
     709                 :            : 
     710                 :        531 : }
     711                 :            : 
     712                 :            : /* Print information about allocno or only regno (if REG_P) conflicts
     713                 :            :    to FILE.  */
     714                 :            : static void
     715                 :         39 : print_conflicts (FILE *file, bool reg_p)
     716                 :            : {
     717                 :         39 :   ira_allocno_t a;
     718                 :         39 :   ira_allocno_iterator ai;
     719                 :            : 
     720                 :        570 :   FOR_EACH_ALLOCNO (a, ai)
     721                 :        531 :     print_allocno_conflicts (file, reg_p, a);
     722                 :         39 :   putc ('\n', file);
     723                 :         39 : }
     724                 :            : 
     725                 :            : /* Print information about allocno or only regno (if REG_P) conflicts
     726                 :            :    to stderr.  */
     727                 :            : void
     728                 :          0 : ira_debug_conflicts (bool reg_p)
     729                 :            : {
     730                 :          0 :   print_conflicts (stderr, reg_p);
     731                 :          0 : }
     732                 :            : 
     733                 :            : 
     734                 :            : 
     735                 :            : /* Entry function which builds allocno conflicts and allocno copies
     736                 :            :    and accumulate some allocno info on upper level regions.  */
     737                 :            : void
     738                 :     960231 : ira_build_conflicts (void)
     739                 :            : {
     740                 :     960231 :   enum reg_class base;
     741                 :     960231 :   ira_allocno_t a;
     742                 :     960231 :   ira_allocno_iterator ai;
     743                 :     960231 :   HARD_REG_SET temp_hard_reg_set;
     744                 :            : 
     745                 :     960231 :   if (ira_conflicts_p)
     746                 :            :     {
     747                 :     687986 :       ira_conflicts_p = build_conflict_bit_table ();
     748                 :     687986 :       if (ira_conflicts_p)
     749                 :            :         {
     750                 :     687986 :           ira_object_t obj;
     751                 :     687986 :           ira_object_iterator oi;
     752                 :            : 
     753                 :     687986 :           build_conflicts ();
     754                 :     687986 :           ira_traverse_loop_tree (true, ira_loop_tree_root, add_copies, NULL);
     755                 :            :           /* We need finished conflict table for the subsequent call.  */
     756                 :     687986 :           if (flag_ira_region == IRA_REGION_ALL
     757                 :     687986 :               || flag_ira_region == IRA_REGION_MIXED)
     758                 :     660062 :             propagate_copies ();
     759                 :            : 
     760                 :            :           /* Now we can free memory for the conflict table (see function
     761                 :            :              build_object_conflicts for details).  */
     762                 :   17936300 :           FOR_EACH_OBJECT (obj, oi)
     763                 :            :             {
     764                 :   17248300 :               if (OBJECT_CONFLICT_ARRAY (obj) != conflicts[OBJECT_CONFLICT_ID (obj)])
     765                 :    4453670 :                 ira_free (conflicts[OBJECT_CONFLICT_ID (obj)]);
     766                 :            :             }
     767                 :     687986 :           ira_free (conflicts);
     768                 :            :         }
     769                 :            :     }
     770                 :     960231 :   base = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH);
     771                 :     960231 :   if (! targetm.class_likely_spilled_p (base))
     772                 :    2880690 :     CLEAR_HARD_REG_SET (temp_hard_reg_set);
     773                 :            :   else
     774                 :          0 :     temp_hard_reg_set = reg_class_contents[base] & ~ira_no_alloc_regs;
     775                 :   25162400 :   FOR_EACH_ALLOCNO (a, ai)
     776                 :            :     {
     777                 :   24202200 :       int i, n = ALLOCNO_NUM_OBJECTS (a);
     778                 :            : 
     779                 :   48971600 :       for (i = 0; i < n; i++)
     780                 :            :         {
     781                 :   24769400 :           ira_object_t obj = ALLOCNO_OBJECT (a, i);
     782                 :   24769400 :           rtx allocno_reg = regno_reg_rtx [ALLOCNO_REGNO (a)];
     783                 :            : 
     784                 :            :           /* For debugging purposes don't put user defined variables in
     785                 :            :              callee-clobbered registers.  However, do allow parameters
     786                 :            :              in callee-clobbered registers to improve debugging.  This
     787                 :            :              is a bit of a fragile hack.  */
     788                 :   24769400 :           if (optimize == 0
     789                 :    7521080 :               && REG_USERVAR_P (allocno_reg)
     790                 :   24771900 :               && ! reg_is_parm_p (allocno_reg))
     791                 :            :             {
     792                 :       2485 :               HARD_REG_SET new_conflict_regs = crtl->abi->full_reg_clobbers ();
     793                 :       2485 :               OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
     794                 :       7455 :               OBJECT_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
     795                 :            :             }
     796                 :            : 
     797                 :   24769400 :           if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
     798                 :            :             {
     799                 :    2905650 :               HARD_REG_SET new_conflict_regs = ira_need_caller_save_regs (a);
     800                 :    2905650 :               if (flag_caller_saves)
     801                 :   10676900 :                 new_conflict_regs &= (~savable_regs | temp_hard_reg_set);
     802                 :    2905650 :               OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
     803                 :    8716940 :               OBJECT_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
     804                 :            :             }
     805                 :            : 
     806                 :            :           /* Now we deal with paradoxical subreg cases where certain registers
     807                 :            :              cannot be accessed in the widest mode.  */
     808                 :   24769400 :           machine_mode outer_mode = ALLOCNO_WMODE (a);
     809                 :   24769400 :           machine_mode inner_mode = ALLOCNO_MODE (a);
     810                 :   24769400 :           if (paradoxical_subreg_p (outer_mode, inner_mode))
     811                 :            :             {
     812                 :     127168 :               enum reg_class aclass = ALLOCNO_CLASS (a);
     813                 :    1284240 :               for (int j = ira_class_hard_regs_num[aclass] - 1; j >= 0; --j)
     814                 :            :                 {
     815                 :    1157070 :                    int inner_regno = ira_class_hard_regs[aclass][j];
     816                 :    2314140 :                    int outer_regno = simplify_subreg_regno (inner_regno,
     817                 :    1157070 :                                                             inner_mode, 0,
     818                 :            :                                                             outer_mode);
     819                 :    1157070 :                    if (outer_regno < 0
     820                 :    1157070 :                        || !in_hard_reg_set_p (reg_class_contents[aclass],
     821                 :            :                                               outer_mode, outer_regno))
     822                 :            :                      {
     823                 :       7882 :                        SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
     824                 :            :                                          inner_regno);
     825                 :    1157070 :                        SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj),
     826                 :            :                                          inner_regno);
     827                 :            :                      }
     828                 :            :                 }
     829                 :            :             }
     830                 :            :         }
     831                 :            :     }
     832                 :     960231 :   if (optimize && ira_conflicts_p
     833                 :     687986 :       && internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
     834                 :         39 :     print_conflicts (ira_dump_file, false);
     835                 :     960231 : }

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.