LCOV - code coverage report
Current view: top level - gcc - ira-emit.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 647 694 93.2 %
Date: 2020-04-04 11:58:09 Functions: 24 31 77.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* Integrated Register Allocator.  Changing code and generating moves.
       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                 :            : /* When we have more one region, we need to change the original RTL
      22                 :            :    code after coloring.  Let us consider two allocnos representing the
      23                 :            :    same pseudo-register outside and inside a region respectively.
      24                 :            :    They can get different hard-registers.  The reload pass works on
      25                 :            :    pseudo registers basis and there is no way to say the reload that
      26                 :            :    pseudo could be in different registers and it is even more
      27                 :            :    difficult to say in what places of the code the pseudo should have
      28                 :            :    particular hard-registers.  So in this case IRA has to create and
      29                 :            :    use a new pseudo-register inside the region and adds code to move
      30                 :            :    allocno values on the region's borders.  This is done by the code
      31                 :            :    in this file.
      32                 :            : 
      33                 :            :    The code makes top-down traversal of the regions and generate new
      34                 :            :    pseudos and the move code on the region borders.  In some
      35                 :            :    complicated cases IRA can create a new pseudo used temporarily to
      36                 :            :    move allocno values when a swap of values stored in two
      37                 :            :    hard-registers is needed (e.g. two allocnos representing different
      38                 :            :    pseudos outside region got respectively hard registers 1 and 2 and
      39                 :            :    the corresponding allocnos inside the region got respectively hard
      40                 :            :    registers 2 and 1).  At this stage, the new pseudo is marked as
      41                 :            :    spilled.
      42                 :            : 
      43                 :            :    IRA still creates the pseudo-register and the moves on the region
      44                 :            :    borders even when the both corresponding allocnos were assigned to
      45                 :            :    the same hard-register.  It is done because, if the reload pass for
      46                 :            :    some reason spills a pseudo-register representing the original
      47                 :            :    pseudo outside or inside the region, the effect will be smaller
      48                 :            :    because another pseudo will still be in the hard-register.  In most
      49                 :            :    cases, this is better then spilling the original pseudo in its
      50                 :            :    whole live-range.  If reload does not change the allocation for the
      51                 :            :    two pseudo-registers, the trivial move will be removed by
      52                 :            :    post-reload optimizations.
      53                 :            : 
      54                 :            :    IRA does not generate a new pseudo and moves for the allocno values
      55                 :            :    if the both allocnos representing an original pseudo inside and
      56                 :            :    outside region assigned to the same hard register when the register
      57                 :            :    pressure in the region for the corresponding pressure class is less
      58                 :            :    than number of available hard registers for given pressure class.
      59                 :            : 
      60                 :            :    IRA also does some optimizations to remove redundant moves which is
      61                 :            :    transformed into stores by the reload pass on CFG edges
      62                 :            :    representing exits from the region.
      63                 :            : 
      64                 :            :    IRA tries to reduce duplication of code generated on CFG edges
      65                 :            :    which are enters and exits to/from regions by moving some code to
      66                 :            :    the edge sources or destinations when it is possible.  */
      67                 :            : 
      68                 :            : #include "config.h"
      69                 :            : #include "system.h"
      70                 :            : #include "coretypes.h"
      71                 :            : #include "backend.h"
      72                 :            : #include "rtl.h"
      73                 :            : #include "tree.h"
      74                 :            : #include "predict.h"
      75                 :            : #include "df.h"
      76                 :            : #include "insn-config.h"
      77                 :            : #include "regs.h"
      78                 :            : #include "memmodel.h"
      79                 :            : #include "ira.h"
      80                 :            : #include "ira-int.h"
      81                 :            : #include "cfgrtl.h"
      82                 :            : #include "cfgbuild.h"
      83                 :            : #include "expr.h"
      84                 :            : #include "reload.h"
      85                 :            : #include "cfgloop.h"
      86                 :            : 
      87                 :            : 
      88                 :            : /* Data used to emit live range split insns and to flattening IR.  */
      89                 :            : ira_emit_data_t ira_allocno_emit_data;
      90                 :            : 
      91                 :            : /* Definitions for vectors of pointers.  */
      92                 :            : typedef void *void_p;
      93                 :            : 
      94                 :            : /* Pointers to data allocated for allocnos being created during
      95                 :            :    emitting.  Usually there are quite few such allocnos because they
      96                 :            :    are created only for resolving loop in register shuffling.  */
      97                 :            : static vec<void_p> new_allocno_emit_data_vec;
      98                 :            : 
      99                 :            : /* Allocate and initiate the emit data.  */
     100                 :            : void
     101                 :     944096 : ira_initiate_emit_data (void)
     102                 :            : {
     103                 :     944096 :   ira_allocno_t a;
     104                 :     944096 :   ira_allocno_iterator ai;
     105                 :            : 
     106                 :     944096 :   ira_allocno_emit_data
     107                 :     944096 :     = (ira_emit_data_t) ira_allocate (ira_allocnos_num
     108                 :            :                                       * sizeof (struct ira_emit_data));
     109                 :     944096 :   memset (ira_allocno_emit_data, 0,
     110                 :     944096 :           ira_allocnos_num * sizeof (struct ira_emit_data));
     111                 :   23853700 :   FOR_EACH_ALLOCNO (a, ai)
     112                 :   22909600 :     ALLOCNO_ADD_DATA (a) = ira_allocno_emit_data + ALLOCNO_NUM (a);
     113                 :     944096 :   new_allocno_emit_data_vec.create (50);
     114                 :            : 
     115                 :     944096 : }
     116                 :            : 
     117                 :            : /* Free the emit data.  */
     118                 :            : void
     119                 :     944096 : ira_finish_emit_data (void)
     120                 :            : {
     121                 :     944096 :   void_p p;
     122                 :     944096 :   ira_allocno_t a;
     123                 :     944096 :   ira_allocno_iterator ai;
     124                 :            : 
     125                 :     944096 :   ira_free (ira_allocno_emit_data);
     126                 :   24800300 :   FOR_EACH_ALLOCNO (a, ai)
     127                 :   22912100 :     ALLOCNO_ADD_DATA (a) = NULL;
     128                 :     946634 :   for (;new_allocno_emit_data_vec.length () != 0;)
     129                 :            :     {
     130                 :       2538 :       p = new_allocno_emit_data_vec.pop ();
     131                 :       2538 :       ira_free (p);
     132                 :            :     }
     133                 :     944096 :   new_allocno_emit_data_vec.release ();
     134                 :     944096 : }
     135                 :            : 
     136                 :            : /* Create and return a new allocno with given REGNO and
     137                 :            :    LOOP_TREE_NODE.  Allocate emit data for it.  */
     138                 :            : static ira_allocno_t
     139                 :       2538 : create_new_allocno (int regno, ira_loop_tree_node_t loop_tree_node)
     140                 :            : {
     141                 :       2538 :   ira_allocno_t a;
     142                 :            : 
     143                 :       2538 :   a = ira_create_allocno (regno, false, loop_tree_node);
     144                 :       2538 :   ALLOCNO_ADD_DATA (a) = ira_allocate (sizeof (struct ira_emit_data));
     145                 :       2538 :   memset (ALLOCNO_ADD_DATA (a), 0, sizeof (struct ira_emit_data));
     146                 :       2538 :   new_allocno_emit_data_vec.safe_push (ALLOCNO_ADD_DATA (a));
     147                 :       2538 :   return a;
     148                 :            : }
     149                 :            : 
     150                 :            : 
     151                 :            : 
     152                 :            : /* See comments below.  */
     153                 :            : typedef struct move *move_t;
     154                 :            : 
     155                 :            : /* The structure represents an allocno move.  Both allocnos have the
     156                 :            :    same original regno but different allocation.  */
     157                 :            : struct move
     158                 :            : {
     159                 :            :   /* The allocnos involved in the move.  */
     160                 :            :   ira_allocno_t from, to;
     161                 :            :   /* The next move in the move sequence.  */
     162                 :            :   move_t next;
     163                 :            :   /* Used for finding dependencies.  */
     164                 :            :   bool visited_p;
     165                 :            :   /* The size of the following array. */
     166                 :            :   int deps_num;
     167                 :            :   /* Moves on which given move depends on.  Dependency can be cyclic.
     168                 :            :      It means we need a temporary to generates the moves.  Sequence
     169                 :            :      A1->A2, B1->B2 where A1 and B2 are assigned to reg R1 and A2 and
     170                 :            :      B1 are assigned to reg R2 is an example of the cyclic
     171                 :            :      dependencies.  */
     172                 :            :   move_t *deps;
     173                 :            :   /* First insn generated for the move.  */
     174                 :            :   rtx_insn *insn;
     175                 :            : };
     176                 :            : 
     177                 :            : /* Array of moves (indexed by BB index) which should be put at the
     178                 :            :    start/end of the corresponding basic blocks.  */
     179                 :            : static move_t *at_bb_start, *at_bb_end;
     180                 :            : 
     181                 :            : /* Max regno before renaming some pseudo-registers.  For example, the
     182                 :            :    same pseudo-register can be renamed in a loop if its allocation is
     183                 :            :    different outside the loop.  */
     184                 :            : static int max_regno_before_changing;
     185                 :            : 
     186                 :            : /* Return new move of allocnos TO and FROM.  */
     187                 :            : static move_t
     188                 :    1129530 : create_move (ira_allocno_t to, ira_allocno_t from)
     189                 :            : {
     190                 :    1129530 :   move_t move;
     191                 :            : 
     192                 :          0 :   move = (move_t) ira_allocate (sizeof (struct move));
     193                 :    1129530 :   move->deps = NULL;
     194                 :    1129530 :   move->deps_num = 0;
     195                 :    1129530 :   move->to = to;
     196                 :    1129530 :   move->from = from;
     197                 :    1129530 :   move->next = NULL;
     198                 :    1129530 :   move->insn = NULL;
     199                 :    1129530 :   move->visited_p = false;
     200                 :    1129530 :   return move;
     201                 :            : }
     202                 :            : 
     203                 :            : /* Free memory for MOVE and its dependencies.  */
     204                 :            : static void
     205                 :    1129530 : free_move (move_t move)
     206                 :            : {
     207                 :    1129530 :   if (move->deps != NULL)
     208                 :    1046120 :     ira_free (move->deps);
     209                 :    1129530 :   ira_free (move);
     210                 :    1129530 : }
     211                 :            : 
     212                 :            : /* Free memory for list of the moves given by its HEAD.  */
     213                 :            : static void
     214                 :          0 : free_move_list (move_t head)
     215                 :            : {
     216                 :    7734610 :   move_t next;
     217                 :            : 
     218                 :    7734610 :   for (; head != NULL; head = next)
     219                 :            :     {
     220                 :    1129530 :       next = head->next;
     221                 :    1129530 :       free_move (head);
     222                 :            :     }
     223                 :          0 : }
     224                 :            : 
     225                 :            : /* Return TRUE if the move list LIST1 and LIST2 are equal (two
     226                 :            :    moves are equal if they involve the same allocnos).  */
     227                 :            : static bool
     228                 :          0 : eq_move_lists_p (move_t list1, move_t list2)
     229                 :            : {
     230                 :    1810120 :   for (; list1 != NULL && list2 != NULL;
     231                 :      68290 :        list1 = list1->next, list2 = list2->next)
     232                 :      68908 :     if (list1->from != list2->from || list1->to != list2->to)
     233                 :            :       return false;
     234                 :    1741210 :   return list1 == list2;
     235                 :            : }
     236                 :            : 
     237                 :            : /* Print move list LIST into file F.  */
     238                 :            : static void
     239                 :          0 : print_move_list (FILE *f, move_t list)
     240                 :            : {
     241                 :          0 :   for (; list != NULL; list = list->next)
     242                 :          0 :     fprintf (f, " a%dr%d->a%dr%d",
     243                 :          0 :              ALLOCNO_NUM (list->from), ALLOCNO_REGNO (list->from),
     244                 :          0 :              ALLOCNO_NUM (list->to), ALLOCNO_REGNO (list->to));
     245                 :          0 :   fprintf (f, "\n");
     246                 :          0 : }
     247                 :            : 
     248                 :            : extern void ira_debug_move_list (move_t list);
     249                 :            : 
     250                 :            : /* Print move list LIST into stderr.  */
     251                 :            : void
     252                 :          0 : ira_debug_move_list (move_t list)
     253                 :            : {
     254                 :          0 :   print_move_list (stderr, list);
     255                 :          0 : }
     256                 :            : 
     257                 :            : /* This recursive function changes pseudo-registers in *LOC if it is
     258                 :            :    necessary.  The function returns TRUE if a change was done.  */
     259                 :            : static bool
     260                 :  122195000 : change_regs (rtx *loc)
     261                 :            : {
     262                 :  122195000 :   int i, regno, result = false;
     263                 :  122195000 :   const char *fmt;
     264                 :  122195000 :   enum rtx_code code;
     265                 :  122195000 :   rtx reg;
     266                 :            : 
     267                 :  122195000 :   if (*loc == NULL_RTX)
     268                 :            :     return false;
     269                 :  107166000 :   code = GET_CODE (*loc);
     270                 :  107166000 :   if (code == REG)
     271                 :            :     {
     272                 :   28101300 :       regno = REGNO (*loc);
     273                 :   28101300 :       if (regno < FIRST_PSEUDO_REGISTER)
     274                 :            :         return false;
     275                 :   15137200 :       if (regno >= max_regno_before_changing)
     276                 :            :         /* It is a shared register which was changed already.  */
     277                 :            :         return false;
     278                 :   15137100 :       if (ira_curr_regno_allocno_map[regno] == NULL)
     279                 :            :         return false;
     280                 :   15131200 :       reg = allocno_emit_reg (ira_curr_regno_allocno_map[regno]);
     281                 :   15131200 :       if (reg == *loc)
     282                 :            :         return false;
     283                 :    1930860 :       *loc = reg;
     284                 :    1930860 :       return true;
     285                 :            :     }
     286                 :            : 
     287                 :   79064400 :   fmt = GET_RTX_FORMAT (code);
     288                 :  285455000 :   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     289                 :            :     {
     290                 :  206390000 :       if (fmt[i] == 'e')
     291                 :  200626000 :         result = change_regs (&XEXP (*loc, i)) || result;
     292                 :  103055000 :       else if (fmt[i] == 'E')
     293                 :            :         {
     294                 :    2114450 :           int j;
     295                 :            : 
     296                 :    6542120 :           for (j = XVECLEN (*loc, i) - 1; j >= 0; j--)
     297                 :    8527020 :             result = change_regs (&XVECEXP (*loc, i, j)) || result;
     298                 :            :         }
     299                 :            :     }
     300                 :   79064400 :   return result;
     301                 :            : }
     302                 :            : 
     303                 :            : static bool
     304                 :   14432200 : change_regs_in_insn (rtx_insn **insn_ptr)
     305                 :            : {
     306                 :   14432200 :   rtx rtx = *insn_ptr;
     307                 :   14432200 :   bool result = change_regs (&rtx);
     308                 :   14432200 :   *insn_ptr = as_a <rtx_insn *> (rtx);
     309                 :   14432200 :   return result;
     310                 :            : }
     311                 :            : 
     312                 :            : /* Attach MOVE to the edge E.  The move is attached to the head of the
     313                 :            :    list if HEAD_P is TRUE.  */
     314                 :            : static void
     315                 :    1127000 : add_to_edge_list (edge e, move_t move, bool head_p)
     316                 :            : {
     317                 :    1127000 :   move_t last;
     318                 :            : 
     319                 :          0 :   if (head_p || e->aux == NULL)
     320                 :            :     {
     321                 :    1127000 :       move->next = (move_t) e->aux;
     322                 :          0 :       e->aux = move;
     323                 :            :     }
     324                 :            :   else
     325                 :            :     {
     326                 :          0 :       for (last = (move_t) e->aux; last->next != NULL; last = last->next)
     327                 :            :         ;
     328                 :          0 :       last->next = move;
     329                 :          0 :       move->next = NULL;
     330                 :            :     }
     331                 :          0 : }
     332                 :            : 
     333                 :            : /* Create and return new pseudo-register with the same attributes as
     334                 :            :    ORIGINAL_REG.  */
     335                 :            : rtx
     336                 :     663002 : ira_create_new_reg (rtx original_reg)
     337                 :            : {
     338                 :     663002 :   rtx new_reg;
     339                 :            : 
     340                 :     663002 :   new_reg = gen_reg_rtx (GET_MODE (original_reg));
     341                 :     663002 :   ORIGINAL_REGNO (new_reg) = ORIGINAL_REGNO (original_reg);
     342                 :     663002 :   REG_USERVAR_P (new_reg) = REG_USERVAR_P (original_reg);
     343                 :     663002 :   REG_POINTER (new_reg) = REG_POINTER (original_reg);
     344                 :     663002 :   REG_ATTRS (new_reg) = REG_ATTRS (original_reg);
     345                 :     663002 :   if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
     346                 :          0 :     fprintf (ira_dump_file, "      Creating newreg=%i from oldreg=%i\n",
     347                 :            :              REGNO (new_reg), REGNO (original_reg));
     348                 :     663002 :   ira_expand_reg_equiv ();
     349                 :     663002 :   return new_reg;
     350                 :            : }
     351                 :            : 
     352                 :            : /* Return TRUE if loop given by SUBNODE inside the loop given by
     353                 :            :    NODE.  */
     354                 :            : static bool
     355                 :          0 : subloop_tree_node_p (ira_loop_tree_node_t subnode, ira_loop_tree_node_t node)
     356                 :            : {
     357                 :   12068400 :   for (; subnode != NULL; subnode = subnode->parent)
     358                 :    9003080 :     if (subnode == node)
     359                 :            :       return true;
     360                 :            :   return false;
     361                 :            : }
     362                 :            : 
     363                 :            : /* Set up member `reg' to REG for allocnos which has the same regno as
     364                 :            :    ALLOCNO and which are inside the loop corresponding to ALLOCNO. */
     365                 :            : static void
     366                 :     648710 : set_allocno_reg (ira_allocno_t allocno, rtx reg)
     367                 :            : {
     368                 :     648710 :   int regno;
     369                 :     648710 :   ira_allocno_t a;
     370                 :     648710 :   ira_loop_tree_node_t node;
     371                 :            : 
     372                 :     648710 :   node = ALLOCNO_LOOP_TREE_NODE (allocno);
     373                 :     648710 :   for (a = ira_regno_allocno_map[ALLOCNO_REGNO (allocno)];
     374                 :    4599230 :        a != NULL;
     375                 :    3950520 :        a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
     376                 :    7901050 :     if (subloop_tree_node_p (ALLOCNO_LOOP_TREE_NODE (a), node))
     377                 :     885249 :       ALLOCNO_EMIT_DATA (a)->reg = reg;
     378                 :     655345 :   for (a = ALLOCNO_CAP (allocno); a != NULL; a = ALLOCNO_CAP (a))
     379                 :       6635 :     ALLOCNO_EMIT_DATA (a)->reg = reg;
     380                 :    1534140 :   regno = ALLOCNO_REGNO (allocno);
     381                 :            :   for (a = allocno;;)
     382                 :            :     {
     383                 :    1534140 :       if (a == NULL || (a = ALLOCNO_CAP (a)) == NULL)
     384                 :            :         {
     385                 :    1332410 :           node = node->parent;
     386                 :    1332410 :           if (node == NULL)
     387                 :            :             break;
     388                 :     965859 :           a = node->regno_allocno_map[regno];
     389                 :            :         }
     390                 :    1167590 :       if (a == NULL)
     391                 :     191596 :         continue;
     392                 :     975994 :       if (ALLOCNO_EMIT_DATA (a)->child_renamed_p)
     393                 :            :         break;
     394                 :     693834 :       ALLOCNO_EMIT_DATA (a)->child_renamed_p = true;
     395                 :            :     }
     396                 :     648710 : }
     397                 :            : 
     398                 :            : /* Return true if there is an entry to given loop not from its parent
     399                 :            :    (or grandparent) block.  For example, it is possible for two
     400                 :            :    adjacent loops inside another loop.  */
     401                 :            : static bool
     402                 :     129863 : entered_from_non_parent_p (ira_loop_tree_node_t loop_node)
     403                 :            : {
     404                 :     129863 :   ira_loop_tree_node_t bb_node, src_loop_node, parent;
     405                 :     129863 :   edge e;
     406                 :     129863 :   edge_iterator ei;
     407                 :            : 
     408                 :     129863 :   for (bb_node = loop_node->children;
     409                 :    1917480 :        bb_node != NULL;
     410                 :    1787620 :        bb_node = bb_node->next)
     411                 :    1787770 :     if (bb_node->bb != NULL)
     412                 :            :       {
     413                 :    4218780 :         FOR_EACH_EDGE (e, ei, bb_node->bb->preds)
     414                 :    2535600 :           if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)
     415                 :    2535600 :               && (src_loop_node = IRA_BB_NODE (e->src)->parent) != loop_node)
     416                 :            :             {
     417                 :     306792 :               for (parent = src_loop_node->parent;
     418                 :     401960 :                    parent != NULL;
     419                 :      95168 :                    parent = parent->parent)
     420                 :     284223 :                 if (parent == loop_node)
     421                 :            :                   break;
     422                 :     306792 :               if (parent != NULL)
     423                 :            :                 /* That is an exit from a nested loop -- skip it.  */
     424                 :     189055 :                 continue;
     425                 :     117737 :               for (parent = loop_node->parent;
     426                 :     117930 :                    parent != NULL;
     427                 :        193 :                    parent = parent->parent)
     428                 :     117777 :                 if (src_loop_node == parent)
     429                 :            :                   break;
     430                 :     117737 :               if (parent == NULL)
     431                 :            :                 return true;
     432                 :            :             }
     433                 :            :       }
     434                 :            :   return false;
     435                 :            : }
     436                 :            : 
     437                 :            : /* Set up ENTERED_FROM_NON_PARENT_P for each loop region.  */
     438                 :            : static void
     439                 :      25420 : setup_entered_from_non_parent_p (void)
     440                 :            : {
     441                 :      25420 :   unsigned int i;
     442                 :      25420 :   loop_p loop;
     443                 :            : 
     444                 :      25420 :   ira_assert (current_loops != NULL);
     445                 :     163491 :   FOR_EACH_VEC_SAFE_ELT (get_loops (cfun), i, loop)
     446                 :     138071 :     if (ira_loop_nodes[i].regno_allocno_map != NULL)
     447                 :     129863 :       ira_loop_nodes[i].entered_from_non_parent_p
     448                 :     129863 :         = entered_from_non_parent_p (&ira_loop_nodes[i]);
     449                 :      25420 : }
     450                 :            : 
     451                 :            : /* Return TRUE if move of SRC_ALLOCNO (assigned to hard register) to
     452                 :            :    DEST_ALLOCNO (assigned to memory) can be removed because it does
     453                 :            :    not change value of the destination.  One possible reason for this
     454                 :            :    is the situation when SRC_ALLOCNO is not modified in the
     455                 :            :    corresponding loop.  */
     456                 :            : static bool
     457                 :      48336 : store_can_be_removed_p (ira_allocno_t src_allocno, ira_allocno_t dest_allocno)
     458                 :            : {
     459                 :      48336 :   int regno, orig_regno;
     460                 :      48336 :   ira_allocno_t a;
     461                 :      48336 :   ira_loop_tree_node_t node;
     462                 :            : 
     463                 :      48336 :   ira_assert (ALLOCNO_CAP_MEMBER (src_allocno) == NULL
     464                 :            :               && ALLOCNO_CAP_MEMBER (dest_allocno) == NULL);
     465                 :      48336 :   orig_regno = ALLOCNO_REGNO (src_allocno);
     466                 :      48336 :   regno = REGNO (allocno_emit_reg (dest_allocno));
     467                 :      48336 :   for (node = ALLOCNO_LOOP_TREE_NODE (src_allocno);
     468                 :      73296 :        node != NULL;
     469                 :      24960 :        node = node->parent)
     470                 :            :     {
     471                 :      73295 :       a = node->regno_allocno_map[orig_regno];
     472                 :      73295 :       ira_assert (a != NULL);
     473                 :      73295 :       if (REGNO (allocno_emit_reg (a)) == (unsigned) regno)
     474                 :            :         /* We achieved the destination and everything is ok.  */
     475                 :            :         return true;
     476                 :      53961 :       else if (bitmap_bit_p (node->modified_regnos, orig_regno))
     477                 :            :         return false;
     478                 :      24992 :       else if (node->entered_from_non_parent_p)
     479                 :            :         /* If there is a path from a destination loop block to the
     480                 :            :            source loop header containing basic blocks of non-parents
     481                 :            :            (grandparents) of the source loop, we should have checked
     482                 :            :            modifications of the pseudo on this path too to decide
     483                 :            :            about possibility to remove the store.  It could be done by
     484                 :            :            solving a data-flow problem.  Unfortunately such global
     485                 :            :            solution would complicate IR flattening.  Therefore we just
     486                 :            :            prohibit removal of the store in such complicated case.  */
     487                 :            :         return false;
     488                 :            :     }
     489                 :            :   /* It is actually a loop entry -- do not remove the store.  */
     490                 :            :   return false;
     491                 :            : }
     492                 :            : 
     493                 :            : /* Generate and attach moves to the edge E.  This looks at the final
     494                 :            :    regnos of allocnos living on the edge with the same original regno
     495                 :            :    to figure out when moves should be generated.  */
     496                 :            : static void
     497                 :    2510470 : generate_edge_moves (edge e)
     498                 :            : {
     499                 :    2510470 :   ira_loop_tree_node_t src_loop_node, dest_loop_node;
     500                 :    2510470 :   unsigned int regno;
     501                 :    2510470 :   bitmap_iterator bi;
     502                 :    2510470 :   ira_allocno_t src_allocno, dest_allocno, *src_map, *dest_map;
     503                 :    2510470 :   move_t move;
     504                 :    2510470 :   bitmap regs_live_in_dest, regs_live_out_src;
     505                 :            : 
     506                 :    2510470 :   src_loop_node = IRA_BB_NODE (e->src)->parent;
     507                 :    2510470 :   dest_loop_node = IRA_BB_NODE (e->dest)->parent;
     508                 :    2510470 :   e->aux = NULL;
     509                 :    2510470 :   if (src_loop_node == dest_loop_node)
     510                 :    2203620 :     return;
     511                 :     306852 :   src_map = src_loop_node->regno_allocno_map;
     512                 :     306852 :   dest_map = dest_loop_node->regno_allocno_map;
     513                 :     306852 :   regs_live_in_dest = df_get_live_in (e->dest);
     514                 :     306852 :   regs_live_out_src = df_get_live_out (e->src);
     515                 :    4941440 :   EXECUTE_IF_SET_IN_REG_SET (regs_live_in_dest,
     516                 :            :                              FIRST_PSEUDO_REGISTER, regno, bi)
     517                 :    4634580 :     if (bitmap_bit_p (regs_live_out_src, regno))
     518                 :            :       {
     519                 :    4634580 :         src_allocno = src_map[regno];
     520                 :    4634580 :         dest_allocno = dest_map[regno];
     521                 :    4634580 :         if (REGNO (allocno_emit_reg (src_allocno))
     522                 :    4634580 :             == REGNO (allocno_emit_reg (dest_allocno)))
     523                 :    3488250 :           continue;
     524                 :            :         /* Remove unnecessary stores at the region exit.  We should do
     525                 :            :            this for readonly memory for sure and this is guaranteed by
     526                 :            :            that we never generate moves on region borders (see
     527                 :            :            checking in function change_loop).  */
     528                 :    1165660 :         if (ALLOCNO_HARD_REGNO (dest_allocno) < 0
     529                 :      48378 :             && ALLOCNO_HARD_REGNO (src_allocno) >= 0
     530                 :    1194670 :             && store_can_be_removed_p (src_allocno, dest_allocno))
     531                 :            :           {
     532                 :      19334 :             ALLOCNO_EMIT_DATA (src_allocno)->mem_optimized_dest = dest_allocno;
     533                 :      19334 :             ALLOCNO_EMIT_DATA (dest_allocno)->mem_optimized_dest_p = true;
     534                 :      19334 :             if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
     535                 :          0 :               fprintf (ira_dump_file, "      Remove r%d:a%d->a%d(mem)\n",
     536                 :            :                        regno, ALLOCNO_NUM (src_allocno),
     537                 :            :                        ALLOCNO_NUM (dest_allocno));
     538                 :      19334 :             continue;
     539                 :            :           }
     540                 :    1127000 :         move = create_move (dest_allocno, src_allocno);
     541                 :    4634580 :         add_to_edge_list (e, move, true);
     542                 :            :     }
     543                 :            : }
     544                 :            : 
     545                 :            : /* Bitmap of allocnos local for the current loop.  */
     546                 :            : static bitmap local_allocno_bitmap;
     547                 :            : 
     548                 :            : /* This bitmap is used to find that we need to generate and to use a
     549                 :            :    new pseudo-register when processing allocnos with the same original
     550                 :            :    regno.  */
     551                 :            : static bitmap used_regno_bitmap;
     552                 :            : 
     553                 :            : /* This bitmap contains regnos of allocnos which were renamed locally
     554                 :            :    because the allocnos correspond to disjoint live ranges in loops
     555                 :            :    with a common parent.  */
     556                 :            : static bitmap renamed_regno_bitmap;
     557                 :            : 
     558                 :            : /* Change (if necessary) pseudo-registers inside loop given by loop
     559                 :            :    tree node NODE.  */
     560                 :            : static void
     561                 :    1813260 : change_loop (ira_loop_tree_node_t node)
     562                 :            : {
     563                 :    1813260 :   bitmap_iterator bi;
     564                 :    1813260 :   unsigned int i;
     565                 :    1813260 :   int regno;
     566                 :    1813260 :   bool used_p;
     567                 :    1813260 :   ira_allocno_t allocno, parent_allocno, *map;
     568                 :    1813260 :   rtx_insn *insn;
     569                 :    1813260 :   rtx original_reg;
     570                 :    1813260 :   enum reg_class aclass, pclass;
     571                 :    1813260 :   ira_loop_tree_node_t parent;
     572                 :            : 
     573                 :    1813260 :   if (node != ira_loop_tree_root)
     574                 :            :     {
     575                 :    1787840 :       ira_assert (current_loops != NULL);
     576                 :            :       
     577                 :    1787840 :       if (node->bb != NULL)
     578                 :            :         {
     579                 :   19219300 :           FOR_BB_INSNS (node->bb, insn)
     580                 :   17535900 :             if (INSN_P (insn) && change_regs_in_insn (&insn))
     581                 :            :               {
     582                 :    1317650 :                 df_insn_rescan (insn);
     583                 :    1317650 :                 df_notes_rescan (insn);
     584                 :            :               }
     585                 :    1683400 :           return;
     586                 :            :         }
     587                 :            : 
     588                 :     104443 :       if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
     589                 :          0 :         fprintf (ira_dump_file,
     590                 :            :                  "      Changing RTL for loop %d (header bb%d)\n",
     591                 :          0 :                  node->loop_num, node->loop->header->index);
     592                 :            : 
     593                 :     104443 :       parent = ira_curr_loop_tree_node->parent;
     594                 :     104443 :       map = parent->regno_allocno_map;
     595                 :    2251380 :       EXECUTE_IF_SET_IN_REG_SET (ira_curr_loop_tree_node->border_allocnos,
     596                 :            :                                  0, i, bi)
     597                 :            :         {
     598                 :    2146940 :           allocno = ira_allocnos[i];
     599                 :    2146940 :           regno = ALLOCNO_REGNO (allocno);
     600                 :    2146940 :           aclass = ALLOCNO_CLASS (allocno);
     601                 :    2146940 :           pclass = ira_pressure_class_translate[aclass];
     602                 :    2146940 :           parent_allocno = map[regno];
     603                 :    2146940 :           ira_assert (regno < ira_reg_equiv_len);
     604                 :            :           /* We generate the same hard register move because the
     605                 :            :              reload pass can put an allocno into memory in this case
     606                 :            :              we will have live range splitting.  If it does not happen
     607                 :            :              such the same hard register moves will be removed.  The
     608                 :            :              worst case when the both allocnos are put into memory by
     609                 :            :              the reload is very rare.  */
     610                 :    3651590 :           if (parent_allocno != NULL
     611                 :    2146940 :               && (ALLOCNO_HARD_REGNO (allocno)
     612                 :    2146940 :                   == ALLOCNO_HARD_REGNO (parent_allocno))
     613                 :    4213980 :               && (ALLOCNO_HARD_REGNO (allocno) < 0
     614                 :     647274 :                   || (parent->reg_pressure[pclass] + 1
     615                 :     647274 :                       <= ira_class_hard_regs_num[pclass])
     616                 :     603205 :                   || TEST_HARD_REG_BIT (ira_prohibited_mode_move_regs
     617                 :     603205 :                                         [ALLOCNO_MODE (allocno)],
     618                 :            :                                         ALLOCNO_HARD_REGNO (allocno))
     619                 :            :                   /* don't create copies because reload can spill an
     620                 :            :                      allocno set by copy although the allocno will not
     621                 :            :                      get memory slot.  */
     622                 :     603205 :                   || ira_equiv_no_lvalue_p (regno)
     623                 :     568012 :                   || (pic_offset_table_rtx != NULL
     624                 :      57694 :                       && (ALLOCNO_REGNO (allocno)
     625                 :      57694 :                           == (int) REGNO (pic_offset_table_rtx)))))
     626                 :    1504650 :             continue;
     627                 :     642290 :           original_reg = allocno_emit_reg (allocno);
     628                 :     642290 :           if (parent_allocno == NULL
     629                 :     642290 :               || (REGNO (allocno_emit_reg (parent_allocno))
     630                 :     642290 :                   == REGNO (original_reg)))
     631                 :            :             {
     632                 :     642290 :               if (internal_flag_ira_verbose > 3 && ira_dump_file)
     633                 :          0 :                 fprintf (ira_dump_file, "  %i vs parent %i:",
     634                 :          0 :                          ALLOCNO_HARD_REGNO (allocno),
     635                 :          0 :                          ALLOCNO_HARD_REGNO (parent_allocno));
     636                 :     642290 :               set_allocno_reg (allocno, ira_create_new_reg (original_reg));
     637                 :            :             }
     638                 :            :         }
     639                 :            :     }
     640                 :            :   /* Rename locals: Local allocnos with same regno in different loops
     641                 :            :      might get the different hard register.  So we need to change
     642                 :            :      ALLOCNO_REG.  */
     643                 :     129863 :   bitmap_and_compl (local_allocno_bitmap,
     644                 :     129863 :                     ira_curr_loop_tree_node->all_allocnos,
     645                 :     129863 :                     ira_curr_loop_tree_node->border_allocnos);
     646                 :    6004180 :   EXECUTE_IF_SET_IN_REG_SET (local_allocno_bitmap, 0, i, bi)
     647                 :            :     {
     648                 :    5874320 :       allocno = ira_allocnos[i];
     649                 :    5874320 :       regno = ALLOCNO_REGNO (allocno);
     650                 :    5874320 :       if (ALLOCNO_CAP_MEMBER (allocno) != NULL)
     651                 :    2800960 :         continue;
     652                 :    3073360 :       used_p = !bitmap_set_bit (used_regno_bitmap, regno);
     653                 :    3073360 :       ALLOCNO_EMIT_DATA (allocno)->somewhere_renamed_p = true;
     654                 :    3073360 :       if (! used_p)
     655                 :    3066940 :         continue;
     656                 :       6420 :       bitmap_set_bit (renamed_regno_bitmap, regno);
     657                 :       6420 :       set_allocno_reg (allocno, ira_create_new_reg (allocno_emit_reg (allocno)));
     658                 :            :     }
     659                 :            : }
     660                 :            : 
     661                 :            : /* Process to set up flag somewhere_renamed_p.  */
     662                 :            : static void
     663                 :      25420 : set_allocno_somewhere_renamed_p (void)
     664                 :            : {
     665                 :      25420 :   unsigned int regno;
     666                 :      25420 :   ira_allocno_t allocno;
     667                 :      25420 :   ira_allocno_iterator ai;
     668                 :            : 
     669                 :    8046680 :   FOR_EACH_ALLOCNO (allocno, ai)
     670                 :            :     {
     671                 :    8021260 :       regno = ALLOCNO_REGNO (allocno);
     672                 :    8021260 :       if (bitmap_bit_p (renamed_regno_bitmap, regno)
     673                 :    8021260 :           && REGNO (allocno_emit_reg (allocno)) == regno)
     674                 :       7693 :         ALLOCNO_EMIT_DATA (allocno)->somewhere_renamed_p = true;
     675                 :            :     }
     676                 :      25420 : }
     677                 :            : 
     678                 :            : /* Return TRUE if move lists on all edges given in vector VEC are
     679                 :            :    equal.  */
     680                 :            : static bool
     681                 :    3306650 : eq_edge_move_lists_p (vec<edge, va_gc> *vec)
     682                 :            : {
     683                 :    3306650 :   move_t list;
     684                 :    3306650 :   int i;
     685                 :            : 
     686                 :    3306650 :   list = (move_t) EDGE_I (vec, 0)->aux;
     687                 :    4889260 :   for (i = EDGE_COUNT (vec) - 1; i > 0; i--)
     688                 :    3483660 :     if (! eq_move_lists_p (list, (move_t) EDGE_I (vec, i)->aux))
     689                 :            :       return false;
     690                 :            :   return true;
     691                 :            : }
     692                 :            : 
     693                 :            : /* Look at all entry edges (if START_P) or exit edges of basic block
     694                 :            :    BB and put move lists at the BB start or end if it is possible.  In
     695                 :            :    other words, this decreases code duplication of allocno moves.  */
     696                 :            : static void
     697                 :    3366800 : unify_moves (basic_block bb, bool start_p)
     698                 :            : {
     699                 :    3366800 :   int i;
     700                 :    3366800 :   edge e;
     701                 :    3366800 :   move_t list;
     702                 :    3366800 :   vec<edge, va_gc> *vec;
     703                 :            : 
     704                 :    3366800 :   vec = (start_p ? bb->preds : bb->succs);
     705                 :    3366800 :   if (EDGE_COUNT (vec) == 0 || ! eq_edge_move_lists_p (vec))
     706                 :            :     return;
     707                 :    3147430 :   e = EDGE_I (vec, 0);
     708                 :    3147430 :   list = (move_t) e->aux;
     709                 :    3147430 :   if (! start_p && control_flow_insn_p (BB_END (bb)))
     710                 :            :     return;
     711                 :    1867320 :   e->aux = NULL;
     712                 :    2568130 :   for (i = EDGE_COUNT (vec) - 1; i > 0; i--)
     713                 :            :     {
     714                 :     700808 :       e = EDGE_I (vec, i);
     715                 :     700808 :       free_move_list ((move_t) e->aux);
     716                 :     700808 :       e->aux = NULL;
     717                 :            :     }
     718                 :    1867320 :   if (start_p)
     719                 :    1568980 :     at_bb_start[bb->index] = list;
     720                 :            :   else
     721                 :     298347 :     at_bb_end[bb->index] = list;
     722                 :            : }
     723                 :            : 
     724                 :            : /* Last move (in move sequence being processed) setting up the
     725                 :            :    corresponding hard register.  */
     726                 :            : static move_t hard_regno_last_set[FIRST_PSEUDO_REGISTER];
     727                 :            : 
     728                 :            : /* If the element value is equal to CURR_TICK then the corresponding
     729                 :            :    element in `hard_regno_last_set' is defined and correct.  */
     730                 :            : static int hard_regno_last_set_check[FIRST_PSEUDO_REGISTER];
     731                 :            : 
     732                 :            : /* Last move (in move sequence being processed) setting up the
     733                 :            :    corresponding allocno.  */
     734                 :            : static move_t *allocno_last_set;
     735                 :            : 
     736                 :            : /* If the element value is equal to CURR_TICK then the corresponding
     737                 :            :    element in . `allocno_last_set' is defined and correct.  */
     738                 :            : static int *allocno_last_set_check;
     739                 :            : 
     740                 :            : /* Definition of vector of moves.  */
     741                 :            : 
     742                 :            : /* This vec contains moves sorted topologically (depth-first) on their
     743                 :            :    dependency graph.  */
     744                 :            : static vec<move_t> move_vec;
     745                 :            : 
     746                 :            : /* The variable value is used to check correctness of values of
     747                 :            :    elements of arrays `hard_regno_last_set' and
     748                 :            :    `allocno_last_set_check'.  */
     749                 :            : static int curr_tick;
     750                 :            : 
     751                 :            : /* This recursive function traverses dependencies of MOVE and produces
     752                 :            :    topological sorting (in depth-first order).  */
     753                 :            : static void
     754                 :    1138910 : traverse_moves (move_t move)
     755                 :            : {
     756                 :    1138910 :   int i;
     757                 :            : 
     758                 :    1138910 :   if (move->visited_p)
     759                 :            :     return;
     760                 :    1104660 :   move->visited_p = true;
     761                 :    1138910 :   for (i = move->deps_num - 1; i >= 0; i--)
     762                 :      34254 :     traverse_moves (move->deps[i]);
     763                 :    1104660 :   move_vec.safe_push (move);
     764                 :            : }
     765                 :            : 
     766                 :            : /* Remove unnecessary moves in the LIST, makes topological sorting,
     767                 :            :    and removes cycles on hard reg dependencies by introducing new
     768                 :            :    allocnos assigned to memory and additional moves.  It returns the
     769                 :            :    result move list.  */
     770                 :            : static move_t
     771                 :     224651 : modify_move_list (move_t list)
     772                 :            : {
     773                 :     224651 :   int i, n, nregs, hard_regno;
     774                 :     224651 :   ira_allocno_t to, from;
     775                 :     224651 :   move_t move, new_move, set_move, first, last;
     776                 :            : 
     777                 :     224651 :   if (list == NULL)
     778                 :            :     return NULL;
     779                 :            :   /* Create move deps.  */
     780                 :     224651 :   curr_tick++;
     781                 :    1329310 :   for (move = list; move != NULL; move = move->next)
     782                 :            :     {
     783                 :    1104660 :       to = move->to;
     784                 :    1104660 :       if ((hard_regno = ALLOCNO_HARD_REGNO (to)) < 0)
     785                 :      28761 :         continue;
     786                 :    1075900 :       nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (to));
     787                 :    2158130 :       for (i = 0; i < nregs; i++)
     788                 :            :         {
     789                 :    1082230 :           hard_regno_last_set[hard_regno + i] = move;
     790                 :    1082230 :           hard_regno_last_set_check[hard_regno + i] = curr_tick;
     791                 :            :         }
     792                 :            :     }
     793                 :    1329310 :   for (move = list; move != NULL; move = move->next)
     794                 :            :     {
     795                 :    1104660 :       from = move->from;
     796                 :    1104660 :       to = move->to;
     797                 :    1104660 :       if ((hard_regno = ALLOCNO_HARD_REGNO (from)) >= 0)
     798                 :            :         {
     799                 :    1046120 :           nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (from));
     800                 :    2098060 :           for (n = i = 0; i < nregs; i++)
     801                 :    1051940 :             if (hard_regno_last_set_check[hard_regno + i] == curr_tick
     802                 :    1017620 :                 && (ALLOCNO_REGNO (hard_regno_last_set[hard_regno + i]->to)
     803                 :    1017620 :                     != ALLOCNO_REGNO (from)))
     804                 :      34254 :               n++;
     805                 :    1046120 :           move->deps = (move_t *) ira_allocate (n * sizeof (move_t));
     806                 :    2098060 :           for (n = i = 0; i < nregs; i++)
     807                 :    1051940 :             if (hard_regno_last_set_check[hard_regno + i] == curr_tick
     808                 :    1017620 :                 && (ALLOCNO_REGNO (hard_regno_last_set[hard_regno + i]->to)
     809                 :    1017620 :                     != ALLOCNO_REGNO (from)))
     810                 :      34254 :               move->deps[n++] = hard_regno_last_set[hard_regno + i];
     811                 :    1046120 :           move->deps_num = n;
     812                 :            :         }
     813                 :            :     }
     814                 :            :   /* Topological sorting:  */
     815                 :     224651 :   move_vec.truncate (0);
     816                 :    1329310 :   for (move = list; move != NULL; move = move->next)
     817                 :    1104660 :     traverse_moves (move);
     818                 :     224651 :   last = NULL;
     819                 :    1553960 :   for (i = (int) move_vec.length () - 1; i >= 0; i--)
     820                 :            :     {
     821                 :    1104660 :       move = move_vec[i];
     822                 :    1104660 :       move->next = NULL;
     823                 :    1104660 :       if (last != NULL)
     824                 :     880007 :         last->next = move;
     825                 :    1104660 :       last = move;
     826                 :            :     }
     827                 :     224651 :   first = move_vec.last ();
     828                 :            :   /* Removing cycles:  */
     829                 :     224651 :   curr_tick++;
     830                 :     224651 :   move_vec.truncate (0);
     831                 :    1329310 :   for (move = first; move != NULL; move = move->next)
     832                 :            :     {
     833                 :    1104660 :       from = move->from;
     834                 :    1104660 :       to = move->to;
     835                 :    1104660 :       if ((hard_regno = ALLOCNO_HARD_REGNO (from)) >= 0)
     836                 :            :         {
     837                 :    1046120 :           nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (from));
     838                 :    2098060 :           for (i = 0; i < nregs; i++)
     839                 :    1051940 :             if (hard_regno_last_set_check[hard_regno + i] == curr_tick
     840                 :       2538 :                 && ALLOCNO_HARD_REGNO
     841                 :            :                    (hard_regno_last_set[hard_regno + i]->to) >= 0)
     842                 :            :               {
     843                 :       2538 :                 int n, j;
     844                 :       2538 :                 ira_allocno_t new_allocno;
     845                 :            : 
     846                 :       2538 :                 set_move = hard_regno_last_set[hard_regno + i];
     847                 :            :                 /* It does not matter what loop_tree_node (of TO or
     848                 :            :                    FROM) to use for the new allocno because of
     849                 :            :                    subsequent IRA internal representation
     850                 :            :                    flattening.  */
     851                 :       2538 :                 new_allocno
     852                 :       2538 :                   = create_new_allocno (ALLOCNO_REGNO (set_move->to),
     853                 :            :                                         ALLOCNO_LOOP_TREE_NODE (set_move->to));
     854                 :       2538 :                 ALLOCNO_MODE (new_allocno) = ALLOCNO_MODE (set_move->to);
     855                 :       2538 :                 ira_set_allocno_class (new_allocno,
     856                 :       2538 :                                        ALLOCNO_CLASS (set_move->to));
     857                 :       2538 :                 ira_create_allocno_objects (new_allocno);
     858                 :       2538 :                 ALLOCNO_ASSIGNED_P (new_allocno) = true;
     859                 :       2538 :                 ALLOCNO_HARD_REGNO (new_allocno) = -1;
     860                 :       2538 :                 ALLOCNO_EMIT_DATA (new_allocno)->reg
     861                 :       2538 :                   = ira_create_new_reg (allocno_emit_reg (set_move->to));
     862                 :            : 
     863                 :            :                 /* Make it possibly conflicting with all earlier
     864                 :            :                    created allocnos.  Cases where temporary allocnos
     865                 :            :                    created to remove the cycles are quite rare.  */
     866                 :       2538 :                 n = ALLOCNO_NUM_OBJECTS (new_allocno);
     867                 :       2538 :                 gcc_assert (n == ALLOCNO_NUM_OBJECTS (set_move->to));
     868                 :       5076 :                 for (j = 0; j < n; j++)
     869                 :            :                   {
     870                 :       2538 :                     ira_object_t new_obj = ALLOCNO_OBJECT (new_allocno, j);
     871                 :            : 
     872                 :       2538 :                     OBJECT_MIN (new_obj) = 0;
     873                 :       2538 :                     OBJECT_MAX (new_obj) = ira_objects_num - 1;
     874                 :            :                   }
     875                 :            : 
     876                 :       2538 :                 new_move = create_move (set_move->to, new_allocno);
     877                 :       2538 :                 set_move->to = new_allocno;
     878                 :       2538 :                 move_vec.safe_push (new_move);
     879                 :       2538 :                 ira_move_loops_num++;
     880                 :       2538 :                 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
     881                 :          0 :                   fprintf (ira_dump_file,
     882                 :            :                            "    Creating temporary allocno a%dr%d\n",
     883                 :            :                            ALLOCNO_NUM (new_allocno),
     884                 :          0 :                            REGNO (allocno_emit_reg (new_allocno)));
     885                 :            :               }
     886                 :            :         }
     887                 :    1104660 :       if ((hard_regno = ALLOCNO_HARD_REGNO (to)) < 0)
     888                 :      28761 :         continue;
     889                 :    1075900 :       nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (to));
     890                 :    2158130 :       for (i = 0; i < nregs; i++)
     891                 :            :         {
     892                 :    1082230 :           hard_regno_last_set[hard_regno + i] = move;
     893                 :    1082230 :           hard_regno_last_set_check[hard_regno + i] = curr_tick;
     894                 :            :         }
     895                 :            :     }
     896                 :     451840 :   for (i = (int) move_vec.length () - 1; i >= 0; i--)
     897                 :            :     {
     898                 :       2538 :       move = move_vec[i];
     899                 :       2538 :       move->next = NULL;
     900                 :       2538 :       last->next = move;
     901                 :       2538 :       last = move;
     902                 :            :     }
     903                 :            :   return first;
     904                 :            : }
     905                 :            : 
     906                 :            : /* Generate RTX move insns from the move list LIST.  This updates
     907                 :            :    allocation cost using move execution frequency FREQ.  */
     908                 :            : static rtx_insn *
     909                 :     224651 : emit_move_list (move_t list, int freq)
     910                 :            : {
     911                 :     224651 :   rtx to, from, dest;
     912                 :     224651 :   int to_regno, from_regno, cost, regno;
     913                 :     224651 :   rtx_insn *result, *insn;
     914                 :     224651 :   rtx set;
     915                 :     224651 :   machine_mode mode;
     916                 :     224651 :   enum reg_class aclass;
     917                 :            : 
     918                 :     224651 :   grow_reg_equivs ();
     919                 :     224651 :   start_sequence ();
     920                 :    1331850 :   for (; list != NULL; list = list->next)
     921                 :            :     {
     922                 :    1107200 :       start_sequence ();
     923                 :    1107200 :       to = allocno_emit_reg (list->to);
     924                 :    1107200 :       to_regno = REGNO (to);
     925                 :    1107200 :       from = allocno_emit_reg (list->from);
     926                 :    1107200 :       from_regno = REGNO (from);
     927                 :    1107200 :       emit_move_insn (to, from);
     928                 :    1107200 :       list->insn = get_insns ();
     929                 :    1107200 :       end_sequence ();
     930                 :    3321590 :       for (insn = list->insn; insn != NULL_RTX; insn = NEXT_INSN (insn))
     931                 :            :         {
     932                 :            :           /* The reload needs to have set up insn codes.  If the
     933                 :            :              reload sets up insn codes by itself, it may fail because
     934                 :            :              insns will have hard registers instead of pseudos and
     935                 :            :              there may be no machine insn with given hard
     936                 :            :              registers.  */
     937                 :    1107200 :           recog_memoized (insn);
     938                 :            :           /* Add insn to equiv init insn list if it is necessary.
     939                 :            :              Otherwise reload will not remove this insn if it decides
     940                 :            :              to use the equivalence.  */
     941                 :    1107200 :           if ((set = single_set (insn)) != NULL_RTX)
     942                 :            :             {
     943                 :    1107200 :               dest = SET_DEST (set);
     944                 :    1107200 :               if (GET_CODE (dest) == SUBREG)
     945                 :          0 :                 dest = SUBREG_REG (dest);
     946                 :    1107200 :               ira_assert (REG_P (dest));
     947                 :    1107200 :               regno = REGNO (dest);
     948                 :    1107200 :               if (regno >= ira_reg_equiv_len
     949                 :    1107200 :                   || (ira_reg_equiv[regno].invariant == NULL_RTX
     950                 :    1107180 :                       && ira_reg_equiv[regno].constant == NULL_RTX))
     951                 :    1107180 :                 continue; /* regno has no equivalence.  */
     952                 :         17 :               ira_assert ((int) reg_equivs->length () > regno);
     953                 :         34 :               reg_equiv_init (regno)
     954                 :         17 :                 = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init (regno));
     955                 :            :             }
     956                 :            :         }
     957                 :    1107200 :       if (ira_use_lra_p)
     958                 :    1107200 :         ira_update_equiv_info_by_shuffle_insn (to_regno, from_regno, list->insn);
     959                 :    1107200 :       emit_insn (list->insn);
     960                 :    1107200 :       mode = ALLOCNO_MODE (list->to);
     961                 :    1107200 :       aclass = ALLOCNO_CLASS (list->to);
     962                 :    1107200 :       cost = 0;
     963                 :    1107200 :       if (ALLOCNO_HARD_REGNO (list->to) < 0)
     964                 :            :         {
     965                 :      31299 :           if (ALLOCNO_HARD_REGNO (list->from) >= 0)
     966                 :            :             {
     967                 :      31258 :               cost = ira_memory_move_cost[mode][aclass][0] * freq;
     968                 :      31258 :               ira_store_cost += cost;
     969                 :            :             }
     970                 :            :         }
     971                 :    1075900 :       else if (ALLOCNO_HARD_REGNO (list->from) < 0)
     972                 :            :         {
     973                 :      61036 :           if (ALLOCNO_HARD_REGNO (list->to) >= 0)
     974                 :            :             {
     975                 :      61036 :               cost = ira_memory_move_cost[mode][aclass][0] * freq;
     976                 :      61036 :               ira_load_cost += cost;
     977                 :            :             }
     978                 :            :         }
     979                 :            :       else
     980                 :            :         {
     981                 :    1014860 :           ira_init_register_move_cost_if_necessary (mode);
     982                 :    1014860 :           cost = ira_register_move_cost[mode][aclass][aclass] * freq;
     983                 :    1014860 :           ira_shuffle_cost += cost;
     984                 :            :         }
     985                 :    1107200 :       ira_overall_cost += cost;
     986                 :            :     }
     987                 :     224651 :   result = get_insns ();
     988                 :     224651 :   end_sequence ();
     989                 :     224651 :   return result;
     990                 :            : }
     991                 :            : 
     992                 :            : /* Generate RTX move insns from move lists attached to basic blocks
     993                 :            :    and edges.  */
     994                 :            : static void
     995                 :      25420 : emit_moves (void)
     996                 :            : {
     997                 :      25420 :   basic_block bb;
     998                 :      25420 :   edge_iterator ei;
     999                 :      25420 :   edge e;
    1000                 :      25420 :   rtx_insn *insns, *tmp, *next;
    1001                 :            : 
    1002                 :    1708820 :   FOR_EACH_BB_FN (bb, cfun)
    1003                 :            :     {
    1004                 :    1683400 :       if (at_bb_start[bb->index] != NULL)
    1005                 :            :         {
    1006                 :      92647 :           at_bb_start[bb->index] = modify_move_list (at_bb_start[bb->index]);
    1007                 :      92647 :           insns
    1008                 :      92647 :             = emit_move_list (at_bb_start[bb->index], REG_FREQ_FROM_BB (bb));
    1009                 :      92647 :           tmp = BB_HEAD (bb);
    1010                 :      92647 :           if (LABEL_P (tmp))
    1011                 :      17686 :             tmp = NEXT_INSN (tmp);
    1012                 :      92647 :           if (NOTE_INSN_BASIC_BLOCK_P (tmp))
    1013                 :      92647 :             tmp = NEXT_INSN (tmp);
    1014                 :            :           /* Make sure to put the location of TMP or a subsequent instruction
    1015                 :            :              to avoid inheriting the location of the previous instruction.  */
    1016                 :      92647 :           next = tmp;
    1017                 :     157822 :           while (next && !NONDEBUG_INSN_P (next))
    1018                 :      65175 :             next = NEXT_INSN (next);
    1019                 :      92647 :           if (next)
    1020                 :      92647 :             set_insn_locations (insns, INSN_LOCATION (next));
    1021                 :      92647 :           if (tmp == BB_HEAD (bb))
    1022                 :          0 :             emit_insn_before (insns, tmp);
    1023                 :      92647 :           else if (tmp)
    1024                 :      92647 :             emit_insn_after (insns, PREV_INSN (tmp));
    1025                 :            :           else
    1026                 :          0 :             emit_insn_after (insns, get_last_insn ());
    1027                 :            :         }
    1028                 :            : 
    1029                 :    1683400 :       if (at_bb_end[bb->index] != NULL)
    1030                 :            :         {
    1031                 :      62126 :           at_bb_end[bb->index] = modify_move_list (at_bb_end[bb->index]);
    1032                 :      62126 :           insns = emit_move_list (at_bb_end[bb->index], REG_FREQ_FROM_BB (bb));
    1033                 :      62126 :           ira_assert (! control_flow_insn_p (BB_END (bb)));
    1034                 :      62126 :           emit_insn_after (insns, BB_END (bb));
    1035                 :            :         }
    1036                 :            : 
    1037                 :    4220860 :       FOR_EACH_EDGE (e, ei, bb->succs)
    1038                 :            :         {
    1039                 :    2537460 :           if (e->aux == NULL)
    1040                 :    2467580 :             continue;
    1041                 :      69878 :           ira_assert ((e->flags & EDGE_ABNORMAL) == 0
    1042                 :            :                       || ! EDGE_CRITICAL_P (e));
    1043                 :      69878 :           e->aux = modify_move_list ((move_t) e->aux);
    1044                 :      69878 :           insert_insn_on_edge
    1045                 :     139756 :             (emit_move_list ((move_t) e->aux,
    1046                 :     139756 :                              REG_FREQ_FROM_EDGE_FREQ (EDGE_FREQUENCY (e))),
    1047                 :            :              e);
    1048                 :      69878 :           if (e->src->next_bb != e->dest)
    1049                 :      54037 :             ira_additional_jumps_num++;
    1050                 :            :         }
    1051                 :            :     }
    1052                 :      25420 : }
    1053                 :            : 
    1054                 :            : /* Update costs of A and corresponding allocnos on upper levels on the
    1055                 :            :    loop tree from reading (if READ_P) or writing A on an execution
    1056                 :            :    path with FREQ.  */
    1057                 :            : static void
    1058                 :    2214390 : update_costs (ira_allocno_t a, bool read_p, int freq)
    1059                 :            : {
    1060                 :    5321010 :   ira_loop_tree_node_t parent;
    1061                 :            : 
    1062                 :    5321010 :   for (;;)
    1063                 :            :     {
    1064                 :    5321010 :       ALLOCNO_NREFS (a)++;
    1065                 :    5321010 :       ALLOCNO_FREQ (a) += freq;
    1066                 :    5321010 :       ALLOCNO_MEMORY_COST (a)
    1067                 :   10642000 :         += (ira_memory_move_cost[ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)]
    1068                 :    5321010 :             [read_p ? 1 : 0] * freq);
    1069                 :    5321010 :       if (ALLOCNO_CAP (a) != NULL)
    1070                 :            :         a = ALLOCNO_CAP (a);
    1071                 :    4381980 :       else if ((parent = ALLOCNO_LOOP_TREE_NODE (a)->parent) == NULL
    1072                 :    4381980 :                || (a = parent->regno_allocno_map[ALLOCNO_REGNO (a)]) == NULL)
    1073                 :            :         break;
    1074                 :            :     }
    1075                 :    2214390 : }
    1076                 :            : 
    1077                 :            : /* Process moves from LIST with execution FREQ to add ranges, copies,
    1078                 :            :    and modify costs for allocnos involved in the moves.  All regnos
    1079                 :            :    living through the list is in LIVE_THROUGH, and the loop tree node
    1080                 :            :    used to find corresponding allocnos is NODE.  */
    1081                 :            : static void
    1082                 :    5904260 : add_range_and_copies_from_move_list (move_t list, ira_loop_tree_node_t node,
    1083                 :            :                                      bitmap live_through, int freq)
    1084                 :            : {
    1085                 :    5904260 :   int start, n;
    1086                 :    5904260 :   unsigned int regno;
    1087                 :    5904260 :   move_t move;
    1088                 :    5904260 :   ira_allocno_t a;
    1089                 :    5904260 :   ira_copy_t cp;
    1090                 :    5904260 :   live_range_t r;
    1091                 :    5904260 :   bitmap_iterator bi;
    1092                 :    5904260 :   HARD_REG_SET hard_regs_live;
    1093                 :            : 
    1094                 :    5904260 :   if (list == NULL)
    1095                 :    5679610 :     return;
    1096                 :     224651 :   n = 0;
    1097                 :    4302090 :   EXECUTE_IF_SET_IN_BITMAP (live_through, FIRST_PSEUDO_REGISTER, regno, bi)
    1098                 :    4077440 :     n++;
    1099                 :     673953 :   REG_SET_TO_HARD_REG_SET (hard_regs_live, live_through);
    1100                 :            :   /* This is a trick to guarantee that new ranges is not merged with
    1101                 :            :      the old ones.  */
    1102                 :     224651 :   ira_max_point++;
    1103                 :     224651 :   start = ira_max_point;
    1104                 :    1331850 :   for (move = list; move != NULL; move = move->next)
    1105                 :            :     {
    1106                 :    1107200 :       ira_allocno_t from = move->from;
    1107                 :    1107200 :       ira_allocno_t to = move->to;
    1108                 :    1107200 :       int nr, i;
    1109                 :            : 
    1110                 :    1107200 :       bitmap_clear_bit (live_through, ALLOCNO_REGNO (from));
    1111                 :    1107200 :       bitmap_clear_bit (live_through, ALLOCNO_REGNO (to));
    1112                 :            : 
    1113                 :    1107200 :       nr = ALLOCNO_NUM_OBJECTS (to);
    1114                 :    2221240 :       for (i = 0; i < nr; i++)
    1115                 :            :         {
    1116                 :    1114050 :           ira_object_t to_obj = ALLOCNO_OBJECT (to, i);
    1117                 :    1114050 :           if (OBJECT_CONFLICT_ARRAY (to_obj) == NULL)
    1118                 :            :             {
    1119                 :       2538 :               if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
    1120                 :          0 :                 fprintf (ira_dump_file, "    Allocate conflicts for a%dr%d\n",
    1121                 :          0 :                          ALLOCNO_NUM (to), REGNO (allocno_emit_reg (to)));
    1122                 :       2538 :               ira_allocate_object_conflicts (to_obj, n);
    1123                 :            :             }
    1124                 :            :         }
    1125                 :    1107200 :       ior_hard_reg_conflicts (from, hard_regs_live);
    1126                 :    1107200 :       ior_hard_reg_conflicts (to, hard_regs_live);
    1127                 :            : 
    1128                 :    1107200 :       update_costs (from, true, freq);
    1129                 :    1107200 :       update_costs (to, false, freq);
    1130                 :    1107200 :       cp = ira_add_allocno_copy (from, to, freq, false, move->insn, NULL);
    1131                 :    1107200 :       if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
    1132                 :          0 :         fprintf (ira_dump_file, "    Adding cp%d:a%dr%d-a%dr%d\n",
    1133                 :            :                  cp->num, ALLOCNO_NUM (cp->first),
    1134                 :          0 :                  REGNO (allocno_emit_reg (cp->first)),
    1135                 :            :                  ALLOCNO_NUM (cp->second),
    1136                 :          0 :                  REGNO (allocno_emit_reg (cp->second)));
    1137                 :            : 
    1138                 :    1107200 :       nr = ALLOCNO_NUM_OBJECTS (from);
    1139                 :    2221240 :       for (i = 0; i < nr; i++)
    1140                 :            :         {
    1141                 :    1114050 :           ira_object_t from_obj = ALLOCNO_OBJECT (from, i);
    1142                 :    1114050 :           r = OBJECT_LIVE_RANGES (from_obj);
    1143                 :    1114050 :           if (r == NULL || r->finish >= 0)
    1144                 :            :             {
    1145                 :    1111510 :               ira_add_live_range_to_object (from_obj, start, ira_max_point);
    1146                 :    1111510 :               if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
    1147                 :          0 :                 fprintf (ira_dump_file,
    1148                 :            :                          "    Adding range [%d..%d] to allocno a%dr%d\n",
    1149                 :            :                          start, ira_max_point, ALLOCNO_NUM (from),
    1150                 :          0 :                          REGNO (allocno_emit_reg (from)));
    1151                 :            :             }
    1152                 :            :           else
    1153                 :            :             {
    1154                 :       2538 :               r->finish = ira_max_point;
    1155                 :       2538 :               if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
    1156                 :          0 :                 fprintf (ira_dump_file,
    1157                 :            :                          "    Adding range [%d..%d] to allocno a%dr%d\n",
    1158                 :            :                          r->start, ira_max_point, ALLOCNO_NUM (from),
    1159                 :          0 :                          REGNO (allocno_emit_reg (from)));
    1160                 :            :             }
    1161                 :            :         }
    1162                 :    1107200 :       ira_max_point++;
    1163                 :    1107200 :       nr = ALLOCNO_NUM_OBJECTS (to);
    1164                 :    2221240 :       for (i = 0; i < nr; i++)
    1165                 :            :         {
    1166                 :    1114050 :           ira_object_t to_obj = ALLOCNO_OBJECT (to, i);
    1167                 :    1114050 :           ira_add_live_range_to_object (to_obj, ira_max_point, -1);
    1168                 :            :         }
    1169                 :    1107200 :       ira_max_point++;
    1170                 :            :     }
    1171                 :    1331850 :   for (move = list; move != NULL; move = move->next)
    1172                 :            :     {
    1173                 :    1107200 :       int nr, i;
    1174                 :    1107200 :       nr = ALLOCNO_NUM_OBJECTS (move->to);
    1175                 :    2221240 :       for (i = 0; i < nr; i++)
    1176                 :            :         {
    1177                 :    1114050 :           ira_object_t to_obj = ALLOCNO_OBJECT (move->to, i);
    1178                 :    1114050 :           r = OBJECT_LIVE_RANGES (to_obj);
    1179                 :    1114050 :           if (r->finish < 0)
    1180                 :            :             {
    1181                 :    1111510 :               r->finish = ira_max_point - 1;
    1182                 :    1111510 :               if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
    1183                 :          0 :                 fprintf (ira_dump_file,
    1184                 :            :                          "    Adding range [%d..%d] to allocno a%dr%d\n",
    1185                 :            :                          r->start, r->finish, ALLOCNO_NUM (move->to),
    1186                 :          0 :                          REGNO (allocno_emit_reg (move->to)));
    1187                 :            :             }
    1188                 :            :         }
    1189                 :            :     }
    1190                 :    3197430 :   EXECUTE_IF_SET_IN_BITMAP (live_through, FIRST_PSEUDO_REGISTER, regno, bi)
    1191                 :            :     {
    1192                 :    2972780 :       ira_allocno_t to;
    1193                 :    2972780 :       int nr, i;
    1194                 :            : 
    1195                 :    2972780 :       a = node->regno_allocno_map[regno];
    1196                 :    2972780 :       if ((to = ALLOCNO_EMIT_DATA (a)->mem_optimized_dest) != NULL)
    1197                 :       3774 :         a = to;
    1198                 :    2972780 :       nr = ALLOCNO_NUM_OBJECTS (a);
    1199                 :    6003670 :       for (i = 0; i < nr; i++)
    1200                 :            :         {
    1201                 :    3030890 :           ira_object_t obj = ALLOCNO_OBJECT (a, i);
    1202                 :    3030890 :           ira_add_live_range_to_object (obj, start, ira_max_point - 1);
    1203                 :            :         }
    1204                 :    2972780 :       if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
    1205                 :          0 :         fprintf
    1206                 :          0 :           (ira_dump_file,
    1207                 :            :            "    Adding range [%d..%d] to live through %s allocno a%dr%d\n",
    1208                 :            :            start, ira_max_point - 1,
    1209                 :            :            to != NULL ? "upper level" : "",
    1210                 :          0 :            ALLOCNO_NUM (a), REGNO (allocno_emit_reg (a)));
    1211                 :            :     }
    1212                 :            : }
    1213                 :            : 
    1214                 :            : /* Process all move list to add ranges, conflicts, copies, and modify
    1215                 :            :    costs for allocnos involved in the moves.  */
    1216                 :            : static void
    1217                 :      25420 : add_ranges_and_copies (void)
    1218                 :            : {
    1219                 :      25420 :   basic_block bb;
    1220                 :      25420 :   edge_iterator ei;
    1221                 :      25420 :   edge e;
    1222                 :      25420 :   ira_loop_tree_node_t node;
    1223                 :      25420 :   bitmap live_through;
    1224                 :            : 
    1225                 :      25420 :   live_through = ira_allocate_bitmap ();
    1226                 :    1708820 :   FOR_EACH_BB_FN (bb, cfun)
    1227                 :            :     {
    1228                 :            :       /* It does not matter what loop_tree_node (of source or
    1229                 :            :          destination block) to use for searching allocnos by their
    1230                 :            :          regnos because of subsequent IR flattening.  */
    1231                 :    1683400 :       node = IRA_BB_NODE (bb)->parent;
    1232                 :    1683400 :       bitmap_copy (live_through, df_get_live_in (bb));
    1233                 :    1683400 :       add_range_and_copies_from_move_list
    1234                 :    1683400 :         (at_bb_start[bb->index], node, live_through, REG_FREQ_FROM_BB (bb));
    1235                 :    1683400 :       bitmap_copy (live_through, df_get_live_out (bb));
    1236                 :    1683400 :       add_range_and_copies_from_move_list
    1237                 :    1683400 :         (at_bb_end[bb->index], node, live_through, REG_FREQ_FROM_BB (bb));
    1238                 :    4220860 :       FOR_EACH_EDGE (e, ei, bb->succs)
    1239                 :            :         {
    1240                 :    2537460 :           bitmap_and (live_through,
    1241                 :    2537460 :                       df_get_live_in (e->dest), df_get_live_out (bb));
    1242                 :    2537460 :           add_range_and_copies_from_move_list
    1243                 :    5074920 :             ((move_t) e->aux, node, live_through,
    1244                 :    7612390 :              REG_FREQ_FROM_EDGE_FREQ (EDGE_FREQUENCY (e)));
    1245                 :            :         }
    1246                 :            :     }
    1247                 :      25420 :   ira_free_bitmap (live_through);
    1248                 :      25420 : }
    1249                 :            : 
    1250                 :            : /* The entry function changes code and generates shuffling allocnos on
    1251                 :            :    region borders for the regional (LOOPS_P is TRUE in this case)
    1252                 :            :    register allocation.  */
    1253                 :            : void
    1254                 :     944096 : ira_emit (bool loops_p)
    1255                 :            : {
    1256                 :     944096 :   basic_block bb;
    1257                 :     944096 :   rtx_insn *insn;
    1258                 :     944096 :   edge_iterator ei;
    1259                 :     944096 :   edge e;
    1260                 :     944096 :   ira_allocno_t a;
    1261                 :     944096 :   ira_allocno_iterator ai;
    1262                 :     944096 :   size_t sz;
    1263                 :            : 
    1264                 :   23853700 :   FOR_EACH_ALLOCNO (a, ai)
    1265                 :   22909600 :     ALLOCNO_EMIT_DATA (a)->reg = regno_reg_rtx[ALLOCNO_REGNO (a)];
    1266                 :     944096 :   if (! loops_p)
    1267                 :     918676 :     return;
    1268                 :      25420 :   sz = sizeof (move_t) * last_basic_block_for_fn (cfun);
    1269                 :      25420 :   at_bb_start = (move_t *) ira_allocate (sz);
    1270                 :      25420 :   memset (at_bb_start, 0, sz);
    1271                 :      25420 :   at_bb_end = (move_t *) ira_allocate (sz);
    1272                 :      25420 :   memset (at_bb_end, 0, sz);
    1273                 :      25420 :   local_allocno_bitmap = ira_allocate_bitmap ();
    1274                 :      25420 :   used_regno_bitmap = ira_allocate_bitmap ();
    1275                 :      25420 :   renamed_regno_bitmap = ira_allocate_bitmap ();
    1276                 :      25420 :   max_regno_before_changing = max_reg_num ();
    1277                 :      25420 :   ira_traverse_loop_tree (true, ira_loop_tree_root, change_loop, NULL);
    1278                 :      25420 :   set_allocno_somewhere_renamed_p ();
    1279                 :      25420 :   ira_free_bitmap (used_regno_bitmap);
    1280                 :      25420 :   ira_free_bitmap (renamed_regno_bitmap);
    1281                 :      25420 :   ira_free_bitmap (local_allocno_bitmap);
    1282                 :      25420 :   setup_entered_from_non_parent_p ();
    1283                 :    1708820 :   FOR_EACH_BB_FN (bb, cfun)
    1284                 :            :     {
    1285                 :    1683400 :       at_bb_start[bb->index] = NULL;
    1286                 :    1683400 :       at_bb_end[bb->index] = NULL;
    1287                 :    4220860 :       FOR_EACH_EDGE (e, ei, bb->succs)
    1288                 :    2537460 :         if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
    1289                 :    2510470 :           generate_edge_moves (e);
    1290                 :            :     }
    1291                 :      25420 :   allocno_last_set
    1292                 :      25420 :     = (move_t *) ira_allocate (sizeof (move_t) * max_reg_num ());
    1293                 :      25420 :   allocno_last_set_check
    1294                 :      25420 :     = (int *) ira_allocate (sizeof (int) * max_reg_num ());
    1295                 :      25420 :   memset (allocno_last_set_check, 0, sizeof (int) * max_reg_num ());
    1296                 :      25420 :   memset (hard_regno_last_set_check, 0, sizeof (hard_regno_last_set_check));
    1297                 :      25420 :   curr_tick = 0;
    1298                 :    1708820 :   FOR_EACH_BB_FN (bb, cfun)
    1299                 :    1683400 :     unify_moves (bb, true);
    1300                 :    1708820 :   FOR_EACH_BB_FN (bb, cfun)
    1301                 :    1683400 :     unify_moves (bb, false);
    1302                 :      25420 :   move_vec.create (ira_allocnos_num);
    1303                 :      25420 :   emit_moves ();
    1304                 :      25420 :   add_ranges_and_copies ();
    1305                 :            :   /* Clean up: */
    1306                 :    1708820 :   FOR_EACH_BB_FN (bb, cfun)
    1307                 :            :     {
    1308                 :    1683400 :       free_move_list (at_bb_start[bb->index]);
    1309                 :    1683400 :       free_move_list (at_bb_end[bb->index]);
    1310                 :    4220860 :       FOR_EACH_EDGE (e, ei, bb->succs)
    1311                 :            :         {
    1312                 :    2537460 :           free_move_list ((move_t) e->aux);
    1313                 :    2537460 :           e->aux = NULL;
    1314                 :            :         }
    1315                 :            :     }
    1316                 :      25420 :   move_vec.release ();
    1317                 :      25420 :   ira_free (allocno_last_set_check);
    1318                 :      25420 :   ira_free (allocno_last_set);
    1319                 :      25420 :   commit_edge_insertions ();
    1320                 :            :   /* Fix insn codes.  It is necessary to do it before reload because
    1321                 :            :      reload assumes initial insn codes defined.  The insn codes can be
    1322                 :            :      invalidated by CFG infrastructure for example in jump
    1323                 :            :      redirection.  */
    1324                 :    1754660 :   FOR_EACH_BB_FN (bb, cfun)
    1325                 :   20461300 :     FOR_BB_INSNS_REVERSE (bb, insn)
    1326                 :   18732000 :       if (INSN_P (insn))
    1327                 :   34285500 :         recog_memoized (insn);
    1328                 :      25420 :   ira_free (at_bb_end);
    1329                 :      25420 :   ira_free (at_bb_start);
    1330                 :            : }

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.