LCOV - code coverage report
Current view: top level - gcc - df-core.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 79.0 % 860 679
Test Date: 2026-02-28 14:20:25 Functions: 72.2 % 79 57
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Allocation for dataflow support routines.
       2              :    Copyright (C) 1999-2026 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     46900803 : df_add_problem (const struct df_problem *problem)
     416              : {
     417     46900803 :   struct dataflow *dflow;
     418     46900803 :   int i;
     419              : 
     420              :   /* First try to add the dependent problem. */
     421     46900803 :   if (problem->dependent_problem)
     422     22159274 :     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     46900803 :   dflow = df->problems_by_index[problem->id];
     428     46900803 :   if (dflow)
     429              :     return;
     430              : 
     431              :   /* Make a new one and add it to the end.  */
     432     30190080 :   dflow = XCNEW (struct dataflow);
     433     30190080 :   dflow->problem = problem;
     434     30190080 :   dflow->computed = false;
     435     30190080 :   dflow->solutions_dirty = true;
     436     30190080 :   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     30190080 :   df->num_problems_defined++;
     446     30647105 :   for (i = df->num_problems_defined - 2; i >= 0; i--)
     447              :     {
     448     29175740 :       if (problem->id < df->problems_in_order[i]->problem->id)
     449       457025 :         df->problems_in_order[i+1] = df->problems_in_order[i];
     450              :       else
     451              :         {
     452     28718715 :           df->problems_in_order[i+1] = dflow;
     453     28718715 :           return;
     454              :         }
     455              :     }
     456      1471365 :   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     49739594 : df_set_flags (int changeable_flags)
     465              : {
     466     49739594 :   int old_flags = df->changeable_flags;
     467     49739594 :   df->changeable_flags |= changeable_flags;
     468     49739594 :   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     27981066 : df_clear_flags (int changeable_flags)
     477              : {
     478     27981066 :   int old_flags = df->changeable_flags;
     479     27981066 :   df->changeable_flags &= ~changeable_flags;
     480     27981066 :   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      1304188 : df_set_blocks (bitmap blocks)
     490              : {
     491      1304188 :   if (blocks)
     492              :     {
     493      1304188 :       if (dump_file)
     494          195 :         bitmap_print (dump_file, blocks, "setting blocks to analyze ", "\n");
     495      1304188 :       if (df->blocks_to_analyze)
     496              :         {
     497              :           /* This block is called to change the focus from one subset
     498              :              to another.  */
     499       910387 :           int p;
     500       910387 :           auto_bitmap diff (&df_bitmap_obstack);
     501       910387 :           bitmap_and_compl (diff, df->blocks_to_analyze, blocks);
     502      6828792 :           for (p = 0; p < df->num_problems_defined; p++)
     503              :             {
     504      5918405 :               struct dataflow *dflow = df->problems_in_order[p];
     505      5918405 :               if (dflow->optional_p && dflow->problem->reset_fun)
     506        29672 :                 dflow->problem->reset_fun (df->blocks_to_analyze);
     507      5888733 :               else if (dflow->problem->free_blocks_on_set_blocks)
     508              :                 {
     509       910387 :                   bitmap_iterator bi;
     510       910387 :                   unsigned int bb_index;
     511              : 
     512      4498506 :                   EXECUTE_IF_SET_IN_BITMAP (diff, 0, bb_index, bi)
     513              :                     {
     514      3588119 :                       basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
     515      3588119 :                       if (bb)
     516              :                         {
     517      7176238 :                           void *bb_info = df_get_bb_info (dflow, bb_index);
     518      3588119 :                           dflow->problem->free_bb_fun (bb, bb_info);
     519      3588119 :                           df_clear_bb_info (dflow, bb_index);
     520              :                         }
     521              :                     }
     522              :                 }
     523              :             }
     524       910387 :         }
     525              :       else
     526              :         {
     527              :           /* This block of code is executed to change the focus from
     528              :              the entire function to a subset.  */
     529       393801 :           bitmap_head blocks_to_reset;
     530       393801 :           bool initialized = false;
     531       393801 :           int p;
     532      2942339 :           for (p = 0; p < df->num_problems_defined; p++)
     533              :             {
     534      2548538 :               struct dataflow *dflow = df->problems_in_order[p];
     535      2548538 :               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       393801 :           if (initialized)
     550              :             bitmap_clear (&blocks_to_reset);
     551              : 
     552       393801 :           df->blocks_to_analyze = BITMAP_ALLOC (&df_bitmap_obstack);
     553              :         }
     554      1304188 :       bitmap_copy (df->blocks_to_analyze, blocks);
     555      1304188 :       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      1304188 :   df_maybe_reorganize_def_refs (DF_REF_ORDER_NO_TABLE);
     574      1304188 :   df_maybe_reorganize_use_refs (DF_REF_ORDER_NO_TABLE);
     575      1304188 :   df_mark_solutions_dirty ();
     576      1304188 : }
     577              : 
     578              : 
     579              : /* Delete a DFLOW problem (and any problems that depend on this
     580              :    problem).  */
     581              : 
     582              : void
     583     24997850 : df_remove_problem (struct dataflow *dflow)
     584              : {
     585     24997850 :   const struct df_problem *problem;
     586     24997850 :   int i;
     587              : 
     588     24997850 :   if (!dflow)
     589              :     return;
     590              : 
     591     24812004 :   problem = dflow->problem;
     592     24812004 :   gcc_assert (problem->remove_problem_fun);
     593              : 
     594              :   /* Delete any problems that depended on this problem first.  */
     595    158041048 :   for (i = 0; i < df->num_problems_defined; i++)
     596    133229044 :     if (df->problems_in_order[i]->problem->dependent_problem == problem)
     597      3927037 :       df_remove_problem (df->problems_in_order[i]);
     598              : 
     599              :   /* Now remove this problem.  */
     600    126717559 :   for (i = 0; i < df->num_problems_defined; i++)
     601    126717559 :     if (df->problems_in_order[i] == dflow)
     602              :       {
     603     24812004 :         int j;
     604     28546555 :         for (j = i + 1; j < df->num_problems_defined; j++)
     605      3734551 :           df->problems_in_order[j-1] = df->problems_in_order[j];
     606     24812004 :         df->problems_in_order[j-1] = NULL;
     607     24812004 :         df->num_problems_defined--;
     608     24812004 :         break;
     609              :       }
     610              : 
     611     24812004 :   (problem->remove_problem_fun) ();
     612     24812004 :   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     40856520 : df_finish_pass (bool verify ATTRIBUTE_UNUSED)
     622              : {
     623     40856520 :   int i;
     624              : 
     625              : #ifdef ENABLE_DF_CHECKING
     626              :   int saved_flags;
     627              : #endif
     628              : 
     629     40856520 :   if (!df)
     630              :     return;
     631              : 
     632     40856519 :   df_maybe_reorganize_def_refs (DF_REF_ORDER_NO_TABLE);
     633     40856519 :   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    449421709 :   for (i = 0; i < DF_LAST_PROBLEM_PLUS1; i++)
     642              :     {
     643    408565190 :       struct dataflow *dflow = df->problems_by_index[i];
     644              : 
     645    408565190 :       if (dflow && dflow->optional_p)
     646     17437001 :         df_remove_problem (dflow);
     647              :     }
     648              : 
     649              :   /* Clear all of the flags.  */
     650     40856519 :   df->changeable_flags = 0;
     651     40856519 :   df_process_deferred_rescans ();
     652              : 
     653              :   /* Set the focus back to the whole function.  */
     654     40856519 :   if (df->blocks_to_analyze)
     655              :     {
     656       393801 :       BITMAP_FREE (df->blocks_to_analyze);
     657       393801 :       df->blocks_to_analyze = NULL;
     658       393801 :       df_mark_solutions_dirty ();
     659       393801 :       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     40856519 :   if (flag_checking && verify)
     677      5312182 :     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      1471365 : rest_of_handle_df_initialize (void)
     685              : {
     686      1471365 :   gcc_assert (!df);
     687      1471365 :   df = XCNEW (class df_d);
     688      1471365 :   df->changeable_flags = 0;
     689              : 
     690      1471365 :   bitmap_obstack_initialize (&df_bitmap_obstack);
     691              : 
     692              :   /* Set this to a conservative value.  Stack_ptr_mod will compute it
     693              :      correctly later.  */
     694      1471365 :   crtl->sp_is_unchanging = 0;
     695              : 
     696      1471365 :   df_scan_add_problem ();
     697      1471365 :   df_scan_alloc (NULL);
     698              : 
     699              :   /* These three problems are permanent.  */
     700      1471365 :   df_lr_add_problem ();
     701      1471365 :   if (optimize > 1)
     702       963981 :     df_live_add_problem ();
     703              : 
     704      1471365 :   df->hard_regs_live_count = XCNEWVEC (unsigned int, FIRST_PSEUDO_REGISTER);
     705              : 
     706      1471365 :   df_hard_reg_init ();
     707              :   /* After reload, some ports add certain bits to regs_ever_live so
     708              :      this cannot be reset.  */
     709      1471365 :   df_compute_regs_ever_live (true);
     710      1471365 :   df_scan_blocks ();
     711      1471365 :   df_compute_regs_ever_live (false);
     712      1471365 :   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       285722 :   pass_df_initialize_opt (gcc::context *ctxt)
     735       571444 :     : rtl_opt_pass (pass_data_df_initialize_opt, ctxt)
     736              :   {}
     737              : 
     738              :   /* opt_pass methods: */
     739      1471370 :   bool gate (function *) final override { return optimize > 0; }
     740      1043685 :   unsigned int execute (function *) final override
     741              :     {
     742      1043685 :       return rest_of_handle_df_initialize ();
     743              :     }
     744              : 
     745              : }; // class pass_df_initialize_opt
     746              : 
     747              : } // anon namespace
     748              : 
     749              : rtl_opt_pass *
     750       285722 : make_pass_df_initialize_opt (gcc::context *ctxt)
     751              : {
     752       285722 :   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       285722 :   pass_df_initialize_no_opt (gcc::context *ctxt)
     775       571444 :     : rtl_opt_pass (pass_data_df_initialize_no_opt, ctxt)
     776              :   {}
     777              : 
     778              :   /* opt_pass methods: */
     779      1471370 :   bool gate (function *) final override { return optimize == 0; }
     780       427680 :   unsigned int execute (function *) final override
     781              :     {
     782       427680 :       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       285722 : make_pass_df_initialize_no_opt (gcc::context *ctxt)
     791              : {
     792       285722 :   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      1471365 : rest_of_handle_df_finish (void)
     801              : {
     802      1471365 :   int i;
     803              : 
     804      1471365 :   gcc_assert (df);
     805              : 
     806      6849441 :   for (i = 0; i < df->num_problems_defined; i++)
     807              :     {
     808      5378076 :       struct dataflow *dflow = df->problems_in_order[i];
     809      5378076 :       if (dflow->problem->free_fun)
     810      3906711 :         dflow->problem->free_fun ();
     811              :       else
     812      1471365 :         free (dflow);
     813              :     }
     814              : 
     815      1471365 :   free (df->postorder);
     816      1471365 :   free (df->postorder_inverted);
     817      1471365 :   free (df->hard_regs_live_count);
     818      1471365 :   free (df);
     819      1471365 :   df = NULL;
     820              : 
     821      1471365 :   bitmap_obstack_release (&df_bitmap_obstack);
     822      1471365 :   return 0;
     823              : }
     824              : 
     825              : 
     826              : namespace {
     827              : 
     828              : const pass_data pass_data_df_finish =
     829              : {
     830              :   RTL_PASS, /* type */
     831              :   "dfinish", /* name */
     832              :   OPTGROUP_NONE, /* optinfo_flags */
     833              :   TV_NONE, /* tv_id */
     834              :   0, /* properties_required */
     835              :   0, /* properties_provided */
     836              :   0, /* properties_destroyed */
     837              :   0, /* todo_flags_start */
     838              :   0, /* todo_flags_finish */
     839              : };
     840              : 
     841              : class pass_df_finish : public rtl_opt_pass
     842              : {
     843              : public:
     844       285722 :   pass_df_finish (gcc::context *ctxt)
     845       571444 :     : rtl_opt_pass (pass_data_df_finish, ctxt)
     846              :   {}
     847              : 
     848              :   /* opt_pass methods: */
     849      1471365 :   unsigned int execute (function *) final override
     850              :     {
     851      1471365 :       return rest_of_handle_df_finish ();
     852              :     }
     853              : 
     854              : }; // class pass_df_finish
     855              : 
     856              : } // anon namespace
     857              : 
     858              : rtl_opt_pass *
     859       285722 : make_pass_df_finish (gcc::context *ctxt)
     860              : {
     861       285722 :   return new pass_df_finish (ctxt);
     862              : }
     863              : 
     864              : 
     865              : 
     866              : 
     867              : 
     868              : /*----------------------------------------------------------------------------
     869              :    The general data flow analysis engine.
     870              : ----------------------------------------------------------------------------*/
     871              : 
     872              : /* Helper function for df_worklist_dataflow.
     873              :    Propagate the dataflow forward.
     874              :    Given a BB_INDEX, do the dataflow propagation
     875              :    and set bits on for successors in PENDING for earlier
     876              :    and WORKLIST for later in bbindex_to_postorder
     877              :    if the out set of the dataflow has changed.  When WORKLIST
     878              :    is NULL we are processing all later blocks.
     879              : 
     880              :    AGE specify time when BB was visited last time.
     881              :    AGE of 0 means we are visiting for first time and need to
     882              :    compute transfer function to initialize datastructures.
     883              :    Otherwise we re-do transfer function only if something change
     884              :    while computing confluence functions.
     885              :    We need to compute confluence only of basic block that are younger
     886              :    then last visit of the BB.
     887              : 
     888              :    Return true if BB info has changed.  This is always the case
     889              :    in the first visit.  */
     890              : 
     891              : static bool
     892    438082854 : df_worklist_propagate_forward (struct dataflow *dataflow,
     893              :                                unsigned bb_index,
     894              :                                unsigned *bbindex_to_postorder,
     895              :                                bitmap worklist,
     896              :                                bitmap pending,
     897              :                                sbitmap considered,
     898              :                                vec<int> &last_change_age,
     899              :                                int age)
     900              : {
     901    438082854 :   edge e;
     902    438082854 :   edge_iterator ei;
     903    438082854 :   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
     904    438082854 :   bool changed = !age;
     905              : 
     906              :   /*  Calculate <conf_op> of incoming edges.  */
     907    438082854 :   if (EDGE_COUNT (bb->preds) > 0)
     908   1045112752 :     FOR_EACH_EDGE (e, ei, bb->preds)
     909              :       {
     910     81518683 :         if ((!age || age <= last_change_age[e->src->index])
     911    682598164 :             && bitmap_bit_p (considered, e->src->index))
     912    596706121 :           changed |= dataflow->problem->con_fun_n (e);
     913              :       }
     914     19976500 :   else if (dataflow->problem->con_fun_0)
     915      1359938 :     dataflow->problem->con_fun_0 (bb);
     916              : 
     917    438082854 :   if (changed
     918    438082854 :       && dataflow->problem->trans_fun (bb_index))
     919              :     {
     920              :       /* The out set of this block has changed.
     921              :          Propagate to the outgoing blocks.  */
     922    917612321 :       FOR_EACH_EDGE (e, ei, bb->succs)
     923              :         {
     924    539229317 :           unsigned ob_index = e->dest->index;
     925              : 
     926    539229317 :           if (bitmap_bit_p (considered, ob_index))
     927              :             {
     928    532817946 :               if (bbindex_to_postorder[bb_index]
     929    532817946 :                   < bbindex_to_postorder[ob_index])
     930              :                 {
     931    507783171 :                   if (worklist)
     932     28791485 :                     bitmap_set_bit (worklist, bbindex_to_postorder[ob_index]);
     933              :                 }
     934              :               else
     935     25034775 :                 bitmap_set_bit (pending, bbindex_to_postorder[ob_index]);
     936              :             }
     937              :         }
     938              :       return true;
     939              :     }
     940              :   return false;
     941              : }
     942              : 
     943              : 
     944              : /* Helper function for df_worklist_dataflow.
     945              :    Propagate the dataflow backward.  */
     946              : 
     947              : static bool
     948    463449714 : df_worklist_propagate_backward (struct dataflow *dataflow,
     949              :                                 unsigned bb_index,
     950              :                                 unsigned *bbindex_to_postorder,
     951              :                                 bitmap worklist,
     952              :                                 bitmap pending,
     953              :                                 sbitmap considered,
     954              :                                 vec<int> &last_change_age,
     955              :                                 int age)
     956              : {
     957    463449714 :   edge e;
     958    463449714 :   edge_iterator ei;
     959    463449714 :   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
     960    463449714 :   bool changed = !age;
     961              : 
     962              :   /*  Calculate <conf_op> of incoming edges.  */
     963    463449714 :   if (EDGE_COUNT (bb->succs) > 0)
     964   1102190230 :     FOR_EACH_EDGE (e, ei, bb->succs)
     965              :       {
     966    112480292 :         if ((!age || age <= last_change_age[e->dest->index])
     967    754651746 :             && bitmap_bit_p (considered, e->dest->index))
     968    636714465 :           changed |= dataflow->problem->con_fun_n (e);
     969              :       }
     970     32730476 :   else if (dataflow->problem->con_fun_0)
     971     29564312 :     dataflow->problem->con_fun_0 (bb);
     972              : 
     973    463449714 :   if (changed
     974    463449714 :       && dataflow->problem->trans_fun (bb_index))
     975              :     {
     976              :       /* The out set of this block has changed.
     977              :          Propagate to the outgoing blocks.  */
     978    742399514 :       FOR_EACH_EDGE (e, ei, bb->preds)
     979              :         {
     980    432552785 :           unsigned ob_index = e->src->index;
     981              : 
     982    432552785 :           if (bitmap_bit_p (considered, ob_index))
     983              :             {
     984    430816645 :               if (bbindex_to_postorder[bb_index]
     985    430816645 :                   < bbindex_to_postorder[ob_index])
     986              :                 {
     987    407658534 :                   if (worklist)
     988     58939398 :                     bitmap_set_bit (worklist, bbindex_to_postorder[ob_index]);
     989              :                 }
     990              :               else
     991     23158111 :                 bitmap_set_bit (pending, bbindex_to_postorder[ob_index]);
     992              :             }
     993              :         }
     994              :       return true;
     995              :     }
     996              :   return false;
     997              : }
     998              : 
     999              : /* Main dataflow solver loop.
    1000              : 
    1001              :    DATAFLOW is problem we are solving, PENDING is worklist of basic blocks we
    1002              :    need to visit.
    1003              :    BLOCK_IN_POSTORDER is array of size N_BLOCKS specifying postorder in BBs and
    1004              :    BBINDEX_TO_POSTORDER is array mapping back BB->index to postorder position.
    1005              :    PENDING will be freed.
    1006              : 
    1007              :    The worklists are bitmaps indexed by postorder positions.
    1008              : 
    1009              :    The function implements standard algorithm for dataflow solving with two
    1010              :    worklists (we are processing WORKLIST and storing new BBs to visit in
    1011              :    PENDING).
    1012              : 
    1013              :    As an optimization we maintain ages when BB was changed (stored in
    1014              :    last_change_age) and when it was last visited (stored in last_visit_age).
    1015              :    This avoids need to re-do confluence function for edges to basic blocks
    1016              :    whose source did not change since destination was visited last time.  */
    1017              : 
    1018              : static void
    1019     41400834 : df_worklist_dataflow_doublequeue (struct dataflow *dataflow,
    1020              :                                   sbitmap considered,
    1021              :                                   int *blocks_in_postorder,
    1022              :                                   unsigned *bbindex_to_postorder,
    1023              :                                   unsigned n_blocks)
    1024              : {
    1025     41400834 :   enum df_flow_dir dir = dataflow->problem->dir;
    1026     41400834 :   int dcount = 0;
    1027     41400834 :   int age = 0;
    1028     41400834 :   bool changed;
    1029     41400834 :   vec<int> last_visit_age = vNULL;
    1030     41400834 :   vec<int> last_change_age = vNULL;
    1031              : 
    1032     41400834 :   bitmap worklist = BITMAP_ALLOC (&df_bitmap_obstack);
    1033     41400834 :   bitmap_tree_view (worklist);
    1034              : 
    1035     41400834 :   last_visit_age.safe_grow (n_blocks, true);
    1036     41400834 :   last_change_age.safe_grow (last_basic_block_for_fn (cfun) + 1, true);
    1037              :   /* Make last_change_age defined - we can access uninit values for not
    1038              :      considered blocks but will make sure they are considered as well.  */
    1039              :   VALGRIND_DISCARD (VALGRIND_MAKE_MEM_DEFINED
    1040              :                       (last_change_age.address (),
    1041     41400834 :                        sizeof (int) * last_basic_block_for_fn (cfun)));
    1042              : 
    1043              :   /* We start with processing all blocks, populating pending for the
    1044              :      next iteration.  */
    1045     41400834 :   bitmap pending = BITMAP_ALLOC (&df_bitmap_obstack);
    1046     41400834 :   bitmap_tree_view (pending);
    1047    833232614 :   for (unsigned index = 0; index < n_blocks; ++index)
    1048              :     {
    1049    791831780 :       unsigned bb_index = blocks_in_postorder[index];
    1050    791831780 :       dcount++;
    1051    791831780 :       if (dir == DF_FORWARD)
    1052    393443311 :         changed = df_worklist_propagate_forward (dataflow, bb_index,
    1053              :                                                  bbindex_to_postorder,
    1054              :                                                  NULL, pending,
    1055              :                                                  considered,
    1056              :                                                  last_change_age, 0);
    1057              :       else
    1058    398388469 :         changed = df_worklist_propagate_backward (dataflow, bb_index,
    1059              :                                                   bbindex_to_postorder,
    1060              :                                                   NULL, pending,
    1061              :                                                   considered,
    1062              :                                                   last_change_age, 0);
    1063    791831780 :       last_visit_age[index] = ++age;
    1064    791831780 :       if (changed)
    1065    625622568 :         last_change_age[bb_index] = age;
    1066              :       else
    1067    166209212 :         last_change_age[bb_index] = 0;
    1068              :     }
    1069              : 
    1070              :   /* Double-queueing.  Worklist is for the current iteration,
    1071              :      and pending is for the next.  */
    1072     56334593 :   while (!bitmap_empty_p (pending))
    1073              :     {
    1074              :       std::swap (pending, worklist);
    1075              : 
    1076    109700788 :       do
    1077              :         {
    1078    109700788 :           unsigned index = bitmap_clear_first_set_bit (worklist);
    1079    109700788 :           unsigned bb_index = blocks_in_postorder[index];
    1080    109700788 :           dcount++;
    1081    109700788 :           int prev_age = last_visit_age[index];
    1082    109700788 :           if (dir == DF_FORWARD)
    1083     44639543 :             changed = df_worklist_propagate_forward (dataflow, bb_index,
    1084              :                                                      bbindex_to_postorder,
    1085              :                                                      worklist, pending,
    1086              :                                                      considered,
    1087              :                                                      last_change_age,
    1088              :                                                      prev_age);
    1089              :           else
    1090     65061245 :             changed = df_worklist_propagate_backward (dataflow, bb_index,
    1091              :                                                       bbindex_to_postorder,
    1092              :                                                       worklist, pending,
    1093              :                                                       considered,
    1094              :                                                       last_change_age,
    1095              :                                                       prev_age);
    1096    109700788 :           last_visit_age[index] = ++age;
    1097    109700788 :           if (changed)
    1098     62607165 :             last_change_age[bb_index] = age;
    1099              :         }
    1100    109700788 :       while (!bitmap_empty_p (worklist));
    1101              :     }
    1102              : 
    1103     41400834 :   BITMAP_FREE (worklist);
    1104     41400834 :   BITMAP_FREE (pending);
    1105     41400834 :   last_visit_age.release ();
    1106     41400834 :   last_change_age.release ();
    1107              : 
    1108              :   /* Dump statistics. */
    1109     41400834 :   if (dump_file)
    1110         1894 :     fprintf (dump_file, "df_worklist_dataflow_doublequeue:"
    1111              :              " n_basic_blocks %d n_edges %d"
    1112              :              " count %d (%5.2g)\n",
    1113              :              n_basic_blocks_for_fn (cfun), n_edges_for_fn (cfun),
    1114         1894 :              dcount, dcount / (double)n_basic_blocks_for_fn (cfun));
    1115     41400834 : }
    1116              : 
    1117              : /* Worklist-based dataflow solver. It uses sbitmap as a worklist,
    1118              :    with "n"-th bit representing the n-th block in the reverse-postorder order.
    1119              :    The solver is a double-queue algorithm similar to the "double stack" solver
    1120              :    from Cooper, Harvey and Kennedy, "Iterative data-flow analysis, Revisited".
    1121              :    The only significant difference is that the worklist in this implementation
    1122              :    is always sorted in RPO of the CFG visiting direction.  */
    1123              : 
    1124              : void
    1125     41400834 : df_worklist_dataflow (struct dataflow *dataflow,
    1126              :                       bitmap blocks_to_consider,
    1127              :                       int *blocks_in_postorder,
    1128              :                       int n_blocks)
    1129              : {
    1130     41400834 :   bitmap_iterator bi;
    1131     41400834 :   unsigned int *bbindex_to_postorder;
    1132     41400834 :   int i;
    1133     41400834 :   unsigned int index;
    1134     41400834 :   enum df_flow_dir dir = dataflow->problem->dir;
    1135              : 
    1136     41400834 :   gcc_assert (dir != DF_NONE);
    1137              : 
    1138              :   /* BBINDEX_TO_POSTORDER maps the bb->index to the reverse postorder.  */
    1139     41400834 :   bbindex_to_postorder = XNEWVEC (unsigned int,
    1140              :                                   last_basic_block_for_fn (cfun));
    1141              : 
    1142              :   /* Initialize the array to an out-of-bound value.  */
    1143   1619590637 :   for (i = 0; i < last_basic_block_for_fn (cfun); i++)
    1144   1536788969 :     bbindex_to_postorder[i] = last_basic_block_for_fn (cfun);
    1145              : 
    1146              :   /* Initialize the considered map.  */
    1147     41400834 :   auto_sbitmap considered (last_basic_block_for_fn (cfun));
    1148     41400834 :   bitmap_clear (considered);
    1149    829392354 :   EXECUTE_IF_SET_IN_BITMAP (blocks_to_consider, 0, index, bi)
    1150              :     {
    1151    787991520 :       bitmap_set_bit (considered, index);
    1152              :     }
    1153              : 
    1154              :   /* Initialize the mapping of block index to postorder.  */
    1155    833232614 :   for (i = 0; i < n_blocks; i++)
    1156    791831780 :     bbindex_to_postorder[blocks_in_postorder[i]] = i;
    1157              : 
    1158              :   /* Initialize the problem. */
    1159     41400834 :   if (dataflow->problem->init_fun)
    1160     38737778 :     dataflow->problem->init_fun (blocks_to_consider);
    1161              : 
    1162              :   /* Solve it.  */
    1163     41400834 :   df_worklist_dataflow_doublequeue (dataflow, considered, blocks_in_postorder,
    1164              :                                     bbindex_to_postorder, n_blocks);
    1165     41400834 :   free (bbindex_to_postorder);
    1166     41400834 : }
    1167              : 
    1168              : 
    1169              : /* Remove the entries not in BLOCKS from the LIST of length LEN, preserving
    1170              :    the order of the remaining entries.  Returns the length of the resulting
    1171              :    list.  */
    1172              : 
    1173              : static unsigned
    1174            0 : df_prune_to_subcfg (int list[], unsigned len, bitmap blocks)
    1175              : {
    1176            0 :   unsigned act, last;
    1177              : 
    1178            0 :   for (act = 0, last = 0; act < len; act++)
    1179            0 :     if (bitmap_bit_p (blocks, list[act]))
    1180            0 :       list[last++] = list[act];
    1181              : 
    1182            0 :   return last;
    1183              : }
    1184              : 
    1185              : 
    1186              : /* Execute dataflow analysis on a single dataflow problem.
    1187              : 
    1188              :    BLOCKS_TO_CONSIDER are the blocks whose solution can either be
    1189              :    examined or will be computed.  For calls from DF_ANALYZE, this is
    1190              :    the set of blocks that has been passed to DF_SET_BLOCKS.
    1191              : */
    1192              : 
    1193              : void
    1194     83977052 : df_analyze_problem (struct dataflow *dflow,
    1195              :                     bitmap blocks_to_consider,
    1196              :                     int *postorder, int n_blocks)
    1197              : {
    1198     83977052 :   timevar_push (dflow->problem->tv_id);
    1199              : 
    1200              :   /* (Re)Allocate the datastructures necessary to solve the problem.  */
    1201     83977052 :   if (dflow->problem->alloc_fun)
    1202     59816805 :     dflow->problem->alloc_fun (blocks_to_consider);
    1203              : 
    1204              : #ifdef ENABLE_DF_CHECKING
    1205              :   if (dflow->problem->verify_start_fun)
    1206              :     dflow->problem->verify_start_fun ();
    1207              : #endif
    1208              : 
    1209              :   /* Set up the problem and compute the local information.  */
    1210     83977052 :   if (dflow->problem->local_compute_fun)
    1211     53807521 :     dflow->problem->local_compute_fun (blocks_to_consider);
    1212              : 
    1213              :   /* Solve the equations.  */
    1214     83977052 :   if (dflow->problem->dataflow_fun)
    1215     38060621 :     dflow->problem->dataflow_fun (dflow, blocks_to_consider,
    1216              :                                   postorder, n_blocks);
    1217              : 
    1218              :   /* Massage the solution.  */
    1219     83977052 :   if (dflow->problem->finalize_fun)
    1220     61110245 :     dflow->problem->finalize_fun (blocks_to_consider);
    1221              : 
    1222              : #ifdef ENABLE_DF_CHECKING
    1223              :   if (dflow->problem->verify_end_fun)
    1224              :     dflow->problem->verify_end_fun ();
    1225              : #endif
    1226              : 
    1227     83977052 :   timevar_pop (dflow->problem->tv_id);
    1228              : 
    1229     83977052 :   dflow->computed = true;
    1230     83977052 : }
    1231              : 
    1232              : 
    1233              : /* Analyze dataflow info.  */
    1234              : 
    1235              : static void
    1236     43717090 : df_analyze_1 (void)
    1237              : {
    1238     43717090 :   int i;
    1239              : 
    1240              :   /* We need to do this before the df_verify_all because this is
    1241              :      not kept incrementally up to date.  */
    1242     43717090 :   df_compute_regs_ever_live (false);
    1243     43717090 :   df_process_deferred_rescans ();
    1244              : 
    1245     43717090 :   if (dump_file)
    1246         1706 :     fprintf (dump_file, "df_analyze called\n");
    1247              : 
    1248              : #ifndef ENABLE_DF_CHECKING
    1249     43717090 :   if (df->changeable_flags & DF_VERIFY_SCHEDULED)
    1250              : #endif
    1251      6379161 :     df_verify ();
    1252              : 
    1253              :   /* Skip over the DF_SCAN problem. */
    1254    198166272 :   for (i = 1; i < df->num_problems_defined; i++)
    1255              :     {
    1256    154449182 :       struct dataflow *dflow = df->problems_in_order[i];
    1257    154449182 :       if (dflow->solutions_dirty)
    1258              :         {
    1259     83976514 :           if (dflow->problem->dir == DF_FORWARD)
    1260     21796873 :             df_analyze_problem (dflow,
    1261              :                                 df->blocks_to_analyze,
    1262              :                                 df->postorder_inverted,
    1263              :                                 df->n_blocks);
    1264              :           else
    1265     62179641 :             df_analyze_problem (dflow,
    1266              :                                 df->blocks_to_analyze,
    1267              :                                 df->postorder,
    1268              :                                 df->n_blocks);
    1269              :         }
    1270              :     }
    1271              : 
    1272     43717090 :   if (!df->analyze_subset)
    1273              :     {
    1274     42412902 :       BITMAP_FREE (df->blocks_to_analyze);
    1275     42412902 :       df->blocks_to_analyze = NULL;
    1276              :     }
    1277              : 
    1278              : #ifdef DF_DEBUG_CFG
    1279              :   df_set_clean_cfg ();
    1280              : #endif
    1281     43717090 : }
    1282              : 
    1283              : /* Analyze dataflow info.  */
    1284              : 
    1285              : void
    1286     42412902 : df_analyze (void)
    1287              : {
    1288     42412902 :   bitmap current_all_blocks = BITMAP_ALLOC (&df_bitmap_obstack);
    1289              : 
    1290     42412902 :   free (df->postorder);
    1291     42412902 :   free (df->postorder_inverted);
    1292              :   /* For DF_FORWARD use a RPO on the forward graph.  Since we want to
    1293              :      have unreachable blocks deleted use post_order_compute and reverse
    1294              :      the order.  */
    1295     42412902 :   df->postorder_inverted = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
    1296     42412902 :   df->n_blocks = post_order_compute (df->postorder_inverted, true, true);
    1297    321398391 :   for (int i = 0; i < df->n_blocks / 2; ++i)
    1298    278985489 :     std::swap (df->postorder_inverted[i],
    1299    278985489 :                df->postorder_inverted[df->n_blocks - 1 - i]);
    1300              :   /* For DF_BACKWARD use a RPO on the reverse graph.  */
    1301     42412902 :   df->postorder = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
    1302     42412902 :   int n = inverted_rev_post_order_compute (cfun, df->postorder);
    1303     42412902 :   gcc_assert (n == df->n_blocks);
    1304              : 
    1305    633294606 :   for (int i = 0; i < df->n_blocks; i++)
    1306    590881704 :     bitmap_set_bit (current_all_blocks, df->postorder[i]);
    1307              : 
    1308     42412902 :   if (flag_checking)
    1309              :     {
    1310              :       /* Verify that POSTORDER_INVERTED only contains blocks reachable from
    1311              :          the ENTRY block.  */
    1312    633289650 :       for (int i = 0; i < df->n_blocks; i++)
    1313    590877421 :         gcc_assert (bitmap_bit_p (current_all_blocks,
    1314              :                                   df->postorder_inverted[i]));
    1315              :     }
    1316              : 
    1317              :   /* Make sure that we have pruned any unreachable blocks from these
    1318              :      sets.  */
    1319     42412902 :   if (df->analyze_subset)
    1320              :     {
    1321            0 :       bitmap_and_into (df->blocks_to_analyze, current_all_blocks);
    1322            0 :       unsigned int newlen = df_prune_to_subcfg (df->postorder, df->n_blocks,
    1323              :                                                 df->blocks_to_analyze);
    1324            0 :       df_prune_to_subcfg (df->postorder_inverted, df->n_blocks,
    1325              :                           df->blocks_to_analyze);
    1326            0 :       df->n_blocks = newlen;
    1327            0 :       BITMAP_FREE (current_all_blocks);
    1328              :     }
    1329              :   else
    1330              :     {
    1331     42412902 :       df->blocks_to_analyze = current_all_blocks;
    1332     42412902 :       current_all_blocks = NULL;
    1333              :     }
    1334              : 
    1335     42412902 :   df_analyze_1 ();
    1336     42412902 : }
    1337              : 
    1338              : /* Compute the reverse top sort order of the sub-CFG specified by LOOP.
    1339              :    Returns the number of blocks which is always loop->num_nodes.  */
    1340              : 
    1341              : static int
    1342      1304188 : loop_rev_post_order_compute (int *post_order, class loop *loop)
    1343              : {
    1344      1304188 :   edge_iterator *stack;
    1345      1304188 :   int sp;
    1346      1304188 :   int post_order_num = loop->num_nodes - 1;
    1347              : 
    1348              :   /* Allocate stack for back-tracking up CFG.  */
    1349      1304188 :   stack = XNEWVEC (edge_iterator, loop->num_nodes + 1);
    1350      1304188 :   sp = 0;
    1351              : 
    1352              :   /* Allocate bitmap to track nodes that have been visited.  */
    1353      1304188 :   auto_bitmap visited;
    1354              : 
    1355              :   /* Push the first edge on to the stack.  */
    1356      1304188 :   stack[sp++] = ei_start (loop_preheader_edge (loop)->src->succs);
    1357              : 
    1358     22959806 :   while (sp)
    1359              :     {
    1360     21655618 :       edge_iterator ei;
    1361     21655618 :       basic_block src;
    1362     21655618 :       basic_block dest;
    1363              : 
    1364              :       /* Look at the edge on the top of the stack.  */
    1365     21655618 :       ei = stack[sp - 1];
    1366     21655618 :       src = ei_edge (ei)->src;
    1367     21655618 :       dest = ei_edge (ei)->dest;
    1368              : 
    1369              :       /* Check if the edge destination has been visited yet and mark it
    1370              :          if not so.  */
    1371     21655618 :       if (flow_bb_inside_loop_p (loop, dest)
    1372     21655618 :           && bitmap_set_bit (visited, dest->index))
    1373              :         {
    1374      7957874 :           if (EDGE_COUNT (dest->succs) > 0)
    1375              :             /* Since the DEST node has been visited for the first
    1376              :                time, check its successors.  */
    1377      7957874 :             stack[sp++] = ei_start (dest->succs);
    1378              :           else
    1379            0 :             post_order[post_order_num--] = dest->index;
    1380              :         }
    1381              :       else
    1382              :         {
    1383     13697744 :           if (ei_one_before_end_p (ei)
    1384     13697744 :               && src != loop_preheader_edge (loop)->src)
    1385      7957874 :             post_order[post_order_num--] = src->index;
    1386              : 
    1387     13697744 :           if (!ei_one_before_end_p (ei))
    1388      4435682 :             ei_next (&stack[sp - 1]);
    1389              :           else
    1390      9262062 :             sp--;
    1391              :         }
    1392              :     }
    1393              : 
    1394      1304188 :   free (stack);
    1395              : 
    1396      1304188 :   return loop->num_nodes;
    1397      1304188 : }
    1398              : 
    1399              : /* Compute the reverse top sort order of the inverted sub-CFG specified
    1400              :    by LOOP.  Returns the number of blocks which is always loop->num_nodes.  */
    1401              : 
    1402              : static int
    1403      1304188 : loop_inverted_rev_post_order_compute (int *post_order, class loop *loop)
    1404              : {
    1405      1304188 :   basic_block bb;
    1406      1304188 :   edge_iterator *stack;
    1407      1304188 :   int sp;
    1408      1304188 :   int post_order_num = loop->num_nodes - 1;
    1409              : 
    1410              :   /* Allocate stack for back-tracking up CFG.  */
    1411      1304188 :   stack = XNEWVEC (edge_iterator, loop->num_nodes + 1);
    1412      1304188 :   sp = 0;
    1413              : 
    1414              :   /* Allocate bitmap to track nodes that have been visited.  */
    1415      1304188 :   auto_bitmap visited;
    1416              : 
    1417              :   /* Put all latches into the initial work list.  In theory we'd want
    1418              :      to start from loop exits but then we'd have the special case of
    1419              :      endless loops.  It doesn't really matter for DF iteration order and
    1420              :      handling latches last is probably even better.  */
    1421      1304188 :   stack[sp++] = ei_start (loop->header->preds);
    1422      1304188 :   bitmap_set_bit (visited, loop->header->index);
    1423              : 
    1424              :   /* The inverted traversal loop. */
    1425     20581510 :   while (sp)
    1426              :     {
    1427     17973134 :       edge_iterator ei;
    1428     17973134 :       basic_block pred;
    1429              : 
    1430              :       /* Look at the edge on the top of the stack.  */
    1431     17973134 :       ei = stack[sp - 1];
    1432     17973134 :       bb = ei_edge (ei)->dest;
    1433     17973134 :       pred = ei_edge (ei)->src;
    1434              : 
    1435              :       /* Check if the predecessor has been visited yet and mark it
    1436              :          if not so.  */
    1437     17973134 :       if (flow_bb_inside_loop_p (loop, pred)
    1438     17973134 :           && bitmap_set_bit (visited, pred->index))
    1439              :         {
    1440      6653686 :           if (EDGE_COUNT (pred->preds) > 0)
    1441              :             /* Since the predecessor node has been visited for the first
    1442              :                time, check its predecessors.  */
    1443      6653686 :             stack[sp++] = ei_start (pred->preds);
    1444              :           else
    1445            0 :             post_order[post_order_num--] = pred->index;
    1446              :         }
    1447              :       else
    1448              :         {
    1449     11319448 :           if (flow_bb_inside_loop_p (loop, bb)
    1450     11319448 :               && ei_one_before_end_p (ei))
    1451      7957874 :             post_order[post_order_num--] = bb->index;
    1452              : 
    1453     11319448 :           if (!ei_one_before_end_p (ei))
    1454      3361574 :             ei_next (&stack[sp - 1]);
    1455              :           else
    1456      7957874 :             sp--;
    1457              :         }
    1458              :     }
    1459              : 
    1460      1304188 :   free (stack);
    1461      1304188 :   return loop->num_nodes;
    1462      1304188 : }
    1463              : 
    1464              : 
    1465              : /* Analyze dataflow info for the basic blocks contained in LOOP.  */
    1466              : 
    1467              : void
    1468      1304188 : df_analyze_loop (class loop *loop)
    1469              : {
    1470      1304188 :   free (df->postorder);
    1471      1304188 :   free (df->postorder_inverted);
    1472              : 
    1473      1304188 :   df->postorder = XNEWVEC (int, loop->num_nodes);
    1474      1304188 :   df->postorder_inverted = XNEWVEC (int, loop->num_nodes);
    1475      1304188 :   df->n_blocks = loop_rev_post_order_compute (df->postorder_inverted, loop);
    1476      1304188 :   int n = loop_inverted_rev_post_order_compute (df->postorder, loop);
    1477      1304188 :   gcc_assert ((unsigned) df->n_blocks == loop->num_nodes);
    1478      1304188 :   gcc_assert ((unsigned) n == loop->num_nodes);
    1479              : 
    1480      1304188 :   bitmap blocks = BITMAP_ALLOC (&df_bitmap_obstack);
    1481      9262062 :   for (int i = 0; i < df->n_blocks; ++i)
    1482      7957874 :     bitmap_set_bit (blocks, df->postorder[i]);
    1483      1304188 :   df_set_blocks (blocks);
    1484      1304188 :   BITMAP_FREE (blocks);
    1485              : 
    1486      1304188 :   df_analyze_1 ();
    1487      1304188 : }
    1488              : 
    1489              : 
    1490              : /* Return the number of basic blocks from the last call to df_analyze.  */
    1491              : 
    1492              : int
    1493     12660989 : df_get_n_blocks (enum df_flow_dir dir)
    1494              : {
    1495     12660989 :   gcc_assert (dir != DF_NONE);
    1496              : 
    1497     12660989 :   if (dir == DF_FORWARD)
    1498              :     {
    1499       368172 :       gcc_assert (df->postorder_inverted);
    1500       368172 :       return df->n_blocks;
    1501              :     }
    1502              : 
    1503     12292817 :   gcc_assert (df->postorder);
    1504     12292817 :   return df->n_blocks;
    1505              : }
    1506              : 
    1507              : 
    1508              : /* Return a pointer to the array of basic blocks in the reverse postorder.
    1509              :    Depending on the direction of the dataflow problem,
    1510              :    it returns either the usual reverse postorder array
    1511              :    or the reverse postorder of inverted traversal. */
    1512              : int *
    1513     12660989 : df_get_postorder (enum df_flow_dir dir)
    1514              : {
    1515     12660989 :   gcc_assert (dir != DF_NONE);
    1516              : 
    1517     12660989 :   if (dir == DF_FORWARD)
    1518              :     {
    1519       368172 :       gcc_assert (df->postorder_inverted);
    1520              :       return df->postorder_inverted;
    1521              :     }
    1522     12292817 :   gcc_assert (df->postorder);
    1523              :   return df->postorder;
    1524              : }
    1525              : 
    1526              : static struct df_problem user_problem;
    1527              : static struct dataflow user_dflow;
    1528              : 
    1529              : /* Interface for calling iterative dataflow with user defined
    1530              :    confluence and transfer functions.  All that is necessary is to
    1531              :    supply DIR, a direction, CONF_FUN_0, a confluence function for
    1532              :    blocks with no logical preds (or NULL), CONF_FUN_N, the normal
    1533              :    confluence function, TRANS_FUN, the basic block transfer function,
    1534              :    and BLOCKS, the set of blocks to examine, POSTORDER the blocks in
    1535              :    postorder, and N_BLOCKS, the number of blocks in POSTORDER. */
    1536              : 
    1537              : void
    1538      2663056 : df_simple_dataflow (enum df_flow_dir dir,
    1539              :                     df_init_function init_fun,
    1540              :                     df_confluence_function_0 con_fun_0,
    1541              :                     df_confluence_function_n con_fun_n,
    1542              :                     df_transfer_function trans_fun,
    1543              :                     bitmap blocks, int * postorder, int n_blocks)
    1544              : {
    1545      2663056 :   memset (&user_problem, 0, sizeof (struct df_problem));
    1546      2663056 :   user_problem.dir = dir;
    1547      2663056 :   user_problem.init_fun = init_fun;
    1548      2663056 :   user_problem.con_fun_0 = con_fun_0;
    1549      2663056 :   user_problem.con_fun_n = con_fun_n;
    1550      2663056 :   user_problem.trans_fun = trans_fun;
    1551      2663056 :   user_dflow.problem = &user_problem;
    1552      2663056 :   df_worklist_dataflow (&user_dflow, blocks, postorder, n_blocks);
    1553      2663056 : }
    1554              : 
    1555              : 
    1556              : 
    1557              : /*----------------------------------------------------------------------------
    1558              :    Functions to support limited incremental change.
    1559              : ----------------------------------------------------------------------------*/
    1560              : 
    1561              : 
    1562              : /* Get basic block info.  */
    1563              : 
    1564              : static void *
    1565     23659618 : df_get_bb_info (struct dataflow *dflow, unsigned int index)
    1566              : {
    1567      3588119 :   if (dflow->block_info == NULL)
    1568              :     return NULL;
    1569     23659618 :   if (index >= dflow->block_info_size)
    1570              :     return NULL;
    1571     23407934 :   return (void *)((char *)dflow->block_info
    1572      3626024 :                   + index * dflow->problem->block_info_elt_size);
    1573              : }
    1574              : 
    1575              : 
    1576              : /* Set basic block info.  */
    1577              : 
    1578              : static void
    1579    618932751 : df_set_bb_info (struct dataflow *dflow, unsigned int index,
    1580              :                 void *bb_info)
    1581              : {
    1582    618932751 :   gcc_assert (dflow->block_info);
    1583    618932751 :   memcpy ((char *)dflow->block_info
    1584    618932751 :           + index * dflow->problem->block_info_elt_size,
    1585    618932751 :           bb_info, dflow->problem->block_info_elt_size);
    1586    618932751 : }
    1587              : 
    1588              : 
    1589              : /* Clear basic block info.  */
    1590              : 
    1591              : static void
    1592     23370029 : df_clear_bb_info (struct dataflow *dflow, unsigned int index)
    1593              : {
    1594     23370029 :   gcc_assert (dflow->block_info);
    1595     23370029 :   gcc_assert (dflow->block_info_size > index);
    1596     23370029 :   memset ((char *)dflow->block_info
    1597     23370029 :           + index * dflow->problem->block_info_elt_size,
    1598     23370029 :           0, dflow->problem->block_info_elt_size);
    1599     23370029 : }
    1600              : 
    1601              : 
    1602              : /* Mark the solutions as being out of date.  */
    1603              : 
    1604              : void
    1605    929143351 : df_mark_solutions_dirty (void)
    1606              : {
    1607    929143351 :   if (df)
    1608              :     {
    1609              :       int p;
    1610   1675370961 :       for (p = 1; p < df->num_problems_defined; p++)
    1611   1257365972 :         df->problems_in_order[p]->solutions_dirty = true;
    1612              :     }
    1613    929143351 : }
    1614              : 
    1615              : 
    1616              : /* Return true if BB needs it's transfer functions recomputed.  */
    1617              : 
    1618              : bool
    1619    103922048 : df_get_bb_dirty (basic_block bb)
    1620              : {
    1621    207844096 :   return bitmap_bit_p ((df_live
    1622    103922048 :                         ? df_live : df_lr)->out_of_date_transfer_functions,
    1623    103922048 :                        bb->index);
    1624              : }
    1625              : 
    1626              : 
    1627              : /* Mark BB as needing it's transfer functions as being out of
    1628              :    date.  */
    1629              : 
    1630              : void
    1631    345892733 : df_set_bb_dirty (basic_block bb)
    1632              : {
    1633    345892733 :   bb->flags |= BB_MODIFIED;
    1634    345892733 :   if (df)
    1635              :     {
    1636              :       int p;
    1637   1342124132 :       for (p = 1; p < df->num_problems_defined; p++)
    1638              :         {
    1639   1003098456 :           struct dataflow *dflow = df->problems_in_order[p];
    1640   1003098456 :           if (dflow->out_of_date_transfer_functions)
    1641    525111904 :             bitmap_set_bit (dflow->out_of_date_transfer_functions, bb->index);
    1642              :         }
    1643    339025676 :       df_mark_solutions_dirty ();
    1644              :     }
    1645    345892733 : }
    1646              : 
    1647              : 
    1648              : /* Grow the bb_info array.  */
    1649              : 
    1650              : void
    1651   1280968122 : df_grow_bb_info (struct dataflow *dflow)
    1652              : {
    1653   1280968122 :   unsigned int new_size = last_basic_block_for_fn (cfun) + 1;
    1654   1280968122 :   if (dflow->block_info_size < new_size)
    1655              :     {
    1656     14190709 :       new_size += new_size / 4;
    1657     14190709 :       dflow->block_info
    1658     14190709 :          = (void *)XRESIZEVEC (char, (char *)dflow->block_info,
    1659              :                                new_size
    1660              :                                * dflow->problem->block_info_elt_size);
    1661     14190709 :       memset ((char *)dflow->block_info
    1662              :               + dflow->block_info_size
    1663     14190709 :               * dflow->problem->block_info_elt_size,
    1664              :               0,
    1665     14190709 :               (new_size - dflow->block_info_size)
    1666     14190709 :               * dflow->problem->block_info_elt_size);
    1667     14190709 :       dflow->block_info_size = new_size;
    1668              :     }
    1669   1280968122 : }
    1670              : 
    1671              : 
    1672              : /* Clear the dirty bits.  This is called from places that delete
    1673              :    blocks.  */
    1674              : static void
    1675      6778054 : df_clear_bb_dirty (basic_block bb)
    1676              : {
    1677      6778054 :   int p;
    1678     27528818 :   for (p = 1; p < df->num_problems_defined; p++)
    1679              :     {
    1680     20750764 :       struct dataflow *dflow = df->problems_in_order[p];
    1681     20750764 :       if (dflow->out_of_date_transfer_functions)
    1682     13293435 :         bitmap_clear_bit (dflow->out_of_date_transfer_functions, bb->index);
    1683              :     }
    1684      6778054 : }
    1685              : 
    1686              : /* Called from the rtl_compact_blocks to reorganize the problems basic
    1687              :    block info.  */
    1688              : 
    1689              : void
    1690     17912457 : df_compact_blocks (void)
    1691              : {
    1692     17912457 :   int i, p;
    1693     17912457 :   basic_block bb;
    1694     17912457 :   void *problem_temps;
    1695              : 
    1696     17912457 :   auto_bitmap tmp (&df_bitmap_obstack);
    1697     88840623 :   for (p = 0; p < df->num_problems_defined; p++)
    1698              :     {
    1699     70928166 :       struct dataflow *dflow = df->problems_in_order[p];
    1700              : 
    1701              :       /* Need to reorganize the out_of_date_transfer_functions for the
    1702              :          dflow problem.  */
    1703     70928166 :       if (dflow->out_of_date_transfer_functions)
    1704              :         {
    1705     33009479 :           bitmap_copy (tmp, dflow->out_of_date_transfer_functions);
    1706     33009479 :           bitmap_clear (dflow->out_of_date_transfer_functions);
    1707     33009479 :           if (bitmap_bit_p (tmp, ENTRY_BLOCK))
    1708       920908 :             bitmap_set_bit (dflow->out_of_date_transfer_functions, ENTRY_BLOCK);
    1709     33009479 :           if (bitmap_bit_p (tmp, EXIT_BLOCK))
    1710       921128 :             bitmap_set_bit (dflow->out_of_date_transfer_functions, EXIT_BLOCK);
    1711              : 
    1712     33009479 :           i = NUM_FIXED_BLOCKS;
    1713    437258084 :           FOR_EACH_BB_FN (bb, cfun)
    1714              :             {
    1715    404248605 :               if (bitmap_bit_p (tmp, bb->index))
    1716     71302905 :                 bitmap_set_bit (dflow->out_of_date_transfer_functions, i);
    1717    404248605 :               i++;
    1718              :             }
    1719              :         }
    1720              : 
    1721              :       /* Now shuffle the block info for the problem.  */
    1722     70928166 :       if (dflow->problem->free_bb_fun)
    1723              :         {
    1724     50921936 :           int size = (last_basic_block_for_fn (cfun)
    1725     50921936 :                       * dflow->problem->block_info_elt_size);
    1726     50921936 :           problem_temps = XNEWVAR (char, size);
    1727     50921936 :           df_grow_bb_info (dflow);
    1728     50921936 :           memcpy (problem_temps, dflow->block_info, size);
    1729              : 
    1730              :           /* Copy the bb info from the problem tmps to the proper
    1731              :              place in the block_info vector.  Null out the copied
    1732              :              item.  The entry and exit blocks never move.  */
    1733     50921936 :           i = NUM_FIXED_BLOCKS;
    1734    669816782 :           FOR_EACH_BB_FN (bb, cfun)
    1735              :             {
    1736    618894846 :               df_set_bb_info (dflow, i,
    1737              :                               (char *)problem_temps
    1738    618894846 :                               + bb->index * dflow->problem->block_info_elt_size);
    1739    618894846 :               i++;
    1740              :             }
    1741     50921936 :           memset ((char *)dflow->block_info
    1742     50921936 :                   + i * dflow->problem->block_info_elt_size, 0,
    1743     50921936 :                   (last_basic_block_for_fn (cfun) - i)
    1744     50921936 :                   * dflow->problem->block_info_elt_size);
    1745     50921936 :           free (problem_temps);
    1746              :         }
    1747              :     }
    1748              : 
    1749              :   /* Shuffle the bits in the basic_block indexed arrays.  */
    1750              : 
    1751     17912457 :   if (df->blocks_to_analyze)
    1752              :     {
    1753            0 :       if (bitmap_bit_p (tmp, ENTRY_BLOCK))
    1754            0 :         bitmap_set_bit (df->blocks_to_analyze, ENTRY_BLOCK);
    1755            0 :       if (bitmap_bit_p (tmp, EXIT_BLOCK))
    1756            0 :         bitmap_set_bit (df->blocks_to_analyze, EXIT_BLOCK);
    1757            0 :       bitmap_copy (tmp, df->blocks_to_analyze);
    1758            0 :       bitmap_clear (df->blocks_to_analyze);
    1759            0 :       i = NUM_FIXED_BLOCKS;
    1760            0 :       FOR_EACH_BB_FN (bb, cfun)
    1761              :         {
    1762            0 :           if (bitmap_bit_p (tmp, bb->index))
    1763            0 :             bitmap_set_bit (df->blocks_to_analyze, i);
    1764            0 :           i++;
    1765              :         }
    1766              :     }
    1767              : 
    1768     17912457 :   i = NUM_FIXED_BLOCKS;
    1769    232558698 :   FOR_EACH_BB_FN (bb, cfun)
    1770              :     {
    1771    214646241 :       SET_BASIC_BLOCK_FOR_FN (cfun, i, bb);
    1772    214646241 :       bb->index = i;
    1773    214646241 :       i++;
    1774              :     }
    1775              : 
    1776     17912457 :   gcc_assert (i == n_basic_blocks_for_fn (cfun));
    1777              : 
    1778     24686140 :   for (; i < last_basic_block_for_fn (cfun); i++)
    1779      6773683 :     SET_BASIC_BLOCK_FOR_FN (cfun, i, NULL);
    1780              : 
    1781              : #ifdef DF_DEBUG_CFG
    1782              :   if (!df_lr->solutions_dirty)
    1783              :     df_set_clean_cfg ();
    1784              : #endif
    1785     17912457 : }
    1786              : 
    1787              : 
    1788              : /* Shove NEW_BLOCK in at OLD_INDEX.  Called from ifcvt to hack a
    1789              :    block.  There is no excuse for people to do this kind of thing.  */
    1790              : 
    1791              : void
    1792        12635 : df_bb_replace (int old_index, basic_block new_block)
    1793              : {
    1794        12635 :   int new_block_index = new_block->index;
    1795        12635 :   int p;
    1796              : 
    1797        12635 :   if (dump_file)
    1798            0 :     fprintf (dump_file, "shoving block %d into %d\n", new_block_index, old_index);
    1799              : 
    1800        12635 :   gcc_assert (df);
    1801        12635 :   gcc_assert (BASIC_BLOCK_FOR_FN (cfun, old_index) == NULL);
    1802              : 
    1803        63175 :   for (p = 0; p < df->num_problems_defined; p++)
    1804              :     {
    1805        50540 :       struct dataflow *dflow = df->problems_in_order[p];
    1806        50540 :       if (dflow->block_info)
    1807              :         {
    1808        37905 :           df_grow_bb_info (dflow);
    1809        75810 :           df_set_bb_info (dflow, old_index,
    1810              :                           df_get_bb_info (dflow, new_block_index));
    1811              :         }
    1812              :     }
    1813              : 
    1814        12635 :   df_clear_bb_dirty (new_block);
    1815        12635 :   SET_BASIC_BLOCK_FOR_FN (cfun, old_index, new_block);
    1816        12635 :   new_block->index = old_index;
    1817        12635 :   df_set_bb_dirty (BASIC_BLOCK_FOR_FN (cfun, old_index));
    1818        12635 :   SET_BASIC_BLOCK_FOR_FN (cfun, new_block_index, NULL);
    1819        12635 : }
    1820              : 
    1821              : 
    1822              : /* Free all of the per basic block dataflow from all of the problems.
    1823              :    This is typically called before a basic block is deleted and the
    1824              :    problem will be reanalyzed.  */
    1825              : 
    1826              : void
    1827     11368115 : df_bb_delete (int bb_index)
    1828              : {
    1829     11368115 :   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
    1830     11368115 :   int i;
    1831              : 
    1832     11368115 :   if (!df)
    1833              :     return;
    1834              : 
    1835     34243697 :   for (i = 0; i < df->num_problems_defined; i++)
    1836              :     {
    1837     27478278 :       struct dataflow *dflow = df->problems_in_order[i];
    1838     27478278 :       if (dflow->problem->free_bb_fun)
    1839              :         {
    1840     47511872 :           void *bb_info = df_get_bb_info (dflow, bb_index);
    1841     19781910 :           if (bb_info)
    1842              :             {
    1843     19781910 :               dflow->problem->free_bb_fun (bb, bb_info);
    1844     19781910 :               df_clear_bb_info (dflow, bb_index);
    1845              :             }
    1846              :         }
    1847              :     }
    1848      6765419 :   df_clear_bb_dirty (bb);
    1849      6765419 :   df_mark_solutions_dirty ();
    1850              : }
    1851              : 
    1852              : 
    1853              : /* Verify that there is a place for everything and everything is in
    1854              :    its place.  This is too expensive to run after every pass in the
    1855              :    mainline.  However this is an excellent debugging tool if the
    1856              :    dataflow information is not being updated properly.  You can just
    1857              :    sprinkle calls in until you find the place that is changing an
    1858              :    underlying structure without calling the proper updating
    1859              :    routine.  */
    1860              : 
    1861              : void
    1862      6379161 : df_verify (void)
    1863              : {
    1864      6379161 :   df_scan_verify ();
    1865              : #ifdef ENABLE_DF_CHECKING
    1866              :   df_lr_verify_transfer_functions ();
    1867              :   if (df_live)
    1868              :     df_live_verify_transfer_functions ();
    1869              : #endif
    1870      6379161 :   df->changeable_flags &= ~DF_VERIFY_SCHEDULED;
    1871      6379161 : }
    1872              : 
    1873              : #ifdef DF_DEBUG_CFG
    1874              : 
    1875              : /* Compute an array of ints that describes the cfg.  This can be used
    1876              :    to discover places where the cfg is modified by the appropriate
    1877              :    calls have not been made to the keep df informed.  The internals of
    1878              :    this are unexciting, the key is that two instances of this can be
    1879              :    compared to see if any changes have been made to the cfg.  */
    1880              : 
    1881              : static int *
    1882              : df_compute_cfg_image (void)
    1883              : {
    1884              :   basic_block bb;
    1885              :   int size = 2 + (2 * n_basic_blocks_for_fn (cfun));
    1886              :   int i;
    1887              :   int * map;
    1888              : 
    1889              :   FOR_ALL_BB_FN (bb, cfun)
    1890              :     {
    1891              :       size += EDGE_COUNT (bb->succs);
    1892              :     }
    1893              : 
    1894              :   map = XNEWVEC (int, size);
    1895              :   map[0] = size;
    1896              :   i = 1;
    1897              :   FOR_ALL_BB_FN (bb, cfun)
    1898              :     {
    1899              :       edge_iterator ei;
    1900              :       edge e;
    1901              : 
    1902              :       map[i++] = bb->index;
    1903              :       FOR_EACH_EDGE (e, ei, bb->succs)
    1904              :         map[i++] = e->dest->index;
    1905              :       map[i++] = -1;
    1906              :     }
    1907              :   map[i] = -1;
    1908              :   return map;
    1909              : }
    1910              : 
    1911              : static int *saved_cfg = NULL;
    1912              : 
    1913              : 
    1914              : /* This function compares the saved version of the cfg with the
    1915              :    current cfg and aborts if the two are identical.  The function
    1916              :    silently returns if the cfg has been marked as dirty or the two are
    1917              :    the same.  */
    1918              : 
    1919              : void
    1920              : df_check_cfg_clean (void)
    1921              : {
    1922              :   int *new_map;
    1923              : 
    1924              :   if (!df)
    1925              :     return;
    1926              : 
    1927              :   if (df_lr->solutions_dirty)
    1928              :     return;
    1929              : 
    1930              :   if (saved_cfg == NULL)
    1931              :     return;
    1932              : 
    1933              :   new_map = df_compute_cfg_image ();
    1934              :   gcc_assert (memcmp (saved_cfg, new_map, saved_cfg[0] * sizeof (int)) == 0);
    1935              :   free (new_map);
    1936              : }
    1937              : 
    1938              : 
    1939              : /* This function builds a cfg fingerprint and squirrels it away in
    1940              :    saved_cfg.  */
    1941              : 
    1942              : static void
    1943              : df_set_clean_cfg (void)
    1944              : {
    1945              :   free (saved_cfg);
    1946              :   saved_cfg = df_compute_cfg_image ();
    1947              : }
    1948              : 
    1949              : #endif /* DF_DEBUG_CFG  */
    1950              : /*----------------------------------------------------------------------------
    1951              :    PUBLIC INTERFACES TO QUERY INFORMATION.
    1952              : ----------------------------------------------------------------------------*/
    1953              : 
    1954              : 
    1955              : /* Return first def of REGNO within BB.  */
    1956              : 
    1957              : df_ref
    1958            0 : df_bb_regno_first_def_find (basic_block bb, unsigned int regno)
    1959              : {
    1960            0 :   rtx_insn *insn;
    1961            0 :   df_ref def;
    1962              : 
    1963            0 :   FOR_BB_INSNS (bb, insn)
    1964              :     {
    1965            0 :       if (!INSN_P (insn))
    1966            0 :         continue;
    1967              : 
    1968            0 :       FOR_EACH_INSN_DEF (def, insn)
    1969            0 :         if (DF_REF_REGNO (def) == regno)
    1970              :           return def;
    1971              :     }
    1972              :   return NULL;
    1973              : }
    1974              : 
    1975              : 
    1976              : /* Return last def of REGNO within BB.  */
    1977              : 
    1978              : df_ref
    1979            0 : df_bb_regno_last_def_find (basic_block bb, unsigned int regno)
    1980              : {
    1981            0 :   rtx_insn *insn;
    1982            0 :   df_ref def;
    1983              : 
    1984            0 :   FOR_BB_INSNS_REVERSE (bb, insn)
    1985              :     {
    1986            0 :       if (!INSN_P (insn))
    1987            0 :         continue;
    1988              : 
    1989            0 :       FOR_EACH_INSN_DEF (def, insn)
    1990            0 :         if (DF_REF_REGNO (def) == regno)
    1991              :           return def;
    1992              :     }
    1993              : 
    1994              :   return NULL;
    1995              : }
    1996              : 
    1997              : /* Return the one and only def of REGNO within BB.  If there is no def or
    1998              :    there are multiple defs, return NULL.  */
    1999              : 
    2000              : df_ref
    2001            0 : df_bb_regno_only_def_find (basic_block bb, unsigned int regno)
    2002              : {
    2003            0 :   df_ref temp = df_bb_regno_first_def_find (bb, regno);
    2004            0 :   if (!temp)
    2005              :     return NULL;
    2006            0 :   else if (temp == df_bb_regno_last_def_find (bb, regno))
    2007              :     return temp;
    2008              :   else
    2009              :     return NULL;
    2010              : }
    2011              : 
    2012              : /* Finds the reference corresponding to the definition of REG in INSN.
    2013              :    DF is the dataflow object.  */
    2014              : 
    2015              : df_ref
    2016       753127 : df_find_def (rtx_insn *insn, rtx reg)
    2017              : {
    2018       753127 :   df_ref def;
    2019              : 
    2020       753127 :   if (GET_CODE (reg) == SUBREG)
    2021            0 :     reg = SUBREG_REG (reg);
    2022       753127 :   gcc_assert (REG_P (reg));
    2023              : 
    2024      1073907 :   FOR_EACH_INSN_DEF (def, insn)
    2025      1073907 :     if (DF_REF_REGNO (def) == REGNO (reg))
    2026              :       return def;
    2027              : 
    2028              :   return NULL;
    2029              : }
    2030              : 
    2031              : 
    2032              : /* Return true if REG is defined in INSN, zero otherwise.  */
    2033              : 
    2034              : bool
    2035            0 : df_reg_defined (rtx_insn *insn, rtx reg)
    2036              : {
    2037            0 :   return df_find_def (insn, reg) != NULL;
    2038              : }
    2039              : 
    2040              : 
    2041              : /* Finds the reference corresponding to the use of REG in INSN.
    2042              :    DF is the dataflow object.  */
    2043              : 
    2044              : df_ref
    2045      4765430 : df_find_use (rtx_insn *insn, rtx reg)
    2046              : {
    2047      4765430 :   df_ref use;
    2048              : 
    2049      4765430 :   if (GET_CODE (reg) == SUBREG)
    2050            0 :     reg = SUBREG_REG (reg);
    2051      4765430 :   gcc_assert (REG_P (reg));
    2052              : 
    2053      4765430 :   df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
    2054      5662876 :   FOR_EACH_INSN_INFO_USE (use, insn_info)
    2055      5662873 :     if (DF_REF_REGNO (use) == REGNO (reg))
    2056              :       return use;
    2057            3 :   if (df->changeable_flags & DF_EQ_NOTES)
    2058            3 :     FOR_EACH_INSN_INFO_EQ_USE (use, insn_info)
    2059            3 :       if (DF_REF_REGNO (use) == REGNO (reg))
    2060              :         return use;
    2061              :   return NULL;
    2062              : }
    2063              : 
    2064              : 
    2065              : /* Return true if REG is referenced in INSN, zero otherwise.  */
    2066              : 
    2067              : bool
    2068            0 : df_reg_used (rtx_insn *insn, rtx reg)
    2069              : {
    2070            0 :   return df_find_use (insn, reg) != NULL;
    2071              : }
    2072              : 
    2073              : /* If REG has a single definition, return its known value, otherwise return
    2074              :    null.  */
    2075              : 
    2076              : rtx
    2077      8972403 : df_find_single_def_src (rtx reg)
    2078              : {
    2079      8972403 :   rtx src = NULL_RTX;
    2080              : 
    2081              :   /* Don't look through unbounded number of single definition REG copies,
    2082              :      there might be loops for sources with uninitialized variables.  */
    2083      9799252 :   for (int cnt = 0; cnt < 128; cnt++)
    2084              :     {
    2085      9799244 :       df_ref adef = DF_REG_DEF_CHAIN (REGNO (reg));
    2086      9799244 :       if (adef == NULL || DF_REF_NEXT_REG (adef) != NULL
    2087      6575051 :           || DF_REF_IS_ARTIFICIAL (adef)
    2088      6409942 :           || (DF_REF_FLAGS (adef)
    2089              :               & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
    2090              :         return NULL_RTX;
    2091              : 
    2092      6409923 :       rtx set = single_set (DF_REF_INSN (adef));
    2093      6409923 :       if (set == NULL || !rtx_equal_p (SET_DEST (set), reg))
    2094        14139 :         return NULL_RTX;
    2095              : 
    2096      6395784 :       rtx note = find_reg_equal_equiv_note (DF_REF_INSN (adef));
    2097      6395784 :       if (note && function_invariant_p (XEXP (note, 0)))
    2098       165995 :         return XEXP (note, 0);
    2099      6229789 :       src = SET_SRC (set);
    2100              : 
    2101      6229789 :       if (REG_P (src))
    2102              :         {
    2103       826849 :           reg = src;
    2104       826849 :           continue;
    2105              :         }
    2106              :       break;
    2107              :     }
    2108      5402948 :   if (!function_invariant_p (src))
    2109              :     return NULL_RTX;
    2110              : 
    2111              :   return src;
    2112              : }
    2113              : 
    2114              : 
    2115              : /*----------------------------------------------------------------------------
    2116              :    Debugging and printing functions.
    2117              : ----------------------------------------------------------------------------*/
    2118              : 
    2119              : /* Write information about registers and basic blocks into FILE.
    2120              :    This is part of making a debugging dump.  */
    2121              : 
    2122              : void
    2123          169 : dump_regset (regset r, FILE *outf)
    2124              : {
    2125          169 :   unsigned i;
    2126          169 :   reg_set_iterator rsi;
    2127              : 
    2128          169 :   if (r == NULL)
    2129              :     {
    2130            0 :       fputs (" (nil)", outf);
    2131            0 :       return;
    2132              :     }
    2133              : 
    2134         2141 :   EXECUTE_IF_SET_IN_REG_SET (r, 0, i, rsi)
    2135              :     {
    2136         1972 :       fprintf (outf, " %d", i);
    2137         1972 :       if (i < FIRST_PSEUDO_REGISTER)
    2138         1285 :         fprintf (outf, " [%s]",
    2139              :                  reg_names[i]);
    2140              :     }
    2141              : }
    2142              : 
    2143              : /* Print a human-readable representation of R on the standard error
    2144              :    stream.  This function is designed to be used from within the
    2145              :    debugger.  */
    2146              : extern void debug_regset (regset);
    2147              : DEBUG_FUNCTION void
    2148            0 : debug_regset (regset r)
    2149              : {
    2150            0 :   dump_regset (r, stderr);
    2151            0 :   putc ('\n', stderr);
    2152            0 : }
    2153              : 
    2154              : /* Write information about registers and basic blocks into FILE.
    2155              :    This is part of making a debugging dump.  */
    2156              : 
    2157              : void
    2158        63053 : df_print_regset (FILE *file, const_bitmap r)
    2159              : {
    2160        63053 :   unsigned int i;
    2161        63053 :   bitmap_iterator bi;
    2162              : 
    2163        63053 :   if (r == NULL)
    2164            0 :     fputs (" (nil)", file);
    2165              :   else
    2166              :     {
    2167       754582 :       EXECUTE_IF_SET_IN_BITMAP (r, 0, i, bi)
    2168              :         {
    2169       691529 :           fprintf (file, " %d", i);
    2170       691529 :           if (i < FIRST_PSEUDO_REGISTER)
    2171       630225 :             fprintf (file, " [%s]", reg_names[i]);
    2172              :         }
    2173              :     }
    2174        63053 :   fprintf (file, "\n");
    2175        63053 : }
    2176              : 
    2177              : 
    2178              : /* Write information about registers and basic blocks into FILE.  The
    2179              :    bitmap is in the form used by df_byte_lr.  This is part of making a
    2180              :    debugging dump.  */
    2181              : 
    2182              : void
    2183            0 : df_print_word_regset (FILE *file, const_bitmap r)
    2184              : {
    2185            0 :   unsigned int max_reg = max_reg_num ();
    2186              : 
    2187            0 :   if (r == NULL)
    2188            0 :     fputs (" (nil)", file);
    2189              :   else
    2190              :     {
    2191              :       unsigned int i;
    2192            0 :       for (i = FIRST_PSEUDO_REGISTER; i < max_reg; i++)
    2193              :         {
    2194            0 :           bool found = (bitmap_bit_p (r, 2 * i)
    2195            0 :                         || bitmap_bit_p (r, 2 * i + 1));
    2196            0 :           if (found)
    2197              :             {
    2198            0 :               int word;
    2199            0 :               const char * sep = "";
    2200            0 :               fprintf (file, " %d", i);
    2201            0 :               fprintf (file, "(");
    2202            0 :               for (word = 0; word < 2; word++)
    2203            0 :                 if (bitmap_bit_p (r, 2 * i + word))
    2204              :                   {
    2205            0 :                     fprintf (file, "%s%d", sep, word);
    2206            0 :                     sep = ", ";
    2207              :                   }
    2208            0 :               fprintf (file, ")");
    2209              :             }
    2210              :         }
    2211              :     }
    2212            0 :   fprintf (file, "\n");
    2213            0 : }
    2214              : 
    2215              : 
    2216              : /* Dump dataflow info.  */
    2217              : 
    2218              : void
    2219          426 : df_dump (FILE *file)
    2220              : {
    2221          426 :   basic_block bb;
    2222          426 :   df_dump_start (file);
    2223              : 
    2224         4596 :   FOR_ALL_BB_FN (bb, cfun)
    2225              :     {
    2226         4170 :       df_print_bb_index (bb, file);
    2227         4170 :       df_dump_top (bb, file);
    2228         4170 :       df_dump_bottom (bb, file);
    2229              :     }
    2230              : 
    2231          426 :   fprintf (file, "\n");
    2232          426 : }
    2233              : 
    2234              : 
    2235              : /* Dump dataflow info for df->blocks_to_analyze.  */
    2236              : 
    2237              : void
    2238          195 : df_dump_region (FILE *file)
    2239              : {
    2240          195 :   if (df->blocks_to_analyze)
    2241              :     {
    2242          195 :       bitmap_iterator bi;
    2243          195 :       unsigned int bb_index;
    2244              : 
    2245          195 :       fprintf (file, "\n\nstarting region dump\n");
    2246          195 :       df_dump_start (file);
    2247              : 
    2248          605 :       EXECUTE_IF_SET_IN_BITMAP (df->blocks_to_analyze, 0, bb_index, bi)
    2249              :         {
    2250          410 :           basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
    2251          410 :           dump_bb (file, bb, 0, TDF_DETAILS);
    2252              :         }
    2253          195 :       fprintf (file, "\n");
    2254              :     }
    2255              :   else
    2256            0 :     df_dump (file);
    2257          195 : }
    2258              : 
    2259              : 
    2260              : /* Dump the introductory information for each problem defined.  */
    2261              : 
    2262              : void
    2263         3940 : df_dump_start (FILE *file)
    2264              : {
    2265         3940 :   int i;
    2266              : 
    2267         3940 :   if (!df || !file)
    2268              :     return;
    2269              : 
    2270         3940 :   fprintf (file, "\n\n%s\n", current_function_name ());
    2271         3940 :   fprintf (file, "\nDataflow summary:\n");
    2272         3940 :   if (df->blocks_to_analyze)
    2273          485 :     fprintf (file, "def_info->table_size = %d, use_info->table_size = %d\n",
    2274              :              DF_DEFS_TABLE_SIZE (), DF_USES_TABLE_SIZE ());
    2275              : 
    2276        18867 :   for (i = 0; i < df->num_problems_defined; i++)
    2277              :     {
    2278        14927 :       struct dataflow *dflow = df->problems_in_order[i];
    2279        14927 :       if (dflow->computed)
    2280              :         {
    2281        14260 :           df_dump_problem_function fun = dflow->problem->dump_start_fun;
    2282        14260 :           if (fun)
    2283         4157 :             fun (file);
    2284              :         }
    2285              :     }
    2286              : }
    2287              : 
    2288              : 
    2289              : /* Dump the top or bottom of the block information for BB.  */
    2290              : static void
    2291        10960 : df_dump_bb_problem_data (basic_block bb, FILE *file, bool top)
    2292              : {
    2293        10960 :   int i;
    2294              : 
    2295        10960 :   if (!df || !file)
    2296              :     return;
    2297              : 
    2298        58832 :   for (i = 0; i < df->num_problems_defined; i++)
    2299              :     {
    2300        47872 :       struct dataflow *dflow = df->problems_in_order[i];
    2301        47872 :       if (dflow->computed)
    2302              :         {
    2303        43336 :           df_dump_bb_problem_function bbfun;
    2304              : 
    2305        43336 :           if (top)
    2306        21668 :             bbfun = dflow->problem->dump_top_fun;
    2307              :           else
    2308        21668 :             bbfun = dflow->problem->dump_bottom_fun;
    2309              : 
    2310        43336 :           if (bbfun)
    2311        26828 :             bbfun (bb, file);
    2312              :         }
    2313              :     }
    2314              : }
    2315              : 
    2316              : /* Dump the top of the block information for BB.  */
    2317              : 
    2318              : void
    2319         5480 : df_dump_top (basic_block bb, FILE *file)
    2320              : {
    2321         5480 :   df_dump_bb_problem_data (bb, file, /*top=*/true);
    2322         5480 : }
    2323              : 
    2324              : /* Dump the bottom of the block information for BB.  */
    2325              : 
    2326              : void
    2327         5480 : df_dump_bottom (basic_block bb, FILE *file)
    2328              : {
    2329         5480 :   df_dump_bb_problem_data (bb, file, /*top=*/false);
    2330         5480 : }
    2331              : 
    2332              : 
    2333              : /* Dump information about INSN just before or after dumping INSN itself.  */
    2334              : static void
    2335        43658 : df_dump_insn_problem_data (const rtx_insn *insn, FILE *file, bool top)
    2336              : {
    2337        43658 :   int i;
    2338              : 
    2339        43658 :   if (!df || !file)
    2340              :     return;
    2341              : 
    2342       161466 :   for (i = 0; i < df->num_problems_defined; i++)
    2343              :     {
    2344       127284 :       struct dataflow *dflow = df->problems_in_order[i];
    2345       127284 :       if (dflow->computed)
    2346              :         {
    2347       124572 :           df_dump_insn_problem_function insnfun;
    2348              : 
    2349       124572 :           if (top)
    2350        62286 :             insnfun = dflow->problem->dump_insn_top_fun;
    2351              :           else
    2352        62286 :             insnfun = dflow->problem->dump_insn_bottom_fun;
    2353              : 
    2354       124572 :           if (insnfun)
    2355         4314 :             insnfun (insn, file);
    2356              :         }
    2357              :     }
    2358              : }
    2359              : 
    2360              : /* Dump information about INSN before dumping INSN itself.  */
    2361              : 
    2362              : void
    2363        21829 : df_dump_insn_top (const rtx_insn *insn, FILE *file)
    2364              : {
    2365        21829 :   df_dump_insn_problem_data (insn,  file, /*top=*/true);
    2366        21829 : }
    2367              : 
    2368              : /* Dump information about INSN after dumping INSN itself.  */
    2369              : 
    2370              : void
    2371        21829 : df_dump_insn_bottom (const rtx_insn *insn, FILE *file)
    2372              : {
    2373        21829 :   df_dump_insn_problem_data (insn,  file, /*top=*/false);
    2374        21829 : }
    2375              : 
    2376              : 
    2377              : static void
    2378        23698 : df_ref_dump (df_ref ref, FILE *file)
    2379              : {
    2380        23698 :   fprintf (file, "%c%d(%d)",
    2381        23698 :            DF_REF_REG_DEF_P (ref)
    2382        15339 :            ? 'd'
    2383        15339 :            : (DF_REF_FLAGS (ref) & DF_REF_IN_NOTE) ? 'e' : 'u',
    2384              :            DF_REF_ID (ref),
    2385              :            DF_REF_REGNO (ref));
    2386        23698 : }
    2387              : 
    2388              : void
    2389        10960 : df_refs_chain_dump (df_ref ref, bool follow_chain, FILE *file)
    2390              : {
    2391        10960 :   fprintf (file, "{ ");
    2392        45618 :   for (; ref; ref = DF_REF_NEXT_LOC (ref))
    2393              :     {
    2394        23698 :       df_ref_dump (ref, file);
    2395        23698 :       if (follow_chain)
    2396        23698 :         df_chain_dump (DF_REF_CHAIN (ref), file);
    2397              :     }
    2398        10960 :   fprintf (file, "}");
    2399        10960 : }
    2400              : 
    2401              : 
    2402              : /* Dump either a ref-def or reg-use chain.  */
    2403              : 
    2404              : void
    2405            0 : df_regs_chain_dump (df_ref ref,  FILE *file)
    2406              : {
    2407            0 :   fprintf (file, "{ ");
    2408            0 :   while (ref)
    2409              :     {
    2410            0 :       df_ref_dump (ref, file);
    2411            0 :       ref = DF_REF_NEXT_REG (ref);
    2412              :     }
    2413            0 :   fprintf (file, "}");
    2414            0 : }
    2415              : 
    2416              : 
    2417              : static void
    2418            0 : df_mws_dump (struct df_mw_hardreg *mws, FILE *file)
    2419              : {
    2420            0 :   for (; mws; mws = DF_MWS_NEXT (mws))
    2421            0 :     fprintf (file, "mw %c r[%d..%d]\n",
    2422            0 :              DF_MWS_REG_DEF_P (mws) ? 'd' : 'u',
    2423              :              mws->start_regno, mws->end_regno);
    2424            0 : }
    2425              : 
    2426              : 
    2427              : static void
    2428            0 : df_insn_uid_debug (unsigned int uid,
    2429              :                    bool follow_chain, FILE *file)
    2430              : {
    2431            0 :   fprintf (file, "insn %d luid %d",
    2432            0 :            uid, DF_INSN_UID_LUID (uid));
    2433              : 
    2434            0 :   if (DF_INSN_UID_DEFS (uid))
    2435              :     {
    2436            0 :       fprintf (file, " defs ");
    2437            0 :       df_refs_chain_dump (DF_INSN_UID_DEFS (uid), follow_chain, file);
    2438              :     }
    2439              : 
    2440            0 :   if (DF_INSN_UID_USES (uid))
    2441              :     {
    2442            0 :       fprintf (file, " uses ");
    2443            0 :       df_refs_chain_dump (DF_INSN_UID_USES (uid), follow_chain, file);
    2444              :     }
    2445              : 
    2446            0 :   if (DF_INSN_UID_EQ_USES (uid))
    2447              :     {
    2448            0 :       fprintf (file, " eq uses ");
    2449            0 :       df_refs_chain_dump (DF_INSN_UID_EQ_USES (uid), follow_chain, file);
    2450              :     }
    2451              : 
    2452            0 :   if (DF_INSN_UID_MWS (uid))
    2453              :     {
    2454            0 :       fprintf (file, " mws ");
    2455            0 :       df_mws_dump (DF_INSN_UID_MWS (uid), file);
    2456              :     }
    2457            0 :   fprintf (file, "\n");
    2458            0 : }
    2459              : 
    2460              : 
    2461              : DEBUG_FUNCTION void
    2462            0 : df_insn_debug (rtx_insn *insn, bool follow_chain, FILE *file)
    2463              : {
    2464            0 :   df_insn_uid_debug (INSN_UID (insn), follow_chain, file);
    2465            0 : }
    2466              : 
    2467              : DEBUG_FUNCTION void
    2468            0 : df_insn_debug_regno (rtx_insn *insn, FILE *file)
    2469              : {
    2470            0 :   struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
    2471              : 
    2472            0 :   fprintf (file, "insn %d bb %d luid %d defs ",
    2473            0 :            INSN_UID (insn), BLOCK_FOR_INSN (insn)->index,
    2474              :            DF_INSN_INFO_LUID (insn_info));
    2475            0 :   df_refs_chain_dump (DF_INSN_INFO_DEFS (insn_info), false, file);
    2476              : 
    2477            0 :   fprintf (file, " uses ");
    2478            0 :   df_refs_chain_dump (DF_INSN_INFO_USES (insn_info), false, file);
    2479              : 
    2480            0 :   fprintf (file, " eq_uses ");
    2481            0 :   df_refs_chain_dump (DF_INSN_INFO_EQ_USES (insn_info), false, file);
    2482            0 :   fprintf (file, "\n");
    2483            0 : }
    2484              : 
    2485              : DEBUG_FUNCTION void
    2486            0 : df_regno_debug (unsigned int regno, FILE *file)
    2487              : {
    2488            0 :   fprintf (file, "reg %d defs ", regno);
    2489            0 :   df_regs_chain_dump (DF_REG_DEF_CHAIN (regno), file);
    2490            0 :   fprintf (file, " uses ");
    2491            0 :   df_regs_chain_dump (DF_REG_USE_CHAIN (regno), file);
    2492            0 :   fprintf (file, " eq_uses ");
    2493            0 :   df_regs_chain_dump (DF_REG_EQ_USE_CHAIN (regno), file);
    2494            0 :   fprintf (file, "\n");
    2495            0 : }
    2496              : 
    2497              : 
    2498              : DEBUG_FUNCTION void
    2499            0 : df_ref_debug (df_ref ref, FILE *file)
    2500              : {
    2501            0 :   fprintf (file, "%c%d ",
    2502            0 :            DF_REF_REG_DEF_P (ref) ? 'd' : 'u',
    2503              :            DF_REF_ID (ref));
    2504            0 :   fprintf (file, "reg %d bb %d insn %d flag %#x type %#x ",
    2505              :            DF_REF_REGNO (ref),
    2506            0 :            DF_REF_BBNO (ref),
    2507            0 :            DF_REF_IS_ARTIFICIAL (ref) ? -1 : DF_REF_INSN_UID (ref),
    2508            0 :            DF_REF_FLAGS (ref),
    2509            0 :            DF_REF_TYPE (ref));
    2510            0 :   if (DF_REF_LOC (ref))
    2511              :     {
    2512            0 :       if (flag_dump_noaddr)
    2513            0 :         fprintf (file, "loc #(#) chain ");
    2514              :       else
    2515            0 :         fprintf (file, "loc %p(%p) chain ", (void *)DF_REF_LOC (ref),
    2516              :                  (void *)*DF_REF_LOC (ref));
    2517              :     }
    2518              :   else
    2519            0 :     fprintf (file, "chain ");
    2520            0 :   df_chain_dump (DF_REF_CHAIN (ref), file);
    2521            0 :   fprintf (file, "\n");
    2522            0 : }
    2523              : 
    2524              : /* Functions for debugging from GDB.  */
    2525              : 
    2526              : DEBUG_FUNCTION void
    2527            0 : debug_df_insn (rtx_insn *insn)
    2528              : {
    2529            0 :   df_insn_debug (insn, true, stderr);
    2530            0 :   debug_rtx (insn);
    2531            0 : }
    2532              : 
    2533              : 
    2534              : DEBUG_FUNCTION void
    2535            0 : debug_df_reg (rtx reg)
    2536              : {
    2537            0 :   df_regno_debug (REGNO (reg), stderr);
    2538            0 : }
    2539              : 
    2540              : 
    2541              : DEBUG_FUNCTION void
    2542            0 : debug_df_regno (unsigned int regno)
    2543              : {
    2544            0 :   df_regno_debug (regno, stderr);
    2545            0 : }
    2546              : 
    2547              : 
    2548              : DEBUG_FUNCTION void
    2549            0 : debug_df_ref (df_ref ref)
    2550              : {
    2551            0 :   df_ref_debug (ref, stderr);
    2552            0 : }
    2553              : 
    2554              : 
    2555              : DEBUG_FUNCTION void
    2556            0 : debug_df_defno (unsigned int defno)
    2557              : {
    2558            0 :   df_ref_debug (DF_DEFS_GET (defno), stderr);
    2559            0 : }
    2560              : 
    2561              : 
    2562              : DEBUG_FUNCTION void
    2563            0 : debug_df_useno (unsigned int defno)
    2564              : {
    2565            0 :   df_ref_debug (DF_USES_GET (defno), stderr);
    2566            0 : }
    2567              : 
    2568              : 
    2569              : DEBUG_FUNCTION void
    2570            0 : debug_df_chain (struct df_link *link)
    2571              : {
    2572            0 :   df_chain_dump (link, stderr);
    2573            0 :   fputc ('\n', stderr);
    2574            0 : }
        

Generated by: LCOV version 2.4-beta

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