LCOV - code coverage report
Current view: top level - gcc - ira-conflicts.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.8 % 445 422
Test Date: 2024-04-20 14:03:02 Functions: 88.9 % 18 16
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-2024 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                 :   220820932 : record_object_conflict (ira_object_t obj1, ira_object_t obj2)
      62                 :             : {
      63                 :   220820932 :   ira_allocno_t a1 = OBJECT_ALLOCNO (obj1);
      64                 :   220820932 :   ira_allocno_t a2 = OBJECT_ALLOCNO (obj2);
      65                 :   220820932 :   int w1 = OBJECT_SUBWORD (obj1);
      66                 :   220820932 :   int w2 = OBJECT_SUBWORD (obj2);
      67                 :   220820932 :   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                 :   220820932 :   if (w1 == w2 && w1 > 0)
      74                 :             :     {
      75                 :     1213392 :       obj1 = ALLOCNO_OBJECT (a1, 0);
      76                 :     1213392 :       obj2 = ALLOCNO_OBJECT (a2, 0);
      77                 :             :     }
      78                 :   220820932 :   id1 = OBJECT_CONFLICT_ID (obj1);
      79                 :   220820932 :   id2 = OBJECT_CONFLICT_ID (obj2);
      80                 :             : 
      81                 :   220820932 :   SET_MINMAX_SET_BIT (conflicts[id1], id2, OBJECT_MIN (obj1),
      82                 :             :                       OBJECT_MAX (obj1));
      83                 :   220820932 :   SET_MINMAX_SET_BIT (conflicts[id2], id1, OBJECT_MIN (obj2),
      84                 :             :                       OBJECT_MAX (obj2));
      85                 :   220820932 : }
      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                 :      987683 : build_conflict_bit_table (void)
      92                 :             : {
      93                 :      987683 :   int i;
      94                 :      987683 :   unsigned int j;
      95                 :      987683 :   enum reg_class aclass;
      96                 :      987683 :   int object_set_words, allocated_words_num, conflict_bit_vec_words_num;
      97                 :      987683 :   live_range_t r;
      98                 :      987683 :   ira_allocno_t allocno;
      99                 :      987683 :   ira_allocno_iterator ai;
     100                 :      987683 :   sparseset objects_live;
     101                 :      987683 :   ira_object_t obj;
     102                 :      987683 :   ira_allocno_object_iterator aoi;
     103                 :             : 
     104                 :      987683 :   allocated_words_num = 0;
     105                 :    26836823 :   FOR_EACH_ALLOCNO (allocno, ai)
     106                 :    51192160 :     FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
     107                 :             :       {
     108                 :    25343020 :         if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
     109                 :     1250637 :           continue;
     110                 :    24092383 :         conflict_bit_vec_words_num
     111                 :    24092383 :           = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
     112                 :             :              / IRA_INT_BITS);
     113                 :    24092383 :         allocated_words_num += conflict_bit_vec_words_num;
     114                 :    24092383 :         if ((uint64_t) allocated_words_num * sizeof (IRA_INT_TYPE)
     115                 :    24092383 :             > (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                 :     1975366 :   conflicts = (IRA_INT_TYPE **) ira_allocate (sizeof (IRA_INT_TYPE *)
     127                 :      987683 :                                               * ira_objects_num);
     128                 :      987683 :   allocated_words_num = 0;
     129                 :    26836823 :   FOR_EACH_ALLOCNO (allocno, ai)
     130                 :    51192160 :     FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
     131                 :             :       {
     132                 :    25343020 :         int id = OBJECT_CONFLICT_ID (obj);
     133                 :    25343020 :         if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
     134                 :             :           {
     135                 :     1250637 :             conflicts[id] = NULL;
     136                 :     1250637 :             continue;
     137                 :             :           }
     138                 :    24092383 :         conflict_bit_vec_words_num
     139                 :    24092383 :           = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
     140                 :             :              / IRA_INT_BITS);
     141                 :    24092383 :         allocated_words_num += conflict_bit_vec_words_num;
     142                 :    24092383 :         conflicts[id]
     143                 :    48184766 :           = (IRA_INT_TYPE *) ira_allocate (sizeof (IRA_INT_TYPE)
     144                 :    24092383 :                                            * conflict_bit_vec_words_num);
     145                 :    24092383 :         memset (conflicts[id], 0,
     146                 :             :                 sizeof (IRA_INT_TYPE) * conflict_bit_vec_words_num);
     147                 :             :       }
     148                 :             : 
     149                 :      987683 :   object_set_words = (ira_objects_num + IRA_INT_BITS - 1) / IRA_INT_BITS;
     150                 :      987683 :   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                 :      987683 :   objects_live = sparseset_alloc (ira_objects_num);
     160                 :    31086594 :   for (i = 0; i < ira_max_point; i++)
     161                 :             :     {
     162                 :    56441308 :       for (r = ira_start_point_ranges[i]; r != NULL; r = r->start_next)
     163                 :             :         {
     164                 :    26342397 :           ira_object_t obj = r->object;
     165                 :    26342397 :           ira_allocno_t allocno = OBJECT_ALLOCNO (obj);
     166                 :    26342397 :           int id = OBJECT_CONFLICT_ID (obj);
     167                 :             : 
     168                 :    26342397 :           gcc_assert (id < ira_objects_num);
     169                 :             : 
     170                 :    26342397 :           aclass = ALLOCNO_CLASS (allocno);
     171                 :   528912922 :           EXECUTE_IF_SET_IN_SPARSESET (objects_live, j)
     172                 :             :             {
     173                 :   281221137 :               ira_object_t live_obj = ira_object_id_map[j];
     174                 :   281221137 :               ira_allocno_t live_a = OBJECT_ALLOCNO (live_obj);
     175                 :   281221137 :               enum reg_class live_aclass = ALLOCNO_CLASS (live_a);
     176                 :             : 
     177                 :   281221137 :               if (ira_reg_classes_intersect_p[aclass][live_aclass]
     178                 :             :                   /* Don't set up conflict for the allocno with itself.  */
     179                 :   221349388 :                   && live_a != allocno)
     180                 :             :                 {
     181                 :   220820932 :                   record_object_conflict (obj, live_obj);
     182                 :             :                 }
     183                 :             :             }
     184                 :    26342397 :           sparseset_set_bit (objects_live, id);
     185                 :             :         }
     186                 :             : 
     187                 :    56441308 :       for (r = ira_finish_point_ranges[i]; r != NULL; r = r->finish_next)
     188                 :    26342397 :         sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (r->object));
     189                 :             :     }
     190                 :      987683 :   sparseset_free (objects_live);
     191                 :      987683 :   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                 :     8713690 : 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                 :     8713690 :   ira_object_t obj1 = ALLOCNO_OBJECT (a1, 0);
     204                 :     8713690 :   ira_object_t obj2 = ALLOCNO_OBJECT (a2, 0);
     205                 :             : 
     206                 :     8713690 :   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                 :    25663020 : go_through_subreg (rtx x, int *offset)
     218                 :             : {
     219                 :    25663020 :   rtx reg;
     220                 :             : 
     221                 :    25663020 :   *offset = 0;
     222                 :    25663020 :   if (REG_P (x))
     223                 :             :     return x;
     224                 :     1026635 :   ira_assert (GET_CODE (x) == SUBREG);
     225                 :     1026635 :   reg = SUBREG_REG (x);
     226                 :     1026635 :   ira_assert (REG_P (reg));
     227                 :     1026635 :   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                 :     1026635 :   else if (!can_div_trunc_p (SUBREG_BYTE (x),
     231                 :     1026635 :                              REGMODE_NATURAL_SIZE (GET_MODE (x)), offset))
     232                 :             :     /* Checked by validate_subreg.  We must know at compile time which
     233                 :             :        inner hard registers are being accessed.  */
     234                 :             :     gcc_unreachable ();
     235                 :             :   return reg;
     236                 :             : }
     237                 :             : 
     238                 :             : /* Return the recomputed frequency for this shuffle copy or its similar
     239                 :             :    case, since it's not for a real move insn, make it smaller.  */
     240                 :             : 
     241                 :             : static int
     242                 :    10573271 : get_freq_for_shuffle_copy (int freq)
     243                 :             : {
     244                 :     9053055 :   return freq < 8 ? 1 : freq / 8;
     245                 :             : }
     246                 :             : 
     247                 :             : /* Process registers REG1 and REG2 in move INSN with execution
     248                 :             :    frequency FREQ.  The function also processes the registers in a
     249                 :             :    potential move insn (INSN == NULL in this case) with frequency
     250                 :             :    FREQ.  The function can modify hard register costs of the
     251                 :             :    corresponding allocnos or create a copy involving the corresponding
     252                 :             :    allocnos.  The function does nothing if the both registers are hard
     253                 :             :    registers.  When nothing is changed, the function returns FALSE.
     254                 :             :    SINGLE_INPUT_OP_HAS_CSTR_P is only meaningful when constraint_p
     255                 :             :    is true, see function ira_get_dup_out_num for its meaning.  */
     256                 :             : static bool
     257                 :    12831510 : process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p, rtx_insn *insn,
     258                 :             :                        int freq, bool single_input_op_has_cstr_p = true)
     259                 :             : {
     260                 :    12831510 :   int allocno_preferenced_hard_regno, index, offset1, offset2;
     261                 :    12831510 :   int cost, conflict_cost, move_cost;
     262                 :    12831510 :   bool only_regs_p;
     263                 :    12831510 :   ira_allocno_t a;
     264                 :    12831510 :   reg_class_t rclass, aclass;
     265                 :    12831510 :   machine_mode mode;
     266                 :    12831510 :   ira_copy_t cp;
     267                 :             : 
     268                 :    12831510 :   gcc_assert (REG_SUBREG_P (reg1) && REG_SUBREG_P (reg2));
     269                 :    12831510 :   only_regs_p = REG_P (reg1) && REG_P (reg2);
     270                 :    12831510 :   reg1 = go_through_subreg (reg1, &offset1);
     271                 :    12831510 :   reg2 = go_through_subreg (reg2, &offset2);
     272                 :             :   /* Set up hard regno preferenced by allocno.  If allocno gets the
     273                 :             :      hard regno the copy (or potential move) insn will be removed.  */
     274                 :    12831510 :   if (HARD_REGISTER_P (reg1))
     275                 :             :     {
     276                 :     2852065 :       if (HARD_REGISTER_P (reg2))
     277                 :             :         return false;
     278                 :     2852065 :       allocno_preferenced_hard_regno = REGNO (reg1) + offset1 - offset2;
     279                 :     2852065 :       a = ira_curr_regno_allocno_map[REGNO (reg2)];
     280                 :             :     }
     281                 :     9979445 :   else if (HARD_REGISTER_P (reg2))
     282                 :             :     {
     283                 :     3098947 :       allocno_preferenced_hard_regno = REGNO (reg2) + offset2 - offset1;
     284                 :     3098947 :       a = ira_curr_regno_allocno_map[REGNO (reg1)];
     285                 :             :     }
     286                 :             :   else
     287                 :             :     {
     288                 :     6880498 :       ira_allocno_t a1 = ira_curr_regno_allocno_map[REGNO (reg1)];
     289                 :     6880498 :       ira_allocno_t a2 = ira_curr_regno_allocno_map[REGNO (reg2)];
     290                 :             : 
     291                 :     6880498 :       if (!allocnos_conflict_for_copy_p (a1, a2)
     292                 :     6458365 :           && offset1 == offset2
     293                 :     6880498 :           && ordered_p (GET_MODE_PRECISION (ALLOCNO_MODE (a1)),
     294                 :     6374464 :                         GET_MODE_PRECISION (ALLOCNO_MODE (a2))))
     295                 :             :         {
     296                 :     6374464 :           cp = ira_add_allocno_copy (a1, a2, freq, constraint_p, insn,
     297                 :             :                                      ira_curr_loop_tree_node);
     298                 :     6374464 :           bitmap_set_bit (ira_curr_loop_tree_node->local_copies, cp->num);
     299                 :     6374464 :           return true;
     300                 :             :         }
     301                 :             :       else
     302                 :             :         return false;
     303                 :             :     }
     304                 :             : 
     305                 :     5951012 :   if (! IN_RANGE (allocno_preferenced_hard_regno,
     306                 :             :                   0, FIRST_PSEUDO_REGISTER - 1))
     307                 :             :     /* Cannot be tied.  */
     308                 :             :     return false;
     309                 :     5951012 :   rclass = REGNO_REG_CLASS (allocno_preferenced_hard_regno);
     310                 :     5951012 :   mode = ALLOCNO_MODE (a);
     311                 :     5951012 :   aclass = ALLOCNO_CLASS (a);
     312                 :     5951012 :   if (only_regs_p && insn != NULL_RTX
     313                 :     5891658 :       && reg_class_size[rclass] <= ira_reg_class_max_nregs [rclass][mode])
     314                 :             :     /* It is already taken into account in ira-costs.cc.  */
     315                 :             :     return false;
     316                 :      356099 :   index = ira_class_hard_reg_index[aclass][allocno_preferenced_hard_regno];
     317                 :      356099 :   if (index < 0)
     318                 :             :     /* Cannot be tied.  It is not in the allocno class.  */
     319                 :             :     return false;
     320                 :      342783 :   ira_init_register_move_cost_if_necessary (mode);
     321                 :      342783 :   if (HARD_REGISTER_P (reg1))
     322                 :      154277 :     move_cost = ira_register_move_cost[mode][aclass][rclass];
     323                 :             :   else
     324                 :      188506 :     move_cost = ira_register_move_cost[mode][rclass][aclass];
     325                 :             : 
     326                 :      342783 :   if (!single_input_op_has_cstr_p)
     327                 :             :     {
     328                 :             :       /* When this is a constraint copy and the matching constraint
     329                 :             :          doesn't only exist for this given operand but also for some
     330                 :             :          other operand(s), it means saving the possible move cost does
     331                 :             :          NOT need to require reg1 and reg2 to use the same hardware
     332                 :             :          register, so this hardware preference isn't required to be
     333                 :             :          fixed.  To avoid it to over prefer this hardware register,
     334                 :             :          and over disparage this hardware register on conflicted
     335                 :             :          objects, we need some cost tweaking here, similar to what
     336                 :             :          we do for shuffle copy.  */
     337                 :           0 :       gcc_assert (constraint_p);
     338                 :           0 :       int reduced_freq = get_freq_for_shuffle_copy (freq);
     339                 :           0 :       if (HARD_REGISTER_P (reg1))
     340                 :             :         /* For reg2 = opcode(reg1, reg3 ...), assume that reg3 is a
     341                 :             :            pseudo register which has matching constraint on reg2,
     342                 :             :            even if reg2 isn't assigned by reg1, it's still possible
     343                 :             :            not to have register moves if reg2 and reg3 use the same
     344                 :             :            hardware register.  So to avoid the allocation to over
     345                 :             :            prefer reg1, we can just take it as a shuffle copy.  */
     346                 :           0 :         cost = conflict_cost = move_cost * reduced_freq;
     347                 :             :       else
     348                 :             :         {
     349                 :             :           /* For reg1 = opcode(reg2, reg3 ...), assume that reg3 is a
     350                 :             :              pseudo register which has matching constraint on reg2,
     351                 :             :              to save the register move, it's better to assign reg1
     352                 :             :              to either of reg2 and reg3 (or one of other pseudos like
     353                 :             :              reg3), it's reasonable to use freq for the cost.  But
     354                 :             :              for conflict_cost, since reg2 and reg3 conflicts with
     355                 :             :              each other, both of them has the chance to be assigned
     356                 :             :              by reg1, assume reg3 has one copy which also conflicts
     357                 :             :              with reg2, we shouldn't make it less preferred on reg1
     358                 :             :              since reg3 has the same chance to be assigned by reg1.
     359                 :             :              So it adjusts the conflic_cost to make it same as what
     360                 :             :              we use for shuffle copy.  */
     361                 :           0 :           cost = move_cost * freq;
     362                 :           0 :           conflict_cost = move_cost * reduced_freq;
     363                 :             :         }
     364                 :             :     }
     365                 :             :   else
     366                 :      342783 :     cost = conflict_cost = move_cost * freq;
     367                 :             : 
     368                 :      390734 :   do
     369                 :             :     {
     370                 :      390734 :       ira_allocate_and_set_costs
     371                 :      390734 :         (&ALLOCNO_HARD_REG_COSTS (a), aclass,
     372                 :             :          ALLOCNO_CLASS_COST (a));
     373                 :      390734 :       ira_allocate_and_set_costs
     374                 :      390734 :         (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), aclass, 0);
     375                 :      390734 :       ALLOCNO_HARD_REG_COSTS (a)[index] -= cost;
     376                 :      390734 :       ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index] -= conflict_cost;
     377                 :      390734 :       if (ALLOCNO_HARD_REG_COSTS (a)[index] < ALLOCNO_CLASS_COST (a))
     378                 :      364440 :         ALLOCNO_CLASS_COST (a) = ALLOCNO_HARD_REG_COSTS (a)[index];
     379                 :      390734 :       ira_add_allocno_pref (a, allocno_preferenced_hard_regno, freq);
     380                 :      390734 :       a = ira_parent_or_cap_allocno (a);
     381                 :             :     }
     382                 :      390734 :   while (a != NULL);
     383                 :             :   return true;
     384                 :             : }
     385                 :             : 
     386                 :             : /* Return true if output operand OUTPUT and input operand INPUT of
     387                 :             :    INSN can use the same register class for at least one alternative.
     388                 :             :    INSN is already described in recog_data and recog_op_alt.  */
     389                 :             : static bool
     390                 :     2358824 : can_use_same_reg_p (rtx_insn *insn, int output, int input)
     391                 :             : {
     392                 :     2358824 :   alternative_mask preferred = get_preferred_alternatives (insn);
     393                 :     3476252 :   for (int nalt = 0; nalt < recog_data.n_alternatives; nalt++)
     394                 :             :     {
     395                 :     3262288 :       if (!TEST_BIT (preferred, nalt))
     396                 :      738393 :         continue;
     397                 :             : 
     398                 :     2523895 :       const operand_alternative *op_alt
     399                 :     2523895 :         = &recog_op_alt[nalt * recog_data.n_operands];
     400                 :     2523895 :       if (op_alt[input].matches == output)
     401                 :             :         return true;
     402                 :             : 
     403                 :     1578937 :       if (op_alt[output].earlyclobber)
     404                 :       59433 :         continue;
     405                 :             : 
     406                 :     1519504 :       if (ira_reg_class_intersect[op_alt[input].cl][op_alt[output].cl]
     407                 :             :           != NO_REGS)
     408                 :             :         return true;
     409                 :             :     }
     410                 :             :   return false;
     411                 :             : }
     412                 :             : 
     413                 :             : /* Process all of the output registers of the current insn (INSN) which
     414                 :             :    are not bound (BOUND_P) and the input register REG (its operand number
     415                 :             :    OP_NUM) which dies in the insn as if there were a move insn between
     416                 :             :    them with frequency FREQ.  */
     417                 :             : static void
     418                 :    10573271 : process_reg_shuffles (rtx_insn *insn, rtx reg, int op_num, int freq,
     419                 :             :                       bool *bound_p)
     420                 :             : {
     421                 :    10573271 :   int i;
     422                 :    10573271 :   rtx another_reg;
     423                 :             : 
     424                 :    10573271 :   gcc_assert (REG_SUBREG_P (reg));
     425                 :    37803599 :   for (i = 0; i < recog_data.n_operands; i++)
     426                 :             :     {
     427                 :    27230328 :       another_reg = recog_data.operand[i];
     428                 :             : 
     429                 :    27230328 :       if (!REG_SUBREG_P (another_reg) || op_num == i
     430                 :     9169904 :           || recog_data.operand_type[i] != OP_OUT
     431                 :     5103024 :           || bound_p[i]
     432                 :    29564460 :           || (!can_use_same_reg_p (insn, i, op_num)
     433                 :      198041 :               && (recog_data.constraints[op_num][0] != '%'
     434                 :       13689 :                   || !can_use_same_reg_p (insn, i, op_num + 1))
     435                 :      189272 :               && (op_num == 0
     436                 :      189272 :                   || recog_data.constraints[op_num - 1][0] != '%'
     437                 :       11003 :                   || !can_use_same_reg_p (insn, i, op_num - 1))))
     438                 :    25085468 :         continue;
     439                 :             : 
     440                 :     2144860 :       process_regs_for_copy (reg, another_reg, false, NULL, freq);
     441                 :             :     }
     442                 :    10573271 : }
     443                 :             : 
     444                 :             : /* Process INSN and create allocno copies if necessary.  For example,
     445                 :             :    it might be because INSN is a pseudo-register move or INSN is two
     446                 :             :    operand insn.  */
     447                 :             : static void
     448                 :    55393787 : add_insn_allocno_copies (rtx_insn *insn)
     449                 :             : {
     450                 :    55393787 :   rtx set, operand, dup;
     451                 :    55393787 :   bool bound_p[MAX_RECOG_OPERANDS];
     452                 :    55393787 :   int i, n, freq;
     453                 :    55393787 :   alternative_mask alts;
     454                 :             : 
     455                 :    55393787 :   freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
     456                 :    46257348 :   if (freq == 0)
     457                 :     7189466 :     freq = 1;
     458                 :    55393787 :   if ((set = single_set (insn)) != NULL_RTX
     459                 :    51687108 :       && REG_SUBREG_P (SET_DEST (set)) && REG_SUBREG_P (SET_SRC (set))
     460                 :    10468704 :       && ! side_effects_p (set)
     461                 :    65862491 :       && find_reg_note (insn, REG_DEAD,
     462                 :    10468704 :                         REG_P (SET_SRC (set))
     463                 :             :                         ? SET_SRC (set)
     464                 :             :                         : SUBREG_REG (SET_SRC (set))) != NULL_RTX)
     465                 :             :     {
     466                 :     8432197 :       process_regs_for_copy (SET_SRC (set), SET_DEST (set),
     467                 :             :                              false, insn, freq);
     468                 :    45548084 :       return;
     469                 :             :     }
     470                 :             :   /* Fast check of possibility of constraint or shuffle copies.  If
     471                 :             :      there are no dead registers, there will be no such copies.  */
     472                 :    46961590 :   if (! find_reg_note (insn, REG_DEAD, NULL_RTX))
     473                 :             :     return;
     474                 :    18277900 :   alts = ira_setup_alts (insn);
     475                 :    79163291 :   for (i = 0; i < recog_data.n_operands; i++)
     476                 :    42607491 :     bound_p[i] = false;
     477                 :    60885391 :   for (i = 0; i < recog_data.n_operands; i++)
     478                 :             :     {
     479                 :    42607491 :       operand = recog_data.operand[i];
     480                 :    42607491 :       if (! REG_SUBREG_P (operand))
     481                 :    23848599 :         continue;
     482                 :    18758892 :       bool single_input_op_has_cstr_p;
     483                 :    18758892 :       if ((n = ira_get_dup_out_num (i, alts, single_input_op_has_cstr_p)) >= 0)
     484                 :             :         {
     485                 :     2779678 :           bound_p[n] = true;
     486                 :     2779678 :           dup = recog_data.operand[n];
     487                 :      151348 :           if (REG_SUBREG_P (dup)
     488                 :     5546393 :               && find_reg_note (insn, REG_DEAD,
     489                 :     2766715 :                                 REG_P (operand)
     490                 :             :                                 ? operand
     491                 :             :                                 : SUBREG_REG (operand)) != NULL_RTX)
     492                 :     2254453 :             process_regs_for_copy (operand, dup, true, NULL, freq,
     493                 :             :                                    single_input_op_has_cstr_p);
     494                 :             :         }
     495                 :             :     }
     496                 :    60885391 :   for (i = 0; i < recog_data.n_operands; i++)
     497                 :             :     {
     498                 :    42607491 :       operand = recog_data.operand[i];
     499                 :    24657997 :       if (REG_SUBREG_P (operand)
     500                 :    43416889 :           && find_reg_note (insn, REG_DEAD,
     501                 :             :                             REG_P (operand)
     502                 :             :                             ? operand : SUBREG_REG (operand)) != NULL_RTX)
     503                 :             :         {
     504                 :             :           /* If an operand dies, prefer its hard register for the output
     505                 :             :              operands by decreasing the hard register cost or creating
     506                 :             :              the corresponding allocno copies.  The cost will not
     507                 :             :              correspond to a real move insn cost, so make the frequency
     508                 :             :              smaller.  */
     509                 :    10573271 :           int new_freq = get_freq_for_shuffle_copy (freq);
     510                 :    10573271 :           process_reg_shuffles (insn, operand, i, new_freq, bound_p);
     511                 :             :         }
     512                 :             :     }
     513                 :             : }
     514                 :             : 
     515                 :             : /* Add copies originated from BB given by LOOP_TREE_NODE.  */
     516                 :             : static void
     517                 :    11069096 : add_copies (ira_loop_tree_node_t loop_tree_node)
     518                 :             : {
     519                 :    11069096 :   basic_block bb;
     520                 :    11069096 :   rtx_insn *insn;
     521                 :             : 
     522                 :    11069096 :   bb = loop_tree_node->bb;
     523                 :    11069096 :   if (bb == NULL)
     524                 :             :     return;
     525                 :   122871228 :   FOR_BB_INSNS (bb, insn)
     526                 :   112939251 :     if (NONDEBUG_INSN_P (insn))
     527                 :    55393787 :       add_insn_allocno_copies (insn);
     528                 :             : }
     529                 :             : 
     530                 :             : /* Propagate copies the corresponding allocnos on upper loop tree
     531                 :             :    level.  */
     532                 :             : static void
     533                 :      946182 : propagate_copies (void)
     534                 :             : {
     535                 :      946182 :   ira_copy_t cp;
     536                 :      946182 :   ira_copy_iterator ci;
     537                 :      946182 :   ira_allocno_t a1, a2, parent_a1, parent_a2;
     538                 :             : 
     539                 :     8941832 :   FOR_EACH_COPY (cp, ci)
     540                 :             :     {
     541                 :     7995650 :       a1 = cp->first;
     542                 :     7995650 :       a2 = cp->second;
     543                 :     7995650 :       if (ALLOCNO_LOOP_TREE_NODE (a1) == ira_loop_tree_root)
     544                 :     6162458 :         continue;
     545                 :     1833192 :       ira_assert ((ALLOCNO_LOOP_TREE_NODE (a2) != ira_loop_tree_root));
     546                 :     1833192 :       parent_a1 = ira_parent_or_cap_allocno (a1);
     547                 :     1833192 :       parent_a2 = ira_parent_or_cap_allocno (a2);
     548                 :     1833192 :       ira_assert (parent_a1 != NULL && parent_a2 != NULL);
     549                 :     1833192 :       if (! allocnos_conflict_for_copy_p (parent_a1, parent_a2))
     550                 :     1833106 :         ira_add_allocno_copy (parent_a1, parent_a2, cp->freq,
     551                 :     1833106 :                               cp->constraint_p, cp->insn, cp->loop_tree_node);
     552                 :             :     }
     553                 :      946182 : }
     554                 :             : 
     555                 :             : /* Array used to collect all conflict allocnos for given allocno.  */
     556                 :             : static ira_object_t *collected_conflict_objects;
     557                 :             : 
     558                 :             : /* Build conflict vectors or bit conflict vectors (whatever is more
     559                 :             :    profitable) for object OBJ from the conflict table.  */
     560                 :             : static void
     561                 :    25343020 : build_object_conflicts (ira_object_t obj)
     562                 :             : {
     563                 :    25343020 :   int i, px, parent_num;
     564                 :    25343020 :   ira_allocno_t parent_a, another_parent_a;
     565                 :    25343020 :   ira_object_t parent_obj;
     566                 :    25343020 :   ira_allocno_t a = OBJECT_ALLOCNO (obj);
     567                 :    25343020 :   IRA_INT_TYPE *object_conflicts;
     568                 :    25343020 :   minmax_set_iterator asi;
     569                 :    25343020 :   int parent_min, parent_max ATTRIBUTE_UNUSED;
     570                 :             : 
     571                 :    25343020 :   object_conflicts = conflicts[OBJECT_CONFLICT_ID (obj)];
     572                 :    25343020 :   px = 0;
     573                 :   675423198 :   FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
     574                 :             :                               OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
     575                 :             :     {
     576                 :   624737158 :       ira_object_t another_obj = ira_object_id_map[i];
     577                 :   624737158 :       ira_allocno_t another_a = OBJECT_ALLOCNO (obj);
     578                 :             : 
     579                 :   624737158 :       ira_assert (ira_reg_classes_intersect_p
     580                 :             :                   [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
     581                 :   624737158 :       collected_conflict_objects[px++] = another_obj;
     582                 :             :     }
     583                 :    25343020 :   if (ira_conflict_vector_profitable_p (obj, px))
     584                 :             :     {
     585                 :     4919568 :       ira_object_t *vec;
     586                 :     4919568 :       ira_allocate_conflict_vec (obj, px);
     587                 :     4919568 :       vec = OBJECT_CONFLICT_VEC (obj);
     588                 :     4919568 :       memcpy (vec, collected_conflict_objects, sizeof (ira_object_t) * px);
     589                 :     4919568 :       vec[px] = NULL;
     590                 :     4919568 :       OBJECT_NUM_CONFLICTS (obj) = px;
     591                 :             :     }
     592                 :             :   else
     593                 :             :     {
     594                 :    20423452 :       int conflict_bit_vec_words_num;
     595                 :             : 
     596                 :    20423452 :       OBJECT_CONFLICT_ARRAY (obj) = object_conflicts;
     597                 :    20423452 :       if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
     598                 :             :         conflict_bit_vec_words_num = 0;
     599                 :             :       else
     600                 :    19172815 :         conflict_bit_vec_words_num
     601                 :    19172815 :           = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
     602                 :             :              / IRA_INT_BITS);
     603                 :    20423452 :       OBJECT_CONFLICT_ARRAY_SIZE (obj)
     604                 :    20423452 :         = conflict_bit_vec_words_num * sizeof (IRA_INT_TYPE);
     605                 :             :     }
     606                 :             : 
     607                 :    25343020 :   parent_a = ira_parent_or_cap_allocno (a);
     608                 :    25343020 :   if (parent_a == NULL)
     609                 :    18809243 :     return;
     610                 :     6533777 :   ira_assert (ALLOCNO_CLASS (a) == ALLOCNO_CLASS (parent_a));
     611                 :     6533777 :   ira_assert (ALLOCNO_NUM_OBJECTS (a) == ALLOCNO_NUM_OBJECTS (parent_a));
     612                 :     6533777 :   parent_obj = ALLOCNO_OBJECT (parent_a, OBJECT_SUBWORD (obj));
     613                 :     6533777 :   parent_num = OBJECT_CONFLICT_ID (parent_obj);
     614                 :     6533777 :   parent_min = OBJECT_MIN (parent_obj);
     615                 :     6533777 :   parent_max = OBJECT_MAX (parent_obj);
     616                 :   377490536 :   FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
     617                 :             :                               OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
     618                 :             :     {
     619                 :   364422982 :       ira_object_t another_obj = ira_object_id_map[i];
     620                 :   364422982 :       ira_allocno_t another_a = OBJECT_ALLOCNO (another_obj);
     621                 :   364422982 :       int another_word = OBJECT_SUBWORD (another_obj);
     622                 :             : 
     623                 :   364422982 :       ira_assert (ira_reg_classes_intersect_p
     624                 :             :                   [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
     625                 :             : 
     626                 :   364422982 :       another_parent_a = ira_parent_or_cap_allocno (another_a);
     627                 :   364422982 :       if (another_parent_a == NULL)
     628                 :           0 :         continue;
     629                 :   364422982 :       ira_assert (ALLOCNO_NUM (another_parent_a) >= 0);
     630                 :   364422982 :       ira_assert (ALLOCNO_CLASS (another_a)
     631                 :             :                   == ALLOCNO_CLASS (another_parent_a));
     632                 :   364422982 :       ira_assert (ALLOCNO_NUM_OBJECTS (another_a)
     633                 :             :                   == ALLOCNO_NUM_OBJECTS (another_parent_a));
     634                 :   364422982 :       SET_MINMAX_SET_BIT (conflicts[parent_num],
     635                 :             :                           OBJECT_CONFLICT_ID (ALLOCNO_OBJECT (another_parent_a,
     636                 :             :                                                               another_word)),
     637                 :             :                           parent_min, parent_max);
     638                 :             :     }
     639                 :             : }
     640                 :             : 
     641                 :             : /* Build conflict vectors or bit conflict vectors (whatever is more
     642                 :             :    profitable) of all allocnos from the conflict table.  */
     643                 :             : static void
     644                 :      987683 : build_conflicts (void)
     645                 :             : {
     646                 :      987683 :   int i;
     647                 :      987683 :   ira_allocno_t a, cap;
     648                 :             : 
     649                 :      987683 :   collected_conflict_objects
     650                 :     1975366 :     = (ira_object_t *) ira_allocate (sizeof (ira_object_t)
     651                 :      987683 :                                           * ira_objects_num);
     652                 :    47850537 :   for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
     653                 :    46862854 :     for (a = ira_regno_allocno_map[i];
     654                 :    68078211 :          a != NULL;
     655                 :    21215357 :          a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
     656                 :             :       {
     657                 :    21215357 :         int j, nregs = ALLOCNO_NUM_OBJECTS (a);
     658                 :    42866660 :         for (j = 0; j < nregs; j++)
     659                 :             :           {
     660                 :    21651303 :             ira_object_t obj = ALLOCNO_OBJECT (a, j);
     661                 :    21651303 :             build_object_conflicts (obj);
     662                 :    25343020 :             for (cap = ALLOCNO_CAP (a); cap != NULL; cap = ALLOCNO_CAP (cap))
     663                 :             :               {
     664                 :     3691717 :                 ira_object_t cap_obj = ALLOCNO_OBJECT (cap, j);
     665                 :     3691717 :                 gcc_assert (ALLOCNO_NUM_OBJECTS (cap) == ALLOCNO_NUM_OBJECTS (a));
     666                 :     3691717 :                 build_object_conflicts (cap_obj);
     667                 :             :               }
     668                 :             :           }
     669                 :             :       }
     670                 :      987683 :   ira_free (collected_conflict_objects);
     671                 :      987683 : }
     672                 :             : 
     673                 :             : 
     674                 :             : 
     675                 :             : /* Print hard reg set SET with TITLE to FILE.  */
     676                 :             : static void
     677                 :         974 : print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set)
     678                 :             : {
     679                 :         974 :   int i, start, end;
     680                 :             : 
     681                 :         974 :   fputs (title, file);
     682                 :       90582 :   for (start = end = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     683                 :             :     {
     684                 :       89608 :       bool reg_included = TEST_HARD_REG_BIT (set, i);
     685                 :             : 
     686                 :       89608 :       if (reg_included)
     687                 :             :         {
     688                 :        1062 :           if (start == -1)
     689                 :         618 :             start = i;
     690                 :             :           end = i;
     691                 :             :         }
     692                 :       89608 :       if (start >= 0 && (!reg_included || i == FIRST_PSEUDO_REGISTER - 1))
     693                 :             :         {
     694                 :         618 :           if (start == end)
     695                 :         198 :             fprintf (file, " %d", start);
     696                 :         420 :           else if (start == end + 1)
     697                 :           0 :             fprintf (file, " %d %d", start, end);
     698                 :             :           else
     699                 :         420 :             fprintf (file, " %d-%d", start, end);
     700                 :             :           start = -1;
     701                 :             :         }
     702                 :             :     }
     703                 :         974 :   putc ('\n', file);
     704                 :         974 : }
     705                 :             : 
     706                 :             : static void
     707                 :         527 : print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
     708                 :             : {
     709                 :         527 :   HARD_REG_SET conflicting_hard_regs;
     710                 :         527 :   basic_block bb;
     711                 :         527 :   int n, i;
     712                 :             : 
     713                 :         527 :   if (reg_p)
     714                 :           0 :     fprintf (file, ";; r%d", ALLOCNO_REGNO (a));
     715                 :             :   else
     716                 :             :     {
     717                 :         527 :       fprintf (file, ";; a%d(r%d,", ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
     718                 :         527 :       if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
     719                 :           0 :         fprintf (file, "b%d", bb->index);
     720                 :             :       else
     721                 :         527 :         fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
     722                 :         527 :       putc (')', file);
     723                 :             :     }
     724                 :             : 
     725                 :         527 :   fputs (" conflicts:", file);
     726                 :         527 :   n = ALLOCNO_NUM_OBJECTS (a);
     727                 :        1054 :   for (i = 0; i < n; i++)
     728                 :             :     {
     729                 :         527 :       ira_object_t obj = ALLOCNO_OBJECT (a, i);
     730                 :         527 :       ira_object_t conflict_obj;
     731                 :         527 :       ira_object_conflict_iterator oci;
     732                 :             : 
     733                 :         527 :       if (OBJECT_CONFLICT_ARRAY (obj) == NULL)
     734                 :             :         {
     735                 :          40 :           fprintf (file, "\n;;     total conflict hard regs:\n");
     736                 :          40 :           fprintf (file, ";;     conflict hard regs:\n\n");
     737                 :          40 :           continue;
     738                 :             :         }
     739                 :             : 
     740                 :         487 :       if (n > 1)
     741                 :           0 :         fprintf (file, "\n;;   subobject %d:", i);
     742                 :        4077 :       FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
     743                 :             :         {
     744                 :        3590 :           ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
     745                 :        3590 :           if (reg_p)
     746                 :           0 :             fprintf (file, " r%d,", ALLOCNO_REGNO (conflict_a));
     747                 :             :           else
     748                 :             :             {
     749                 :        3590 :               fprintf (file, " a%d(r%d", ALLOCNO_NUM (conflict_a),
     750                 :             :                        ALLOCNO_REGNO (conflict_a));
     751                 :        3590 :               if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
     752                 :           0 :                 fprintf (file, ",w%d", OBJECT_SUBWORD (conflict_obj));
     753                 :        3590 :               if ((bb = ALLOCNO_LOOP_TREE_NODE (conflict_a)->bb) != NULL)
     754                 :           0 :                 fprintf (file, ",b%d", bb->index);
     755                 :             :               else
     756                 :        3590 :                 fprintf (file, ",l%d",
     757                 :             :                          ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop_num);
     758                 :        3590 :               putc (')', file);
     759                 :             :             }
     760                 :             :         }
     761                 :         487 :       conflicting_hard_regs = (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)
     762                 :         487 :                                & ~ira_no_alloc_regs
     763                 :         487 :                                & reg_class_contents[ALLOCNO_CLASS (a)]);
     764                 :         487 :       print_hard_reg_set (file, "\n;;     total conflict hard regs:",
     765                 :             :                           conflicting_hard_regs);
     766                 :             : 
     767                 :         487 :       conflicting_hard_regs = (OBJECT_CONFLICT_HARD_REGS (obj)
     768                 :         487 :                                & ~ira_no_alloc_regs
     769                 :         487 :                                & reg_class_contents[ALLOCNO_CLASS (a)]);
     770                 :         487 :       print_hard_reg_set (file, ";;     conflict hard regs:",
     771                 :             :                           conflicting_hard_regs);
     772                 :         487 :       putc ('\n', file);
     773                 :             :     }
     774                 :             : 
     775                 :         527 : }
     776                 :             : 
     777                 :             : /* Print information about allocno or only regno (if REG_P) conflicts
     778                 :             :    to FILE.  */
     779                 :             : static void
     780                 :          39 : print_conflicts (FILE *file, bool reg_p)
     781                 :             : {
     782                 :          39 :   ira_allocno_t a;
     783                 :          39 :   ira_allocno_iterator ai;
     784                 :             : 
     785                 :         566 :   FOR_EACH_ALLOCNO (a, ai)
     786                 :         527 :     print_allocno_conflicts (file, reg_p, a);
     787                 :          39 :   putc ('\n', file);
     788                 :          39 : }
     789                 :             : 
     790                 :             : /* Print information about allocno or only regno (if REG_P) conflicts
     791                 :             :    to stderr.  */
     792                 :             : void
     793                 :           0 : ira_debug_conflicts (bool reg_p)
     794                 :             : {
     795                 :           0 :   print_conflicts (stderr, reg_p);
     796                 :           0 : }
     797                 :             : 
     798                 :             : 
     799                 :             : 
     800                 :             : /* Entry function which builds allocno conflicts and allocno copies
     801                 :             :    and accumulate some allocno info on upper level regions.  */
     802                 :             : void
     803                 :     1426764 : ira_build_conflicts (void)
     804                 :             : {
     805                 :     1426764 :   enum reg_class base;
     806                 :     1426764 :   ira_allocno_t a;
     807                 :     1426764 :   ira_allocno_iterator ai;
     808                 :     1426764 :   HARD_REG_SET temp_hard_reg_set;
     809                 :             : 
     810                 :     1426764 :   if (ira_conflicts_p)
     811                 :             :     {
     812                 :      987683 :       ira_conflicts_p = build_conflict_bit_table ();
     813                 :      987683 :       if (ira_conflicts_p)
     814                 :             :         {
     815                 :      987683 :           ira_object_t obj;
     816                 :      987683 :           ira_object_iterator oi;
     817                 :             : 
     818                 :      987683 :           build_conflicts ();
     819                 :      987683 :           ira_traverse_loop_tree (true, ira_loop_tree_root, add_copies, NULL);
     820                 :             :           /* We need finished conflict table for the subsequent call.  */
     821                 :      987683 :           if (flag_ira_region == IRA_REGION_ALL
     822                 :      987683 :               || flag_ira_region == IRA_REGION_MIXED)
     823                 :      946182 :             propagate_copies ();
     824                 :             : 
     825                 :             :           /* Now we can free memory for the conflict table (see function
     826                 :             :              build_object_conflicts for details).  */
     827                 :    27318386 :           FOR_EACH_OBJECT (obj, oi)
     828                 :             :             {
     829                 :    25343020 :               if (OBJECT_CONFLICT_ARRAY (obj) != conflicts[OBJECT_CONFLICT_ID (obj)])
     830                 :     4919568 :                 ira_free (conflicts[OBJECT_CONFLICT_ID (obj)]);
     831                 :             :             }
     832                 :      987683 :           ira_free (conflicts);
     833                 :             :         }
     834                 :             :     }
     835                 :     1426764 :   base = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH);
     836                 :     1426764 :   if (! targetm.class_likely_spilled_p (base))
     837                 :     1426764 :     CLEAR_HARD_REG_SET (temp_hard_reg_set);
     838                 :             :   else
     839                 :           0 :     temp_hard_reg_set = reg_class_contents[base] & ~ira_no_alloc_regs;
     840                 :    37549769 :   FOR_EACH_ALLOCNO (a, ai)
     841                 :             :     {
     842                 :    36123005 :       int i, n = ALLOCNO_NUM_OBJECTS (a);
     843                 :             : 
     844                 :    73540293 :       for (i = 0; i < n; i++)
     845                 :             :         {
     846                 :    37417288 :           ira_object_t obj = ALLOCNO_OBJECT (a, i);
     847                 :    37417288 :           rtx allocno_reg = regno_reg_rtx [ALLOCNO_REGNO (a)];
     848                 :             : 
     849                 :             :           /* For debugging purposes don't put user defined variables in
     850                 :             :              callee-clobbered registers.  However, do allow parameters
     851                 :             :              in callee-clobbered registers to improve debugging.  This
     852                 :             :              is a bit of a fragile hack.  */
     853                 :    37417288 :           if (optimize == 0
     854                 :    12074268 :               && REG_USERVAR_P (allocno_reg)
     855                 :    37428092 :               && ! reg_is_parm_p (allocno_reg))
     856                 :             :             {
     857                 :       10760 :               HARD_REG_SET new_conflict_regs = crtl->abi->full_reg_clobbers ();
     858                 :       10760 :               OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
     859                 :       32280 :               OBJECT_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
     860                 :             :             }
     861                 :             : 
     862                 :    37417288 :           if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
     863                 :             :             {
     864                 :     3682284 :               HARD_REG_SET new_conflict_regs = ira_need_caller_save_regs (a);
     865                 :     3682284 :               if (flag_caller_saves)
     866                 :     6585490 :                 new_conflict_regs &= (~savable_regs | temp_hard_reg_set);
     867                 :     3682284 :               OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
     868                 :    11046852 :               OBJECT_CONFLICT_HARD_REGS (obj) |= new_conflict_regs;
     869                 :             :             }
     870                 :             : 
     871                 :             :           /* Now we deal with paradoxical subreg cases where certain registers
     872                 :             :              cannot be accessed in the widest mode.  */
     873                 :    37417288 :           machine_mode outer_mode = ALLOCNO_WMODE (a);
     874                 :    37417288 :           machine_mode inner_mode = ALLOCNO_MODE (a);
     875                 :    37417288 :           if (paradoxical_subreg_p (outer_mode, inner_mode))
     876                 :             :             {
     877                 :      424076 :               enum reg_class aclass = ALLOCNO_CLASS (a);
     878                 :     4770561 :               for (int j = ira_class_hard_regs_num[aclass] - 1; j >= 0; --j)
     879                 :             :                 {
     880                 :     4346485 :                    int inner_regno = ira_class_hard_regs[aclass][j];
     881                 :     8692970 :                    int outer_regno = simplify_subreg_regno (inner_regno,
     882                 :     4346485 :                                                             inner_mode, 0,
     883                 :             :                                                             outer_mode);
     884                 :     4346485 :                    if (outer_regno < 0
     885                 :     4346485 :                        || !in_hard_reg_set_p (reg_class_contents[aclass],
     886                 :             :                                               outer_mode, outer_regno))
     887                 :             :                      {
     888                 :        3225 :                        SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
     889                 :             :                                          inner_regno);
     890                 :        3225 :                        SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj),
     891                 :             :                                          inner_regno);
     892                 :             :                      }
     893                 :             :                 }
     894                 :             :             }
     895                 :             :         }
     896                 :             :     }
     897                 :     1426764 :   if (optimize && ira_conflicts_p
     898                 :      987683 :       && internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
     899                 :          39 :     print_conflicts (ira_dump_file, false);
     900                 :     1426764 : }
        

Generated by: LCOV version 2.1-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.