LCOV - code coverage report
Current view: top level - gcc - df-core.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 78.3 % 849 665
Test Date: 2024-11-30 13:30:02 Functions: 70.9 % 79 56
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Allocation for dataflow support routines.
       2                 :             :    Copyright (C) 1999-2024 Free Software Foundation, Inc.
       3                 :             :    Originally contributed by Michael P. Hayes
       4                 :             :              (m.hayes@elec.canterbury.ac.nz, mhayes@redhat.com)
       5                 :             :    Major rewrite contributed by Danny Berlin (dberlin@dberlin.org)
       6                 :             :              and Kenneth Zadeck (zadeck@naturalbridge.com).
       7                 :             : 
       8                 :             : This file is part of GCC.
       9                 :             : 
      10                 :             : GCC is free software; you can redistribute it and/or modify it under
      11                 :             : the terms of the GNU General Public License as published by the Free
      12                 :             : Software Foundation; either version 3, or (at your option) any later
      13                 :             : version.
      14                 :             : 
      15                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      16                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      17                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      18                 :             : for more details.
      19                 :             : 
      20                 :             : You should have received a copy of the GNU General Public License
      21                 :             : along with GCC; see the file COPYING3.  If not see
      22                 :             : <http://www.gnu.org/licenses/>.  */
      23                 :             : 
      24                 :             : /*
      25                 :             : OVERVIEW:
      26                 :             : 
      27                 :             : The files in this collection (df*.c,df.h) provide a general framework
      28                 :             : for solving dataflow problems.  The global dataflow is performed using
      29                 :             : a good implementation of iterative dataflow analysis.
      30                 :             : 
      31                 :             : The file df-problems.cc provides problem instance for the most common
      32                 :             : dataflow problems: reaching defs, upward exposed uses, live variables,
      33                 :             : uninitialized variables, def-use chains, and use-def chains.  However,
      34                 :             : the interface allows other dataflow problems to be defined as well.
      35                 :             : 
      36                 :             : Dataflow analysis is available in most of the rtl backend (the parts
      37                 :             : between pass_df_initialize and pass_df_finish).  It is quite likely
      38                 :             : that these boundaries will be expanded in the future.  The only
      39                 :             : requirement is that there be a correct control flow graph.
      40                 :             : 
      41                 :             : There are three variations of the live variable problem that are
      42                 :             : available whenever dataflow is available.  The LR problem finds the
      43                 :             : areas that can reach a use of a variable, the UR problems finds the
      44                 :             : areas that can be reached from a definition of a variable.  The LIVE
      45                 :             : problem finds the intersection of these two areas.
      46                 :             : 
      47                 :             : There are several optional problems.  These can be enabled when they
      48                 :             : are needed and disabled when they are not needed.
      49                 :             : 
      50                 :             : Dataflow problems are generally solved in three layers.  The bottom
      51                 :             : layer is called scanning where a data structure is built for each rtl
      52                 :             : insn that describes the set of defs and uses of that insn.  Scanning
      53                 :             : is generally kept up to date, i.e. as the insns changes, the scanned
      54                 :             : version of that insn changes also.  There are various mechanisms for
      55                 :             : making this happen and are described in the INCREMENTAL SCANNING
      56                 :             : section.
      57                 :             : 
      58                 :             : In the middle layer, basic blocks are scanned to produce transfer
      59                 :             : functions which describe the effects of that block on the global
      60                 :             : dataflow solution.  The transfer functions are only rebuilt if the
      61                 :             : some instruction within the block has changed.
      62                 :             : 
      63                 :             : The top layer is the dataflow solution itself.  The dataflow solution
      64                 :             : is computed by using an efficient iterative solver and the transfer
      65                 :             : functions.  The dataflow solution must be recomputed whenever the
      66                 :             : control changes or if one of the transfer function changes.
      67                 :             : 
      68                 :             : 
      69                 :             : USAGE:
      70                 :             : 
      71                 :             : Here is an example of using the dataflow routines.
      72                 :             : 
      73                 :             :       df_[chain,live,note,rd]_add_problem (flags);
      74                 :             : 
      75                 :             :       df_set_blocks (blocks);
      76                 :             : 
      77                 :             :       df_analyze ();
      78                 :             : 
      79                 :             :       df_dump (stderr);
      80                 :             : 
      81                 :             :       df_finish_pass (false);
      82                 :             : 
      83                 :             : DF_[chain,live,note,rd]_ADD_PROBLEM adds a problem, defined by an
      84                 :             : instance to struct df_problem, to the set of problems solved in this
      85                 :             : instance of df.  All calls to add a problem for a given instance of df
      86                 :             : must occur before the first call to DF_ANALYZE.
      87                 :             : 
      88                 :             : Problems can be dependent on other problems.  For instance, solving
      89                 :             : def-use or use-def chains is dependent on solving reaching
      90                 :             : definitions. As long as these dependencies are listed in the problem
      91                 :             : definition, the order of adding the problems is not material.
      92                 :             : Otherwise, the problems will be solved in the order of calls to
      93                 :             : df_add_problem.  Note that it is not necessary to have a problem.  In
      94                 :             : that case, df will just be used to do the scanning.
      95                 :             : 
      96                 :             : 
      97                 :             : 
      98                 :             : DF_SET_BLOCKS is an optional call used to define a region of the
      99                 :             : function on which the analysis will be performed.  The normal case is
     100                 :             : to analyze the entire function and no call to df_set_blocks is made.
     101                 :             : DF_SET_BLOCKS only effects the blocks that are effected when computing
     102                 :             : the transfer functions and final solution.  The insn level information
     103                 :             : is always kept up to date.
     104                 :             : 
     105                 :             : When a subset is given, the analysis behaves as if the function only
     106                 :             : contains those blocks and any edges that occur directly between the
     107                 :             : blocks in the set.  Care should be taken to call df_set_blocks right
     108                 :             : before the call to analyze in order to eliminate the possibility that
     109                 :             : optimizations that reorder blocks invalidate the bitvector.
     110                 :             : 
     111                 :             : DF_ANALYZE causes all of the defined problems to be (re)solved.  When
     112                 :             : DF_ANALYZE is completes, the IN and OUT sets for each basic block
     113                 :             : contain the computer information.  The DF_*_BB_INFO macros can be used
     114                 :             : to access these bitvectors.  All deferred rescannings are down before
     115                 :             : the transfer functions are recomputed.
     116                 :             : 
     117                 :             : DF_DUMP can then be called to dump the information produce to some
     118                 :             : file.  This calls DF_DUMP_START, to print the information that is not
     119                 :             : basic block specific, and then calls DF_DUMP_TOP and DF_DUMP_BOTTOM
     120                 :             : for each block to print the basic specific information.  These parts
     121                 :             : can all be called separately as part of a larger dump function.
     122                 :             : 
     123                 :             : 
     124                 :             : DF_FINISH_PASS causes df_remove_problem to be called on all of the
     125                 :             : optional problems.  It also causes any insns whose scanning has been
     126                 :             : deferred to be rescanned as well as clears all of the changeable flags.
     127                 :             : Setting the pass manager TODO_df_finish flag causes this function to
     128                 :             : be run.  However, the pass manager will call df_finish_pass AFTER the
     129                 :             : pass dumping has been done, so if you want to see the results of the
     130                 :             : optional problems in the pass dumps, use the TODO flag rather than
     131                 :             : calling the function yourself.
     132                 :             : 
     133                 :             : INCREMENTAL SCANNING
     134                 :             : 
     135                 :             : There are four ways of doing the incremental scanning:
     136                 :             : 
     137                 :             : 1) Immediate rescanning - Calls to df_insn_rescan, df_notes_rescan,
     138                 :             :    df_bb_delete, df_insn_change_bb have been added to most of
     139                 :             :    the low level service functions that maintain the cfg and change
     140                 :             :    rtl.  Calling and of these routines many cause some number of insns
     141                 :             :    to be rescanned.
     142                 :             : 
     143                 :             :    For most modern rtl passes, this is certainly the easiest way to
     144                 :             :    manage rescanning the insns.  This technique also has the advantage
     145                 :             :    that the scanning information is always correct and can be relied
     146                 :             :    upon even after changes have been made to the instructions.  This
     147                 :             :    technique is contra indicated in several cases:
     148                 :             : 
     149                 :             :    a) If def-use chains OR use-def chains (but not both) are built,
     150                 :             :       using this is SIMPLY WRONG.  The problem is that when a ref is
     151                 :             :       deleted that is the target of an edge, there is not enough
     152                 :             :       information to efficiently find the source of the edge and
     153                 :             :       delete the edge.  This leaves a dangling reference that may
     154                 :             :       cause problems.
     155                 :             : 
     156                 :             :    b) If def-use chains AND use-def chains are built, this may
     157                 :             :       produce unexpected results.  The problem is that the incremental
     158                 :             :       scanning of an insn does not know how to repair the chains that
     159                 :             :       point into an insn when the insn changes.  So the incremental
     160                 :             :       scanning just deletes the chains that enter and exit the insn
     161                 :             :       being changed.  The dangling reference issue in (a) is not a
     162                 :             :       problem here, but if the pass is depending on the chains being
     163                 :             :       maintained after insns have been modified, this technique will
     164                 :             :       not do the correct thing.
     165                 :             : 
     166                 :             :    c) If the pass modifies insns several times, this incremental
     167                 :             :       updating may be expensive.
     168                 :             : 
     169                 :             :    d) If the pass modifies all of the insns, as does register
     170                 :             :       allocation, it is simply better to rescan the entire function.
     171                 :             : 
     172                 :             : 2) Deferred rescanning - Calls to df_insn_rescan, df_notes_rescan, and
     173                 :             :    df_insn_delete do not immediately change the insn but instead make
     174                 :             :    a note that the insn needs to be rescanned.  The next call to
     175                 :             :    df_analyze, df_finish_pass, or df_process_deferred_rescans will
     176                 :             :    cause all of the pending rescans to be processed.
     177                 :             : 
     178                 :             :    This is the technique of choice if either 1a, 1b, or 1c are issues
     179                 :             :    in the pass.  In the case of 1a or 1b, a call to df_finish_pass
     180                 :             :    (either manually or via TODO_df_finish) should be made before the
     181                 :             :    next call to df_analyze or df_process_deferred_rescans.
     182                 :             : 
     183                 :             :    This mode is also used by a few passes that still rely on note_uses,
     184                 :             :    note_stores and rtx iterators instead of using the DF data.  This
     185                 :             :    can be said to fall under case 1c.
     186                 :             : 
     187                 :             :    To enable this mode, call df_set_flags (DF_DEFER_INSN_RESCAN).
     188                 :             :    (This mode can be cleared by calling df_clear_flags
     189                 :             :    (DF_DEFER_INSN_RESCAN) but this does not cause the deferred insns to
     190                 :             :    be rescanned.
     191                 :             : 
     192                 :             : 3) Total rescanning - In this mode the rescanning is disabled.
     193                 :             :    Only when insns are deleted is the df information associated with
     194                 :             :    it also deleted.  At the end of the pass, a call must be made to
     195                 :             :    df_insn_rescan_all.  This method is used by the register allocator
     196                 :             :    since it generally changes each insn multiple times (once for each ref)
     197                 :             :    and does not need to make use of the updated scanning information.
     198                 :             : 
     199                 :             : 4) Do it yourself - In this mechanism, the pass updates the insns
     200                 :             :    itself using the low level df primitives.  Currently no pass does
     201                 :             :    this, but it has the advantage that it is quite efficient given
     202                 :             :    that the pass generally has exact knowledge of what it is changing.
     203                 :             : 
     204                 :             : DATA STRUCTURES
     205                 :             : 
     206                 :             : Scanning produces a `struct df_ref' data structure (ref) is allocated
     207                 :             : for every register reference (def or use) and this records the insn
     208                 :             : and bb the ref is found within.  The refs are linked together in
     209                 :             : chains of uses and defs for each insn and for each register.  Each ref
     210                 :             : also has a chain field that links all the use refs for a def or all
     211                 :             : the def refs for a use.  This is used to create use-def or def-use
     212                 :             : chains.
     213                 :             : 
     214                 :             : Different optimizations have different needs.  Ultimately, only
     215                 :             : register allocation and schedulers should be using the bitmaps
     216                 :             : produced for the live register and uninitialized register problems.
     217                 :             : The rest of the backend should be upgraded to using and maintaining
     218                 :             : the linked information such as def use or use def chains.
     219                 :             : 
     220                 :             : 
     221                 :             : PHILOSOPHY:
     222                 :             : 
     223                 :             : While incremental bitmaps are not worthwhile to maintain, incremental
     224                 :             : chains may be perfectly reasonable.  The fastest way to build chains
     225                 :             : from scratch or after significant modifications is to build reaching
     226                 :             : definitions (RD) and build the chains from this.
     227                 :             : 
     228                 :             : However, general algorithms for maintaining use-def or def-use chains
     229                 :             : are not practical.  The amount of work to recompute the chain any
     230                 :             : chain after an arbitrary change is large.  However, with a modest
     231                 :             : amount of work it is generally possible to have the application that
     232                 :             : uses the chains keep them up to date.  The high level knowledge of
     233                 :             : what is really happening is essential to crafting efficient
     234                 :             : incremental algorithms.
     235                 :             : 
     236                 :             : As for the bit vector problems, there is no interface to give a set of
     237                 :             : blocks over with to resolve the iteration.  In general, restarting a
     238                 :             : dataflow iteration is difficult and expensive.  Again, the best way to
     239                 :             : keep the dataflow information up to data (if this is really what is
     240                 :             : needed) it to formulate a problem specific solution.
     241                 :             : 
     242                 :             : There are fine grained calls for creating and deleting references from
     243                 :             : instructions in df-scan.cc.  However, these are not currently connected
     244                 :             : to the engine that resolves the dataflow equations.
     245                 :             : 
     246                 :             : 
     247                 :             : DATA STRUCTURES:
     248                 :             : 
     249                 :             : The basic object is a DF_REF (reference) and this may either be a
     250                 :             : DEF (definition) or a USE of a register.
     251                 :             : 
     252                 :             : These are linked into a variety of lists; namely reg-def, reg-use,
     253                 :             : insn-def, insn-use, def-use, and use-def lists.  For example, the
     254                 :             : reg-def lists contain all the locations that define a given register
     255                 :             : while the insn-use lists contain all the locations that use a
     256                 :             : register.
     257                 :             : 
     258                 :             : Note that the reg-def and reg-use chains are generally short for
     259                 :             : pseudos and long for the hard registers.
     260                 :             : 
     261                 :             : ACCESSING INSNS:
     262                 :             : 
     263                 :             : 1) The df insn information is kept in an array of DF_INSN_INFO objects.
     264                 :             :    The array is indexed by insn uid, and every DF_REF points to the
     265                 :             :    DF_INSN_INFO object of the insn that contains the reference.
     266                 :             : 
     267                 :             : 2) Each insn has three sets of refs, which are linked into one of three
     268                 :             :    lists: The insn's defs list (accessed by the DF_INSN_INFO_DEFS,
     269                 :             :    DF_INSN_DEFS, or DF_INSN_UID_DEFS macros), the insn's uses list
     270                 :             :    (accessed by the DF_INSN_INFO_USES, DF_INSN_USES, or
     271                 :             :    DF_INSN_UID_USES macros) or the insn's eq_uses list (accessed by the
     272                 :             :    DF_INSN_INFO_EQ_USES, DF_INSN_EQ_USES or DF_INSN_UID_EQ_USES macros).
     273                 :             :    The latter list are the list of references in REG_EQUAL or REG_EQUIV
     274                 :             :    notes.  These macros produce a ref (or NULL), the rest of the list
     275                 :             :    can be obtained by traversal of the NEXT_REF field (accessed by the
     276                 :             :    DF_REF_NEXT_REF macro.)  There is no significance to the ordering of
     277                 :             :    the uses or refs in an instruction.
     278                 :             : 
     279                 :             : 3) Each insn has a logical uid field (LUID) which is stored in the
     280                 :             :    DF_INSN_INFO object for the insn.  The LUID field is accessed by
     281                 :             :    the DF_INSN_INFO_LUID, DF_INSN_LUID, and DF_INSN_UID_LUID macros.
     282                 :             :    When properly set, the LUID is an integer that numbers each insn in
     283                 :             :    the basic block, in order from the start of the block.
     284                 :             :    The numbers are only correct after a call to df_analyze.  They will
     285                 :             :    rot after insns are added deleted or moved round.
     286                 :             : 
     287                 :             : ACCESSING REFS:
     288                 :             : 
     289                 :             : There are 4 ways to obtain access to refs:
     290                 :             : 
     291                 :             : 1) References are divided into two categories, REAL and ARTIFICIAL.
     292                 :             : 
     293                 :             :    REAL refs are associated with instructions.
     294                 :             : 
     295                 :             :    ARTIFICIAL refs are associated with basic blocks.  The heads of
     296                 :             :    these lists can be accessed by calling df_get_artificial_defs or
     297                 :             :    df_get_artificial_uses for the particular basic block.
     298                 :             : 
     299                 :             :    Artificial defs and uses occur both at the beginning and ends of blocks.
     300                 :             : 
     301                 :             :      For blocks that are at the destination of eh edges, the
     302                 :             :      artificial uses and defs occur at the beginning.  The defs relate
     303                 :             :      to the registers specified in EH_RETURN_DATA_REGNO and the uses
     304                 :             :      relate to the registers specified in EH_USES.  Logically these
     305                 :             :      defs and uses should really occur along the eh edge, but there is
     306                 :             :      no convenient way to do this.  Artificial defs that occur at the
     307                 :             :      beginning of the block have the DF_REF_AT_TOP flag set.
     308                 :             : 
     309                 :             :      Artificial uses occur at the end of all blocks.  These arise from
     310                 :             :      the hard registers that are always live, such as the stack
     311                 :             :      register and are put there to keep the code from forgetting about
     312                 :             :      them.
     313                 :             : 
     314                 :             :      Artificial defs occur at the end of the entry block.  These arise
     315                 :             :      from registers that are live at entry to the function.
     316                 :             : 
     317                 :             : 2) There are three types of refs: defs, uses and eq_uses.  (Eq_uses are
     318                 :             :    uses that appear inside a REG_EQUAL or REG_EQUIV note.)
     319                 :             : 
     320                 :             :    All of the eq_uses, uses and defs associated with each pseudo or
     321                 :             :    hard register may be linked in a bidirectional chain.  These are
     322                 :             :    called reg-use or reg_def chains.  If the changeable flag
     323                 :             :    DF_EQ_NOTES is set when the chains are built, the eq_uses will be
     324                 :             :    treated like uses.  If it is not set they are ignored.
     325                 :             : 
     326                 :             :    The first use, eq_use or def for a register can be obtained using
     327                 :             :    the DF_REG_USE_CHAIN, DF_REG_EQ_USE_CHAIN or DF_REG_DEF_CHAIN
     328                 :             :    macros.  Subsequent uses for the same regno can be obtained by
     329                 :             :    following the next_reg field of the ref.  The number of elements in
     330                 :             :    each of the chains can be found by using the DF_REG_USE_COUNT,
     331                 :             :    DF_REG_EQ_USE_COUNT or DF_REG_DEF_COUNT macros.
     332                 :             : 
     333                 :             :    In previous versions of this code, these chains were ordered.  It
     334                 :             :    has not been practical to continue this practice.
     335                 :             : 
     336                 :             : 3) If def-use or use-def chains are built, these can be traversed to
     337                 :             :    get to other refs.  If the flag DF_EQ_NOTES has been set, the chains
     338                 :             :    include the eq_uses.  Otherwise these are ignored when building the
     339                 :             :    chains.
     340                 :             : 
     341                 :             : 4) An array of all of the uses (and an array of all of the defs) can
     342                 :             :    be built.  These arrays are indexed by the value in the id
     343                 :             :    structure.  These arrays are only lazily kept up to date, and that
     344                 :             :    process can be expensive.  To have these arrays built, call
     345                 :             :    df_reorganize_defs or df_reorganize_uses.  If the flag DF_EQ_NOTES
     346                 :             :    has been set the array will contain the eq_uses.  Otherwise these
     347                 :             :    are ignored when building the array and assigning the ids.  Note
     348                 :             :    that the values in the id field of a ref may change across calls to
     349                 :             :    df_analyze or df_reorganize_defs or df_reorganize_uses.
     350                 :             : 
     351                 :             :    If the only use of this array is to find all of the refs, it is
     352                 :             :    better to traverse all of the registers and then traverse all of
     353                 :             :    reg-use or reg-def chains.
     354                 :             : 
     355                 :             : NOTES:
     356                 :             : 
     357                 :             : Embedded addressing side-effects, such as POST_INC or PRE_INC, generate
     358                 :             : both a use and a def.  These are both marked read/write to show that they
     359                 :             : are dependent. For example, (set (reg 40) (mem (post_inc (reg 42))))
     360                 :             : will generate a use of reg 42 followed by a def of reg 42 (both marked
     361                 :             : read/write).  Similarly, (set (reg 40) (mem (pre_dec (reg 41))))
     362                 :             : generates a use of reg 41 then a def of reg 41 (both marked read/write),
     363                 :             : even though reg 41 is decremented before it is used for the memory
     364                 :             : address in this second example.
     365                 :             : 
     366                 :             : A set to a REG inside a ZERO_EXTRACT, or a set to a non-paradoxical SUBREG
     367                 :             : for which the number of word_mode units covered by the outer mode is
     368                 :             : smaller than that covered by the inner mode, invokes a read-modify-write
     369                 :             : operation.  We generate both a use and a def and again mark them
     370                 :             : read/write.
     371                 :             : 
     372                 :             : Paradoxical subreg writes do not leave a trace of the old content, so they
     373                 :             : are write-only operations.
     374                 :             : */
     375                 :             : 
     376                 :             : 
     377                 :             : #include "config.h"
     378                 :             : #include "system.h"
     379                 :             : #include "coretypes.h"
     380                 :             : #include "backend.h"
     381                 :             : #include "rtl.h"
     382                 :             : #include "df.h"
     383                 :             : #include "memmodel.h"
     384                 :             : #include "emit-rtl.h"
     385                 :             : #include "cfganal.h"
     386                 :             : #include "tree-pass.h"
     387                 :             : #include "cfgloop.h"
     388                 :             : 
     389                 :             : static void *df_get_bb_info (struct dataflow *, unsigned int);
     390                 :             : static void df_set_bb_info (struct dataflow *, unsigned int, void *);
     391                 :             : static void df_clear_bb_info (struct dataflow *, unsigned int);
     392                 :             : #ifdef DF_DEBUG_CFG
     393                 :             : static void df_set_clean_cfg (void);
     394                 :             : #endif
     395                 :             : 
     396                 :             : /* The obstack on which regsets are allocated.  */
     397                 :             : struct bitmap_obstack reg_obstack;
     398                 :             : 
     399                 :             : /* An obstack for bitmap not related to specific dataflow problems.
     400                 :             :    This obstack should e.g. be used for bitmaps with a short life time
     401                 :             :    such as temporary bitmaps.  */
     402                 :             : 
     403                 :             : bitmap_obstack df_bitmap_obstack;
     404                 :             : 
     405                 :             : 
     406                 :             : /*----------------------------------------------------------------------------
     407                 :             :   Functions to create, destroy and manipulate an instance of df.
     408                 :             : ----------------------------------------------------------------------------*/
     409                 :             : 
     410                 :             : class df_d *df;
     411                 :             : 
     412                 :             : /* Add PROBLEM (and any dependent problems) to the DF instance.  */
     413                 :             : 
     414                 :             : void
     415                 :    46175360 : df_add_problem (const struct df_problem *problem)
     416                 :             : {
     417                 :    46175360 :   struct dataflow *dflow;
     418                 :    46175360 :   int i;
     419                 :             : 
     420                 :             :   /* First try to add the dependent problem. */
     421                 :    46175360 :   if (problem->dependent_problem)
     422                 :    21785044 :     df_add_problem (problem->dependent_problem);
     423                 :             : 
     424                 :             :   /* Check to see if this problem has already been defined.  If it
     425                 :             :      has, just return that instance, if not, add it to the end of the
     426                 :             :      vector.  */
     427                 :    46175360 :   dflow = df->problems_by_index[problem->id];
     428                 :    46175360 :   if (dflow)
     429                 :             :     return;
     430                 :             : 
     431                 :             :   /* Make a new one and add it to the end.  */
     432                 :    30592399 :   dflow = XCNEW (struct dataflow);
     433                 :    30592399 :   dflow->problem = problem;
     434                 :    30592399 :   dflow->computed = false;
     435                 :    30592399 :   dflow->solutions_dirty = true;
     436                 :    30592399 :   df->problems_by_index[dflow->problem->id] = dflow;
     437                 :             : 
     438                 :             :   /* Keep the defined problems ordered by index.  This solves the
     439                 :             :      problem that RI will use the information from UREC if UREC has
     440                 :             :      been defined, or from LIVE if LIVE is defined and otherwise LR.
     441                 :             :      However for this to work, the computation of RI must be pushed
     442                 :             :      after which ever of those problems is defined, but we do not
     443                 :             :      require any of those except for LR to have actually been
     444                 :             :      defined.  */
     445                 :    30592399 :   df->num_problems_defined++;
     446                 :    31069312 :   for (i = df->num_problems_defined - 2; i >= 0; i--)
     447                 :             :     {
     448                 :    29582608 :       if (problem->id < df->problems_in_order[i]->problem->id)
     449                 :      476913 :         df->problems_in_order[i+1] = df->problems_in_order[i];
     450                 :             :       else
     451                 :             :         {
     452                 :    29105695 :           df->problems_in_order[i+1] = dflow;
     453                 :    29105695 :           return;
     454                 :             :         }
     455                 :             :     }
     456                 :     1486704 :   df->problems_in_order[0] = dflow;
     457                 :             : }
     458                 :             : 
     459                 :             : 
     460                 :             : /* Set the MASK flags in the DFLOW problem.  The old flags are
     461                 :             :    returned.  If a flag is not allowed to be changed this will fail if
     462                 :             :    checking is enabled.  */
     463                 :             : int
     464                 :    49963729 : df_set_flags (int changeable_flags)
     465                 :             : {
     466                 :    49963729 :   int old_flags = df->changeable_flags;
     467                 :    49963729 :   df->changeable_flags |= changeable_flags;
     468                 :    49963729 :   return old_flags;
     469                 :             : }
     470                 :             : 
     471                 :             : 
     472                 :             : /* Clear the MASK flags in the DFLOW problem.  The old flags are
     473                 :             :    returned.  If a flag is not allowed to be changed this will fail if
     474                 :             :    checking is enabled.  */
     475                 :             : int
     476                 :    27655580 : df_clear_flags (int changeable_flags)
     477                 :             : {
     478                 :    27655580 :   int old_flags = df->changeable_flags;
     479                 :    27655580 :   df->changeable_flags &= ~changeable_flags;
     480                 :    27655580 :   return old_flags;
     481                 :             : }
     482                 :             : 
     483                 :             : 
     484                 :             : /* Set the blocks that are to be considered for analysis.  If this is
     485                 :             :    not called or is called with null, the entire function in
     486                 :             :    analyzed.  */
     487                 :             : 
     488                 :             : void
     489                 :     1444676 : df_set_blocks (bitmap blocks)
     490                 :             : {
     491                 :     1444676 :   if (blocks)
     492                 :             :     {
     493                 :     1444676 :       if (dump_file)
     494                 :         195 :         bitmap_print (dump_file, blocks, "setting blocks to analyze ", "\n");
     495                 :     1444676 :       if (df->blocks_to_analyze)
     496                 :             :         {
     497                 :             :           /* This block is called to change the focus from one subset
     498                 :             :              to another.  */
     499                 :      982122 :           int p;
     500                 :      982122 :           auto_bitmap diff (&df_bitmap_obstack);
     501                 :      982122 :           bitmap_and_compl (diff, df->blocks_to_analyze, blocks);
     502                 :     7351098 :           for (p = 0; p < df->num_problems_defined; p++)
     503                 :             :             {
     504                 :     6368976 :               struct dataflow *dflow = df->problems_in_order[p];
     505                 :     6368976 :               if (dflow->optional_p && dflow->problem->reset_fun)
     506                 :       43534 :                 dflow->problem->reset_fun (df->blocks_to_analyze);
     507                 :     6325442 :               else if (dflow->problem->free_blocks_on_set_blocks)
     508                 :             :                 {
     509                 :      982122 :                   bitmap_iterator bi;
     510                 :      982122 :                   unsigned int bb_index;
     511                 :             : 
     512                 :     4569831 :                   EXECUTE_IF_SET_IN_BITMAP (diff, 0, bb_index, bi)
     513                 :             :                     {
     514                 :     3587709 :                       basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
     515                 :     3587709 :                       if (bb)
     516                 :             :                         {
     517                 :     7175418 :                           void *bb_info = df_get_bb_info (dflow, bb_index);
     518                 :     3587709 :                           dflow->problem->free_bb_fun (bb, bb_info);
     519                 :     3587709 :                           df_clear_bb_info (dflow, bb_index);
     520                 :             :                         }
     521                 :             :                     }
     522                 :             :                 }
     523                 :             :             }
     524                 :      982122 :         }
     525                 :             :       else
     526                 :             :         {
     527                 :             :           /* This block of code is executed to change the focus from
     528                 :             :              the entire function to a subset.  */
     529                 :      462554 :           bitmap_head blocks_to_reset;
     530                 :      462554 :           bool initialized = false;
     531                 :      462554 :           int p;
     532                 :     3450705 :           for (p = 0; p < df->num_problems_defined; p++)
     533                 :             :             {
     534                 :     2988151 :               struct dataflow *dflow = df->problems_in_order[p];
     535                 :     2988151 :               if (dflow->optional_p && dflow->problem->reset_fun)
     536                 :             :                 {
     537                 :           0 :                   if (!initialized)
     538                 :             :                     {
     539                 :           0 :                       basic_block bb;
     540                 :           0 :                       bitmap_initialize (&blocks_to_reset, &df_bitmap_obstack);
     541                 :           0 :                       FOR_ALL_BB_FN (bb, cfun)
     542                 :             :                         {
     543                 :           0 :                           bitmap_set_bit (&blocks_to_reset, bb->index);
     544                 :             :                         }
     545                 :             :                     }
     546                 :           0 :                   dflow->problem->reset_fun (&blocks_to_reset);
     547                 :             :                 }
     548                 :             :             }
     549                 :      462554 :           if (initialized)
     550                 :             :             bitmap_clear (&blocks_to_reset);
     551                 :             : 
     552                 :      462554 :           df->blocks_to_analyze = BITMAP_ALLOC (&df_bitmap_obstack);
     553                 :             :         }
     554                 :     1444676 :       bitmap_copy (df->blocks_to_analyze, blocks);
     555                 :     1444676 :       df->analyze_subset = true;
     556                 :             :     }
     557                 :             :   else
     558                 :             :     {
     559                 :             :       /* This block is executed to reset the focus to the entire
     560                 :             :          function.  */
     561                 :           0 :       if (dump_file)
     562                 :           0 :         fprintf (dump_file, "clearing blocks_to_analyze\n");
     563                 :           0 :       if (df->blocks_to_analyze)
     564                 :             :         {
     565                 :           0 :           BITMAP_FREE (df->blocks_to_analyze);
     566                 :           0 :           df->blocks_to_analyze = NULL;
     567                 :             :         }
     568                 :           0 :       df->analyze_subset = false;
     569                 :             :     }
     570                 :             : 
     571                 :             :   /* Setting the blocks causes the refs to be unorganized since only
     572                 :             :      the refs in the blocks are seen.  */
     573                 :     1444676 :   df_maybe_reorganize_def_refs (DF_REF_ORDER_NO_TABLE);
     574                 :     1444676 :   df_maybe_reorganize_use_refs (DF_REF_ORDER_NO_TABLE);
     575                 :     1444676 :   df_mark_solutions_dirty ();
     576                 :     1444676 : }
     577                 :             : 
     578                 :             : 
     579                 :             : /* Delete a DFLOW problem (and any problems that depend on this
     580                 :             :    problem).  */
     581                 :             : 
     582                 :             : void
     583                 :    25376294 : df_remove_problem (struct dataflow *dflow)
     584                 :             : {
     585                 :    25376294 :   const struct df_problem *problem;
     586                 :    25376294 :   int i;
     587                 :             : 
     588                 :    25376294 :   if (!dflow)
     589                 :             :     return;
     590                 :             : 
     591                 :    25163341 :   problem = dflow->problem;
     592                 :    25163341 :   gcc_assert (problem->remove_problem_fun);
     593                 :             : 
     594                 :             :   /* Delete any problems that depended on this problem first.  */
     595                 :   160430112 :   for (i = 0; i < df->num_problems_defined; i++)
     596                 :   135266771 :     if (df->problems_in_order[i]->problem->dependent_problem == problem)
     597                 :     3973714 :       df_remove_problem (df->problems_in_order[i]);
     598                 :             : 
     599                 :             :   /* Now remove this problem.  */
     600                 :   128644541 :   for (i = 0; i < df->num_problems_defined; i++)
     601                 :   128644541 :     if (df->problems_in_order[i] == dflow)
     602                 :             :       {
     603                 :    25163341 :         int j;
     604                 :    28993869 :         for (j = i + 1; j < df->num_problems_defined; j++)
     605                 :     3830528 :           df->problems_in_order[j-1] = df->problems_in_order[j];
     606                 :    25163341 :         df->problems_in_order[j-1] = NULL;
     607                 :    25163341 :         df->num_problems_defined--;
     608                 :    25163341 :         break;
     609                 :             :       }
     610                 :             : 
     611                 :    25163341 :   (problem->remove_problem_fun) ();
     612                 :    25163341 :   df->problems_by_index[problem->id] = NULL;
     613                 :             : }
     614                 :             : 
     615                 :             : 
     616                 :             : /* Remove all of the problems that are not permanent.  Scanning, LR
     617                 :             :    and (at -O2 or higher) LIVE are permanent, the rest are removable.
     618                 :             :    Also clear all of the changeable_flags.  */
     619                 :             : 
     620                 :             : void
     621                 :    39383693 : df_finish_pass (bool verify ATTRIBUTE_UNUSED)
     622                 :             : {
     623                 :    39383693 :   int i;
     624                 :             : 
     625                 :             : #ifdef ENABLE_DF_CHECKING
     626                 :             :   int saved_flags;
     627                 :             : #endif
     628                 :             : 
     629                 :    39383693 :   if (!df)
     630                 :             :     return;
     631                 :             : 
     632                 :    39383692 :   df_maybe_reorganize_def_refs (DF_REF_ORDER_NO_TABLE);
     633                 :    39383692 :   df_maybe_reorganize_use_refs (DF_REF_ORDER_NO_TABLE);
     634                 :             : 
     635                 :             : #ifdef ENABLE_DF_CHECKING
     636                 :             :   saved_flags = df->changeable_flags;
     637                 :             : #endif
     638                 :             : 
     639                 :             :   /* We iterate over problems by index as each problem removed will
     640                 :             :      lead to problems_in_order to be reordered.  */
     641                 :   433220612 :   for (i = 0; i < DF_LAST_PROBLEM_PLUS1; i++)
     642                 :             :     {
     643                 :   393836920 :       struct dataflow *dflow = df->problems_by_index[i];
     644                 :             : 
     645                 :   393836920 :       if (dflow && dflow->optional_p)
     646                 :    17600766 :         df_remove_problem (dflow);
     647                 :             :     }
     648                 :             : 
     649                 :             :   /* Clear all of the flags.  */
     650                 :    39383692 :   df->changeable_flags = 0;
     651                 :    39383692 :   df_process_deferred_rescans ();
     652                 :             : 
     653                 :             :   /* Set the focus back to the whole function.  */
     654                 :    39383692 :   if (df->blocks_to_analyze)
     655                 :             :     {
     656                 :      462554 :       BITMAP_FREE (df->blocks_to_analyze);
     657                 :      462554 :       df->blocks_to_analyze = NULL;
     658                 :      462554 :       df_mark_solutions_dirty ();
     659                 :      462554 :       df->analyze_subset = false;
     660                 :             :     }
     661                 :             : 
     662                 :             : #ifdef ENABLE_DF_CHECKING
     663                 :             :   /* Verification will fail in DF_NO_INSN_RESCAN.  */
     664                 :             :   if (!(saved_flags & DF_NO_INSN_RESCAN))
     665                 :             :     {
     666                 :             :       df_lr_verify_transfer_functions ();
     667                 :             :       if (df_live)
     668                 :             :         df_live_verify_transfer_functions ();
     669                 :             :     }
     670                 :             : 
     671                 :             : #ifdef DF_DEBUG_CFG
     672                 :             :   df_set_clean_cfg ();
     673                 :             : #endif
     674                 :             : #endif
     675                 :             : 
     676                 :    39383692 :   if (flag_checking && verify)
     677                 :     5422025 :     df->changeable_flags |= DF_VERIFY_SCHEDULED;
     678                 :             : }
     679                 :             : 
     680                 :             : 
     681                 :             : /* Set up the dataflow instance for the entire back end.  */
     682                 :             : 
     683                 :             : static unsigned int
     684                 :     1486704 : rest_of_handle_df_initialize (void)
     685                 :             : {
     686                 :     1486704 :   gcc_assert (!df);
     687                 :     1486704 :   df = XCNEW (class df_d);
     688                 :     1486704 :   df->changeable_flags = 0;
     689                 :             : 
     690                 :     1486704 :   bitmap_obstack_initialize (&df_bitmap_obstack);
     691                 :             : 
     692                 :             :   /* Set this to a conservative value.  Stack_ptr_mod will compute it
     693                 :             :      correctly later.  */
     694                 :     1486704 :   crtl->sp_is_unchanging = 0;
     695                 :             : 
     696                 :     1486704 :   df_scan_add_problem ();
     697                 :     1486704 :   df_scan_alloc (NULL);
     698                 :             : 
     699                 :             :   /* These three problems are permanent.  */
     700                 :     1486704 :   df_lr_add_problem ();
     701                 :     1486704 :   if (optimize > 1)
     702                 :      968946 :     df_live_add_problem ();
     703                 :             : 
     704                 :     1486704 :   df->hard_regs_live_count = XCNEWVEC (unsigned int, FIRST_PSEUDO_REGISTER);
     705                 :             : 
     706                 :     1486704 :   df_hard_reg_init ();
     707                 :             :   /* After reload, some ports add certain bits to regs_ever_live so
     708                 :             :      this cannot be reset.  */
     709                 :     1486704 :   df_compute_regs_ever_live (true);
     710                 :     1486704 :   df_scan_blocks ();
     711                 :     1486704 :   df_compute_regs_ever_live (false);
     712                 :     1486704 :   return 0;
     713                 :             : }
     714                 :             : 
     715                 :             : 
     716                 :             : namespace {
     717                 :             : 
     718                 :             : const pass_data pass_data_df_initialize_opt =
     719                 :             : {
     720                 :             :   RTL_PASS, /* type */
     721                 :             :   "dfinit", /* name */
     722                 :             :   OPTGROUP_NONE, /* optinfo_flags */
     723                 :             :   TV_DF_SCAN, /* tv_id */
     724                 :             :   0, /* properties_required */
     725                 :             :   0, /* properties_provided */
     726                 :             :   0, /* properties_destroyed */
     727                 :             :   0, /* todo_flags_start */
     728                 :             :   0, /* todo_flags_finish */
     729                 :             : };
     730                 :             : 
     731                 :             : class pass_df_initialize_opt : public rtl_opt_pass
     732                 :             : {
     733                 :             : public:
     734                 :      281608 :   pass_df_initialize_opt (gcc::context *ctxt)
     735                 :      563216 :     : rtl_opt_pass (pass_data_df_initialize_opt, ctxt)
     736                 :             :   {}
     737                 :             : 
     738                 :             :   /* opt_pass methods: */
     739                 :     1486709 :   bool gate (function *) final override { return optimize > 0; }
     740                 :     1051273 :   unsigned int execute (function *) final override
     741                 :             :     {
     742                 :     1051273 :       return rest_of_handle_df_initialize ();
     743                 :             :     }
     744                 :             : 
     745                 :             : }; // class pass_df_initialize_opt
     746                 :             : 
     747                 :             : } // anon namespace
     748                 :             : 
     749                 :             : rtl_opt_pass *
     750                 :      281608 : make_pass_df_initialize_opt (gcc::context *ctxt)
     751                 :             : {
     752                 :      281608 :   return new pass_df_initialize_opt (ctxt);
     753                 :             : }
     754                 :             : 
     755                 :             : 
     756                 :             : namespace {
     757                 :             : 
     758                 :             : const pass_data pass_data_df_initialize_no_opt =
     759                 :             : {
     760                 :             :   RTL_PASS, /* type */
     761                 :             :   "no-opt dfinit", /* name */
     762                 :             :   OPTGROUP_NONE, /* optinfo_flags */
     763                 :             :   TV_DF_SCAN, /* tv_id */
     764                 :             :   0, /* properties_required */
     765                 :             :   0, /* properties_provided */
     766                 :             :   0, /* properties_destroyed */
     767                 :             :   0, /* todo_flags_start */
     768                 :             :   0, /* todo_flags_finish */
     769                 :             : };
     770                 :             : 
     771                 :             : class pass_df_initialize_no_opt : public rtl_opt_pass
     772                 :             : {
     773                 :             : public:
     774                 :      281608 :   pass_df_initialize_no_opt (gcc::context *ctxt)
     775                 :      563216 :     : rtl_opt_pass (pass_data_df_initialize_no_opt, ctxt)
     776                 :             :   {}
     777                 :             : 
     778                 :             :   /* opt_pass methods: */
     779                 :     1486709 :   bool gate (function *) final override { return optimize == 0; }
     780                 :      435431 :   unsigned int execute (function *) final override
     781                 :             :     {
     782                 :      435431 :       return rest_of_handle_df_initialize ();
     783                 :             :     }
     784                 :             : 
     785                 :             : }; // class pass_df_initialize_no_opt
     786                 :             : 
     787                 :             : } // anon namespace
     788                 :             : 
     789                 :             : rtl_opt_pass *
     790                 :      281608 : make_pass_df_initialize_no_opt (gcc::context *ctxt)
     791                 :             : {
     792                 :      281608 :   return new pass_df_initialize_no_opt (ctxt);
     793                 :             : }
     794                 :             : 
     795                 :             : 
     796                 :             : /* Free all the dataflow info and the DF structure.  This should be
     797                 :             :    called from the df_finish macro which also NULLs the parm.  */
     798                 :             : 
     799                 :             : static unsigned int
     800                 :     1486704 : rest_of_handle_df_finish (void)
     801                 :             : {
     802                 :     1486704 :   int i;
     803                 :             : 
     804                 :     1486704 :   gcc_assert (df);
     805                 :             : 
     806                 :     6915762 :   for (i = 0; i < df->num_problems_defined; i++)
     807                 :             :     {
     808                 :     5429058 :       struct dataflow *dflow = df->problems_in_order[i];
     809                 :     5429058 :       if (dflow->problem->free_fun)
     810                 :     3942354 :         dflow->problem->free_fun ();
     811                 :             :     }
     812                 :             : 
     813                 :     1486704 :   free (df->postorder);
     814                 :     1486704 :   free (df->postorder_inverted);
     815                 :     1486704 :   free (df->hard_regs_live_count);
     816                 :     1486704 :   free (df);
     817                 :     1486704 :   df = NULL;
     818                 :             : 
     819                 :     1486704 :   bitmap_obstack_release (&df_bitmap_obstack);
     820                 :     1486704 :   return 0;
     821                 :             : }
     822                 :             : 
     823                 :             : 
     824                 :             : namespace {
     825                 :             : 
     826                 :             : const pass_data pass_data_df_finish =
     827                 :             : {
     828                 :             :   RTL_PASS, /* type */
     829                 :             :   "dfinish", /* name */
     830                 :             :   OPTGROUP_NONE, /* optinfo_flags */
     831                 :             :   TV_NONE, /* tv_id */
     832                 :             :   0, /* properties_required */
     833                 :             :   0, /* properties_provided */
     834                 :             :   0, /* properties_destroyed */
     835                 :             :   0, /* todo_flags_start */
     836                 :             :   0, /* todo_flags_finish */
     837                 :             : };
     838                 :             : 
     839                 :             : class pass_df_finish : public rtl_opt_pass
     840                 :             : {
     841                 :             : public:
     842                 :      281608 :   pass_df_finish (gcc::context *ctxt)
     843                 :      563216 :     : rtl_opt_pass (pass_data_df_finish, ctxt)
     844                 :             :   {}
     845                 :             : 
     846                 :             :   /* opt_pass methods: */
     847                 :     1486704 :   unsigned int execute (function *) final override
     848                 :             :     {
     849                 :     1486704 :       return rest_of_handle_df_finish ();
     850                 :             :     }
     851                 :             : 
     852                 :             : }; // class pass_df_finish
     853                 :             : 
     854                 :             : } // anon namespace
     855                 :             : 
     856                 :             : rtl_opt_pass *
     857                 :      281608 : make_pass_df_finish (gcc::context *ctxt)
     858                 :             : {
     859                 :      281608 :   return new pass_df_finish (ctxt);
     860                 :             : }
     861                 :             : 
     862                 :             : 
     863                 :             : 
     864                 :             : 
     865                 :             : 
     866                 :             : /*----------------------------------------------------------------------------
     867                 :             :    The general data flow analysis engine.
     868                 :             : ----------------------------------------------------------------------------*/
     869                 :             : 
     870                 :             : /* Helper function for df_worklist_dataflow.
     871                 :             :    Propagate the dataflow forward.
     872                 :             :    Given a BB_INDEX, do the dataflow propagation
     873                 :             :    and set bits on for successors in PENDING for earlier
     874                 :             :    and WORKLIST for later in bbindex_to_postorder
     875                 :             :    if the out set of the dataflow has changed.
     876                 :             : 
     877                 :             :    AGE specify time when BB was visited last time.
     878                 :             :    AGE of 0 means we are visiting for first time and need to
     879                 :             :    compute transfer function to initialize datastructures.
     880                 :             :    Otherwise we re-do transfer function only if something change
     881                 :             :    while computing confluence functions.
     882                 :             :    We need to compute confluence only of basic block that are younger
     883                 :             :    then last visit of the BB.
     884                 :             : 
     885                 :             :    Return true if BB info has changed.  This is always the case
     886                 :             :    in the first visit.  */
     887                 :             : 
     888                 :             : static bool
     889                 :   398642557 : df_worklist_propagate_forward (struct dataflow *dataflow,
     890                 :             :                                unsigned bb_index,
     891                 :             :                                unsigned *bbindex_to_postorder,
     892                 :             :                                bitmap worklist,
     893                 :             :                                bitmap pending,
     894                 :             :                                sbitmap considered,
     895                 :             :                                vec<int> &last_change_age,
     896                 :             :                                int age)
     897                 :             : {
     898                 :   398642557 :   edge e;
     899                 :   398642557 :   edge_iterator ei;
     900                 :   398642557 :   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
     901                 :   398642557 :   bool changed = !age;
     902                 :             : 
     903                 :             :   /*  Calculate <conf_op> of incoming edges.  */
     904                 :   398642557 :   if (EDGE_COUNT (bb->preds) > 0)
     905                 :   950999334 :     FOR_EACH_EDGE (e, ei, bb->preds)
     906                 :             :       {
     907                 :  1141505346 :         if (bbindex_to_postorder[e->src->index] < last_change_age.length ()
     908                 :   565156111 :             && age <= last_change_age[bbindex_to_postorder[e->src->index]]
     909                 :  1111641271 :             && bitmap_bit_p (considered, e->src->index))
     910                 :   540888598 :           changed |= dataflow->problem->con_fun_n (e);
     911                 :             :       }
     912                 :    18395896 :   else if (dataflow->problem->con_fun_0)
     913                 :     1391642 :     dataflow->problem->con_fun_0 (bb);
     914                 :             : 
     915                 :   398642557 :   if (changed
     916                 :   398642557 :       && dataflow->problem->trans_fun (bb_index))
     917                 :             :     {
     918                 :             :       /* The out set of this block has changed.
     919                 :             :          Propagate to the outgoing blocks.  */
     920                 :   834330598 :       FOR_EACH_EDGE (e, ei, bb->succs)
     921                 :             :         {
     922                 :   490300389 :           unsigned ob_index = e->dest->index;
     923                 :             : 
     924                 :   490300389 :           if (bitmap_bit_p (considered, ob_index))
     925                 :             :             {
     926                 :   482810299 :               if (bbindex_to_postorder[bb_index]
     927                 :   482810299 :                   < bbindex_to_postorder[ob_index])
     928                 :   458641767 :                 bitmap_set_bit (worklist, bbindex_to_postorder[ob_index]);
     929                 :             :               else
     930                 :    24168532 :                 bitmap_set_bit (pending, bbindex_to_postorder[ob_index]);
     931                 :             :             }
     932                 :             :         }
     933                 :             :       return true;
     934                 :             :     }
     935                 :             :   return false;
     936                 :             : }
     937                 :             : 
     938                 :             : 
     939                 :             : /* Helper function for df_worklist_dataflow.
     940                 :             :    Propagate the dataflow backward.  */
     941                 :             : 
     942                 :             : static bool
     943                 :   425591010 : df_worklist_propagate_backward (struct dataflow *dataflow,
     944                 :             :                                 unsigned bb_index,
     945                 :             :                                 unsigned *bbindex_to_postorder,
     946                 :             :                                 bitmap worklist,
     947                 :             :                                 bitmap pending,
     948                 :             :                                 sbitmap considered,
     949                 :             :                                 vec<int> &last_change_age,
     950                 :             :                                 int age)
     951                 :             : {
     952                 :   425591010 :   edge e;
     953                 :   425591010 :   edge_iterator ei;
     954                 :   425591010 :   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
     955                 :   425591010 :   bool changed = !age;
     956                 :             : 
     957                 :             :   /*  Calculate <conf_op> of incoming edges.  */
     958                 :   425591010 :   if (EDGE_COUNT (bb->succs) > 0)
     959                 :  1011780017 :     FOR_EACH_EDGE (e, ei, bb->succs)
     960                 :             :       {
     961                 :  1234506890 :         if (bbindex_to_postorder[e->dest->index] < last_change_age.length ()
     962                 :   612963067 :             && age <= last_change_age[bbindex_to_postorder[e->dest->index]]
     963                 :  1202430087 :             && bitmap_bit_p (considered, e->dest->index))
     964                 :   583177836 :           changed |= dataflow->problem->con_fun_n (e);
     965                 :             :       }
     966                 :    31064438 :   else if (dataflow->problem->con_fun_0)
     967                 :    27827764 :     dataflow->problem->con_fun_0 (bb);
     968                 :             : 
     969                 :   425591010 :   if (changed
     970                 :   425591010 :       && dataflow->problem->trans_fun (bb_index))
     971                 :             :     {
     972                 :             :       /* The out set of this block has changed.
     973                 :             :          Propagate to the outgoing blocks.  */
     974                 :   659506176 :       FOR_EACH_EDGE (e, ei, bb->preds)
     975                 :             :         {
     976                 :   383564535 :           unsigned ob_index = e->src->index;
     977                 :             : 
     978                 :   383564535 :           if (bitmap_bit_p (considered, ob_index))
     979                 :             :             {
     980                 :   381736519 :               if (bbindex_to_postorder[bb_index]
     981                 :   381736519 :                   < bbindex_to_postorder[ob_index])
     982                 :   360755258 :                 bitmap_set_bit (worklist, bbindex_to_postorder[ob_index]);
     983                 :             :               else
     984                 :    20981261 :                 bitmap_set_bit (pending, bbindex_to_postorder[ob_index]);
     985                 :             :             }
     986                 :             :         }
     987                 :             :       return true;
     988                 :             :     }
     989                 :             :   return false;
     990                 :             : }
     991                 :             : 
     992                 :             : /* Main dataflow solver loop.
     993                 :             : 
     994                 :             :    DATAFLOW is problem we are solving, PENDING is worklist of basic blocks we
     995                 :             :    need to visit.
     996                 :             :    BLOCK_IN_POSTORDER is array of size N_BLOCKS specifying postorder in BBs and
     997                 :             :    BBINDEX_TO_POSTORDER is array mapping back BB->index to postorder position.
     998                 :             :    PENDING will be freed.
     999                 :             : 
    1000                 :             :    The worklists are bitmaps indexed by postorder positions.
    1001                 :             : 
    1002                 :             :    The function implements standard algorithm for dataflow solving with two
    1003                 :             :    worklists (we are processing WORKLIST and storing new BBs to visit in
    1004                 :             :    PENDING).
    1005                 :             : 
    1006                 :             :    As an optimization we maintain ages when BB was changed (stored in
    1007                 :             :    last_change_age) and when it was last visited (stored in last_visit_age).
    1008                 :             :    This avoids need to re-do confluence function for edges to basic blocks
    1009                 :             :    whose source did not change since destination was visited last time.  */
    1010                 :             : 
    1011                 :             : static void
    1012                 :    39181412 : df_worklist_dataflow_doublequeue (struct dataflow *dataflow,
    1013                 :             :                                   bitmap pending,
    1014                 :             :                                   sbitmap considered,
    1015                 :             :                                   int *blocks_in_postorder,
    1016                 :             :                                   unsigned *bbindex_to_postorder,
    1017                 :             :                                   int n_blocks)
    1018                 :             : {
    1019                 :    39181412 :   enum df_flow_dir dir = dataflow->problem->dir;
    1020                 :    39181412 :   int dcount = 0;
    1021                 :    39181412 :   bitmap worklist = BITMAP_ALLOC (&df_bitmap_obstack);
    1022                 :    39181412 :   int age = 0;
    1023                 :    39181412 :   bool changed;
    1024                 :    39181412 :   vec<int> last_visit_age = vNULL;
    1025                 :    39181412 :   vec<int> last_change_age = vNULL;
    1026                 :    39181412 :   int prev_age;
    1027                 :             : 
    1028                 :    39181412 :   last_visit_age.safe_grow_cleared (n_blocks, true);
    1029                 :    39181412 :   last_change_age.safe_grow_cleared (n_blocks, true);
    1030                 :             : 
    1031                 :             :   /* Double-queueing. Worklist is for the current iteration,
    1032                 :             :      and pending is for the next. */
    1033                 :   132800086 :   while (!bitmap_empty_p (pending))
    1034                 :             :     {
    1035                 :             :       std::swap (pending, worklist);
    1036                 :             : 
    1037                 :   824233567 :       do
    1038                 :             :         {
    1039                 :   824233567 :           unsigned index = bitmap_clear_first_set_bit (worklist);
    1040                 :             : 
    1041                 :   824233567 :           unsigned bb_index;
    1042                 :   824233567 :           dcount++;
    1043                 :             : 
    1044                 :   824233567 :           bb_index = blocks_in_postorder[index];
    1045                 :   824233567 :           prev_age = last_visit_age[index];
    1046                 :   824233567 :           if (dir == DF_FORWARD)
    1047                 :   398642557 :             changed = df_worklist_propagate_forward (dataflow, bb_index,
    1048                 :             :                                                      bbindex_to_postorder,
    1049                 :             :                                                      worklist, pending,
    1050                 :             :                                                      considered,
    1051                 :             :                                                      last_change_age,
    1052                 :             :                                                      prev_age);
    1053                 :             :           else
    1054                 :   425591010 :             changed = df_worklist_propagate_backward (dataflow, bb_index,
    1055                 :             :                                                       bbindex_to_postorder,
    1056                 :             :                                                       worklist, pending,
    1057                 :             :                                                       considered,
    1058                 :             :                                                       last_change_age,
    1059                 :             :                                                       prev_age);
    1060                 :   824233567 :           last_visit_age[index] = ++age;
    1061                 :   824233567 :           if (changed)
    1062                 :   619971850 :             last_change_age[index] = age;
    1063                 :             :         }
    1064                 :   824233567 :       while (!bitmap_empty_p (worklist));
    1065                 :             :     }
    1066                 :             : 
    1067                 :    39181412 :   BITMAP_FREE (worklist);
    1068                 :    39181412 :   BITMAP_FREE (pending);
    1069                 :    39181412 :   last_visit_age.release ();
    1070                 :    39181412 :   last_change_age.release ();
    1071                 :             : 
    1072                 :             :   /* Dump statistics. */
    1073                 :    39181412 :   if (dump_file)
    1074                 :        1651 :     fprintf (dump_file, "df_worklist_dataflow_doublequeue:"
    1075                 :             :              " n_basic_blocks %d n_edges %d"
    1076                 :             :              " count %d (%5.2g)\n",
    1077                 :             :              n_basic_blocks_for_fn (cfun), n_edges_for_fn (cfun),
    1078                 :        1651 :              dcount, dcount / (double)n_basic_blocks_for_fn (cfun));
    1079                 :    39181412 : }
    1080                 :             : 
    1081                 :             : /* Worklist-based dataflow solver. It uses sbitmap as a worklist,
    1082                 :             :    with "n"-th bit representing the n-th block in the reverse-postorder order.
    1083                 :             :    The solver is a double-queue algorithm similar to the "double stack" solver
    1084                 :             :    from Cooper, Harvey and Kennedy, "Iterative data-flow analysis, Revisited".
    1085                 :             :    The only significant difference is that the worklist in this implementation
    1086                 :             :    is always sorted in RPO of the CFG visiting direction.  */
    1087                 :             : 
    1088                 :             : void
    1089                 :    39181412 : df_worklist_dataflow (struct dataflow *dataflow,
    1090                 :             :                       bitmap blocks_to_consider,
    1091                 :             :                       int *blocks_in_postorder,
    1092                 :             :                       int n_blocks)
    1093                 :             : {
    1094                 :    39181412 :   bitmap pending = BITMAP_ALLOC (&df_bitmap_obstack);
    1095                 :    39181412 :   bitmap_iterator bi;
    1096                 :    39181412 :   unsigned int *bbindex_to_postorder;
    1097                 :    39181412 :   int i;
    1098                 :    39181412 :   unsigned int index;
    1099                 :    39181412 :   enum df_flow_dir dir = dataflow->problem->dir;
    1100                 :             : 
    1101                 :    39181412 :   gcc_assert (dir != DF_NONE);
    1102                 :             : 
    1103                 :             :   /* BBINDEX_TO_POSTORDER maps the bb->index to the reverse postorder.  */
    1104                 :    39181412 :   bbindex_to_postorder = XNEWVEC (unsigned int,
    1105                 :             :                                   last_basic_block_for_fn (cfun));
    1106                 :             : 
    1107                 :             :   /* Initialize the array to an out-of-bound value.  */
    1108                 :  1442625854 :   for (i = 0; i < last_basic_block_for_fn (cfun); i++)
    1109                 :  1364263030 :     bbindex_to_postorder[i] = last_basic_block_for_fn (cfun);
    1110                 :             : 
    1111                 :             :   /* Initialize the considered map.  */
    1112                 :    39181412 :   auto_sbitmap considered (last_basic_block_for_fn (cfun));
    1113                 :    39181412 :   bitmap_clear (considered);
    1114                 :   754658037 :   EXECUTE_IF_SET_IN_BITMAP (blocks_to_consider, 0, index, bi)
    1115                 :             :     {
    1116                 :   715476625 :       bitmap_set_bit (considered, index);
    1117                 :             :     }
    1118                 :             : 
    1119                 :             :   /* Initialize the mapping of block index to postorder.  */
    1120                 :   758510193 :   for (i = 0; i < n_blocks; i++)
    1121                 :             :     {
    1122                 :   719328781 :       bbindex_to_postorder[blocks_in_postorder[i]] = i;
    1123                 :             :       /* Add all blocks to the worklist.  */
    1124                 :   719328781 :       bitmap_set_bit (pending, i);
    1125                 :             :     }
    1126                 :             : 
    1127                 :             :   /* Initialize the problem. */
    1128                 :    39181412 :   if (dataflow->problem->init_fun)
    1129                 :    36435123 :     dataflow->problem->init_fun (blocks_to_consider);
    1130                 :             : 
    1131                 :             :   /* Solve it.  */
    1132                 :    39181412 :   df_worklist_dataflow_doublequeue (dataflow, pending, considered,
    1133                 :             :                                     blocks_in_postorder,
    1134                 :             :                                     bbindex_to_postorder,
    1135                 :             :                                     n_blocks);
    1136                 :    39181412 :   free (bbindex_to_postorder);
    1137                 :    39181412 : }
    1138                 :             : 
    1139                 :             : 
    1140                 :             : /* Remove the entries not in BLOCKS from the LIST of length LEN, preserving
    1141                 :             :    the order of the remaining entries.  Returns the length of the resulting
    1142                 :             :    list.  */
    1143                 :             : 
    1144                 :             : static unsigned
    1145                 :           0 : df_prune_to_subcfg (int list[], unsigned len, bitmap blocks)
    1146                 :             : {
    1147                 :           0 :   unsigned act, last;
    1148                 :             : 
    1149                 :           0 :   for (act = 0, last = 0; act < len; act++)
    1150                 :           0 :     if (bitmap_bit_p (blocks, list[act]))
    1151                 :           0 :       list[last++] = list[act];
    1152                 :             : 
    1153                 :           0 :   return last;
    1154                 :             : }
    1155                 :             : 
    1156                 :             : 
    1157                 :             : /* Execute dataflow analysis on a single dataflow problem.
    1158                 :             : 
    1159                 :             :    BLOCKS_TO_CONSIDER are the blocks whose solution can either be
    1160                 :             :    examined or will be computed.  For calls from DF_ANALYZE, this is
    1161                 :             :    the set of blocks that has been passed to DF_SET_BLOCKS.
    1162                 :             : */
    1163                 :             : 
    1164                 :             : void
    1165                 :    80701737 : df_analyze_problem (struct dataflow *dflow,
    1166                 :             :                     bitmap blocks_to_consider,
    1167                 :             :                     int *postorder, int n_blocks)
    1168                 :             : {
    1169                 :    80701737 :   timevar_push (dflow->problem->tv_id);
    1170                 :             : 
    1171                 :             :   /* (Re)Allocate the datastructures necessary to solve the problem.  */
    1172                 :    80701737 :   if (dflow->problem->alloc_fun)
    1173                 :    57864985 :     dflow->problem->alloc_fun (blocks_to_consider);
    1174                 :             : 
    1175                 :             : #ifdef ENABLE_DF_CHECKING
    1176                 :             :   if (dflow->problem->verify_start_fun)
    1177                 :             :     dflow->problem->verify_start_fun ();
    1178                 :             : #endif
    1179                 :             : 
    1180                 :             :   /* Set up the problem and compute the local information.  */
    1181                 :    80701737 :   if (dflow->problem->local_compute_fun)
    1182                 :    51690675 :     dflow->problem->local_compute_fun (blocks_to_consider);
    1183                 :             : 
    1184                 :             :   /* Solve the equations.  */
    1185                 :    80701737 :   if (dflow->problem->dataflow_fun)
    1186                 :    35724387 :     dflow->problem->dataflow_fun (dflow, blocks_to_consider,
    1187                 :             :                                   postorder, n_blocks);
    1188                 :             : 
    1189                 :             :   /* Massage the solution.  */
    1190                 :    80701737 :   if (dflow->problem->finalize_fun)
    1191                 :    57442675 :     dflow->problem->finalize_fun (blocks_to_consider);
    1192                 :             : 
    1193                 :             : #ifdef ENABLE_DF_CHECKING
    1194                 :             :   if (dflow->problem->verify_end_fun)
    1195                 :             :     dflow->problem->verify_end_fun ();
    1196                 :             : #endif
    1197                 :             : 
    1198                 :    80701737 :   timevar_pop (dflow->problem->tv_id);
    1199                 :             : 
    1200                 :    80701737 :   dflow->computed = true;
    1201                 :    80701737 : }
    1202                 :             : 
    1203                 :             : 
    1204                 :             : /* Analyze dataflow info.  */
    1205                 :             : 
    1206                 :             : static void
    1207                 :    40840758 : df_analyze_1 (void)
    1208                 :             : {
    1209                 :    40840758 :   int i;
    1210                 :             : 
    1211                 :             :   /* We need to do this before the df_verify_all because this is
    1212                 :             :      not kept incrementally up to date.  */
    1213                 :    40840758 :   df_compute_regs_ever_live (false);
    1214                 :    40840758 :   df_process_deferred_rescans ();
    1215                 :             : 
    1216                 :    40840758 :   if (dump_file)
    1217                 :        1523 :     fprintf (dump_file, "df_analyze called\n");
    1218                 :             : 
    1219                 :             : #ifndef ENABLE_DF_CHECKING
    1220                 :    40840758 :   if (df->changeable_flags & DF_VERIFY_SCHEDULED)
    1221                 :             : #endif
    1222                 :     6496418 :     df_verify ();
    1223                 :             : 
    1224                 :             :   /* Skip over the DF_SCAN problem. */
    1225                 :   187129951 :   for (i = 1; i < df->num_problems_defined; i++)
    1226                 :             :     {
    1227                 :   146289193 :       struct dataflow *dflow = df->problems_in_order[i];
    1228                 :   146289193 :       if (dflow->solutions_dirty)
    1229                 :             :         {
    1230                 :    80701470 :           if (dflow->problem->dir == DF_FORWARD)
    1231                 :    20557131 :             df_analyze_problem (dflow,
    1232                 :             :                                 df->blocks_to_analyze,
    1233                 :             :                                 df->postorder_inverted,
    1234                 :             :                                 df->n_blocks);
    1235                 :             :           else
    1236                 :    60144339 :             df_analyze_problem (dflow,
    1237                 :             :                                 df->blocks_to_analyze,
    1238                 :             :                                 df->postorder,
    1239                 :             :                                 df->n_blocks);
    1240                 :             :         }
    1241                 :             :     }
    1242                 :             : 
    1243                 :    40840758 :   if (!df->analyze_subset)
    1244                 :             :     {
    1245                 :    39396082 :       BITMAP_FREE (df->blocks_to_analyze);
    1246                 :    39396082 :       df->blocks_to_analyze = NULL;
    1247                 :             :     }
    1248                 :             : 
    1249                 :             : #ifdef DF_DEBUG_CFG
    1250                 :             :   df_set_clean_cfg ();
    1251                 :             : #endif
    1252                 :    40840758 : }
    1253                 :             : 
    1254                 :             : /* Analyze dataflow info.  */
    1255                 :             : 
    1256                 :             : void
    1257                 :    39396082 : df_analyze (void)
    1258                 :             : {
    1259                 :    39396082 :   bitmap current_all_blocks = BITMAP_ALLOC (&df_bitmap_obstack);
    1260                 :             : 
    1261                 :    39396082 :   free (df->postorder);
    1262                 :    39396082 :   free (df->postorder_inverted);
    1263                 :             :   /* For DF_FORWARD use a RPO on the forward graph.  Since we want to
    1264                 :             :      have unreachable blocks deleted use post_order_compute and reverse
    1265                 :             :      the order.  */
    1266                 :    39396082 :   df->postorder_inverted = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
    1267                 :    39396082 :   df->n_blocks = post_order_compute (df->postorder_inverted, true, true);
    1268                 :   292585294 :   for (int i = 0; i < df->n_blocks / 2; ++i)
    1269                 :   253189212 :     std::swap (df->postorder_inverted[i],
    1270                 :   253189212 :                df->postorder_inverted[df->n_blocks - 1 - i]);
    1271                 :             :   /* For DF_BACKWARD use a RPO on the reverse graph.  */
    1272                 :    39396082 :   df->postorder = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
    1273                 :    39396082 :   int n = inverted_rev_post_order_compute (cfun, df->postorder);
    1274                 :    39396082 :   gcc_assert (n == df->n_blocks);
    1275                 :             : 
    1276                 :   576067323 :   for (int i = 0; i < df->n_blocks; i++)
    1277                 :   536671241 :     bitmap_set_bit (current_all_blocks, df->postorder[i]);
    1278                 :             : 
    1279                 :    39396082 :   if (flag_checking)
    1280                 :             :     {
    1281                 :             :       /* Verify that POSTORDER_INVERTED only contains blocks reachable from
    1282                 :             :          the ENTRY block.  */
    1283                 :   576063157 :       for (int i = 0; i < df->n_blocks; i++)
    1284                 :   536667680 :         gcc_assert (bitmap_bit_p (current_all_blocks,
    1285                 :             :                                   df->postorder_inverted[i]));
    1286                 :             :     }
    1287                 :             : 
    1288                 :             :   /* Make sure that we have pruned any unreachable blocks from these
    1289                 :             :      sets.  */
    1290                 :    39396082 :   if (df->analyze_subset)
    1291                 :             :     {
    1292                 :           0 :       bitmap_and_into (df->blocks_to_analyze, current_all_blocks);
    1293                 :           0 :       unsigned int newlen = df_prune_to_subcfg (df->postorder, df->n_blocks,
    1294                 :             :                                                 df->blocks_to_analyze);
    1295                 :           0 :       df_prune_to_subcfg (df->postorder_inverted, df->n_blocks,
    1296                 :             :                           df->blocks_to_analyze);
    1297                 :           0 :       df->n_blocks = newlen;
    1298                 :           0 :       BITMAP_FREE (current_all_blocks);
    1299                 :             :     }
    1300                 :             :   else
    1301                 :             :     {
    1302                 :    39396082 :       df->blocks_to_analyze = current_all_blocks;
    1303                 :    39396082 :       current_all_blocks = NULL;
    1304                 :             :     }
    1305                 :             : 
    1306                 :    39396082 :   df_analyze_1 ();
    1307                 :    39396082 : }
    1308                 :             : 
    1309                 :             : /* Compute the reverse top sort order of the sub-CFG specified by LOOP.
    1310                 :             :    Returns the number of blocks which is always loop->num_nodes.  */
    1311                 :             : 
    1312                 :             : static int
    1313                 :     1444676 : loop_rev_post_order_compute (int *post_order, class loop *loop)
    1314                 :             : {
    1315                 :     1444676 :   edge_iterator *stack;
    1316                 :     1444676 :   int sp;
    1317                 :     1444676 :   int post_order_num = loop->num_nodes - 1;
    1318                 :             : 
    1319                 :             :   /* Allocate stack for back-tracking up CFG.  */
    1320                 :     1444676 :   stack = XNEWVEC (edge_iterator, loop->num_nodes + 1);
    1321                 :     1444676 :   sp = 0;
    1322                 :             : 
    1323                 :             :   /* Allocate bitmap to track nodes that have been visited.  */
    1324                 :     1444676 :   auto_bitmap visited;
    1325                 :             : 
    1326                 :             :   /* Push the first edge on to the stack.  */
    1327                 :     1444676 :   stack[sp++] = ei_start (loop_preheader_edge (loop)->src->succs);
    1328                 :             : 
    1329                 :    23466308 :   while (sp)
    1330                 :             :     {
    1331                 :    22021632 :       edge_iterator ei;
    1332                 :    22021632 :       basic_block src;
    1333                 :    22021632 :       basic_block dest;
    1334                 :             : 
    1335                 :             :       /* Look at the edge on the top of the stack.  */
    1336                 :    22021632 :       ei = stack[sp - 1];
    1337                 :    22021632 :       src = ei_edge (ei)->src;
    1338                 :    22021632 :       dest = ei_edge (ei)->dest;
    1339                 :             : 
    1340                 :             :       /* Check if the edge destination has been visited yet and mark it
    1341                 :             :          if not so.  */
    1342                 :    22021632 :       if (flow_bb_inside_loop_p (loop, dest)
    1343                 :    22021632 :           && bitmap_set_bit (visited, dest->index))
    1344                 :             :         {
    1345                 :     7993512 :           if (EDGE_COUNT (dest->succs) > 0)
    1346                 :             :             /* Since the DEST node has been visited for the first
    1347                 :             :                time, check its successors.  */
    1348                 :     7993512 :             stack[sp++] = ei_start (dest->succs);
    1349                 :             :           else
    1350                 :           0 :             post_order[post_order_num--] = dest->index;
    1351                 :             :         }
    1352                 :             :       else
    1353                 :             :         {
    1354                 :    14028120 :           if (ei_one_before_end_p (ei)
    1355                 :    14028120 :               && src != loop_preheader_edge (loop)->src)
    1356                 :     7993512 :             post_order[post_order_num--] = src->index;
    1357                 :             : 
    1358                 :    14028120 :           if (!ei_one_before_end_p (ei))
    1359                 :     4589932 :             ei_next (&stack[sp - 1]);
    1360                 :             :           else
    1361                 :     9438188 :             sp--;
    1362                 :             :         }
    1363                 :             :     }
    1364                 :             : 
    1365                 :     1444676 :   free (stack);
    1366                 :             : 
    1367                 :     1444676 :   return loop->num_nodes;
    1368                 :     1444676 : }
    1369                 :             : 
    1370                 :             : /* Compute the reverse top sort order of the inverted sub-CFG specified
    1371                 :             :    by LOOP.  Returns the number of blocks which is always loop->num_nodes.  */
    1372                 :             : 
    1373                 :             : static int
    1374                 :     1444676 : loop_inverted_rev_post_order_compute (int *post_order, class loop *loop)
    1375                 :             : {
    1376                 :     1444676 :   basic_block bb;
    1377                 :     1444676 :   edge_iterator *stack;
    1378                 :     1444676 :   int sp;
    1379                 :     1444676 :   int post_order_num = loop->num_nodes - 1;
    1380                 :             : 
    1381                 :             :   /* Allocate stack for back-tracking up CFG.  */
    1382                 :     1444676 :   stack = XNEWVEC (edge_iterator, loop->num_nodes + 1);
    1383                 :     1444676 :   sp = 0;
    1384                 :             : 
    1385                 :             :   /* Allocate bitmap to track nodes that have been visited.  */
    1386                 :     1444676 :   auto_bitmap visited;
    1387                 :             : 
    1388                 :             :   /* Put all latches into the initial work list.  In theory we'd want
    1389                 :             :      to start from loop exits but then we'd have the special case of
    1390                 :             :      endless loops.  It doesn't really matter for DF iteration order and
    1391                 :             :      handling latches last is probably even better.  */
    1392                 :     1444676 :   stack[sp++] = ei_start (loop->header->preds);
    1393                 :     1444676 :   bitmap_set_bit (visited, loop->header->index);
    1394                 :             : 
    1395                 :             :   /* The inverted traversal loop. */
    1396                 :    20694532 :   while (sp)
    1397                 :             :     {
    1398                 :    17805180 :       edge_iterator ei;
    1399                 :    17805180 :       basic_block pred;
    1400                 :             : 
    1401                 :             :       /* Look at the edge on the top of the stack.  */
    1402                 :    17805180 :       ei = stack[sp - 1];
    1403                 :    17805180 :       bb = ei_edge (ei)->dest;
    1404                 :    17805180 :       pred = ei_edge (ei)->src;
    1405                 :             : 
    1406                 :             :       /* Check if the predecessor has been visited yet and mark it
    1407                 :             :          if not so.  */
    1408                 :    17805180 :       if (flow_bb_inside_loop_p (loop, pred)
    1409                 :    17805180 :           && bitmap_set_bit (visited, pred->index))
    1410                 :             :         {
    1411                 :     6548836 :           if (EDGE_COUNT (pred->preds) > 0)
    1412                 :             :             /* Since the predecessor node has been visited for the first
    1413                 :             :                time, check its predecessors.  */
    1414                 :     6548836 :             stack[sp++] = ei_start (pred->preds);
    1415                 :             :           else
    1416                 :           0 :             post_order[post_order_num--] = pred->index;
    1417                 :             :         }
    1418                 :             :       else
    1419                 :             :         {
    1420                 :    11256344 :           if (flow_bb_inside_loop_p (loop, bb)
    1421                 :    11256344 :               && ei_one_before_end_p (ei))
    1422                 :     7993512 :             post_order[post_order_num--] = bb->index;
    1423                 :             : 
    1424                 :    11256344 :           if (!ei_one_before_end_p (ei))
    1425                 :     3262832 :             ei_next (&stack[sp - 1]);
    1426                 :             :           else
    1427                 :     7993512 :             sp--;
    1428                 :             :         }
    1429                 :             :     }
    1430                 :             : 
    1431                 :     1444676 :   free (stack);
    1432                 :     1444676 :   return loop->num_nodes;
    1433                 :     1444676 : }
    1434                 :             : 
    1435                 :             : 
    1436                 :             : /* Analyze dataflow info for the basic blocks contained in LOOP.  */
    1437                 :             : 
    1438                 :             : void
    1439                 :     1444676 : df_analyze_loop (class loop *loop)
    1440                 :             : {
    1441                 :     1444676 :   free (df->postorder);
    1442                 :     1444676 :   free (df->postorder_inverted);
    1443                 :             : 
    1444                 :     1444676 :   df->postorder = XNEWVEC (int, loop->num_nodes);
    1445                 :     1444676 :   df->postorder_inverted = XNEWVEC (int, loop->num_nodes);
    1446                 :     1444676 :   df->n_blocks = loop_rev_post_order_compute (df->postorder_inverted, loop);
    1447                 :     1444676 :   int n = loop_inverted_rev_post_order_compute (df->postorder, loop);
    1448                 :     1444676 :   gcc_assert ((unsigned) df->n_blocks == loop->num_nodes);
    1449                 :     1444676 :   gcc_assert ((unsigned) n == loop->num_nodes);
    1450                 :             : 
    1451                 :     1444676 :   bitmap blocks = BITMAP_ALLOC (&df_bitmap_obstack);
    1452                 :     9438188 :   for (int i = 0; i < df->n_blocks; ++i)
    1453                 :     7993512 :     bitmap_set_bit (blocks, df->postorder[i]);
    1454                 :     1444676 :   df_set_blocks (blocks);
    1455                 :     1444676 :   BITMAP_FREE (blocks);
    1456                 :             : 
    1457                 :     1444676 :   df_analyze_1 ();
    1458                 :     1444676 : }
    1459                 :             : 
    1460                 :             : 
    1461                 :             : /* Return the number of basic blocks from the last call to df_analyze.  */
    1462                 :             : 
    1463                 :             : int
    1464                 :    12963713 : df_get_n_blocks (enum df_flow_dir dir)
    1465                 :             : {
    1466                 :    12963713 :   gcc_assert (dir != DF_NONE);
    1467                 :             : 
    1468                 :    12963713 :   if (dir == DF_FORWARD)
    1469                 :             :     {
    1470                 :      397546 :       gcc_assert (df->postorder_inverted);
    1471                 :      397546 :       return df->n_blocks;
    1472                 :             :     }
    1473                 :             : 
    1474                 :    12566167 :   gcc_assert (df->postorder);
    1475                 :    12566167 :   return df->n_blocks;
    1476                 :             : }
    1477                 :             : 
    1478                 :             : 
    1479                 :             : /* Return a pointer to the array of basic blocks in the reverse postorder.
    1480                 :             :    Depending on the direction of the dataflow problem,
    1481                 :             :    it returns either the usual reverse postorder array
    1482                 :             :    or the reverse postorder of inverted traversal. */
    1483                 :             : int *
    1484                 :    12963713 : df_get_postorder (enum df_flow_dir dir)
    1485                 :             : {
    1486                 :    12963713 :   gcc_assert (dir != DF_NONE);
    1487                 :             : 
    1488                 :    12963713 :   if (dir == DF_FORWARD)
    1489                 :             :     {
    1490                 :      397546 :       gcc_assert (df->postorder_inverted);
    1491                 :             :       return df->postorder_inverted;
    1492                 :             :     }
    1493                 :    12566167 :   gcc_assert (df->postorder);
    1494                 :             :   return df->postorder;
    1495                 :             : }
    1496                 :             : 
    1497                 :             : static struct df_problem user_problem;
    1498                 :             : static struct dataflow user_dflow;
    1499                 :             : 
    1500                 :             : /* Interface for calling iterative dataflow with user defined
    1501                 :             :    confluence and transfer functions.  All that is necessary is to
    1502                 :             :    supply DIR, a direction, CONF_FUN_0, a confluence function for
    1503                 :             :    blocks with no logical preds (or NULL), CONF_FUN_N, the normal
    1504                 :             :    confluence function, TRANS_FUN, the basic block transfer function,
    1505                 :             :    and BLOCKS, the set of blocks to examine, POSTORDER the blocks in
    1506                 :             :    postorder, and N_BLOCKS, the number of blocks in POSTORDER. */
    1507                 :             : 
    1508                 :             : void
    1509                 :     2746289 : df_simple_dataflow (enum df_flow_dir dir,
    1510                 :             :                     df_init_function init_fun,
    1511                 :             :                     df_confluence_function_0 con_fun_0,
    1512                 :             :                     df_confluence_function_n con_fun_n,
    1513                 :             :                     df_transfer_function trans_fun,
    1514                 :             :                     bitmap blocks, int * postorder, int n_blocks)
    1515                 :             : {
    1516                 :     2746289 :   memset (&user_problem, 0, sizeof (struct df_problem));
    1517                 :     2746289 :   user_problem.dir = dir;
    1518                 :     2746289 :   user_problem.init_fun = init_fun;
    1519                 :     2746289 :   user_problem.con_fun_0 = con_fun_0;
    1520                 :     2746289 :   user_problem.con_fun_n = con_fun_n;
    1521                 :     2746289 :   user_problem.trans_fun = trans_fun;
    1522                 :     2746289 :   user_dflow.problem = &user_problem;
    1523                 :     2746289 :   df_worklist_dataflow (&user_dflow, blocks, postorder, n_blocks);
    1524                 :     2746289 : }
    1525                 :             : 
    1526                 :             : 
    1527                 :             : 
    1528                 :             : /*----------------------------------------------------------------------------
    1529                 :             :    Functions to support limited incremental change.
    1530                 :             : ----------------------------------------------------------------------------*/
    1531                 :             : 
    1532                 :             : 
    1533                 :             : /* Get basic block info.  */
    1534                 :             : 
    1535                 :             : static void *
    1536                 :    23052681 : df_get_bb_info (struct dataflow *dflow, unsigned int index)
    1537                 :             : {
    1538                 :     3587709 :   if (dflow->block_info == NULL)
    1539                 :             :     return NULL;
    1540                 :    23052681 :   if (index >= dflow->block_info_size)
    1541                 :             :     return NULL;
    1542                 :    22811417 :   return (void *)((char *)dflow->block_info
    1543                 :     3619263 :                   + index * dflow->problem->block_info_elt_size);
    1544                 :             : }
    1545                 :             : 
    1546                 :             : 
    1547                 :             : /* Set basic block info.  */
    1548                 :             : 
    1549                 :             : static void
    1550                 :   602960179 : df_set_bb_info (struct dataflow *dflow, unsigned int index,
    1551                 :             :                 void *bb_info)
    1552                 :             : {
    1553                 :   602960179 :   gcc_assert (dflow->block_info);
    1554                 :   602960179 :   memcpy ((char *)dflow->block_info
    1555                 :   602960179 :           + index * dflow->problem->block_info_elt_size,
    1556                 :   602960179 :           bb_info, dflow->problem->block_info_elt_size);
    1557                 :   602960179 : }
    1558                 :             : 
    1559                 :             : 
    1560                 :             : /* Clear basic block info.  */
    1561                 :             : 
    1562                 :             : static void
    1563                 :    22779863 : df_clear_bb_info (struct dataflow *dflow, unsigned int index)
    1564                 :             : {
    1565                 :    22779863 :   gcc_assert (dflow->block_info);
    1566                 :    22779863 :   gcc_assert (dflow->block_info_size > index);
    1567                 :    22779863 :   memset ((char *)dflow->block_info
    1568                 :    22779863 :           + index * dflow->problem->block_info_elt_size,
    1569                 :    22779863 :           0, dflow->problem->block_info_elt_size);
    1570                 :    22779863 : }
    1571                 :             : 
    1572                 :             : 
    1573                 :             : /* Mark the solutions as being out of date.  */
    1574                 :             : 
    1575                 :             : void
    1576                 :   896329320 : df_mark_solutions_dirty (void)
    1577                 :             : {
    1578                 :   896329320 :   if (df)
    1579                 :             :     {
    1580                 :             :       int p;
    1581                 :  1607691593 :       for (p = 1; p < df->num_problems_defined; p++)
    1582                 :  1206001491 :         df->problems_in_order[p]->solutions_dirty = true;
    1583                 :             :     }
    1584                 :   896329320 : }
    1585                 :             : 
    1586                 :             : 
    1587                 :             : /* Return true if BB needs it's transfer functions recomputed.  */
    1588                 :             : 
    1589                 :             : bool
    1590                 :   100713319 : df_get_bb_dirty (basic_block bb)
    1591                 :             : {
    1592                 :   201426638 :   return bitmap_bit_p ((df_live
    1593                 :   100713319 :                         ? df_live : df_lr)->out_of_date_transfer_functions,
    1594                 :   100713319 :                        bb->index);
    1595                 :             : }
    1596                 :             : 
    1597                 :             : 
    1598                 :             : /* Mark BB as needing it's transfer functions as being out of
    1599                 :             :    date.  */
    1600                 :             : 
    1601                 :             : void
    1602                 :   331155203 : df_set_bb_dirty (basic_block bb)
    1603                 :             : {
    1604                 :   331155203 :   bb->flags |= BB_MODIFIED;
    1605                 :   331155203 :   if (df)
    1606                 :             :     {
    1607                 :             :       int p;
    1608                 :  1280589108 :       for (p = 1; p < df->num_problems_defined; p++)
    1609                 :             :         {
    1610                 :   956509487 :           struct dataflow *dflow = df->problems_in_order[p];
    1611                 :   956509487 :           if (dflow->out_of_date_transfer_functions)
    1612                 :   501211614 :             bitmap_set_bit (dflow->out_of_date_transfer_functions, bb->index);
    1613                 :             :         }
    1614                 :   324079621 :       df_mark_solutions_dirty ();
    1615                 :             :     }
    1616                 :   331155203 : }
    1617                 :             : 
    1618                 :             : 
    1619                 :             : /* Grow the bb_info array.  */
    1620                 :             : 
    1621                 :             : void
    1622                 :  1167087677 : df_grow_bb_info (struct dataflow *dflow)
    1623                 :             : {
    1624                 :  1167087677 :   unsigned int new_size = last_basic_block_for_fn (cfun) + 1;
    1625                 :  1167087677 :   if (dflow->block_info_size < new_size)
    1626                 :             :     {
    1627                 :    14329179 :       new_size += new_size / 4;
    1628                 :    14329179 :       dflow->block_info
    1629                 :    14329179 :          = (void *)XRESIZEVEC (char, (char *)dflow->block_info,
    1630                 :             :                                new_size
    1631                 :             :                                * dflow->problem->block_info_elt_size);
    1632                 :    14329179 :       memset ((char *)dflow->block_info
    1633                 :             :               + dflow->block_info_size
    1634                 :    14329179 :               * dflow->problem->block_info_elt_size,
    1635                 :             :               0,
    1636                 :    14329179 :               (new_size - dflow->block_info_size)
    1637                 :    14329179 :               * dflow->problem->block_info_elt_size);
    1638                 :    14329179 :       dflow->block_info_size = new_size;
    1639                 :             :     }
    1640                 :  1167087677 : }
    1641                 :             : 
    1642                 :             : 
    1643                 :             : /* Clear the dirty bits.  This is called from places that delete
    1644                 :             :    blocks.  */
    1645                 :             : static void
    1646                 :     6609571 : df_clear_bb_dirty (basic_block bb)
    1647                 :             : {
    1648                 :     6609571 :   int p;
    1649                 :    26788251 :   for (p = 1; p < df->num_problems_defined; p++)
    1650                 :             :     {
    1651                 :    20178680 :       struct dataflow *dflow = df->problems_in_order[p];
    1652                 :    20178680 :       if (dflow->out_of_date_transfer_functions)
    1653                 :    12855393 :         bitmap_clear_bit (dflow->out_of_date_transfer_functions, bb->index);
    1654                 :             :     }
    1655                 :     6609571 : }
    1656                 :             : 
    1657                 :             : /* Called from the rtl_compact_blocks to reorganize the problems basic
    1658                 :             :    block info.  */
    1659                 :             : 
    1660                 :             : void
    1661                 :    18079949 : df_compact_blocks (void)
    1662                 :             : {
    1663                 :    18079949 :   int i, p;
    1664                 :    18079949 :   basic_block bb;
    1665                 :    18079949 :   void *problem_temps;
    1666                 :             : 
    1667                 :    18079949 :   auto_bitmap tmp (&df_bitmap_obstack);
    1668                 :    89559538 :   for (p = 0; p < df->num_problems_defined; p++)
    1669                 :             :     {
    1670                 :    71479589 :       struct dataflow *dflow = df->problems_in_order[p];
    1671                 :             : 
    1672                 :             :       /* Need to reorganize the out_of_date_transfer_functions for the
    1673                 :             :          dflow problem.  */
    1674                 :    71479589 :       if (dflow->out_of_date_transfer_functions)
    1675                 :             :         {
    1676                 :    33213160 :           bitmap_copy (tmp, dflow->out_of_date_transfer_functions);
    1677                 :    33213160 :           bitmap_clear (dflow->out_of_date_transfer_functions);
    1678                 :    33213160 :           if (bitmap_bit_p (tmp, ENTRY_BLOCK))
    1679                 :      839275 :             bitmap_set_bit (dflow->out_of_date_transfer_functions, ENTRY_BLOCK);
    1680                 :    33213160 :           if (bitmap_bit_p (tmp, EXIT_BLOCK))
    1681                 :      839476 :             bitmap_set_bit (dflow->out_of_date_transfer_functions, EXIT_BLOCK);
    1682                 :             : 
    1683                 :    33213160 :           i = NUM_FIXED_BLOCKS;
    1684                 :   426474777 :           FOR_EACH_BB_FN (bb, cfun)
    1685                 :             :             {
    1686                 :   393261617 :               if (bitmap_bit_p (tmp, bb->index))
    1687                 :    70341667 :                 bitmap_set_bit (dflow->out_of_date_transfer_functions, i);
    1688                 :   393261617 :               i++;
    1689                 :             :             }
    1690                 :             :         }
    1691                 :             : 
    1692                 :             :       /* Now shuffle the block info for the problem.  */
    1693                 :    71479589 :       if (dflow->problem->free_bb_fun)
    1694                 :             :         {
    1695                 :    51293109 :           int size = (last_basic_block_for_fn (cfun)
    1696                 :    51293109 :                       * dflow->problem->block_info_elt_size);
    1697                 :    51293109 :           problem_temps = XNEWVAR (char, size);
    1698                 :    51293109 :           df_grow_bb_info (dflow);
    1699                 :    51293109 :           memcpy (problem_temps, dflow->block_info, size);
    1700                 :             : 
    1701                 :             :           /* Copy the bb info from the problem tmps to the proper
    1702                 :             :              place in the block_info vector.  Null out the copied
    1703                 :             :              item.  The entry and exit blocks never move.  */
    1704                 :    51293109 :           i = NUM_FIXED_BLOCKS;
    1705                 :   654221734 :           FOR_EACH_BB_FN (bb, cfun)
    1706                 :             :             {
    1707                 :   602928625 :               df_set_bb_info (dflow, i,
    1708                 :             :                               (char *)problem_temps
    1709                 :   602928625 :                               + bb->index * dflow->problem->block_info_elt_size);
    1710                 :   602928625 :               i++;
    1711                 :             :             }
    1712                 :    51293109 :           memset ((char *)dflow->block_info
    1713                 :    51293109 :                   + i * dflow->problem->block_info_elt_size, 0,
    1714                 :    51293109 :                   (last_basic_block_for_fn (cfun) - i)
    1715                 :    51293109 :                   * dflow->problem->block_info_elt_size);
    1716                 :    51293109 :           free (problem_temps);
    1717                 :             :         }
    1718                 :             :     }
    1719                 :             : 
    1720                 :             :   /* Shuffle the bits in the basic_block indexed arrays.  */
    1721                 :             : 
    1722                 :    18079949 :   if (df->blocks_to_analyze)
    1723                 :             :     {
    1724                 :           0 :       if (bitmap_bit_p (tmp, ENTRY_BLOCK))
    1725                 :           0 :         bitmap_set_bit (df->blocks_to_analyze, ENTRY_BLOCK);
    1726                 :           0 :       if (bitmap_bit_p (tmp, EXIT_BLOCK))
    1727                 :           0 :         bitmap_set_bit (df->blocks_to_analyze, EXIT_BLOCK);
    1728                 :           0 :       bitmap_copy (tmp, df->blocks_to_analyze);
    1729                 :           0 :       bitmap_clear (df->blocks_to_analyze);
    1730                 :           0 :       i = NUM_FIXED_BLOCKS;
    1731                 :           0 :       FOR_EACH_BB_FN (bb, cfun)
    1732                 :             :         {
    1733                 :           0 :           if (bitmap_bit_p (tmp, bb->index))
    1734                 :           0 :             bitmap_set_bit (df->blocks_to_analyze, i);
    1735                 :           0 :           i++;
    1736                 :             :         }
    1737                 :             :     }
    1738                 :             : 
    1739                 :    18079949 :   i = NUM_FIXED_BLOCKS;
    1740                 :   227746957 :   FOR_EACH_BB_FN (bb, cfun)
    1741                 :             :     {
    1742                 :   209667008 :       SET_BASIC_BLOCK_FOR_FN (cfun, i, bb);
    1743                 :   209667008 :       bb->index = i;
    1744                 :   209667008 :       i++;
    1745                 :             :     }
    1746                 :             : 
    1747                 :    18079949 :   gcc_assert (i == n_basic_blocks_for_fn (cfun));
    1748                 :             : 
    1749                 :    24685179 :   for (; i < last_basic_block_for_fn (cfun); i++)
    1750                 :     6605230 :     SET_BASIC_BLOCK_FOR_FN (cfun, i, NULL);
    1751                 :             : 
    1752                 :             : #ifdef DF_DEBUG_CFG
    1753                 :             :   if (!df_lr->solutions_dirty)
    1754                 :             :     df_set_clean_cfg ();
    1755                 :             : #endif
    1756                 :    18079949 : }
    1757                 :             : 
    1758                 :             : 
    1759                 :             : /* Shove NEW_BLOCK in at OLD_INDEX.  Called from ifcvt to hack a
    1760                 :             :    block.  There is no excuse for people to do this kind of thing.  */
    1761                 :             : 
    1762                 :             : void
    1763                 :       10518 : df_bb_replace (int old_index, basic_block new_block)
    1764                 :             : {
    1765                 :       10518 :   int new_block_index = new_block->index;
    1766                 :       10518 :   int p;
    1767                 :             : 
    1768                 :       10518 :   if (dump_file)
    1769                 :           0 :     fprintf (dump_file, "shoving block %d into %d\n", new_block_index, old_index);
    1770                 :             : 
    1771                 :       10518 :   gcc_assert (df);
    1772                 :       10518 :   gcc_assert (BASIC_BLOCK_FOR_FN (cfun, old_index) == NULL);
    1773                 :             : 
    1774                 :       52590 :   for (p = 0; p < df->num_problems_defined; p++)
    1775                 :             :     {
    1776                 :       42072 :       struct dataflow *dflow = df->problems_in_order[p];
    1777                 :       42072 :       if (dflow->block_info)
    1778                 :             :         {
    1779                 :       31554 :           df_grow_bb_info (dflow);
    1780                 :       63108 :           df_set_bb_info (dflow, old_index,
    1781                 :             :                           df_get_bb_info (dflow, new_block_index));
    1782                 :             :         }
    1783                 :             :     }
    1784                 :             : 
    1785                 :       10518 :   df_clear_bb_dirty (new_block);
    1786                 :       10518 :   SET_BASIC_BLOCK_FOR_FN (cfun, old_index, new_block);
    1787                 :       10518 :   new_block->index = old_index;
    1788                 :       10518 :   df_set_bb_dirty (BASIC_BLOCK_FOR_FN (cfun, old_index));
    1789                 :       10518 :   SET_BASIC_BLOCK_FOR_FN (cfun, new_block_index, NULL);
    1790                 :       10518 : }
    1791                 :             : 
    1792                 :             : 
    1793                 :             : /* Free all of the per basic block dataflow from all of the problems.
    1794                 :             :    This is typically called before a basic block is deleted and the
    1795                 :             :    problem will be reanalyzed.  */
    1796                 :             : 
    1797                 :             : void
    1798                 :    11308761 : df_bb_delete (int bb_index)
    1799                 :             : {
    1800                 :    11308761 :   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
    1801                 :    11308761 :   int i;
    1802                 :             : 
    1803                 :    11308761 :   if (!df)
    1804                 :             :     return;
    1805                 :             : 
    1806                 :    33345232 :   for (i = 0; i < df->num_problems_defined; i++)
    1807                 :             :     {
    1808                 :    26746179 :       struct dataflow *dflow = df->problems_in_order[i];
    1809                 :    26746179 :       if (dflow->problem->free_bb_fun)
    1810                 :             :         {
    1811                 :    46179597 :           void *bb_info = df_get_bb_info (dflow, bb_index);
    1812                 :    19192154 :           if (bb_info)
    1813                 :             :             {
    1814                 :    19192154 :               dflow->problem->free_bb_fun (bb, bb_info);
    1815                 :    19192154 :               df_clear_bb_info (dflow, bb_index);
    1816                 :             :             }
    1817                 :             :         }
    1818                 :             :     }
    1819                 :     6599053 :   df_clear_bb_dirty (bb);
    1820                 :     6599053 :   df_mark_solutions_dirty ();
    1821                 :             : }
    1822                 :             : 
    1823                 :             : 
    1824                 :             : /* Verify that there is a place for everything and everything is in
    1825                 :             :    its place.  This is too expensive to run after every pass in the
    1826                 :             :    mainline.  However this is an excellent debugging tool if the
    1827                 :             :    dataflow information is not being updated properly.  You can just
    1828                 :             :    sprinkle calls in until you find the place that is changing an
    1829                 :             :    underlying structure without calling the proper updating
    1830                 :             :    routine.  */
    1831                 :             : 
    1832                 :             : void
    1833                 :     6496418 : df_verify (void)
    1834                 :             : {
    1835                 :     6496418 :   df_scan_verify ();
    1836                 :             : #ifdef ENABLE_DF_CHECKING
    1837                 :             :   df_lr_verify_transfer_functions ();
    1838                 :             :   if (df_live)
    1839                 :             :     df_live_verify_transfer_functions ();
    1840                 :             : #endif
    1841                 :     6496418 :   df->changeable_flags &= ~DF_VERIFY_SCHEDULED;
    1842                 :     6496418 : }
    1843                 :             : 
    1844                 :             : #ifdef DF_DEBUG_CFG
    1845                 :             : 
    1846                 :             : /* Compute an array of ints that describes the cfg.  This can be used
    1847                 :             :    to discover places where the cfg is modified by the appropriate
    1848                 :             :    calls have not been made to the keep df informed.  The internals of
    1849                 :             :    this are unexciting, the key is that two instances of this can be
    1850                 :             :    compared to see if any changes have been made to the cfg.  */
    1851                 :             : 
    1852                 :             : static int *
    1853                 :             : df_compute_cfg_image (void)
    1854                 :             : {
    1855                 :             :   basic_block bb;
    1856                 :             :   int size = 2 + (2 * n_basic_blocks_for_fn (cfun));
    1857                 :             :   int i;
    1858                 :             :   int * map;
    1859                 :             : 
    1860                 :             :   FOR_ALL_BB_FN (bb, cfun)
    1861                 :             :     {
    1862                 :             :       size += EDGE_COUNT (bb->succs);
    1863                 :             :     }
    1864                 :             : 
    1865                 :             :   map = XNEWVEC (int, size);
    1866                 :             :   map[0] = size;
    1867                 :             :   i = 1;
    1868                 :             :   FOR_ALL_BB_FN (bb, cfun)
    1869                 :             :     {
    1870                 :             :       edge_iterator ei;
    1871                 :             :       edge e;
    1872                 :             : 
    1873                 :             :       map[i++] = bb->index;
    1874                 :             :       FOR_EACH_EDGE (e, ei, bb->succs)
    1875                 :             :         map[i++] = e->dest->index;
    1876                 :             :       map[i++] = -1;
    1877                 :             :     }
    1878                 :             :   map[i] = -1;
    1879                 :             :   return map;
    1880                 :             : }
    1881                 :             : 
    1882                 :             : static int *saved_cfg = NULL;
    1883                 :             : 
    1884                 :             : 
    1885                 :             : /* This function compares the saved version of the cfg with the
    1886                 :             :    current cfg and aborts if the two are identical.  The function
    1887                 :             :    silently returns if the cfg has been marked as dirty or the two are
    1888                 :             :    the same.  */
    1889                 :             : 
    1890                 :             : void
    1891                 :             : df_check_cfg_clean (void)
    1892                 :             : {
    1893                 :             :   int *new_map;
    1894                 :             : 
    1895                 :             :   if (!df)
    1896                 :             :     return;
    1897                 :             : 
    1898                 :             :   if (df_lr->solutions_dirty)
    1899                 :             :     return;
    1900                 :             : 
    1901                 :             :   if (saved_cfg == NULL)
    1902                 :             :     return;
    1903                 :             : 
    1904                 :             :   new_map = df_compute_cfg_image ();
    1905                 :             :   gcc_assert (memcmp (saved_cfg, new_map, saved_cfg[0] * sizeof (int)) == 0);
    1906                 :             :   free (new_map);
    1907                 :             : }
    1908                 :             : 
    1909                 :             : 
    1910                 :             : /* This function builds a cfg fingerprint and squirrels it away in
    1911                 :             :    saved_cfg.  */
    1912                 :             : 
    1913                 :             : static void
    1914                 :             : df_set_clean_cfg (void)
    1915                 :             : {
    1916                 :             :   free (saved_cfg);
    1917                 :             :   saved_cfg = df_compute_cfg_image ();
    1918                 :             : }
    1919                 :             : 
    1920                 :             : #endif /* DF_DEBUG_CFG  */
    1921                 :             : /*----------------------------------------------------------------------------
    1922                 :             :    PUBLIC INTERFACES TO QUERY INFORMATION.
    1923                 :             : ----------------------------------------------------------------------------*/
    1924                 :             : 
    1925                 :             : 
    1926                 :             : /* Return first def of REGNO within BB.  */
    1927                 :             : 
    1928                 :             : df_ref
    1929                 :           0 : df_bb_regno_first_def_find (basic_block bb, unsigned int regno)
    1930                 :             : {
    1931                 :           0 :   rtx_insn *insn;
    1932                 :           0 :   df_ref def;
    1933                 :             : 
    1934                 :           0 :   FOR_BB_INSNS (bb, insn)
    1935                 :             :     {
    1936                 :           0 :       if (!INSN_P (insn))
    1937                 :           0 :         continue;
    1938                 :             : 
    1939                 :           0 :       FOR_EACH_INSN_DEF (def, insn)
    1940                 :           0 :         if (DF_REF_REGNO (def) == regno)
    1941                 :             :           return def;
    1942                 :             :     }
    1943                 :             :   return NULL;
    1944                 :             : }
    1945                 :             : 
    1946                 :             : 
    1947                 :             : /* Return last def of REGNO within BB.  */
    1948                 :             : 
    1949                 :             : df_ref
    1950                 :           0 : df_bb_regno_last_def_find (basic_block bb, unsigned int regno)
    1951                 :             : {
    1952                 :           0 :   rtx_insn *insn;
    1953                 :           0 :   df_ref def;
    1954                 :             : 
    1955                 :           0 :   FOR_BB_INSNS_REVERSE (bb, insn)
    1956                 :             :     {
    1957                 :           0 :       if (!INSN_P (insn))
    1958                 :           0 :         continue;
    1959                 :             : 
    1960                 :           0 :       FOR_EACH_INSN_DEF (def, insn)
    1961                 :           0 :         if (DF_REF_REGNO (def) == regno)
    1962                 :             :           return def;
    1963                 :             :     }
    1964                 :             : 
    1965                 :             :   return NULL;
    1966                 :             : }
    1967                 :             : 
    1968                 :             : /* Return the one and only def of REGNO within BB.  If there is no def or
    1969                 :             :    there are multiple defs, return NULL.  */
    1970                 :             : 
    1971                 :             : df_ref
    1972                 :           0 : df_bb_regno_only_def_find (basic_block bb, unsigned int regno)
    1973                 :             : {
    1974                 :           0 :   df_ref temp = df_bb_regno_first_def_find (bb, regno);
    1975                 :           0 :   if (!temp)
    1976                 :             :     return NULL;
    1977                 :           0 :   else if (temp == df_bb_regno_last_def_find (bb, regno))
    1978                 :             :     return temp;
    1979                 :             :   else
    1980                 :             :     return NULL;
    1981                 :             : }
    1982                 :             : 
    1983                 :             : /* Finds the reference corresponding to the definition of REG in INSN.
    1984                 :             :    DF is the dataflow object.  */
    1985                 :             : 
    1986                 :             : df_ref
    1987                 :      769811 : df_find_def (rtx_insn *insn, rtx reg)
    1988                 :             : {
    1989                 :      769811 :   df_ref def;
    1990                 :             : 
    1991                 :      769811 :   if (GET_CODE (reg) == SUBREG)
    1992                 :           0 :     reg = SUBREG_REG (reg);
    1993                 :      769811 :   gcc_assert (REG_P (reg));
    1994                 :             : 
    1995                 :     1077124 :   FOR_EACH_INSN_DEF (def, insn)
    1996                 :     1077124 :     if (DF_REF_REGNO (def) == REGNO (reg))
    1997                 :             :       return def;
    1998                 :             : 
    1999                 :             :   return NULL;
    2000                 :             : }
    2001                 :             : 
    2002                 :             : 
    2003                 :             : /* Return true if REG is defined in INSN, zero otherwise.  */
    2004                 :             : 
    2005                 :             : bool
    2006                 :           0 : df_reg_defined (rtx_insn *insn, rtx reg)
    2007                 :             : {
    2008                 :           0 :   return df_find_def (insn, reg) != NULL;
    2009                 :             : }
    2010                 :             : 
    2011                 :             : 
    2012                 :             : /* Finds the reference corresponding to the use of REG in INSN.
    2013                 :             :    DF is the dataflow object.  */
    2014                 :             : 
    2015                 :             : df_ref
    2016                 :     5047674 : df_find_use (rtx_insn *insn, rtx reg)
    2017                 :             : {
    2018                 :     5047674 :   df_ref use;
    2019                 :             : 
    2020                 :     5047674 :   if (GET_CODE (reg) == SUBREG)
    2021                 :           0 :     reg = SUBREG_REG (reg);
    2022                 :     5047674 :   gcc_assert (REG_P (reg));
    2023                 :             : 
    2024                 :     5047674 :   df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
    2025                 :     6048381 :   FOR_EACH_INSN_INFO_USE (use, insn_info)
    2026                 :     6048381 :     if (DF_REF_REGNO (use) == REGNO (reg))
    2027                 :             :       return use;
    2028                 :           0 :   if (df->changeable_flags & DF_EQ_NOTES)
    2029                 :           0 :     FOR_EACH_INSN_INFO_EQ_USE (use, insn_info)
    2030                 :           0 :       if (DF_REF_REGNO (use) == REGNO (reg))
    2031                 :             :         return use;
    2032                 :             :   return NULL;
    2033                 :             : }
    2034                 :             : 
    2035                 :             : 
    2036                 :             : /* Return true if REG is referenced in INSN, zero otherwise.  */
    2037                 :             : 
    2038                 :             : bool
    2039                 :           0 : df_reg_used (rtx_insn *insn, rtx reg)
    2040                 :             : {
    2041                 :           0 :   return df_find_use (insn, reg) != NULL;
    2042                 :             : }
    2043                 :             : 
    2044                 :             : /* If REG has a single definition, return its known value, otherwise return
    2045                 :             :    null.  */
    2046                 :             : 
    2047                 :             : rtx
    2048                 :     8411159 : df_find_single_def_src (rtx reg)
    2049                 :             : {
    2050                 :     8411159 :   rtx src = NULL_RTX;
    2051                 :             : 
    2052                 :             :   /* Don't look through unbounded number of single definition REG copies,
    2053                 :             :      there might be loops for sources with uninitialized variables.  */
    2054                 :     9149979 :   for (int cnt = 0; cnt < 128; cnt++)
    2055                 :             :     {
    2056                 :     9149971 :       df_ref adef = DF_REG_DEF_CHAIN (REGNO (reg));
    2057                 :     9149971 :       if (adef == NULL || DF_REF_NEXT_REG (adef) != NULL
    2058                 :     6067887 :           || DF_REF_IS_ARTIFICIAL (adef)
    2059                 :     5919878 :           || (DF_REF_FLAGS (adef)
    2060                 :             :               & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
    2061                 :             :         return NULL_RTX;
    2062                 :             : 
    2063                 :     5919862 :       rtx set = single_set (DF_REF_INSN (adef));
    2064                 :     5919862 :       if (set == NULL || !rtx_equal_p (SET_DEST (set), reg))
    2065                 :       13705 :         return NULL_RTX;
    2066                 :             : 
    2067                 :     5906157 :       rtx note = find_reg_equal_equiv_note (DF_REF_INSN (adef));
    2068                 :     5906157 :       if (note && function_invariant_p (XEXP (note, 0)))
    2069                 :      152822 :         return XEXP (note, 0);
    2070                 :     5753335 :       src = SET_SRC (set);
    2071                 :             : 
    2072                 :     5753335 :       if (REG_P (src))
    2073                 :             :         {
    2074                 :      738820 :           reg = src;
    2075                 :      738820 :           continue;
    2076                 :             :         }
    2077                 :             :       break;
    2078                 :             :     }
    2079                 :     5014523 :   if (!function_invariant_p (src))
    2080                 :             :     return NULL_RTX;
    2081                 :             : 
    2082                 :             :   return src;
    2083                 :             : }
    2084                 :             : 
    2085                 :             : 
    2086                 :             : /*----------------------------------------------------------------------------
    2087                 :             :    Debugging and printing functions.
    2088                 :             : ----------------------------------------------------------------------------*/
    2089                 :             : 
    2090                 :             : /* Write information about registers and basic blocks into FILE.
    2091                 :             :    This is part of making a debugging dump.  */
    2092                 :             : 
    2093                 :             : void
    2094                 :         169 : dump_regset (regset r, FILE *outf)
    2095                 :             : {
    2096                 :         169 :   unsigned i;
    2097                 :         169 :   reg_set_iterator rsi;
    2098                 :             : 
    2099                 :         169 :   if (r == NULL)
    2100                 :             :     {
    2101                 :           0 :       fputs (" (nil)", outf);
    2102                 :           0 :       return;
    2103                 :             :     }
    2104                 :             : 
    2105                 :        2169 :   EXECUTE_IF_SET_IN_REG_SET (r, 0, i, rsi)
    2106                 :             :     {
    2107                 :        2000 :       fprintf (outf, " %d", i);
    2108                 :        2000 :       if (i < FIRST_PSEUDO_REGISTER)
    2109                 :        1285 :         fprintf (outf, " [%s]",
    2110                 :             :                  reg_names[i]);
    2111                 :             :     }
    2112                 :             : }
    2113                 :             : 
    2114                 :             : /* Print a human-readable representation of R on the standard error
    2115                 :             :    stream.  This function is designed to be used from within the
    2116                 :             :    debugger.  */
    2117                 :             : extern void debug_regset (regset);
    2118                 :             : DEBUG_FUNCTION void
    2119                 :           0 : debug_regset (regset r)
    2120                 :             : {
    2121                 :           0 :   dump_regset (r, stderr);
    2122                 :           0 :   putc ('\n', stderr);
    2123                 :           0 : }
    2124                 :             : 
    2125                 :             : /* Write information about registers and basic blocks into FILE.
    2126                 :             :    This is part of making a debugging dump.  */
    2127                 :             : 
    2128                 :             : void
    2129                 :       64011 : df_print_regset (FILE *file, const_bitmap r)
    2130                 :             : {
    2131                 :       64011 :   unsigned int i;
    2132                 :       64011 :   bitmap_iterator bi;
    2133                 :             : 
    2134                 :       64011 :   if (r == NULL)
    2135                 :           0 :     fputs (" (nil)", file);
    2136                 :             :   else
    2137                 :             :     {
    2138                 :      752121 :       EXECUTE_IF_SET_IN_BITMAP (r, 0, i, bi)
    2139                 :             :         {
    2140                 :      688110 :           fprintf (file, " %d", i);
    2141                 :      688110 :           if (i < FIRST_PSEUDO_REGISTER)
    2142                 :      622868 :             fprintf (file, " [%s]", reg_names[i]);
    2143                 :             :         }
    2144                 :             :     }
    2145                 :       64011 :   fprintf (file, "\n");
    2146                 :       64011 : }
    2147                 :             : 
    2148                 :             : 
    2149                 :             : /* Write information about registers and basic blocks into FILE.  The
    2150                 :             :    bitmap is in the form used by df_byte_lr.  This is part of making a
    2151                 :             :    debugging dump.  */
    2152                 :             : 
    2153                 :             : void
    2154                 :           0 : df_print_word_regset (FILE *file, const_bitmap r)
    2155                 :             : {
    2156                 :           0 :   unsigned int max_reg = max_reg_num ();
    2157                 :             : 
    2158                 :           0 :   if (r == NULL)
    2159                 :           0 :     fputs (" (nil)", file);
    2160                 :             :   else
    2161                 :             :     {
    2162                 :             :       unsigned int i;
    2163                 :           0 :       for (i = FIRST_PSEUDO_REGISTER; i < max_reg; i++)
    2164                 :             :         {
    2165                 :           0 :           bool found = (bitmap_bit_p (r, 2 * i)
    2166                 :           0 :                         || bitmap_bit_p (r, 2 * i + 1));
    2167                 :           0 :           if (found)
    2168                 :             :             {
    2169                 :           0 :               int word;
    2170                 :           0 :               const char * sep = "";
    2171                 :           0 :               fprintf (file, " %d", i);
    2172                 :           0 :               fprintf (file, "(");
    2173                 :           0 :               for (word = 0; word < 2; word++)
    2174                 :           0 :                 if (bitmap_bit_p (r, 2 * i + word))
    2175                 :             :                   {
    2176                 :           0 :                     fprintf (file, "%s%d", sep, word);
    2177                 :           0 :                     sep = ", ";
    2178                 :             :                   }
    2179                 :           0 :               fprintf (file, ")");
    2180                 :             :             }
    2181                 :             :         }
    2182                 :             :     }
    2183                 :           0 :   fprintf (file, "\n");
    2184                 :           0 : }
    2185                 :             : 
    2186                 :             : 
    2187                 :             : /* Dump dataflow info.  */
    2188                 :             : 
    2189                 :             : void
    2190                 :         434 : df_dump (FILE *file)
    2191                 :             : {
    2192                 :         434 :   basic_block bb;
    2193                 :         434 :   df_dump_start (file);
    2194                 :             : 
    2195                 :        4788 :   FOR_ALL_BB_FN (bb, cfun)
    2196                 :             :     {
    2197                 :        4354 :       df_print_bb_index (bb, file);
    2198                 :        4354 :       df_dump_top (bb, file);
    2199                 :        4354 :       df_dump_bottom (bb, file);
    2200                 :             :     }
    2201                 :             : 
    2202                 :         434 :   fprintf (file, "\n");
    2203                 :         434 : }
    2204                 :             : 
    2205                 :             : 
    2206                 :             : /* Dump dataflow info for df->blocks_to_analyze.  */
    2207                 :             : 
    2208                 :             : void
    2209                 :         195 : df_dump_region (FILE *file)
    2210                 :             : {
    2211                 :         195 :   if (df->blocks_to_analyze)
    2212                 :             :     {
    2213                 :         195 :       bitmap_iterator bi;
    2214                 :         195 :       unsigned int bb_index;
    2215                 :             : 
    2216                 :         195 :       fprintf (file, "\n\nstarting region dump\n");
    2217                 :         195 :       df_dump_start (file);
    2218                 :             : 
    2219                 :         605 :       EXECUTE_IF_SET_IN_BITMAP (df->blocks_to_analyze, 0, bb_index, bi)
    2220                 :             :         {
    2221                 :         410 :           basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
    2222                 :         410 :           dump_bb (file, bb, 0, TDF_DETAILS);
    2223                 :             :         }
    2224                 :         195 :       fprintf (file, "\n");
    2225                 :             :     }
    2226                 :             :   else
    2227                 :           0 :     df_dump (file);
    2228                 :         195 : }
    2229                 :             : 
    2230                 :             : 
    2231                 :             : /* Dump the introductory information for each problem defined.  */
    2232                 :             : 
    2233                 :             : void
    2234                 :        3852 : df_dump_start (FILE *file)
    2235                 :             : {
    2236                 :        3852 :   int i;
    2237                 :             : 
    2238                 :        3852 :   if (!df || !file)
    2239                 :             :     return;
    2240                 :             : 
    2241                 :        3852 :   fprintf (file, "\n\n%s\n", current_function_name ());
    2242                 :        3852 :   fprintf (file, "\nDataflow summary:\n");
    2243                 :        3852 :   if (df->blocks_to_analyze)
    2244                 :         493 :     fprintf (file, "def_info->table_size = %d, use_info->table_size = %d\n",
    2245                 :             :              DF_DEFS_TABLE_SIZE (), DF_USES_TABLE_SIZE ());
    2246                 :             : 
    2247                 :       18439 :   for (i = 0; i < df->num_problems_defined; i++)
    2248                 :             :     {
    2249                 :       14587 :       struct dataflow *dflow = df->problems_in_order[i];
    2250                 :       14587 :       if (dflow->computed)
    2251                 :             :         {
    2252                 :       13918 :           df_dump_problem_function fun = dflow->problem->dump_start_fun;
    2253                 :       13918 :           if (fun)
    2254                 :        4069 :             fun (file);
    2255                 :             :         }
    2256                 :             :     }
    2257                 :             : }
    2258                 :             : 
    2259                 :             : 
    2260                 :             : /* Dump the top or bottom of the block information for BB.  */
    2261                 :             : static void
    2262                 :       11342 : df_dump_bb_problem_data (basic_block bb, FILE *file, bool top)
    2263                 :             : {
    2264                 :       11342 :   int i;
    2265                 :             : 
    2266                 :       11342 :   if (!df || !file)
    2267                 :             :     return;
    2268                 :             : 
    2269                 :       60746 :   for (i = 0; i < df->num_problems_defined; i++)
    2270                 :             :     {
    2271                 :       49404 :       struct dataflow *dflow = df->problems_in_order[i];
    2272                 :       49404 :       if (dflow->computed)
    2273                 :             :         {
    2274                 :       44744 :           df_dump_bb_problem_function bbfun;
    2275                 :             : 
    2276                 :       44744 :           if (top)
    2277                 :       22372 :             bbfun = dflow->problem->dump_top_fun;
    2278                 :             :           else
    2279                 :       22372 :             bbfun = dflow->problem->dump_bottom_fun;
    2280                 :             : 
    2281                 :       44744 :           if (bbfun)
    2282                 :       27683 :             bbfun (bb, file);
    2283                 :             :         }
    2284                 :             :     }
    2285                 :             : }
    2286                 :             : 
    2287                 :             : /* Dump the top of the block information for BB.  */
    2288                 :             : 
    2289                 :             : void
    2290                 :        5671 : df_dump_top (basic_block bb, FILE *file)
    2291                 :             : {
    2292                 :        5671 :   df_dump_bb_problem_data (bb, file, /*top=*/true);
    2293                 :        5671 : }
    2294                 :             : 
    2295                 :             : /* Dump the bottom of the block information for BB.  */
    2296                 :             : 
    2297                 :             : void
    2298                 :        5671 : df_dump_bottom (basic_block bb, FILE *file)
    2299                 :             : {
    2300                 :        5671 :   df_dump_bb_problem_data (bb, file, /*top=*/false);
    2301                 :        5671 : }
    2302                 :             : 
    2303                 :             : 
    2304                 :             : /* Dump information about INSN just before or after dumping INSN itself.  */
    2305                 :             : static void
    2306                 :       38966 : df_dump_insn_problem_data (const rtx_insn *insn, FILE *file, bool top)
    2307                 :             : {
    2308                 :       38966 :   int i;
    2309                 :             : 
    2310                 :       38966 :   if (!df || !file)
    2311                 :             :     return;
    2312                 :             : 
    2313                 :      162048 :   for (i = 0; i < df->num_problems_defined; i++)
    2314                 :             :     {
    2315                 :      127748 :       struct dataflow *dflow = df->problems_in_order[i];
    2316                 :      127748 :       if (dflow->computed)
    2317                 :             :         {
    2318                 :      125036 :           df_dump_insn_problem_function insnfun;
    2319                 :             : 
    2320                 :      125036 :           if (top)
    2321                 :       62518 :             insnfun = dflow->problem->dump_insn_top_fun;
    2322                 :             :           else
    2323                 :       62518 :             insnfun = dflow->problem->dump_insn_bottom_fun;
    2324                 :             : 
    2325                 :      125036 :           if (insnfun)
    2326                 :        4330 :             insnfun (insn, file);
    2327                 :             :         }
    2328                 :             :     }
    2329                 :             : }
    2330                 :             : 
    2331                 :             : /* Dump information about INSN before dumping INSN itself.  */
    2332                 :             : 
    2333                 :             : void
    2334                 :       19483 : df_dump_insn_top (const rtx_insn *insn, FILE *file)
    2335                 :             : {
    2336                 :       19483 :   df_dump_insn_problem_data (insn,  file, /*top=*/true);
    2337                 :       19483 : }
    2338                 :             : 
    2339                 :             : /* Dump information about INSN after dumping INSN itself.  */
    2340                 :             : 
    2341                 :             : void
    2342                 :       19483 : df_dump_insn_bottom (const rtx_insn *insn, FILE *file)
    2343                 :             : {
    2344                 :       19483 :   df_dump_insn_problem_data (insn,  file, /*top=*/false);
    2345                 :       19483 : }
    2346                 :             : 
    2347                 :             : 
    2348                 :             : static void
    2349                 :       24508 : df_ref_dump (df_ref ref, FILE *file)
    2350                 :             : {
    2351                 :       24508 :   fprintf (file, "%c%d(%d)",
    2352                 :       24508 :            DF_REF_REG_DEF_P (ref)
    2353                 :       16023 :            ? 'd'
    2354                 :       16023 :            : (DF_REF_FLAGS (ref) & DF_REF_IN_NOTE) ? 'e' : 'u',
    2355                 :             :            DF_REF_ID (ref),
    2356                 :             :            DF_REF_REGNO (ref));
    2357                 :       24508 : }
    2358                 :             : 
    2359                 :             : void
    2360                 :       11342 : df_refs_chain_dump (df_ref ref, bool follow_chain, FILE *file)
    2361                 :             : {
    2362                 :       11342 :   fprintf (file, "{ ");
    2363                 :       47192 :   for (; ref; ref = DF_REF_NEXT_LOC (ref))
    2364                 :             :     {
    2365                 :       24508 :       df_ref_dump (ref, file);
    2366                 :       24508 :       if (follow_chain)
    2367                 :       24508 :         df_chain_dump (DF_REF_CHAIN (ref), file);
    2368                 :             :     }
    2369                 :       11342 :   fprintf (file, "}");
    2370                 :       11342 : }
    2371                 :             : 
    2372                 :             : 
    2373                 :             : /* Dump either a ref-def or reg-use chain.  */
    2374                 :             : 
    2375                 :             : void
    2376                 :           0 : df_regs_chain_dump (df_ref ref,  FILE *file)
    2377                 :             : {
    2378                 :           0 :   fprintf (file, "{ ");
    2379                 :           0 :   while (ref)
    2380                 :             :     {
    2381                 :           0 :       df_ref_dump (ref, file);
    2382                 :           0 :       ref = DF_REF_NEXT_REG (ref);
    2383                 :             :     }
    2384                 :           0 :   fprintf (file, "}");
    2385                 :           0 : }
    2386                 :             : 
    2387                 :             : 
    2388                 :             : static void
    2389                 :           0 : df_mws_dump (struct df_mw_hardreg *mws, FILE *file)
    2390                 :             : {
    2391                 :           0 :   for (; mws; mws = DF_MWS_NEXT (mws))
    2392                 :           0 :     fprintf (file, "mw %c r[%d..%d]\n",
    2393                 :           0 :              DF_MWS_REG_DEF_P (mws) ? 'd' : 'u',
    2394                 :             :              mws->start_regno, mws->end_regno);
    2395                 :           0 : }
    2396                 :             : 
    2397                 :             : 
    2398                 :             : static void
    2399                 :           0 : df_insn_uid_debug (unsigned int uid,
    2400                 :             :                    bool follow_chain, FILE *file)
    2401                 :             : {
    2402                 :           0 :   fprintf (file, "insn %d luid %d",
    2403                 :           0 :            uid, DF_INSN_UID_LUID (uid));
    2404                 :             : 
    2405                 :           0 :   if (DF_INSN_UID_DEFS (uid))
    2406                 :             :     {
    2407                 :           0 :       fprintf (file, " defs ");
    2408                 :           0 :       df_refs_chain_dump (DF_INSN_UID_DEFS (uid), follow_chain, file);
    2409                 :             :     }
    2410                 :             : 
    2411                 :           0 :   if (DF_INSN_UID_USES (uid))
    2412                 :             :     {
    2413                 :           0 :       fprintf (file, " uses ");
    2414                 :           0 :       df_refs_chain_dump (DF_INSN_UID_USES (uid), follow_chain, file);
    2415                 :             :     }
    2416                 :             : 
    2417                 :           0 :   if (DF_INSN_UID_EQ_USES (uid))
    2418                 :             :     {
    2419                 :           0 :       fprintf (file, " eq uses ");
    2420                 :           0 :       df_refs_chain_dump (DF_INSN_UID_EQ_USES (uid), follow_chain, file);
    2421                 :             :     }
    2422                 :             : 
    2423                 :           0 :   if (DF_INSN_UID_MWS (uid))
    2424                 :             :     {
    2425                 :           0 :       fprintf (file, " mws ");
    2426                 :           0 :       df_mws_dump (DF_INSN_UID_MWS (uid), file);
    2427                 :             :     }
    2428                 :           0 :   fprintf (file, "\n");
    2429                 :           0 : }
    2430                 :             : 
    2431                 :             : 
    2432                 :             : DEBUG_FUNCTION void
    2433                 :           0 : df_insn_debug (rtx_insn *insn, bool follow_chain, FILE *file)
    2434                 :             : {
    2435                 :           0 :   df_insn_uid_debug (INSN_UID (insn), follow_chain, file);
    2436                 :           0 : }
    2437                 :             : 
    2438                 :             : DEBUG_FUNCTION void
    2439                 :           0 : df_insn_debug_regno (rtx_insn *insn, FILE *file)
    2440                 :             : {
    2441                 :           0 :   struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
    2442                 :             : 
    2443                 :           0 :   fprintf (file, "insn %d bb %d luid %d defs ",
    2444                 :           0 :            INSN_UID (insn), BLOCK_FOR_INSN (insn)->index,
    2445                 :             :            DF_INSN_INFO_LUID (insn_info));
    2446                 :           0 :   df_refs_chain_dump (DF_INSN_INFO_DEFS (insn_info), false, file);
    2447                 :             : 
    2448                 :           0 :   fprintf (file, " uses ");
    2449                 :           0 :   df_refs_chain_dump (DF_INSN_INFO_USES (insn_info), false, file);
    2450                 :             : 
    2451                 :           0 :   fprintf (file, " eq_uses ");
    2452                 :           0 :   df_refs_chain_dump (DF_INSN_INFO_EQ_USES (insn_info), false, file);
    2453                 :           0 :   fprintf (file, "\n");
    2454                 :           0 : }
    2455                 :             : 
    2456                 :             : DEBUG_FUNCTION void
    2457                 :           0 : df_regno_debug (unsigned int regno, FILE *file)
    2458                 :             : {
    2459                 :           0 :   fprintf (file, "reg %d defs ", regno);
    2460                 :           0 :   df_regs_chain_dump (DF_REG_DEF_CHAIN (regno), file);
    2461                 :           0 :   fprintf (file, " uses ");
    2462                 :           0 :   df_regs_chain_dump (DF_REG_USE_CHAIN (regno), file);
    2463                 :           0 :   fprintf (file, " eq_uses ");
    2464                 :           0 :   df_regs_chain_dump (DF_REG_EQ_USE_CHAIN (regno), file);
    2465                 :           0 :   fprintf (file, "\n");
    2466                 :           0 : }
    2467                 :             : 
    2468                 :             : 
    2469                 :             : DEBUG_FUNCTION void
    2470                 :           0 : df_ref_debug (df_ref ref, FILE *file)
    2471                 :             : {
    2472                 :           0 :   fprintf (file, "%c%d ",
    2473                 :           0 :            DF_REF_REG_DEF_P (ref) ? 'd' : 'u',
    2474                 :             :            DF_REF_ID (ref));
    2475                 :           0 :   fprintf (file, "reg %d bb %d insn %d flag %#x type %#x ",
    2476                 :             :            DF_REF_REGNO (ref),
    2477                 :           0 :            DF_REF_BBNO (ref),
    2478                 :           0 :            DF_REF_IS_ARTIFICIAL (ref) ? -1 : DF_REF_INSN_UID (ref),
    2479                 :           0 :            DF_REF_FLAGS (ref),
    2480                 :           0 :            DF_REF_TYPE (ref));
    2481                 :           0 :   if (DF_REF_LOC (ref))
    2482                 :             :     {
    2483                 :           0 :       if (flag_dump_noaddr)
    2484                 :           0 :         fprintf (file, "loc #(#) chain ");
    2485                 :             :       else
    2486                 :           0 :         fprintf (file, "loc %p(%p) chain ", (void *)DF_REF_LOC (ref),
    2487                 :             :                  (void *)*DF_REF_LOC (ref));
    2488                 :             :     }
    2489                 :             :   else
    2490                 :           0 :     fprintf (file, "chain ");
    2491                 :           0 :   df_chain_dump (DF_REF_CHAIN (ref), file);
    2492                 :           0 :   fprintf (file, "\n");
    2493                 :           0 : }
    2494                 :             : 
    2495                 :             : /* Functions for debugging from GDB.  */
    2496                 :             : 
    2497                 :             : DEBUG_FUNCTION void
    2498                 :           0 : debug_df_insn (rtx_insn *insn)
    2499                 :             : {
    2500                 :           0 :   df_insn_debug (insn, true, stderr);
    2501                 :           0 :   debug_rtx (insn);
    2502                 :           0 : }
    2503                 :             : 
    2504                 :             : 
    2505                 :             : DEBUG_FUNCTION void
    2506                 :           0 : debug_df_reg (rtx reg)
    2507                 :             : {
    2508                 :           0 :   df_regno_debug (REGNO (reg), stderr);
    2509                 :           0 : }
    2510                 :             : 
    2511                 :             : 
    2512                 :             : DEBUG_FUNCTION void
    2513                 :           0 : debug_df_regno (unsigned int regno)
    2514                 :             : {
    2515                 :           0 :   df_regno_debug (regno, stderr);
    2516                 :           0 : }
    2517                 :             : 
    2518                 :             : 
    2519                 :             : DEBUG_FUNCTION void
    2520                 :           0 : debug_df_ref (df_ref ref)
    2521                 :             : {
    2522                 :           0 :   df_ref_debug (ref, stderr);
    2523                 :           0 : }
    2524                 :             : 
    2525                 :             : 
    2526                 :             : DEBUG_FUNCTION void
    2527                 :           0 : debug_df_defno (unsigned int defno)
    2528                 :             : {
    2529                 :           0 :   df_ref_debug (DF_DEFS_GET (defno), stderr);
    2530                 :           0 : }
    2531                 :             : 
    2532                 :             : 
    2533                 :             : DEBUG_FUNCTION void
    2534                 :           0 : debug_df_useno (unsigned int defno)
    2535                 :             : {
    2536                 :           0 :   df_ref_debug (DF_USES_GET (defno), stderr);
    2537                 :           0 : }
    2538                 :             : 
    2539                 :             : 
    2540                 :             : DEBUG_FUNCTION void
    2541                 :           0 : debug_df_chain (struct df_link *link)
    2542                 :             : {
    2543                 :           0 :   df_chain_dump (link, stderr);
    2544                 :           0 :   fputc ('\n', stderr);
    2545                 :           0 : }
        

Generated by: LCOV version 2.1-beta

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