110d565efSmrg /* Standard problems for dataflow support routines.
2*ec02198aSmrg    Copyright (C) 1999-2020 Free Software Foundation, Inc.
310d565efSmrg    Originally contributed by Michael P. Hayes
410d565efSmrg              (m.hayes@elec.canterbury.ac.nz, mhayes@redhat.com)
510d565efSmrg    Major rewrite contributed by Danny Berlin (dberlin@dberlin.org)
610d565efSmrg              and Kenneth Zadeck (zadeck@naturalbridge.com).
710d565efSmrg 
810d565efSmrg This file is part of GCC.
910d565efSmrg 
1010d565efSmrg GCC is free software; you can redistribute it and/or modify it under
1110d565efSmrg the terms of the GNU General Public License as published by the Free
1210d565efSmrg Software Foundation; either version 3, or (at your option) any later
1310d565efSmrg version.
1410d565efSmrg 
1510d565efSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1610d565efSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
1710d565efSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1810d565efSmrg for more details.
1910d565efSmrg 
2010d565efSmrg You should have received a copy of the GNU General Public License
2110d565efSmrg along with GCC; see the file COPYING3.  If not see
2210d565efSmrg <http://www.gnu.org/licenses/>.  */
2310d565efSmrg 
2410d565efSmrg #include "config.h"
2510d565efSmrg #include "system.h"
2610d565efSmrg #include "coretypes.h"
2710d565efSmrg #include "backend.h"
2810d565efSmrg #include "target.h"
2910d565efSmrg #include "rtl.h"
3010d565efSmrg #include "df.h"
3110d565efSmrg #include "memmodel.h"
3210d565efSmrg #include "tm_p.h"
3310d565efSmrg #include "insn-config.h"
3410d565efSmrg #include "cfganal.h"
3510d565efSmrg #include "dce.h"
3610d565efSmrg #include "valtrack.h"
3710d565efSmrg #include "dumpfile.h"
3810d565efSmrg #include "rtl-iter.h"
39*ec02198aSmrg #include "regs.h"
40*ec02198aSmrg #include "function-abi.h"
4110d565efSmrg 
4210d565efSmrg /* Note that turning REG_DEAD_DEBUGGING on will cause
4310d565efSmrg    gcc.c-torture/unsorted/dump-noaddr.c to fail because it prints
4410d565efSmrg    addresses in the dumps.  */
4510d565efSmrg #define REG_DEAD_DEBUGGING 0
4610d565efSmrg 
4710d565efSmrg #define DF_SPARSE_THRESHOLD 32
4810d565efSmrg 
4910d565efSmrg static bitmap_head seen_in_block;
5010d565efSmrg static bitmap_head seen_in_insn;
5110d565efSmrg 
5210d565efSmrg /*----------------------------------------------------------------------------
5310d565efSmrg    Utility functions.
5410d565efSmrg ----------------------------------------------------------------------------*/
5510d565efSmrg 
5610d565efSmrg /* Generic versions to get the void* version of the block info.  Only
5710d565efSmrg    used inside the problem instance vectors.  */
5810d565efSmrg 
5910d565efSmrg /* Dump a def-use or use-def chain for REF to FILE.  */
6010d565efSmrg 
6110d565efSmrg void
df_chain_dump(struct df_link * link,FILE * file)6210d565efSmrg df_chain_dump (struct df_link *link, FILE *file)
6310d565efSmrg {
6410d565efSmrg   fprintf (file, "{ ");
6510d565efSmrg   for (; link; link = link->next)
6610d565efSmrg     {
6710d565efSmrg       fprintf (file, "%c%d(bb %d insn %d) ",
6810d565efSmrg 	       DF_REF_REG_DEF_P (link->ref)
6910d565efSmrg 	       ? 'd'
7010d565efSmrg 	       : (DF_REF_FLAGS (link->ref) & DF_REF_IN_NOTE) ? 'e' : 'u',
7110d565efSmrg 	       DF_REF_ID (link->ref),
7210d565efSmrg 	       DF_REF_BBNO (link->ref),
7310d565efSmrg 	       DF_REF_IS_ARTIFICIAL (link->ref)
7410d565efSmrg 	       ? -1 : DF_REF_INSN_UID (link->ref));
7510d565efSmrg     }
7610d565efSmrg   fprintf (file, "}");
7710d565efSmrg }
7810d565efSmrg 
7910d565efSmrg 
8010d565efSmrg /* Print some basic block info as part of df_dump.  */
8110d565efSmrg 
8210d565efSmrg void
df_print_bb_index(basic_block bb,FILE * file)8310d565efSmrg df_print_bb_index (basic_block bb, FILE *file)
8410d565efSmrg {
8510d565efSmrg   edge e;
8610d565efSmrg   edge_iterator ei;
8710d565efSmrg 
8810d565efSmrg   fprintf (file, "\n( ");
8910d565efSmrg     FOR_EACH_EDGE (e, ei, bb->preds)
9010d565efSmrg     {
9110d565efSmrg       basic_block pred = e->src;
9210d565efSmrg       fprintf (file, "%d%s ", pred->index, e->flags & EDGE_EH ? "(EH)" : "");
9310d565efSmrg     }
9410d565efSmrg   fprintf (file, ")->[%d]->( ", bb->index);
9510d565efSmrg   FOR_EACH_EDGE (e, ei, bb->succs)
9610d565efSmrg     {
9710d565efSmrg       basic_block succ = e->dest;
9810d565efSmrg       fprintf (file, "%d%s ", succ->index, e->flags & EDGE_EH ? "(EH)" : "");
9910d565efSmrg     }
10010d565efSmrg   fprintf (file, ")\n");
10110d565efSmrg }
10210d565efSmrg 
10310d565efSmrg 
10410d565efSmrg /*----------------------------------------------------------------------------
10510d565efSmrg    REACHING DEFINITIONS
10610d565efSmrg 
10710d565efSmrg    Find the locations in the function where each definition site for a
10810d565efSmrg    pseudo reaches.  In and out bitvectors are built for each basic
10910d565efSmrg    block.  The id field in the ref is used to index into these sets.
11010d565efSmrg    See df.h for details.
11110d565efSmrg 
11210d565efSmrg    If the DF_RD_PRUNE_DEAD_DEFS changeable flag is set, only DEFs reaching
11310d565efSmrg    existing uses are included in the global reaching DEFs set, or in other
11410d565efSmrg    words only DEFs that are still live.  This is a kind of pruned version
11510d565efSmrg    of the traditional reaching definitions problem that is much less
11610d565efSmrg    complex to compute and produces enough information to compute UD-chains.
11710d565efSmrg    In this context, live must be interpreted in the DF_LR sense: Uses that
11810d565efSmrg    are upward exposed but maybe not initialized on all paths through the
11910d565efSmrg    CFG.  For a USE that is not reached by a DEF on all paths, we still want
12010d565efSmrg    to make those DEFs that do reach the USE visible, and pruning based on
12110d565efSmrg    DF_LIVE would make that impossible.
12210d565efSmrg    ----------------------------------------------------------------------------*/
12310d565efSmrg 
12410d565efSmrg /* This problem plays a large number of games for the sake of
12510d565efSmrg    efficiency.
12610d565efSmrg 
12710d565efSmrg    1) The order of the bits in the bitvectors.  After the scanning
12810d565efSmrg    phase, all of the defs are sorted.  All of the defs for the reg 0
12910d565efSmrg    are first, followed by all defs for reg 1 and so on.
13010d565efSmrg 
13110d565efSmrg    2) There are two kill sets, one if the number of defs is less or
13210d565efSmrg    equal to DF_SPARSE_THRESHOLD and another if the number of defs is
13310d565efSmrg    greater.
13410d565efSmrg 
13510d565efSmrg    <= : Data is built directly in the kill set.
13610d565efSmrg 
13710d565efSmrg    > : One level of indirection is used to keep from generating long
13810d565efSmrg    strings of 1 bits in the kill sets.  Bitvectors that are indexed
13910d565efSmrg    by the regnum are used to represent that there is a killing def
14010d565efSmrg    for the register.  The confluence and transfer functions use
14110d565efSmrg    these along with the bitmap_clear_range call to remove ranges of
14210d565efSmrg    bits without actually generating a knockout vector.
14310d565efSmrg 
144*ec02198aSmrg    The kill and sparse_kill and the dense_invalidated_by_eh and
145*ec02198aSmrg    sparse_invalidated_by_eh both play this game.  */
14610d565efSmrg 
14710d565efSmrg /* Private data used to compute the solution for this problem.  These
14810d565efSmrg    data structures are not accessible outside of this module.  */
149*ec02198aSmrg class df_rd_problem_data
15010d565efSmrg {
151*ec02198aSmrg public:
152*ec02198aSmrg   /* The set of defs to regs invalidated by EH edges.  */
153*ec02198aSmrg   bitmap_head sparse_invalidated_by_eh;
154*ec02198aSmrg   bitmap_head dense_invalidated_by_eh;
15510d565efSmrg   /* An obstack for the bitmaps we need for this problem.  */
15610d565efSmrg   bitmap_obstack rd_bitmaps;
15710d565efSmrg };
15810d565efSmrg 
15910d565efSmrg 
16010d565efSmrg /* Free basic block info.  */
16110d565efSmrg 
16210d565efSmrg static void
df_rd_free_bb_info(basic_block bb ATTRIBUTE_UNUSED,void * vbb_info)16310d565efSmrg df_rd_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
16410d565efSmrg 		    void *vbb_info)
16510d565efSmrg {
166*ec02198aSmrg   class df_rd_bb_info *bb_info = (class df_rd_bb_info *) vbb_info;
16710d565efSmrg   if (bb_info)
16810d565efSmrg     {
16910d565efSmrg       bitmap_clear (&bb_info->kill);
17010d565efSmrg       bitmap_clear (&bb_info->sparse_kill);
17110d565efSmrg       bitmap_clear (&bb_info->gen);
17210d565efSmrg       bitmap_clear (&bb_info->in);
17310d565efSmrg       bitmap_clear (&bb_info->out);
17410d565efSmrg     }
17510d565efSmrg }
17610d565efSmrg 
17710d565efSmrg 
17810d565efSmrg /* Allocate or reset bitmaps for DF_RD blocks. The solution bits are
17910d565efSmrg    not touched unless the block is new.  */
18010d565efSmrg 
18110d565efSmrg static void
df_rd_alloc(bitmap all_blocks)18210d565efSmrg df_rd_alloc (bitmap all_blocks)
18310d565efSmrg {
18410d565efSmrg   unsigned int bb_index;
18510d565efSmrg   bitmap_iterator bi;
186*ec02198aSmrg   class df_rd_problem_data *problem_data;
18710d565efSmrg 
18810d565efSmrg   if (df_rd->problem_data)
18910d565efSmrg     {
190*ec02198aSmrg       problem_data = (class df_rd_problem_data *) df_rd->problem_data;
191*ec02198aSmrg       bitmap_clear (&problem_data->sparse_invalidated_by_eh);
192*ec02198aSmrg       bitmap_clear (&problem_data->dense_invalidated_by_eh);
19310d565efSmrg     }
19410d565efSmrg   else
19510d565efSmrg     {
196*ec02198aSmrg       problem_data = XNEW (class df_rd_problem_data);
19710d565efSmrg       df_rd->problem_data = problem_data;
19810d565efSmrg 
19910d565efSmrg       bitmap_obstack_initialize (&problem_data->rd_bitmaps);
200*ec02198aSmrg       bitmap_initialize (&problem_data->sparse_invalidated_by_eh,
20110d565efSmrg 			 &problem_data->rd_bitmaps);
202*ec02198aSmrg       bitmap_initialize (&problem_data->dense_invalidated_by_eh,
20310d565efSmrg 			 &problem_data->rd_bitmaps);
20410d565efSmrg     }
20510d565efSmrg 
20610d565efSmrg   df_grow_bb_info (df_rd);
20710d565efSmrg 
20810d565efSmrg   /* Because of the clustering of all use sites for the same pseudo,
20910d565efSmrg      we have to process all of the blocks before doing the analysis.  */
21010d565efSmrg 
21110d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
21210d565efSmrg     {
213*ec02198aSmrg       class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
21410d565efSmrg 
21510d565efSmrg       /* When bitmaps are already initialized, just clear them.  */
21610d565efSmrg       if (bb_info->kill.obstack)
21710d565efSmrg 	{
21810d565efSmrg 	  bitmap_clear (&bb_info->kill);
21910d565efSmrg 	  bitmap_clear (&bb_info->sparse_kill);
22010d565efSmrg 	  bitmap_clear (&bb_info->gen);
22110d565efSmrg 	}
22210d565efSmrg       else
22310d565efSmrg 	{
22410d565efSmrg 	  bitmap_initialize (&bb_info->kill, &problem_data->rd_bitmaps);
22510d565efSmrg 	  bitmap_initialize (&bb_info->sparse_kill, &problem_data->rd_bitmaps);
22610d565efSmrg 	  bitmap_initialize (&bb_info->gen, &problem_data->rd_bitmaps);
22710d565efSmrg 	  bitmap_initialize (&bb_info->in, &problem_data->rd_bitmaps);
22810d565efSmrg 	  bitmap_initialize (&bb_info->out, &problem_data->rd_bitmaps);
22910d565efSmrg 	}
23010d565efSmrg     }
23110d565efSmrg   df_rd->optional_p = true;
23210d565efSmrg }
23310d565efSmrg 
23410d565efSmrg 
23510d565efSmrg /* Add the effect of the top artificial defs of BB to the reaching definitions
23610d565efSmrg    bitmap LOCAL_RD.  */
23710d565efSmrg 
23810d565efSmrg void
df_rd_simulate_artificial_defs_at_top(basic_block bb,bitmap local_rd)23910d565efSmrg df_rd_simulate_artificial_defs_at_top (basic_block bb, bitmap local_rd)
24010d565efSmrg {
24110d565efSmrg   int bb_index = bb->index;
24210d565efSmrg   df_ref def;
24310d565efSmrg   FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
24410d565efSmrg     if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
24510d565efSmrg       {
24610d565efSmrg 	unsigned int dregno = DF_REF_REGNO (def);
24710d565efSmrg 	if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
24810d565efSmrg 	  bitmap_clear_range (local_rd,
24910d565efSmrg 			      DF_DEFS_BEGIN (dregno),
25010d565efSmrg 			      DF_DEFS_COUNT (dregno));
25110d565efSmrg 	bitmap_set_bit (local_rd, DF_REF_ID (def));
25210d565efSmrg       }
25310d565efSmrg }
25410d565efSmrg 
25510d565efSmrg /* Add the effect of the defs of INSN to the reaching definitions bitmap
25610d565efSmrg    LOCAL_RD.  */
25710d565efSmrg 
25810d565efSmrg void
df_rd_simulate_one_insn(basic_block bb ATTRIBUTE_UNUSED,rtx_insn * insn,bitmap local_rd)25910d565efSmrg df_rd_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx_insn *insn,
26010d565efSmrg 			 bitmap local_rd)
26110d565efSmrg {
26210d565efSmrg   df_ref def;
26310d565efSmrg 
26410d565efSmrg   FOR_EACH_INSN_DEF (def, insn)
26510d565efSmrg     {
26610d565efSmrg       unsigned int dregno = DF_REF_REGNO (def);
26710d565efSmrg       if ((!(df->changeable_flags & DF_NO_HARD_REGS))
26810d565efSmrg           || (dregno >= FIRST_PSEUDO_REGISTER))
26910d565efSmrg         {
27010d565efSmrg           if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
27110d565efSmrg 	    bitmap_clear_range (local_rd,
27210d565efSmrg 				DF_DEFS_BEGIN (dregno),
27310d565efSmrg 				DF_DEFS_COUNT (dregno));
27410d565efSmrg 	  if (!(DF_REF_FLAGS (def)
27510d565efSmrg 		& (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
27610d565efSmrg 	    bitmap_set_bit (local_rd, DF_REF_ID (def));
27710d565efSmrg 	}
27810d565efSmrg     }
27910d565efSmrg }
28010d565efSmrg 
28110d565efSmrg /* Process a list of DEFs for df_rd_bb_local_compute.  This is a bit
28210d565efSmrg    more complicated than just simulating, because we must produce the
28310d565efSmrg    gen and kill sets and hence deal with the two possible representations
28410d565efSmrg    of kill sets.   */
28510d565efSmrg 
28610d565efSmrg static void
df_rd_bb_local_compute_process_def(class df_rd_bb_info * bb_info,df_ref def,int top_flag)287*ec02198aSmrg df_rd_bb_local_compute_process_def (class df_rd_bb_info *bb_info,
28810d565efSmrg 				    df_ref def,
28910d565efSmrg 				    int top_flag)
29010d565efSmrg {
29110d565efSmrg   for (; def; def = DF_REF_NEXT_LOC (def))
29210d565efSmrg     {
29310d565efSmrg       if (top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
29410d565efSmrg 	{
29510d565efSmrg 	  unsigned int regno = DF_REF_REGNO (def);
29610d565efSmrg 	  unsigned int begin = DF_DEFS_BEGIN (regno);
29710d565efSmrg 	  unsigned int n_defs = DF_DEFS_COUNT (regno);
29810d565efSmrg 
29910d565efSmrg 	  if ((!(df->changeable_flags & DF_NO_HARD_REGS))
30010d565efSmrg 	      || (regno >= FIRST_PSEUDO_REGISTER))
30110d565efSmrg 	    {
30210d565efSmrg 	      /* Only the last def(s) for a regno in the block has any
30310d565efSmrg 		 effect.  */
30410d565efSmrg 	      if (!bitmap_bit_p (&seen_in_block, regno))
30510d565efSmrg 		{
30610d565efSmrg 		  /* The first def for regno in insn gets to knock out the
30710d565efSmrg 		     defs from other instructions.  */
30810d565efSmrg 		  if ((!bitmap_bit_p (&seen_in_insn, regno))
30910d565efSmrg 		      /* If the def is to only part of the reg, it does
31010d565efSmrg 			 not kill the other defs that reach here.  */
31110d565efSmrg 		      && (!(DF_REF_FLAGS (def) &
31210d565efSmrg 			    (DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER))))
31310d565efSmrg 		    {
31410d565efSmrg 		      if (n_defs > DF_SPARSE_THRESHOLD)
31510d565efSmrg 			{
31610d565efSmrg 			  bitmap_set_bit (&bb_info->sparse_kill, regno);
31710d565efSmrg 			  bitmap_clear_range (&bb_info->gen, begin, n_defs);
31810d565efSmrg 			}
31910d565efSmrg 		      else
32010d565efSmrg 			{
32110d565efSmrg 			  bitmap_set_range (&bb_info->kill, begin, n_defs);
32210d565efSmrg 			  bitmap_clear_range (&bb_info->gen, begin, n_defs);
32310d565efSmrg 			}
32410d565efSmrg 		    }
32510d565efSmrg 
32610d565efSmrg 		  bitmap_set_bit (&seen_in_insn, regno);
32710d565efSmrg 		  /* All defs for regno in the instruction may be put into
32810d565efSmrg 		     the gen set.  */
32910d565efSmrg 		  if (!(DF_REF_FLAGS (def)
33010d565efSmrg 			& (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
33110d565efSmrg 		    bitmap_set_bit (&bb_info->gen, DF_REF_ID (def));
33210d565efSmrg 		}
33310d565efSmrg 	    }
33410d565efSmrg 	}
33510d565efSmrg     }
33610d565efSmrg }
33710d565efSmrg 
33810d565efSmrg /* Compute local reaching def info for basic block BB.  */
33910d565efSmrg 
34010d565efSmrg static void
df_rd_bb_local_compute(unsigned int bb_index)34110d565efSmrg df_rd_bb_local_compute (unsigned int bb_index)
34210d565efSmrg {
34310d565efSmrg   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
344*ec02198aSmrg   class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
34510d565efSmrg   rtx_insn *insn;
34610d565efSmrg 
34710d565efSmrg   bitmap_clear (&seen_in_block);
34810d565efSmrg   bitmap_clear (&seen_in_insn);
34910d565efSmrg 
35010d565efSmrg   /* Artificials are only hard regs.  */
35110d565efSmrg   if (!(df->changeable_flags & DF_NO_HARD_REGS))
35210d565efSmrg     df_rd_bb_local_compute_process_def (bb_info,
35310d565efSmrg 					df_get_artificial_defs (bb_index),
35410d565efSmrg 					0);
35510d565efSmrg 
35610d565efSmrg   FOR_BB_INSNS_REVERSE (bb, insn)
35710d565efSmrg     {
35810d565efSmrg       unsigned int uid = INSN_UID (insn);
35910d565efSmrg 
36010d565efSmrg       if (!INSN_P (insn))
36110d565efSmrg 	continue;
36210d565efSmrg 
36310d565efSmrg       df_rd_bb_local_compute_process_def (bb_info,
36410d565efSmrg 					  DF_INSN_UID_DEFS (uid), 0);
36510d565efSmrg 
36610d565efSmrg       /* This complex dance with the two bitmaps is required because
36710d565efSmrg 	 instructions can assign twice to the same pseudo.  This
36810d565efSmrg 	 generally happens with calls that will have one def for the
36910d565efSmrg 	 result and another def for the clobber.  If only one vector
37010d565efSmrg 	 is used and the clobber goes first, the result will be
37110d565efSmrg 	 lost.  */
37210d565efSmrg       bitmap_ior_into (&seen_in_block, &seen_in_insn);
37310d565efSmrg       bitmap_clear (&seen_in_insn);
37410d565efSmrg     }
37510d565efSmrg 
37610d565efSmrg   /* Process the artificial defs at the top of the block last since we
37710d565efSmrg      are going backwards through the block and these are logically at
37810d565efSmrg      the start.  */
37910d565efSmrg   if (!(df->changeable_flags & DF_NO_HARD_REGS))
38010d565efSmrg     df_rd_bb_local_compute_process_def (bb_info,
38110d565efSmrg 					df_get_artificial_defs (bb_index),
38210d565efSmrg 					DF_REF_AT_TOP);
38310d565efSmrg }
38410d565efSmrg 
38510d565efSmrg 
38610d565efSmrg /* Compute local reaching def info for each basic block within BLOCKS.  */
38710d565efSmrg 
38810d565efSmrg static void
df_rd_local_compute(bitmap all_blocks)38910d565efSmrg df_rd_local_compute (bitmap all_blocks)
39010d565efSmrg {
39110d565efSmrg   unsigned int bb_index;
39210d565efSmrg   bitmap_iterator bi;
393*ec02198aSmrg   class df_rd_problem_data *problem_data
394*ec02198aSmrg     = (class df_rd_problem_data *) df_rd->problem_data;
395*ec02198aSmrg   bitmap sparse_invalidated = &problem_data->sparse_invalidated_by_eh;
396*ec02198aSmrg   bitmap dense_invalidated = &problem_data->dense_invalidated_by_eh;
39710d565efSmrg 
39810d565efSmrg   bitmap_initialize (&seen_in_block, &df_bitmap_obstack);
39910d565efSmrg   bitmap_initialize (&seen_in_insn, &df_bitmap_obstack);
40010d565efSmrg 
40110d565efSmrg   df_maybe_reorganize_def_refs (DF_REF_ORDER_BY_REG);
40210d565efSmrg 
40310d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
40410d565efSmrg     {
40510d565efSmrg       df_rd_bb_local_compute (bb_index);
40610d565efSmrg     }
40710d565efSmrg 
408*ec02198aSmrg   /* Set up the knockout bit vectors to be applied across EH_EDGES.
409*ec02198aSmrg      Conservatively treat partially-clobbered registers as surviving
410*ec02198aSmrg      across the EH edge, i.e. assume that definitions before the edge
411*ec02198aSmrg      is taken *might* reach uses after it has been taken.  */
412*ec02198aSmrg   if (!(df->changeable_flags & DF_NO_HARD_REGS))
413*ec02198aSmrg     for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
414*ec02198aSmrg       if (eh_edge_abi.clobbers_full_reg_p (regno))
41510d565efSmrg 	{
41610d565efSmrg 	  if (DF_DEFS_COUNT (regno) > DF_SPARSE_THRESHOLD)
41710d565efSmrg 	    bitmap_set_bit (sparse_invalidated, regno);
41810d565efSmrg 	  else
41910d565efSmrg 	    bitmap_set_range (dense_invalidated,
42010d565efSmrg 			      DF_DEFS_BEGIN (regno),
42110d565efSmrg 			      DF_DEFS_COUNT (regno));
42210d565efSmrg 	}
42310d565efSmrg 
4240fc04c29Smrg   bitmap_release (&seen_in_block);
4250fc04c29Smrg   bitmap_release (&seen_in_insn);
42610d565efSmrg }
42710d565efSmrg 
42810d565efSmrg 
42910d565efSmrg /* Initialize the solution bit vectors for problem.  */
43010d565efSmrg 
43110d565efSmrg static void
df_rd_init_solution(bitmap all_blocks)43210d565efSmrg df_rd_init_solution (bitmap all_blocks)
43310d565efSmrg {
43410d565efSmrg   unsigned int bb_index;
43510d565efSmrg   bitmap_iterator bi;
43610d565efSmrg 
43710d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
43810d565efSmrg     {
439*ec02198aSmrg       class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
44010d565efSmrg 
44110d565efSmrg       bitmap_copy (&bb_info->out, &bb_info->gen);
44210d565efSmrg       bitmap_clear (&bb_info->in);
44310d565efSmrg     }
44410d565efSmrg }
44510d565efSmrg 
44610d565efSmrg /* In of target gets or of out of source.  */
44710d565efSmrg 
44810d565efSmrg static bool
df_rd_confluence_n(edge e)44910d565efSmrg df_rd_confluence_n (edge e)
45010d565efSmrg {
45110d565efSmrg   bitmap op1 = &df_rd_get_bb_info (e->dest->index)->in;
45210d565efSmrg   bitmap op2 = &df_rd_get_bb_info (e->src->index)->out;
45310d565efSmrg   bool changed = false;
45410d565efSmrg 
45510d565efSmrg   if (e->flags & EDGE_FAKE)
45610d565efSmrg     return false;
45710d565efSmrg 
45810d565efSmrg   if (e->flags & EDGE_EH)
45910d565efSmrg     {
460*ec02198aSmrg       class df_rd_problem_data *problem_data
461*ec02198aSmrg 	= (class df_rd_problem_data *) df_rd->problem_data;
462*ec02198aSmrg       bitmap sparse_invalidated = &problem_data->sparse_invalidated_by_eh;
463*ec02198aSmrg       bitmap dense_invalidated = &problem_data->dense_invalidated_by_eh;
46410d565efSmrg       bitmap_iterator bi;
46510d565efSmrg       unsigned int regno;
46610d565efSmrg 
467c7a68eb7Smrg       auto_bitmap tmp (&df_bitmap_obstack);
468c7a68eb7Smrg       bitmap_and_compl (tmp, op2, dense_invalidated);
46910d565efSmrg 
47010d565efSmrg       EXECUTE_IF_SET_IN_BITMAP (sparse_invalidated, 0, regno, bi)
47110d565efSmrg  	{
472c7a68eb7Smrg 	  bitmap_clear_range (tmp,
47310d565efSmrg  			      DF_DEFS_BEGIN (regno),
47410d565efSmrg  			      DF_DEFS_COUNT (regno));
47510d565efSmrg 	}
476c7a68eb7Smrg       changed |= bitmap_ior_into (op1, tmp);
47710d565efSmrg       return changed;
47810d565efSmrg     }
47910d565efSmrg   else
48010d565efSmrg     return bitmap_ior_into (op1, op2);
48110d565efSmrg }
48210d565efSmrg 
48310d565efSmrg 
48410d565efSmrg /* Transfer function.  */
48510d565efSmrg 
48610d565efSmrg static bool
df_rd_transfer_function(int bb_index)48710d565efSmrg df_rd_transfer_function (int bb_index)
48810d565efSmrg {
489*ec02198aSmrg   class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
49010d565efSmrg   unsigned int regno;
49110d565efSmrg   bitmap_iterator bi;
49210d565efSmrg   bitmap in = &bb_info->in;
49310d565efSmrg   bitmap out = &bb_info->out;
49410d565efSmrg   bitmap gen = &bb_info->gen;
49510d565efSmrg   bitmap kill = &bb_info->kill;
49610d565efSmrg   bitmap sparse_kill = &bb_info->sparse_kill;
49710d565efSmrg   bool changed = false;
49810d565efSmrg 
49910d565efSmrg   if (bitmap_empty_p (sparse_kill))
50010d565efSmrg     changed = bitmap_ior_and_compl (out, gen, in, kill);
50110d565efSmrg   else
50210d565efSmrg     {
503*ec02198aSmrg       class df_rd_problem_data *problem_data;
50410d565efSmrg       bitmap_head tmp;
50510d565efSmrg 
50610d565efSmrg       /* Note that TMP is _not_ a temporary bitmap if we end up replacing
50710d565efSmrg 	 OUT with TMP.  Therefore, allocate TMP in the RD bitmaps obstack.  */
508*ec02198aSmrg       problem_data = (class df_rd_problem_data *) df_rd->problem_data;
50910d565efSmrg       bitmap_initialize (&tmp, &problem_data->rd_bitmaps);
51010d565efSmrg 
51110d565efSmrg       bitmap_and_compl (&tmp, in, kill);
51210d565efSmrg       EXECUTE_IF_SET_IN_BITMAP (sparse_kill, 0, regno, bi)
51310d565efSmrg 	{
51410d565efSmrg 	  bitmap_clear_range (&tmp,
51510d565efSmrg 			      DF_DEFS_BEGIN (regno),
51610d565efSmrg 			      DF_DEFS_COUNT (regno));
51710d565efSmrg 	}
51810d565efSmrg       bitmap_ior_into (&tmp, gen);
51910d565efSmrg       changed = !bitmap_equal_p (&tmp, out);
52010d565efSmrg       if (changed)
52110d565efSmrg 	bitmap_move (out, &tmp);
52210d565efSmrg       else
52310d565efSmrg 	bitmap_clear (&tmp);
52410d565efSmrg     }
52510d565efSmrg 
52610d565efSmrg   if (df->changeable_flags & DF_RD_PRUNE_DEAD_DEFS)
52710d565efSmrg     {
52810d565efSmrg       /* Create a mask of DEFs for all registers live at the end of this
52910d565efSmrg 	 basic block, and mask out DEFs of registers that are not live.
53010d565efSmrg 	 Computing the mask looks costly, but the benefit of the pruning
53110d565efSmrg 	 outweighs the cost.  */
532*ec02198aSmrg       class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
53310d565efSmrg       bitmap regs_live_out = &df_lr_get_bb_info (bb_index)->out;
53410d565efSmrg       bitmap live_defs = BITMAP_ALLOC (&df_bitmap_obstack);
53510d565efSmrg       unsigned int regno;
53610d565efSmrg       bitmap_iterator bi;
53710d565efSmrg 
53810d565efSmrg       EXECUTE_IF_SET_IN_BITMAP (regs_live_out, 0, regno, bi)
53910d565efSmrg 	bitmap_set_range (live_defs,
54010d565efSmrg 			  DF_DEFS_BEGIN (regno),
54110d565efSmrg 			  DF_DEFS_COUNT (regno));
54210d565efSmrg       changed |= bitmap_and_into (&bb_info->out, live_defs);
54310d565efSmrg       BITMAP_FREE (live_defs);
54410d565efSmrg     }
54510d565efSmrg 
54610d565efSmrg   return changed;
54710d565efSmrg }
54810d565efSmrg 
54910d565efSmrg /* Free all storage associated with the problem.  */
55010d565efSmrg 
55110d565efSmrg static void
df_rd_free(void)55210d565efSmrg df_rd_free (void)
55310d565efSmrg {
554*ec02198aSmrg   class df_rd_problem_data *problem_data
555*ec02198aSmrg     = (class df_rd_problem_data *) df_rd->problem_data;
55610d565efSmrg 
55710d565efSmrg   if (problem_data)
55810d565efSmrg     {
55910d565efSmrg       bitmap_obstack_release (&problem_data->rd_bitmaps);
56010d565efSmrg 
56110d565efSmrg       df_rd->block_info_size = 0;
56210d565efSmrg       free (df_rd->block_info);
56310d565efSmrg       df_rd->block_info = NULL;
56410d565efSmrg       free (df_rd->problem_data);
56510d565efSmrg     }
56610d565efSmrg   free (df_rd);
56710d565efSmrg }
56810d565efSmrg 
56910d565efSmrg 
57010d565efSmrg /* Debugging info.  */
57110d565efSmrg 
57210d565efSmrg static void
df_rd_start_dump(FILE * file)57310d565efSmrg df_rd_start_dump (FILE *file)
57410d565efSmrg {
575*ec02198aSmrg   class df_rd_problem_data *problem_data
576*ec02198aSmrg     = (class df_rd_problem_data *) df_rd->problem_data;
57710d565efSmrg   unsigned int m = DF_REG_SIZE (df);
57810d565efSmrg   unsigned int regno;
57910d565efSmrg 
58010d565efSmrg   if (!df_rd->block_info)
58110d565efSmrg     return;
58210d565efSmrg 
58310d565efSmrg   fprintf (file, ";; Reaching defs:\n");
58410d565efSmrg 
58510d565efSmrg   fprintf (file, ";;  sparse invalidated \t");
586*ec02198aSmrg   dump_bitmap (file, &problem_data->sparse_invalidated_by_eh);
58710d565efSmrg   fprintf (file, ";;  dense invalidated \t");
588*ec02198aSmrg   dump_bitmap (file, &problem_data->dense_invalidated_by_eh);
58910d565efSmrg 
59010d565efSmrg   fprintf (file, ";;  reg->defs[] map:\t");
59110d565efSmrg   for (regno = 0; regno < m; regno++)
59210d565efSmrg     if (DF_DEFS_COUNT (regno))
59310d565efSmrg       fprintf (file, "%d[%d,%d] ", regno,
59410d565efSmrg 	       DF_DEFS_BEGIN (regno),
59510d565efSmrg 	       DF_DEFS_BEGIN (regno) + DF_DEFS_COUNT (regno) - 1);
59610d565efSmrg   fprintf (file, "\n");
59710d565efSmrg }
59810d565efSmrg 
59910d565efSmrg 
60010d565efSmrg static void
df_rd_dump_defs_set(bitmap defs_set,const char * prefix,FILE * file)60110d565efSmrg df_rd_dump_defs_set (bitmap defs_set, const char *prefix, FILE *file)
60210d565efSmrg {
60310d565efSmrg   bitmap_head tmp;
60410d565efSmrg   unsigned int regno;
60510d565efSmrg   unsigned int m = DF_REG_SIZE (df);
60610d565efSmrg   bool first_reg = true;
60710d565efSmrg 
60810d565efSmrg   fprintf (file, "%s\t(%d) ", prefix, (int) bitmap_count_bits (defs_set));
60910d565efSmrg 
61010d565efSmrg   bitmap_initialize (&tmp, &df_bitmap_obstack);
61110d565efSmrg   for (regno = 0; regno < m; regno++)
61210d565efSmrg     {
61310d565efSmrg       if (HARD_REGISTER_NUM_P (regno)
61410d565efSmrg 	  && (df->changeable_flags & DF_NO_HARD_REGS))
61510d565efSmrg 	continue;
61610d565efSmrg       bitmap_set_range (&tmp, DF_DEFS_BEGIN (regno), DF_DEFS_COUNT (regno));
61710d565efSmrg       bitmap_and_into (&tmp, defs_set);
61810d565efSmrg       if (! bitmap_empty_p (&tmp))
61910d565efSmrg 	{
62010d565efSmrg 	  bitmap_iterator bi;
62110d565efSmrg 	  unsigned int ix;
62210d565efSmrg 	  bool first_def = true;
62310d565efSmrg 
62410d565efSmrg 	  if (! first_reg)
62510d565efSmrg 	    fprintf (file, ",");
62610d565efSmrg 	  first_reg = false;
62710d565efSmrg 
62810d565efSmrg 	  fprintf (file, "%u[", regno);
62910d565efSmrg 	  EXECUTE_IF_SET_IN_BITMAP (&tmp, 0, ix, bi)
63010d565efSmrg 	    {
63110d565efSmrg 	      fprintf (file, "%s%u", first_def ? "" : ",", ix);
63210d565efSmrg 	      first_def = false;
63310d565efSmrg 	    }
63410d565efSmrg 	  fprintf (file, "]");
63510d565efSmrg 	}
63610d565efSmrg       bitmap_clear (&tmp);
63710d565efSmrg     }
63810d565efSmrg 
63910d565efSmrg   fprintf (file, "\n");
64010d565efSmrg   bitmap_clear (&tmp);
64110d565efSmrg }
64210d565efSmrg 
64310d565efSmrg /* Debugging info at top of bb.  */
64410d565efSmrg 
64510d565efSmrg static void
df_rd_top_dump(basic_block bb,FILE * file)64610d565efSmrg df_rd_top_dump (basic_block bb, FILE *file)
64710d565efSmrg {
648*ec02198aSmrg   class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb->index);
64910d565efSmrg   if (!bb_info)
65010d565efSmrg     return;
65110d565efSmrg 
65210d565efSmrg   df_rd_dump_defs_set (&bb_info->in, ";; rd  in  ", file);
65310d565efSmrg   df_rd_dump_defs_set (&bb_info->gen, ";; rd  gen ", file);
65410d565efSmrg   df_rd_dump_defs_set (&bb_info->kill, ";; rd  kill", file);
65510d565efSmrg }
65610d565efSmrg 
65710d565efSmrg 
65810d565efSmrg /* Debugging info at bottom of bb.  */
65910d565efSmrg 
66010d565efSmrg static void
df_rd_bottom_dump(basic_block bb,FILE * file)66110d565efSmrg df_rd_bottom_dump (basic_block bb, FILE *file)
66210d565efSmrg {
663*ec02198aSmrg   class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb->index);
66410d565efSmrg   if (!bb_info)
66510d565efSmrg     return;
66610d565efSmrg 
66710d565efSmrg   df_rd_dump_defs_set (&bb_info->out, ";; rd  out ", file);
66810d565efSmrg }
66910d565efSmrg 
67010d565efSmrg /* All of the information associated with every instance of the problem.  */
67110d565efSmrg 
67210d565efSmrg static const struct df_problem problem_RD =
67310d565efSmrg {
67410d565efSmrg   DF_RD,                      /* Problem id.  */
67510d565efSmrg   DF_FORWARD,                 /* Direction.  */
67610d565efSmrg   df_rd_alloc,                /* Allocate the problem specific data.  */
67710d565efSmrg   NULL,                       /* Reset global information.  */
67810d565efSmrg   df_rd_free_bb_info,         /* Free basic block info.  */
67910d565efSmrg   df_rd_local_compute,        /* Local compute function.  */
68010d565efSmrg   df_rd_init_solution,        /* Init the solution specific data.  */
68110d565efSmrg   df_worklist_dataflow,       /* Worklist solver.  */
68210d565efSmrg   NULL,                       /* Confluence operator 0.  */
68310d565efSmrg   df_rd_confluence_n,         /* Confluence operator n.  */
68410d565efSmrg   df_rd_transfer_function,    /* Transfer function.  */
68510d565efSmrg   NULL,                       /* Finalize function.  */
68610d565efSmrg   df_rd_free,                 /* Free all of the problem information.  */
68710d565efSmrg   df_rd_free,                 /* Remove this problem from the stack of dataflow problems.  */
68810d565efSmrg   df_rd_start_dump,           /* Debugging.  */
68910d565efSmrg   df_rd_top_dump,             /* Debugging start block.  */
69010d565efSmrg   df_rd_bottom_dump,          /* Debugging end block.  */
69110d565efSmrg   NULL,                       /* Debugging start insn.  */
69210d565efSmrg   NULL,                       /* Debugging end insn.  */
69310d565efSmrg   NULL,                       /* Incremental solution verify start.  */
69410d565efSmrg   NULL,                       /* Incremental solution verify end.  */
69510d565efSmrg   NULL,                       /* Dependent problem.  */
696*ec02198aSmrg   sizeof (class df_rd_bb_info),/* Size of entry of block_info array.  */
69710d565efSmrg   TV_DF_RD,                   /* Timing variable.  */
69810d565efSmrg   true                        /* Reset blocks on dropping out of blocks_to_analyze.  */
69910d565efSmrg };
70010d565efSmrg 
70110d565efSmrg 
70210d565efSmrg 
70310d565efSmrg /* Create a new RD instance and add it to the existing instance
70410d565efSmrg    of DF.  */
70510d565efSmrg 
70610d565efSmrg void
df_rd_add_problem(void)70710d565efSmrg df_rd_add_problem (void)
70810d565efSmrg {
70910d565efSmrg   df_add_problem (&problem_RD);
71010d565efSmrg }
71110d565efSmrg 
71210d565efSmrg 
71310d565efSmrg 
71410d565efSmrg /*----------------------------------------------------------------------------
71510d565efSmrg    LIVE REGISTERS
71610d565efSmrg 
71710d565efSmrg    Find the locations in the function where any use of a pseudo can
71810d565efSmrg    reach in the backwards direction.  In and out bitvectors are built
71910d565efSmrg    for each basic block.  The regno is used to index into these sets.
72010d565efSmrg    See df.h for details.
72110d565efSmrg    ----------------------------------------------------------------------------*/
72210d565efSmrg 
72310d565efSmrg /* Private data used to verify the solution for this problem.  */
72410d565efSmrg struct df_lr_problem_data
72510d565efSmrg {
72610d565efSmrg   bitmap_head *in;
72710d565efSmrg   bitmap_head *out;
72810d565efSmrg   /* An obstack for the bitmaps we need for this problem.  */
72910d565efSmrg   bitmap_obstack lr_bitmaps;
73010d565efSmrg };
73110d565efSmrg 
73210d565efSmrg /* Free basic block info.  */
73310d565efSmrg 
73410d565efSmrg static void
df_lr_free_bb_info(basic_block bb ATTRIBUTE_UNUSED,void * vbb_info)73510d565efSmrg df_lr_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
73610d565efSmrg 		    void *vbb_info)
73710d565efSmrg {
738*ec02198aSmrg   class df_lr_bb_info *bb_info = (class df_lr_bb_info *) vbb_info;
73910d565efSmrg   if (bb_info)
74010d565efSmrg     {
74110d565efSmrg       bitmap_clear (&bb_info->use);
74210d565efSmrg       bitmap_clear (&bb_info->def);
74310d565efSmrg       bitmap_clear (&bb_info->in);
74410d565efSmrg       bitmap_clear (&bb_info->out);
74510d565efSmrg     }
74610d565efSmrg }
74710d565efSmrg 
74810d565efSmrg 
74910d565efSmrg /* Allocate or reset bitmaps for DF_LR blocks. The solution bits are
75010d565efSmrg    not touched unless the block is new.  */
75110d565efSmrg 
75210d565efSmrg static void
df_lr_alloc(bitmap all_blocks ATTRIBUTE_UNUSED)75310d565efSmrg df_lr_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
75410d565efSmrg {
75510d565efSmrg   unsigned int bb_index;
75610d565efSmrg   bitmap_iterator bi;
75710d565efSmrg   struct df_lr_problem_data *problem_data;
75810d565efSmrg 
75910d565efSmrg   df_grow_bb_info (df_lr);
76010d565efSmrg   if (df_lr->problem_data)
76110d565efSmrg     problem_data = (struct df_lr_problem_data *) df_lr->problem_data;
76210d565efSmrg   else
76310d565efSmrg     {
76410d565efSmrg       problem_data = XNEW (struct df_lr_problem_data);
76510d565efSmrg       df_lr->problem_data = problem_data;
76610d565efSmrg 
76710d565efSmrg       problem_data->out = NULL;
76810d565efSmrg       problem_data->in = NULL;
76910d565efSmrg       bitmap_obstack_initialize (&problem_data->lr_bitmaps);
77010d565efSmrg     }
77110d565efSmrg 
77210d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (df_lr->out_of_date_transfer_functions, 0, bb_index, bi)
77310d565efSmrg     {
774*ec02198aSmrg       class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
77510d565efSmrg 
77610d565efSmrg       /* When bitmaps are already initialized, just clear them.  */
77710d565efSmrg       if (bb_info->use.obstack)
77810d565efSmrg 	{
77910d565efSmrg 	  bitmap_clear (&bb_info->def);
78010d565efSmrg 	  bitmap_clear (&bb_info->use);
78110d565efSmrg 	}
78210d565efSmrg       else
78310d565efSmrg 	{
78410d565efSmrg 	  bitmap_initialize (&bb_info->use, &problem_data->lr_bitmaps);
78510d565efSmrg 	  bitmap_initialize (&bb_info->def, &problem_data->lr_bitmaps);
78610d565efSmrg 	  bitmap_initialize (&bb_info->in, &problem_data->lr_bitmaps);
78710d565efSmrg 	  bitmap_initialize (&bb_info->out, &problem_data->lr_bitmaps);
78810d565efSmrg 	}
78910d565efSmrg     }
79010d565efSmrg 
79110d565efSmrg   df_lr->optional_p = false;
79210d565efSmrg }
79310d565efSmrg 
79410d565efSmrg 
79510d565efSmrg /* Reset the global solution for recalculation.  */
79610d565efSmrg 
79710d565efSmrg static void
df_lr_reset(bitmap all_blocks)79810d565efSmrg df_lr_reset (bitmap all_blocks)
79910d565efSmrg {
80010d565efSmrg   unsigned int bb_index;
80110d565efSmrg   bitmap_iterator bi;
80210d565efSmrg 
80310d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
80410d565efSmrg     {
805*ec02198aSmrg       class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
80610d565efSmrg       gcc_assert (bb_info);
80710d565efSmrg       bitmap_clear (&bb_info->in);
80810d565efSmrg       bitmap_clear (&bb_info->out);
80910d565efSmrg     }
81010d565efSmrg }
81110d565efSmrg 
81210d565efSmrg 
81310d565efSmrg /* Compute local live register info for basic block BB.  */
81410d565efSmrg 
81510d565efSmrg static void
df_lr_bb_local_compute(unsigned int bb_index)81610d565efSmrg df_lr_bb_local_compute (unsigned int bb_index)
81710d565efSmrg {
81810d565efSmrg   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
819*ec02198aSmrg   class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
82010d565efSmrg   rtx_insn *insn;
82110d565efSmrg   df_ref def, use;
82210d565efSmrg 
82310d565efSmrg   /* Process the registers set in an exception handler.  */
82410d565efSmrg   FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
82510d565efSmrg     if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
82610d565efSmrg       {
82710d565efSmrg 	unsigned int dregno = DF_REF_REGNO (def);
82810d565efSmrg 	bitmap_set_bit (&bb_info->def, dregno);
82910d565efSmrg 	bitmap_clear_bit (&bb_info->use, dregno);
83010d565efSmrg       }
83110d565efSmrg 
83210d565efSmrg   /* Process the hardware registers that are always live.  */
83310d565efSmrg   FOR_EACH_ARTIFICIAL_USE (use, bb_index)
83410d565efSmrg     /* Add use to set of uses in this BB.  */
83510d565efSmrg     if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
83610d565efSmrg       bitmap_set_bit (&bb_info->use, DF_REF_REGNO (use));
83710d565efSmrg 
83810d565efSmrg   FOR_BB_INSNS_REVERSE (bb, insn)
83910d565efSmrg     {
84010d565efSmrg       if (!NONDEBUG_INSN_P (insn))
84110d565efSmrg 	continue;
84210d565efSmrg 
84310d565efSmrg       df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
84410d565efSmrg       FOR_EACH_INSN_INFO_DEF (def, insn_info)
84510d565efSmrg 	/* If the def is to only part of the reg, it does
84610d565efSmrg 	   not kill the other defs that reach here.  */
84710d565efSmrg 	if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
84810d565efSmrg 	  {
84910d565efSmrg 	    unsigned int dregno = DF_REF_REGNO (def);
85010d565efSmrg 	    bitmap_set_bit (&bb_info->def, dregno);
85110d565efSmrg 	    bitmap_clear_bit (&bb_info->use, dregno);
85210d565efSmrg 	  }
85310d565efSmrg 
85410d565efSmrg       FOR_EACH_INSN_INFO_USE (use, insn_info)
85510d565efSmrg 	/* Add use to set of uses in this BB.  */
85610d565efSmrg 	bitmap_set_bit (&bb_info->use, DF_REF_REGNO (use));
85710d565efSmrg     }
85810d565efSmrg 
85910d565efSmrg   /* Process the registers set in an exception handler or the hard
86010d565efSmrg      frame pointer if this block is the target of a non local
86110d565efSmrg      goto.  */
86210d565efSmrg   FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
86310d565efSmrg     if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
86410d565efSmrg       {
86510d565efSmrg 	unsigned int dregno = DF_REF_REGNO (def);
86610d565efSmrg 	bitmap_set_bit (&bb_info->def, dregno);
86710d565efSmrg 	bitmap_clear_bit (&bb_info->use, dregno);
86810d565efSmrg       }
86910d565efSmrg 
87010d565efSmrg #ifdef EH_USES
87110d565efSmrg   /* Process the uses that are live into an exception handler.  */
87210d565efSmrg   FOR_EACH_ARTIFICIAL_USE (use, bb_index)
87310d565efSmrg     /* Add use to set of uses in this BB.  */
87410d565efSmrg     if (DF_REF_FLAGS (use) & DF_REF_AT_TOP)
87510d565efSmrg       bitmap_set_bit (&bb_info->use, DF_REF_REGNO (use));
87610d565efSmrg #endif
87710d565efSmrg 
87810d565efSmrg   /* If the df_live problem is not defined, such as at -O0 and -O1, we
87910d565efSmrg      still need to keep the luids up to date.  This is normally done
88010d565efSmrg      in the df_live problem since this problem has a forwards
88110d565efSmrg      scan.  */
88210d565efSmrg   if (!df_live)
88310d565efSmrg     df_recompute_luids (bb);
88410d565efSmrg }
88510d565efSmrg 
88610d565efSmrg 
88710d565efSmrg /* Compute local live register info for each basic block within BLOCKS.  */
88810d565efSmrg 
88910d565efSmrg static void
df_lr_local_compute(bitmap all_blocks ATTRIBUTE_UNUSED)89010d565efSmrg df_lr_local_compute (bitmap all_blocks ATTRIBUTE_UNUSED)
89110d565efSmrg {
89210d565efSmrg   unsigned int bb_index, i;
89310d565efSmrg   bitmap_iterator bi;
89410d565efSmrg 
89510d565efSmrg   bitmap_clear (&df->hardware_regs_used);
89610d565efSmrg 
89710d565efSmrg   /* The all-important stack pointer must always be live.  */
89810d565efSmrg   bitmap_set_bit (&df->hardware_regs_used, STACK_POINTER_REGNUM);
89910d565efSmrg 
90010d565efSmrg   /* Global regs are always live, too.  */
90110d565efSmrg   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
90210d565efSmrg     if (global_regs[i])
90310d565efSmrg       bitmap_set_bit (&df->hardware_regs_used, i);
90410d565efSmrg 
90510d565efSmrg   /* Before reload, there are a few registers that must be forced
90610d565efSmrg      live everywhere -- which might not already be the case for
90710d565efSmrg      blocks within infinite loops.  */
90810d565efSmrg   if (!reload_completed)
90910d565efSmrg     {
91010d565efSmrg       unsigned int pic_offset_table_regnum = PIC_OFFSET_TABLE_REGNUM;
91110d565efSmrg       /* Any reference to any pseudo before reload is a potential
91210d565efSmrg 	 reference of the frame pointer.  */
91310d565efSmrg       bitmap_set_bit (&df->hardware_regs_used, FRAME_POINTER_REGNUM);
91410d565efSmrg 
91510d565efSmrg       /* Pseudos with argument area equivalences may require
91610d565efSmrg 	 reloading via the argument pointer.  */
91710d565efSmrg       if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
91810d565efSmrg 	  && fixed_regs[ARG_POINTER_REGNUM])
91910d565efSmrg 	bitmap_set_bit (&df->hardware_regs_used, ARG_POINTER_REGNUM);
92010d565efSmrg 
92110d565efSmrg       /* Any constant, or pseudo with constant equivalences, may
92210d565efSmrg 	 require reloading from memory using the pic register.  */
92310d565efSmrg       if (pic_offset_table_regnum != INVALID_REGNUM
92410d565efSmrg 	  && fixed_regs[pic_offset_table_regnum])
92510d565efSmrg 	bitmap_set_bit (&df->hardware_regs_used, pic_offset_table_regnum);
92610d565efSmrg     }
92710d565efSmrg 
92810d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (df_lr->out_of_date_transfer_functions, 0, bb_index, bi)
92910d565efSmrg     {
93010d565efSmrg       if (bb_index == EXIT_BLOCK)
93110d565efSmrg 	{
93210d565efSmrg 	  /* The exit block is special for this problem and its bits are
93310d565efSmrg 	     computed from thin air.  */
934*ec02198aSmrg 	  class df_lr_bb_info *bb_info = df_lr_get_bb_info (EXIT_BLOCK);
93510d565efSmrg 	  bitmap_copy (&bb_info->use, df->exit_block_uses);
93610d565efSmrg 	}
93710d565efSmrg       else
93810d565efSmrg 	df_lr_bb_local_compute (bb_index);
93910d565efSmrg     }
94010d565efSmrg 
94110d565efSmrg   bitmap_clear (df_lr->out_of_date_transfer_functions);
94210d565efSmrg }
94310d565efSmrg 
94410d565efSmrg 
94510d565efSmrg /* Initialize the solution vectors.  */
94610d565efSmrg 
94710d565efSmrg static void
df_lr_init(bitmap all_blocks)94810d565efSmrg df_lr_init (bitmap all_blocks)
94910d565efSmrg {
95010d565efSmrg   unsigned int bb_index;
95110d565efSmrg   bitmap_iterator bi;
95210d565efSmrg 
95310d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
95410d565efSmrg     {
955*ec02198aSmrg       class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
95610d565efSmrg       bitmap_copy (&bb_info->in, &bb_info->use);
95710d565efSmrg       bitmap_clear (&bb_info->out);
95810d565efSmrg     }
95910d565efSmrg }
96010d565efSmrg 
96110d565efSmrg 
96210d565efSmrg /* Confluence function that processes infinite loops.  This might be a
96310d565efSmrg    noreturn function that throws.  And even if it isn't, getting the
96410d565efSmrg    unwind info right helps debugging.  */
96510d565efSmrg static void
df_lr_confluence_0(basic_block bb)96610d565efSmrg df_lr_confluence_0 (basic_block bb)
96710d565efSmrg {
96810d565efSmrg   bitmap op1 = &df_lr_get_bb_info (bb->index)->out;
96910d565efSmrg   if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
97010d565efSmrg     bitmap_copy (op1, &df->hardware_regs_used);
97110d565efSmrg }
97210d565efSmrg 
97310d565efSmrg 
97410d565efSmrg /* Confluence function that ignores fake edges.  */
97510d565efSmrg 
97610d565efSmrg static bool
df_lr_confluence_n(edge e)97710d565efSmrg df_lr_confluence_n (edge e)
97810d565efSmrg {
97910d565efSmrg   bitmap op1 = &df_lr_get_bb_info (e->src->index)->out;
98010d565efSmrg   bitmap op2 = &df_lr_get_bb_info (e->dest->index)->in;
98110d565efSmrg   bool changed = false;
98210d565efSmrg 
983*ec02198aSmrg   /* Call-clobbered registers die across exception and call edges.
984*ec02198aSmrg      Conservatively treat partially-clobbered registers as surviving
985*ec02198aSmrg      across the edges; they might or might not, depending on what
986*ec02198aSmrg      mode they have.  */
98710d565efSmrg   /* ??? Abnormal call edges ignored for the moment, as this gets
98810d565efSmrg      confused by sibling call edges, which crashes reg-stack.  */
98910d565efSmrg   if (e->flags & EDGE_EH)
990*ec02198aSmrg     {
991*ec02198aSmrg       bitmap_view<HARD_REG_SET> eh_kills (eh_edge_abi.full_reg_clobbers ());
992*ec02198aSmrg       changed = bitmap_ior_and_compl_into (op1, op2, eh_kills);
993*ec02198aSmrg     }
99410d565efSmrg   else
99510d565efSmrg     changed = bitmap_ior_into (op1, op2);
99610d565efSmrg 
99710d565efSmrg   changed |= bitmap_ior_into (op1, &df->hardware_regs_used);
99810d565efSmrg   return changed;
99910d565efSmrg }
100010d565efSmrg 
100110d565efSmrg 
100210d565efSmrg /* Transfer function.  */
100310d565efSmrg 
100410d565efSmrg static bool
df_lr_transfer_function(int bb_index)100510d565efSmrg df_lr_transfer_function (int bb_index)
100610d565efSmrg {
1007*ec02198aSmrg   class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
100810d565efSmrg   bitmap in = &bb_info->in;
100910d565efSmrg   bitmap out = &bb_info->out;
101010d565efSmrg   bitmap use = &bb_info->use;
101110d565efSmrg   bitmap def = &bb_info->def;
101210d565efSmrg 
101310d565efSmrg   return bitmap_ior_and_compl (in, use, out, def);
101410d565efSmrg }
101510d565efSmrg 
101610d565efSmrg 
101710d565efSmrg /* Run the fast dce as a side effect of building LR.  */
101810d565efSmrg 
101910d565efSmrg static void
df_lr_finalize(bitmap all_blocks)102010d565efSmrg df_lr_finalize (bitmap all_blocks)
102110d565efSmrg {
102210d565efSmrg   df_lr->solutions_dirty = false;
102310d565efSmrg   if (df->changeable_flags & DF_LR_RUN_DCE)
102410d565efSmrg     {
102510d565efSmrg       run_fast_df_dce ();
102610d565efSmrg 
102710d565efSmrg       /* If dce deletes some instructions, we need to recompute the lr
102810d565efSmrg 	 solution before proceeding further.  The problem is that fast
102910d565efSmrg 	 dce is a pessimestic dataflow algorithm.  In the case where
103010d565efSmrg 	 it deletes a statement S inside of a loop, the uses inside of
103110d565efSmrg 	 S may not be deleted from the dataflow solution because they
103210d565efSmrg 	 were carried around the loop.  While it is conservatively
103310d565efSmrg 	 correct to leave these extra bits, the standards of df
103410d565efSmrg 	 require that we maintain the best possible (least fixed
103510d565efSmrg 	 point) solution.  The only way to do that is to redo the
103610d565efSmrg 	 iteration from the beginning.  See PR35805 for an
103710d565efSmrg 	 example.  */
103810d565efSmrg       if (df_lr->solutions_dirty)
103910d565efSmrg 	{
104010d565efSmrg 	  df_clear_flags (DF_LR_RUN_DCE);
104110d565efSmrg 	  df_lr_alloc (all_blocks);
104210d565efSmrg 	  df_lr_local_compute (all_blocks);
104310d565efSmrg 	  df_worklist_dataflow (df_lr, all_blocks, df->postorder, df->n_blocks);
104410d565efSmrg 	  df_lr_finalize (all_blocks);
104510d565efSmrg 	  df_set_flags (DF_LR_RUN_DCE);
104610d565efSmrg 	}
104710d565efSmrg     }
104810d565efSmrg }
104910d565efSmrg 
105010d565efSmrg 
105110d565efSmrg /* Free all storage associated with the problem.  */
105210d565efSmrg 
105310d565efSmrg static void
df_lr_free(void)105410d565efSmrg df_lr_free (void)
105510d565efSmrg {
105610d565efSmrg   struct df_lr_problem_data *problem_data
105710d565efSmrg     = (struct df_lr_problem_data *) df_lr->problem_data;
105810d565efSmrg   if (df_lr->block_info)
105910d565efSmrg     {
106010d565efSmrg 
106110d565efSmrg       df_lr->block_info_size = 0;
106210d565efSmrg       free (df_lr->block_info);
106310d565efSmrg       df_lr->block_info = NULL;
106410d565efSmrg       bitmap_obstack_release (&problem_data->lr_bitmaps);
106510d565efSmrg       free (df_lr->problem_data);
106610d565efSmrg       df_lr->problem_data = NULL;
106710d565efSmrg     }
106810d565efSmrg 
106910d565efSmrg   BITMAP_FREE (df_lr->out_of_date_transfer_functions);
107010d565efSmrg   free (df_lr);
107110d565efSmrg }
107210d565efSmrg 
107310d565efSmrg 
107410d565efSmrg /* Debugging info at top of bb.  */
107510d565efSmrg 
107610d565efSmrg static void
df_lr_top_dump(basic_block bb,FILE * file)107710d565efSmrg df_lr_top_dump (basic_block bb, FILE *file)
107810d565efSmrg {
1079*ec02198aSmrg   class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb->index);
108010d565efSmrg   struct df_lr_problem_data *problem_data;
108110d565efSmrg   if (!bb_info)
108210d565efSmrg     return;
108310d565efSmrg 
108410d565efSmrg   fprintf (file, ";; lr  in  \t");
108510d565efSmrg   df_print_regset (file, &bb_info->in);
108610d565efSmrg   if (df_lr->problem_data)
108710d565efSmrg     {
108810d565efSmrg       problem_data = (struct df_lr_problem_data *)df_lr->problem_data;
108910d565efSmrg       if (problem_data->in)
109010d565efSmrg 	{
109110d565efSmrg       	  fprintf (file, ";;  old in  \t");
109210d565efSmrg       	  df_print_regset (file, &problem_data->in[bb->index]);
109310d565efSmrg 	}
109410d565efSmrg     }
109510d565efSmrg   fprintf (file, ";; lr  use \t");
109610d565efSmrg   df_print_regset (file, &bb_info->use);
109710d565efSmrg   fprintf (file, ";; lr  def \t");
109810d565efSmrg   df_print_regset (file, &bb_info->def);
109910d565efSmrg }
110010d565efSmrg 
110110d565efSmrg 
110210d565efSmrg /* Debugging info at bottom of bb.  */
110310d565efSmrg 
110410d565efSmrg static void
df_lr_bottom_dump(basic_block bb,FILE * file)110510d565efSmrg df_lr_bottom_dump (basic_block bb, FILE *file)
110610d565efSmrg {
1107*ec02198aSmrg   class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb->index);
110810d565efSmrg   struct df_lr_problem_data *problem_data;
110910d565efSmrg   if (!bb_info)
111010d565efSmrg     return;
111110d565efSmrg 
111210d565efSmrg   fprintf (file, ";; lr  out \t");
111310d565efSmrg   df_print_regset (file, &bb_info->out);
111410d565efSmrg   if (df_lr->problem_data)
111510d565efSmrg     {
111610d565efSmrg       problem_data = (struct df_lr_problem_data *)df_lr->problem_data;
111710d565efSmrg       if (problem_data->out)
111810d565efSmrg 	{
111910d565efSmrg           fprintf (file, ";;  old out  \t");
112010d565efSmrg           df_print_regset (file, &problem_data->out[bb->index]);
112110d565efSmrg 	}
112210d565efSmrg     }
112310d565efSmrg }
112410d565efSmrg 
112510d565efSmrg 
112610d565efSmrg /* Build the datastructure to verify that the solution to the dataflow
112710d565efSmrg    equations is not dirty.  */
112810d565efSmrg 
112910d565efSmrg static void
df_lr_verify_solution_start(void)113010d565efSmrg df_lr_verify_solution_start (void)
113110d565efSmrg {
113210d565efSmrg   basic_block bb;
113310d565efSmrg   struct df_lr_problem_data *problem_data;
113410d565efSmrg   if (df_lr->solutions_dirty)
113510d565efSmrg     return;
113610d565efSmrg 
113710d565efSmrg   /* Set it true so that the solution is recomputed.  */
113810d565efSmrg   df_lr->solutions_dirty = true;
113910d565efSmrg 
114010d565efSmrg   problem_data = (struct df_lr_problem_data *)df_lr->problem_data;
114110d565efSmrg   problem_data->in = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
114210d565efSmrg   problem_data->out = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
114310d565efSmrg 
114410d565efSmrg   FOR_ALL_BB_FN (bb, cfun)
114510d565efSmrg     {
114610d565efSmrg       bitmap_initialize (&problem_data->in[bb->index], &problem_data->lr_bitmaps);
114710d565efSmrg       bitmap_initialize (&problem_data->out[bb->index], &problem_data->lr_bitmaps);
114810d565efSmrg       bitmap_copy (&problem_data->in[bb->index], DF_LR_IN (bb));
114910d565efSmrg       bitmap_copy (&problem_data->out[bb->index], DF_LR_OUT (bb));
115010d565efSmrg     }
115110d565efSmrg }
115210d565efSmrg 
115310d565efSmrg 
115410d565efSmrg /* Compare the saved datastructure and the new solution to the dataflow
115510d565efSmrg    equations.  */
115610d565efSmrg 
115710d565efSmrg static void
df_lr_verify_solution_end(void)115810d565efSmrg df_lr_verify_solution_end (void)
115910d565efSmrg {
116010d565efSmrg   struct df_lr_problem_data *problem_data;
116110d565efSmrg   basic_block bb;
116210d565efSmrg 
116310d565efSmrg   problem_data = (struct df_lr_problem_data *)df_lr->problem_data;
116410d565efSmrg 
116510d565efSmrg   if (!problem_data->out)
116610d565efSmrg     return;
116710d565efSmrg 
116810d565efSmrg   if (df_lr->solutions_dirty)
116910d565efSmrg     /* Do not check if the solution is still dirty.  See the comment
117010d565efSmrg        in df_lr_finalize for details.  */
117110d565efSmrg     df_lr->solutions_dirty = false;
117210d565efSmrg   else
117310d565efSmrg     FOR_ALL_BB_FN (bb, cfun)
117410d565efSmrg       {
117510d565efSmrg 	if ((!bitmap_equal_p (&problem_data->in[bb->index], DF_LR_IN (bb)))
117610d565efSmrg 	    || (!bitmap_equal_p (&problem_data->out[bb->index], DF_LR_OUT (bb))))
117710d565efSmrg 	  {
117810d565efSmrg 	    /*df_dump (stderr);*/
117910d565efSmrg 	    gcc_unreachable ();
118010d565efSmrg 	  }
118110d565efSmrg       }
118210d565efSmrg 
118310d565efSmrg   /* Cannot delete them immediately because you may want to dump them
118410d565efSmrg      if the comparison fails.  */
118510d565efSmrg   FOR_ALL_BB_FN (bb, cfun)
118610d565efSmrg     {
118710d565efSmrg       bitmap_clear (&problem_data->in[bb->index]);
118810d565efSmrg       bitmap_clear (&problem_data->out[bb->index]);
118910d565efSmrg     }
119010d565efSmrg 
119110d565efSmrg   free (problem_data->in);
119210d565efSmrg   free (problem_data->out);
119310d565efSmrg   problem_data->in = NULL;
119410d565efSmrg   problem_data->out = NULL;
119510d565efSmrg }
119610d565efSmrg 
119710d565efSmrg 
119810d565efSmrg /* All of the information associated with every instance of the problem.  */
119910d565efSmrg 
120010d565efSmrg static const struct df_problem problem_LR =
120110d565efSmrg {
120210d565efSmrg   DF_LR,                      /* Problem id.  */
120310d565efSmrg   DF_BACKWARD,                /* Direction.  */
120410d565efSmrg   df_lr_alloc,                /* Allocate the problem specific data.  */
120510d565efSmrg   df_lr_reset,                /* Reset global information.  */
120610d565efSmrg   df_lr_free_bb_info,         /* Free basic block info.  */
120710d565efSmrg   df_lr_local_compute,        /* Local compute function.  */
120810d565efSmrg   df_lr_init,                 /* Init the solution specific data.  */
120910d565efSmrg   df_worklist_dataflow,       /* Worklist solver.  */
121010d565efSmrg   df_lr_confluence_0,         /* Confluence operator 0.  */
121110d565efSmrg   df_lr_confluence_n,         /* Confluence operator n.  */
121210d565efSmrg   df_lr_transfer_function,    /* Transfer function.  */
121310d565efSmrg   df_lr_finalize,             /* Finalize function.  */
121410d565efSmrg   df_lr_free,                 /* Free all of the problem information.  */
121510d565efSmrg   NULL,                       /* Remove this problem from the stack of dataflow problems.  */
121610d565efSmrg   NULL,                       /* Debugging.  */
121710d565efSmrg   df_lr_top_dump,             /* Debugging start block.  */
121810d565efSmrg   df_lr_bottom_dump,          /* Debugging end block.  */
121910d565efSmrg   NULL,                       /* Debugging start insn.  */
122010d565efSmrg   NULL,                       /* Debugging end insn.  */
122110d565efSmrg   df_lr_verify_solution_start,/* Incremental solution verify start.  */
122210d565efSmrg   df_lr_verify_solution_end,  /* Incremental solution verify end.  */
122310d565efSmrg   NULL,                       /* Dependent problem.  */
1224*ec02198aSmrg   sizeof (class df_lr_bb_info),/* Size of entry of block_info array.  */
122510d565efSmrg   TV_DF_LR,                   /* Timing variable.  */
122610d565efSmrg   false                       /* Reset blocks on dropping out of blocks_to_analyze.  */
122710d565efSmrg };
122810d565efSmrg 
122910d565efSmrg 
123010d565efSmrg /* Create a new DATAFLOW instance and add it to an existing instance
123110d565efSmrg    of DF.  The returned structure is what is used to get at the
123210d565efSmrg    solution.  */
123310d565efSmrg 
123410d565efSmrg void
df_lr_add_problem(void)123510d565efSmrg df_lr_add_problem (void)
123610d565efSmrg {
123710d565efSmrg   df_add_problem (&problem_LR);
123810d565efSmrg   /* These will be initialized when df_scan_blocks processes each
123910d565efSmrg      block.  */
124010d565efSmrg   df_lr->out_of_date_transfer_functions = BITMAP_ALLOC (&df_bitmap_obstack);
124110d565efSmrg }
124210d565efSmrg 
124310d565efSmrg 
124410d565efSmrg /* Verify that all of the lr related info is consistent and
124510d565efSmrg    correct.  */
124610d565efSmrg 
124710d565efSmrg void
df_lr_verify_transfer_functions(void)124810d565efSmrg df_lr_verify_transfer_functions (void)
124910d565efSmrg {
125010d565efSmrg   basic_block bb;
125110d565efSmrg   bitmap_head saved_def;
125210d565efSmrg   bitmap_head saved_use;
125310d565efSmrg   bitmap_head all_blocks;
125410d565efSmrg 
125510d565efSmrg   if (!df)
125610d565efSmrg     return;
125710d565efSmrg 
125810d565efSmrg   bitmap_initialize (&saved_def, &bitmap_default_obstack);
125910d565efSmrg   bitmap_initialize (&saved_use, &bitmap_default_obstack);
126010d565efSmrg   bitmap_initialize (&all_blocks, &bitmap_default_obstack);
126110d565efSmrg 
126210d565efSmrg   FOR_ALL_BB_FN (bb, cfun)
126310d565efSmrg     {
1264*ec02198aSmrg       class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb->index);
126510d565efSmrg       bitmap_set_bit (&all_blocks, bb->index);
126610d565efSmrg 
126710d565efSmrg       if (bb_info)
126810d565efSmrg 	{
126910d565efSmrg 	  /* Make a copy of the transfer functions and then compute
127010d565efSmrg 	     new ones to see if the transfer functions have
127110d565efSmrg 	     changed.  */
127210d565efSmrg 	  if (!bitmap_bit_p (df_lr->out_of_date_transfer_functions,
127310d565efSmrg 			     bb->index))
127410d565efSmrg 	    {
127510d565efSmrg 	      bitmap_copy (&saved_def, &bb_info->def);
127610d565efSmrg 	      bitmap_copy (&saved_use, &bb_info->use);
127710d565efSmrg 	      bitmap_clear (&bb_info->def);
127810d565efSmrg 	      bitmap_clear (&bb_info->use);
127910d565efSmrg 
128010d565efSmrg 	      df_lr_bb_local_compute (bb->index);
128110d565efSmrg 	      gcc_assert (bitmap_equal_p (&saved_def, &bb_info->def));
128210d565efSmrg 	      gcc_assert (bitmap_equal_p (&saved_use, &bb_info->use));
128310d565efSmrg 	    }
128410d565efSmrg 	}
128510d565efSmrg       else
128610d565efSmrg 	{
128710d565efSmrg 	  /* If we do not have basic block info, the block must be in
128810d565efSmrg 	     the list of dirty blocks or else some one has added a
128910d565efSmrg 	     block behind our backs. */
129010d565efSmrg 	  gcc_assert (bitmap_bit_p (df_lr->out_of_date_transfer_functions,
129110d565efSmrg 				    bb->index));
129210d565efSmrg 	}
129310d565efSmrg       /* Make sure no one created a block without following
129410d565efSmrg 	 procedures.  */
129510d565efSmrg       gcc_assert (df_scan_get_bb_info (bb->index));
129610d565efSmrg     }
129710d565efSmrg 
129810d565efSmrg   /* Make sure there are no dirty bits in blocks that have been deleted.  */
129910d565efSmrg   gcc_assert (!bitmap_intersect_compl_p (df_lr->out_of_date_transfer_functions,
130010d565efSmrg 					 &all_blocks));
130110d565efSmrg 
130210d565efSmrg   bitmap_clear (&saved_def);
130310d565efSmrg   bitmap_clear (&saved_use);
130410d565efSmrg   bitmap_clear (&all_blocks);
130510d565efSmrg }
130610d565efSmrg 
130710d565efSmrg 
130810d565efSmrg 
130910d565efSmrg /*----------------------------------------------------------------------------
131010d565efSmrg    LIVE AND MAY-INITIALIZED REGISTERS.
131110d565efSmrg 
131210d565efSmrg    This problem first computes the IN and OUT bitvectors for the
131310d565efSmrg    may-initialized registers problems, which is a forward problem.
131410d565efSmrg    It gives the set of registers for which we MAY have an available
131510d565efSmrg    definition, i.e. for which there is an available definition on
131610d565efSmrg    at least one path from the entry block to the entry/exit of a
131710d565efSmrg    basic block.  Sets generate a definition, while clobbers kill
131810d565efSmrg    a definition.
131910d565efSmrg 
132010d565efSmrg    In and out bitvectors are built for each basic block and are indexed by
132110d565efSmrg    regnum (see df.h for details).  In and out bitvectors in struct
132210d565efSmrg    df_live_bb_info actually refers to the may-initialized problem;
132310d565efSmrg 
132410d565efSmrg    Then, the in and out sets for the LIVE problem itself are computed.
132510d565efSmrg    These are the logical AND of the IN and OUT sets from the LR problem
132610d565efSmrg    and the may-initialized problem.
132710d565efSmrg ----------------------------------------------------------------------------*/
132810d565efSmrg 
132910d565efSmrg /* Private data used to verify the solution for this problem.  */
133010d565efSmrg struct df_live_problem_data
133110d565efSmrg {
133210d565efSmrg   bitmap_head *in;
133310d565efSmrg   bitmap_head *out;
133410d565efSmrg   /* An obstack for the bitmaps we need for this problem.  */
133510d565efSmrg   bitmap_obstack live_bitmaps;
133610d565efSmrg };
133710d565efSmrg 
133810d565efSmrg /* Scratch var used by transfer functions.  This is used to implement
133910d565efSmrg    an optimization to reduce the amount of space used to compute the
134010d565efSmrg    combined lr and live analysis.  */
134110d565efSmrg static bitmap_head df_live_scratch;
134210d565efSmrg 
134310d565efSmrg 
134410d565efSmrg /* Free basic block info.  */
134510d565efSmrg 
134610d565efSmrg static void
df_live_free_bb_info(basic_block bb ATTRIBUTE_UNUSED,void * vbb_info)134710d565efSmrg df_live_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
134810d565efSmrg 		    void *vbb_info)
134910d565efSmrg {
1350*ec02198aSmrg   class df_live_bb_info *bb_info = (class df_live_bb_info *) vbb_info;
135110d565efSmrg   if (bb_info)
135210d565efSmrg     {
135310d565efSmrg       bitmap_clear (&bb_info->gen);
135410d565efSmrg       bitmap_clear (&bb_info->kill);
135510d565efSmrg       bitmap_clear (&bb_info->in);
135610d565efSmrg       bitmap_clear (&bb_info->out);
135710d565efSmrg     }
135810d565efSmrg }
135910d565efSmrg 
136010d565efSmrg 
136110d565efSmrg /* Allocate or reset bitmaps for DF_LIVE blocks. The solution bits are
136210d565efSmrg    not touched unless the block is new.  */
136310d565efSmrg 
136410d565efSmrg static void
df_live_alloc(bitmap all_blocks ATTRIBUTE_UNUSED)136510d565efSmrg df_live_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
136610d565efSmrg {
136710d565efSmrg   unsigned int bb_index;
136810d565efSmrg   bitmap_iterator bi;
136910d565efSmrg   struct df_live_problem_data *problem_data;
137010d565efSmrg 
137110d565efSmrg   if (df_live->problem_data)
137210d565efSmrg     problem_data = (struct df_live_problem_data *) df_live->problem_data;
137310d565efSmrg   else
137410d565efSmrg     {
137510d565efSmrg       problem_data = XNEW (struct df_live_problem_data);
137610d565efSmrg       df_live->problem_data = problem_data;
137710d565efSmrg 
137810d565efSmrg       problem_data->out = NULL;
137910d565efSmrg       problem_data->in = NULL;
138010d565efSmrg       bitmap_obstack_initialize (&problem_data->live_bitmaps);
138110d565efSmrg       bitmap_initialize (&df_live_scratch, &problem_data->live_bitmaps);
138210d565efSmrg     }
138310d565efSmrg 
138410d565efSmrg   df_grow_bb_info (df_live);
138510d565efSmrg 
138610d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (df_live->out_of_date_transfer_functions, 0, bb_index, bi)
138710d565efSmrg     {
1388*ec02198aSmrg       class df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
138910d565efSmrg 
139010d565efSmrg       /* When bitmaps are already initialized, just clear them.  */
139110d565efSmrg       if (bb_info->kill.obstack)
139210d565efSmrg 	{
139310d565efSmrg 	  bitmap_clear (&bb_info->kill);
139410d565efSmrg 	  bitmap_clear (&bb_info->gen);
139510d565efSmrg 	}
139610d565efSmrg       else
139710d565efSmrg 	{
139810d565efSmrg 	  bitmap_initialize (&bb_info->kill, &problem_data->live_bitmaps);
139910d565efSmrg 	  bitmap_initialize (&bb_info->gen, &problem_data->live_bitmaps);
140010d565efSmrg 	  bitmap_initialize (&bb_info->in, &problem_data->live_bitmaps);
140110d565efSmrg 	  bitmap_initialize (&bb_info->out, &problem_data->live_bitmaps);
140210d565efSmrg 	}
140310d565efSmrg     }
140410d565efSmrg   df_live->optional_p = (optimize <= 1);
140510d565efSmrg }
140610d565efSmrg 
140710d565efSmrg 
140810d565efSmrg /* Reset the global solution for recalculation.  */
140910d565efSmrg 
141010d565efSmrg static void
df_live_reset(bitmap all_blocks)141110d565efSmrg df_live_reset (bitmap all_blocks)
141210d565efSmrg {
141310d565efSmrg   unsigned int bb_index;
141410d565efSmrg   bitmap_iterator bi;
141510d565efSmrg 
141610d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
141710d565efSmrg     {
1418*ec02198aSmrg       class df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
141910d565efSmrg       gcc_assert (bb_info);
142010d565efSmrg       bitmap_clear (&bb_info->in);
142110d565efSmrg       bitmap_clear (&bb_info->out);
142210d565efSmrg     }
142310d565efSmrg }
142410d565efSmrg 
142510d565efSmrg 
142610d565efSmrg /* Compute local uninitialized register info for basic block BB.  */
142710d565efSmrg 
142810d565efSmrg static void
df_live_bb_local_compute(unsigned int bb_index)142910d565efSmrg df_live_bb_local_compute (unsigned int bb_index)
143010d565efSmrg {
143110d565efSmrg   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
1432*ec02198aSmrg   class df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
143310d565efSmrg   rtx_insn *insn;
143410d565efSmrg   df_ref def;
143510d565efSmrg   int luid = 0;
143610d565efSmrg 
143710d565efSmrg   FOR_BB_INSNS (bb, insn)
143810d565efSmrg     {
143910d565efSmrg       unsigned int uid = INSN_UID (insn);
144010d565efSmrg       struct df_insn_info *insn_info = DF_INSN_UID_GET (uid);
144110d565efSmrg 
144210d565efSmrg       /* Inserting labels does not always trigger the incremental
144310d565efSmrg 	 rescanning.  */
144410d565efSmrg       if (!insn_info)
144510d565efSmrg 	{
144610d565efSmrg 	  gcc_assert (!INSN_P (insn));
144710d565efSmrg 	  insn_info = df_insn_create_insn_record (insn);
144810d565efSmrg 	}
144910d565efSmrg 
145010d565efSmrg       DF_INSN_INFO_LUID (insn_info) = luid;
145110d565efSmrg       if (!INSN_P (insn))
145210d565efSmrg 	continue;
145310d565efSmrg 
145410d565efSmrg       luid++;
145510d565efSmrg       FOR_EACH_INSN_INFO_DEF (def, insn_info)
145610d565efSmrg 	{
145710d565efSmrg 	  unsigned int regno = DF_REF_REGNO (def);
145810d565efSmrg 
145910d565efSmrg 	  if (DF_REF_FLAGS_IS_SET (def,
146010d565efSmrg 				   DF_REF_PARTIAL | DF_REF_CONDITIONAL))
146110d565efSmrg 	    /* All partial or conditional def
146210d565efSmrg 	       seen are included in the gen set. */
146310d565efSmrg 	    bitmap_set_bit (&bb_info->gen, regno);
146410d565efSmrg 	  else if (DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER))
146510d565efSmrg 	    /* Only must clobbers for the entire reg destroy the
146610d565efSmrg 	       value.  */
146710d565efSmrg 	    bitmap_set_bit (&bb_info->kill, regno);
146810d565efSmrg 	  else if (! DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER))
146910d565efSmrg 	    bitmap_set_bit (&bb_info->gen, regno);
147010d565efSmrg 	}
147110d565efSmrg     }
147210d565efSmrg 
147310d565efSmrg   FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
147410d565efSmrg     bitmap_set_bit (&bb_info->gen, DF_REF_REGNO (def));
147510d565efSmrg }
147610d565efSmrg 
147710d565efSmrg 
147810d565efSmrg /* Compute local uninitialized register info.  */
147910d565efSmrg 
148010d565efSmrg static void
df_live_local_compute(bitmap all_blocks ATTRIBUTE_UNUSED)148110d565efSmrg df_live_local_compute (bitmap all_blocks ATTRIBUTE_UNUSED)
148210d565efSmrg {
148310d565efSmrg   unsigned int bb_index;
148410d565efSmrg   bitmap_iterator bi;
148510d565efSmrg 
148610d565efSmrg   df_grow_insn_info ();
148710d565efSmrg 
148810d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (df_live->out_of_date_transfer_functions,
148910d565efSmrg 			    0, bb_index, bi)
149010d565efSmrg     {
149110d565efSmrg       df_live_bb_local_compute (bb_index);
149210d565efSmrg     }
149310d565efSmrg 
149410d565efSmrg   bitmap_clear (df_live->out_of_date_transfer_functions);
149510d565efSmrg }
149610d565efSmrg 
149710d565efSmrg 
149810d565efSmrg /* Initialize the solution vectors.  */
149910d565efSmrg 
150010d565efSmrg static void
df_live_init(bitmap all_blocks)150110d565efSmrg df_live_init (bitmap all_blocks)
150210d565efSmrg {
150310d565efSmrg   unsigned int bb_index;
150410d565efSmrg   bitmap_iterator bi;
150510d565efSmrg 
150610d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
150710d565efSmrg     {
1508*ec02198aSmrg       class df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
1509*ec02198aSmrg       class df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
151010d565efSmrg 
151110d565efSmrg       /* No register may reach a location where it is not used.  Thus
151210d565efSmrg 	 we trim the rr result to the places where it is used.  */
151310d565efSmrg       bitmap_and (&bb_info->out, &bb_info->gen, &bb_lr_info->out);
151410d565efSmrg       bitmap_clear (&bb_info->in);
151510d565efSmrg     }
151610d565efSmrg }
151710d565efSmrg 
151810d565efSmrg /* Forward confluence function that ignores fake edges.  */
151910d565efSmrg 
152010d565efSmrg static bool
df_live_confluence_n(edge e)152110d565efSmrg df_live_confluence_n (edge e)
152210d565efSmrg {
152310d565efSmrg   bitmap op1 = &df_live_get_bb_info (e->dest->index)->in;
152410d565efSmrg   bitmap op2 = &df_live_get_bb_info (e->src->index)->out;
152510d565efSmrg 
152610d565efSmrg   if (e->flags & EDGE_FAKE)
152710d565efSmrg     return false;
152810d565efSmrg 
152910d565efSmrg   return bitmap_ior_into (op1, op2);
153010d565efSmrg }
153110d565efSmrg 
153210d565efSmrg 
153310d565efSmrg /* Transfer function for the forwards may-initialized problem.  */
153410d565efSmrg 
153510d565efSmrg static bool
df_live_transfer_function(int bb_index)153610d565efSmrg df_live_transfer_function (int bb_index)
153710d565efSmrg {
1538*ec02198aSmrg   class df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
1539*ec02198aSmrg   class df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
154010d565efSmrg   bitmap in = &bb_info->in;
154110d565efSmrg   bitmap out = &bb_info->out;
154210d565efSmrg   bitmap gen = &bb_info->gen;
154310d565efSmrg   bitmap kill = &bb_info->kill;
154410d565efSmrg 
154510d565efSmrg   /* We need to use a scratch set here so that the value returned from this
154610d565efSmrg      function invocation properly reflects whether the sets changed in a
154710d565efSmrg      significant way; i.e. not just because the lr set was anded in.  */
154810d565efSmrg   bitmap_and (&df_live_scratch, gen, &bb_lr_info->out);
154910d565efSmrg   /* No register may reach a location where it is not used.  Thus
155010d565efSmrg      we trim the rr result to the places where it is used.  */
155110d565efSmrg   bitmap_and_into (in, &bb_lr_info->in);
155210d565efSmrg 
155310d565efSmrg   return bitmap_ior_and_compl (out, &df_live_scratch, in, kill);
155410d565efSmrg }
155510d565efSmrg 
155610d565efSmrg 
155710d565efSmrg /* And the LR info with the may-initialized registers to produce the LIVE info.  */
155810d565efSmrg 
155910d565efSmrg static void
df_live_finalize(bitmap all_blocks)156010d565efSmrg df_live_finalize (bitmap all_blocks)
156110d565efSmrg {
156210d565efSmrg 
156310d565efSmrg   if (df_live->solutions_dirty)
156410d565efSmrg     {
156510d565efSmrg       bitmap_iterator bi;
156610d565efSmrg       unsigned int bb_index;
156710d565efSmrg 
156810d565efSmrg       EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
156910d565efSmrg 	{
1570*ec02198aSmrg 	  class df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
1571*ec02198aSmrg 	  class df_live_bb_info *bb_live_info = df_live_get_bb_info (bb_index);
157210d565efSmrg 
157310d565efSmrg 	  /* No register may reach a location where it is not used.  Thus
157410d565efSmrg 	     we trim the rr result to the places where it is used.  */
157510d565efSmrg 	  bitmap_and_into (&bb_live_info->in, &bb_lr_info->in);
157610d565efSmrg 	  bitmap_and_into (&bb_live_info->out, &bb_lr_info->out);
157710d565efSmrg 	}
157810d565efSmrg 
157910d565efSmrg       df_live->solutions_dirty = false;
158010d565efSmrg     }
158110d565efSmrg }
158210d565efSmrg 
158310d565efSmrg 
158410d565efSmrg /* Free all storage associated with the problem.  */
158510d565efSmrg 
158610d565efSmrg static void
df_live_free(void)158710d565efSmrg df_live_free (void)
158810d565efSmrg {
158910d565efSmrg   struct df_live_problem_data *problem_data
159010d565efSmrg     = (struct df_live_problem_data *) df_live->problem_data;
159110d565efSmrg   if (df_live->block_info)
159210d565efSmrg     {
159310d565efSmrg       df_live->block_info_size = 0;
159410d565efSmrg       free (df_live->block_info);
159510d565efSmrg       df_live->block_info = NULL;
15960fc04c29Smrg       bitmap_release (&df_live_scratch);
159710d565efSmrg       bitmap_obstack_release (&problem_data->live_bitmaps);
159810d565efSmrg       free (problem_data);
159910d565efSmrg       df_live->problem_data = NULL;
160010d565efSmrg     }
160110d565efSmrg   BITMAP_FREE (df_live->out_of_date_transfer_functions);
160210d565efSmrg   free (df_live);
160310d565efSmrg }
160410d565efSmrg 
160510d565efSmrg 
160610d565efSmrg /* Debugging info at top of bb.  */
160710d565efSmrg 
160810d565efSmrg static void
df_live_top_dump(basic_block bb,FILE * file)160910d565efSmrg df_live_top_dump (basic_block bb, FILE *file)
161010d565efSmrg {
1611*ec02198aSmrg   class df_live_bb_info *bb_info = df_live_get_bb_info (bb->index);
161210d565efSmrg   struct df_live_problem_data *problem_data;
161310d565efSmrg 
161410d565efSmrg   if (!bb_info)
161510d565efSmrg     return;
161610d565efSmrg 
161710d565efSmrg   fprintf (file, ";; live  in  \t");
161810d565efSmrg   df_print_regset (file, &bb_info->in);
161910d565efSmrg   if (df_live->problem_data)
162010d565efSmrg     {
162110d565efSmrg       problem_data = (struct df_live_problem_data *)df_live->problem_data;
162210d565efSmrg       if (problem_data->in)
162310d565efSmrg 	{
162410d565efSmrg 	  fprintf (file, ";;  old in  \t");
162510d565efSmrg 	  df_print_regset (file, &problem_data->in[bb->index]);
162610d565efSmrg 	}
162710d565efSmrg     }
162810d565efSmrg   fprintf (file, ";; live  gen \t");
162910d565efSmrg   df_print_regset (file, &bb_info->gen);
163010d565efSmrg   fprintf (file, ";; live  kill\t");
163110d565efSmrg   df_print_regset (file, &bb_info->kill);
163210d565efSmrg }
163310d565efSmrg 
163410d565efSmrg 
163510d565efSmrg /* Debugging info at bottom of bb.  */
163610d565efSmrg 
163710d565efSmrg static void
df_live_bottom_dump(basic_block bb,FILE * file)163810d565efSmrg df_live_bottom_dump (basic_block bb, FILE *file)
163910d565efSmrg {
1640*ec02198aSmrg   class df_live_bb_info *bb_info = df_live_get_bb_info (bb->index);
164110d565efSmrg   struct df_live_problem_data *problem_data;
164210d565efSmrg 
164310d565efSmrg   if (!bb_info)
164410d565efSmrg     return;
164510d565efSmrg 
164610d565efSmrg   fprintf (file, ";; live  out \t");
164710d565efSmrg   df_print_regset (file, &bb_info->out);
164810d565efSmrg   if (df_live->problem_data)
164910d565efSmrg     {
165010d565efSmrg       problem_data = (struct df_live_problem_data *)df_live->problem_data;
165110d565efSmrg       if (problem_data->out)
165210d565efSmrg 	{
165310d565efSmrg 	  fprintf (file, ";;  old out  \t");
165410d565efSmrg 	  df_print_regset (file, &problem_data->out[bb->index]);
165510d565efSmrg 	}
165610d565efSmrg     }
165710d565efSmrg }
165810d565efSmrg 
165910d565efSmrg 
166010d565efSmrg /* Build the datastructure to verify that the solution to the dataflow
166110d565efSmrg    equations is not dirty.  */
166210d565efSmrg 
166310d565efSmrg static void
df_live_verify_solution_start(void)166410d565efSmrg df_live_verify_solution_start (void)
166510d565efSmrg {
166610d565efSmrg   basic_block bb;
166710d565efSmrg   struct df_live_problem_data *problem_data;
166810d565efSmrg   if (df_live->solutions_dirty)
166910d565efSmrg     return;
167010d565efSmrg 
167110d565efSmrg   /* Set it true so that the solution is recomputed.  */
167210d565efSmrg   df_live->solutions_dirty = true;
167310d565efSmrg 
167410d565efSmrg   problem_data = (struct df_live_problem_data *)df_live->problem_data;
167510d565efSmrg   problem_data->in = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
167610d565efSmrg   problem_data->out = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
167710d565efSmrg 
167810d565efSmrg   FOR_ALL_BB_FN (bb, cfun)
167910d565efSmrg     {
168010d565efSmrg       bitmap_initialize (&problem_data->in[bb->index], &problem_data->live_bitmaps);
168110d565efSmrg       bitmap_initialize (&problem_data->out[bb->index], &problem_data->live_bitmaps);
168210d565efSmrg       bitmap_copy (&problem_data->in[bb->index], DF_LIVE_IN (bb));
168310d565efSmrg       bitmap_copy (&problem_data->out[bb->index], DF_LIVE_OUT (bb));
168410d565efSmrg     }
168510d565efSmrg }
168610d565efSmrg 
168710d565efSmrg 
168810d565efSmrg /* Compare the saved datastructure and the new solution to the dataflow
168910d565efSmrg    equations.  */
169010d565efSmrg 
169110d565efSmrg static void
df_live_verify_solution_end(void)169210d565efSmrg df_live_verify_solution_end (void)
169310d565efSmrg {
169410d565efSmrg   struct df_live_problem_data *problem_data;
169510d565efSmrg   basic_block bb;
169610d565efSmrg 
169710d565efSmrg   problem_data = (struct df_live_problem_data *)df_live->problem_data;
169810d565efSmrg   if (!problem_data->out)
169910d565efSmrg     return;
170010d565efSmrg 
170110d565efSmrg   FOR_ALL_BB_FN (bb, cfun)
170210d565efSmrg     {
170310d565efSmrg       if ((!bitmap_equal_p (&problem_data->in[bb->index], DF_LIVE_IN (bb)))
170410d565efSmrg 	  || (!bitmap_equal_p (&problem_data->out[bb->index], DF_LIVE_OUT (bb))))
170510d565efSmrg 	{
170610d565efSmrg 	  /*df_dump (stderr);*/
170710d565efSmrg 	  gcc_unreachable ();
170810d565efSmrg 	}
170910d565efSmrg     }
171010d565efSmrg 
171110d565efSmrg   /* Cannot delete them immediately because you may want to dump them
171210d565efSmrg      if the comparison fails.  */
171310d565efSmrg   FOR_ALL_BB_FN (bb, cfun)
171410d565efSmrg     {
171510d565efSmrg       bitmap_clear (&problem_data->in[bb->index]);
171610d565efSmrg       bitmap_clear (&problem_data->out[bb->index]);
171710d565efSmrg     }
171810d565efSmrg 
171910d565efSmrg   free (problem_data->in);
172010d565efSmrg   free (problem_data->out);
172110d565efSmrg   free (problem_data);
172210d565efSmrg   df_live->problem_data = NULL;
172310d565efSmrg }
172410d565efSmrg 
172510d565efSmrg 
172610d565efSmrg /* All of the information associated with every instance of the problem.  */
172710d565efSmrg 
172810d565efSmrg static const struct df_problem problem_LIVE =
172910d565efSmrg {
173010d565efSmrg   DF_LIVE,                      /* Problem id.  */
173110d565efSmrg   DF_FORWARD,                   /* Direction.  */
173210d565efSmrg   df_live_alloc,                /* Allocate the problem specific data.  */
173310d565efSmrg   df_live_reset,                /* Reset global information.  */
173410d565efSmrg   df_live_free_bb_info,         /* Free basic block info.  */
173510d565efSmrg   df_live_local_compute,        /* Local compute function.  */
173610d565efSmrg   df_live_init,                 /* Init the solution specific data.  */
173710d565efSmrg   df_worklist_dataflow,         /* Worklist solver.  */
173810d565efSmrg   NULL,                         /* Confluence operator 0.  */
173910d565efSmrg   df_live_confluence_n,         /* Confluence operator n.  */
174010d565efSmrg   df_live_transfer_function,    /* Transfer function.  */
174110d565efSmrg   df_live_finalize,             /* Finalize function.  */
174210d565efSmrg   df_live_free,                 /* Free all of the problem information.  */
174310d565efSmrg   df_live_free,                 /* Remove this problem from the stack of dataflow problems.  */
174410d565efSmrg   NULL,                         /* Debugging.  */
174510d565efSmrg   df_live_top_dump,             /* Debugging start block.  */
174610d565efSmrg   df_live_bottom_dump,          /* Debugging end block.  */
174710d565efSmrg   NULL,                         /* Debugging start insn.  */
174810d565efSmrg   NULL,                         /* Debugging end insn.  */
174910d565efSmrg   df_live_verify_solution_start,/* Incremental solution verify start.  */
175010d565efSmrg   df_live_verify_solution_end,  /* Incremental solution verify end.  */
175110d565efSmrg   &problem_LR,                  /* Dependent problem.  */
1752*ec02198aSmrg   sizeof (class df_live_bb_info),/* Size of entry of block_info array.  */
175310d565efSmrg   TV_DF_LIVE,                   /* Timing variable.  */
175410d565efSmrg   false                         /* Reset blocks on dropping out of blocks_to_analyze.  */
175510d565efSmrg };
175610d565efSmrg 
175710d565efSmrg 
175810d565efSmrg /* Create a new DATAFLOW instance and add it to an existing instance
175910d565efSmrg    of DF.  The returned structure is what is used to get at the
176010d565efSmrg    solution.  */
176110d565efSmrg 
176210d565efSmrg void
df_live_add_problem(void)176310d565efSmrg df_live_add_problem (void)
176410d565efSmrg {
176510d565efSmrg   df_add_problem (&problem_LIVE);
176610d565efSmrg   /* These will be initialized when df_scan_blocks processes each
176710d565efSmrg      block.  */
176810d565efSmrg   df_live->out_of_date_transfer_functions = BITMAP_ALLOC (&df_bitmap_obstack);
176910d565efSmrg }
177010d565efSmrg 
177110d565efSmrg 
177210d565efSmrg /* Set all of the blocks as dirty.  This needs to be done if this
177310d565efSmrg    problem is added after all of the insns have been scanned.  */
177410d565efSmrg 
177510d565efSmrg void
df_live_set_all_dirty(void)177610d565efSmrg df_live_set_all_dirty (void)
177710d565efSmrg {
177810d565efSmrg   basic_block bb;
177910d565efSmrg   FOR_ALL_BB_FN (bb, cfun)
178010d565efSmrg     bitmap_set_bit (df_live->out_of_date_transfer_functions,
178110d565efSmrg 		    bb->index);
178210d565efSmrg }
178310d565efSmrg 
178410d565efSmrg 
178510d565efSmrg /* Verify that all of the lr related info is consistent and
178610d565efSmrg    correct.  */
178710d565efSmrg 
178810d565efSmrg void
df_live_verify_transfer_functions(void)178910d565efSmrg df_live_verify_transfer_functions (void)
179010d565efSmrg {
179110d565efSmrg   basic_block bb;
179210d565efSmrg   bitmap_head saved_gen;
179310d565efSmrg   bitmap_head saved_kill;
179410d565efSmrg   bitmap_head all_blocks;
179510d565efSmrg 
179610d565efSmrg   if (!df)
179710d565efSmrg     return;
179810d565efSmrg 
179910d565efSmrg   bitmap_initialize (&saved_gen, &bitmap_default_obstack);
180010d565efSmrg   bitmap_initialize (&saved_kill, &bitmap_default_obstack);
180110d565efSmrg   bitmap_initialize (&all_blocks, &bitmap_default_obstack);
180210d565efSmrg 
180310d565efSmrg   df_grow_insn_info ();
180410d565efSmrg 
180510d565efSmrg   FOR_ALL_BB_FN (bb, cfun)
180610d565efSmrg     {
1807*ec02198aSmrg       class df_live_bb_info *bb_info = df_live_get_bb_info (bb->index);
180810d565efSmrg       bitmap_set_bit (&all_blocks, bb->index);
180910d565efSmrg 
181010d565efSmrg       if (bb_info)
181110d565efSmrg 	{
181210d565efSmrg 	  /* Make a copy of the transfer functions and then compute
181310d565efSmrg 	     new ones to see if the transfer functions have
181410d565efSmrg 	     changed.  */
181510d565efSmrg 	  if (!bitmap_bit_p (df_live->out_of_date_transfer_functions,
181610d565efSmrg 			     bb->index))
181710d565efSmrg 	    {
181810d565efSmrg 	      bitmap_copy (&saved_gen, &bb_info->gen);
181910d565efSmrg 	      bitmap_copy (&saved_kill, &bb_info->kill);
182010d565efSmrg 	      bitmap_clear (&bb_info->gen);
182110d565efSmrg 	      bitmap_clear (&bb_info->kill);
182210d565efSmrg 
182310d565efSmrg 	      df_live_bb_local_compute (bb->index);
182410d565efSmrg 	      gcc_assert (bitmap_equal_p (&saved_gen, &bb_info->gen));
182510d565efSmrg 	      gcc_assert (bitmap_equal_p (&saved_kill, &bb_info->kill));
182610d565efSmrg 	    }
182710d565efSmrg 	}
182810d565efSmrg       else
182910d565efSmrg 	{
183010d565efSmrg 	  /* If we do not have basic block info, the block must be in
183110d565efSmrg 	     the list of dirty blocks or else some one has added a
183210d565efSmrg 	     block behind our backs. */
183310d565efSmrg 	  gcc_assert (bitmap_bit_p (df_live->out_of_date_transfer_functions,
183410d565efSmrg 				    bb->index));
183510d565efSmrg 	}
183610d565efSmrg       /* Make sure no one created a block without following
183710d565efSmrg 	 procedures.  */
183810d565efSmrg       gcc_assert (df_scan_get_bb_info (bb->index));
183910d565efSmrg     }
184010d565efSmrg 
184110d565efSmrg   /* Make sure there are no dirty bits in blocks that have been deleted.  */
184210d565efSmrg   gcc_assert (!bitmap_intersect_compl_p (df_live->out_of_date_transfer_functions,
184310d565efSmrg 					 &all_blocks));
184410d565efSmrg   bitmap_clear (&saved_gen);
184510d565efSmrg   bitmap_clear (&saved_kill);
184610d565efSmrg   bitmap_clear (&all_blocks);
184710d565efSmrg }
184810d565efSmrg 
184910d565efSmrg /*----------------------------------------------------------------------------
185010d565efSmrg    MUST-INITIALIZED REGISTERS.
185110d565efSmrg ----------------------------------------------------------------------------*/
185210d565efSmrg 
185310d565efSmrg /* Private data used to verify the solution for this problem.  */
185410d565efSmrg struct df_mir_problem_data
185510d565efSmrg {
185610d565efSmrg   bitmap_head *in;
185710d565efSmrg   bitmap_head *out;
185810d565efSmrg   /* An obstack for the bitmaps we need for this problem.  */
185910d565efSmrg   bitmap_obstack mir_bitmaps;
186010d565efSmrg };
186110d565efSmrg 
186210d565efSmrg 
186310d565efSmrg /* Free basic block info.  */
186410d565efSmrg 
186510d565efSmrg static void
df_mir_free_bb_info(basic_block bb ATTRIBUTE_UNUSED,void * vbb_info)186610d565efSmrg df_mir_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
186710d565efSmrg 		     void *vbb_info)
186810d565efSmrg {
1869*ec02198aSmrg   class df_mir_bb_info *bb_info = (class df_mir_bb_info *) vbb_info;
187010d565efSmrg   if (bb_info)
187110d565efSmrg     {
187210d565efSmrg       bitmap_clear (&bb_info->gen);
187310d565efSmrg       bitmap_clear (&bb_info->kill);
187410d565efSmrg       bitmap_clear (&bb_info->in);
187510d565efSmrg       bitmap_clear (&bb_info->out);
187610d565efSmrg     }
187710d565efSmrg }
187810d565efSmrg 
187910d565efSmrg 
188010d565efSmrg /* Allocate or reset bitmaps for DF_MIR blocks. The solution bits are
188110d565efSmrg    not touched unless the block is new.  */
188210d565efSmrg 
188310d565efSmrg static void
df_mir_alloc(bitmap all_blocks)188410d565efSmrg df_mir_alloc (bitmap all_blocks)
188510d565efSmrg {
188610d565efSmrg   unsigned int bb_index;
188710d565efSmrg   bitmap_iterator bi;
188810d565efSmrg   struct df_mir_problem_data *problem_data;
188910d565efSmrg 
189010d565efSmrg   if (df_mir->problem_data)
189110d565efSmrg     problem_data = (struct df_mir_problem_data *) df_mir->problem_data;
189210d565efSmrg   else
189310d565efSmrg     {
189410d565efSmrg       problem_data = XNEW (struct df_mir_problem_data);
189510d565efSmrg       df_mir->problem_data = problem_data;
189610d565efSmrg 
189710d565efSmrg       problem_data->out = NULL;
189810d565efSmrg       problem_data->in = NULL;
189910d565efSmrg       bitmap_obstack_initialize (&problem_data->mir_bitmaps);
190010d565efSmrg     }
190110d565efSmrg 
190210d565efSmrg   df_grow_bb_info (df_mir);
190310d565efSmrg 
190410d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
190510d565efSmrg     {
1906*ec02198aSmrg       class df_mir_bb_info *bb_info = df_mir_get_bb_info (bb_index);
190710d565efSmrg 
190810d565efSmrg       /* When bitmaps are already initialized, just clear them.  */
190910d565efSmrg       if (bb_info->kill.obstack)
191010d565efSmrg 	{
191110d565efSmrg 	  bitmap_clear (&bb_info->kill);
191210d565efSmrg 	  bitmap_clear (&bb_info->gen);
191310d565efSmrg 	}
191410d565efSmrg       else
191510d565efSmrg 	{
191610d565efSmrg 	  bitmap_initialize (&bb_info->kill, &problem_data->mir_bitmaps);
191710d565efSmrg 	  bitmap_initialize (&bb_info->gen, &problem_data->mir_bitmaps);
191810d565efSmrg 	  bitmap_initialize (&bb_info->in, &problem_data->mir_bitmaps);
191910d565efSmrg 	  bitmap_initialize (&bb_info->out, &problem_data->mir_bitmaps);
1920*ec02198aSmrg 	  bb_info->con_visited = false;
192110d565efSmrg 	}
192210d565efSmrg     }
192310d565efSmrg 
192410d565efSmrg   df_mir->optional_p = 1;
192510d565efSmrg }
192610d565efSmrg 
192710d565efSmrg 
192810d565efSmrg /* Reset the global solution for recalculation.  */
192910d565efSmrg 
193010d565efSmrg static void
df_mir_reset(bitmap all_blocks)193110d565efSmrg df_mir_reset (bitmap all_blocks)
193210d565efSmrg {
193310d565efSmrg   unsigned int bb_index;
193410d565efSmrg   bitmap_iterator bi;
193510d565efSmrg 
193610d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
193710d565efSmrg     {
1938*ec02198aSmrg       class df_mir_bb_info *bb_info = df_mir_get_bb_info (bb_index);
193910d565efSmrg 
194010d565efSmrg       gcc_assert (bb_info);
194110d565efSmrg 
194210d565efSmrg       bitmap_clear (&bb_info->in);
194310d565efSmrg       bitmap_clear (&bb_info->out);
1944*ec02198aSmrg       bb_info->con_visited = false;
194510d565efSmrg     }
194610d565efSmrg }
194710d565efSmrg 
194810d565efSmrg 
194910d565efSmrg /* Compute local uninitialized register info for basic block BB.  */
195010d565efSmrg 
195110d565efSmrg static void
df_mir_bb_local_compute(unsigned int bb_index)195210d565efSmrg df_mir_bb_local_compute (unsigned int bb_index)
195310d565efSmrg {
195410d565efSmrg   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
1955*ec02198aSmrg   class df_mir_bb_info *bb_info = df_mir_get_bb_info (bb_index);
195610d565efSmrg   rtx_insn *insn;
195710d565efSmrg   int luid = 0;
195810d565efSmrg 
195910d565efSmrg   /* Ignoring artificial defs is intentional: these often pretend that some
196010d565efSmrg      registers carry incoming arguments (when they are FUNCTION_ARG_REGNO) even
196110d565efSmrg      though they are not used for that.  As a result, conservatively assume
196210d565efSmrg      they may be uninitialized.  */
196310d565efSmrg 
196410d565efSmrg   FOR_BB_INSNS (bb, insn)
196510d565efSmrg     {
196610d565efSmrg       unsigned int uid = INSN_UID (insn);
196710d565efSmrg       struct df_insn_info *insn_info = DF_INSN_UID_GET (uid);
196810d565efSmrg 
196910d565efSmrg       /* Inserting labels does not always trigger the incremental
197010d565efSmrg 	 rescanning.  */
197110d565efSmrg       if (!insn_info)
197210d565efSmrg 	{
197310d565efSmrg 	  gcc_assert (!INSN_P (insn));
197410d565efSmrg 	  insn_info = df_insn_create_insn_record (insn);
197510d565efSmrg 	}
197610d565efSmrg 
197710d565efSmrg       DF_INSN_INFO_LUID (insn_info) = luid;
197810d565efSmrg       if (!INSN_P (insn))
197910d565efSmrg 	continue;
198010d565efSmrg 
198110d565efSmrg       luid++;
198210d565efSmrg       df_mir_simulate_one_insn (bb, insn, &bb_info->kill, &bb_info->gen);
198310d565efSmrg     }
198410d565efSmrg }
198510d565efSmrg 
198610d565efSmrg 
198710d565efSmrg /* Compute local uninitialized register info.  */
198810d565efSmrg 
198910d565efSmrg static void
df_mir_local_compute(bitmap all_blocks)199010d565efSmrg df_mir_local_compute (bitmap all_blocks)
199110d565efSmrg {
199210d565efSmrg   unsigned int bb_index;
199310d565efSmrg   bitmap_iterator bi;
199410d565efSmrg 
199510d565efSmrg   df_grow_insn_info ();
199610d565efSmrg 
199710d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
199810d565efSmrg     {
199910d565efSmrg       df_mir_bb_local_compute (bb_index);
200010d565efSmrg     }
200110d565efSmrg }
200210d565efSmrg 
200310d565efSmrg 
200410d565efSmrg /* Initialize the solution vectors.  */
200510d565efSmrg 
200610d565efSmrg static void
df_mir_init(bitmap all_blocks)200710d565efSmrg df_mir_init (bitmap all_blocks)
200810d565efSmrg {
200910d565efSmrg   df_mir_reset (all_blocks);
201010d565efSmrg }
201110d565efSmrg 
201210d565efSmrg 
201310d565efSmrg /* Initialize IN sets for blocks with no predecessors: when landing on such
201410d565efSmrg    blocks, assume all registers are uninitialized.  */
201510d565efSmrg 
201610d565efSmrg static void
df_mir_confluence_0(basic_block bb)201710d565efSmrg df_mir_confluence_0 (basic_block bb)
201810d565efSmrg {
2019*ec02198aSmrg   class df_mir_bb_info *bb_info = df_mir_get_bb_info (bb->index);
202010d565efSmrg 
202110d565efSmrg   bitmap_clear (&bb_info->in);
2022*ec02198aSmrg   bb_info->con_visited = true;
202310d565efSmrg }
202410d565efSmrg 
202510d565efSmrg 
202610d565efSmrg /* Forward confluence function that ignores fake edges.  */
202710d565efSmrg 
202810d565efSmrg static bool
df_mir_confluence_n(edge e)202910d565efSmrg df_mir_confluence_n (edge e)
203010d565efSmrg {
203110d565efSmrg   if (e->flags & EDGE_FAKE)
203210d565efSmrg     return false;
203310d565efSmrg 
2034*ec02198aSmrg   df_mir_bb_info *src_info = df_mir_get_bb_info (e->src->index);
2035*ec02198aSmrg   /* If SRC was not visited yet then we'll and with all-ones which
2036*ec02198aSmrg      means no changes.  Do not consider DST con_visited by this
2037*ec02198aSmrg      operation alone either.  */
2038*ec02198aSmrg   if (!src_info->con_visited)
2039*ec02198aSmrg     return false;
2040*ec02198aSmrg 
2041*ec02198aSmrg   df_mir_bb_info *dst_info = df_mir_get_bb_info (e->dest->index);
2042*ec02198aSmrg   bitmap op1 = &dst_info->in;
2043*ec02198aSmrg   bitmap op2 = &src_info->out;
2044*ec02198aSmrg   /* If DEST was not visited yet just copy the SRC bitmap.  */
2045*ec02198aSmrg   if (!dst_info->con_visited)
2046*ec02198aSmrg     {
2047*ec02198aSmrg       dst_info->con_visited = true;
2048*ec02198aSmrg       bitmap_copy (op1, op2);
2049*ec02198aSmrg       return true;
2050*ec02198aSmrg     }
2051*ec02198aSmrg 
205210d565efSmrg   /* A register is must-initialized at the entry of a basic block iff it is
205310d565efSmrg      must-initialized at the exit of all the predecessors.  */
205410d565efSmrg   return bitmap_and_into (op1, op2);
205510d565efSmrg }
205610d565efSmrg 
205710d565efSmrg 
205810d565efSmrg /* Transfer function for the forwards must-initialized problem.  */
205910d565efSmrg 
206010d565efSmrg static bool
df_mir_transfer_function(int bb_index)206110d565efSmrg df_mir_transfer_function (int bb_index)
206210d565efSmrg {
2063*ec02198aSmrg   class df_mir_bb_info *bb_info = df_mir_get_bb_info (bb_index);
206410d565efSmrg   bitmap in = &bb_info->in;
206510d565efSmrg   bitmap out = &bb_info->out;
206610d565efSmrg   bitmap gen = &bb_info->gen;
206710d565efSmrg   bitmap kill = &bb_info->kill;
206810d565efSmrg 
206910d565efSmrg   return bitmap_ior_and_compl (out, gen, in, kill);
207010d565efSmrg }
207110d565efSmrg 
207210d565efSmrg 
207310d565efSmrg /* Free all storage associated with the problem.  */
207410d565efSmrg 
207510d565efSmrg static void
df_mir_free(void)207610d565efSmrg df_mir_free (void)
207710d565efSmrg {
207810d565efSmrg   struct df_mir_problem_data *problem_data
207910d565efSmrg     = (struct df_mir_problem_data *) df_mir->problem_data;
208010d565efSmrg   if (df_mir->block_info)
208110d565efSmrg     {
208210d565efSmrg       df_mir->block_info_size = 0;
208310d565efSmrg       free (df_mir->block_info);
208410d565efSmrg       df_mir->block_info = NULL;
208510d565efSmrg       bitmap_obstack_release (&problem_data->mir_bitmaps);
208610d565efSmrg       free (problem_data);
208710d565efSmrg       df_mir->problem_data = NULL;
208810d565efSmrg     }
208910d565efSmrg   free (df_mir);
209010d565efSmrg }
209110d565efSmrg 
209210d565efSmrg 
209310d565efSmrg /* Debugging info at top of bb.  */
209410d565efSmrg 
209510d565efSmrg static void
df_mir_top_dump(basic_block bb,FILE * file)209610d565efSmrg df_mir_top_dump (basic_block bb, FILE *file)
209710d565efSmrg {
2098*ec02198aSmrg   class df_mir_bb_info *bb_info = df_mir_get_bb_info (bb->index);
209910d565efSmrg 
210010d565efSmrg   if (!bb_info)
210110d565efSmrg     return;
210210d565efSmrg 
210310d565efSmrg   fprintf (file, ";; mir   in  \t");
210410d565efSmrg   df_print_regset (file, &bb_info->in);
210510d565efSmrg   fprintf (file, ";; mir   kill\t");
210610d565efSmrg   df_print_regset (file, &bb_info->kill);
210710d565efSmrg   fprintf (file, ";; mir   gen \t");
210810d565efSmrg   df_print_regset (file, &bb_info->gen);
210910d565efSmrg }
211010d565efSmrg 
211110d565efSmrg /* Debugging info at bottom of bb.  */
211210d565efSmrg 
211310d565efSmrg static void
df_mir_bottom_dump(basic_block bb,FILE * file)211410d565efSmrg df_mir_bottom_dump (basic_block bb, FILE *file)
211510d565efSmrg {
2116*ec02198aSmrg   class df_mir_bb_info *bb_info = df_mir_get_bb_info (bb->index);
211710d565efSmrg 
211810d565efSmrg   if (!bb_info)
211910d565efSmrg     return;
212010d565efSmrg 
212110d565efSmrg   fprintf (file, ";; mir   out \t");
212210d565efSmrg   df_print_regset (file, &bb_info->out);
212310d565efSmrg }
212410d565efSmrg 
212510d565efSmrg 
212610d565efSmrg /* Build the datastructure to verify that the solution to the dataflow
212710d565efSmrg    equations is not dirty.  */
212810d565efSmrg 
212910d565efSmrg static void
df_mir_verify_solution_start(void)213010d565efSmrg df_mir_verify_solution_start (void)
213110d565efSmrg {
213210d565efSmrg   basic_block bb;
213310d565efSmrg   struct df_mir_problem_data *problem_data;
213410d565efSmrg   if (df_mir->solutions_dirty)
213510d565efSmrg     return;
213610d565efSmrg 
213710d565efSmrg   /* Set it true so that the solution is recomputed.  */
213810d565efSmrg   df_mir->solutions_dirty = true;
213910d565efSmrg 
214010d565efSmrg   problem_data = (struct df_mir_problem_data *) df_mir->problem_data;
214110d565efSmrg   problem_data->in = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
214210d565efSmrg   problem_data->out = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
214310d565efSmrg   bitmap_obstack_initialize (&problem_data->mir_bitmaps);
214410d565efSmrg 
214510d565efSmrg   FOR_ALL_BB_FN (bb, cfun)
214610d565efSmrg     {
214710d565efSmrg       bitmap_initialize (&problem_data->in[bb->index], &problem_data->mir_bitmaps);
214810d565efSmrg       bitmap_initialize (&problem_data->out[bb->index], &problem_data->mir_bitmaps);
214910d565efSmrg       bitmap_copy (&problem_data->in[bb->index], DF_MIR_IN (bb));
215010d565efSmrg       bitmap_copy (&problem_data->out[bb->index], DF_MIR_OUT (bb));
215110d565efSmrg     }
215210d565efSmrg }
215310d565efSmrg 
215410d565efSmrg 
215510d565efSmrg /* Compare the saved datastructure and the new solution to the dataflow
215610d565efSmrg    equations.  */
215710d565efSmrg 
215810d565efSmrg static void
df_mir_verify_solution_end(void)215910d565efSmrg df_mir_verify_solution_end (void)
216010d565efSmrg {
216110d565efSmrg   struct df_mir_problem_data *problem_data;
216210d565efSmrg   basic_block bb;
216310d565efSmrg 
216410d565efSmrg   problem_data = (struct df_mir_problem_data *) df_mir->problem_data;
216510d565efSmrg   if (!problem_data->out)
216610d565efSmrg     return;
216710d565efSmrg 
216810d565efSmrg   FOR_ALL_BB_FN (bb, cfun)
216910d565efSmrg     {
217010d565efSmrg       if ((!bitmap_equal_p (&problem_data->in[bb->index], DF_MIR_IN (bb)))
217110d565efSmrg 	  || (!bitmap_equal_p (&problem_data->out[bb->index], DF_MIR_OUT (bb))))
217210d565efSmrg 	gcc_unreachable ();
217310d565efSmrg     }
217410d565efSmrg 
217510d565efSmrg   /* Cannot delete them immediately because you may want to dump them
217610d565efSmrg      if the comparison fails.  */
217710d565efSmrg   FOR_ALL_BB_FN (bb, cfun)
217810d565efSmrg     {
217910d565efSmrg       bitmap_clear (&problem_data->in[bb->index]);
218010d565efSmrg       bitmap_clear (&problem_data->out[bb->index]);
218110d565efSmrg     }
218210d565efSmrg 
218310d565efSmrg   free (problem_data->in);
218410d565efSmrg   free (problem_data->out);
218510d565efSmrg   bitmap_obstack_release (&problem_data->mir_bitmaps);
218610d565efSmrg   free (problem_data);
218710d565efSmrg   df_mir->problem_data = NULL;
218810d565efSmrg }
218910d565efSmrg 
219010d565efSmrg 
219110d565efSmrg /* All of the information associated with every instance of the problem.  */
219210d565efSmrg 
219310d565efSmrg static const struct df_problem problem_MIR =
219410d565efSmrg {
219510d565efSmrg   DF_MIR,                       /* Problem id.  */
219610d565efSmrg   DF_FORWARD,                   /* Direction.  */
219710d565efSmrg   df_mir_alloc,                 /* Allocate the problem specific data.  */
219810d565efSmrg   df_mir_reset,                 /* Reset global information.  */
219910d565efSmrg   df_mir_free_bb_info,          /* Free basic block info.  */
220010d565efSmrg   df_mir_local_compute,         /* Local compute function.  */
220110d565efSmrg   df_mir_init,                  /* Init the solution specific data.  */
220210d565efSmrg   df_worklist_dataflow,         /* Worklist solver.  */
220310d565efSmrg   df_mir_confluence_0,          /* Confluence operator 0.  */
220410d565efSmrg   df_mir_confluence_n,          /* Confluence operator n.  */
220510d565efSmrg   df_mir_transfer_function,     /* Transfer function.  */
220610d565efSmrg   NULL,                         /* Finalize function.  */
220710d565efSmrg   df_mir_free,                  /* Free all of the problem information.  */
220810d565efSmrg   df_mir_free,                  /* Remove this problem from the stack of dataflow problems.  */
220910d565efSmrg   NULL,                         /* Debugging.  */
221010d565efSmrg   df_mir_top_dump,              /* Debugging start block.  */
221110d565efSmrg   df_mir_bottom_dump,           /* Debugging end block.  */
221210d565efSmrg   NULL,                         /* Debugging start insn.  */
221310d565efSmrg   NULL,                         /* Debugging end insn.  */
221410d565efSmrg   df_mir_verify_solution_start, /* Incremental solution verify start.  */
221510d565efSmrg   df_mir_verify_solution_end,   /* Incremental solution verify end.  */
221610d565efSmrg   NULL,                         /* Dependent problem.  */
2217*ec02198aSmrg   sizeof (class df_mir_bb_info),/* Size of entry of block_info array.  */
221810d565efSmrg   TV_DF_MIR,                    /* Timing variable.  */
221910d565efSmrg   false                         /* Reset blocks on dropping out of blocks_to_analyze.  */
222010d565efSmrg };
222110d565efSmrg 
222210d565efSmrg 
222310d565efSmrg /* Create a new DATAFLOW instance and add it to an existing instance
222410d565efSmrg    of DF.  */
222510d565efSmrg 
222610d565efSmrg void
df_mir_add_problem(void)222710d565efSmrg df_mir_add_problem (void)
222810d565efSmrg {
222910d565efSmrg   df_add_problem (&problem_MIR);
223010d565efSmrg   /* These will be initialized when df_scan_blocks processes each
223110d565efSmrg      block.  */
223210d565efSmrg   df_mir->out_of_date_transfer_functions = BITMAP_ALLOC (&df_bitmap_obstack);
223310d565efSmrg }
223410d565efSmrg 
223510d565efSmrg 
223610d565efSmrg /* Apply the effects of the gen/kills in INSN to the corresponding bitmaps.  */
223710d565efSmrg 
223810d565efSmrg void
df_mir_simulate_one_insn(basic_block bb ATTRIBUTE_UNUSED,rtx_insn * insn,bitmap kill,bitmap gen)223910d565efSmrg df_mir_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx_insn *insn,
224010d565efSmrg 			  bitmap kill, bitmap gen)
224110d565efSmrg {
224210d565efSmrg   df_ref def;
224310d565efSmrg 
224410d565efSmrg   FOR_EACH_INSN_DEF (def, insn)
224510d565efSmrg     {
224610d565efSmrg       unsigned int regno = DF_REF_REGNO (def);
224710d565efSmrg 
224810d565efSmrg       /* The order of GENs/KILLs matters, so if this def clobbers a reg, any
224910d565efSmrg 	 previous gen is irrelevant (and reciprocally).  Also, claim that a
225010d565efSmrg 	 register is GEN only if it is in all cases.  */
225110d565efSmrg       if (DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))
225210d565efSmrg 	{
225310d565efSmrg 	  bitmap_set_bit (kill, regno);
225410d565efSmrg 	  bitmap_clear_bit (gen, regno);
225510d565efSmrg 	}
225610d565efSmrg       /* In the worst case, partial and conditional defs can leave bits
225710d565efSmrg 	 uninitialized, so assume they do not change anything.  */
225810d565efSmrg       else if (!DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL | DF_REF_CONDITIONAL))
225910d565efSmrg 	{
226010d565efSmrg 	  bitmap_set_bit (gen, regno);
226110d565efSmrg 	  bitmap_clear_bit (kill, regno);
226210d565efSmrg 	}
226310d565efSmrg     }
226410d565efSmrg }
226510d565efSmrg 
226610d565efSmrg /*----------------------------------------------------------------------------
226710d565efSmrg    CREATE DEF_USE (DU) and / or USE_DEF (UD) CHAINS
226810d565efSmrg 
226910d565efSmrg    Link either the defs to the uses and / or the uses to the defs.
227010d565efSmrg 
227110d565efSmrg    These problems are set up like the other dataflow problems so that
227210d565efSmrg    they nicely fit into the framework.  They are much simpler and only
227310d565efSmrg    involve a single traversal of instructions and an examination of
227410d565efSmrg    the reaching defs information (the dependent problem).
227510d565efSmrg ----------------------------------------------------------------------------*/
227610d565efSmrg 
227710d565efSmrg #define df_chain_problem_p(FLAG) (((enum df_chain_flags)df_chain->local_flags)&(FLAG))
227810d565efSmrg 
227910d565efSmrg /* Create a du or ud chain from SRC to DST and link it into SRC.   */
228010d565efSmrg 
228110d565efSmrg struct df_link *
df_chain_create(df_ref src,df_ref dst)228210d565efSmrg df_chain_create (df_ref src, df_ref dst)
228310d565efSmrg {
228410d565efSmrg   struct df_link *head = DF_REF_CHAIN (src);
228510d565efSmrg   struct df_link *link = df_chain->block_pool->allocate ();
228610d565efSmrg 
228710d565efSmrg   DF_REF_CHAIN (src) = link;
228810d565efSmrg   link->next = head;
228910d565efSmrg   link->ref = dst;
229010d565efSmrg   return link;
229110d565efSmrg }
229210d565efSmrg 
229310d565efSmrg 
229410d565efSmrg /* Delete any du or ud chains that start at REF and point to
229510d565efSmrg    TARGET.  */
229610d565efSmrg static void
df_chain_unlink_1(df_ref ref,df_ref target)229710d565efSmrg df_chain_unlink_1 (df_ref ref, df_ref target)
229810d565efSmrg {
229910d565efSmrg   struct df_link *chain = DF_REF_CHAIN (ref);
230010d565efSmrg   struct df_link *prev = NULL;
230110d565efSmrg 
230210d565efSmrg   while (chain)
230310d565efSmrg     {
230410d565efSmrg       if (chain->ref == target)
230510d565efSmrg 	{
230610d565efSmrg 	  if (prev)
230710d565efSmrg 	    prev->next = chain->next;
230810d565efSmrg 	  else
230910d565efSmrg 	    DF_REF_CHAIN (ref) = chain->next;
231010d565efSmrg 	  df_chain->block_pool->remove (chain);
231110d565efSmrg 	  return;
231210d565efSmrg 	}
231310d565efSmrg       prev = chain;
231410d565efSmrg       chain = chain->next;
231510d565efSmrg     }
231610d565efSmrg }
231710d565efSmrg 
231810d565efSmrg 
231910d565efSmrg /* Delete a du or ud chain that leave or point to REF.  */
232010d565efSmrg 
232110d565efSmrg void
df_chain_unlink(df_ref ref)232210d565efSmrg df_chain_unlink (df_ref ref)
232310d565efSmrg {
232410d565efSmrg   struct df_link *chain = DF_REF_CHAIN (ref);
232510d565efSmrg   while (chain)
232610d565efSmrg     {
232710d565efSmrg       struct df_link *next = chain->next;
232810d565efSmrg       /* Delete the other side if it exists.  */
232910d565efSmrg       df_chain_unlink_1 (chain->ref, ref);
233010d565efSmrg       df_chain->block_pool->remove (chain);
233110d565efSmrg       chain = next;
233210d565efSmrg     }
233310d565efSmrg   DF_REF_CHAIN (ref) = NULL;
233410d565efSmrg }
233510d565efSmrg 
233610d565efSmrg 
233710d565efSmrg /* Copy the du or ud chain starting at FROM_REF and attach it to
233810d565efSmrg    TO_REF.  */
233910d565efSmrg 
234010d565efSmrg void
df_chain_copy(df_ref to_ref,struct df_link * from_ref)234110d565efSmrg df_chain_copy (df_ref to_ref,
234210d565efSmrg 	       struct df_link *from_ref)
234310d565efSmrg {
234410d565efSmrg   while (from_ref)
234510d565efSmrg     {
234610d565efSmrg       df_chain_create (to_ref, from_ref->ref);
234710d565efSmrg       from_ref = from_ref->next;
234810d565efSmrg     }
234910d565efSmrg }
235010d565efSmrg 
235110d565efSmrg 
235210d565efSmrg /* Remove this problem from the stack of dataflow problems.  */
235310d565efSmrg 
235410d565efSmrg static void
df_chain_remove_problem(void)235510d565efSmrg df_chain_remove_problem (void)
235610d565efSmrg {
235710d565efSmrg   bitmap_iterator bi;
235810d565efSmrg   unsigned int bb_index;
235910d565efSmrg 
236010d565efSmrg   /* Wholesale destruction of the old chains.  */
236110d565efSmrg   if (df_chain->block_pool)
236210d565efSmrg     delete df_chain->block_pool;
236310d565efSmrg 
236410d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (df_chain->out_of_date_transfer_functions, 0, bb_index, bi)
236510d565efSmrg     {
236610d565efSmrg       rtx_insn *insn;
236710d565efSmrg       df_ref def, use;
236810d565efSmrg       basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
236910d565efSmrg 
237010d565efSmrg       if (df_chain_problem_p (DF_DU_CHAIN))
237110d565efSmrg 	FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
237210d565efSmrg 	  DF_REF_CHAIN (def) = NULL;
237310d565efSmrg       if (df_chain_problem_p (DF_UD_CHAIN))
237410d565efSmrg 	FOR_EACH_ARTIFICIAL_USE (use, bb_index)
237510d565efSmrg 	  DF_REF_CHAIN (use) = NULL;
237610d565efSmrg 
237710d565efSmrg       FOR_BB_INSNS (bb, insn)
237810d565efSmrg 	if (INSN_P (insn))
237910d565efSmrg 	  {
238010d565efSmrg 	    df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
238110d565efSmrg 	    if (df_chain_problem_p (DF_DU_CHAIN))
238210d565efSmrg 	      FOR_EACH_INSN_INFO_DEF (def, insn_info)
238310d565efSmrg 		DF_REF_CHAIN (def) = NULL;
238410d565efSmrg 	    if (df_chain_problem_p (DF_UD_CHAIN))
238510d565efSmrg 	      {
238610d565efSmrg 		FOR_EACH_INSN_INFO_USE (use, insn_info)
238710d565efSmrg 		  DF_REF_CHAIN (use) = NULL;
238810d565efSmrg 		FOR_EACH_INSN_INFO_EQ_USE (use, insn_info)
238910d565efSmrg 		  DF_REF_CHAIN (use) = NULL;
239010d565efSmrg 	      }
239110d565efSmrg 	  }
239210d565efSmrg     }
239310d565efSmrg 
239410d565efSmrg   bitmap_clear (df_chain->out_of_date_transfer_functions);
239510d565efSmrg   df_chain->block_pool = NULL;
239610d565efSmrg }
239710d565efSmrg 
239810d565efSmrg 
239910d565efSmrg /* Remove the chain problem completely.  */
240010d565efSmrg 
240110d565efSmrg static void
df_chain_fully_remove_problem(void)240210d565efSmrg df_chain_fully_remove_problem (void)
240310d565efSmrg {
240410d565efSmrg   df_chain_remove_problem ();
240510d565efSmrg   BITMAP_FREE (df_chain->out_of_date_transfer_functions);
240610d565efSmrg   free (df_chain);
240710d565efSmrg }
240810d565efSmrg 
240910d565efSmrg 
241010d565efSmrg /* Create def-use or use-def chains.  */
241110d565efSmrg 
241210d565efSmrg static void
df_chain_alloc(bitmap all_blocks ATTRIBUTE_UNUSED)241310d565efSmrg df_chain_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
241410d565efSmrg {
241510d565efSmrg   df_chain_remove_problem ();
241610d565efSmrg   df_chain->block_pool = new object_allocator<df_link> ("df_chain_block pool");
241710d565efSmrg   df_chain->optional_p = true;
241810d565efSmrg }
241910d565efSmrg 
242010d565efSmrg 
242110d565efSmrg /* Reset all of the chains when the set of basic blocks changes.  */
242210d565efSmrg 
242310d565efSmrg static void
df_chain_reset(bitmap blocks_to_clear ATTRIBUTE_UNUSED)242410d565efSmrg df_chain_reset (bitmap blocks_to_clear ATTRIBUTE_UNUSED)
242510d565efSmrg {
242610d565efSmrg   df_chain_remove_problem ();
242710d565efSmrg }
242810d565efSmrg 
242910d565efSmrg 
243010d565efSmrg /* Create the chains for a list of USEs.  */
243110d565efSmrg 
243210d565efSmrg static void
df_chain_create_bb_process_use(bitmap local_rd,df_ref use,int top_flag)243310d565efSmrg df_chain_create_bb_process_use (bitmap local_rd,
243410d565efSmrg 				df_ref use,
243510d565efSmrg 				int top_flag)
243610d565efSmrg {
243710d565efSmrg   bitmap_iterator bi;
243810d565efSmrg   unsigned int def_index;
243910d565efSmrg 
244010d565efSmrg   for (; use; use = DF_REF_NEXT_LOC (use))
244110d565efSmrg     {
244210d565efSmrg       unsigned int uregno = DF_REF_REGNO (use);
244310d565efSmrg       if ((!(df->changeable_flags & DF_NO_HARD_REGS))
244410d565efSmrg 	  || (uregno >= FIRST_PSEUDO_REGISTER))
244510d565efSmrg 	{
244610d565efSmrg 	  /* Do not want to go through this for an uninitialized var.  */
244710d565efSmrg 	  int count = DF_DEFS_COUNT (uregno);
244810d565efSmrg 	  if (count)
244910d565efSmrg 	    {
245010d565efSmrg 	      if (top_flag == (DF_REF_FLAGS (use) & DF_REF_AT_TOP))
245110d565efSmrg 		{
245210d565efSmrg 		  unsigned int first_index = DF_DEFS_BEGIN (uregno);
245310d565efSmrg 		  unsigned int last_index = first_index + count - 1;
245410d565efSmrg 
245510d565efSmrg 		  EXECUTE_IF_SET_IN_BITMAP (local_rd, first_index, def_index, bi)
245610d565efSmrg 		    {
245710d565efSmrg 		      df_ref def;
245810d565efSmrg 		      if (def_index > last_index)
245910d565efSmrg 			break;
246010d565efSmrg 
246110d565efSmrg 		      def = DF_DEFS_GET (def_index);
246210d565efSmrg 		      if (df_chain_problem_p (DF_DU_CHAIN))
246310d565efSmrg 			df_chain_create (def, use);
246410d565efSmrg 		      if (df_chain_problem_p (DF_UD_CHAIN))
246510d565efSmrg 			df_chain_create (use, def);
246610d565efSmrg 		    }
246710d565efSmrg 		}
246810d565efSmrg 	    }
246910d565efSmrg 	}
247010d565efSmrg     }
247110d565efSmrg }
247210d565efSmrg 
247310d565efSmrg 
247410d565efSmrg /* Create chains from reaching defs bitmaps for basic block BB.  */
247510d565efSmrg 
247610d565efSmrg static void
df_chain_create_bb(unsigned int bb_index)247710d565efSmrg df_chain_create_bb (unsigned int bb_index)
247810d565efSmrg {
247910d565efSmrg   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
2480*ec02198aSmrg   class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
248110d565efSmrg   rtx_insn *insn;
248210d565efSmrg   bitmap_head cpy;
248310d565efSmrg 
248410d565efSmrg   bitmap_initialize (&cpy, &bitmap_default_obstack);
248510d565efSmrg   bitmap_copy (&cpy, &bb_info->in);
248610d565efSmrg   bitmap_set_bit (df_chain->out_of_date_transfer_functions, bb_index);
248710d565efSmrg 
248810d565efSmrg   /* Since we are going forwards, process the artificial uses first
248910d565efSmrg      then the artificial defs second.  */
249010d565efSmrg 
249110d565efSmrg #ifdef EH_USES
249210d565efSmrg   /* Create the chains for the artificial uses from the EH_USES at the
249310d565efSmrg      beginning of the block.  */
249410d565efSmrg 
249510d565efSmrg   /* Artificials are only hard regs.  */
249610d565efSmrg   if (!(df->changeable_flags & DF_NO_HARD_REGS))
249710d565efSmrg     df_chain_create_bb_process_use (&cpy,
249810d565efSmrg 				    df_get_artificial_uses (bb->index),
249910d565efSmrg 				    DF_REF_AT_TOP);
250010d565efSmrg #endif
250110d565efSmrg 
250210d565efSmrg   df_rd_simulate_artificial_defs_at_top (bb, &cpy);
250310d565efSmrg 
250410d565efSmrg   /* Process the regular instructions next.  */
250510d565efSmrg   FOR_BB_INSNS (bb, insn)
250610d565efSmrg     if (INSN_P (insn))
250710d565efSmrg       {
250810d565efSmrg         unsigned int uid = INSN_UID (insn);
250910d565efSmrg 
251010d565efSmrg         /* First scan the uses and link them up with the defs that remain
251110d565efSmrg 	   in the cpy vector.  */
251210d565efSmrg         df_chain_create_bb_process_use (&cpy, DF_INSN_UID_USES (uid), 0);
251310d565efSmrg         if (df->changeable_flags & DF_EQ_NOTES)
251410d565efSmrg 	  df_chain_create_bb_process_use (&cpy, DF_INSN_UID_EQ_USES (uid), 0);
251510d565efSmrg 
251610d565efSmrg         /* Since we are going forwards, process the defs second.  */
251710d565efSmrg         df_rd_simulate_one_insn (bb, insn, &cpy);
251810d565efSmrg       }
251910d565efSmrg 
252010d565efSmrg   /* Create the chains for the artificial uses of the hard registers
252110d565efSmrg      at the end of the block.  */
252210d565efSmrg   if (!(df->changeable_flags & DF_NO_HARD_REGS))
252310d565efSmrg     df_chain_create_bb_process_use (&cpy,
252410d565efSmrg 				    df_get_artificial_uses (bb->index),
252510d565efSmrg 				    0);
252610d565efSmrg 
252710d565efSmrg   bitmap_clear (&cpy);
252810d565efSmrg }
252910d565efSmrg 
253010d565efSmrg /* Create def-use chains from reaching use bitmaps for basic blocks
253110d565efSmrg    in BLOCKS.  */
253210d565efSmrg 
253310d565efSmrg static void
df_chain_finalize(bitmap all_blocks)253410d565efSmrg df_chain_finalize (bitmap all_blocks)
253510d565efSmrg {
253610d565efSmrg   unsigned int bb_index;
253710d565efSmrg   bitmap_iterator bi;
253810d565efSmrg 
253910d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
254010d565efSmrg     {
254110d565efSmrg       df_chain_create_bb (bb_index);
254210d565efSmrg     }
254310d565efSmrg }
254410d565efSmrg 
254510d565efSmrg 
254610d565efSmrg /* Free all storage associated with the problem.  */
254710d565efSmrg 
254810d565efSmrg static void
df_chain_free(void)254910d565efSmrg df_chain_free (void)
255010d565efSmrg {
255110d565efSmrg   delete df_chain->block_pool;
255210d565efSmrg   BITMAP_FREE (df_chain->out_of_date_transfer_functions);
255310d565efSmrg   free (df_chain);
255410d565efSmrg }
255510d565efSmrg 
255610d565efSmrg 
255710d565efSmrg /* Debugging info.  */
255810d565efSmrg 
255910d565efSmrg static void
df_chain_bb_dump(basic_block bb,FILE * file,bool top)256010d565efSmrg df_chain_bb_dump (basic_block bb, FILE *file, bool top)
256110d565efSmrg {
256210d565efSmrg   /* Artificials are only hard regs.  */
256310d565efSmrg   if (df->changeable_flags & DF_NO_HARD_REGS)
256410d565efSmrg     return;
256510d565efSmrg   if (df_chain_problem_p (DF_UD_CHAIN))
256610d565efSmrg     {
256710d565efSmrg       df_ref use;
256810d565efSmrg 
256910d565efSmrg       fprintf (file,
257010d565efSmrg 	       ";;  UD chains for artificial uses at %s\n",
257110d565efSmrg 	       top ? "top" : "bottom");
257210d565efSmrg       FOR_EACH_ARTIFICIAL_USE (use, bb->index)
257310d565efSmrg 	if ((top && (DF_REF_FLAGS (use) & DF_REF_AT_TOP))
257410d565efSmrg 	    || (!top && !(DF_REF_FLAGS (use) & DF_REF_AT_TOP)))
257510d565efSmrg 	  {
257610d565efSmrg 	    fprintf (file, ";;   reg %d ", DF_REF_REGNO (use));
257710d565efSmrg 	    df_chain_dump (DF_REF_CHAIN (use), file);
257810d565efSmrg 	    fprintf (file, "\n");
257910d565efSmrg 	  }
258010d565efSmrg     }
258110d565efSmrg   if (df_chain_problem_p (DF_DU_CHAIN))
258210d565efSmrg     {
258310d565efSmrg       df_ref def;
258410d565efSmrg 
258510d565efSmrg       fprintf (file,
258610d565efSmrg 	       ";;  DU chains for artificial defs at %s\n",
258710d565efSmrg 	       top ? "top" : "bottom");
258810d565efSmrg       FOR_EACH_ARTIFICIAL_DEF (def, bb->index)
258910d565efSmrg 	if ((top && (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
259010d565efSmrg 	    || (!top && !(DF_REF_FLAGS (def) & DF_REF_AT_TOP)))
259110d565efSmrg 	  {
259210d565efSmrg 	    fprintf (file, ";;   reg %d ", DF_REF_REGNO (def));
259310d565efSmrg 	    df_chain_dump (DF_REF_CHAIN (def), file);
259410d565efSmrg 	    fprintf (file, "\n");
259510d565efSmrg 	  }
259610d565efSmrg     }
259710d565efSmrg }
259810d565efSmrg 
259910d565efSmrg static void
df_chain_top_dump(basic_block bb,FILE * file)260010d565efSmrg df_chain_top_dump (basic_block bb, FILE *file)
260110d565efSmrg {
260210d565efSmrg   df_chain_bb_dump (bb, file, /*top=*/true);
260310d565efSmrg }
260410d565efSmrg 
260510d565efSmrg static void
df_chain_bottom_dump(basic_block bb,FILE * file)260610d565efSmrg df_chain_bottom_dump (basic_block bb, FILE *file)
260710d565efSmrg {
260810d565efSmrg   df_chain_bb_dump (bb, file, /*top=*/false);
260910d565efSmrg }
261010d565efSmrg 
261110d565efSmrg static void
df_chain_insn_top_dump(const rtx_insn * insn,FILE * file)261210d565efSmrg df_chain_insn_top_dump (const rtx_insn *insn, FILE *file)
261310d565efSmrg {
261410d565efSmrg   if (df_chain_problem_p (DF_UD_CHAIN) && INSN_P (insn))
261510d565efSmrg     {
261610d565efSmrg       struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
261710d565efSmrg       df_ref use;
261810d565efSmrg 
261910d565efSmrg       fprintf (file, ";;   UD chains for insn luid %d uid %d\n",
262010d565efSmrg 	       DF_INSN_INFO_LUID (insn_info), INSN_UID (insn));
262110d565efSmrg       FOR_EACH_INSN_INFO_USE (use, insn_info)
262210d565efSmrg 	if (!HARD_REGISTER_NUM_P (DF_REF_REGNO (use))
262310d565efSmrg 	    || !(df->changeable_flags & DF_NO_HARD_REGS))
262410d565efSmrg 	  {
262510d565efSmrg 	    fprintf (file, ";;      reg %d ", DF_REF_REGNO (use));
262610d565efSmrg 	    if (DF_REF_FLAGS (use) & DF_REF_READ_WRITE)
262710d565efSmrg 	      fprintf (file, "read/write ");
262810d565efSmrg 	    df_chain_dump (DF_REF_CHAIN (use), file);
262910d565efSmrg 	    fprintf (file, "\n");
263010d565efSmrg 	  }
263110d565efSmrg       FOR_EACH_INSN_INFO_EQ_USE (use, insn_info)
263210d565efSmrg 	if (!HARD_REGISTER_NUM_P (DF_REF_REGNO (use))
263310d565efSmrg 	    || !(df->changeable_flags & DF_NO_HARD_REGS))
263410d565efSmrg 	  {
263510d565efSmrg 	    fprintf (file, ";;   eq_note reg %d ", DF_REF_REGNO (use));
263610d565efSmrg 	    df_chain_dump (DF_REF_CHAIN (use), file);
263710d565efSmrg 	    fprintf (file, "\n");
263810d565efSmrg 	  }
263910d565efSmrg     }
264010d565efSmrg }
264110d565efSmrg 
264210d565efSmrg static void
df_chain_insn_bottom_dump(const rtx_insn * insn,FILE * file)264310d565efSmrg df_chain_insn_bottom_dump (const rtx_insn *insn, FILE *file)
264410d565efSmrg {
264510d565efSmrg   if (df_chain_problem_p (DF_DU_CHAIN) && INSN_P (insn))
264610d565efSmrg     {
264710d565efSmrg       struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
264810d565efSmrg       df_ref def;
264910d565efSmrg       fprintf (file, ";;   DU chains for insn luid %d uid %d\n",
265010d565efSmrg 	       DF_INSN_INFO_LUID (insn_info), INSN_UID (insn));
265110d565efSmrg       FOR_EACH_INSN_INFO_DEF (def, insn_info)
265210d565efSmrg 	if (!HARD_REGISTER_NUM_P (DF_REF_REGNO (def))
265310d565efSmrg 	    || !(df->changeable_flags & DF_NO_HARD_REGS))
265410d565efSmrg 	  {
265510d565efSmrg 	    fprintf (file, ";;      reg %d ", DF_REF_REGNO (def));
265610d565efSmrg 	    if (DF_REF_FLAGS (def) & DF_REF_READ_WRITE)
265710d565efSmrg 	      fprintf (file, "read/write ");
265810d565efSmrg 	    df_chain_dump (DF_REF_CHAIN (def), file);
265910d565efSmrg 	    fprintf (file, "\n");
266010d565efSmrg 	  }
266110d565efSmrg       fprintf (file, "\n");
266210d565efSmrg     }
266310d565efSmrg }
266410d565efSmrg 
266510d565efSmrg static const struct df_problem problem_CHAIN =
266610d565efSmrg {
266710d565efSmrg   DF_CHAIN,                   /* Problem id.  */
266810d565efSmrg   DF_NONE,                    /* Direction.  */
266910d565efSmrg   df_chain_alloc,             /* Allocate the problem specific data.  */
267010d565efSmrg   df_chain_reset,             /* Reset global information.  */
267110d565efSmrg   NULL,                       /* Free basic block info.  */
267210d565efSmrg   NULL,                       /* Local compute function.  */
267310d565efSmrg   NULL,                       /* Init the solution specific data.  */
267410d565efSmrg   NULL,                       /* Iterative solver.  */
267510d565efSmrg   NULL,                       /* Confluence operator 0.  */
267610d565efSmrg   NULL,                       /* Confluence operator n.  */
267710d565efSmrg   NULL,                       /* Transfer function.  */
267810d565efSmrg   df_chain_finalize,          /* Finalize function.  */
267910d565efSmrg   df_chain_free,              /* Free all of the problem information.  */
268010d565efSmrg   df_chain_fully_remove_problem,/* Remove this problem from the stack of dataflow problems.  */
268110d565efSmrg   NULL,                       /* Debugging.  */
268210d565efSmrg   df_chain_top_dump,          /* Debugging start block.  */
268310d565efSmrg   df_chain_bottom_dump,       /* Debugging end block.  */
268410d565efSmrg   df_chain_insn_top_dump,     /* Debugging start insn.  */
268510d565efSmrg   df_chain_insn_bottom_dump,  /* Debugging end insn.  */
268610d565efSmrg   NULL,                       /* Incremental solution verify start.  */
268710d565efSmrg   NULL,                       /* Incremental solution verify end.  */
268810d565efSmrg   &problem_RD,                /* Dependent problem.  */
268910d565efSmrg   sizeof (struct df_scan_bb_info),/* Size of entry of block_info array.  */
269010d565efSmrg   TV_DF_CHAIN,                /* Timing variable.  */
269110d565efSmrg   false                       /* Reset blocks on dropping out of blocks_to_analyze.  */
269210d565efSmrg };
269310d565efSmrg 
269410d565efSmrg 
269510d565efSmrg /* Create a new DATAFLOW instance and add it to an existing instance
269610d565efSmrg    of DF.  The returned structure is what is used to get at the
269710d565efSmrg    solution.  */
269810d565efSmrg 
269910d565efSmrg void
df_chain_add_problem(unsigned int chain_flags)270010d565efSmrg df_chain_add_problem (unsigned int chain_flags)
270110d565efSmrg {
270210d565efSmrg   df_add_problem (&problem_CHAIN);
270310d565efSmrg   df_chain->local_flags = chain_flags;
270410d565efSmrg   df_chain->out_of_date_transfer_functions = BITMAP_ALLOC (&df_bitmap_obstack);
270510d565efSmrg }
270610d565efSmrg 
270710d565efSmrg #undef df_chain_problem_p
270810d565efSmrg 
270910d565efSmrg 
271010d565efSmrg /*----------------------------------------------------------------------------
271110d565efSmrg    WORD LEVEL LIVE REGISTERS
271210d565efSmrg 
271310d565efSmrg    Find the locations in the function where any use of a pseudo can
271410d565efSmrg    reach in the backwards direction.  In and out bitvectors are built
271510d565efSmrg    for each basic block.  We only track pseudo registers that have a
271610d565efSmrg    size of 2 * UNITS_PER_WORD; bitmaps are indexed by 2 * regno and
271710d565efSmrg    contain two bits corresponding to each of the subwords.
271810d565efSmrg 
271910d565efSmrg    ----------------------------------------------------------------------------*/
272010d565efSmrg 
272110d565efSmrg /* Private data used to verify the solution for this problem.  */
272210d565efSmrg struct df_word_lr_problem_data
272310d565efSmrg {
272410d565efSmrg   /* An obstack for the bitmaps we need for this problem.  */
272510d565efSmrg   bitmap_obstack word_lr_bitmaps;
272610d565efSmrg };
272710d565efSmrg 
272810d565efSmrg 
272910d565efSmrg /* Free basic block info.  */
273010d565efSmrg 
273110d565efSmrg static void
df_word_lr_free_bb_info(basic_block bb ATTRIBUTE_UNUSED,void * vbb_info)273210d565efSmrg df_word_lr_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
273310d565efSmrg 			 void *vbb_info)
273410d565efSmrg {
2735*ec02198aSmrg   class df_word_lr_bb_info *bb_info = (class df_word_lr_bb_info *) vbb_info;
273610d565efSmrg   if (bb_info)
273710d565efSmrg     {
273810d565efSmrg       bitmap_clear (&bb_info->use);
273910d565efSmrg       bitmap_clear (&bb_info->def);
274010d565efSmrg       bitmap_clear (&bb_info->in);
274110d565efSmrg       bitmap_clear (&bb_info->out);
274210d565efSmrg     }
274310d565efSmrg }
274410d565efSmrg 
274510d565efSmrg 
274610d565efSmrg /* Allocate or reset bitmaps for DF_WORD_LR blocks. The solution bits are
274710d565efSmrg    not touched unless the block is new.  */
274810d565efSmrg 
274910d565efSmrg static void
df_word_lr_alloc(bitmap all_blocks ATTRIBUTE_UNUSED)275010d565efSmrg df_word_lr_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
275110d565efSmrg {
275210d565efSmrg   unsigned int bb_index;
275310d565efSmrg   bitmap_iterator bi;
275410d565efSmrg   basic_block bb;
275510d565efSmrg   struct df_word_lr_problem_data *problem_data
275610d565efSmrg     = XNEW (struct df_word_lr_problem_data);
275710d565efSmrg 
275810d565efSmrg   df_word_lr->problem_data = problem_data;
275910d565efSmrg 
276010d565efSmrg   df_grow_bb_info (df_word_lr);
276110d565efSmrg 
276210d565efSmrg   /* Create the mapping from regnos to slots. This does not change
276310d565efSmrg      unless the problem is destroyed and recreated.  In particular, if
276410d565efSmrg      we end up deleting the only insn that used a subreg, we do not
276510d565efSmrg      want to redo the mapping because this would invalidate everything
276610d565efSmrg      else.  */
276710d565efSmrg 
276810d565efSmrg   bitmap_obstack_initialize (&problem_data->word_lr_bitmaps);
276910d565efSmrg 
277010d565efSmrg   FOR_EACH_BB_FN (bb, cfun)
277110d565efSmrg     bitmap_set_bit (df_word_lr->out_of_date_transfer_functions, bb->index);
277210d565efSmrg 
277310d565efSmrg   bitmap_set_bit (df_word_lr->out_of_date_transfer_functions, ENTRY_BLOCK);
277410d565efSmrg   bitmap_set_bit (df_word_lr->out_of_date_transfer_functions, EXIT_BLOCK);
277510d565efSmrg 
277610d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (df_word_lr->out_of_date_transfer_functions, 0, bb_index, bi)
277710d565efSmrg     {
2778*ec02198aSmrg       class df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
277910d565efSmrg 
278010d565efSmrg       /* When bitmaps are already initialized, just clear them.  */
278110d565efSmrg       if (bb_info->use.obstack)
278210d565efSmrg 	{
278310d565efSmrg 	  bitmap_clear (&bb_info->def);
278410d565efSmrg 	  bitmap_clear (&bb_info->use);
278510d565efSmrg 	}
278610d565efSmrg       else
278710d565efSmrg 	{
278810d565efSmrg 	  bitmap_initialize (&bb_info->use, &problem_data->word_lr_bitmaps);
278910d565efSmrg 	  bitmap_initialize (&bb_info->def, &problem_data->word_lr_bitmaps);
279010d565efSmrg 	  bitmap_initialize (&bb_info->in, &problem_data->word_lr_bitmaps);
279110d565efSmrg 	  bitmap_initialize (&bb_info->out, &problem_data->word_lr_bitmaps);
279210d565efSmrg 	}
279310d565efSmrg     }
279410d565efSmrg 
279510d565efSmrg   df_word_lr->optional_p = true;
279610d565efSmrg }
279710d565efSmrg 
279810d565efSmrg 
279910d565efSmrg /* Reset the global solution for recalculation.  */
280010d565efSmrg 
280110d565efSmrg static void
df_word_lr_reset(bitmap all_blocks)280210d565efSmrg df_word_lr_reset (bitmap all_blocks)
280310d565efSmrg {
280410d565efSmrg   unsigned int bb_index;
280510d565efSmrg   bitmap_iterator bi;
280610d565efSmrg 
280710d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
280810d565efSmrg     {
2809*ec02198aSmrg       class df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
281010d565efSmrg       gcc_assert (bb_info);
281110d565efSmrg       bitmap_clear (&bb_info->in);
281210d565efSmrg       bitmap_clear (&bb_info->out);
281310d565efSmrg     }
281410d565efSmrg }
281510d565efSmrg 
281610d565efSmrg /* Examine REF, and if it is for a reg we're interested in, set or
281710d565efSmrg    clear the bits corresponding to its subwords from the bitmap
281810d565efSmrg    according to IS_SET.  LIVE is the bitmap we should update.  We do
281910d565efSmrg    not track hard regs or pseudos of any size other than 2 *
282010d565efSmrg    UNITS_PER_WORD.
282110d565efSmrg    We return true if we changed the bitmap, or if we encountered a register
282210d565efSmrg    we're not tracking.  */
282310d565efSmrg 
282410d565efSmrg bool
df_word_lr_mark_ref(df_ref ref,bool is_set,regset live)282510d565efSmrg df_word_lr_mark_ref (df_ref ref, bool is_set, regset live)
282610d565efSmrg {
282710d565efSmrg   rtx orig_reg = DF_REF_REG (ref);
282810d565efSmrg   rtx reg = orig_reg;
282910d565efSmrg   machine_mode reg_mode;
283010d565efSmrg   unsigned regno;
283110d565efSmrg   /* Left at -1 for whole accesses.  */
283210d565efSmrg   int which_subword = -1;
283310d565efSmrg   bool changed = false;
283410d565efSmrg 
283510d565efSmrg   if (GET_CODE (reg) == SUBREG)
283610d565efSmrg     reg = SUBREG_REG (orig_reg);
283710d565efSmrg   regno = REGNO (reg);
283810d565efSmrg   reg_mode = GET_MODE (reg);
283910d565efSmrg   if (regno < FIRST_PSEUDO_REGISTER
2840c7a68eb7Smrg       || maybe_ne (GET_MODE_SIZE (reg_mode), 2 * UNITS_PER_WORD))
284110d565efSmrg     return true;
284210d565efSmrg 
284310d565efSmrg   if (GET_CODE (orig_reg) == SUBREG
2844c7a68eb7Smrg       && read_modify_subreg_p (orig_reg))
284510d565efSmrg     {
284610d565efSmrg       gcc_assert (DF_REF_FLAGS_IS_SET (ref, DF_REF_PARTIAL));
284710d565efSmrg       if (subreg_lowpart_p (orig_reg))
284810d565efSmrg 	which_subword = 0;
284910d565efSmrg       else
285010d565efSmrg 	which_subword = 1;
285110d565efSmrg     }
285210d565efSmrg   if (is_set)
285310d565efSmrg     {
285410d565efSmrg       if (which_subword != 1)
285510d565efSmrg 	changed |= bitmap_set_bit (live, regno * 2);
285610d565efSmrg       if (which_subword != 0)
285710d565efSmrg 	changed |= bitmap_set_bit (live, regno * 2 + 1);
285810d565efSmrg     }
285910d565efSmrg   else
286010d565efSmrg     {
286110d565efSmrg       if (which_subword != 1)
286210d565efSmrg 	changed |= bitmap_clear_bit (live, regno * 2);
286310d565efSmrg       if (which_subword != 0)
286410d565efSmrg 	changed |= bitmap_clear_bit (live, regno * 2 + 1);
286510d565efSmrg     }
286610d565efSmrg   return changed;
286710d565efSmrg }
286810d565efSmrg 
286910d565efSmrg /* Compute local live register info for basic block BB.  */
287010d565efSmrg 
287110d565efSmrg static void
df_word_lr_bb_local_compute(unsigned int bb_index)287210d565efSmrg df_word_lr_bb_local_compute (unsigned int bb_index)
287310d565efSmrg {
287410d565efSmrg   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
2875*ec02198aSmrg   class df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
287610d565efSmrg   rtx_insn *insn;
287710d565efSmrg   df_ref def, use;
287810d565efSmrg 
287910d565efSmrg   /* Ensure that artificial refs don't contain references to pseudos.  */
288010d565efSmrg   FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
288110d565efSmrg     gcc_assert (DF_REF_REGNO (def) < FIRST_PSEUDO_REGISTER);
288210d565efSmrg 
288310d565efSmrg   FOR_EACH_ARTIFICIAL_USE (use, bb_index)
288410d565efSmrg     gcc_assert (DF_REF_REGNO (use) < FIRST_PSEUDO_REGISTER);
288510d565efSmrg 
288610d565efSmrg   FOR_BB_INSNS_REVERSE (bb, insn)
288710d565efSmrg     {
288810d565efSmrg       if (!NONDEBUG_INSN_P (insn))
288910d565efSmrg 	continue;
289010d565efSmrg 
289110d565efSmrg       df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
289210d565efSmrg       FOR_EACH_INSN_INFO_DEF (def, insn_info)
289310d565efSmrg 	/* If the def is to only part of the reg, it does
289410d565efSmrg 	   not kill the other defs that reach here.  */
289510d565efSmrg 	if (!(DF_REF_FLAGS (def) & (DF_REF_CONDITIONAL)))
289610d565efSmrg 	  {
289710d565efSmrg 	    df_word_lr_mark_ref (def, true, &bb_info->def);
289810d565efSmrg 	    df_word_lr_mark_ref (def, false, &bb_info->use);
289910d565efSmrg 	  }
290010d565efSmrg       FOR_EACH_INSN_INFO_USE (use, insn_info)
290110d565efSmrg 	df_word_lr_mark_ref (use, true, &bb_info->use);
290210d565efSmrg     }
290310d565efSmrg }
290410d565efSmrg 
290510d565efSmrg 
290610d565efSmrg /* Compute local live register info for each basic block within BLOCKS.  */
290710d565efSmrg 
290810d565efSmrg static void
df_word_lr_local_compute(bitmap all_blocks ATTRIBUTE_UNUSED)290910d565efSmrg df_word_lr_local_compute (bitmap all_blocks ATTRIBUTE_UNUSED)
291010d565efSmrg {
291110d565efSmrg   unsigned int bb_index;
291210d565efSmrg   bitmap_iterator bi;
291310d565efSmrg 
291410d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (df_word_lr->out_of_date_transfer_functions, 0, bb_index, bi)
291510d565efSmrg     {
291610d565efSmrg       if (bb_index == EXIT_BLOCK)
291710d565efSmrg 	{
291810d565efSmrg 	  unsigned regno;
291910d565efSmrg 	  bitmap_iterator bi;
292010d565efSmrg 	  EXECUTE_IF_SET_IN_BITMAP (df->exit_block_uses, FIRST_PSEUDO_REGISTER,
292110d565efSmrg 				    regno, bi)
292210d565efSmrg 	    gcc_unreachable ();
292310d565efSmrg 	}
292410d565efSmrg       else
292510d565efSmrg 	df_word_lr_bb_local_compute (bb_index);
292610d565efSmrg     }
292710d565efSmrg 
292810d565efSmrg   bitmap_clear (df_word_lr->out_of_date_transfer_functions);
292910d565efSmrg }
293010d565efSmrg 
293110d565efSmrg 
293210d565efSmrg /* Initialize the solution vectors.  */
293310d565efSmrg 
293410d565efSmrg static void
df_word_lr_init(bitmap all_blocks)293510d565efSmrg df_word_lr_init (bitmap all_blocks)
293610d565efSmrg {
293710d565efSmrg   unsigned int bb_index;
293810d565efSmrg   bitmap_iterator bi;
293910d565efSmrg 
294010d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
294110d565efSmrg     {
2942*ec02198aSmrg       class df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
294310d565efSmrg       bitmap_copy (&bb_info->in, &bb_info->use);
294410d565efSmrg       bitmap_clear (&bb_info->out);
294510d565efSmrg     }
294610d565efSmrg }
294710d565efSmrg 
294810d565efSmrg 
294910d565efSmrg /* Confluence function that ignores fake edges.  */
295010d565efSmrg 
295110d565efSmrg static bool
df_word_lr_confluence_n(edge e)295210d565efSmrg df_word_lr_confluence_n (edge e)
295310d565efSmrg {
295410d565efSmrg   bitmap op1 = &df_word_lr_get_bb_info (e->src->index)->out;
295510d565efSmrg   bitmap op2 = &df_word_lr_get_bb_info (e->dest->index)->in;
295610d565efSmrg 
295710d565efSmrg   return bitmap_ior_into (op1, op2);
295810d565efSmrg }
295910d565efSmrg 
296010d565efSmrg 
296110d565efSmrg /* Transfer function.  */
296210d565efSmrg 
296310d565efSmrg static bool
df_word_lr_transfer_function(int bb_index)296410d565efSmrg df_word_lr_transfer_function (int bb_index)
296510d565efSmrg {
2966*ec02198aSmrg   class df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
296710d565efSmrg   bitmap in = &bb_info->in;
296810d565efSmrg   bitmap out = &bb_info->out;
296910d565efSmrg   bitmap use = &bb_info->use;
297010d565efSmrg   bitmap def = &bb_info->def;
297110d565efSmrg 
297210d565efSmrg   return bitmap_ior_and_compl (in, use, out, def);
297310d565efSmrg }
297410d565efSmrg 
297510d565efSmrg 
297610d565efSmrg /* Free all storage associated with the problem.  */
297710d565efSmrg 
297810d565efSmrg static void
df_word_lr_free(void)297910d565efSmrg df_word_lr_free (void)
298010d565efSmrg {
298110d565efSmrg   struct df_word_lr_problem_data *problem_data
298210d565efSmrg     = (struct df_word_lr_problem_data *)df_word_lr->problem_data;
298310d565efSmrg 
298410d565efSmrg   if (df_word_lr->block_info)
298510d565efSmrg     {
298610d565efSmrg       df_word_lr->block_info_size = 0;
298710d565efSmrg       free (df_word_lr->block_info);
298810d565efSmrg       df_word_lr->block_info = NULL;
298910d565efSmrg     }
299010d565efSmrg 
299110d565efSmrg   BITMAP_FREE (df_word_lr->out_of_date_transfer_functions);
299210d565efSmrg   bitmap_obstack_release (&problem_data->word_lr_bitmaps);
299310d565efSmrg   free (problem_data);
299410d565efSmrg   free (df_word_lr);
299510d565efSmrg }
299610d565efSmrg 
299710d565efSmrg 
299810d565efSmrg /* Debugging info at top of bb.  */
299910d565efSmrg 
300010d565efSmrg static void
df_word_lr_top_dump(basic_block bb,FILE * file)300110d565efSmrg df_word_lr_top_dump (basic_block bb, FILE *file)
300210d565efSmrg {
3003*ec02198aSmrg   class df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb->index);
300410d565efSmrg   if (!bb_info)
300510d565efSmrg     return;
300610d565efSmrg 
300710d565efSmrg   fprintf (file, ";; blr  in  \t");
300810d565efSmrg   df_print_word_regset (file, &bb_info->in);
300910d565efSmrg   fprintf (file, ";; blr  use \t");
301010d565efSmrg   df_print_word_regset (file, &bb_info->use);
301110d565efSmrg   fprintf (file, ";; blr  def \t");
301210d565efSmrg   df_print_word_regset (file, &bb_info->def);
301310d565efSmrg }
301410d565efSmrg 
301510d565efSmrg 
301610d565efSmrg /* Debugging info at bottom of bb.  */
301710d565efSmrg 
301810d565efSmrg static void
df_word_lr_bottom_dump(basic_block bb,FILE * file)301910d565efSmrg df_word_lr_bottom_dump (basic_block bb, FILE *file)
302010d565efSmrg {
3021*ec02198aSmrg   class df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb->index);
302210d565efSmrg   if (!bb_info)
302310d565efSmrg     return;
302410d565efSmrg 
302510d565efSmrg   fprintf (file, ";; blr  out \t");
302610d565efSmrg   df_print_word_regset (file, &bb_info->out);
302710d565efSmrg }
302810d565efSmrg 
302910d565efSmrg 
303010d565efSmrg /* All of the information associated with every instance of the problem.  */
303110d565efSmrg 
303210d565efSmrg static const struct df_problem problem_WORD_LR =
303310d565efSmrg {
303410d565efSmrg   DF_WORD_LR,                      /* Problem id.  */
303510d565efSmrg   DF_BACKWARD,                     /* Direction.  */
303610d565efSmrg   df_word_lr_alloc,                /* Allocate the problem specific data.  */
303710d565efSmrg   df_word_lr_reset,                /* Reset global information.  */
303810d565efSmrg   df_word_lr_free_bb_info,         /* Free basic block info.  */
303910d565efSmrg   df_word_lr_local_compute,        /* Local compute function.  */
304010d565efSmrg   df_word_lr_init,                 /* Init the solution specific data.  */
304110d565efSmrg   df_worklist_dataflow,            /* Worklist solver.  */
304210d565efSmrg   NULL,                            /* Confluence operator 0.  */
304310d565efSmrg   df_word_lr_confluence_n,         /* Confluence operator n.  */
304410d565efSmrg   df_word_lr_transfer_function,    /* Transfer function.  */
304510d565efSmrg   NULL,                            /* Finalize function.  */
304610d565efSmrg   df_word_lr_free,                 /* Free all of the problem information.  */
304710d565efSmrg   df_word_lr_free,                 /* Remove this problem from the stack of dataflow problems.  */
304810d565efSmrg   NULL,                            /* Debugging.  */
304910d565efSmrg   df_word_lr_top_dump,             /* Debugging start block.  */
305010d565efSmrg   df_word_lr_bottom_dump,          /* Debugging end block.  */
305110d565efSmrg   NULL,                            /* Debugging start insn.  */
305210d565efSmrg   NULL,                            /* Debugging end insn.  */
305310d565efSmrg   NULL,                            /* Incremental solution verify start.  */
305410d565efSmrg   NULL,                            /* Incremental solution verify end.  */
305510d565efSmrg   NULL,                            /* Dependent problem.  */
3056*ec02198aSmrg   sizeof (class df_word_lr_bb_info),/* Size of entry of block_info array.  */
305710d565efSmrg   TV_DF_WORD_LR,                   /* Timing variable.  */
305810d565efSmrg   false                            /* Reset blocks on dropping out of blocks_to_analyze.  */
305910d565efSmrg };
306010d565efSmrg 
306110d565efSmrg 
306210d565efSmrg /* Create a new DATAFLOW instance and add it to an existing instance
306310d565efSmrg    of DF.  The returned structure is what is used to get at the
306410d565efSmrg    solution.  */
306510d565efSmrg 
306610d565efSmrg void
df_word_lr_add_problem(void)306710d565efSmrg df_word_lr_add_problem (void)
306810d565efSmrg {
306910d565efSmrg   df_add_problem (&problem_WORD_LR);
307010d565efSmrg   /* These will be initialized when df_scan_blocks processes each
307110d565efSmrg      block.  */
307210d565efSmrg   df_word_lr->out_of_date_transfer_functions = BITMAP_ALLOC (&df_bitmap_obstack);
307310d565efSmrg }
307410d565efSmrg 
307510d565efSmrg 
307610d565efSmrg /* Simulate the effects of the defs of INSN on LIVE.  Return true if we changed
307710d565efSmrg    any bits, which is used by the caller to determine whether a set is
307810d565efSmrg    necessary.  We also return true if there are other reasons not to delete
307910d565efSmrg    an insn.  */
308010d565efSmrg 
308110d565efSmrg bool
df_word_lr_simulate_defs(rtx_insn * insn,bitmap live)308210d565efSmrg df_word_lr_simulate_defs (rtx_insn *insn, bitmap live)
308310d565efSmrg {
308410d565efSmrg   bool changed = false;
308510d565efSmrg   df_ref def;
308610d565efSmrg 
308710d565efSmrg   FOR_EACH_INSN_DEF (def, insn)
308810d565efSmrg     if (DF_REF_FLAGS (def) & DF_REF_CONDITIONAL)
308910d565efSmrg       changed = true;
309010d565efSmrg     else
309110d565efSmrg       changed |= df_word_lr_mark_ref (def, false, live);
309210d565efSmrg   return changed;
309310d565efSmrg }
309410d565efSmrg 
309510d565efSmrg 
309610d565efSmrg /* Simulate the effects of the uses of INSN on LIVE.  */
309710d565efSmrg 
309810d565efSmrg void
df_word_lr_simulate_uses(rtx_insn * insn,bitmap live)309910d565efSmrg df_word_lr_simulate_uses (rtx_insn *insn, bitmap live)
310010d565efSmrg {
310110d565efSmrg   df_ref use;
310210d565efSmrg 
310310d565efSmrg   FOR_EACH_INSN_USE (use, insn)
310410d565efSmrg     df_word_lr_mark_ref (use, true, live);
310510d565efSmrg }
310610d565efSmrg 
310710d565efSmrg /*----------------------------------------------------------------------------
310810d565efSmrg    This problem computes REG_DEAD and REG_UNUSED notes.
310910d565efSmrg    ----------------------------------------------------------------------------*/
311010d565efSmrg 
311110d565efSmrg static void
df_note_alloc(bitmap all_blocks ATTRIBUTE_UNUSED)311210d565efSmrg df_note_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
311310d565efSmrg {
311410d565efSmrg   df_note->optional_p = true;
311510d565efSmrg }
311610d565efSmrg 
311710d565efSmrg /* This is only used if REG_DEAD_DEBUGGING is in effect.  */
311810d565efSmrg static void
df_print_note(const char * prefix,rtx_insn * insn,rtx note)311910d565efSmrg df_print_note (const char *prefix, rtx_insn *insn, rtx note)
312010d565efSmrg {
312110d565efSmrg   if (dump_file)
312210d565efSmrg     {
312310d565efSmrg       fprintf (dump_file, "%s %d ", prefix, INSN_UID (insn));
312410d565efSmrg       print_rtl (dump_file, note);
312510d565efSmrg       fprintf (dump_file, "\n");
312610d565efSmrg     }
312710d565efSmrg }
312810d565efSmrg 
312910d565efSmrg 
313010d565efSmrg /* After reg-stack, the x86 floating point stack regs are difficult to
313110d565efSmrg    analyze because of all of the pushes, pops and rotations.  Thus, we
313210d565efSmrg    just leave the notes alone. */
313310d565efSmrg 
313410d565efSmrg #ifdef STACK_REGS
313510d565efSmrg static inline bool
df_ignore_stack_reg(int regno)313610d565efSmrg df_ignore_stack_reg (int regno)
313710d565efSmrg {
313810d565efSmrg   return regstack_completed
313910d565efSmrg     && IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG);
314010d565efSmrg }
314110d565efSmrg #else
314210d565efSmrg static inline bool
df_ignore_stack_reg(int regno ATTRIBUTE_UNUSED)314310d565efSmrg df_ignore_stack_reg (int regno ATTRIBUTE_UNUSED)
314410d565efSmrg {
314510d565efSmrg   return false;
314610d565efSmrg }
314710d565efSmrg #endif
314810d565efSmrg 
314910d565efSmrg 
315010d565efSmrg /* Remove all of the REG_DEAD or REG_UNUSED notes from INSN.  */
315110d565efSmrg 
315210d565efSmrg static void
df_remove_dead_and_unused_notes(rtx_insn * insn)315310d565efSmrg df_remove_dead_and_unused_notes (rtx_insn *insn)
315410d565efSmrg {
315510d565efSmrg   rtx *pprev = &REG_NOTES (insn);
315610d565efSmrg   rtx link = *pprev;
315710d565efSmrg 
315810d565efSmrg   while (link)
315910d565efSmrg     {
316010d565efSmrg       switch (REG_NOTE_KIND (link))
316110d565efSmrg 	{
316210d565efSmrg 	case REG_DEAD:
316310d565efSmrg 	  /* After reg-stack, we need to ignore any unused notes
316410d565efSmrg 	     for the stack registers.  */
316510d565efSmrg 	  if (df_ignore_stack_reg (REGNO (XEXP (link, 0))))
316610d565efSmrg 	    {
316710d565efSmrg 	      pprev = &XEXP (link, 1);
316810d565efSmrg 	      link = *pprev;
316910d565efSmrg 	    }
317010d565efSmrg 	  else
317110d565efSmrg 	    {
317210d565efSmrg 	      rtx next = XEXP (link, 1);
317310d565efSmrg 	      if (REG_DEAD_DEBUGGING)
317410d565efSmrg 		df_print_note ("deleting: ", insn, link);
317510d565efSmrg 	      free_EXPR_LIST_node (link);
317610d565efSmrg 	      *pprev = link = next;
317710d565efSmrg 	    }
317810d565efSmrg 	  break;
317910d565efSmrg 
318010d565efSmrg 	case REG_UNUSED:
318110d565efSmrg 	  /* After reg-stack, we need to ignore any unused notes
318210d565efSmrg 	     for the stack registers.  */
318310d565efSmrg 	  if (df_ignore_stack_reg (REGNO (XEXP (link, 0))))
318410d565efSmrg 	    {
318510d565efSmrg 	      pprev = &XEXP (link, 1);
318610d565efSmrg 	      link = *pprev;
318710d565efSmrg 	    }
318810d565efSmrg 	  else
318910d565efSmrg 	    {
319010d565efSmrg 	      rtx next = XEXP (link, 1);
319110d565efSmrg 	      if (REG_DEAD_DEBUGGING)
319210d565efSmrg 		df_print_note ("deleting: ", insn, link);
319310d565efSmrg 	      free_EXPR_LIST_node (link);
319410d565efSmrg 	      *pprev = link = next;
319510d565efSmrg 	    }
319610d565efSmrg 	  break;
319710d565efSmrg 
319810d565efSmrg 	default:
319910d565efSmrg 	  pprev = &XEXP (link, 1);
320010d565efSmrg 	  link = *pprev;
320110d565efSmrg 	  break;
320210d565efSmrg 	}
320310d565efSmrg     }
320410d565efSmrg }
320510d565efSmrg 
320610d565efSmrg /* Remove REG_EQUAL/REG_EQUIV notes referring to dead pseudos using LIVE
320710d565efSmrg    as the bitmap of currently live registers.  */
320810d565efSmrg 
320910d565efSmrg static void
df_remove_dead_eq_notes(rtx_insn * insn,bitmap live)321010d565efSmrg df_remove_dead_eq_notes (rtx_insn *insn, bitmap live)
321110d565efSmrg {
321210d565efSmrg   rtx *pprev = &REG_NOTES (insn);
321310d565efSmrg   rtx link = *pprev;
321410d565efSmrg 
321510d565efSmrg   while (link)
321610d565efSmrg     {
321710d565efSmrg       switch (REG_NOTE_KIND (link))
321810d565efSmrg 	{
321910d565efSmrg 	case REG_EQUAL:
322010d565efSmrg 	case REG_EQUIV:
322110d565efSmrg 	  {
322210d565efSmrg 	    /* Remove the notes that refer to dead registers.  As we have at most
322310d565efSmrg 	       one REG_EQUAL/EQUIV note, all of EQ_USES will refer to this note
322410d565efSmrg 	       so we need to purge the complete EQ_USES vector when removing
322510d565efSmrg 	       the note using df_notes_rescan.  */
322610d565efSmrg 	    df_ref use;
322710d565efSmrg 	    bool deleted = false;
322810d565efSmrg 
322910d565efSmrg 	    FOR_EACH_INSN_EQ_USE (use, insn)
32300fc04c29Smrg 	      if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER
323110d565efSmrg 		  && DF_REF_LOC (use)
323210d565efSmrg 		  && (DF_REF_FLAGS (use) & DF_REF_IN_NOTE)
323310d565efSmrg 		  && !bitmap_bit_p (live, DF_REF_REGNO (use))
323410d565efSmrg 		  && loc_mentioned_in_p (DF_REF_LOC (use), XEXP (link, 0)))
323510d565efSmrg 		{
323610d565efSmrg 		  deleted = true;
323710d565efSmrg 		  break;
323810d565efSmrg 		}
323910d565efSmrg 	    if (deleted)
324010d565efSmrg 	      {
324110d565efSmrg 		rtx next;
324210d565efSmrg 		if (REG_DEAD_DEBUGGING)
324310d565efSmrg 		  df_print_note ("deleting: ", insn, link);
324410d565efSmrg 		next = XEXP (link, 1);
324510d565efSmrg 		free_EXPR_LIST_node (link);
324610d565efSmrg 		*pprev = link = next;
324710d565efSmrg 		df_notes_rescan (insn);
324810d565efSmrg 	      }
324910d565efSmrg 	    else
325010d565efSmrg 	      {
325110d565efSmrg 		pprev = &XEXP (link, 1);
325210d565efSmrg 		link = *pprev;
325310d565efSmrg 	      }
325410d565efSmrg 	    break;
325510d565efSmrg 	  }
325610d565efSmrg 
325710d565efSmrg 	default:
325810d565efSmrg 	  pprev = &XEXP (link, 1);
325910d565efSmrg 	  link = *pprev;
326010d565efSmrg 	  break;
326110d565efSmrg 	}
326210d565efSmrg     }
326310d565efSmrg }
326410d565efSmrg 
326510d565efSmrg /* Set a NOTE_TYPE note for REG in INSN.  */
326610d565efSmrg 
326710d565efSmrg static inline void
df_set_note(enum reg_note note_type,rtx_insn * insn,rtx reg)326810d565efSmrg df_set_note (enum reg_note note_type, rtx_insn *insn, rtx reg)
326910d565efSmrg {
327010d565efSmrg   gcc_checking_assert (!DEBUG_INSN_P (insn));
327110d565efSmrg   add_reg_note (insn, note_type, reg);
327210d565efSmrg }
327310d565efSmrg 
327410d565efSmrg /* A subroutine of df_set_unused_notes_for_mw, with a selection of its
327510d565efSmrg    arguments.  Return true if the register value described by MWS's
327610d565efSmrg    mw_reg is known to be completely unused, and if mw_reg can therefore
327710d565efSmrg    be used in a REG_UNUSED note.  */
327810d565efSmrg 
327910d565efSmrg static bool
df_whole_mw_reg_unused_p(struct df_mw_hardreg * mws,bitmap live,bitmap artificial_uses)328010d565efSmrg df_whole_mw_reg_unused_p (struct df_mw_hardreg *mws,
328110d565efSmrg 			  bitmap live, bitmap artificial_uses)
328210d565efSmrg {
328310d565efSmrg   unsigned int r;
328410d565efSmrg 
328510d565efSmrg   /* If MWS describes a partial reference, create REG_UNUSED notes for
328610d565efSmrg      individual hard registers.  */
328710d565efSmrg   if (mws->flags & DF_REF_PARTIAL)
328810d565efSmrg     return false;
328910d565efSmrg 
329010d565efSmrg   /* Likewise if some part of the register is used.  */
329110d565efSmrg   for (r = mws->start_regno; r <= mws->end_regno; r++)
329210d565efSmrg     if (bitmap_bit_p (live, r)
329310d565efSmrg 	|| bitmap_bit_p (artificial_uses, r))
329410d565efSmrg       return false;
329510d565efSmrg 
329610d565efSmrg   gcc_assert (REG_P (mws->mw_reg));
329710d565efSmrg   return true;
329810d565efSmrg }
329910d565efSmrg 
330010d565efSmrg 
330110d565efSmrg /* Set the REG_UNUSED notes for the multiword hardreg defs in INSN
330210d565efSmrg    based on the bits in LIVE.  Do not generate notes for registers in
330310d565efSmrg    artificial uses.  DO_NOT_GEN is updated so that REG_DEAD notes are
330410d565efSmrg    not generated if the reg is both read and written by the
330510d565efSmrg    instruction.
330610d565efSmrg */
330710d565efSmrg 
330810d565efSmrg static void
df_set_unused_notes_for_mw(rtx_insn * insn,struct df_mw_hardreg * mws,bitmap live,bitmap do_not_gen,bitmap artificial_uses,struct dead_debug_local * debug)330910d565efSmrg df_set_unused_notes_for_mw (rtx_insn *insn, struct df_mw_hardreg *mws,
331010d565efSmrg 			    bitmap live, bitmap do_not_gen,
331110d565efSmrg 			    bitmap artificial_uses,
331210d565efSmrg 			    struct dead_debug_local *debug)
331310d565efSmrg {
331410d565efSmrg   unsigned int r;
331510d565efSmrg 
331610d565efSmrg   if (REG_DEAD_DEBUGGING && dump_file)
331710d565efSmrg     fprintf (dump_file, "mw_set_unused looking at mws[%d..%d]\n",
331810d565efSmrg 	     mws->start_regno, mws->end_regno);
331910d565efSmrg 
332010d565efSmrg   if (df_whole_mw_reg_unused_p (mws, live, artificial_uses))
332110d565efSmrg     {
332210d565efSmrg       unsigned int regno = mws->start_regno;
332310d565efSmrg       df_set_note (REG_UNUSED, insn, mws->mw_reg);
332410d565efSmrg       dead_debug_insert_temp (debug, regno, insn, DEBUG_TEMP_AFTER_WITH_REG);
332510d565efSmrg 
332610d565efSmrg       if (REG_DEAD_DEBUGGING)
332710d565efSmrg 	df_print_note ("adding 1: ", insn, REG_NOTES (insn));
332810d565efSmrg 
332910d565efSmrg       bitmap_set_bit (do_not_gen, regno);
333010d565efSmrg       /* Only do this if the value is totally dead.  */
333110d565efSmrg     }
333210d565efSmrg   else
333310d565efSmrg     for (r = mws->start_regno; r <= mws->end_regno; r++)
333410d565efSmrg       {
333510d565efSmrg 	if (!bitmap_bit_p (live, r)
333610d565efSmrg 	    && !bitmap_bit_p (artificial_uses, r))
333710d565efSmrg 	  {
333810d565efSmrg 	    df_set_note (REG_UNUSED, insn, regno_reg_rtx[r]);
333910d565efSmrg 	    dead_debug_insert_temp (debug, r, insn, DEBUG_TEMP_AFTER_WITH_REG);
334010d565efSmrg 	    if (REG_DEAD_DEBUGGING)
334110d565efSmrg 	      df_print_note ("adding 2: ", insn, REG_NOTES (insn));
334210d565efSmrg 	  }
334310d565efSmrg 	bitmap_set_bit (do_not_gen, r);
334410d565efSmrg       }
334510d565efSmrg }
334610d565efSmrg 
334710d565efSmrg 
334810d565efSmrg /* A subroutine of df_set_dead_notes_for_mw, with a selection of its
334910d565efSmrg    arguments.  Return true if the register value described by MWS's
335010d565efSmrg    mw_reg is known to be completely dead, and if mw_reg can therefore
335110d565efSmrg    be used in a REG_DEAD note.  */
335210d565efSmrg 
335310d565efSmrg static bool
df_whole_mw_reg_dead_p(struct df_mw_hardreg * mws,bitmap live,bitmap artificial_uses,bitmap do_not_gen)335410d565efSmrg df_whole_mw_reg_dead_p (struct df_mw_hardreg *mws,
335510d565efSmrg 			bitmap live, bitmap artificial_uses,
335610d565efSmrg 			bitmap do_not_gen)
335710d565efSmrg {
335810d565efSmrg   unsigned int r;
335910d565efSmrg 
336010d565efSmrg   /* If MWS describes a partial reference, create REG_DEAD notes for
336110d565efSmrg      individual hard registers.  */
336210d565efSmrg   if (mws->flags & DF_REF_PARTIAL)
336310d565efSmrg     return false;
336410d565efSmrg 
336510d565efSmrg   /* Likewise if some part of the register is not dead.  */
336610d565efSmrg   for (r = mws->start_regno; r <= mws->end_regno; r++)
336710d565efSmrg     if (bitmap_bit_p (live, r)
336810d565efSmrg 	|| bitmap_bit_p (artificial_uses, r)
336910d565efSmrg 	|| bitmap_bit_p (do_not_gen, r))
337010d565efSmrg       return false;
337110d565efSmrg 
337210d565efSmrg   gcc_assert (REG_P (mws->mw_reg));
337310d565efSmrg   return true;
337410d565efSmrg }
337510d565efSmrg 
337610d565efSmrg /* Set the REG_DEAD notes for the multiword hardreg use in INSN based
337710d565efSmrg    on the bits in LIVE.  DO_NOT_GEN is used to keep REG_DEAD notes
337810d565efSmrg    from being set if the instruction both reads and writes the
337910d565efSmrg    register.  */
338010d565efSmrg 
338110d565efSmrg static void
df_set_dead_notes_for_mw(rtx_insn * insn,struct df_mw_hardreg * mws,bitmap live,bitmap do_not_gen,bitmap artificial_uses,bool * added_notes_p)338210d565efSmrg df_set_dead_notes_for_mw (rtx_insn *insn, struct df_mw_hardreg *mws,
338310d565efSmrg 			  bitmap live, bitmap do_not_gen,
338410d565efSmrg 			  bitmap artificial_uses, bool *added_notes_p)
338510d565efSmrg {
338610d565efSmrg   unsigned int r;
338710d565efSmrg   bool is_debug = *added_notes_p;
338810d565efSmrg 
338910d565efSmrg   *added_notes_p = false;
339010d565efSmrg 
339110d565efSmrg   if (REG_DEAD_DEBUGGING && dump_file)
339210d565efSmrg     {
339310d565efSmrg       fprintf (dump_file, "mw_set_dead looking at mws[%d..%d]\n  do_not_gen =",
339410d565efSmrg 	       mws->start_regno, mws->end_regno);
339510d565efSmrg       df_print_regset (dump_file, do_not_gen);
339610d565efSmrg       fprintf (dump_file, "  live =");
339710d565efSmrg       df_print_regset (dump_file, live);
339810d565efSmrg       fprintf (dump_file, "  artificial uses =");
339910d565efSmrg       df_print_regset (dump_file, artificial_uses);
340010d565efSmrg     }
340110d565efSmrg 
340210d565efSmrg   if (df_whole_mw_reg_dead_p (mws, live, artificial_uses, do_not_gen))
340310d565efSmrg     {
340410d565efSmrg       if (is_debug)
340510d565efSmrg 	{
340610d565efSmrg 	  *added_notes_p = true;
340710d565efSmrg 	  return;
340810d565efSmrg 	}
340910d565efSmrg       /* Add a dead note for the entire multi word register.  */
341010d565efSmrg       df_set_note (REG_DEAD, insn, mws->mw_reg);
341110d565efSmrg       if (REG_DEAD_DEBUGGING)
341210d565efSmrg 	df_print_note ("adding 1: ", insn, REG_NOTES (insn));
341310d565efSmrg     }
341410d565efSmrg   else
341510d565efSmrg     {
341610d565efSmrg       for (r = mws->start_regno; r <= mws->end_regno; r++)
341710d565efSmrg 	if (!bitmap_bit_p (live, r)
341810d565efSmrg 	    && !bitmap_bit_p (artificial_uses, r)
341910d565efSmrg 	    && !bitmap_bit_p (do_not_gen, r))
342010d565efSmrg 	  {
342110d565efSmrg 	    if (is_debug)
342210d565efSmrg 	      {
342310d565efSmrg 		*added_notes_p = true;
342410d565efSmrg 		return;
342510d565efSmrg 	      }
342610d565efSmrg 	    df_set_note (REG_DEAD, insn, regno_reg_rtx[r]);
342710d565efSmrg 	    if (REG_DEAD_DEBUGGING)
342810d565efSmrg 	      df_print_note ("adding 2: ", insn, REG_NOTES (insn));
342910d565efSmrg 	  }
343010d565efSmrg     }
343110d565efSmrg   return;
343210d565efSmrg }
343310d565efSmrg 
343410d565efSmrg 
343510d565efSmrg /* Create a REG_UNUSED note if necessary for DEF in INSN updating
343610d565efSmrg    LIVE.  Do not generate notes for registers in ARTIFICIAL_USES.  */
343710d565efSmrg 
343810d565efSmrg static void
df_create_unused_note(rtx_insn * insn,df_ref def,bitmap live,bitmap artificial_uses,struct dead_debug_local * debug)343910d565efSmrg df_create_unused_note (rtx_insn *insn, df_ref def,
344010d565efSmrg 		       bitmap live, bitmap artificial_uses,
344110d565efSmrg 		       struct dead_debug_local *debug)
344210d565efSmrg {
344310d565efSmrg   unsigned int dregno = DF_REF_REGNO (def);
344410d565efSmrg 
344510d565efSmrg   if (REG_DEAD_DEBUGGING && dump_file)
344610d565efSmrg     {
344710d565efSmrg       fprintf (dump_file, "  regular looking at def ");
344810d565efSmrg       df_ref_debug (def, dump_file);
344910d565efSmrg     }
345010d565efSmrg 
345110d565efSmrg   if (!((DF_REF_FLAGS (def) & DF_REF_MW_HARDREG)
345210d565efSmrg 	|| bitmap_bit_p (live, dregno)
345310d565efSmrg 	|| bitmap_bit_p (artificial_uses, dregno)
345410d565efSmrg 	|| df_ignore_stack_reg (dregno)))
345510d565efSmrg     {
345610d565efSmrg       rtx reg = (DF_REF_LOC (def))
345710d565efSmrg                 ? *DF_REF_REAL_LOC (def): DF_REF_REG (def);
345810d565efSmrg       df_set_note (REG_UNUSED, insn, reg);
345910d565efSmrg       dead_debug_insert_temp (debug, dregno, insn, DEBUG_TEMP_AFTER_WITH_REG);
346010d565efSmrg       if (REG_DEAD_DEBUGGING)
346110d565efSmrg 	df_print_note ("adding 3: ", insn, REG_NOTES (insn));
346210d565efSmrg     }
346310d565efSmrg 
346410d565efSmrg   return;
346510d565efSmrg }
346610d565efSmrg 
346710d565efSmrg 
346810d565efSmrg /* Recompute the REG_DEAD and REG_UNUSED notes and compute register
346910d565efSmrg    info: lifetime, bb, and number of defs and uses for basic block
347010d565efSmrg    BB.  The three bitvectors are scratch regs used here.  */
347110d565efSmrg 
347210d565efSmrg static void
df_note_bb_compute(unsigned int bb_index,bitmap live,bitmap do_not_gen,bitmap artificial_uses)347310d565efSmrg df_note_bb_compute (unsigned int bb_index,
347410d565efSmrg 		    bitmap live, bitmap do_not_gen, bitmap artificial_uses)
347510d565efSmrg {
347610d565efSmrg   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
347710d565efSmrg   rtx_insn *insn;
347810d565efSmrg   df_ref def, use;
347910d565efSmrg   struct dead_debug_local debug;
348010d565efSmrg 
348110d565efSmrg   dead_debug_local_init (&debug, NULL, NULL);
348210d565efSmrg 
348310d565efSmrg   bitmap_copy (live, df_get_live_out (bb));
348410d565efSmrg   bitmap_clear (artificial_uses);
348510d565efSmrg 
348610d565efSmrg   if (REG_DEAD_DEBUGGING && dump_file)
348710d565efSmrg     {
348810d565efSmrg       fprintf (dump_file, "live at bottom ");
348910d565efSmrg       df_print_regset (dump_file, live);
349010d565efSmrg     }
349110d565efSmrg 
349210d565efSmrg   /* Process the artificial defs and uses at the bottom of the block
349310d565efSmrg      to begin processing.  */
349410d565efSmrg   FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
349510d565efSmrg     {
349610d565efSmrg       if (REG_DEAD_DEBUGGING && dump_file)
349710d565efSmrg 	fprintf (dump_file, "artificial def %d\n", DF_REF_REGNO (def));
349810d565efSmrg 
349910d565efSmrg       if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
350010d565efSmrg 	bitmap_clear_bit (live, DF_REF_REGNO (def));
350110d565efSmrg     }
350210d565efSmrg 
350310d565efSmrg   FOR_EACH_ARTIFICIAL_USE (use, bb_index)
350410d565efSmrg     if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
350510d565efSmrg       {
350610d565efSmrg 	unsigned int regno = DF_REF_REGNO (use);
350710d565efSmrg 	bitmap_set_bit (live, regno);
350810d565efSmrg 
350910d565efSmrg 	/* Notes are not generated for any of the artificial registers
351010d565efSmrg 	   at the bottom of the block.  */
351110d565efSmrg 	bitmap_set_bit (artificial_uses, regno);
351210d565efSmrg       }
351310d565efSmrg 
351410d565efSmrg   if (REG_DEAD_DEBUGGING && dump_file)
351510d565efSmrg     {
351610d565efSmrg       fprintf (dump_file, "live before artificials out ");
351710d565efSmrg       df_print_regset (dump_file, live);
351810d565efSmrg     }
351910d565efSmrg 
352010d565efSmrg   FOR_BB_INSNS_REVERSE (bb, insn)
352110d565efSmrg     {
352210d565efSmrg       if (!INSN_P (insn))
352310d565efSmrg 	continue;
352410d565efSmrg 
352510d565efSmrg       df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
352610d565efSmrg       df_mw_hardreg *mw;
352710d565efSmrg       int debug_insn;
352810d565efSmrg 
352910d565efSmrg       debug_insn = DEBUG_INSN_P (insn);
353010d565efSmrg 
353110d565efSmrg       bitmap_clear (do_not_gen);
353210d565efSmrg       df_remove_dead_and_unused_notes (insn);
353310d565efSmrg 
353410d565efSmrg       /* Process the defs.  */
353510d565efSmrg       if (CALL_P (insn))
353610d565efSmrg 	{
353710d565efSmrg 	  if (REG_DEAD_DEBUGGING && dump_file)
353810d565efSmrg 	    {
353910d565efSmrg 	      fprintf (dump_file, "processing call %d\n  live =",
354010d565efSmrg 		       INSN_UID (insn));
354110d565efSmrg 	      df_print_regset (dump_file, live);
354210d565efSmrg 	    }
354310d565efSmrg 
354410d565efSmrg 	  /* We only care about real sets for calls.  Clobbers cannot
354510d565efSmrg 	     be depended on to really die.  */
354610d565efSmrg 	  FOR_EACH_INSN_INFO_MW (mw, insn_info)
354710d565efSmrg 	    if ((DF_MWS_REG_DEF_P (mw))
354810d565efSmrg 		&& !df_ignore_stack_reg (mw->start_regno))
354910d565efSmrg 	      df_set_unused_notes_for_mw (insn, mw, live, do_not_gen,
355010d565efSmrg 					  artificial_uses, &debug);
355110d565efSmrg 
355210d565efSmrg 	  /* All of the defs except the return value are some sort of
355310d565efSmrg 	     clobber.  This code is for the return.  */
355410d565efSmrg 	  FOR_EACH_INSN_INFO_DEF (def, insn_info)
355510d565efSmrg 	    {
355610d565efSmrg 	      unsigned int dregno = DF_REF_REGNO (def);
355710d565efSmrg 	      if (!DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))
355810d565efSmrg 		{
355910d565efSmrg 		  df_create_unused_note (insn,
356010d565efSmrg 					 def, live, artificial_uses, &debug);
356110d565efSmrg 		  bitmap_set_bit (do_not_gen, dregno);
356210d565efSmrg 		}
356310d565efSmrg 
356410d565efSmrg 	      if (!DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL | DF_REF_CONDITIONAL))
356510d565efSmrg 		bitmap_clear_bit (live, dregno);
356610d565efSmrg 	    }
356710d565efSmrg 	}
356810d565efSmrg       else
356910d565efSmrg 	{
357010d565efSmrg 	  /* Regular insn.  */
357110d565efSmrg 	  FOR_EACH_INSN_INFO_MW (mw, insn_info)
357210d565efSmrg 	    if (DF_MWS_REG_DEF_P (mw))
357310d565efSmrg 	      df_set_unused_notes_for_mw (insn, mw, live, do_not_gen,
357410d565efSmrg 					  artificial_uses, &debug);
357510d565efSmrg 
357610d565efSmrg 	  FOR_EACH_INSN_INFO_DEF (def, insn_info)
357710d565efSmrg 	    {
357810d565efSmrg 	      unsigned int dregno = DF_REF_REGNO (def);
357910d565efSmrg 	      df_create_unused_note (insn,
358010d565efSmrg 				     def, live, artificial_uses, &debug);
358110d565efSmrg 
358210d565efSmrg 	      if (!DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))
358310d565efSmrg 		bitmap_set_bit (do_not_gen, dregno);
358410d565efSmrg 
358510d565efSmrg 	      if (!DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL | DF_REF_CONDITIONAL))
358610d565efSmrg 		bitmap_clear_bit (live, dregno);
358710d565efSmrg 	    }
358810d565efSmrg 	}
358910d565efSmrg 
359010d565efSmrg       /* Process the uses.  */
359110d565efSmrg       FOR_EACH_INSN_INFO_MW (mw, insn_info)
359210d565efSmrg 	if (DF_MWS_REG_USE_P (mw)
359310d565efSmrg 	    && !df_ignore_stack_reg (mw->start_regno))
359410d565efSmrg 	  {
359510d565efSmrg 	    bool really_add_notes = debug_insn != 0;
359610d565efSmrg 
359710d565efSmrg 	    df_set_dead_notes_for_mw (insn, mw, live, do_not_gen,
359810d565efSmrg 				      artificial_uses,
359910d565efSmrg 				      &really_add_notes);
360010d565efSmrg 
360110d565efSmrg 	    if (really_add_notes)
360210d565efSmrg 	      debug_insn = -1;
360310d565efSmrg 	  }
360410d565efSmrg 
360510d565efSmrg       FOR_EACH_INSN_INFO_USE (use, insn_info)
360610d565efSmrg 	{
360710d565efSmrg 	  unsigned int uregno = DF_REF_REGNO (use);
360810d565efSmrg 
360910d565efSmrg 	  if (REG_DEAD_DEBUGGING && dump_file && !debug_insn)
361010d565efSmrg 	    {
361110d565efSmrg 	      fprintf (dump_file, "  regular looking at use ");
361210d565efSmrg 	      df_ref_debug (use, dump_file);
361310d565efSmrg 	    }
361410d565efSmrg 
361510d565efSmrg 	  if (!bitmap_bit_p (live, uregno))
361610d565efSmrg 	    {
361710d565efSmrg 	      if (debug_insn)
361810d565efSmrg 		{
361910d565efSmrg 		  if (debug_insn > 0)
362010d565efSmrg 		    {
362110d565efSmrg 		      /* We won't add REG_UNUSED or REG_DEAD notes for
362210d565efSmrg 			 these, so we don't have to mess with them in
362310d565efSmrg 			 debug insns either.  */
362410d565efSmrg 		      if (!bitmap_bit_p (artificial_uses, uregno)
362510d565efSmrg 			  && !df_ignore_stack_reg (uregno))
362610d565efSmrg 			dead_debug_add (&debug, use, uregno);
362710d565efSmrg 		      continue;
362810d565efSmrg 		    }
362910d565efSmrg 		  break;
363010d565efSmrg 		}
363110d565efSmrg 	      else
363210d565efSmrg 		dead_debug_insert_temp (&debug, uregno, insn,
363310d565efSmrg 					DEBUG_TEMP_BEFORE_WITH_REG);
363410d565efSmrg 
363510d565efSmrg 	      if ( (!(DF_REF_FLAGS (use)
363610d565efSmrg 		      & (DF_REF_MW_HARDREG | DF_REF_READ_WRITE)))
363710d565efSmrg 		   && (!bitmap_bit_p (do_not_gen, uregno))
363810d565efSmrg 		   && (!bitmap_bit_p (artificial_uses, uregno))
363910d565efSmrg 		   && (!df_ignore_stack_reg (uregno)))
364010d565efSmrg 		{
364110d565efSmrg 		  rtx reg = (DF_REF_LOC (use))
364210d565efSmrg                             ? *DF_REF_REAL_LOC (use) : DF_REF_REG (use);
364310d565efSmrg 		  df_set_note (REG_DEAD, insn, reg);
364410d565efSmrg 
364510d565efSmrg 		  if (REG_DEAD_DEBUGGING)
364610d565efSmrg 		    df_print_note ("adding 4: ", insn, REG_NOTES (insn));
364710d565efSmrg 		}
364810d565efSmrg 	      /* This register is now live.  */
364910d565efSmrg 	      bitmap_set_bit (live, uregno);
365010d565efSmrg 	    }
365110d565efSmrg 	}
365210d565efSmrg 
365310d565efSmrg       df_remove_dead_eq_notes (insn, live);
365410d565efSmrg 
365510d565efSmrg       if (debug_insn == -1)
365610d565efSmrg 	{
365710d565efSmrg 	  /* ??? We could probably do better here, replacing dead
365810d565efSmrg 	     registers with their definitions.  */
365910d565efSmrg 	  INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
366010d565efSmrg 	  df_insn_rescan_debug_internal (insn);
366110d565efSmrg 	}
366210d565efSmrg     }
366310d565efSmrg 
366410d565efSmrg   dead_debug_local_finish (&debug, NULL);
366510d565efSmrg }
366610d565efSmrg 
366710d565efSmrg 
366810d565efSmrg /* Compute register info: lifetime, bb, and number of defs and uses.  */
366910d565efSmrg static void
df_note_compute(bitmap all_blocks)367010d565efSmrg df_note_compute (bitmap all_blocks)
367110d565efSmrg {
367210d565efSmrg   unsigned int bb_index;
367310d565efSmrg   bitmap_iterator bi;
367410d565efSmrg   bitmap_head live, do_not_gen, artificial_uses;
367510d565efSmrg 
367610d565efSmrg   bitmap_initialize (&live, &df_bitmap_obstack);
367710d565efSmrg   bitmap_initialize (&do_not_gen, &df_bitmap_obstack);
367810d565efSmrg   bitmap_initialize (&artificial_uses, &df_bitmap_obstack);
367910d565efSmrg 
368010d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
368110d565efSmrg   {
368210d565efSmrg     /* ??? Unlike fast DCE, we don't use global_debug for uses of dead
368310d565efSmrg        pseudos in debug insns because we don't always (re)visit blocks
368410d565efSmrg        with death points after visiting dead uses.  Even changing this
368510d565efSmrg        loop to postorder would still leave room for visiting a death
368610d565efSmrg        point before visiting a subsequent debug use.  */
368710d565efSmrg     df_note_bb_compute (bb_index, &live, &do_not_gen, &artificial_uses);
368810d565efSmrg   }
368910d565efSmrg 
369010d565efSmrg   bitmap_clear (&live);
369110d565efSmrg   bitmap_clear (&do_not_gen);
369210d565efSmrg   bitmap_clear (&artificial_uses);
369310d565efSmrg }
369410d565efSmrg 
369510d565efSmrg 
369610d565efSmrg /* Free all storage associated with the problem.  */
369710d565efSmrg 
369810d565efSmrg static void
df_note_free(void)369910d565efSmrg df_note_free (void)
370010d565efSmrg {
370110d565efSmrg   free (df_note);
370210d565efSmrg }
370310d565efSmrg 
370410d565efSmrg 
370510d565efSmrg /* All of the information associated every instance of the problem.  */
370610d565efSmrg 
370710d565efSmrg static const struct df_problem problem_NOTE =
370810d565efSmrg {
370910d565efSmrg   DF_NOTE,                    /* Problem id.  */
371010d565efSmrg   DF_NONE,                    /* Direction.  */
371110d565efSmrg   df_note_alloc,              /* Allocate the problem specific data.  */
371210d565efSmrg   NULL,                       /* Reset global information.  */
371310d565efSmrg   NULL,                       /* Free basic block info.  */
371410d565efSmrg   df_note_compute,            /* Local compute function.  */
371510d565efSmrg   NULL,                       /* Init the solution specific data.  */
371610d565efSmrg   NULL,                       /* Iterative solver.  */
371710d565efSmrg   NULL,                       /* Confluence operator 0.  */
371810d565efSmrg   NULL,                       /* Confluence operator n.  */
371910d565efSmrg   NULL,                       /* Transfer function.  */
372010d565efSmrg   NULL,                       /* Finalize function.  */
372110d565efSmrg   df_note_free,               /* Free all of the problem information.  */
372210d565efSmrg   df_note_free,               /* Remove this problem from the stack of dataflow problems.  */
372310d565efSmrg   NULL,                       /* Debugging.  */
372410d565efSmrg   NULL,                       /* Debugging start block.  */
372510d565efSmrg   NULL,                       /* Debugging end block.  */
372610d565efSmrg   NULL,                       /* Debugging start insn.  */
372710d565efSmrg   NULL,                       /* Debugging end insn.  */
372810d565efSmrg   NULL,                       /* Incremental solution verify start.  */
372910d565efSmrg   NULL,                       /* Incremental solution verify end.  */
373010d565efSmrg   &problem_LR,                /* Dependent problem.  */
373110d565efSmrg   sizeof (struct df_scan_bb_info),/* Size of entry of block_info array.  */
373210d565efSmrg   TV_DF_NOTE,                 /* Timing variable.  */
373310d565efSmrg   false                       /* Reset blocks on dropping out of blocks_to_analyze.  */
373410d565efSmrg };
373510d565efSmrg 
373610d565efSmrg 
373710d565efSmrg /* Create a new DATAFLOW instance and add it to an existing instance
373810d565efSmrg    of DF.  The returned structure is what is used to get at the
373910d565efSmrg    solution.  */
374010d565efSmrg 
374110d565efSmrg void
df_note_add_problem(void)374210d565efSmrg df_note_add_problem (void)
374310d565efSmrg {
374410d565efSmrg   df_add_problem (&problem_NOTE);
374510d565efSmrg }
374610d565efSmrg 
374710d565efSmrg 
374810d565efSmrg 
374910d565efSmrg 
375010d565efSmrg /*----------------------------------------------------------------------------
375110d565efSmrg    Functions for simulating the effects of single insns.
375210d565efSmrg 
375310d565efSmrg    You can either simulate in the forwards direction, starting from
375410d565efSmrg    the top of a block or the backwards direction from the end of the
375510d565efSmrg    block.  If you go backwards, defs are examined first to clear bits,
375610d565efSmrg    then uses are examined to set bits.  If you go forwards, defs are
375710d565efSmrg    examined first to set bits, then REG_DEAD and REG_UNUSED notes
375810d565efSmrg    are examined to clear bits.  In either case, the result of examining
375910d565efSmrg    a def can be undone (respectively by a use or a REG_UNUSED note).
376010d565efSmrg 
376110d565efSmrg    If you start at the top of the block, use one of DF_LIVE_IN or
376210d565efSmrg    DF_LR_IN.  If you start at the bottom of the block use one of
376310d565efSmrg    DF_LIVE_OUT or DF_LR_OUT.  BE SURE TO PASS A COPY OF THESE SETS,
376410d565efSmrg    THEY WILL BE DESTROYED.
376510d565efSmrg ----------------------------------------------------------------------------*/
376610d565efSmrg 
376710d565efSmrg 
376810d565efSmrg /* Find the set of DEFs for INSN.  */
376910d565efSmrg 
377010d565efSmrg void
df_simulate_find_defs(rtx_insn * insn,bitmap defs)377110d565efSmrg df_simulate_find_defs (rtx_insn *insn, bitmap defs)
377210d565efSmrg {
377310d565efSmrg   df_ref def;
377410d565efSmrg 
377510d565efSmrg   FOR_EACH_INSN_DEF (def, insn)
377610d565efSmrg     bitmap_set_bit (defs, DF_REF_REGNO (def));
377710d565efSmrg }
377810d565efSmrg 
377910d565efSmrg /* Find the set of uses for INSN.  This includes partial defs.  */
378010d565efSmrg 
378110d565efSmrg static void
df_simulate_find_uses(rtx_insn * insn,bitmap uses)378210d565efSmrg df_simulate_find_uses (rtx_insn *insn, bitmap uses)
378310d565efSmrg {
378410d565efSmrg   df_ref def, use;
378510d565efSmrg   struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
378610d565efSmrg 
378710d565efSmrg   FOR_EACH_INSN_INFO_DEF (def, insn_info)
378810d565efSmrg     if (DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))
378910d565efSmrg       bitmap_set_bit (uses, DF_REF_REGNO (def));
379010d565efSmrg   FOR_EACH_INSN_INFO_USE (use, insn_info)
379110d565efSmrg     bitmap_set_bit (uses, DF_REF_REGNO (use));
379210d565efSmrg }
379310d565efSmrg 
379410d565efSmrg /* Find the set of real DEFs, which are not clobbers, for INSN.  */
379510d565efSmrg 
379610d565efSmrg void
df_simulate_find_noclobber_defs(rtx_insn * insn,bitmap defs)379710d565efSmrg df_simulate_find_noclobber_defs (rtx_insn *insn, bitmap defs)
379810d565efSmrg {
379910d565efSmrg   df_ref def;
380010d565efSmrg 
380110d565efSmrg   FOR_EACH_INSN_DEF (def, insn)
380210d565efSmrg     if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
380310d565efSmrg       bitmap_set_bit (defs, DF_REF_REGNO (def));
380410d565efSmrg }
380510d565efSmrg 
380610d565efSmrg 
380710d565efSmrg /* Simulate the effects of the defs of INSN on LIVE.  */
380810d565efSmrg 
380910d565efSmrg void
df_simulate_defs(rtx_insn * insn,bitmap live)381010d565efSmrg df_simulate_defs (rtx_insn *insn, bitmap live)
381110d565efSmrg {
381210d565efSmrg   df_ref def;
381310d565efSmrg 
381410d565efSmrg   FOR_EACH_INSN_DEF (def, insn)
381510d565efSmrg     {
381610d565efSmrg       unsigned int dregno = DF_REF_REGNO (def);
381710d565efSmrg 
381810d565efSmrg       /* If the def is to only part of the reg, it does
381910d565efSmrg 	 not kill the other defs that reach here.  */
382010d565efSmrg       if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
382110d565efSmrg 	bitmap_clear_bit (live, dregno);
382210d565efSmrg     }
382310d565efSmrg }
382410d565efSmrg 
382510d565efSmrg 
382610d565efSmrg /* Simulate the effects of the uses of INSN on LIVE.  */
382710d565efSmrg 
382810d565efSmrg void
df_simulate_uses(rtx_insn * insn,bitmap live)382910d565efSmrg df_simulate_uses (rtx_insn *insn, bitmap live)
383010d565efSmrg {
383110d565efSmrg   df_ref use;
383210d565efSmrg 
383310d565efSmrg   if (DEBUG_INSN_P (insn))
383410d565efSmrg     return;
383510d565efSmrg 
383610d565efSmrg   FOR_EACH_INSN_USE (use, insn)
383710d565efSmrg     /* Add use to set of uses in this BB.  */
383810d565efSmrg     bitmap_set_bit (live, DF_REF_REGNO (use));
383910d565efSmrg }
384010d565efSmrg 
384110d565efSmrg 
384210d565efSmrg /* Add back the always live regs in BB to LIVE.  */
384310d565efSmrg 
384410d565efSmrg static inline void
df_simulate_fixup_sets(basic_block bb,bitmap live)384510d565efSmrg df_simulate_fixup_sets (basic_block bb, bitmap live)
384610d565efSmrg {
384710d565efSmrg   /* These regs are considered always live so if they end up dying
384810d565efSmrg      because of some def, we need to bring the back again.  */
384910d565efSmrg   if (bb_has_eh_pred (bb))
385010d565efSmrg     bitmap_ior_into (live, &df->eh_block_artificial_uses);
385110d565efSmrg   else
385210d565efSmrg     bitmap_ior_into (live, &df->regular_block_artificial_uses);
385310d565efSmrg }
385410d565efSmrg 
385510d565efSmrg 
385610d565efSmrg /*----------------------------------------------------------------------------
385710d565efSmrg    The following three functions are used only for BACKWARDS scanning:
385810d565efSmrg    i.e. they process the defs before the uses.
385910d565efSmrg 
386010d565efSmrg    df_simulate_initialize_backwards should be called first with a
386110d565efSmrg    bitvector copyied from the DF_LIVE_OUT or DF_LR_OUT.  Then
386210d565efSmrg    df_simulate_one_insn_backwards should be called for each insn in
386310d565efSmrg    the block, starting with the last one.  Finally,
386410d565efSmrg    df_simulate_finalize_backwards can be called to get a new value
386510d565efSmrg    of the sets at the top of the block (this is rarely used).
386610d565efSmrg    ----------------------------------------------------------------------------*/
386710d565efSmrg 
386810d565efSmrg /* Apply the artificial uses and defs at the end of BB in a backwards
386910d565efSmrg    direction.  */
387010d565efSmrg 
387110d565efSmrg void
df_simulate_initialize_backwards(basic_block bb,bitmap live)387210d565efSmrg df_simulate_initialize_backwards (basic_block bb, bitmap live)
387310d565efSmrg {
387410d565efSmrg   df_ref def, use;
387510d565efSmrg   int bb_index = bb->index;
387610d565efSmrg 
387710d565efSmrg   FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
387810d565efSmrg     if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
387910d565efSmrg       bitmap_clear_bit (live, DF_REF_REGNO (def));
388010d565efSmrg 
388110d565efSmrg   FOR_EACH_ARTIFICIAL_USE (use, bb_index)
388210d565efSmrg     if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
388310d565efSmrg       bitmap_set_bit (live, DF_REF_REGNO (use));
388410d565efSmrg }
388510d565efSmrg 
388610d565efSmrg 
388710d565efSmrg /* Simulate the backwards effects of INSN on the bitmap LIVE.  */
388810d565efSmrg 
388910d565efSmrg void
df_simulate_one_insn_backwards(basic_block bb,rtx_insn * insn,bitmap live)389010d565efSmrg df_simulate_one_insn_backwards (basic_block bb, rtx_insn *insn, bitmap live)
389110d565efSmrg {
389210d565efSmrg   if (!NONDEBUG_INSN_P (insn))
389310d565efSmrg     return;
389410d565efSmrg 
389510d565efSmrg   df_simulate_defs (insn, live);
389610d565efSmrg   df_simulate_uses (insn, live);
389710d565efSmrg   df_simulate_fixup_sets (bb, live);
389810d565efSmrg }
389910d565efSmrg 
390010d565efSmrg 
390110d565efSmrg /* Apply the artificial uses and defs at the top of BB in a backwards
390210d565efSmrg    direction.  */
390310d565efSmrg 
390410d565efSmrg void
df_simulate_finalize_backwards(basic_block bb,bitmap live)390510d565efSmrg df_simulate_finalize_backwards (basic_block bb, bitmap live)
390610d565efSmrg {
390710d565efSmrg   df_ref def;
390810d565efSmrg #ifdef EH_USES
390910d565efSmrg   df_ref use;
391010d565efSmrg #endif
391110d565efSmrg   int bb_index = bb->index;
391210d565efSmrg 
391310d565efSmrg   FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
391410d565efSmrg     if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
391510d565efSmrg       bitmap_clear_bit (live, DF_REF_REGNO (def));
391610d565efSmrg 
391710d565efSmrg #ifdef EH_USES
391810d565efSmrg   FOR_EACH_ARTIFICIAL_USE (use, bb_index)
391910d565efSmrg     if (DF_REF_FLAGS (use) & DF_REF_AT_TOP)
392010d565efSmrg       bitmap_set_bit (live, DF_REF_REGNO (use));
392110d565efSmrg #endif
392210d565efSmrg }
392310d565efSmrg /*----------------------------------------------------------------------------
392410d565efSmrg    The following three functions are used only for FORWARDS scanning:
392510d565efSmrg    i.e. they process the defs and the REG_DEAD and REG_UNUSED notes.
392610d565efSmrg    Thus it is important to add the DF_NOTES problem to the stack of
392710d565efSmrg    problems computed before using these functions.
392810d565efSmrg 
392910d565efSmrg    df_simulate_initialize_forwards should be called first with a
393010d565efSmrg    bitvector copyied from the DF_LIVE_IN or DF_LR_IN.  Then
393110d565efSmrg    df_simulate_one_insn_forwards should be called for each insn in
393210d565efSmrg    the block, starting with the first one.
393310d565efSmrg    ----------------------------------------------------------------------------*/
393410d565efSmrg 
393510d565efSmrg /* Initialize the LIVE bitmap, which should be copied from DF_LIVE_IN or
393610d565efSmrg    DF_LR_IN for basic block BB, for forward scanning by marking artificial
393710d565efSmrg    defs live.  */
393810d565efSmrg 
393910d565efSmrg void
df_simulate_initialize_forwards(basic_block bb,bitmap live)394010d565efSmrg df_simulate_initialize_forwards (basic_block bb, bitmap live)
394110d565efSmrg {
394210d565efSmrg   df_ref def;
394310d565efSmrg   int bb_index = bb->index;
394410d565efSmrg 
394510d565efSmrg   FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
394610d565efSmrg     if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
394710d565efSmrg       bitmap_set_bit (live, DF_REF_REGNO (def));
394810d565efSmrg }
394910d565efSmrg 
395010d565efSmrg /* Simulate the forwards effects of INSN on the bitmap LIVE.  */
395110d565efSmrg 
395210d565efSmrg void
df_simulate_one_insn_forwards(basic_block bb,rtx_insn * insn,bitmap live)395310d565efSmrg df_simulate_one_insn_forwards (basic_block bb, rtx_insn *insn, bitmap live)
395410d565efSmrg {
395510d565efSmrg   rtx link;
395610d565efSmrg   if (! INSN_P (insn))
395710d565efSmrg     return;
395810d565efSmrg 
395910d565efSmrg   /* Make sure that DF_NOTE really is an active df problem.  */
396010d565efSmrg   gcc_assert (df_note);
396110d565efSmrg 
396210d565efSmrg   /* Note that this is the opposite as how the problem is defined, because
396310d565efSmrg      in the LR problem defs _kill_ liveness.  However, they do so backwards,
396410d565efSmrg      while here the scan is performed forwards!  So, first assume that the
396510d565efSmrg      def is live, and if this is not true REG_UNUSED notes will rectify the
396610d565efSmrg      situation.  */
396710d565efSmrg   df_simulate_find_noclobber_defs (insn, live);
396810d565efSmrg 
396910d565efSmrg   /* Clear all of the registers that go dead.  */
397010d565efSmrg   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
397110d565efSmrg     {
397210d565efSmrg       switch (REG_NOTE_KIND (link))
397310d565efSmrg 	{
397410d565efSmrg 	case REG_DEAD:
397510d565efSmrg 	case REG_UNUSED:
397610d565efSmrg 	  {
397710d565efSmrg 	    rtx reg = XEXP (link, 0);
397810d565efSmrg 	    bitmap_clear_range (live, REGNO (reg), REG_NREGS (reg));
397910d565efSmrg 	  }
398010d565efSmrg 	  break;
398110d565efSmrg 	default:
398210d565efSmrg 	  break;
398310d565efSmrg 	}
398410d565efSmrg     }
398510d565efSmrg   df_simulate_fixup_sets (bb, live);
398610d565efSmrg }
398710d565efSmrg 
398810d565efSmrg /* Used by the next two functions to encode information about the
398910d565efSmrg    memory references we found.  */
399010d565efSmrg #define MEMREF_NORMAL 1
399110d565efSmrg #define MEMREF_VOLATILE 2
399210d565efSmrg 
399310d565efSmrg /* Return an OR of MEMREF_NORMAL or MEMREF_VOLATILE for the MEMs in X.  */
399410d565efSmrg 
399510d565efSmrg static int
find_memory(rtx_insn * insn)399610d565efSmrg find_memory (rtx_insn *insn)
399710d565efSmrg {
399810d565efSmrg   int flags = 0;
399910d565efSmrg   subrtx_iterator::array_type array;
400010d565efSmrg   FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
400110d565efSmrg     {
400210d565efSmrg       const_rtx x = *iter;
400310d565efSmrg       if (GET_CODE (x) == ASM_OPERANDS && MEM_VOLATILE_P (x))
400410d565efSmrg 	flags |= MEMREF_VOLATILE;
400510d565efSmrg       else if (MEM_P (x))
400610d565efSmrg 	{
400710d565efSmrg 	  if (MEM_VOLATILE_P (x))
400810d565efSmrg 	    flags |= MEMREF_VOLATILE;
400910d565efSmrg 	  else if (!MEM_READONLY_P (x))
401010d565efSmrg 	    flags |= MEMREF_NORMAL;
401110d565efSmrg 	}
401210d565efSmrg     }
401310d565efSmrg   return flags;
401410d565efSmrg }
401510d565efSmrg 
401610d565efSmrg /* A subroutine of can_move_insns_across_p called through note_stores.
401710d565efSmrg    DATA points to an integer in which we set either the bit for
401810d565efSmrg    MEMREF_NORMAL or the bit for MEMREF_VOLATILE if we find a MEM
401910d565efSmrg    of either kind.  */
402010d565efSmrg 
402110d565efSmrg static void
find_memory_stores(rtx x,const_rtx pat ATTRIBUTE_UNUSED,void * data ATTRIBUTE_UNUSED)402210d565efSmrg find_memory_stores (rtx x, const_rtx pat ATTRIBUTE_UNUSED,
402310d565efSmrg 		    void *data ATTRIBUTE_UNUSED)
402410d565efSmrg {
402510d565efSmrg   int *pflags = (int *)data;
402610d565efSmrg   if (GET_CODE (x) == SUBREG)
402710d565efSmrg     x = XEXP (x, 0);
402810d565efSmrg   /* Treat stores to SP as stores to memory, this will prevent problems
402910d565efSmrg      when there are references to the stack frame.  */
403010d565efSmrg   if (x == stack_pointer_rtx)
403110d565efSmrg     *pflags |= MEMREF_VOLATILE;
403210d565efSmrg   if (!MEM_P (x))
403310d565efSmrg     return;
403410d565efSmrg   *pflags |= MEM_VOLATILE_P (x) ? MEMREF_VOLATILE : MEMREF_NORMAL;
403510d565efSmrg }
403610d565efSmrg 
403710d565efSmrg /* Scan BB backwards, using df_simulate functions to keep track of
403810d565efSmrg    lifetimes, up to insn POINT.  The result is stored in LIVE.  */
403910d565efSmrg 
404010d565efSmrg void
simulate_backwards_to_point(basic_block bb,regset live,rtx point)404110d565efSmrg simulate_backwards_to_point (basic_block bb, regset live, rtx point)
404210d565efSmrg {
404310d565efSmrg   rtx_insn *insn;
404410d565efSmrg   bitmap_copy (live, df_get_live_out (bb));
404510d565efSmrg   df_simulate_initialize_backwards (bb, live);
404610d565efSmrg 
404710d565efSmrg   /* Scan and update life information until we reach the point we're
404810d565efSmrg      interested in.  */
404910d565efSmrg   for (insn = BB_END (bb); insn != point; insn = PREV_INSN (insn))
405010d565efSmrg     df_simulate_one_insn_backwards (bb, insn, live);
405110d565efSmrg }
405210d565efSmrg 
405310d565efSmrg /* Return true if it is safe to move a group of insns, described by
405410d565efSmrg    the range FROM to TO, backwards across another group of insns,
405510d565efSmrg    described by ACROSS_FROM to ACROSS_TO.  It is assumed that there
405610d565efSmrg    are no insns between ACROSS_TO and FROM, but they may be in
405710d565efSmrg    different basic blocks; MERGE_BB is the block from which the
405810d565efSmrg    insns will be moved.  The caller must pass in a regset MERGE_LIVE
405910d565efSmrg    which specifies the registers live after TO.
406010d565efSmrg 
406110d565efSmrg    This function may be called in one of two cases: either we try to
406210d565efSmrg    move identical instructions from all successor blocks into their
406310d565efSmrg    predecessor, or we try to move from only one successor block.  If
406410d565efSmrg    OTHER_BRANCH_LIVE is nonnull, it indicates that we're dealing with
406510d565efSmrg    the second case.  It should contain a set of registers live at the
406610d565efSmrg    end of ACROSS_TO which must not be clobbered by moving the insns.
406710d565efSmrg    In that case, we're also more careful about moving memory references
406810d565efSmrg    and trapping insns.
406910d565efSmrg 
407010d565efSmrg    We return false if it is not safe to move the entire group, but it
407110d565efSmrg    may still be possible to move a subgroup.  PMOVE_UPTO, if nonnull,
407210d565efSmrg    is set to point at the last moveable insn in such a case.  */
407310d565efSmrg 
407410d565efSmrg bool
can_move_insns_across(rtx_insn * from,rtx_insn * to,rtx_insn * across_from,rtx_insn * across_to,basic_block merge_bb,regset merge_live,regset other_branch_live,rtx_insn ** pmove_upto)407510d565efSmrg can_move_insns_across (rtx_insn *from, rtx_insn *to,
407610d565efSmrg 		       rtx_insn *across_from, rtx_insn *across_to,
407710d565efSmrg 		       basic_block merge_bb, regset merge_live,
407810d565efSmrg 		       regset other_branch_live, rtx_insn **pmove_upto)
407910d565efSmrg {
408010d565efSmrg   rtx_insn *insn, *next, *max_to;
408110d565efSmrg   bitmap merge_set, merge_use, local_merge_live;
408210d565efSmrg   bitmap test_set, test_use;
408310d565efSmrg   unsigned i, fail = 0;
408410d565efSmrg   bitmap_iterator bi;
408510d565efSmrg   int memrefs_in_across = 0;
408610d565efSmrg   int mem_sets_in_across = 0;
408710d565efSmrg   bool trapping_insns_in_across = false;
408810d565efSmrg 
408910d565efSmrg   if (pmove_upto != NULL)
409010d565efSmrg     *pmove_upto = NULL;
409110d565efSmrg 
409210d565efSmrg   /* Find real bounds, ignoring debug insns.  */
409310d565efSmrg   while (!NONDEBUG_INSN_P (from) && from != to)
409410d565efSmrg     from = NEXT_INSN (from);
409510d565efSmrg   while (!NONDEBUG_INSN_P (to) && from != to)
409610d565efSmrg     to = PREV_INSN (to);
409710d565efSmrg 
409810d565efSmrg   for (insn = across_to; ; insn = next)
409910d565efSmrg     {
410010d565efSmrg       if (CALL_P (insn))
410110d565efSmrg 	{
410210d565efSmrg 	  if (RTL_CONST_OR_PURE_CALL_P (insn))
410310d565efSmrg 	    /* Pure functions can read from memory.  Const functions can
410410d565efSmrg 	       read from arguments that the ABI has forced onto the stack.
410510d565efSmrg 	       Neither sort of read can be volatile.  */
410610d565efSmrg 	    memrefs_in_across |= MEMREF_NORMAL;
410710d565efSmrg 	  else
410810d565efSmrg 	    {
410910d565efSmrg 	      memrefs_in_across |= MEMREF_VOLATILE;
411010d565efSmrg 	      mem_sets_in_across |= MEMREF_VOLATILE;
411110d565efSmrg 	    }
411210d565efSmrg 	}
411310d565efSmrg       if (NONDEBUG_INSN_P (insn))
411410d565efSmrg 	{
411510d565efSmrg 	  if (volatile_insn_p (PATTERN (insn)))
411610d565efSmrg 	    return false;
411710d565efSmrg 	  memrefs_in_across |= find_memory (insn);
4118*ec02198aSmrg 	  note_stores (insn, find_memory_stores, &mem_sets_in_across);
411910d565efSmrg 	  /* This is used just to find sets of the stack pointer.  */
412010d565efSmrg 	  memrefs_in_across |= mem_sets_in_across;
412110d565efSmrg 	  trapping_insns_in_across |= may_trap_p (PATTERN (insn));
412210d565efSmrg 	}
412310d565efSmrg       next = PREV_INSN (insn);
412410d565efSmrg       if (insn == across_from)
412510d565efSmrg 	break;
412610d565efSmrg     }
412710d565efSmrg 
412810d565efSmrg   /* Collect:
412910d565efSmrg      MERGE_SET = set of registers set in MERGE_BB
413010d565efSmrg      MERGE_USE = set of registers used in MERGE_BB and live at its top
413110d565efSmrg      MERGE_LIVE = set of registers live at the point inside the MERGE
413210d565efSmrg      range that we've reached during scanning
413310d565efSmrg      TEST_SET = set of registers set between ACROSS_FROM and ACROSS_END.
413410d565efSmrg      TEST_USE = set of registers used between ACROSS_FROM and ACROSS_END,
413510d565efSmrg      and live before ACROSS_FROM.  */
413610d565efSmrg 
413710d565efSmrg   merge_set = BITMAP_ALLOC (&reg_obstack);
413810d565efSmrg   merge_use = BITMAP_ALLOC (&reg_obstack);
413910d565efSmrg   local_merge_live = BITMAP_ALLOC (&reg_obstack);
414010d565efSmrg   test_set = BITMAP_ALLOC (&reg_obstack);
414110d565efSmrg   test_use = BITMAP_ALLOC (&reg_obstack);
414210d565efSmrg 
414310d565efSmrg   /* Compute the set of registers set and used in the ACROSS range.  */
414410d565efSmrg   if (other_branch_live != NULL)
414510d565efSmrg     bitmap_copy (test_use, other_branch_live);
414610d565efSmrg   df_simulate_initialize_backwards (merge_bb, test_use);
414710d565efSmrg   for (insn = across_to; ; insn = next)
414810d565efSmrg     {
414910d565efSmrg       if (NONDEBUG_INSN_P (insn))
415010d565efSmrg 	{
415110d565efSmrg 	  df_simulate_find_defs (insn, test_set);
415210d565efSmrg 	  df_simulate_defs (insn, test_use);
415310d565efSmrg 	  df_simulate_uses (insn, test_use);
415410d565efSmrg 	}
415510d565efSmrg       next = PREV_INSN (insn);
415610d565efSmrg       if (insn == across_from)
415710d565efSmrg 	break;
415810d565efSmrg     }
415910d565efSmrg 
416010d565efSmrg   /* Compute an upper bound for the amount of insns moved, by finding
416110d565efSmrg      the first insn in MERGE that sets a register in TEST_USE, or uses
416210d565efSmrg      a register in TEST_SET.  We also check for calls, trapping operations,
416310d565efSmrg      and memory references.  */
416410d565efSmrg   max_to = NULL;
416510d565efSmrg   for (insn = from; ; insn = next)
416610d565efSmrg     {
416710d565efSmrg       if (CALL_P (insn))
416810d565efSmrg 	break;
416910d565efSmrg       if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG)
417010d565efSmrg 	break;
417110d565efSmrg       if (NONDEBUG_INSN_P (insn))
417210d565efSmrg 	{
417310d565efSmrg 	  if (may_trap_or_fault_p (PATTERN (insn))
417410d565efSmrg 	      && (trapping_insns_in_across
417510d565efSmrg 		  || other_branch_live != NULL
417610d565efSmrg 		  || volatile_insn_p (PATTERN (insn))))
417710d565efSmrg 	    break;
417810d565efSmrg 
417910d565efSmrg 	  /* We cannot move memory stores past each other, or move memory
418010d565efSmrg 	     reads past stores, at least not without tracking them and
418110d565efSmrg 	     calling true_dependence on every pair.
418210d565efSmrg 
418310d565efSmrg 	     If there is no other branch and no memory references or
418410d565efSmrg 	     sets in the ACROSS range, we can move memory references
418510d565efSmrg 	     freely, even volatile ones.
418610d565efSmrg 
418710d565efSmrg 	     Otherwise, the rules are as follows: volatile memory
418810d565efSmrg 	     references and stores can't be moved at all, and any type
418910d565efSmrg 	     of memory reference can't be moved if there are volatile
419010d565efSmrg 	     accesses or stores in the ACROSS range.  That leaves
419110d565efSmrg 	     normal reads, which can be moved, as the trapping case is
419210d565efSmrg 	     dealt with elsewhere.  */
419310d565efSmrg 	  if (other_branch_live != NULL || memrefs_in_across != 0)
419410d565efSmrg 	    {
419510d565efSmrg 	      int mem_ref_flags = 0;
419610d565efSmrg 	      int mem_set_flags = 0;
4197*ec02198aSmrg 	      note_stores (insn, find_memory_stores, &mem_set_flags);
419810d565efSmrg 	      mem_ref_flags = find_memory (insn);
419910d565efSmrg 	      /* Catch sets of the stack pointer.  */
420010d565efSmrg 	      mem_ref_flags |= mem_set_flags;
420110d565efSmrg 
420210d565efSmrg 	      if ((mem_ref_flags | mem_set_flags) & MEMREF_VOLATILE)
420310d565efSmrg 		break;
420410d565efSmrg 	      if ((memrefs_in_across & MEMREF_VOLATILE) && mem_ref_flags != 0)
420510d565efSmrg 		break;
420610d565efSmrg 	      if (mem_set_flags != 0
420710d565efSmrg 		  || (mem_sets_in_across != 0 && mem_ref_flags != 0))
420810d565efSmrg 		break;
420910d565efSmrg 	    }
421010d565efSmrg 	  df_simulate_find_uses (insn, merge_use);
421110d565efSmrg 	  /* We're only interested in uses which use a value live at
421210d565efSmrg 	     the top, not one previously set in this block.  */
421310d565efSmrg 	  bitmap_and_compl_into (merge_use, merge_set);
421410d565efSmrg 	  df_simulate_find_defs (insn, merge_set);
421510d565efSmrg 	  if (bitmap_intersect_p (merge_set, test_use)
421610d565efSmrg 	      || bitmap_intersect_p (merge_use, test_set))
421710d565efSmrg 	    break;
421810d565efSmrg 	  if (!HAVE_cc0 || !sets_cc0_p (insn))
421910d565efSmrg 	    max_to = insn;
422010d565efSmrg 	}
422110d565efSmrg       next = NEXT_INSN (insn);
422210d565efSmrg       if (insn == to)
422310d565efSmrg 	break;
422410d565efSmrg     }
422510d565efSmrg   if (max_to != to)
422610d565efSmrg     fail = 1;
422710d565efSmrg 
422810d565efSmrg   if (max_to == NULL_RTX || (fail && pmove_upto == NULL))
422910d565efSmrg     goto out;
423010d565efSmrg 
423110d565efSmrg   /* Now, lower this upper bound by also taking into account that
423210d565efSmrg      a range of insns moved across ACROSS must not leave a register
423310d565efSmrg      live at the end that will be clobbered in ACROSS.  We need to
423410d565efSmrg      find a point where TEST_SET & LIVE == 0.
423510d565efSmrg 
423610d565efSmrg      Insns in the MERGE range that set registers which are also set
423710d565efSmrg      in the ACROSS range may still be moved as long as we also move
423810d565efSmrg      later insns which use the results of the set, and make the
423910d565efSmrg      register dead again.  This is verified by the condition stated
424010d565efSmrg      above.  We only need to test it for registers that are set in
424110d565efSmrg      the moved region.
424210d565efSmrg 
424310d565efSmrg      MERGE_LIVE is provided by the caller and holds live registers after
424410d565efSmrg      TO.  */
424510d565efSmrg   bitmap_copy (local_merge_live, merge_live);
424610d565efSmrg   for (insn = to; insn != max_to; insn = PREV_INSN (insn))
424710d565efSmrg     df_simulate_one_insn_backwards (merge_bb, insn, local_merge_live);
424810d565efSmrg 
424910d565efSmrg   /* We're not interested in registers that aren't set in the moved
425010d565efSmrg      region at all.  */
425110d565efSmrg   bitmap_and_into (local_merge_live, merge_set);
425210d565efSmrg   for (;;)
425310d565efSmrg     {
425410d565efSmrg       if (NONDEBUG_INSN_P (insn))
425510d565efSmrg 	{
425610d565efSmrg 	  if (!bitmap_intersect_p (test_set, local_merge_live)
425710d565efSmrg 	      && (!HAVE_cc0 || !sets_cc0_p (insn)))
425810d565efSmrg 	    {
425910d565efSmrg 	      max_to = insn;
426010d565efSmrg 	      break;
426110d565efSmrg 	    }
426210d565efSmrg 
426310d565efSmrg 	  df_simulate_one_insn_backwards (merge_bb, insn,
426410d565efSmrg 					  local_merge_live);
426510d565efSmrg 	}
426610d565efSmrg       if (insn == from)
426710d565efSmrg 	{
426810d565efSmrg 	  fail = 1;
426910d565efSmrg 	  goto out;
427010d565efSmrg 	}
427110d565efSmrg       insn = PREV_INSN (insn);
427210d565efSmrg     }
427310d565efSmrg 
427410d565efSmrg   if (max_to != to)
427510d565efSmrg     fail = 1;
427610d565efSmrg 
427710d565efSmrg   if (pmove_upto)
427810d565efSmrg     *pmove_upto = max_to;
427910d565efSmrg 
428010d565efSmrg   /* For small register class machines, don't lengthen lifetimes of
428110d565efSmrg      hard registers before reload.  */
428210d565efSmrg   if (! reload_completed
428310d565efSmrg       && targetm.small_register_classes_for_mode_p (VOIDmode))
428410d565efSmrg     {
428510d565efSmrg       EXECUTE_IF_SET_IN_BITMAP (merge_set, 0, i, bi)
428610d565efSmrg 	{
428710d565efSmrg 	  if (i < FIRST_PSEUDO_REGISTER
428810d565efSmrg 	      && ! fixed_regs[i]
428910d565efSmrg 	      && ! global_regs[i])
429010d565efSmrg 	    {
429110d565efSmrg 	      fail = 1;
429210d565efSmrg 	      break;
429310d565efSmrg 	    }
429410d565efSmrg 	}
429510d565efSmrg     }
429610d565efSmrg 
429710d565efSmrg  out:
429810d565efSmrg   BITMAP_FREE (merge_set);
429910d565efSmrg   BITMAP_FREE (merge_use);
430010d565efSmrg   BITMAP_FREE (local_merge_live);
430110d565efSmrg   BITMAP_FREE (test_set);
430210d565efSmrg   BITMAP_FREE (test_use);
430310d565efSmrg 
430410d565efSmrg   return !fail;
430510d565efSmrg }
430610d565efSmrg 
430710d565efSmrg 
430810d565efSmrg /*----------------------------------------------------------------------------
430910d565efSmrg    MULTIPLE DEFINITIONS
431010d565efSmrg 
431110d565efSmrg    Find the locations in the function reached by multiple definition sites
431210d565efSmrg    for a live pseudo.  In and out bitvectors are built for each basic
431310d565efSmrg    block.  They are restricted for efficiency to live registers.
431410d565efSmrg 
431510d565efSmrg    The gen and kill sets for the problem are obvious.  Together they
431610d565efSmrg    include all defined registers in a basic block; the gen set includes
431710d565efSmrg    registers where a partial or conditional or may-clobber definition is
431810d565efSmrg    last in the BB, while the kill set includes registers with a complete
431910d565efSmrg    definition coming last.  However, the computation of the dataflow
432010d565efSmrg    itself is interesting.
432110d565efSmrg 
432210d565efSmrg    The idea behind it comes from SSA form's iterated dominance frontier
432310d565efSmrg    criterion for inserting PHI functions.  Just like in that case, we can use
432410d565efSmrg    the dominance frontier to find places where multiple definitions meet;
432510d565efSmrg    a register X defined in a basic block BB1 has multiple definitions in
432610d565efSmrg    basic blocks in BB1's dominance frontier.
432710d565efSmrg 
432810d565efSmrg    So, the in-set of a basic block BB2 is not just the union of the
432910d565efSmrg    out-sets of BB2's predecessors, but includes some more bits that come
433010d565efSmrg    from the basic blocks of whose dominance frontier BB2 is part (BB1 in
433110d565efSmrg    the previous paragraph).  I called this set the init-set of BB2.
433210d565efSmrg 
433310d565efSmrg       (Note: I actually use the kill-set only to build the init-set.
433410d565efSmrg       gen bits are anyway propagated from BB1 to BB2 by dataflow).
433510d565efSmrg 
433610d565efSmrg     For example, if you have
433710d565efSmrg 
433810d565efSmrg        BB1 : r10 = 0
433910d565efSmrg              r11 = 0
434010d565efSmrg              if <...> goto BB2 else goto BB3;
434110d565efSmrg 
434210d565efSmrg        BB2 : r10 = 1
434310d565efSmrg              r12 = 1
434410d565efSmrg              goto BB3;
434510d565efSmrg 
434610d565efSmrg        BB3 :
434710d565efSmrg 
434810d565efSmrg     you have BB3 in BB2's dominance frontier but not in BB1's, so that the
434910d565efSmrg     init-set of BB3 includes r10 and r12, but not r11.  Note that we do
435010d565efSmrg     not need to iterate the dominance frontier, because we do not insert
435110d565efSmrg     anything like PHI functions there!  Instead, dataflow will take care of
435210d565efSmrg     propagating the information to BB3's successors.
435310d565efSmrg    ---------------------------------------------------------------------------*/
435410d565efSmrg 
435510d565efSmrg /* Private data used to verify the solution for this problem.  */
435610d565efSmrg struct df_md_problem_data
435710d565efSmrg {
435810d565efSmrg   /* An obstack for the bitmaps we need for this problem.  */
435910d565efSmrg   bitmap_obstack md_bitmaps;
436010d565efSmrg };
436110d565efSmrg 
436210d565efSmrg /* Scratch var used by transfer functions.  This is used to do md analysis
436310d565efSmrg    only for live registers.  */
436410d565efSmrg static bitmap_head df_md_scratch;
436510d565efSmrg 
436610d565efSmrg 
436710d565efSmrg static void
df_md_free_bb_info(basic_block bb ATTRIBUTE_UNUSED,void * vbb_info)436810d565efSmrg df_md_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
436910d565efSmrg                     void *vbb_info)
437010d565efSmrg {
4371*ec02198aSmrg   class df_md_bb_info *bb_info = (class df_md_bb_info *) vbb_info;
437210d565efSmrg   if (bb_info)
437310d565efSmrg     {
437410d565efSmrg       bitmap_clear (&bb_info->kill);
437510d565efSmrg       bitmap_clear (&bb_info->gen);
437610d565efSmrg       bitmap_clear (&bb_info->init);
437710d565efSmrg       bitmap_clear (&bb_info->in);
437810d565efSmrg       bitmap_clear (&bb_info->out);
437910d565efSmrg     }
438010d565efSmrg }
438110d565efSmrg 
438210d565efSmrg 
438310d565efSmrg /* Allocate or reset bitmaps for DF_MD. The solution bits are
438410d565efSmrg    not touched unless the block is new.  */
438510d565efSmrg 
438610d565efSmrg static void
df_md_alloc(bitmap all_blocks)438710d565efSmrg df_md_alloc (bitmap all_blocks)
438810d565efSmrg {
438910d565efSmrg   unsigned int bb_index;
439010d565efSmrg   bitmap_iterator bi;
439110d565efSmrg   struct df_md_problem_data *problem_data;
439210d565efSmrg 
439310d565efSmrg   df_grow_bb_info (df_md);
439410d565efSmrg   if (df_md->problem_data)
439510d565efSmrg     problem_data = (struct df_md_problem_data *) df_md->problem_data;
439610d565efSmrg   else
439710d565efSmrg     {
439810d565efSmrg       problem_data = XNEW (struct df_md_problem_data);
439910d565efSmrg       df_md->problem_data = problem_data;
440010d565efSmrg       bitmap_obstack_initialize (&problem_data->md_bitmaps);
440110d565efSmrg     }
440210d565efSmrg   bitmap_initialize (&df_md_scratch, &problem_data->md_bitmaps);
440310d565efSmrg 
440410d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
440510d565efSmrg     {
4406*ec02198aSmrg       class df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
440710d565efSmrg       /* When bitmaps are already initialized, just clear them.  */
440810d565efSmrg       if (bb_info->init.obstack)
440910d565efSmrg         {
441010d565efSmrg           bitmap_clear (&bb_info->init);
441110d565efSmrg           bitmap_clear (&bb_info->gen);
441210d565efSmrg           bitmap_clear (&bb_info->kill);
441310d565efSmrg           bitmap_clear (&bb_info->in);
441410d565efSmrg           bitmap_clear (&bb_info->out);
441510d565efSmrg         }
441610d565efSmrg       else
441710d565efSmrg         {
441810d565efSmrg 	  bitmap_initialize (&bb_info->init, &problem_data->md_bitmaps);
441910d565efSmrg 	  bitmap_initialize (&bb_info->gen, &problem_data->md_bitmaps);
442010d565efSmrg 	  bitmap_initialize (&bb_info->kill, &problem_data->md_bitmaps);
442110d565efSmrg 	  bitmap_initialize (&bb_info->in, &problem_data->md_bitmaps);
442210d565efSmrg 	  bitmap_initialize (&bb_info->out, &problem_data->md_bitmaps);
442310d565efSmrg         }
442410d565efSmrg     }
442510d565efSmrg 
442610d565efSmrg   df_md->optional_p = true;
442710d565efSmrg }
442810d565efSmrg 
442910d565efSmrg /* Add the effect of the top artificial defs of BB to the multiple definitions
443010d565efSmrg    bitmap LOCAL_MD.  */
443110d565efSmrg 
443210d565efSmrg void
df_md_simulate_artificial_defs_at_top(basic_block bb,bitmap local_md)443310d565efSmrg df_md_simulate_artificial_defs_at_top (basic_block bb, bitmap local_md)
443410d565efSmrg {
443510d565efSmrg   int bb_index = bb->index;
443610d565efSmrg   df_ref def;
443710d565efSmrg   FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
443810d565efSmrg     if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
443910d565efSmrg       {
444010d565efSmrg 	unsigned int dregno = DF_REF_REGNO (def);
444110d565efSmrg 	if (DF_REF_FLAGS (def)
444210d565efSmrg 	    & (DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER))
444310d565efSmrg 	  bitmap_set_bit (local_md, dregno);
444410d565efSmrg 	else
444510d565efSmrg 	  bitmap_clear_bit (local_md, dregno);
444610d565efSmrg       }
444710d565efSmrg }
444810d565efSmrg 
444910d565efSmrg 
445010d565efSmrg /* Add the effect of the defs of INSN to the reaching definitions bitmap
445110d565efSmrg    LOCAL_MD.  */
445210d565efSmrg 
445310d565efSmrg void
df_md_simulate_one_insn(basic_block bb ATTRIBUTE_UNUSED,rtx_insn * insn,bitmap local_md)445410d565efSmrg df_md_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx_insn *insn,
445510d565efSmrg 			 bitmap local_md)
445610d565efSmrg {
445710d565efSmrg   df_ref def;
445810d565efSmrg 
445910d565efSmrg   FOR_EACH_INSN_DEF (def, insn)
446010d565efSmrg     {
446110d565efSmrg       unsigned int dregno = DF_REF_REGNO (def);
446210d565efSmrg       if ((!(df->changeable_flags & DF_NO_HARD_REGS))
446310d565efSmrg           || (dregno >= FIRST_PSEUDO_REGISTER))
446410d565efSmrg         {
446510d565efSmrg           if (DF_REF_FLAGS (def)
446610d565efSmrg 	      & (DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER))
446710d565efSmrg            bitmap_set_bit (local_md, DF_REF_ID (def));
446810d565efSmrg          else
446910d565efSmrg            bitmap_clear_bit (local_md, DF_REF_ID (def));
447010d565efSmrg         }
447110d565efSmrg     }
447210d565efSmrg }
447310d565efSmrg 
447410d565efSmrg static void
df_md_bb_local_compute_process_def(class df_md_bb_info * bb_info,df_ref def,int top_flag)4475*ec02198aSmrg df_md_bb_local_compute_process_def (class df_md_bb_info *bb_info,
447610d565efSmrg                                     df_ref def,
447710d565efSmrg                                     int top_flag)
447810d565efSmrg {
447910d565efSmrg   bitmap_clear (&seen_in_insn);
448010d565efSmrg 
448110d565efSmrg   for (; def; def = DF_REF_NEXT_LOC (def))
448210d565efSmrg     {
448310d565efSmrg       unsigned int dregno = DF_REF_REGNO (def);
448410d565efSmrg       if (((!(df->changeable_flags & DF_NO_HARD_REGS))
448510d565efSmrg 	    || (dregno >= FIRST_PSEUDO_REGISTER))
448610d565efSmrg 	  && top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
448710d565efSmrg 	{
448810d565efSmrg           if (!bitmap_bit_p (&seen_in_insn, dregno))
448910d565efSmrg 	    {
449010d565efSmrg 	      if (DF_REF_FLAGS (def)
449110d565efSmrg 	          & (DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER))
449210d565efSmrg 	        {
449310d565efSmrg 	          bitmap_set_bit (&bb_info->gen, dregno);
449410d565efSmrg 	          bitmap_clear_bit (&bb_info->kill, dregno);
449510d565efSmrg 	        }
449610d565efSmrg 	      else
449710d565efSmrg 	        {
449810d565efSmrg 		  /* When we find a clobber and a regular def,
449910d565efSmrg 		     make sure the regular def wins.  */
450010d565efSmrg 	          bitmap_set_bit (&seen_in_insn, dregno);
450110d565efSmrg 	          bitmap_set_bit (&bb_info->kill, dregno);
450210d565efSmrg 	          bitmap_clear_bit (&bb_info->gen, dregno);
450310d565efSmrg 	        }
450410d565efSmrg 	    }
450510d565efSmrg 	}
450610d565efSmrg     }
450710d565efSmrg }
450810d565efSmrg 
450910d565efSmrg 
451010d565efSmrg /* Compute local multiple def info for basic block BB.  */
451110d565efSmrg 
451210d565efSmrg static void
df_md_bb_local_compute(unsigned int bb_index)451310d565efSmrg df_md_bb_local_compute (unsigned int bb_index)
451410d565efSmrg {
451510d565efSmrg   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
4516*ec02198aSmrg   class df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
451710d565efSmrg   rtx_insn *insn;
451810d565efSmrg 
451910d565efSmrg   /* Artificials are only hard regs.  */
452010d565efSmrg   if (!(df->changeable_flags & DF_NO_HARD_REGS))
452110d565efSmrg     df_md_bb_local_compute_process_def (bb_info,
452210d565efSmrg                                         df_get_artificial_defs (bb_index),
452310d565efSmrg                                         DF_REF_AT_TOP);
452410d565efSmrg 
452510d565efSmrg   FOR_BB_INSNS (bb, insn)
452610d565efSmrg     {
452710d565efSmrg       unsigned int uid = INSN_UID (insn);
452810d565efSmrg       if (!INSN_P (insn))
452910d565efSmrg         continue;
453010d565efSmrg 
453110d565efSmrg       df_md_bb_local_compute_process_def (bb_info, DF_INSN_UID_DEFS (uid), 0);
453210d565efSmrg     }
453310d565efSmrg 
453410d565efSmrg   if (!(df->changeable_flags & DF_NO_HARD_REGS))
453510d565efSmrg     df_md_bb_local_compute_process_def (bb_info,
453610d565efSmrg                                         df_get_artificial_defs (bb_index),
453710d565efSmrg                                         0);
453810d565efSmrg }
453910d565efSmrg 
454010d565efSmrg /* Compute local reaching def info for each basic block within BLOCKS.  */
454110d565efSmrg 
454210d565efSmrg static void
df_md_local_compute(bitmap all_blocks)454310d565efSmrg df_md_local_compute (bitmap all_blocks)
454410d565efSmrg {
454510d565efSmrg   unsigned int bb_index, df_bb_index;
454610d565efSmrg   bitmap_iterator bi1, bi2;
454710d565efSmrg   basic_block bb;
454810d565efSmrg   bitmap_head *frontiers;
454910d565efSmrg 
455010d565efSmrg   bitmap_initialize (&seen_in_insn, &bitmap_default_obstack);
455110d565efSmrg 
455210d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi1)
455310d565efSmrg     {
455410d565efSmrg       df_md_bb_local_compute (bb_index);
455510d565efSmrg     }
455610d565efSmrg 
45570fc04c29Smrg   bitmap_release (&seen_in_insn);
455810d565efSmrg 
455910d565efSmrg   frontiers = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
456010d565efSmrg   FOR_ALL_BB_FN (bb, cfun)
456110d565efSmrg     bitmap_initialize (&frontiers[bb->index], &bitmap_default_obstack);
456210d565efSmrg 
456310d565efSmrg   compute_dominance_frontiers (frontiers);
456410d565efSmrg 
456510d565efSmrg   /* Add each basic block's kills to the nodes in the frontier of the BB.  */
456610d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi1)
456710d565efSmrg     {
456810d565efSmrg       bitmap kill = &df_md_get_bb_info (bb_index)->kill;
456910d565efSmrg       EXECUTE_IF_SET_IN_BITMAP (&frontiers[bb_index], 0, df_bb_index, bi2)
457010d565efSmrg 	{
457110d565efSmrg 	  basic_block bb = BASIC_BLOCK_FOR_FN (cfun, df_bb_index);
457210d565efSmrg 	  if (bitmap_bit_p (all_blocks, df_bb_index))
457310d565efSmrg 	    bitmap_ior_and_into (&df_md_get_bb_info (df_bb_index)->init, kill,
457410d565efSmrg 				 df_get_live_in (bb));
457510d565efSmrg 	}
457610d565efSmrg     }
457710d565efSmrg 
457810d565efSmrg   FOR_ALL_BB_FN (bb, cfun)
457910d565efSmrg     bitmap_clear (&frontiers[bb->index]);
458010d565efSmrg   free (frontiers);
458110d565efSmrg }
458210d565efSmrg 
458310d565efSmrg 
458410d565efSmrg /* Reset the global solution for recalculation.  */
458510d565efSmrg 
458610d565efSmrg static void
df_md_reset(bitmap all_blocks)458710d565efSmrg df_md_reset (bitmap all_blocks)
458810d565efSmrg {
458910d565efSmrg   unsigned int bb_index;
459010d565efSmrg   bitmap_iterator bi;
459110d565efSmrg 
459210d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
459310d565efSmrg     {
4594*ec02198aSmrg       class df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
459510d565efSmrg       gcc_assert (bb_info);
459610d565efSmrg       bitmap_clear (&bb_info->in);
459710d565efSmrg       bitmap_clear (&bb_info->out);
459810d565efSmrg     }
459910d565efSmrg }
460010d565efSmrg 
460110d565efSmrg static bool
df_md_transfer_function(int bb_index)460210d565efSmrg df_md_transfer_function (int bb_index)
460310d565efSmrg {
460410d565efSmrg   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
4605*ec02198aSmrg   class df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
460610d565efSmrg   bitmap in = &bb_info->in;
460710d565efSmrg   bitmap out = &bb_info->out;
460810d565efSmrg   bitmap gen = &bb_info->gen;
460910d565efSmrg   bitmap kill = &bb_info->kill;
461010d565efSmrg 
461110d565efSmrg   /* We need to use a scratch set here so that the value returned from this
461210d565efSmrg      function invocation properly reflects whether the sets changed in a
461310d565efSmrg      significant way; i.e. not just because the live set was anded in.  */
461410d565efSmrg   bitmap_and (&df_md_scratch, gen, df_get_live_out (bb));
461510d565efSmrg 
461610d565efSmrg   /* Multiple definitions of a register are not relevant if it is not
461710d565efSmrg      live.  Thus we trim the result to the places where it is live.  */
461810d565efSmrg   bitmap_and_into (in, df_get_live_in (bb));
461910d565efSmrg 
462010d565efSmrg   return bitmap_ior_and_compl (out, &df_md_scratch, in, kill);
462110d565efSmrg }
462210d565efSmrg 
462310d565efSmrg /* Initialize the solution bit vectors for problem.  */
462410d565efSmrg 
462510d565efSmrg static void
df_md_init(bitmap all_blocks)462610d565efSmrg df_md_init (bitmap all_blocks)
462710d565efSmrg {
462810d565efSmrg   unsigned int bb_index;
462910d565efSmrg   bitmap_iterator bi;
463010d565efSmrg 
463110d565efSmrg   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
463210d565efSmrg     {
4633*ec02198aSmrg       class df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
463410d565efSmrg 
463510d565efSmrg       bitmap_copy (&bb_info->in, &bb_info->init);
463610d565efSmrg       df_md_transfer_function (bb_index);
463710d565efSmrg     }
463810d565efSmrg }
463910d565efSmrg 
464010d565efSmrg static void
df_md_confluence_0(basic_block bb)464110d565efSmrg df_md_confluence_0 (basic_block bb)
464210d565efSmrg {
4643*ec02198aSmrg   class df_md_bb_info *bb_info = df_md_get_bb_info (bb->index);
464410d565efSmrg   bitmap_copy (&bb_info->in, &bb_info->init);
464510d565efSmrg }
464610d565efSmrg 
464710d565efSmrg /* In of target gets or of out of source.  */
464810d565efSmrg 
464910d565efSmrg static bool
df_md_confluence_n(edge e)465010d565efSmrg df_md_confluence_n (edge e)
465110d565efSmrg {
465210d565efSmrg   bitmap op1 = &df_md_get_bb_info (e->dest->index)->in;
465310d565efSmrg   bitmap op2 = &df_md_get_bb_info (e->src->index)->out;
465410d565efSmrg 
465510d565efSmrg   if (e->flags & EDGE_FAKE)
465610d565efSmrg     return false;
465710d565efSmrg 
465810d565efSmrg   if (e->flags & EDGE_EH)
4659*ec02198aSmrg     {
4660*ec02198aSmrg       /* Conservatively treat partially-clobbered registers as surviving
4661*ec02198aSmrg 	 across the edge; they might or might not, depending on what mode
4662*ec02198aSmrg 	 they have.  */
4663*ec02198aSmrg       bitmap_view<HARD_REG_SET> eh_kills (eh_edge_abi.full_reg_clobbers ());
4664*ec02198aSmrg       return bitmap_ior_and_compl_into (op1, op2, eh_kills);
4665*ec02198aSmrg     }
466610d565efSmrg   else
466710d565efSmrg     return bitmap_ior_into (op1, op2);
466810d565efSmrg }
466910d565efSmrg 
467010d565efSmrg /* Free all storage associated with the problem.  */
467110d565efSmrg 
467210d565efSmrg static void
df_md_free(void)467310d565efSmrg df_md_free (void)
467410d565efSmrg {
467510d565efSmrg   struct df_md_problem_data *problem_data
467610d565efSmrg     = (struct df_md_problem_data *) df_md->problem_data;
467710d565efSmrg 
46780fc04c29Smrg   bitmap_release (&df_md_scratch);
467910d565efSmrg   bitmap_obstack_release (&problem_data->md_bitmaps);
468010d565efSmrg   free (problem_data);
468110d565efSmrg   df_md->problem_data = NULL;
468210d565efSmrg 
468310d565efSmrg   df_md->block_info_size = 0;
468410d565efSmrg   free (df_md->block_info);
468510d565efSmrg   df_md->block_info = NULL;
468610d565efSmrg   free (df_md);
468710d565efSmrg }
468810d565efSmrg 
468910d565efSmrg 
469010d565efSmrg /* Debugging info at top of bb.  */
469110d565efSmrg 
469210d565efSmrg static void
df_md_top_dump(basic_block bb,FILE * file)469310d565efSmrg df_md_top_dump (basic_block bb, FILE *file)
469410d565efSmrg {
4695*ec02198aSmrg   class df_md_bb_info *bb_info = df_md_get_bb_info (bb->index);
469610d565efSmrg   if (!bb_info)
469710d565efSmrg     return;
469810d565efSmrg 
469910d565efSmrg   fprintf (file, ";; md  in  \t");
470010d565efSmrg   df_print_regset (file, &bb_info->in);
470110d565efSmrg   fprintf (file, ";; md  init  \t");
470210d565efSmrg   df_print_regset (file, &bb_info->init);
470310d565efSmrg   fprintf (file, ";; md  gen \t");
470410d565efSmrg   df_print_regset (file, &bb_info->gen);
470510d565efSmrg   fprintf (file, ";; md  kill \t");
470610d565efSmrg   df_print_regset (file, &bb_info->kill);
470710d565efSmrg }
470810d565efSmrg 
470910d565efSmrg /* Debugging info at bottom of bb.  */
471010d565efSmrg 
471110d565efSmrg static void
df_md_bottom_dump(basic_block bb,FILE * file)471210d565efSmrg df_md_bottom_dump (basic_block bb, FILE *file)
471310d565efSmrg {
4714*ec02198aSmrg   class df_md_bb_info *bb_info = df_md_get_bb_info (bb->index);
471510d565efSmrg   if (!bb_info)
471610d565efSmrg     return;
471710d565efSmrg 
471810d565efSmrg   fprintf (file, ";; md  out \t");
471910d565efSmrg   df_print_regset (file, &bb_info->out);
472010d565efSmrg }
472110d565efSmrg 
472210d565efSmrg static const struct df_problem problem_MD =
472310d565efSmrg {
472410d565efSmrg   DF_MD,                      /* Problem id.  */
472510d565efSmrg   DF_FORWARD,                 /* Direction.  */
472610d565efSmrg   df_md_alloc,                /* Allocate the problem specific data.  */
472710d565efSmrg   df_md_reset,                /* Reset global information.  */
472810d565efSmrg   df_md_free_bb_info,         /* Free basic block info.  */
472910d565efSmrg   df_md_local_compute,        /* Local compute function.  */
473010d565efSmrg   df_md_init,                 /* Init the solution specific data.  */
473110d565efSmrg   df_worklist_dataflow,       /* Worklist solver.  */
473210d565efSmrg   df_md_confluence_0,         /* Confluence operator 0.  */
473310d565efSmrg   df_md_confluence_n,         /* Confluence operator n.  */
473410d565efSmrg   df_md_transfer_function,    /* Transfer function.  */
473510d565efSmrg   NULL,                       /* Finalize function.  */
473610d565efSmrg   df_md_free,                 /* Free all of the problem information.  */
473710d565efSmrg   df_md_free,                 /* Remove this problem from the stack of dataflow problems.  */
473810d565efSmrg   NULL,                       /* Debugging.  */
473910d565efSmrg   df_md_top_dump,             /* Debugging start block.  */
474010d565efSmrg   df_md_bottom_dump,          /* Debugging end block.  */
474110d565efSmrg   NULL,                       /* Debugging start insn.  */
474210d565efSmrg   NULL,                       /* Debugging end insn.  */
474310d565efSmrg   NULL,			      /* Incremental solution verify start.  */
474410d565efSmrg   NULL,			      /* Incremental solution verify end.  */
474510d565efSmrg   NULL,                       /* Dependent problem.  */
4746*ec02198aSmrg   sizeof (class df_md_bb_info),/* Size of entry of block_info array.  */
474710d565efSmrg   TV_DF_MD,                   /* Timing variable.  */
474810d565efSmrg   false                       /* Reset blocks on dropping out of blocks_to_analyze.  */
474910d565efSmrg };
475010d565efSmrg 
475110d565efSmrg /* Create a new MD instance and add it to the existing instance
475210d565efSmrg    of DF.  */
475310d565efSmrg 
475410d565efSmrg void
df_md_add_problem(void)475510d565efSmrg df_md_add_problem (void)
475610d565efSmrg {
475710d565efSmrg   df_add_problem (&problem_MD);
475810d565efSmrg }
475910d565efSmrg 
476010d565efSmrg 
476110d565efSmrg 
4762