xref: /dflybsd-src/contrib/gcc-4.7/gcc/df-problems.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino /* Standard problems for dataflow support routines.
2*e4b17023SJohn Marino    Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3*e4b17023SJohn Marino    2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
4*e4b17023SJohn Marino    Originally contributed by Michael P. Hayes
5*e4b17023SJohn Marino              (m.hayes@elec.canterbury.ac.nz, mhayes@redhat.com)
6*e4b17023SJohn Marino    Major rewrite contributed by Danny Berlin (dberlin@dberlin.org)
7*e4b17023SJohn Marino              and Kenneth Zadeck (zadeck@naturalbridge.com).
8*e4b17023SJohn Marino 
9*e4b17023SJohn Marino This file is part of GCC.
10*e4b17023SJohn Marino 
11*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
12*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
13*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
14*e4b17023SJohn Marino version.
15*e4b17023SJohn Marino 
16*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
18*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19*e4b17023SJohn Marino for more details.
20*e4b17023SJohn Marino 
21*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
22*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
23*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
24*e4b17023SJohn Marino 
25*e4b17023SJohn Marino #include "config.h"
26*e4b17023SJohn Marino #include "system.h"
27*e4b17023SJohn Marino #include "coretypes.h"
28*e4b17023SJohn Marino #include "tm.h"
29*e4b17023SJohn Marino #include "rtl.h"
30*e4b17023SJohn Marino #include "tm_p.h"
31*e4b17023SJohn Marino #include "insn-config.h"
32*e4b17023SJohn Marino #include "recog.h"
33*e4b17023SJohn Marino #include "function.h"
34*e4b17023SJohn Marino #include "regs.h"
35*e4b17023SJohn Marino #include "output.h"
36*e4b17023SJohn Marino #include "alloc-pool.h"
37*e4b17023SJohn Marino #include "flags.h"
38*e4b17023SJohn Marino #include "hard-reg-set.h"
39*e4b17023SJohn Marino #include "basic-block.h"
40*e4b17023SJohn Marino #include "sbitmap.h"
41*e4b17023SJohn Marino #include "bitmap.h"
42*e4b17023SJohn Marino #include "target.h"
43*e4b17023SJohn Marino #include "timevar.h"
44*e4b17023SJohn Marino #include "df.h"
45*e4b17023SJohn Marino #include "except.h"
46*e4b17023SJohn Marino #include "dce.h"
47*e4b17023SJohn Marino #include "vecprim.h"
48*e4b17023SJohn Marino 
49*e4b17023SJohn Marino /* Note that turning REG_DEAD_DEBUGGING on will cause
50*e4b17023SJohn Marino    gcc.c-torture/unsorted/dump-noaddr.c to fail because it prints
51*e4b17023SJohn Marino    addresses in the dumps.  */
52*e4b17023SJohn Marino #if 0
53*e4b17023SJohn Marino #define REG_DEAD_DEBUGGING
54*e4b17023SJohn Marino #endif
55*e4b17023SJohn Marino 
56*e4b17023SJohn Marino #define DF_SPARSE_THRESHOLD 32
57*e4b17023SJohn Marino 
58*e4b17023SJohn Marino static bitmap_head seen_in_block;
59*e4b17023SJohn Marino static bitmap_head seen_in_insn;
60*e4b17023SJohn Marino 
61*e4b17023SJohn Marino 
62*e4b17023SJohn Marino /*----------------------------------------------------------------------------
63*e4b17023SJohn Marino    Public functions access functions for the dataflow problems.
64*e4b17023SJohn Marino ----------------------------------------------------------------------------*/
65*e4b17023SJohn Marino /* Get the live at out set for BB no matter what problem happens to be
66*e4b17023SJohn Marino    defined.  This function is used by the register allocators who
67*e4b17023SJohn Marino    choose different dataflow problems depending on the optimization
68*e4b17023SJohn Marino    level.  */
69*e4b17023SJohn Marino 
70*e4b17023SJohn Marino bitmap
df_get_live_out(basic_block bb)71*e4b17023SJohn Marino df_get_live_out (basic_block bb)
72*e4b17023SJohn Marino {
73*e4b17023SJohn Marino   gcc_assert (df_lr);
74*e4b17023SJohn Marino 
75*e4b17023SJohn Marino   if (df_live)
76*e4b17023SJohn Marino     return DF_LIVE_OUT (bb);
77*e4b17023SJohn Marino   else
78*e4b17023SJohn Marino     return DF_LR_OUT (bb);
79*e4b17023SJohn Marino }
80*e4b17023SJohn Marino 
81*e4b17023SJohn Marino /* Get the live at in set for BB no matter what problem happens to be
82*e4b17023SJohn Marino    defined.  This function is used by the register allocators who
83*e4b17023SJohn Marino    choose different dataflow problems depending on the optimization
84*e4b17023SJohn Marino    level.  */
85*e4b17023SJohn Marino 
86*e4b17023SJohn Marino bitmap
df_get_live_in(basic_block bb)87*e4b17023SJohn Marino df_get_live_in (basic_block bb)
88*e4b17023SJohn Marino {
89*e4b17023SJohn Marino   gcc_assert (df_lr);
90*e4b17023SJohn Marino 
91*e4b17023SJohn Marino   if (df_live)
92*e4b17023SJohn Marino     return DF_LIVE_IN (bb);
93*e4b17023SJohn Marino   else
94*e4b17023SJohn Marino     return DF_LR_IN (bb);
95*e4b17023SJohn Marino }
96*e4b17023SJohn Marino 
97*e4b17023SJohn Marino /*----------------------------------------------------------------------------
98*e4b17023SJohn Marino    Utility functions.
99*e4b17023SJohn Marino ----------------------------------------------------------------------------*/
100*e4b17023SJohn Marino 
101*e4b17023SJohn Marino /* Generic versions to get the void* version of the block info.  Only
102*e4b17023SJohn Marino    used inside the problem instance vectors.  */
103*e4b17023SJohn Marino 
104*e4b17023SJohn Marino /* Dump a def-use or use-def chain for REF to FILE.  */
105*e4b17023SJohn Marino 
106*e4b17023SJohn Marino void
df_chain_dump(struct df_link * link,FILE * file)107*e4b17023SJohn Marino df_chain_dump (struct df_link *link, FILE *file)
108*e4b17023SJohn Marino {
109*e4b17023SJohn Marino   fprintf (file, "{ ");
110*e4b17023SJohn Marino   for (; link; link = link->next)
111*e4b17023SJohn Marino     {
112*e4b17023SJohn Marino       fprintf (file, "%c%d(bb %d insn %d) ",
113*e4b17023SJohn Marino 	       DF_REF_REG_DEF_P (link->ref)
114*e4b17023SJohn Marino 	       ? 'd'
115*e4b17023SJohn Marino 	       : (DF_REF_FLAGS (link->ref) & DF_REF_IN_NOTE) ? 'e' : 'u',
116*e4b17023SJohn Marino 	       DF_REF_ID (link->ref),
117*e4b17023SJohn Marino 	       DF_REF_BBNO (link->ref),
118*e4b17023SJohn Marino 	       DF_REF_IS_ARTIFICIAL (link->ref)
119*e4b17023SJohn Marino 	       ? -1 : DF_REF_INSN_UID (link->ref));
120*e4b17023SJohn Marino     }
121*e4b17023SJohn Marino   fprintf (file, "}");
122*e4b17023SJohn Marino }
123*e4b17023SJohn Marino 
124*e4b17023SJohn Marino 
125*e4b17023SJohn Marino /* Print some basic block info as part of df_dump.  */
126*e4b17023SJohn Marino 
127*e4b17023SJohn Marino void
df_print_bb_index(basic_block bb,FILE * file)128*e4b17023SJohn Marino df_print_bb_index (basic_block bb, FILE *file)
129*e4b17023SJohn Marino {
130*e4b17023SJohn Marino   edge e;
131*e4b17023SJohn Marino   edge_iterator ei;
132*e4b17023SJohn Marino 
133*e4b17023SJohn Marino   fprintf (file, "\n( ");
134*e4b17023SJohn Marino     FOR_EACH_EDGE (e, ei, bb->preds)
135*e4b17023SJohn Marino     {
136*e4b17023SJohn Marino       basic_block pred = e->src;
137*e4b17023SJohn Marino       fprintf (file, "%d%s ", pred->index, e->flags & EDGE_EH ? "(EH)" : "");
138*e4b17023SJohn Marino     }
139*e4b17023SJohn Marino   fprintf (file, ")->[%d]->( ", bb->index);
140*e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, bb->succs)
141*e4b17023SJohn Marino     {
142*e4b17023SJohn Marino       basic_block succ = e->dest;
143*e4b17023SJohn Marino       fprintf (file, "%d%s ", succ->index, e->flags & EDGE_EH ? "(EH)" : "");
144*e4b17023SJohn Marino     }
145*e4b17023SJohn Marino   fprintf (file, ")\n");
146*e4b17023SJohn Marino }
147*e4b17023SJohn Marino 
148*e4b17023SJohn Marino 
149*e4b17023SJohn Marino /*----------------------------------------------------------------------------
150*e4b17023SJohn Marino    REACHING DEFINITIONS
151*e4b17023SJohn Marino 
152*e4b17023SJohn Marino    Find the locations in the function where each definition site for a
153*e4b17023SJohn Marino    pseudo reaches.  In and out bitvectors are built for each basic
154*e4b17023SJohn Marino    block.  The id field in the ref is used to index into these sets.
155*e4b17023SJohn Marino    See df.h for details.
156*e4b17023SJohn Marino    ----------------------------------------------------------------------------*/
157*e4b17023SJohn Marino 
158*e4b17023SJohn Marino /* This problem plays a large number of games for the sake of
159*e4b17023SJohn Marino    efficiency.
160*e4b17023SJohn Marino 
161*e4b17023SJohn Marino    1) The order of the bits in the bitvectors.  After the scanning
162*e4b17023SJohn Marino    phase, all of the defs are sorted.  All of the defs for the reg 0
163*e4b17023SJohn Marino    are first, followed by all defs for reg 1 and so on.
164*e4b17023SJohn Marino 
165*e4b17023SJohn Marino    2) There are two kill sets, one if the number of defs is less or
166*e4b17023SJohn Marino    equal to DF_SPARSE_THRESHOLD and another if the number of defs is
167*e4b17023SJohn Marino    greater.
168*e4b17023SJohn Marino 
169*e4b17023SJohn Marino    <= : Data is built directly in the kill set.
170*e4b17023SJohn Marino 
171*e4b17023SJohn Marino    > : One level of indirection is used to keep from generating long
172*e4b17023SJohn Marino    strings of 1 bits in the kill sets.  Bitvectors that are indexed
173*e4b17023SJohn Marino    by the regnum are used to represent that there is a killing def
174*e4b17023SJohn Marino    for the register.  The confluence and transfer functions use
175*e4b17023SJohn Marino    these along with the bitmap_clear_range call to remove ranges of
176*e4b17023SJohn Marino    bits without actually generating a knockout vector.
177*e4b17023SJohn Marino 
178*e4b17023SJohn Marino    The kill and sparse_kill and the dense_invalidated_by_call and
179*e4b17023SJohn Marino    sparse_invalidated_by_call both play this game.  */
180*e4b17023SJohn Marino 
181*e4b17023SJohn Marino /* Private data used to compute the solution for this problem.  These
182*e4b17023SJohn Marino    data structures are not accessible outside of this module.  */
183*e4b17023SJohn Marino struct df_rd_problem_data
184*e4b17023SJohn Marino {
185*e4b17023SJohn Marino   /* The set of defs to regs invalidated by call.  */
186*e4b17023SJohn Marino   bitmap_head sparse_invalidated_by_call;
187*e4b17023SJohn Marino   /* The set of defs to regs invalidate by call for rd.  */
188*e4b17023SJohn Marino   bitmap_head dense_invalidated_by_call;
189*e4b17023SJohn Marino   /* An obstack for the bitmaps we need for this problem.  */
190*e4b17023SJohn Marino   bitmap_obstack rd_bitmaps;
191*e4b17023SJohn Marino };
192*e4b17023SJohn Marino 
193*e4b17023SJohn Marino 
194*e4b17023SJohn Marino /* Free basic block info.  */
195*e4b17023SJohn Marino 
196*e4b17023SJohn Marino static void
df_rd_free_bb_info(basic_block bb ATTRIBUTE_UNUSED,void * vbb_info)197*e4b17023SJohn Marino df_rd_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
198*e4b17023SJohn Marino 		    void *vbb_info)
199*e4b17023SJohn Marino {
200*e4b17023SJohn Marino   struct df_rd_bb_info *bb_info = (struct df_rd_bb_info *) vbb_info;
201*e4b17023SJohn Marino   if (bb_info)
202*e4b17023SJohn Marino     {
203*e4b17023SJohn Marino       bitmap_clear (&bb_info->kill);
204*e4b17023SJohn Marino       bitmap_clear (&bb_info->sparse_kill);
205*e4b17023SJohn Marino       bitmap_clear (&bb_info->gen);
206*e4b17023SJohn Marino       bitmap_clear (&bb_info->in);
207*e4b17023SJohn Marino       bitmap_clear (&bb_info->out);
208*e4b17023SJohn Marino     }
209*e4b17023SJohn Marino }
210*e4b17023SJohn Marino 
211*e4b17023SJohn Marino 
212*e4b17023SJohn Marino /* Allocate or reset bitmaps for DF_RD blocks. The solution bits are
213*e4b17023SJohn Marino    not touched unless the block is new.  */
214*e4b17023SJohn Marino 
215*e4b17023SJohn Marino static void
df_rd_alloc(bitmap all_blocks)216*e4b17023SJohn Marino df_rd_alloc (bitmap all_blocks)
217*e4b17023SJohn Marino {
218*e4b17023SJohn Marino   unsigned int bb_index;
219*e4b17023SJohn Marino   bitmap_iterator bi;
220*e4b17023SJohn Marino   struct df_rd_problem_data *problem_data;
221*e4b17023SJohn Marino 
222*e4b17023SJohn Marino   if (df_rd->problem_data)
223*e4b17023SJohn Marino     {
224*e4b17023SJohn Marino       problem_data = (struct df_rd_problem_data *) df_rd->problem_data;
225*e4b17023SJohn Marino       bitmap_clear (&problem_data->sparse_invalidated_by_call);
226*e4b17023SJohn Marino       bitmap_clear (&problem_data->dense_invalidated_by_call);
227*e4b17023SJohn Marino     }
228*e4b17023SJohn Marino   else
229*e4b17023SJohn Marino     {
230*e4b17023SJohn Marino       problem_data = XNEW (struct df_rd_problem_data);
231*e4b17023SJohn Marino       df_rd->problem_data = problem_data;
232*e4b17023SJohn Marino 
233*e4b17023SJohn Marino       bitmap_obstack_initialize (&problem_data->rd_bitmaps);
234*e4b17023SJohn Marino       bitmap_initialize (&problem_data->sparse_invalidated_by_call,
235*e4b17023SJohn Marino 			 &problem_data->rd_bitmaps);
236*e4b17023SJohn Marino       bitmap_initialize (&problem_data->dense_invalidated_by_call,
237*e4b17023SJohn Marino 			 &problem_data->rd_bitmaps);
238*e4b17023SJohn Marino     }
239*e4b17023SJohn Marino 
240*e4b17023SJohn Marino   df_grow_bb_info (df_rd);
241*e4b17023SJohn Marino 
242*e4b17023SJohn Marino   /* Because of the clustering of all use sites for the same pseudo,
243*e4b17023SJohn Marino      we have to process all of the blocks before doing the
244*e4b17023SJohn Marino      analysis.  */
245*e4b17023SJohn Marino 
246*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
247*e4b17023SJohn Marino     {
248*e4b17023SJohn Marino       struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
249*e4b17023SJohn Marino 
250*e4b17023SJohn Marino       /* When bitmaps are already initialized, just clear them.  */
251*e4b17023SJohn Marino       if (bb_info->kill.obstack)
252*e4b17023SJohn Marino 	{
253*e4b17023SJohn Marino 	  bitmap_clear (&bb_info->kill);
254*e4b17023SJohn Marino 	  bitmap_clear (&bb_info->sparse_kill);
255*e4b17023SJohn Marino 	  bitmap_clear (&bb_info->gen);
256*e4b17023SJohn Marino 	}
257*e4b17023SJohn Marino       else
258*e4b17023SJohn Marino 	{
259*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->kill, &problem_data->rd_bitmaps);
260*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->sparse_kill, &problem_data->rd_bitmaps);
261*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->gen, &problem_data->rd_bitmaps);
262*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->in, &problem_data->rd_bitmaps);
263*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->out, &problem_data->rd_bitmaps);
264*e4b17023SJohn Marino 	}
265*e4b17023SJohn Marino     }
266*e4b17023SJohn Marino   df_rd->optional_p = true;
267*e4b17023SJohn Marino }
268*e4b17023SJohn Marino 
269*e4b17023SJohn Marino 
270*e4b17023SJohn Marino /* Add the effect of the top artificial defs of BB to the reaching definitions
271*e4b17023SJohn Marino    bitmap LOCAL_RD.  */
272*e4b17023SJohn Marino 
273*e4b17023SJohn Marino void
df_rd_simulate_artificial_defs_at_top(basic_block bb,bitmap local_rd)274*e4b17023SJohn Marino df_rd_simulate_artificial_defs_at_top (basic_block bb, bitmap local_rd)
275*e4b17023SJohn Marino {
276*e4b17023SJohn Marino   int bb_index = bb->index;
277*e4b17023SJohn Marino   df_ref *def_rec;
278*e4b17023SJohn Marino   for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
279*e4b17023SJohn Marino     {
280*e4b17023SJohn Marino       df_ref def = *def_rec;
281*e4b17023SJohn Marino       if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
282*e4b17023SJohn Marino 	{
283*e4b17023SJohn Marino 	  unsigned int dregno = DF_REF_REGNO (def);
284*e4b17023SJohn Marino 	  if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
285*e4b17023SJohn Marino 	    bitmap_clear_range (local_rd,
286*e4b17023SJohn Marino 				DF_DEFS_BEGIN (dregno),
287*e4b17023SJohn Marino 				DF_DEFS_COUNT (dregno));
288*e4b17023SJohn Marino 	  bitmap_set_bit (local_rd, DF_REF_ID (def));
289*e4b17023SJohn Marino 	}
290*e4b17023SJohn Marino     }
291*e4b17023SJohn Marino }
292*e4b17023SJohn Marino 
293*e4b17023SJohn Marino /* Add the effect of the defs of INSN to the reaching definitions bitmap
294*e4b17023SJohn Marino    LOCAL_RD.  */
295*e4b17023SJohn Marino 
296*e4b17023SJohn Marino void
df_rd_simulate_one_insn(basic_block bb ATTRIBUTE_UNUSED,rtx insn,bitmap local_rd)297*e4b17023SJohn Marino df_rd_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx insn,
298*e4b17023SJohn Marino 			 bitmap local_rd)
299*e4b17023SJohn Marino {
300*e4b17023SJohn Marino   unsigned uid = INSN_UID (insn);
301*e4b17023SJohn Marino   df_ref *def_rec;
302*e4b17023SJohn Marino 
303*e4b17023SJohn Marino   for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
304*e4b17023SJohn Marino     {
305*e4b17023SJohn Marino       df_ref def = *def_rec;
306*e4b17023SJohn Marino       unsigned int dregno = DF_REF_REGNO (def);
307*e4b17023SJohn Marino       if ((!(df->changeable_flags & DF_NO_HARD_REGS))
308*e4b17023SJohn Marino           || (dregno >= FIRST_PSEUDO_REGISTER))
309*e4b17023SJohn Marino         {
310*e4b17023SJohn Marino           if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
311*e4b17023SJohn Marino 	    bitmap_clear_range (local_rd,
312*e4b17023SJohn Marino 				DF_DEFS_BEGIN (dregno),
313*e4b17023SJohn Marino 				DF_DEFS_COUNT (dregno));
314*e4b17023SJohn Marino 	  if (!(DF_REF_FLAGS (def)
315*e4b17023SJohn Marino 		& (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
316*e4b17023SJohn Marino 	    bitmap_set_bit (local_rd, DF_REF_ID (def));
317*e4b17023SJohn Marino 	}
318*e4b17023SJohn Marino     }
319*e4b17023SJohn Marino }
320*e4b17023SJohn Marino 
321*e4b17023SJohn Marino /* Process a list of DEFs for df_rd_bb_local_compute.  This is a bit
322*e4b17023SJohn Marino    more complicated than just simulating, because we must produce the
323*e4b17023SJohn Marino    gen and kill sets and hence deal with the two possible representations
324*e4b17023SJohn Marino    of kill sets.   */
325*e4b17023SJohn Marino 
326*e4b17023SJohn Marino static void
df_rd_bb_local_compute_process_def(struct df_rd_bb_info * bb_info,df_ref * def_rec,int top_flag)327*e4b17023SJohn Marino df_rd_bb_local_compute_process_def (struct df_rd_bb_info *bb_info,
328*e4b17023SJohn Marino 				    df_ref *def_rec,
329*e4b17023SJohn Marino 				    int top_flag)
330*e4b17023SJohn Marino {
331*e4b17023SJohn Marino   while (*def_rec)
332*e4b17023SJohn Marino     {
333*e4b17023SJohn Marino       df_ref def = *def_rec;
334*e4b17023SJohn Marino       if (top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
335*e4b17023SJohn Marino 	{
336*e4b17023SJohn Marino 	  unsigned int regno = DF_REF_REGNO (def);
337*e4b17023SJohn Marino 	  unsigned int begin = DF_DEFS_BEGIN (regno);
338*e4b17023SJohn Marino 	  unsigned int n_defs = DF_DEFS_COUNT (regno);
339*e4b17023SJohn Marino 
340*e4b17023SJohn Marino 	  if ((!(df->changeable_flags & DF_NO_HARD_REGS))
341*e4b17023SJohn Marino 	      || (regno >= FIRST_PSEUDO_REGISTER))
342*e4b17023SJohn Marino 	    {
343*e4b17023SJohn Marino 	      /* Only the last def(s) for a regno in the block has any
344*e4b17023SJohn Marino 		 effect.  */
345*e4b17023SJohn Marino 	      if (!bitmap_bit_p (&seen_in_block, regno))
346*e4b17023SJohn Marino 		{
347*e4b17023SJohn Marino 		  /* The first def for regno in insn gets to knock out the
348*e4b17023SJohn Marino 		     defs from other instructions.  */
349*e4b17023SJohn Marino 		  if ((!bitmap_bit_p (&seen_in_insn, regno))
350*e4b17023SJohn Marino 		      /* If the def is to only part of the reg, it does
351*e4b17023SJohn Marino 			 not kill the other defs that reach here.  */
352*e4b17023SJohn Marino 		      && (!(DF_REF_FLAGS (def) &
353*e4b17023SJohn Marino 			    (DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER))))
354*e4b17023SJohn Marino 		    {
355*e4b17023SJohn Marino 		      if (n_defs > DF_SPARSE_THRESHOLD)
356*e4b17023SJohn Marino 			{
357*e4b17023SJohn Marino 			  bitmap_set_bit (&bb_info->sparse_kill, regno);
358*e4b17023SJohn Marino 			  bitmap_clear_range(&bb_info->gen, begin, n_defs);
359*e4b17023SJohn Marino 			}
360*e4b17023SJohn Marino 		      else
361*e4b17023SJohn Marino 			{
362*e4b17023SJohn Marino 			  bitmap_set_range (&bb_info->kill, begin, n_defs);
363*e4b17023SJohn Marino 			  bitmap_clear_range (&bb_info->gen, begin, n_defs);
364*e4b17023SJohn Marino 			}
365*e4b17023SJohn Marino 		    }
366*e4b17023SJohn Marino 
367*e4b17023SJohn Marino 		  bitmap_set_bit (&seen_in_insn, regno);
368*e4b17023SJohn Marino 		  /* All defs for regno in the instruction may be put into
369*e4b17023SJohn Marino 		     the gen set.  */
370*e4b17023SJohn Marino 		  if (!(DF_REF_FLAGS (def)
371*e4b17023SJohn Marino 			& (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
372*e4b17023SJohn Marino 		    bitmap_set_bit (&bb_info->gen, DF_REF_ID (def));
373*e4b17023SJohn Marino 		}
374*e4b17023SJohn Marino 	    }
375*e4b17023SJohn Marino 	}
376*e4b17023SJohn Marino       def_rec++;
377*e4b17023SJohn Marino     }
378*e4b17023SJohn Marino }
379*e4b17023SJohn Marino 
380*e4b17023SJohn Marino /* Compute local reaching def info for basic block BB.  */
381*e4b17023SJohn Marino 
382*e4b17023SJohn Marino static void
df_rd_bb_local_compute(unsigned int bb_index)383*e4b17023SJohn Marino df_rd_bb_local_compute (unsigned int bb_index)
384*e4b17023SJohn Marino {
385*e4b17023SJohn Marino   basic_block bb = BASIC_BLOCK (bb_index);
386*e4b17023SJohn Marino   struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
387*e4b17023SJohn Marino   rtx insn;
388*e4b17023SJohn Marino 
389*e4b17023SJohn Marino   bitmap_clear (&seen_in_block);
390*e4b17023SJohn Marino   bitmap_clear (&seen_in_insn);
391*e4b17023SJohn Marino 
392*e4b17023SJohn Marino   /* Artificials are only hard regs.  */
393*e4b17023SJohn Marino   if (!(df->changeable_flags & DF_NO_HARD_REGS))
394*e4b17023SJohn Marino     df_rd_bb_local_compute_process_def (bb_info,
395*e4b17023SJohn Marino 					df_get_artificial_defs (bb_index),
396*e4b17023SJohn Marino 					0);
397*e4b17023SJohn Marino 
398*e4b17023SJohn Marino   FOR_BB_INSNS_REVERSE (bb, insn)
399*e4b17023SJohn Marino     {
400*e4b17023SJohn Marino       unsigned int uid = INSN_UID (insn);
401*e4b17023SJohn Marino 
402*e4b17023SJohn Marino       if (!INSN_P (insn))
403*e4b17023SJohn Marino 	continue;
404*e4b17023SJohn Marino 
405*e4b17023SJohn Marino       df_rd_bb_local_compute_process_def (bb_info,
406*e4b17023SJohn Marino 					  DF_INSN_UID_DEFS (uid), 0);
407*e4b17023SJohn Marino 
408*e4b17023SJohn Marino       /* This complex dance with the two bitmaps is required because
409*e4b17023SJohn Marino 	 instructions can assign twice to the same pseudo.  This
410*e4b17023SJohn Marino 	 generally happens with calls that will have one def for the
411*e4b17023SJohn Marino 	 result and another def for the clobber.  If only one vector
412*e4b17023SJohn Marino 	 is used and the clobber goes first, the result will be
413*e4b17023SJohn Marino 	 lost.  */
414*e4b17023SJohn Marino       bitmap_ior_into (&seen_in_block, &seen_in_insn);
415*e4b17023SJohn Marino       bitmap_clear (&seen_in_insn);
416*e4b17023SJohn Marino     }
417*e4b17023SJohn Marino 
418*e4b17023SJohn Marino   /* Process the artificial defs at the top of the block last since we
419*e4b17023SJohn Marino      are going backwards through the block and these are logically at
420*e4b17023SJohn Marino      the start.  */
421*e4b17023SJohn Marino   if (!(df->changeable_flags & DF_NO_HARD_REGS))
422*e4b17023SJohn Marino     df_rd_bb_local_compute_process_def (bb_info,
423*e4b17023SJohn Marino 					df_get_artificial_defs (bb_index),
424*e4b17023SJohn Marino 					DF_REF_AT_TOP);
425*e4b17023SJohn Marino }
426*e4b17023SJohn Marino 
427*e4b17023SJohn Marino 
428*e4b17023SJohn Marino /* Compute local reaching def info for each basic block within BLOCKS.  */
429*e4b17023SJohn Marino 
430*e4b17023SJohn Marino static void
df_rd_local_compute(bitmap all_blocks)431*e4b17023SJohn Marino df_rd_local_compute (bitmap all_blocks)
432*e4b17023SJohn Marino {
433*e4b17023SJohn Marino   unsigned int bb_index;
434*e4b17023SJohn Marino   bitmap_iterator bi;
435*e4b17023SJohn Marino   unsigned int regno;
436*e4b17023SJohn Marino   struct df_rd_problem_data *problem_data
437*e4b17023SJohn Marino     = (struct df_rd_problem_data *) df_rd->problem_data;
438*e4b17023SJohn Marino   bitmap sparse_invalidated = &problem_data->sparse_invalidated_by_call;
439*e4b17023SJohn Marino   bitmap dense_invalidated = &problem_data->dense_invalidated_by_call;
440*e4b17023SJohn Marino 
441*e4b17023SJohn Marino   bitmap_initialize (&seen_in_block, &df_bitmap_obstack);
442*e4b17023SJohn Marino   bitmap_initialize (&seen_in_insn, &df_bitmap_obstack);
443*e4b17023SJohn Marino 
444*e4b17023SJohn Marino   df_maybe_reorganize_def_refs (DF_REF_ORDER_BY_REG);
445*e4b17023SJohn Marino 
446*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
447*e4b17023SJohn Marino     {
448*e4b17023SJohn Marino       df_rd_bb_local_compute (bb_index);
449*e4b17023SJohn Marino     }
450*e4b17023SJohn Marino 
451*e4b17023SJohn Marino   /* Set up the knockout bit vectors to be applied across EH_EDGES.  */
452*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (regs_invalidated_by_call_regset, 0, regno, bi)
453*e4b17023SJohn Marino     {
454*e4b17023SJohn Marino       if (DF_DEFS_COUNT (regno) > DF_SPARSE_THRESHOLD)
455*e4b17023SJohn Marino 	bitmap_set_bit (sparse_invalidated, regno);
456*e4b17023SJohn Marino       else
457*e4b17023SJohn Marino 	bitmap_set_range (dense_invalidated,
458*e4b17023SJohn Marino 			  DF_DEFS_BEGIN (regno),
459*e4b17023SJohn Marino 			  DF_DEFS_COUNT (regno));
460*e4b17023SJohn Marino     }
461*e4b17023SJohn Marino 
462*e4b17023SJohn Marino   bitmap_clear (&seen_in_block);
463*e4b17023SJohn Marino   bitmap_clear (&seen_in_insn);
464*e4b17023SJohn Marino }
465*e4b17023SJohn Marino 
466*e4b17023SJohn Marino 
467*e4b17023SJohn Marino /* Initialize the solution bit vectors for problem.  */
468*e4b17023SJohn Marino 
469*e4b17023SJohn Marino static void
df_rd_init_solution(bitmap all_blocks)470*e4b17023SJohn Marino df_rd_init_solution (bitmap all_blocks)
471*e4b17023SJohn Marino {
472*e4b17023SJohn Marino   unsigned int bb_index;
473*e4b17023SJohn Marino   bitmap_iterator bi;
474*e4b17023SJohn Marino 
475*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
476*e4b17023SJohn Marino     {
477*e4b17023SJohn Marino       struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
478*e4b17023SJohn Marino 
479*e4b17023SJohn Marino       bitmap_copy (&bb_info->out, &bb_info->gen);
480*e4b17023SJohn Marino       bitmap_clear (&bb_info->in);
481*e4b17023SJohn Marino     }
482*e4b17023SJohn Marino }
483*e4b17023SJohn Marino 
484*e4b17023SJohn Marino /* In of target gets or of out of source.  */
485*e4b17023SJohn Marino 
486*e4b17023SJohn Marino static bool
df_rd_confluence_n(edge e)487*e4b17023SJohn Marino df_rd_confluence_n (edge e)
488*e4b17023SJohn Marino {
489*e4b17023SJohn Marino   bitmap op1 = &df_rd_get_bb_info (e->dest->index)->in;
490*e4b17023SJohn Marino   bitmap op2 = &df_rd_get_bb_info (e->src->index)->out;
491*e4b17023SJohn Marino   bool changed = false;
492*e4b17023SJohn Marino 
493*e4b17023SJohn Marino   if (e->flags & EDGE_FAKE)
494*e4b17023SJohn Marino     return false;
495*e4b17023SJohn Marino 
496*e4b17023SJohn Marino   if (e->flags & EDGE_EH)
497*e4b17023SJohn Marino     {
498*e4b17023SJohn Marino       struct df_rd_problem_data *problem_data
499*e4b17023SJohn Marino 	= (struct df_rd_problem_data *) df_rd->problem_data;
500*e4b17023SJohn Marino       bitmap sparse_invalidated = &problem_data->sparse_invalidated_by_call;
501*e4b17023SJohn Marino       bitmap dense_invalidated = &problem_data->dense_invalidated_by_call;
502*e4b17023SJohn Marino       bitmap_iterator bi;
503*e4b17023SJohn Marino       unsigned int regno;
504*e4b17023SJohn Marino       bitmap_head tmp;
505*e4b17023SJohn Marino 
506*e4b17023SJohn Marino       bitmap_initialize (&tmp, &df_bitmap_obstack);
507*e4b17023SJohn Marino       bitmap_copy (&tmp, op2);
508*e4b17023SJohn Marino       bitmap_and_compl_into (&tmp, dense_invalidated);
509*e4b17023SJohn Marino 
510*e4b17023SJohn Marino       EXECUTE_IF_SET_IN_BITMAP (sparse_invalidated, 0, regno, bi)
511*e4b17023SJohn Marino  	{
512*e4b17023SJohn Marino  	  bitmap_clear_range (&tmp,
513*e4b17023SJohn Marino  			      DF_DEFS_BEGIN (regno),
514*e4b17023SJohn Marino  			      DF_DEFS_COUNT (regno));
515*e4b17023SJohn Marino 	}
516*e4b17023SJohn Marino       changed |= bitmap_ior_into (op1, &tmp);
517*e4b17023SJohn Marino       bitmap_clear (&tmp);
518*e4b17023SJohn Marino       return changed;
519*e4b17023SJohn Marino     }
520*e4b17023SJohn Marino   else
521*e4b17023SJohn Marino     return bitmap_ior_into (op1, op2);
522*e4b17023SJohn Marino }
523*e4b17023SJohn Marino 
524*e4b17023SJohn Marino 
525*e4b17023SJohn Marino /* Transfer function.  */
526*e4b17023SJohn Marino 
527*e4b17023SJohn Marino static bool
df_rd_transfer_function(int bb_index)528*e4b17023SJohn Marino df_rd_transfer_function (int bb_index)
529*e4b17023SJohn Marino {
530*e4b17023SJohn Marino   struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
531*e4b17023SJohn Marino   unsigned int regno;
532*e4b17023SJohn Marino   bitmap_iterator bi;
533*e4b17023SJohn Marino   bitmap in = &bb_info->in;
534*e4b17023SJohn Marino   bitmap out = &bb_info->out;
535*e4b17023SJohn Marino   bitmap gen = &bb_info->gen;
536*e4b17023SJohn Marino   bitmap kill = &bb_info->kill;
537*e4b17023SJohn Marino   bitmap sparse_kill = &bb_info->sparse_kill;
538*e4b17023SJohn Marino 
539*e4b17023SJohn Marino   if (bitmap_empty_p (sparse_kill))
540*e4b17023SJohn Marino     return  bitmap_ior_and_compl (out, gen, in, kill);
541*e4b17023SJohn Marino   else
542*e4b17023SJohn Marino     {
543*e4b17023SJohn Marino       struct df_rd_problem_data *problem_data;
544*e4b17023SJohn Marino       bool changed = false;
545*e4b17023SJohn Marino       bitmap_head tmp;
546*e4b17023SJohn Marino 
547*e4b17023SJohn Marino       /* Note that TMP is _not_ a temporary bitmap if we end up replacing
548*e4b17023SJohn Marino 	 OUT with TMP.  Therefore, allocate TMP in the RD bitmaps obstack.  */
549*e4b17023SJohn Marino       problem_data = (struct df_rd_problem_data *) df_rd->problem_data;
550*e4b17023SJohn Marino       bitmap_initialize (&tmp, &problem_data->rd_bitmaps);
551*e4b17023SJohn Marino 
552*e4b17023SJohn Marino       bitmap_copy (&tmp, in);
553*e4b17023SJohn Marino       EXECUTE_IF_SET_IN_BITMAP (sparse_kill, 0, regno, bi)
554*e4b17023SJohn Marino 	{
555*e4b17023SJohn Marino 	  bitmap_clear_range (&tmp,
556*e4b17023SJohn Marino 			      DF_DEFS_BEGIN (regno),
557*e4b17023SJohn Marino 			      DF_DEFS_COUNT (regno));
558*e4b17023SJohn Marino 	}
559*e4b17023SJohn Marino       bitmap_and_compl_into (&tmp, kill);
560*e4b17023SJohn Marino       bitmap_ior_into (&tmp, gen);
561*e4b17023SJohn Marino       changed = !bitmap_equal_p (&tmp, out);
562*e4b17023SJohn Marino       if (changed)
563*e4b17023SJohn Marino 	{
564*e4b17023SJohn Marino 	  bitmap_clear (out);
565*e4b17023SJohn Marino 	  bb_info->out = tmp;
566*e4b17023SJohn Marino 	}
567*e4b17023SJohn Marino       else
568*e4b17023SJohn Marino 	  bitmap_clear (&tmp);
569*e4b17023SJohn Marino       return changed;
570*e4b17023SJohn Marino     }
571*e4b17023SJohn Marino }
572*e4b17023SJohn Marino 
573*e4b17023SJohn Marino 
574*e4b17023SJohn Marino /* Free all storage associated with the problem.  */
575*e4b17023SJohn Marino 
576*e4b17023SJohn Marino static void
df_rd_free(void)577*e4b17023SJohn Marino df_rd_free (void)
578*e4b17023SJohn Marino {
579*e4b17023SJohn Marino   struct df_rd_problem_data *problem_data
580*e4b17023SJohn Marino     = (struct df_rd_problem_data *) df_rd->problem_data;
581*e4b17023SJohn Marino 
582*e4b17023SJohn Marino   if (problem_data)
583*e4b17023SJohn Marino     {
584*e4b17023SJohn Marino       bitmap_obstack_release (&problem_data->rd_bitmaps);
585*e4b17023SJohn Marino 
586*e4b17023SJohn Marino       df_rd->block_info_size = 0;
587*e4b17023SJohn Marino       free (df_rd->block_info);
588*e4b17023SJohn Marino       df_rd->block_info = NULL;
589*e4b17023SJohn Marino       free (df_rd->problem_data);
590*e4b17023SJohn Marino     }
591*e4b17023SJohn Marino   free (df_rd);
592*e4b17023SJohn Marino }
593*e4b17023SJohn Marino 
594*e4b17023SJohn Marino 
595*e4b17023SJohn Marino /* Debugging info.  */
596*e4b17023SJohn Marino 
597*e4b17023SJohn Marino static void
df_rd_start_dump(FILE * file)598*e4b17023SJohn Marino df_rd_start_dump (FILE *file)
599*e4b17023SJohn Marino {
600*e4b17023SJohn Marino   struct df_rd_problem_data *problem_data
601*e4b17023SJohn Marino     = (struct df_rd_problem_data *) df_rd->problem_data;
602*e4b17023SJohn Marino   unsigned int m = DF_REG_SIZE(df);
603*e4b17023SJohn Marino   unsigned int regno;
604*e4b17023SJohn Marino 
605*e4b17023SJohn Marino   if (!df_rd->block_info)
606*e4b17023SJohn Marino     return;
607*e4b17023SJohn Marino 
608*e4b17023SJohn Marino   fprintf (file, ";; Reaching defs:\n\n");
609*e4b17023SJohn Marino 
610*e4b17023SJohn Marino   fprintf (file, "  sparse invalidated \t");
611*e4b17023SJohn Marino   dump_bitmap (file, &problem_data->sparse_invalidated_by_call);
612*e4b17023SJohn Marino   fprintf (file, "  dense invalidated \t");
613*e4b17023SJohn Marino   dump_bitmap (file, &problem_data->dense_invalidated_by_call);
614*e4b17023SJohn Marino 
615*e4b17023SJohn Marino   for (regno = 0; regno < m; regno++)
616*e4b17023SJohn Marino     if (DF_DEFS_COUNT (regno))
617*e4b17023SJohn Marino       fprintf (file, "%d[%d,%d] ", regno,
618*e4b17023SJohn Marino 	       DF_DEFS_BEGIN (regno),
619*e4b17023SJohn Marino 	       DF_DEFS_COUNT (regno));
620*e4b17023SJohn Marino   fprintf (file, "\n");
621*e4b17023SJohn Marino 
622*e4b17023SJohn Marino }
623*e4b17023SJohn Marino 
624*e4b17023SJohn Marino 
625*e4b17023SJohn Marino /* Debugging info at top of bb.  */
626*e4b17023SJohn Marino 
627*e4b17023SJohn Marino static void
df_rd_top_dump(basic_block bb,FILE * file)628*e4b17023SJohn Marino df_rd_top_dump (basic_block bb, FILE *file)
629*e4b17023SJohn Marino {
630*e4b17023SJohn Marino   struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb->index);
631*e4b17023SJohn Marino   if (!bb_info)
632*e4b17023SJohn Marino     return;
633*e4b17023SJohn Marino 
634*e4b17023SJohn Marino   fprintf (file, ";; rd  in  \t(%d)\n", (int) bitmap_count_bits (&bb_info->in));
635*e4b17023SJohn Marino   dump_bitmap (file, &bb_info->in);
636*e4b17023SJohn Marino   fprintf (file, ";; rd  gen \t(%d)\n", (int) bitmap_count_bits (&bb_info->gen));
637*e4b17023SJohn Marino   dump_bitmap (file, &bb_info->gen);
638*e4b17023SJohn Marino   fprintf (file, ";; rd  kill\t(%d)\n", (int) bitmap_count_bits (&bb_info->kill));
639*e4b17023SJohn Marino   dump_bitmap (file, &bb_info->kill);
640*e4b17023SJohn Marino }
641*e4b17023SJohn Marino 
642*e4b17023SJohn Marino 
643*e4b17023SJohn Marino /* Debugging info at top of bb.  */
644*e4b17023SJohn Marino 
645*e4b17023SJohn Marino static void
df_rd_bottom_dump(basic_block bb,FILE * file)646*e4b17023SJohn Marino df_rd_bottom_dump (basic_block bb, FILE *file)
647*e4b17023SJohn Marino {
648*e4b17023SJohn Marino   struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb->index);
649*e4b17023SJohn Marino   if (!bb_info)
650*e4b17023SJohn Marino     return;
651*e4b17023SJohn Marino 
652*e4b17023SJohn Marino   fprintf (file, ";; rd  out \t(%d)\n", (int) bitmap_count_bits (&bb_info->out));
653*e4b17023SJohn Marino   dump_bitmap (file, &bb_info->out);
654*e4b17023SJohn Marino }
655*e4b17023SJohn Marino 
656*e4b17023SJohn Marino /* All of the information associated with every instance of the problem.  */
657*e4b17023SJohn Marino 
658*e4b17023SJohn Marino static struct df_problem problem_RD =
659*e4b17023SJohn Marino {
660*e4b17023SJohn Marino   DF_RD,                      /* Problem id.  */
661*e4b17023SJohn Marino   DF_FORWARD,                 /* Direction.  */
662*e4b17023SJohn Marino   df_rd_alloc,                /* Allocate the problem specific data.  */
663*e4b17023SJohn Marino   NULL,                       /* Reset global information.  */
664*e4b17023SJohn Marino   df_rd_free_bb_info,         /* Free basic block info.  */
665*e4b17023SJohn Marino   df_rd_local_compute,        /* Local compute function.  */
666*e4b17023SJohn Marino   df_rd_init_solution,        /* Init the solution specific data.  */
667*e4b17023SJohn Marino   df_worklist_dataflow,       /* Worklist solver.  */
668*e4b17023SJohn Marino   NULL,                       /* Confluence operator 0.  */
669*e4b17023SJohn Marino   df_rd_confluence_n,         /* Confluence operator n.  */
670*e4b17023SJohn Marino   df_rd_transfer_function,    /* Transfer function.  */
671*e4b17023SJohn Marino   NULL,                       /* Finalize function.  */
672*e4b17023SJohn Marino   df_rd_free,                 /* Free all of the problem information.  */
673*e4b17023SJohn Marino   df_rd_free,                 /* Remove this problem from the stack of dataflow problems.  */
674*e4b17023SJohn Marino   df_rd_start_dump,           /* Debugging.  */
675*e4b17023SJohn Marino   df_rd_top_dump,             /* Debugging start block.  */
676*e4b17023SJohn Marino   df_rd_bottom_dump,          /* Debugging end block.  */
677*e4b17023SJohn Marino   NULL,                       /* Incremental solution verify start.  */
678*e4b17023SJohn Marino   NULL,                       /* Incremental solution verify end.  */
679*e4b17023SJohn Marino   NULL,                       /* Dependent problem.  */
680*e4b17023SJohn Marino   sizeof (struct df_rd_bb_info),/* Size of entry of block_info array.  */
681*e4b17023SJohn Marino   TV_DF_RD,                   /* Timing variable.  */
682*e4b17023SJohn Marino   true                        /* Reset blocks on dropping out of blocks_to_analyze.  */
683*e4b17023SJohn Marino };
684*e4b17023SJohn Marino 
685*e4b17023SJohn Marino 
686*e4b17023SJohn Marino 
687*e4b17023SJohn Marino /* Create a new RD instance and add it to the existing instance
688*e4b17023SJohn Marino    of DF.  */
689*e4b17023SJohn Marino 
690*e4b17023SJohn Marino void
df_rd_add_problem(void)691*e4b17023SJohn Marino df_rd_add_problem (void)
692*e4b17023SJohn Marino {
693*e4b17023SJohn Marino   df_add_problem (&problem_RD);
694*e4b17023SJohn Marino }
695*e4b17023SJohn Marino 
696*e4b17023SJohn Marino 
697*e4b17023SJohn Marino 
698*e4b17023SJohn Marino /*----------------------------------------------------------------------------
699*e4b17023SJohn Marino    LIVE REGISTERS
700*e4b17023SJohn Marino 
701*e4b17023SJohn Marino    Find the locations in the function where any use of a pseudo can
702*e4b17023SJohn Marino    reach in the backwards direction.  In and out bitvectors are built
703*e4b17023SJohn Marino    for each basic block.  The regno is used to index into these sets.
704*e4b17023SJohn Marino    See df.h for details.
705*e4b17023SJohn Marino    ----------------------------------------------------------------------------*/
706*e4b17023SJohn Marino 
707*e4b17023SJohn Marino /* Private data used to verify the solution for this problem.  */
708*e4b17023SJohn Marino struct df_lr_problem_data
709*e4b17023SJohn Marino {
710*e4b17023SJohn Marino   bitmap_head *in;
711*e4b17023SJohn Marino   bitmap_head *out;
712*e4b17023SJohn Marino   /* An obstack for the bitmaps we need for this problem.  */
713*e4b17023SJohn Marino   bitmap_obstack lr_bitmaps;
714*e4b17023SJohn Marino };
715*e4b17023SJohn Marino 
716*e4b17023SJohn Marino /* Free basic block info.  */
717*e4b17023SJohn Marino 
718*e4b17023SJohn Marino static void
df_lr_free_bb_info(basic_block bb ATTRIBUTE_UNUSED,void * vbb_info)719*e4b17023SJohn Marino df_lr_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
720*e4b17023SJohn Marino 		    void *vbb_info)
721*e4b17023SJohn Marino {
722*e4b17023SJohn Marino   struct df_lr_bb_info *bb_info = (struct df_lr_bb_info *) vbb_info;
723*e4b17023SJohn Marino   if (bb_info)
724*e4b17023SJohn Marino     {
725*e4b17023SJohn Marino       bitmap_clear (&bb_info->use);
726*e4b17023SJohn Marino       bitmap_clear (&bb_info->def);
727*e4b17023SJohn Marino       bitmap_clear (&bb_info->in);
728*e4b17023SJohn Marino       bitmap_clear (&bb_info->out);
729*e4b17023SJohn Marino     }
730*e4b17023SJohn Marino }
731*e4b17023SJohn Marino 
732*e4b17023SJohn Marino 
733*e4b17023SJohn Marino /* Allocate or reset bitmaps for DF_LR blocks. The solution bits are
734*e4b17023SJohn Marino    not touched unless the block is new.  */
735*e4b17023SJohn Marino 
736*e4b17023SJohn Marino static void
df_lr_alloc(bitmap all_blocks ATTRIBUTE_UNUSED)737*e4b17023SJohn Marino df_lr_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
738*e4b17023SJohn Marino {
739*e4b17023SJohn Marino   unsigned int bb_index;
740*e4b17023SJohn Marino   bitmap_iterator bi;
741*e4b17023SJohn Marino   struct df_lr_problem_data *problem_data;
742*e4b17023SJohn Marino 
743*e4b17023SJohn Marino   df_grow_bb_info (df_lr);
744*e4b17023SJohn Marino   if (df_lr->problem_data)
745*e4b17023SJohn Marino     problem_data = (struct df_lr_problem_data *) df_lr->problem_data;
746*e4b17023SJohn Marino   else
747*e4b17023SJohn Marino     {
748*e4b17023SJohn Marino       problem_data = XNEW (struct df_lr_problem_data);
749*e4b17023SJohn Marino       df_lr->problem_data = problem_data;
750*e4b17023SJohn Marino 
751*e4b17023SJohn Marino       problem_data->out = NULL;
752*e4b17023SJohn Marino       problem_data->in = NULL;
753*e4b17023SJohn Marino       bitmap_obstack_initialize (&problem_data->lr_bitmaps);
754*e4b17023SJohn Marino     }
755*e4b17023SJohn Marino 
756*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (df_lr->out_of_date_transfer_functions, 0, bb_index, bi)
757*e4b17023SJohn Marino     {
758*e4b17023SJohn Marino       struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
759*e4b17023SJohn Marino 
760*e4b17023SJohn Marino       /* When bitmaps are already initialized, just clear them.  */
761*e4b17023SJohn Marino       if (bb_info->use.obstack)
762*e4b17023SJohn Marino 	{
763*e4b17023SJohn Marino 	  bitmap_clear (&bb_info->def);
764*e4b17023SJohn Marino 	  bitmap_clear (&bb_info->use);
765*e4b17023SJohn Marino 	}
766*e4b17023SJohn Marino       else
767*e4b17023SJohn Marino 	{
768*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->use, &problem_data->lr_bitmaps);
769*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->def, &problem_data->lr_bitmaps);
770*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->in, &problem_data->lr_bitmaps);
771*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->out, &problem_data->lr_bitmaps);
772*e4b17023SJohn Marino 	}
773*e4b17023SJohn Marino     }
774*e4b17023SJohn Marino 
775*e4b17023SJohn Marino   df_lr->optional_p = false;
776*e4b17023SJohn Marino }
777*e4b17023SJohn Marino 
778*e4b17023SJohn Marino 
779*e4b17023SJohn Marino /* Reset the global solution for recalculation.  */
780*e4b17023SJohn Marino 
781*e4b17023SJohn Marino static void
df_lr_reset(bitmap all_blocks)782*e4b17023SJohn Marino df_lr_reset (bitmap all_blocks)
783*e4b17023SJohn Marino {
784*e4b17023SJohn Marino   unsigned int bb_index;
785*e4b17023SJohn Marino   bitmap_iterator bi;
786*e4b17023SJohn Marino 
787*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
788*e4b17023SJohn Marino     {
789*e4b17023SJohn Marino       struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
790*e4b17023SJohn Marino       gcc_assert (bb_info);
791*e4b17023SJohn Marino       bitmap_clear (&bb_info->in);
792*e4b17023SJohn Marino       bitmap_clear (&bb_info->out);
793*e4b17023SJohn Marino     }
794*e4b17023SJohn Marino }
795*e4b17023SJohn Marino 
796*e4b17023SJohn Marino 
797*e4b17023SJohn Marino /* Compute local live register info for basic block BB.  */
798*e4b17023SJohn Marino 
799*e4b17023SJohn Marino static void
df_lr_bb_local_compute(unsigned int bb_index)800*e4b17023SJohn Marino df_lr_bb_local_compute (unsigned int bb_index)
801*e4b17023SJohn Marino {
802*e4b17023SJohn Marino   basic_block bb = BASIC_BLOCK (bb_index);
803*e4b17023SJohn Marino   struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
804*e4b17023SJohn Marino   rtx insn;
805*e4b17023SJohn Marino   df_ref *def_rec;
806*e4b17023SJohn Marino   df_ref *use_rec;
807*e4b17023SJohn Marino 
808*e4b17023SJohn Marino   /* Process the registers set in an exception handler.  */
809*e4b17023SJohn Marino   for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
810*e4b17023SJohn Marino     {
811*e4b17023SJohn Marino       df_ref def = *def_rec;
812*e4b17023SJohn Marino       if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
813*e4b17023SJohn Marino 	{
814*e4b17023SJohn Marino 	  unsigned int dregno = DF_REF_REGNO (def);
815*e4b17023SJohn Marino 	  bitmap_set_bit (&bb_info->def, dregno);
816*e4b17023SJohn Marino 	  bitmap_clear_bit (&bb_info->use, dregno);
817*e4b17023SJohn Marino 	}
818*e4b17023SJohn Marino     }
819*e4b17023SJohn Marino 
820*e4b17023SJohn Marino   /* Process the hardware registers that are always live.  */
821*e4b17023SJohn Marino   for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
822*e4b17023SJohn Marino     {
823*e4b17023SJohn Marino       df_ref use = *use_rec;
824*e4b17023SJohn Marino       /* Add use to set of uses in this BB.  */
825*e4b17023SJohn Marino       if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
826*e4b17023SJohn Marino 	bitmap_set_bit (&bb_info->use, DF_REF_REGNO (use));
827*e4b17023SJohn Marino     }
828*e4b17023SJohn Marino 
829*e4b17023SJohn Marino   FOR_BB_INSNS_REVERSE (bb, insn)
830*e4b17023SJohn Marino     {
831*e4b17023SJohn Marino       unsigned int uid = INSN_UID (insn);
832*e4b17023SJohn Marino 
833*e4b17023SJohn Marino       if (!NONDEBUG_INSN_P (insn))
834*e4b17023SJohn Marino 	continue;
835*e4b17023SJohn Marino 
836*e4b17023SJohn Marino       for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
837*e4b17023SJohn Marino 	{
838*e4b17023SJohn Marino 	  df_ref def = *def_rec;
839*e4b17023SJohn Marino 	  /* If the def is to only part of the reg, it does
840*e4b17023SJohn Marino 	     not kill the other defs that reach here.  */
841*e4b17023SJohn Marino 	  if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
842*e4b17023SJohn Marino 	    {
843*e4b17023SJohn Marino 	      unsigned int dregno = DF_REF_REGNO (def);
844*e4b17023SJohn Marino 	      bitmap_set_bit (&bb_info->def, dregno);
845*e4b17023SJohn Marino 	      bitmap_clear_bit (&bb_info->use, dregno);
846*e4b17023SJohn Marino 	    }
847*e4b17023SJohn Marino 	}
848*e4b17023SJohn Marino 
849*e4b17023SJohn Marino       for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
850*e4b17023SJohn Marino 	{
851*e4b17023SJohn Marino 	  df_ref use = *use_rec;
852*e4b17023SJohn Marino 	  /* Add use to set of uses in this BB.  */
853*e4b17023SJohn Marino 	  bitmap_set_bit (&bb_info->use, DF_REF_REGNO (use));
854*e4b17023SJohn Marino 	}
855*e4b17023SJohn Marino     }
856*e4b17023SJohn Marino 
857*e4b17023SJohn Marino   /* Process the registers set in an exception handler or the hard
858*e4b17023SJohn Marino      frame pointer if this block is the target of a non local
859*e4b17023SJohn Marino      goto.  */
860*e4b17023SJohn Marino   for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
861*e4b17023SJohn Marino     {
862*e4b17023SJohn Marino       df_ref def = *def_rec;
863*e4b17023SJohn Marino       if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
864*e4b17023SJohn Marino 	{
865*e4b17023SJohn Marino 	  unsigned int dregno = DF_REF_REGNO (def);
866*e4b17023SJohn Marino 	  bitmap_set_bit (&bb_info->def, dregno);
867*e4b17023SJohn Marino 	  bitmap_clear_bit (&bb_info->use, dregno);
868*e4b17023SJohn Marino 	}
869*e4b17023SJohn Marino     }
870*e4b17023SJohn Marino 
871*e4b17023SJohn Marino #ifdef EH_USES
872*e4b17023SJohn Marino   /* Process the uses that are live into an exception handler.  */
873*e4b17023SJohn Marino   for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
874*e4b17023SJohn Marino     {
875*e4b17023SJohn Marino       df_ref use = *use_rec;
876*e4b17023SJohn Marino       /* Add use to set of uses in this BB.  */
877*e4b17023SJohn Marino       if (DF_REF_FLAGS (use) & DF_REF_AT_TOP)
878*e4b17023SJohn Marino 	bitmap_set_bit (&bb_info->use, DF_REF_REGNO (use));
879*e4b17023SJohn Marino     }
880*e4b17023SJohn Marino #endif
881*e4b17023SJohn Marino 
882*e4b17023SJohn Marino   /* If the df_live problem is not defined, such as at -O0 and -O1, we
883*e4b17023SJohn Marino      still need to keep the luids up to date.  This is normally done
884*e4b17023SJohn Marino      in the df_live problem since this problem has a forwards
885*e4b17023SJohn Marino      scan.  */
886*e4b17023SJohn Marino   if (!df_live)
887*e4b17023SJohn Marino     df_recompute_luids (bb);
888*e4b17023SJohn Marino }
889*e4b17023SJohn Marino 
890*e4b17023SJohn Marino 
891*e4b17023SJohn Marino /* Compute local live register info for each basic block within BLOCKS.  */
892*e4b17023SJohn Marino 
893*e4b17023SJohn Marino static void
df_lr_local_compute(bitmap all_blocks ATTRIBUTE_UNUSED)894*e4b17023SJohn Marino df_lr_local_compute (bitmap all_blocks ATTRIBUTE_UNUSED)
895*e4b17023SJohn Marino {
896*e4b17023SJohn Marino   unsigned int bb_index;
897*e4b17023SJohn Marino   bitmap_iterator bi;
898*e4b17023SJohn Marino 
899*e4b17023SJohn Marino   bitmap_clear (&df->hardware_regs_used);
900*e4b17023SJohn Marino 
901*e4b17023SJohn Marino   /* The all-important stack pointer must always be live.  */
902*e4b17023SJohn Marino   bitmap_set_bit (&df->hardware_regs_used, STACK_POINTER_REGNUM);
903*e4b17023SJohn Marino 
904*e4b17023SJohn Marino   /* Before reload, there are a few registers that must be forced
905*e4b17023SJohn Marino      live everywhere -- which might not already be the case for
906*e4b17023SJohn Marino      blocks within infinite loops.  */
907*e4b17023SJohn Marino   if (!reload_completed)
908*e4b17023SJohn Marino     {
909*e4b17023SJohn Marino       unsigned int pic_offset_table_regnum = PIC_OFFSET_TABLE_REGNUM;
910*e4b17023SJohn Marino       /* Any reference to any pseudo before reload is a potential
911*e4b17023SJohn Marino 	 reference of the frame pointer.  */
912*e4b17023SJohn Marino       bitmap_set_bit (&df->hardware_regs_used, FRAME_POINTER_REGNUM);
913*e4b17023SJohn Marino 
914*e4b17023SJohn Marino #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
915*e4b17023SJohn Marino       /* Pseudos with argument area equivalences may require
916*e4b17023SJohn Marino 	 reloading via the argument pointer.  */
917*e4b17023SJohn Marino       if (fixed_regs[ARG_POINTER_REGNUM])
918*e4b17023SJohn Marino 	bitmap_set_bit (&df->hardware_regs_used, ARG_POINTER_REGNUM);
919*e4b17023SJohn Marino #endif
920*e4b17023SJohn Marino 
921*e4b17023SJohn Marino       /* Any constant, or pseudo with constant equivalences, may
922*e4b17023SJohn Marino 	 require reloading from memory using the pic register.  */
923*e4b17023SJohn Marino       if (pic_offset_table_regnum != INVALID_REGNUM
924*e4b17023SJohn Marino 	  && fixed_regs[pic_offset_table_regnum])
925*e4b17023SJohn Marino 	bitmap_set_bit (&df->hardware_regs_used, pic_offset_table_regnum);
926*e4b17023SJohn Marino     }
927*e4b17023SJohn Marino 
928*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (df_lr->out_of_date_transfer_functions, 0, bb_index, bi)
929*e4b17023SJohn Marino     {
930*e4b17023SJohn Marino       if (bb_index == EXIT_BLOCK)
931*e4b17023SJohn Marino 	{
932*e4b17023SJohn Marino 	  /* The exit block is special for this problem and its bits are
933*e4b17023SJohn Marino 	     computed from thin air.  */
934*e4b17023SJohn Marino 	  struct df_lr_bb_info *bb_info = df_lr_get_bb_info (EXIT_BLOCK);
935*e4b17023SJohn Marino 	  bitmap_copy (&bb_info->use, df->exit_block_uses);
936*e4b17023SJohn Marino 	}
937*e4b17023SJohn Marino       else
938*e4b17023SJohn Marino 	df_lr_bb_local_compute (bb_index);
939*e4b17023SJohn Marino     }
940*e4b17023SJohn Marino 
941*e4b17023SJohn Marino   bitmap_clear (df_lr->out_of_date_transfer_functions);
942*e4b17023SJohn Marino }
943*e4b17023SJohn Marino 
944*e4b17023SJohn Marino 
945*e4b17023SJohn Marino /* Initialize the solution vectors.  */
946*e4b17023SJohn Marino 
947*e4b17023SJohn Marino static void
df_lr_init(bitmap all_blocks)948*e4b17023SJohn Marino df_lr_init (bitmap all_blocks)
949*e4b17023SJohn Marino {
950*e4b17023SJohn Marino   unsigned int bb_index;
951*e4b17023SJohn Marino   bitmap_iterator bi;
952*e4b17023SJohn Marino 
953*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
954*e4b17023SJohn Marino     {
955*e4b17023SJohn Marino       struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
956*e4b17023SJohn Marino       bitmap_copy (&bb_info->in, &bb_info->use);
957*e4b17023SJohn Marino       bitmap_clear (&bb_info->out);
958*e4b17023SJohn Marino     }
959*e4b17023SJohn Marino }
960*e4b17023SJohn Marino 
961*e4b17023SJohn Marino 
962*e4b17023SJohn Marino /* Confluence function that processes infinite loops.  This might be a
963*e4b17023SJohn Marino    noreturn function that throws.  And even if it isn't, getting the
964*e4b17023SJohn Marino    unwind info right helps debugging.  */
965*e4b17023SJohn Marino static void
df_lr_confluence_0(basic_block bb)966*e4b17023SJohn Marino df_lr_confluence_0 (basic_block bb)
967*e4b17023SJohn Marino {
968*e4b17023SJohn Marino   bitmap op1 = &df_lr_get_bb_info (bb->index)->out;
969*e4b17023SJohn Marino   if (bb != EXIT_BLOCK_PTR)
970*e4b17023SJohn Marino     bitmap_copy (op1, &df->hardware_regs_used);
971*e4b17023SJohn Marino }
972*e4b17023SJohn Marino 
973*e4b17023SJohn Marino 
974*e4b17023SJohn Marino /* Confluence function that ignores fake edges.  */
975*e4b17023SJohn Marino 
976*e4b17023SJohn Marino static bool
df_lr_confluence_n(edge e)977*e4b17023SJohn Marino df_lr_confluence_n (edge e)
978*e4b17023SJohn Marino {
979*e4b17023SJohn Marino   bitmap op1 = &df_lr_get_bb_info (e->src->index)->out;
980*e4b17023SJohn Marino   bitmap op2 = &df_lr_get_bb_info (e->dest->index)->in;
981*e4b17023SJohn Marino   bool changed = false;
982*e4b17023SJohn Marino 
983*e4b17023SJohn Marino   /* Call-clobbered registers die across exception and call edges.  */
984*e4b17023SJohn Marino   /* ??? Abnormal call edges ignored for the moment, as this gets
985*e4b17023SJohn Marino      confused by sibling call edges, which crashes reg-stack.  */
986*e4b17023SJohn Marino   if (e->flags & EDGE_EH)
987*e4b17023SJohn Marino     changed = bitmap_ior_and_compl_into (op1, op2, regs_invalidated_by_call_regset);
988*e4b17023SJohn Marino   else
989*e4b17023SJohn Marino     changed = bitmap_ior_into (op1, op2);
990*e4b17023SJohn Marino 
991*e4b17023SJohn Marino   changed |= bitmap_ior_into (op1, &df->hardware_regs_used);
992*e4b17023SJohn Marino   return changed;
993*e4b17023SJohn Marino }
994*e4b17023SJohn Marino 
995*e4b17023SJohn Marino 
996*e4b17023SJohn Marino /* Transfer function.  */
997*e4b17023SJohn Marino 
998*e4b17023SJohn Marino static bool
df_lr_transfer_function(int bb_index)999*e4b17023SJohn Marino df_lr_transfer_function (int bb_index)
1000*e4b17023SJohn Marino {
1001*e4b17023SJohn Marino   struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
1002*e4b17023SJohn Marino   bitmap in = &bb_info->in;
1003*e4b17023SJohn Marino   bitmap out = &bb_info->out;
1004*e4b17023SJohn Marino   bitmap use = &bb_info->use;
1005*e4b17023SJohn Marino   bitmap def = &bb_info->def;
1006*e4b17023SJohn Marino 
1007*e4b17023SJohn Marino   return bitmap_ior_and_compl (in, use, out, def);
1008*e4b17023SJohn Marino }
1009*e4b17023SJohn Marino 
1010*e4b17023SJohn Marino 
1011*e4b17023SJohn Marino /* Run the fast dce as a side effect of building LR.  */
1012*e4b17023SJohn Marino 
1013*e4b17023SJohn Marino static void
df_lr_finalize(bitmap all_blocks)1014*e4b17023SJohn Marino df_lr_finalize (bitmap all_blocks)
1015*e4b17023SJohn Marino {
1016*e4b17023SJohn Marino   df_lr->solutions_dirty = false;
1017*e4b17023SJohn Marino   if (df->changeable_flags & DF_LR_RUN_DCE)
1018*e4b17023SJohn Marino     {
1019*e4b17023SJohn Marino       run_fast_df_dce ();
1020*e4b17023SJohn Marino 
1021*e4b17023SJohn Marino       /* If dce deletes some instructions, we need to recompute the lr
1022*e4b17023SJohn Marino 	 solution before proceeding further.  The problem is that fast
1023*e4b17023SJohn Marino 	 dce is a pessimestic dataflow algorithm.  In the case where
1024*e4b17023SJohn Marino 	 it deletes a statement S inside of a loop, the uses inside of
1025*e4b17023SJohn Marino 	 S may not be deleted from the dataflow solution because they
1026*e4b17023SJohn Marino 	 were carried around the loop.  While it is conservatively
1027*e4b17023SJohn Marino 	 correct to leave these extra bits, the standards of df
1028*e4b17023SJohn Marino 	 require that we maintain the best possible (least fixed
1029*e4b17023SJohn Marino 	 point) solution.  The only way to do that is to redo the
1030*e4b17023SJohn Marino 	 iteration from the beginning.  See PR35805 for an
1031*e4b17023SJohn Marino 	 example.  */
1032*e4b17023SJohn Marino       if (df_lr->solutions_dirty)
1033*e4b17023SJohn Marino 	{
1034*e4b17023SJohn Marino 	  df_clear_flags (DF_LR_RUN_DCE);
1035*e4b17023SJohn Marino 	  df_lr_alloc (all_blocks);
1036*e4b17023SJohn Marino 	  df_lr_local_compute (all_blocks);
1037*e4b17023SJohn Marino 	  df_worklist_dataflow (df_lr, all_blocks, df->postorder, df->n_blocks);
1038*e4b17023SJohn Marino 	  df_lr_finalize (all_blocks);
1039*e4b17023SJohn Marino 	  df_set_flags (DF_LR_RUN_DCE);
1040*e4b17023SJohn Marino 	}
1041*e4b17023SJohn Marino     }
1042*e4b17023SJohn Marino }
1043*e4b17023SJohn Marino 
1044*e4b17023SJohn Marino 
1045*e4b17023SJohn Marino /* Free all storage associated with the problem.  */
1046*e4b17023SJohn Marino 
1047*e4b17023SJohn Marino static void
df_lr_free(void)1048*e4b17023SJohn Marino df_lr_free (void)
1049*e4b17023SJohn Marino {
1050*e4b17023SJohn Marino   struct df_lr_problem_data *problem_data
1051*e4b17023SJohn Marino     = (struct df_lr_problem_data *) df_lr->problem_data;
1052*e4b17023SJohn Marino   if (df_lr->block_info)
1053*e4b17023SJohn Marino     {
1054*e4b17023SJohn Marino 
1055*e4b17023SJohn Marino       df_lr->block_info_size = 0;
1056*e4b17023SJohn Marino       free (df_lr->block_info);
1057*e4b17023SJohn Marino       df_lr->block_info = NULL;
1058*e4b17023SJohn Marino       bitmap_obstack_release (&problem_data->lr_bitmaps);
1059*e4b17023SJohn Marino       free (df_lr->problem_data);
1060*e4b17023SJohn Marino       df_lr->problem_data = NULL;
1061*e4b17023SJohn Marino     }
1062*e4b17023SJohn Marino 
1063*e4b17023SJohn Marino   BITMAP_FREE (df_lr->out_of_date_transfer_functions);
1064*e4b17023SJohn Marino   free (df_lr);
1065*e4b17023SJohn Marino }
1066*e4b17023SJohn Marino 
1067*e4b17023SJohn Marino 
1068*e4b17023SJohn Marino /* Debugging info at top of bb.  */
1069*e4b17023SJohn Marino 
1070*e4b17023SJohn Marino static void
df_lr_top_dump(basic_block bb,FILE * file)1071*e4b17023SJohn Marino df_lr_top_dump (basic_block bb, FILE *file)
1072*e4b17023SJohn Marino {
1073*e4b17023SJohn Marino   struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb->index);
1074*e4b17023SJohn Marino   struct df_lr_problem_data *problem_data;
1075*e4b17023SJohn Marino   if (!bb_info)
1076*e4b17023SJohn Marino     return;
1077*e4b17023SJohn Marino 
1078*e4b17023SJohn Marino   fprintf (file, ";; lr  in  \t");
1079*e4b17023SJohn Marino   df_print_regset (file, &bb_info->in);
1080*e4b17023SJohn Marino   if (df_lr->problem_data)
1081*e4b17023SJohn Marino     {
1082*e4b17023SJohn Marino       problem_data = (struct df_lr_problem_data *)df_lr->problem_data;
1083*e4b17023SJohn Marino       if (problem_data->in)
1084*e4b17023SJohn Marino 	{
1085*e4b17023SJohn Marino       	  fprintf (file, ";;  old in  \t");
1086*e4b17023SJohn Marino       	  df_print_regset (file, &problem_data->in[bb->index]);
1087*e4b17023SJohn Marino 	}
1088*e4b17023SJohn Marino     }
1089*e4b17023SJohn Marino   fprintf (file, ";; lr  use \t");
1090*e4b17023SJohn Marino   df_print_regset (file, &bb_info->use);
1091*e4b17023SJohn Marino   fprintf (file, ";; lr  def \t");
1092*e4b17023SJohn Marino   df_print_regset (file, &bb_info->def);
1093*e4b17023SJohn Marino }
1094*e4b17023SJohn Marino 
1095*e4b17023SJohn Marino 
1096*e4b17023SJohn Marino /* Debugging info at bottom of bb.  */
1097*e4b17023SJohn Marino 
1098*e4b17023SJohn Marino static void
df_lr_bottom_dump(basic_block bb,FILE * file)1099*e4b17023SJohn Marino df_lr_bottom_dump (basic_block bb, FILE *file)
1100*e4b17023SJohn Marino {
1101*e4b17023SJohn Marino   struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb->index);
1102*e4b17023SJohn Marino   struct df_lr_problem_data *problem_data;
1103*e4b17023SJohn Marino   if (!bb_info)
1104*e4b17023SJohn Marino     return;
1105*e4b17023SJohn Marino 
1106*e4b17023SJohn Marino   fprintf (file, ";; lr  out \t");
1107*e4b17023SJohn Marino   df_print_regset (file, &bb_info->out);
1108*e4b17023SJohn Marino   if (df_lr->problem_data)
1109*e4b17023SJohn Marino     {
1110*e4b17023SJohn Marino       problem_data = (struct df_lr_problem_data *)df_lr->problem_data;
1111*e4b17023SJohn Marino       if (problem_data->out)
1112*e4b17023SJohn Marino 	{
1113*e4b17023SJohn Marino           fprintf (file, ";;  old out  \t");
1114*e4b17023SJohn Marino           df_print_regset (file, &problem_data->out[bb->index]);
1115*e4b17023SJohn Marino 	}
1116*e4b17023SJohn Marino     }
1117*e4b17023SJohn Marino }
1118*e4b17023SJohn Marino 
1119*e4b17023SJohn Marino 
1120*e4b17023SJohn Marino /* Build the datastructure to verify that the solution to the dataflow
1121*e4b17023SJohn Marino    equations is not dirty.  */
1122*e4b17023SJohn Marino 
1123*e4b17023SJohn Marino static void
df_lr_verify_solution_start(void)1124*e4b17023SJohn Marino df_lr_verify_solution_start (void)
1125*e4b17023SJohn Marino {
1126*e4b17023SJohn Marino   basic_block bb;
1127*e4b17023SJohn Marino   struct df_lr_problem_data *problem_data;
1128*e4b17023SJohn Marino   if (df_lr->solutions_dirty)
1129*e4b17023SJohn Marino     return;
1130*e4b17023SJohn Marino 
1131*e4b17023SJohn Marino   /* Set it true so that the solution is recomputed.  */
1132*e4b17023SJohn Marino   df_lr->solutions_dirty = true;
1133*e4b17023SJohn Marino 
1134*e4b17023SJohn Marino   problem_data = (struct df_lr_problem_data *)df_lr->problem_data;
1135*e4b17023SJohn Marino   problem_data->in = XNEWVEC (bitmap_head, last_basic_block);
1136*e4b17023SJohn Marino   problem_data->out = XNEWVEC (bitmap_head, last_basic_block);
1137*e4b17023SJohn Marino 
1138*e4b17023SJohn Marino   FOR_ALL_BB (bb)
1139*e4b17023SJohn Marino     {
1140*e4b17023SJohn Marino       bitmap_initialize (&problem_data->in[bb->index], &problem_data->lr_bitmaps);
1141*e4b17023SJohn Marino       bitmap_initialize (&problem_data->out[bb->index], &problem_data->lr_bitmaps);
1142*e4b17023SJohn Marino       bitmap_copy (&problem_data->in[bb->index], DF_LR_IN (bb));
1143*e4b17023SJohn Marino       bitmap_copy (&problem_data->out[bb->index], DF_LR_OUT (bb));
1144*e4b17023SJohn Marino     }
1145*e4b17023SJohn Marino }
1146*e4b17023SJohn Marino 
1147*e4b17023SJohn Marino 
1148*e4b17023SJohn Marino /* Compare the saved datastructure and the new solution to the dataflow
1149*e4b17023SJohn Marino    equations.  */
1150*e4b17023SJohn Marino 
1151*e4b17023SJohn Marino static void
df_lr_verify_solution_end(void)1152*e4b17023SJohn Marino df_lr_verify_solution_end (void)
1153*e4b17023SJohn Marino {
1154*e4b17023SJohn Marino   struct df_lr_problem_data *problem_data;
1155*e4b17023SJohn Marino   basic_block bb;
1156*e4b17023SJohn Marino 
1157*e4b17023SJohn Marino   problem_data = (struct df_lr_problem_data *)df_lr->problem_data;
1158*e4b17023SJohn Marino 
1159*e4b17023SJohn Marino   if (!problem_data->out)
1160*e4b17023SJohn Marino     return;
1161*e4b17023SJohn Marino 
1162*e4b17023SJohn Marino   if (df_lr->solutions_dirty)
1163*e4b17023SJohn Marino     /* Do not check if the solution is still dirty.  See the comment
1164*e4b17023SJohn Marino        in df_lr_finalize for details.  */
1165*e4b17023SJohn Marino     df_lr->solutions_dirty = false;
1166*e4b17023SJohn Marino   else
1167*e4b17023SJohn Marino     FOR_ALL_BB (bb)
1168*e4b17023SJohn Marino       {
1169*e4b17023SJohn Marino 	if ((!bitmap_equal_p (&problem_data->in[bb->index], DF_LR_IN (bb)))
1170*e4b17023SJohn Marino 	    || (!bitmap_equal_p (&problem_data->out[bb->index], DF_LR_OUT (bb))))
1171*e4b17023SJohn Marino 	  {
1172*e4b17023SJohn Marino 	    /*df_dump (stderr);*/
1173*e4b17023SJohn Marino 	    gcc_unreachable ();
1174*e4b17023SJohn Marino 	  }
1175*e4b17023SJohn Marino       }
1176*e4b17023SJohn Marino 
1177*e4b17023SJohn Marino   /* Cannot delete them immediately because you may want to dump them
1178*e4b17023SJohn Marino      if the comparison fails.  */
1179*e4b17023SJohn Marino   FOR_ALL_BB (bb)
1180*e4b17023SJohn Marino     {
1181*e4b17023SJohn Marino       bitmap_clear (&problem_data->in[bb->index]);
1182*e4b17023SJohn Marino       bitmap_clear (&problem_data->out[bb->index]);
1183*e4b17023SJohn Marino     }
1184*e4b17023SJohn Marino 
1185*e4b17023SJohn Marino   free (problem_data->in);
1186*e4b17023SJohn Marino   free (problem_data->out);
1187*e4b17023SJohn Marino   problem_data->in = NULL;
1188*e4b17023SJohn Marino   problem_data->out = NULL;
1189*e4b17023SJohn Marino }
1190*e4b17023SJohn Marino 
1191*e4b17023SJohn Marino 
1192*e4b17023SJohn Marino /* All of the information associated with every instance of the problem.  */
1193*e4b17023SJohn Marino 
1194*e4b17023SJohn Marino static struct df_problem problem_LR =
1195*e4b17023SJohn Marino {
1196*e4b17023SJohn Marino   DF_LR,                      /* Problem id.  */
1197*e4b17023SJohn Marino   DF_BACKWARD,                /* Direction.  */
1198*e4b17023SJohn Marino   df_lr_alloc,                /* Allocate the problem specific data.  */
1199*e4b17023SJohn Marino   df_lr_reset,                /* Reset global information.  */
1200*e4b17023SJohn Marino   df_lr_free_bb_info,         /* Free basic block info.  */
1201*e4b17023SJohn Marino   df_lr_local_compute,        /* Local compute function.  */
1202*e4b17023SJohn Marino   df_lr_init,                 /* Init the solution specific data.  */
1203*e4b17023SJohn Marino   df_worklist_dataflow,       /* Worklist solver.  */
1204*e4b17023SJohn Marino   df_lr_confluence_0,         /* Confluence operator 0.  */
1205*e4b17023SJohn Marino   df_lr_confluence_n,         /* Confluence operator n.  */
1206*e4b17023SJohn Marino   df_lr_transfer_function,    /* Transfer function.  */
1207*e4b17023SJohn Marino   df_lr_finalize,             /* Finalize function.  */
1208*e4b17023SJohn Marino   df_lr_free,                 /* Free all of the problem information.  */
1209*e4b17023SJohn Marino   NULL,                       /* Remove this problem from the stack of dataflow problems.  */
1210*e4b17023SJohn Marino   NULL,                       /* Debugging.  */
1211*e4b17023SJohn Marino   df_lr_top_dump,             /* Debugging start block.  */
1212*e4b17023SJohn Marino   df_lr_bottom_dump,          /* Debugging end block.  */
1213*e4b17023SJohn Marino   df_lr_verify_solution_start,/* Incremental solution verify start.  */
1214*e4b17023SJohn Marino   df_lr_verify_solution_end,  /* Incremental solution verify end.  */
1215*e4b17023SJohn Marino   NULL,                       /* Dependent problem.  */
1216*e4b17023SJohn Marino   sizeof (struct df_lr_bb_info),/* Size of entry of block_info array.  */
1217*e4b17023SJohn Marino   TV_DF_LR,                   /* Timing variable.  */
1218*e4b17023SJohn Marino   false                       /* Reset blocks on dropping out of blocks_to_analyze.  */
1219*e4b17023SJohn Marino };
1220*e4b17023SJohn Marino 
1221*e4b17023SJohn Marino 
1222*e4b17023SJohn Marino /* Create a new DATAFLOW instance and add it to an existing instance
1223*e4b17023SJohn Marino    of DF.  The returned structure is what is used to get at the
1224*e4b17023SJohn Marino    solution.  */
1225*e4b17023SJohn Marino 
1226*e4b17023SJohn Marino void
df_lr_add_problem(void)1227*e4b17023SJohn Marino df_lr_add_problem (void)
1228*e4b17023SJohn Marino {
1229*e4b17023SJohn Marino   df_add_problem (&problem_LR);
1230*e4b17023SJohn Marino   /* These will be initialized when df_scan_blocks processes each
1231*e4b17023SJohn Marino      block.  */
1232*e4b17023SJohn Marino   df_lr->out_of_date_transfer_functions = BITMAP_ALLOC (NULL);
1233*e4b17023SJohn Marino }
1234*e4b17023SJohn Marino 
1235*e4b17023SJohn Marino 
1236*e4b17023SJohn Marino /* Verify that all of the lr related info is consistent and
1237*e4b17023SJohn Marino    correct.  */
1238*e4b17023SJohn Marino 
1239*e4b17023SJohn Marino void
df_lr_verify_transfer_functions(void)1240*e4b17023SJohn Marino df_lr_verify_transfer_functions (void)
1241*e4b17023SJohn Marino {
1242*e4b17023SJohn Marino   basic_block bb;
1243*e4b17023SJohn Marino   bitmap_head saved_def;
1244*e4b17023SJohn Marino   bitmap_head saved_use;
1245*e4b17023SJohn Marino   bitmap_head all_blocks;
1246*e4b17023SJohn Marino 
1247*e4b17023SJohn Marino   if (!df)
1248*e4b17023SJohn Marino     return;
1249*e4b17023SJohn Marino 
1250*e4b17023SJohn Marino   bitmap_initialize (&saved_def, &bitmap_default_obstack);
1251*e4b17023SJohn Marino   bitmap_initialize (&saved_use, &bitmap_default_obstack);
1252*e4b17023SJohn Marino   bitmap_initialize (&all_blocks, &bitmap_default_obstack);
1253*e4b17023SJohn Marino 
1254*e4b17023SJohn Marino   FOR_ALL_BB (bb)
1255*e4b17023SJohn Marino     {
1256*e4b17023SJohn Marino       struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb->index);
1257*e4b17023SJohn Marino       bitmap_set_bit (&all_blocks, bb->index);
1258*e4b17023SJohn Marino 
1259*e4b17023SJohn Marino       if (bb_info)
1260*e4b17023SJohn Marino 	{
1261*e4b17023SJohn Marino 	  /* Make a copy of the transfer functions and then compute
1262*e4b17023SJohn Marino 	     new ones to see if the transfer functions have
1263*e4b17023SJohn Marino 	     changed.  */
1264*e4b17023SJohn Marino 	  if (!bitmap_bit_p (df_lr->out_of_date_transfer_functions,
1265*e4b17023SJohn Marino 			     bb->index))
1266*e4b17023SJohn Marino 	    {
1267*e4b17023SJohn Marino 	      bitmap_copy (&saved_def, &bb_info->def);
1268*e4b17023SJohn Marino 	      bitmap_copy (&saved_use, &bb_info->use);
1269*e4b17023SJohn Marino 	      bitmap_clear (&bb_info->def);
1270*e4b17023SJohn Marino 	      bitmap_clear (&bb_info->use);
1271*e4b17023SJohn Marino 
1272*e4b17023SJohn Marino 	      df_lr_bb_local_compute (bb->index);
1273*e4b17023SJohn Marino 	      gcc_assert (bitmap_equal_p (&saved_def, &bb_info->def));
1274*e4b17023SJohn Marino 	      gcc_assert (bitmap_equal_p (&saved_use, &bb_info->use));
1275*e4b17023SJohn Marino 	    }
1276*e4b17023SJohn Marino 	}
1277*e4b17023SJohn Marino       else
1278*e4b17023SJohn Marino 	{
1279*e4b17023SJohn Marino 	  /* If we do not have basic block info, the block must be in
1280*e4b17023SJohn Marino 	     the list of dirty blocks or else some one has added a
1281*e4b17023SJohn Marino 	     block behind our backs. */
1282*e4b17023SJohn Marino 	  gcc_assert (bitmap_bit_p (df_lr->out_of_date_transfer_functions,
1283*e4b17023SJohn Marino 				    bb->index));
1284*e4b17023SJohn Marino 	}
1285*e4b17023SJohn Marino       /* Make sure no one created a block without following
1286*e4b17023SJohn Marino 	 procedures.  */
1287*e4b17023SJohn Marino       gcc_assert (df_scan_get_bb_info (bb->index));
1288*e4b17023SJohn Marino     }
1289*e4b17023SJohn Marino 
1290*e4b17023SJohn Marino   /* Make sure there are no dirty bits in blocks that have been deleted.  */
1291*e4b17023SJohn Marino   gcc_assert (!bitmap_intersect_compl_p (df_lr->out_of_date_transfer_functions,
1292*e4b17023SJohn Marino 					 &all_blocks));
1293*e4b17023SJohn Marino 
1294*e4b17023SJohn Marino   bitmap_clear (&saved_def);
1295*e4b17023SJohn Marino   bitmap_clear (&saved_use);
1296*e4b17023SJohn Marino   bitmap_clear (&all_blocks);
1297*e4b17023SJohn Marino }
1298*e4b17023SJohn Marino 
1299*e4b17023SJohn Marino 
1300*e4b17023SJohn Marino 
1301*e4b17023SJohn Marino /*----------------------------------------------------------------------------
1302*e4b17023SJohn Marino    LIVE AND MUST-INITIALIZED REGISTERS.
1303*e4b17023SJohn Marino 
1304*e4b17023SJohn Marino    This problem first computes the IN and OUT bitvectors for the
1305*e4b17023SJohn Marino    must-initialized registers problems, which is a forward problem.
1306*e4b17023SJohn Marino    It gives the set of registers for which we MUST have an available
1307*e4b17023SJohn Marino    definition on any path from the entry block to the entry/exit of
1308*e4b17023SJohn Marino    a basic block.  Sets generate a definition, while clobbers kill
1309*e4b17023SJohn Marino    a definition.
1310*e4b17023SJohn Marino 
1311*e4b17023SJohn Marino    In and out bitvectors are built for each basic block and are indexed by
1312*e4b17023SJohn Marino    regnum (see df.h for details).  In and out bitvectors in struct
1313*e4b17023SJohn Marino    df_live_bb_info actually refers to the must-initialized problem;
1314*e4b17023SJohn Marino 
1315*e4b17023SJohn Marino    Then, the in and out sets for the LIVE problem itself are computed.
1316*e4b17023SJohn Marino    These are the logical AND of the IN and OUT sets from the LR problem
1317*e4b17023SJohn Marino    and the must-initialized problem.
1318*e4b17023SJohn Marino ----------------------------------------------------------------------------*/
1319*e4b17023SJohn Marino 
1320*e4b17023SJohn Marino /* Private data used to verify the solution for this problem.  */
1321*e4b17023SJohn Marino struct df_live_problem_data
1322*e4b17023SJohn Marino {
1323*e4b17023SJohn Marino   bitmap_head *in;
1324*e4b17023SJohn Marino   bitmap_head *out;
1325*e4b17023SJohn Marino   /* An obstack for the bitmaps we need for this problem.  */
1326*e4b17023SJohn Marino   bitmap_obstack live_bitmaps;
1327*e4b17023SJohn Marino };
1328*e4b17023SJohn Marino 
1329*e4b17023SJohn Marino /* Scratch var used by transfer functions.  This is used to implement
1330*e4b17023SJohn Marino    an optimization to reduce the amount of space used to compute the
1331*e4b17023SJohn Marino    combined lr and live analysis.  */
1332*e4b17023SJohn Marino static bitmap_head df_live_scratch;
1333*e4b17023SJohn Marino 
1334*e4b17023SJohn Marino 
1335*e4b17023SJohn Marino /* Free basic block info.  */
1336*e4b17023SJohn Marino 
1337*e4b17023SJohn Marino static void
df_live_free_bb_info(basic_block bb ATTRIBUTE_UNUSED,void * vbb_info)1338*e4b17023SJohn Marino df_live_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
1339*e4b17023SJohn Marino 		    void *vbb_info)
1340*e4b17023SJohn Marino {
1341*e4b17023SJohn Marino   struct df_live_bb_info *bb_info = (struct df_live_bb_info *) vbb_info;
1342*e4b17023SJohn Marino   if (bb_info)
1343*e4b17023SJohn Marino     {
1344*e4b17023SJohn Marino       bitmap_clear (&bb_info->gen);
1345*e4b17023SJohn Marino       bitmap_clear (&bb_info->kill);
1346*e4b17023SJohn Marino       bitmap_clear (&bb_info->in);
1347*e4b17023SJohn Marino       bitmap_clear (&bb_info->out);
1348*e4b17023SJohn Marino     }
1349*e4b17023SJohn Marino }
1350*e4b17023SJohn Marino 
1351*e4b17023SJohn Marino 
1352*e4b17023SJohn Marino /* Allocate or reset bitmaps for DF_LIVE blocks. The solution bits are
1353*e4b17023SJohn Marino    not touched unless the block is new.  */
1354*e4b17023SJohn Marino 
1355*e4b17023SJohn Marino static void
df_live_alloc(bitmap all_blocks ATTRIBUTE_UNUSED)1356*e4b17023SJohn Marino df_live_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
1357*e4b17023SJohn Marino {
1358*e4b17023SJohn Marino   unsigned int bb_index;
1359*e4b17023SJohn Marino   bitmap_iterator bi;
1360*e4b17023SJohn Marino   struct df_live_problem_data *problem_data;
1361*e4b17023SJohn Marino 
1362*e4b17023SJohn Marino   if (df_live->problem_data)
1363*e4b17023SJohn Marino     problem_data = (struct df_live_problem_data *) df_live->problem_data;
1364*e4b17023SJohn Marino   else
1365*e4b17023SJohn Marino     {
1366*e4b17023SJohn Marino       problem_data = XNEW (struct df_live_problem_data);
1367*e4b17023SJohn Marino       df_live->problem_data = problem_data;
1368*e4b17023SJohn Marino 
1369*e4b17023SJohn Marino       problem_data->out = NULL;
1370*e4b17023SJohn Marino       problem_data->in = NULL;
1371*e4b17023SJohn Marino       bitmap_obstack_initialize (&problem_data->live_bitmaps);
1372*e4b17023SJohn Marino       bitmap_initialize (&df_live_scratch, &problem_data->live_bitmaps);
1373*e4b17023SJohn Marino     }
1374*e4b17023SJohn Marino 
1375*e4b17023SJohn Marino   df_grow_bb_info (df_live);
1376*e4b17023SJohn Marino 
1377*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (df_live->out_of_date_transfer_functions, 0, bb_index, bi)
1378*e4b17023SJohn Marino     {
1379*e4b17023SJohn Marino       struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
1380*e4b17023SJohn Marino 
1381*e4b17023SJohn Marino       /* When bitmaps are already initialized, just clear them.  */
1382*e4b17023SJohn Marino       if (bb_info->kill.obstack)
1383*e4b17023SJohn Marino 	{
1384*e4b17023SJohn Marino 	  bitmap_clear (&bb_info->kill);
1385*e4b17023SJohn Marino 	  bitmap_clear (&bb_info->gen);
1386*e4b17023SJohn Marino 	}
1387*e4b17023SJohn Marino       else
1388*e4b17023SJohn Marino 	{
1389*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->kill, &problem_data->live_bitmaps);
1390*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->gen, &problem_data->live_bitmaps);
1391*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->in, &problem_data->live_bitmaps);
1392*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->out, &problem_data->live_bitmaps);
1393*e4b17023SJohn Marino 	}
1394*e4b17023SJohn Marino     }
1395*e4b17023SJohn Marino   df_live->optional_p = (optimize <= 1);
1396*e4b17023SJohn Marino }
1397*e4b17023SJohn Marino 
1398*e4b17023SJohn Marino 
1399*e4b17023SJohn Marino /* Reset the global solution for recalculation.  */
1400*e4b17023SJohn Marino 
1401*e4b17023SJohn Marino static void
df_live_reset(bitmap all_blocks)1402*e4b17023SJohn Marino df_live_reset (bitmap all_blocks)
1403*e4b17023SJohn Marino {
1404*e4b17023SJohn Marino   unsigned int bb_index;
1405*e4b17023SJohn Marino   bitmap_iterator bi;
1406*e4b17023SJohn Marino 
1407*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
1408*e4b17023SJohn Marino     {
1409*e4b17023SJohn Marino       struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
1410*e4b17023SJohn Marino       gcc_assert (bb_info);
1411*e4b17023SJohn Marino       bitmap_clear (&bb_info->in);
1412*e4b17023SJohn Marino       bitmap_clear (&bb_info->out);
1413*e4b17023SJohn Marino     }
1414*e4b17023SJohn Marino }
1415*e4b17023SJohn Marino 
1416*e4b17023SJohn Marino 
1417*e4b17023SJohn Marino /* Compute local uninitialized register info for basic block BB.  */
1418*e4b17023SJohn Marino 
1419*e4b17023SJohn Marino static void
df_live_bb_local_compute(unsigned int bb_index)1420*e4b17023SJohn Marino df_live_bb_local_compute (unsigned int bb_index)
1421*e4b17023SJohn Marino {
1422*e4b17023SJohn Marino   basic_block bb = BASIC_BLOCK (bb_index);
1423*e4b17023SJohn Marino   struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
1424*e4b17023SJohn Marino   rtx insn;
1425*e4b17023SJohn Marino   df_ref *def_rec;
1426*e4b17023SJohn Marino   int luid = 0;
1427*e4b17023SJohn Marino 
1428*e4b17023SJohn Marino   FOR_BB_INSNS (bb, insn)
1429*e4b17023SJohn Marino     {
1430*e4b17023SJohn Marino       unsigned int uid = INSN_UID (insn);
1431*e4b17023SJohn Marino       struct df_insn_info *insn_info = DF_INSN_UID_GET (uid);
1432*e4b17023SJohn Marino 
1433*e4b17023SJohn Marino       /* Inserting labels does not always trigger the incremental
1434*e4b17023SJohn Marino 	 rescanning.  */
1435*e4b17023SJohn Marino       if (!insn_info)
1436*e4b17023SJohn Marino 	{
1437*e4b17023SJohn Marino 	  gcc_assert (!INSN_P (insn));
1438*e4b17023SJohn Marino 	  insn_info = df_insn_create_insn_record (insn);
1439*e4b17023SJohn Marino 	}
1440*e4b17023SJohn Marino 
1441*e4b17023SJohn Marino       DF_INSN_INFO_LUID (insn_info) = luid;
1442*e4b17023SJohn Marino       if (!INSN_P (insn))
1443*e4b17023SJohn Marino 	continue;
1444*e4b17023SJohn Marino 
1445*e4b17023SJohn Marino       luid++;
1446*e4b17023SJohn Marino       for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++)
1447*e4b17023SJohn Marino 	{
1448*e4b17023SJohn Marino 	  df_ref def = *def_rec;
1449*e4b17023SJohn Marino 	  unsigned int regno = DF_REF_REGNO (def);
1450*e4b17023SJohn Marino 
1451*e4b17023SJohn Marino 	  if (DF_REF_FLAGS_IS_SET (def,
1452*e4b17023SJohn Marino 				   DF_REF_PARTIAL | DF_REF_CONDITIONAL))
1453*e4b17023SJohn Marino 	    /* All partial or conditional def
1454*e4b17023SJohn Marino 	       seen are included in the gen set. */
1455*e4b17023SJohn Marino 	    bitmap_set_bit (&bb_info->gen, regno);
1456*e4b17023SJohn Marino 	  else if (DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER))
1457*e4b17023SJohn Marino 	    /* Only must clobbers for the entire reg destroy the
1458*e4b17023SJohn Marino 	       value.  */
1459*e4b17023SJohn Marino 	    bitmap_set_bit (&bb_info->kill, regno);
1460*e4b17023SJohn Marino 	  else if (! DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER))
1461*e4b17023SJohn Marino 	    bitmap_set_bit (&bb_info->gen, regno);
1462*e4b17023SJohn Marino 	}
1463*e4b17023SJohn Marino     }
1464*e4b17023SJohn Marino 
1465*e4b17023SJohn Marino   for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
1466*e4b17023SJohn Marino     {
1467*e4b17023SJohn Marino       df_ref def = *def_rec;
1468*e4b17023SJohn Marino       bitmap_set_bit (&bb_info->gen, DF_REF_REGNO (def));
1469*e4b17023SJohn Marino     }
1470*e4b17023SJohn Marino }
1471*e4b17023SJohn Marino 
1472*e4b17023SJohn Marino 
1473*e4b17023SJohn Marino /* Compute local uninitialized register info.  */
1474*e4b17023SJohn Marino 
1475*e4b17023SJohn Marino static void
df_live_local_compute(bitmap all_blocks ATTRIBUTE_UNUSED)1476*e4b17023SJohn Marino df_live_local_compute (bitmap all_blocks ATTRIBUTE_UNUSED)
1477*e4b17023SJohn Marino {
1478*e4b17023SJohn Marino   unsigned int bb_index;
1479*e4b17023SJohn Marino   bitmap_iterator bi;
1480*e4b17023SJohn Marino 
1481*e4b17023SJohn Marino   df_grow_insn_info ();
1482*e4b17023SJohn Marino 
1483*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (df_live->out_of_date_transfer_functions,
1484*e4b17023SJohn Marino 			    0, bb_index, bi)
1485*e4b17023SJohn Marino     {
1486*e4b17023SJohn Marino       df_live_bb_local_compute (bb_index);
1487*e4b17023SJohn Marino     }
1488*e4b17023SJohn Marino 
1489*e4b17023SJohn Marino   bitmap_clear (df_live->out_of_date_transfer_functions);
1490*e4b17023SJohn Marino }
1491*e4b17023SJohn Marino 
1492*e4b17023SJohn Marino 
1493*e4b17023SJohn Marino /* Initialize the solution vectors.  */
1494*e4b17023SJohn Marino 
1495*e4b17023SJohn Marino static void
df_live_init(bitmap all_blocks)1496*e4b17023SJohn Marino df_live_init (bitmap all_blocks)
1497*e4b17023SJohn Marino {
1498*e4b17023SJohn Marino   unsigned int bb_index;
1499*e4b17023SJohn Marino   bitmap_iterator bi;
1500*e4b17023SJohn Marino 
1501*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
1502*e4b17023SJohn Marino     {
1503*e4b17023SJohn Marino       struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
1504*e4b17023SJohn Marino       struct df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
1505*e4b17023SJohn Marino 
1506*e4b17023SJohn Marino       /* No register may reach a location where it is not used.  Thus
1507*e4b17023SJohn Marino 	 we trim the rr result to the places where it is used.  */
1508*e4b17023SJohn Marino       bitmap_and (&bb_info->out, &bb_info->gen, &bb_lr_info->out);
1509*e4b17023SJohn Marino       bitmap_clear (&bb_info->in);
1510*e4b17023SJohn Marino     }
1511*e4b17023SJohn Marino }
1512*e4b17023SJohn Marino 
1513*e4b17023SJohn Marino /* Forward confluence function that ignores fake edges.  */
1514*e4b17023SJohn Marino 
1515*e4b17023SJohn Marino static bool
df_live_confluence_n(edge e)1516*e4b17023SJohn Marino df_live_confluence_n (edge e)
1517*e4b17023SJohn Marino {
1518*e4b17023SJohn Marino   bitmap op1 = &df_live_get_bb_info (e->dest->index)->in;
1519*e4b17023SJohn Marino   bitmap op2 = &df_live_get_bb_info (e->src->index)->out;
1520*e4b17023SJohn Marino 
1521*e4b17023SJohn Marino   if (e->flags & EDGE_FAKE)
1522*e4b17023SJohn Marino     return false;
1523*e4b17023SJohn Marino 
1524*e4b17023SJohn Marino   return bitmap_ior_into (op1, op2);
1525*e4b17023SJohn Marino }
1526*e4b17023SJohn Marino 
1527*e4b17023SJohn Marino 
1528*e4b17023SJohn Marino /* Transfer function for the forwards must-initialized problem.  */
1529*e4b17023SJohn Marino 
1530*e4b17023SJohn Marino static bool
df_live_transfer_function(int bb_index)1531*e4b17023SJohn Marino df_live_transfer_function (int bb_index)
1532*e4b17023SJohn Marino {
1533*e4b17023SJohn Marino   struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
1534*e4b17023SJohn Marino   struct df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
1535*e4b17023SJohn Marino   bitmap in = &bb_info->in;
1536*e4b17023SJohn Marino   bitmap out = &bb_info->out;
1537*e4b17023SJohn Marino   bitmap gen = &bb_info->gen;
1538*e4b17023SJohn Marino   bitmap kill = &bb_info->kill;
1539*e4b17023SJohn Marino 
1540*e4b17023SJohn Marino   /* We need to use a scratch set here so that the value returned from this
1541*e4b17023SJohn Marino      function invocation properly reflects whether the sets changed in a
1542*e4b17023SJohn Marino      significant way; i.e. not just because the lr set was anded in.  */
1543*e4b17023SJohn Marino   bitmap_and (&df_live_scratch, gen, &bb_lr_info->out);
1544*e4b17023SJohn Marino   /* No register may reach a location where it is not used.  Thus
1545*e4b17023SJohn Marino      we trim the rr result to the places where it is used.  */
1546*e4b17023SJohn Marino   bitmap_and_into (in, &bb_lr_info->in);
1547*e4b17023SJohn Marino 
1548*e4b17023SJohn Marino   return bitmap_ior_and_compl (out, &df_live_scratch, in, kill);
1549*e4b17023SJohn Marino }
1550*e4b17023SJohn Marino 
1551*e4b17023SJohn Marino 
1552*e4b17023SJohn Marino /* And the LR info with the must-initialized registers, to produce the LIVE info.  */
1553*e4b17023SJohn Marino 
1554*e4b17023SJohn Marino static void
df_live_finalize(bitmap all_blocks)1555*e4b17023SJohn Marino df_live_finalize (bitmap all_blocks)
1556*e4b17023SJohn Marino {
1557*e4b17023SJohn Marino 
1558*e4b17023SJohn Marino   if (df_live->solutions_dirty)
1559*e4b17023SJohn Marino     {
1560*e4b17023SJohn Marino       bitmap_iterator bi;
1561*e4b17023SJohn Marino       unsigned int bb_index;
1562*e4b17023SJohn Marino 
1563*e4b17023SJohn Marino       EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
1564*e4b17023SJohn Marino 	{
1565*e4b17023SJohn Marino 	  struct df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
1566*e4b17023SJohn Marino 	  struct df_live_bb_info *bb_live_info = df_live_get_bb_info (bb_index);
1567*e4b17023SJohn Marino 
1568*e4b17023SJohn Marino 	  /* No register may reach a location where it is not used.  Thus
1569*e4b17023SJohn Marino 	     we trim the rr result to the places where it is used.  */
1570*e4b17023SJohn Marino 	  bitmap_and_into (&bb_live_info->in, &bb_lr_info->in);
1571*e4b17023SJohn Marino 	  bitmap_and_into (&bb_live_info->out, &bb_lr_info->out);
1572*e4b17023SJohn Marino 	}
1573*e4b17023SJohn Marino 
1574*e4b17023SJohn Marino       df_live->solutions_dirty = false;
1575*e4b17023SJohn Marino     }
1576*e4b17023SJohn Marino }
1577*e4b17023SJohn Marino 
1578*e4b17023SJohn Marino 
1579*e4b17023SJohn Marino /* Free all storage associated with the problem.  */
1580*e4b17023SJohn Marino 
1581*e4b17023SJohn Marino static void
df_live_free(void)1582*e4b17023SJohn Marino df_live_free (void)
1583*e4b17023SJohn Marino {
1584*e4b17023SJohn Marino   struct df_live_problem_data *problem_data
1585*e4b17023SJohn Marino     = (struct df_live_problem_data *) df_live->problem_data;
1586*e4b17023SJohn Marino   if (df_live->block_info)
1587*e4b17023SJohn Marino     {
1588*e4b17023SJohn Marino       df_live->block_info_size = 0;
1589*e4b17023SJohn Marino       free (df_live->block_info);
1590*e4b17023SJohn Marino       df_live->block_info = NULL;
1591*e4b17023SJohn Marino       bitmap_clear (&df_live_scratch);
1592*e4b17023SJohn Marino       bitmap_obstack_release (&problem_data->live_bitmaps);
1593*e4b17023SJohn Marino       free (problem_data);
1594*e4b17023SJohn Marino       df_live->problem_data = NULL;
1595*e4b17023SJohn Marino     }
1596*e4b17023SJohn Marino   BITMAP_FREE (df_live->out_of_date_transfer_functions);
1597*e4b17023SJohn Marino   free (df_live);
1598*e4b17023SJohn Marino }
1599*e4b17023SJohn Marino 
1600*e4b17023SJohn Marino 
1601*e4b17023SJohn Marino /* Debugging info at top of bb.  */
1602*e4b17023SJohn Marino 
1603*e4b17023SJohn Marino static void
df_live_top_dump(basic_block bb,FILE * file)1604*e4b17023SJohn Marino df_live_top_dump (basic_block bb, FILE *file)
1605*e4b17023SJohn Marino {
1606*e4b17023SJohn Marino   struct df_live_bb_info *bb_info = df_live_get_bb_info (bb->index);
1607*e4b17023SJohn Marino   struct df_live_problem_data *problem_data;
1608*e4b17023SJohn Marino 
1609*e4b17023SJohn Marino   if (!bb_info)
1610*e4b17023SJohn Marino     return;
1611*e4b17023SJohn Marino 
1612*e4b17023SJohn Marino   fprintf (file, ";; live  in  \t");
1613*e4b17023SJohn Marino   df_print_regset (file, &bb_info->in);
1614*e4b17023SJohn Marino   if (df_live->problem_data)
1615*e4b17023SJohn Marino     {
1616*e4b17023SJohn Marino       problem_data = (struct df_live_problem_data *)df_live->problem_data;
1617*e4b17023SJohn Marino       if (problem_data->in)
1618*e4b17023SJohn Marino 	{
1619*e4b17023SJohn Marino 	  fprintf (file, ";;  old in  \t");
1620*e4b17023SJohn Marino 	  df_print_regset (file, &problem_data->in[bb->index]);
1621*e4b17023SJohn Marino 	}
1622*e4b17023SJohn Marino     }
1623*e4b17023SJohn Marino   fprintf (file, ";; live  gen \t");
1624*e4b17023SJohn Marino   df_print_regset (file, &bb_info->gen);
1625*e4b17023SJohn Marino   fprintf (file, ";; live  kill\t");
1626*e4b17023SJohn Marino   df_print_regset (file, &bb_info->kill);
1627*e4b17023SJohn Marino }
1628*e4b17023SJohn Marino 
1629*e4b17023SJohn Marino 
1630*e4b17023SJohn Marino /* Debugging info at bottom of bb.  */
1631*e4b17023SJohn Marino 
1632*e4b17023SJohn Marino static void
df_live_bottom_dump(basic_block bb,FILE * file)1633*e4b17023SJohn Marino df_live_bottom_dump (basic_block bb, FILE *file)
1634*e4b17023SJohn Marino {
1635*e4b17023SJohn Marino   struct df_live_bb_info *bb_info = df_live_get_bb_info (bb->index);
1636*e4b17023SJohn Marino   struct df_live_problem_data *problem_data;
1637*e4b17023SJohn Marino 
1638*e4b17023SJohn Marino   if (!bb_info)
1639*e4b17023SJohn Marino     return;
1640*e4b17023SJohn Marino 
1641*e4b17023SJohn Marino   fprintf (file, ";; live  out \t");
1642*e4b17023SJohn Marino   df_print_regset (file, &bb_info->out);
1643*e4b17023SJohn Marino   if (df_live->problem_data)
1644*e4b17023SJohn Marino     {
1645*e4b17023SJohn Marino       problem_data = (struct df_live_problem_data *)df_live->problem_data;
1646*e4b17023SJohn Marino       if (problem_data->out)
1647*e4b17023SJohn Marino 	{
1648*e4b17023SJohn Marino 	  fprintf (file, ";;  old out  \t");
1649*e4b17023SJohn Marino 	  df_print_regset (file, &problem_data->out[bb->index]);
1650*e4b17023SJohn Marino 	}
1651*e4b17023SJohn Marino     }
1652*e4b17023SJohn Marino }
1653*e4b17023SJohn Marino 
1654*e4b17023SJohn Marino 
1655*e4b17023SJohn Marino /* Build the datastructure to verify that the solution to the dataflow
1656*e4b17023SJohn Marino    equations is not dirty.  */
1657*e4b17023SJohn Marino 
1658*e4b17023SJohn Marino static void
df_live_verify_solution_start(void)1659*e4b17023SJohn Marino df_live_verify_solution_start (void)
1660*e4b17023SJohn Marino {
1661*e4b17023SJohn Marino   basic_block bb;
1662*e4b17023SJohn Marino   struct df_live_problem_data *problem_data;
1663*e4b17023SJohn Marino   if (df_live->solutions_dirty)
1664*e4b17023SJohn Marino     return;
1665*e4b17023SJohn Marino 
1666*e4b17023SJohn Marino   /* Set it true so that the solution is recomputed.  */
1667*e4b17023SJohn Marino   df_live->solutions_dirty = true;
1668*e4b17023SJohn Marino 
1669*e4b17023SJohn Marino   problem_data = (struct df_live_problem_data *)df_live->problem_data;
1670*e4b17023SJohn Marino   problem_data->in = XNEWVEC (bitmap_head, last_basic_block);
1671*e4b17023SJohn Marino   problem_data->out = XNEWVEC (bitmap_head, last_basic_block);
1672*e4b17023SJohn Marino 
1673*e4b17023SJohn Marino   FOR_ALL_BB (bb)
1674*e4b17023SJohn Marino     {
1675*e4b17023SJohn Marino       bitmap_initialize (&problem_data->in[bb->index], &problem_data->live_bitmaps);
1676*e4b17023SJohn Marino       bitmap_initialize (&problem_data->out[bb->index], &problem_data->live_bitmaps);
1677*e4b17023SJohn Marino       bitmap_copy (&problem_data->in[bb->index], DF_LIVE_IN (bb));
1678*e4b17023SJohn Marino       bitmap_copy (&problem_data->out[bb->index], DF_LIVE_OUT (bb));
1679*e4b17023SJohn Marino     }
1680*e4b17023SJohn Marino }
1681*e4b17023SJohn Marino 
1682*e4b17023SJohn Marino 
1683*e4b17023SJohn Marino /* Compare the saved datastructure and the new solution to the dataflow
1684*e4b17023SJohn Marino    equations.  */
1685*e4b17023SJohn Marino 
1686*e4b17023SJohn Marino static void
df_live_verify_solution_end(void)1687*e4b17023SJohn Marino df_live_verify_solution_end (void)
1688*e4b17023SJohn Marino {
1689*e4b17023SJohn Marino   struct df_live_problem_data *problem_data;
1690*e4b17023SJohn Marino   basic_block bb;
1691*e4b17023SJohn Marino 
1692*e4b17023SJohn Marino   problem_data = (struct df_live_problem_data *)df_live->problem_data;
1693*e4b17023SJohn Marino   if (!problem_data->out)
1694*e4b17023SJohn Marino     return;
1695*e4b17023SJohn Marino 
1696*e4b17023SJohn Marino   FOR_ALL_BB (bb)
1697*e4b17023SJohn Marino     {
1698*e4b17023SJohn Marino       if ((!bitmap_equal_p (&problem_data->in[bb->index], DF_LIVE_IN (bb)))
1699*e4b17023SJohn Marino 	  || (!bitmap_equal_p (&problem_data->out[bb->index], DF_LIVE_OUT (bb))))
1700*e4b17023SJohn Marino 	{
1701*e4b17023SJohn Marino 	  /*df_dump (stderr);*/
1702*e4b17023SJohn Marino 	  gcc_unreachable ();
1703*e4b17023SJohn Marino 	}
1704*e4b17023SJohn Marino     }
1705*e4b17023SJohn Marino 
1706*e4b17023SJohn Marino   /* Cannot delete them immediately because you may want to dump them
1707*e4b17023SJohn Marino      if the comparison fails.  */
1708*e4b17023SJohn Marino   FOR_ALL_BB (bb)
1709*e4b17023SJohn Marino     {
1710*e4b17023SJohn Marino       bitmap_clear (&problem_data->in[bb->index]);
1711*e4b17023SJohn Marino       bitmap_clear (&problem_data->out[bb->index]);
1712*e4b17023SJohn Marino     }
1713*e4b17023SJohn Marino 
1714*e4b17023SJohn Marino   free (problem_data->in);
1715*e4b17023SJohn Marino   free (problem_data->out);
1716*e4b17023SJohn Marino   free (problem_data);
1717*e4b17023SJohn Marino   df_live->problem_data = NULL;
1718*e4b17023SJohn Marino }
1719*e4b17023SJohn Marino 
1720*e4b17023SJohn Marino 
1721*e4b17023SJohn Marino /* All of the information associated with every instance of the problem.  */
1722*e4b17023SJohn Marino 
1723*e4b17023SJohn Marino static struct df_problem problem_LIVE =
1724*e4b17023SJohn Marino {
1725*e4b17023SJohn Marino   DF_LIVE,                      /* Problem id.  */
1726*e4b17023SJohn Marino   DF_FORWARD,                   /* Direction.  */
1727*e4b17023SJohn Marino   df_live_alloc,                /* Allocate the problem specific data.  */
1728*e4b17023SJohn Marino   df_live_reset,                /* Reset global information.  */
1729*e4b17023SJohn Marino   df_live_free_bb_info,         /* Free basic block info.  */
1730*e4b17023SJohn Marino   df_live_local_compute,        /* Local compute function.  */
1731*e4b17023SJohn Marino   df_live_init,                 /* Init the solution specific data.  */
1732*e4b17023SJohn Marino   df_worklist_dataflow,         /* Worklist solver.  */
1733*e4b17023SJohn Marino   NULL,                         /* Confluence operator 0.  */
1734*e4b17023SJohn Marino   df_live_confluence_n,         /* Confluence operator n.  */
1735*e4b17023SJohn Marino   df_live_transfer_function,    /* Transfer function.  */
1736*e4b17023SJohn Marino   df_live_finalize,             /* Finalize function.  */
1737*e4b17023SJohn Marino   df_live_free,                 /* Free all of the problem information.  */
1738*e4b17023SJohn Marino   df_live_free,                 /* Remove this problem from the stack of dataflow problems.  */
1739*e4b17023SJohn Marino   NULL,                         /* Debugging.  */
1740*e4b17023SJohn Marino   df_live_top_dump,             /* Debugging start block.  */
1741*e4b17023SJohn Marino   df_live_bottom_dump,          /* Debugging end block.  */
1742*e4b17023SJohn Marino   df_live_verify_solution_start,/* Incremental solution verify start.  */
1743*e4b17023SJohn Marino   df_live_verify_solution_end,  /* Incremental solution verify end.  */
1744*e4b17023SJohn Marino   &problem_LR,                  /* Dependent problem.  */
1745*e4b17023SJohn Marino   sizeof (struct df_live_bb_info),/* Size of entry of block_info array.  */
1746*e4b17023SJohn Marino   TV_DF_LIVE,                   /* Timing variable.  */
1747*e4b17023SJohn Marino   false                         /* Reset blocks on dropping out of blocks_to_analyze.  */
1748*e4b17023SJohn Marino };
1749*e4b17023SJohn Marino 
1750*e4b17023SJohn Marino 
1751*e4b17023SJohn Marino /* Create a new DATAFLOW instance and add it to an existing instance
1752*e4b17023SJohn Marino    of DF.  The returned structure is what is used to get at the
1753*e4b17023SJohn Marino    solution.  */
1754*e4b17023SJohn Marino 
1755*e4b17023SJohn Marino void
df_live_add_problem(void)1756*e4b17023SJohn Marino df_live_add_problem (void)
1757*e4b17023SJohn Marino {
1758*e4b17023SJohn Marino   df_add_problem (&problem_LIVE);
1759*e4b17023SJohn Marino   /* These will be initialized when df_scan_blocks processes each
1760*e4b17023SJohn Marino      block.  */
1761*e4b17023SJohn Marino   df_live->out_of_date_transfer_functions = BITMAP_ALLOC (NULL);
1762*e4b17023SJohn Marino }
1763*e4b17023SJohn Marino 
1764*e4b17023SJohn Marino 
1765*e4b17023SJohn Marino /* Set all of the blocks as dirty.  This needs to be done if this
1766*e4b17023SJohn Marino    problem is added after all of the insns have been scanned.  */
1767*e4b17023SJohn Marino 
1768*e4b17023SJohn Marino void
df_live_set_all_dirty(void)1769*e4b17023SJohn Marino df_live_set_all_dirty (void)
1770*e4b17023SJohn Marino {
1771*e4b17023SJohn Marino   basic_block bb;
1772*e4b17023SJohn Marino   FOR_ALL_BB (bb)
1773*e4b17023SJohn Marino     bitmap_set_bit (df_live->out_of_date_transfer_functions,
1774*e4b17023SJohn Marino 		    bb->index);
1775*e4b17023SJohn Marino }
1776*e4b17023SJohn Marino 
1777*e4b17023SJohn Marino 
1778*e4b17023SJohn Marino /* Verify that all of the lr related info is consistent and
1779*e4b17023SJohn Marino    correct.  */
1780*e4b17023SJohn Marino 
1781*e4b17023SJohn Marino void
df_live_verify_transfer_functions(void)1782*e4b17023SJohn Marino df_live_verify_transfer_functions (void)
1783*e4b17023SJohn Marino {
1784*e4b17023SJohn Marino   basic_block bb;
1785*e4b17023SJohn Marino   bitmap_head saved_gen;
1786*e4b17023SJohn Marino   bitmap_head saved_kill;
1787*e4b17023SJohn Marino   bitmap_head all_blocks;
1788*e4b17023SJohn Marino 
1789*e4b17023SJohn Marino   if (!df)
1790*e4b17023SJohn Marino     return;
1791*e4b17023SJohn Marino 
1792*e4b17023SJohn Marino   bitmap_initialize (&saved_gen, &bitmap_default_obstack);
1793*e4b17023SJohn Marino   bitmap_initialize (&saved_kill, &bitmap_default_obstack);
1794*e4b17023SJohn Marino   bitmap_initialize (&all_blocks, &bitmap_default_obstack);
1795*e4b17023SJohn Marino 
1796*e4b17023SJohn Marino   df_grow_insn_info ();
1797*e4b17023SJohn Marino 
1798*e4b17023SJohn Marino   FOR_ALL_BB (bb)
1799*e4b17023SJohn Marino     {
1800*e4b17023SJohn Marino       struct df_live_bb_info *bb_info = df_live_get_bb_info (bb->index);
1801*e4b17023SJohn Marino       bitmap_set_bit (&all_blocks, bb->index);
1802*e4b17023SJohn Marino 
1803*e4b17023SJohn Marino       if (bb_info)
1804*e4b17023SJohn Marino 	{
1805*e4b17023SJohn Marino 	  /* Make a copy of the transfer functions and then compute
1806*e4b17023SJohn Marino 	     new ones to see if the transfer functions have
1807*e4b17023SJohn Marino 	     changed.  */
1808*e4b17023SJohn Marino 	  if (!bitmap_bit_p (df_live->out_of_date_transfer_functions,
1809*e4b17023SJohn Marino 			     bb->index))
1810*e4b17023SJohn Marino 	    {
1811*e4b17023SJohn Marino 	      bitmap_copy (&saved_gen, &bb_info->gen);
1812*e4b17023SJohn Marino 	      bitmap_copy (&saved_kill, &bb_info->kill);
1813*e4b17023SJohn Marino 	      bitmap_clear (&bb_info->gen);
1814*e4b17023SJohn Marino 	      bitmap_clear (&bb_info->kill);
1815*e4b17023SJohn Marino 
1816*e4b17023SJohn Marino 	      df_live_bb_local_compute (bb->index);
1817*e4b17023SJohn Marino 	      gcc_assert (bitmap_equal_p (&saved_gen, &bb_info->gen));
1818*e4b17023SJohn Marino 	      gcc_assert (bitmap_equal_p (&saved_kill, &bb_info->kill));
1819*e4b17023SJohn Marino 	    }
1820*e4b17023SJohn Marino 	}
1821*e4b17023SJohn Marino       else
1822*e4b17023SJohn Marino 	{
1823*e4b17023SJohn Marino 	  /* If we do not have basic block info, the block must be in
1824*e4b17023SJohn Marino 	     the list of dirty blocks or else some one has added a
1825*e4b17023SJohn Marino 	     block behind our backs. */
1826*e4b17023SJohn Marino 	  gcc_assert (bitmap_bit_p (df_live->out_of_date_transfer_functions,
1827*e4b17023SJohn Marino 				    bb->index));
1828*e4b17023SJohn Marino 	}
1829*e4b17023SJohn Marino       /* Make sure no one created a block without following
1830*e4b17023SJohn Marino 	 procedures.  */
1831*e4b17023SJohn Marino       gcc_assert (df_scan_get_bb_info (bb->index));
1832*e4b17023SJohn Marino     }
1833*e4b17023SJohn Marino 
1834*e4b17023SJohn Marino   /* Make sure there are no dirty bits in blocks that have been deleted.  */
1835*e4b17023SJohn Marino   gcc_assert (!bitmap_intersect_compl_p (df_live->out_of_date_transfer_functions,
1836*e4b17023SJohn Marino 					 &all_blocks));
1837*e4b17023SJohn Marino   bitmap_clear (&saved_gen);
1838*e4b17023SJohn Marino   bitmap_clear (&saved_kill);
1839*e4b17023SJohn Marino   bitmap_clear (&all_blocks);
1840*e4b17023SJohn Marino }
1841*e4b17023SJohn Marino 
1842*e4b17023SJohn Marino /*----------------------------------------------------------------------------
1843*e4b17023SJohn Marino    CREATE DEF_USE (DU) and / or USE_DEF (UD) CHAINS
1844*e4b17023SJohn Marino 
1845*e4b17023SJohn Marino    Link either the defs to the uses and / or the uses to the defs.
1846*e4b17023SJohn Marino 
1847*e4b17023SJohn Marino    These problems are set up like the other dataflow problems so that
1848*e4b17023SJohn Marino    they nicely fit into the framework.  They are much simpler and only
1849*e4b17023SJohn Marino    involve a single traversal of instructions and an examination of
1850*e4b17023SJohn Marino    the reaching defs information (the dependent problem).
1851*e4b17023SJohn Marino ----------------------------------------------------------------------------*/
1852*e4b17023SJohn Marino 
1853*e4b17023SJohn Marino #define df_chain_problem_p(FLAG) (((enum df_chain_flags)df_chain->local_flags)&(FLAG))
1854*e4b17023SJohn Marino 
1855*e4b17023SJohn Marino /* Create a du or ud chain from SRC to DST and link it into SRC.   */
1856*e4b17023SJohn Marino 
1857*e4b17023SJohn Marino struct df_link *
df_chain_create(df_ref src,df_ref dst)1858*e4b17023SJohn Marino df_chain_create (df_ref src, df_ref dst)
1859*e4b17023SJohn Marino {
1860*e4b17023SJohn Marino   struct df_link *head = DF_REF_CHAIN (src);
1861*e4b17023SJohn Marino   struct df_link *link = (struct df_link *) pool_alloc (df_chain->block_pool);
1862*e4b17023SJohn Marino 
1863*e4b17023SJohn Marino   DF_REF_CHAIN (src) = link;
1864*e4b17023SJohn Marino   link->next = head;
1865*e4b17023SJohn Marino   link->ref = dst;
1866*e4b17023SJohn Marino   return link;
1867*e4b17023SJohn Marino }
1868*e4b17023SJohn Marino 
1869*e4b17023SJohn Marino 
1870*e4b17023SJohn Marino /* Delete any du or ud chains that start at REF and point to
1871*e4b17023SJohn Marino    TARGET.  */
1872*e4b17023SJohn Marino static void
df_chain_unlink_1(df_ref ref,df_ref target)1873*e4b17023SJohn Marino df_chain_unlink_1 (df_ref ref, df_ref target)
1874*e4b17023SJohn Marino {
1875*e4b17023SJohn Marino   struct df_link *chain = DF_REF_CHAIN (ref);
1876*e4b17023SJohn Marino   struct df_link *prev = NULL;
1877*e4b17023SJohn Marino 
1878*e4b17023SJohn Marino   while (chain)
1879*e4b17023SJohn Marino     {
1880*e4b17023SJohn Marino       if (chain->ref == target)
1881*e4b17023SJohn Marino 	{
1882*e4b17023SJohn Marino 	  if (prev)
1883*e4b17023SJohn Marino 	    prev->next = chain->next;
1884*e4b17023SJohn Marino 	  else
1885*e4b17023SJohn Marino 	    DF_REF_CHAIN (ref) = chain->next;
1886*e4b17023SJohn Marino 	  pool_free (df_chain->block_pool, chain);
1887*e4b17023SJohn Marino 	  return;
1888*e4b17023SJohn Marino 	}
1889*e4b17023SJohn Marino       prev = chain;
1890*e4b17023SJohn Marino       chain = chain->next;
1891*e4b17023SJohn Marino     }
1892*e4b17023SJohn Marino }
1893*e4b17023SJohn Marino 
1894*e4b17023SJohn Marino 
1895*e4b17023SJohn Marino /* Delete a du or ud chain that leave or point to REF.  */
1896*e4b17023SJohn Marino 
1897*e4b17023SJohn Marino void
df_chain_unlink(df_ref ref)1898*e4b17023SJohn Marino df_chain_unlink (df_ref ref)
1899*e4b17023SJohn Marino {
1900*e4b17023SJohn Marino   struct df_link *chain = DF_REF_CHAIN (ref);
1901*e4b17023SJohn Marino   while (chain)
1902*e4b17023SJohn Marino     {
1903*e4b17023SJohn Marino       struct df_link *next = chain->next;
1904*e4b17023SJohn Marino       /* Delete the other side if it exists.  */
1905*e4b17023SJohn Marino       df_chain_unlink_1 (chain->ref, ref);
1906*e4b17023SJohn Marino       pool_free (df_chain->block_pool, chain);
1907*e4b17023SJohn Marino       chain = next;
1908*e4b17023SJohn Marino     }
1909*e4b17023SJohn Marino   DF_REF_CHAIN (ref) = NULL;
1910*e4b17023SJohn Marino }
1911*e4b17023SJohn Marino 
1912*e4b17023SJohn Marino 
1913*e4b17023SJohn Marino /* Copy the du or ud chain starting at FROM_REF and attach it to
1914*e4b17023SJohn Marino    TO_REF.  */
1915*e4b17023SJohn Marino 
1916*e4b17023SJohn Marino void
df_chain_copy(df_ref to_ref,struct df_link * from_ref)1917*e4b17023SJohn Marino df_chain_copy (df_ref to_ref,
1918*e4b17023SJohn Marino 	       struct df_link *from_ref)
1919*e4b17023SJohn Marino {
1920*e4b17023SJohn Marino   while (from_ref)
1921*e4b17023SJohn Marino     {
1922*e4b17023SJohn Marino       df_chain_create (to_ref, from_ref->ref);
1923*e4b17023SJohn Marino       from_ref = from_ref->next;
1924*e4b17023SJohn Marino     }
1925*e4b17023SJohn Marino }
1926*e4b17023SJohn Marino 
1927*e4b17023SJohn Marino 
1928*e4b17023SJohn Marino /* Remove this problem from the stack of dataflow problems.  */
1929*e4b17023SJohn Marino 
1930*e4b17023SJohn Marino static void
df_chain_remove_problem(void)1931*e4b17023SJohn Marino df_chain_remove_problem (void)
1932*e4b17023SJohn Marino {
1933*e4b17023SJohn Marino   bitmap_iterator bi;
1934*e4b17023SJohn Marino   unsigned int bb_index;
1935*e4b17023SJohn Marino 
1936*e4b17023SJohn Marino   /* Wholesale destruction of the old chains.  */
1937*e4b17023SJohn Marino   if (df_chain->block_pool)
1938*e4b17023SJohn Marino     free_alloc_pool (df_chain->block_pool);
1939*e4b17023SJohn Marino 
1940*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (df_chain->out_of_date_transfer_functions, 0, bb_index, bi)
1941*e4b17023SJohn Marino     {
1942*e4b17023SJohn Marino       rtx insn;
1943*e4b17023SJohn Marino       df_ref *def_rec;
1944*e4b17023SJohn Marino       df_ref *use_rec;
1945*e4b17023SJohn Marino       basic_block bb = BASIC_BLOCK (bb_index);
1946*e4b17023SJohn Marino 
1947*e4b17023SJohn Marino       if (df_chain_problem_p (DF_DU_CHAIN))
1948*e4b17023SJohn Marino 	for (def_rec = df_get_artificial_defs (bb->index); *def_rec; def_rec++)
1949*e4b17023SJohn Marino 	  DF_REF_CHAIN (*def_rec) = NULL;
1950*e4b17023SJohn Marino       if (df_chain_problem_p (DF_UD_CHAIN))
1951*e4b17023SJohn Marino 	for (use_rec = df_get_artificial_uses (bb->index); *use_rec; use_rec++)
1952*e4b17023SJohn Marino 	  DF_REF_CHAIN (*use_rec) = NULL;
1953*e4b17023SJohn Marino 
1954*e4b17023SJohn Marino       FOR_BB_INSNS (bb, insn)
1955*e4b17023SJohn Marino 	{
1956*e4b17023SJohn Marino 	  unsigned int uid = INSN_UID (insn);
1957*e4b17023SJohn Marino 
1958*e4b17023SJohn Marino 	  if (INSN_P (insn))
1959*e4b17023SJohn Marino 	    {
1960*e4b17023SJohn Marino 	      if (df_chain_problem_p (DF_DU_CHAIN))
1961*e4b17023SJohn Marino 		for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
1962*e4b17023SJohn Marino 		  DF_REF_CHAIN (*def_rec) = NULL;
1963*e4b17023SJohn Marino 	      if (df_chain_problem_p (DF_UD_CHAIN))
1964*e4b17023SJohn Marino 		{
1965*e4b17023SJohn Marino 		  for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
1966*e4b17023SJohn Marino 		    DF_REF_CHAIN (*use_rec) = NULL;
1967*e4b17023SJohn Marino 		  for (use_rec = DF_INSN_UID_EQ_USES (uid); *use_rec; use_rec++)
1968*e4b17023SJohn Marino 		    DF_REF_CHAIN (*use_rec) = NULL;
1969*e4b17023SJohn Marino 		}
1970*e4b17023SJohn Marino 	    }
1971*e4b17023SJohn Marino 	}
1972*e4b17023SJohn Marino     }
1973*e4b17023SJohn Marino 
1974*e4b17023SJohn Marino   bitmap_clear (df_chain->out_of_date_transfer_functions);
1975*e4b17023SJohn Marino   df_chain->block_pool = NULL;
1976*e4b17023SJohn Marino }
1977*e4b17023SJohn Marino 
1978*e4b17023SJohn Marino 
1979*e4b17023SJohn Marino /* Remove the chain problem completely.  */
1980*e4b17023SJohn Marino 
1981*e4b17023SJohn Marino static void
df_chain_fully_remove_problem(void)1982*e4b17023SJohn Marino df_chain_fully_remove_problem (void)
1983*e4b17023SJohn Marino {
1984*e4b17023SJohn Marino   df_chain_remove_problem ();
1985*e4b17023SJohn Marino   BITMAP_FREE (df_chain->out_of_date_transfer_functions);
1986*e4b17023SJohn Marino   free (df_chain);
1987*e4b17023SJohn Marino }
1988*e4b17023SJohn Marino 
1989*e4b17023SJohn Marino 
1990*e4b17023SJohn Marino /* Create def-use or use-def chains.  */
1991*e4b17023SJohn Marino 
1992*e4b17023SJohn Marino static void
df_chain_alloc(bitmap all_blocks ATTRIBUTE_UNUSED)1993*e4b17023SJohn Marino df_chain_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
1994*e4b17023SJohn Marino {
1995*e4b17023SJohn Marino   df_chain_remove_problem ();
1996*e4b17023SJohn Marino   df_chain->block_pool = create_alloc_pool ("df_chain_block pool",
1997*e4b17023SJohn Marino 					 sizeof (struct df_link), 50);
1998*e4b17023SJohn Marino   df_chain->optional_p = true;
1999*e4b17023SJohn Marino }
2000*e4b17023SJohn Marino 
2001*e4b17023SJohn Marino 
2002*e4b17023SJohn Marino /* Reset all of the chains when the set of basic blocks changes.  */
2003*e4b17023SJohn Marino 
2004*e4b17023SJohn Marino static void
df_chain_reset(bitmap blocks_to_clear ATTRIBUTE_UNUSED)2005*e4b17023SJohn Marino df_chain_reset (bitmap blocks_to_clear ATTRIBUTE_UNUSED)
2006*e4b17023SJohn Marino {
2007*e4b17023SJohn Marino   df_chain_remove_problem ();
2008*e4b17023SJohn Marino }
2009*e4b17023SJohn Marino 
2010*e4b17023SJohn Marino 
2011*e4b17023SJohn Marino /* Create the chains for a list of USEs.  */
2012*e4b17023SJohn Marino 
2013*e4b17023SJohn Marino static void
df_chain_create_bb_process_use(bitmap local_rd,df_ref * use_rec,int top_flag)2014*e4b17023SJohn Marino df_chain_create_bb_process_use (bitmap local_rd,
2015*e4b17023SJohn Marino 				df_ref *use_rec,
2016*e4b17023SJohn Marino 				int top_flag)
2017*e4b17023SJohn Marino {
2018*e4b17023SJohn Marino   bitmap_iterator bi;
2019*e4b17023SJohn Marino   unsigned int def_index;
2020*e4b17023SJohn Marino 
2021*e4b17023SJohn Marino   while (*use_rec)
2022*e4b17023SJohn Marino     {
2023*e4b17023SJohn Marino       df_ref use = *use_rec;
2024*e4b17023SJohn Marino       unsigned int uregno = DF_REF_REGNO (use);
2025*e4b17023SJohn Marino       if ((!(df->changeable_flags & DF_NO_HARD_REGS))
2026*e4b17023SJohn Marino 	  || (uregno >= FIRST_PSEUDO_REGISTER))
2027*e4b17023SJohn Marino 	{
2028*e4b17023SJohn Marino 	  /* Do not want to go through this for an uninitialized var.  */
2029*e4b17023SJohn Marino 	  int count = DF_DEFS_COUNT (uregno);
2030*e4b17023SJohn Marino 	  if (count)
2031*e4b17023SJohn Marino 	    {
2032*e4b17023SJohn Marino 	      if (top_flag == (DF_REF_FLAGS (use) & DF_REF_AT_TOP))
2033*e4b17023SJohn Marino 		{
2034*e4b17023SJohn Marino 		  unsigned int first_index = DF_DEFS_BEGIN (uregno);
2035*e4b17023SJohn Marino 		  unsigned int last_index = first_index + count - 1;
2036*e4b17023SJohn Marino 
2037*e4b17023SJohn Marino 		  EXECUTE_IF_SET_IN_BITMAP (local_rd, first_index, def_index, bi)
2038*e4b17023SJohn Marino 		    {
2039*e4b17023SJohn Marino 		      df_ref def;
2040*e4b17023SJohn Marino 		      if (def_index > last_index)
2041*e4b17023SJohn Marino 			break;
2042*e4b17023SJohn Marino 
2043*e4b17023SJohn Marino 		      def = DF_DEFS_GET (def_index);
2044*e4b17023SJohn Marino 		      if (df_chain_problem_p (DF_DU_CHAIN))
2045*e4b17023SJohn Marino 			df_chain_create (def, use);
2046*e4b17023SJohn Marino 		      if (df_chain_problem_p (DF_UD_CHAIN))
2047*e4b17023SJohn Marino 			df_chain_create (use, def);
2048*e4b17023SJohn Marino 		    }
2049*e4b17023SJohn Marino 		}
2050*e4b17023SJohn Marino 	    }
2051*e4b17023SJohn Marino 	}
2052*e4b17023SJohn Marino 
2053*e4b17023SJohn Marino       use_rec++;
2054*e4b17023SJohn Marino     }
2055*e4b17023SJohn Marino }
2056*e4b17023SJohn Marino 
2057*e4b17023SJohn Marino 
2058*e4b17023SJohn Marino /* Create chains from reaching defs bitmaps for basic block BB.  */
2059*e4b17023SJohn Marino 
2060*e4b17023SJohn Marino static void
df_chain_create_bb(unsigned int bb_index)2061*e4b17023SJohn Marino df_chain_create_bb (unsigned int bb_index)
2062*e4b17023SJohn Marino {
2063*e4b17023SJohn Marino   basic_block bb = BASIC_BLOCK (bb_index);
2064*e4b17023SJohn Marino   struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
2065*e4b17023SJohn Marino   rtx insn;
2066*e4b17023SJohn Marino   bitmap_head cpy;
2067*e4b17023SJohn Marino 
2068*e4b17023SJohn Marino   bitmap_initialize (&cpy, &bitmap_default_obstack);
2069*e4b17023SJohn Marino   bitmap_copy (&cpy, &bb_info->in);
2070*e4b17023SJohn Marino   bitmap_set_bit (df_chain->out_of_date_transfer_functions, bb_index);
2071*e4b17023SJohn Marino 
2072*e4b17023SJohn Marino   /* Since we are going forwards, process the artificial uses first
2073*e4b17023SJohn Marino      then the artificial defs second.  */
2074*e4b17023SJohn Marino 
2075*e4b17023SJohn Marino #ifdef EH_USES
2076*e4b17023SJohn Marino   /* Create the chains for the artificial uses from the EH_USES at the
2077*e4b17023SJohn Marino      beginning of the block.  */
2078*e4b17023SJohn Marino 
2079*e4b17023SJohn Marino   /* Artificials are only hard regs.  */
2080*e4b17023SJohn Marino   if (!(df->changeable_flags & DF_NO_HARD_REGS))
2081*e4b17023SJohn Marino     df_chain_create_bb_process_use (&cpy,
2082*e4b17023SJohn Marino 				    df_get_artificial_uses (bb->index),
2083*e4b17023SJohn Marino 				    DF_REF_AT_TOP);
2084*e4b17023SJohn Marino #endif
2085*e4b17023SJohn Marino 
2086*e4b17023SJohn Marino   df_rd_simulate_artificial_defs_at_top (bb, &cpy);
2087*e4b17023SJohn Marino 
2088*e4b17023SJohn Marino   /* Process the regular instructions next.  */
2089*e4b17023SJohn Marino   FOR_BB_INSNS (bb, insn)
2090*e4b17023SJohn Marino     if (INSN_P (insn))
2091*e4b17023SJohn Marino       {
2092*e4b17023SJohn Marino         unsigned int uid = INSN_UID (insn);
2093*e4b17023SJohn Marino 
2094*e4b17023SJohn Marino         /* First scan the uses and link them up with the defs that remain
2095*e4b17023SJohn Marino 	   in the cpy vector.  */
2096*e4b17023SJohn Marino         df_chain_create_bb_process_use (&cpy, DF_INSN_UID_USES (uid), 0);
2097*e4b17023SJohn Marino         if (df->changeable_flags & DF_EQ_NOTES)
2098*e4b17023SJohn Marino 	  df_chain_create_bb_process_use (&cpy, DF_INSN_UID_EQ_USES (uid), 0);
2099*e4b17023SJohn Marino 
2100*e4b17023SJohn Marino         /* Since we are going forwards, process the defs second.  */
2101*e4b17023SJohn Marino         df_rd_simulate_one_insn (bb, insn, &cpy);
2102*e4b17023SJohn Marino       }
2103*e4b17023SJohn Marino 
2104*e4b17023SJohn Marino   /* Create the chains for the artificial uses of the hard registers
2105*e4b17023SJohn Marino      at the end of the block.  */
2106*e4b17023SJohn Marino   if (!(df->changeable_flags & DF_NO_HARD_REGS))
2107*e4b17023SJohn Marino     df_chain_create_bb_process_use (&cpy,
2108*e4b17023SJohn Marino 				    df_get_artificial_uses (bb->index),
2109*e4b17023SJohn Marino 				    0);
2110*e4b17023SJohn Marino 
2111*e4b17023SJohn Marino   bitmap_clear (&cpy);
2112*e4b17023SJohn Marino }
2113*e4b17023SJohn Marino 
2114*e4b17023SJohn Marino /* Create def-use chains from reaching use bitmaps for basic blocks
2115*e4b17023SJohn Marino    in BLOCKS.  */
2116*e4b17023SJohn Marino 
2117*e4b17023SJohn Marino static void
df_chain_finalize(bitmap all_blocks)2118*e4b17023SJohn Marino df_chain_finalize (bitmap all_blocks)
2119*e4b17023SJohn Marino {
2120*e4b17023SJohn Marino   unsigned int bb_index;
2121*e4b17023SJohn Marino   bitmap_iterator bi;
2122*e4b17023SJohn Marino 
2123*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
2124*e4b17023SJohn Marino     {
2125*e4b17023SJohn Marino       df_chain_create_bb (bb_index);
2126*e4b17023SJohn Marino     }
2127*e4b17023SJohn Marino }
2128*e4b17023SJohn Marino 
2129*e4b17023SJohn Marino 
2130*e4b17023SJohn Marino /* Free all storage associated with the problem.  */
2131*e4b17023SJohn Marino 
2132*e4b17023SJohn Marino static void
df_chain_free(void)2133*e4b17023SJohn Marino df_chain_free (void)
2134*e4b17023SJohn Marino {
2135*e4b17023SJohn Marino   free_alloc_pool (df_chain->block_pool);
2136*e4b17023SJohn Marino   BITMAP_FREE (df_chain->out_of_date_transfer_functions);
2137*e4b17023SJohn Marino   free (df_chain);
2138*e4b17023SJohn Marino }
2139*e4b17023SJohn Marino 
2140*e4b17023SJohn Marino 
2141*e4b17023SJohn Marino /* Debugging info.  */
2142*e4b17023SJohn Marino 
2143*e4b17023SJohn Marino static void
df_chain_top_dump(basic_block bb,FILE * file)2144*e4b17023SJohn Marino df_chain_top_dump (basic_block bb, FILE *file)
2145*e4b17023SJohn Marino {
2146*e4b17023SJohn Marino   if (df_chain_problem_p (DF_DU_CHAIN))
2147*e4b17023SJohn Marino     {
2148*e4b17023SJohn Marino       rtx insn;
2149*e4b17023SJohn Marino       df_ref *def_rec = df_get_artificial_defs (bb->index);
2150*e4b17023SJohn Marino       if (*def_rec)
2151*e4b17023SJohn Marino 	{
2152*e4b17023SJohn Marino 
2153*e4b17023SJohn Marino 	  fprintf (file, ";;  DU chains for artificial defs\n");
2154*e4b17023SJohn Marino 	  while (*def_rec)
2155*e4b17023SJohn Marino 	    {
2156*e4b17023SJohn Marino 	      df_ref def = *def_rec;
2157*e4b17023SJohn Marino 	      fprintf (file, ";;   reg %d ", DF_REF_REGNO (def));
2158*e4b17023SJohn Marino 	      df_chain_dump (DF_REF_CHAIN (def), file);
2159*e4b17023SJohn Marino 	      fprintf (file, "\n");
2160*e4b17023SJohn Marino 	      def_rec++;
2161*e4b17023SJohn Marino 	    }
2162*e4b17023SJohn Marino 	}
2163*e4b17023SJohn Marino 
2164*e4b17023SJohn Marino       FOR_BB_INSNS (bb, insn)
2165*e4b17023SJohn Marino 	{
2166*e4b17023SJohn Marino 	  if (INSN_P (insn))
2167*e4b17023SJohn Marino 	    {
2168*e4b17023SJohn Marino 	      struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
2169*e4b17023SJohn Marino 	      def_rec = DF_INSN_INFO_DEFS (insn_info);
2170*e4b17023SJohn Marino 	      if (*def_rec)
2171*e4b17023SJohn Marino 		{
2172*e4b17023SJohn Marino 		  fprintf (file, ";;   DU chains for insn luid %d uid %d\n",
2173*e4b17023SJohn Marino 			   DF_INSN_INFO_LUID (insn_info), INSN_UID (insn));
2174*e4b17023SJohn Marino 
2175*e4b17023SJohn Marino 		  while (*def_rec)
2176*e4b17023SJohn Marino 		    {
2177*e4b17023SJohn Marino 		      df_ref def = *def_rec;
2178*e4b17023SJohn Marino 		      fprintf (file, ";;      reg %d ", DF_REF_REGNO (def));
2179*e4b17023SJohn Marino 		      if (DF_REF_FLAGS (def) & DF_REF_READ_WRITE)
2180*e4b17023SJohn Marino 			fprintf (file, "read/write ");
2181*e4b17023SJohn Marino 		      df_chain_dump (DF_REF_CHAIN (def), file);
2182*e4b17023SJohn Marino 		      fprintf (file, "\n");
2183*e4b17023SJohn Marino 		      def_rec++;
2184*e4b17023SJohn Marino 		    }
2185*e4b17023SJohn Marino 		}
2186*e4b17023SJohn Marino 	    }
2187*e4b17023SJohn Marino 	}
2188*e4b17023SJohn Marino     }
2189*e4b17023SJohn Marino }
2190*e4b17023SJohn Marino 
2191*e4b17023SJohn Marino 
2192*e4b17023SJohn Marino static void
df_chain_bottom_dump(basic_block bb,FILE * file)2193*e4b17023SJohn Marino df_chain_bottom_dump (basic_block bb, FILE *file)
2194*e4b17023SJohn Marino {
2195*e4b17023SJohn Marino   if (df_chain_problem_p (DF_UD_CHAIN))
2196*e4b17023SJohn Marino     {
2197*e4b17023SJohn Marino       rtx insn;
2198*e4b17023SJohn Marino       df_ref *use_rec = df_get_artificial_uses (bb->index);
2199*e4b17023SJohn Marino 
2200*e4b17023SJohn Marino       if (*use_rec)
2201*e4b17023SJohn Marino 	{
2202*e4b17023SJohn Marino 	  fprintf (file, ";;  UD chains for artificial uses\n");
2203*e4b17023SJohn Marino 	  while (*use_rec)
2204*e4b17023SJohn Marino 	    {
2205*e4b17023SJohn Marino 	      df_ref use = *use_rec;
2206*e4b17023SJohn Marino 	      fprintf (file, ";;   reg %d ", DF_REF_REGNO (use));
2207*e4b17023SJohn Marino 	      df_chain_dump (DF_REF_CHAIN (use), file);
2208*e4b17023SJohn Marino 	      fprintf (file, "\n");
2209*e4b17023SJohn Marino 	      use_rec++;
2210*e4b17023SJohn Marino 	    }
2211*e4b17023SJohn Marino 	}
2212*e4b17023SJohn Marino 
2213*e4b17023SJohn Marino       FOR_BB_INSNS (bb, insn)
2214*e4b17023SJohn Marino 	{
2215*e4b17023SJohn Marino 	  if (INSN_P (insn))
2216*e4b17023SJohn Marino 	    {
2217*e4b17023SJohn Marino 	      struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
2218*e4b17023SJohn Marino 	      df_ref *eq_use_rec = DF_INSN_INFO_EQ_USES (insn_info);
2219*e4b17023SJohn Marino 	      use_rec = DF_INSN_INFO_USES (insn_info);
2220*e4b17023SJohn Marino 	      if (*use_rec || *eq_use_rec)
2221*e4b17023SJohn Marino 		{
2222*e4b17023SJohn Marino 		  fprintf (file, ";;   UD chains for insn luid %d uid %d\n",
2223*e4b17023SJohn Marino 			   DF_INSN_INFO_LUID (insn_info), INSN_UID (insn));
2224*e4b17023SJohn Marino 
2225*e4b17023SJohn Marino 		  while (*use_rec)
2226*e4b17023SJohn Marino 		    {
2227*e4b17023SJohn Marino 		      df_ref use = *use_rec;
2228*e4b17023SJohn Marino 		      fprintf (file, ";;      reg %d ", DF_REF_REGNO (use));
2229*e4b17023SJohn Marino 		      if (DF_REF_FLAGS (use) & DF_REF_READ_WRITE)
2230*e4b17023SJohn Marino 			fprintf (file, "read/write ");
2231*e4b17023SJohn Marino 		      df_chain_dump (DF_REF_CHAIN (use), file);
2232*e4b17023SJohn Marino 		      fprintf (file, "\n");
2233*e4b17023SJohn Marino 		      use_rec++;
2234*e4b17023SJohn Marino 		    }
2235*e4b17023SJohn Marino 		  while (*eq_use_rec)
2236*e4b17023SJohn Marino 		    {
2237*e4b17023SJohn Marino 		      df_ref use = *eq_use_rec;
2238*e4b17023SJohn Marino 		      fprintf (file, ";;   eq_note reg %d ", DF_REF_REGNO (use));
2239*e4b17023SJohn Marino 		      df_chain_dump (DF_REF_CHAIN (use), file);
2240*e4b17023SJohn Marino 		      fprintf (file, "\n");
2241*e4b17023SJohn Marino 		      eq_use_rec++;
2242*e4b17023SJohn Marino 		    }
2243*e4b17023SJohn Marino 		}
2244*e4b17023SJohn Marino 	    }
2245*e4b17023SJohn Marino 	}
2246*e4b17023SJohn Marino     }
2247*e4b17023SJohn Marino }
2248*e4b17023SJohn Marino 
2249*e4b17023SJohn Marino 
2250*e4b17023SJohn Marino static struct df_problem problem_CHAIN =
2251*e4b17023SJohn Marino {
2252*e4b17023SJohn Marino   DF_CHAIN,                   /* Problem id.  */
2253*e4b17023SJohn Marino   DF_NONE,                    /* Direction.  */
2254*e4b17023SJohn Marino   df_chain_alloc,             /* Allocate the problem specific data.  */
2255*e4b17023SJohn Marino   df_chain_reset,             /* Reset global information.  */
2256*e4b17023SJohn Marino   NULL,                       /* Free basic block info.  */
2257*e4b17023SJohn Marino   NULL,                       /* Local compute function.  */
2258*e4b17023SJohn Marino   NULL,                       /* Init the solution specific data.  */
2259*e4b17023SJohn Marino   NULL,                       /* Iterative solver.  */
2260*e4b17023SJohn Marino   NULL,                       /* Confluence operator 0.  */
2261*e4b17023SJohn Marino   NULL,                       /* Confluence operator n.  */
2262*e4b17023SJohn Marino   NULL,                       /* Transfer function.  */
2263*e4b17023SJohn Marino   df_chain_finalize,          /* Finalize function.  */
2264*e4b17023SJohn Marino   df_chain_free,              /* Free all of the problem information.  */
2265*e4b17023SJohn Marino   df_chain_fully_remove_problem,/* Remove this problem from the stack of dataflow problems.  */
2266*e4b17023SJohn Marino   NULL,                       /* Debugging.  */
2267*e4b17023SJohn Marino   df_chain_top_dump,          /* Debugging start block.  */
2268*e4b17023SJohn Marino   df_chain_bottom_dump,       /* Debugging end block.  */
2269*e4b17023SJohn Marino   NULL,                       /* Incremental solution verify start.  */
2270*e4b17023SJohn Marino   NULL,                       /* Incremental solution verify end.  */
2271*e4b17023SJohn Marino   &problem_RD,                /* Dependent problem.  */
2272*e4b17023SJohn Marino   sizeof (struct df_scan_bb_info),/* Size of entry of block_info array.  */
2273*e4b17023SJohn Marino   TV_DF_CHAIN,                /* Timing variable.  */
2274*e4b17023SJohn Marino   false                       /* Reset blocks on dropping out of blocks_to_analyze.  */
2275*e4b17023SJohn Marino };
2276*e4b17023SJohn Marino 
2277*e4b17023SJohn Marino 
2278*e4b17023SJohn Marino /* Create a new DATAFLOW instance and add it to an existing instance
2279*e4b17023SJohn Marino    of DF.  The returned structure is what is used to get at the
2280*e4b17023SJohn Marino    solution.  */
2281*e4b17023SJohn Marino 
2282*e4b17023SJohn Marino void
df_chain_add_problem(unsigned int chain_flags)2283*e4b17023SJohn Marino df_chain_add_problem (unsigned int chain_flags)
2284*e4b17023SJohn Marino {
2285*e4b17023SJohn Marino   df_add_problem (&problem_CHAIN);
2286*e4b17023SJohn Marino   df_chain->local_flags = chain_flags;
2287*e4b17023SJohn Marino   df_chain->out_of_date_transfer_functions = BITMAP_ALLOC (NULL);
2288*e4b17023SJohn Marino }
2289*e4b17023SJohn Marino 
2290*e4b17023SJohn Marino #undef df_chain_problem_p
2291*e4b17023SJohn Marino 
2292*e4b17023SJohn Marino 
2293*e4b17023SJohn Marino /*----------------------------------------------------------------------------
2294*e4b17023SJohn Marino    WORD LEVEL LIVE REGISTERS
2295*e4b17023SJohn Marino 
2296*e4b17023SJohn Marino    Find the locations in the function where any use of a pseudo can
2297*e4b17023SJohn Marino    reach in the backwards direction.  In and out bitvectors are built
2298*e4b17023SJohn Marino    for each basic block.  We only track pseudo registers that have a
2299*e4b17023SJohn Marino    size of 2 * UNITS_PER_WORD; bitmaps are indexed by 2 * regno and
2300*e4b17023SJohn Marino    contain two bits corresponding to each of the subwords.
2301*e4b17023SJohn Marino 
2302*e4b17023SJohn Marino    ----------------------------------------------------------------------------*/
2303*e4b17023SJohn Marino 
2304*e4b17023SJohn Marino /* Private data used to verify the solution for this problem.  */
2305*e4b17023SJohn Marino struct df_word_lr_problem_data
2306*e4b17023SJohn Marino {
2307*e4b17023SJohn Marino   /* An obstack for the bitmaps we need for this problem.  */
2308*e4b17023SJohn Marino   bitmap_obstack word_lr_bitmaps;
2309*e4b17023SJohn Marino };
2310*e4b17023SJohn Marino 
2311*e4b17023SJohn Marino 
2312*e4b17023SJohn Marino /* Free basic block info.  */
2313*e4b17023SJohn Marino 
2314*e4b17023SJohn Marino static void
df_word_lr_free_bb_info(basic_block bb ATTRIBUTE_UNUSED,void * vbb_info)2315*e4b17023SJohn Marino df_word_lr_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
2316*e4b17023SJohn Marino 			 void *vbb_info)
2317*e4b17023SJohn Marino {
2318*e4b17023SJohn Marino   struct df_word_lr_bb_info *bb_info = (struct df_word_lr_bb_info *) vbb_info;
2319*e4b17023SJohn Marino   if (bb_info)
2320*e4b17023SJohn Marino     {
2321*e4b17023SJohn Marino       bitmap_clear (&bb_info->use);
2322*e4b17023SJohn Marino       bitmap_clear (&bb_info->def);
2323*e4b17023SJohn Marino       bitmap_clear (&bb_info->in);
2324*e4b17023SJohn Marino       bitmap_clear (&bb_info->out);
2325*e4b17023SJohn Marino     }
2326*e4b17023SJohn Marino }
2327*e4b17023SJohn Marino 
2328*e4b17023SJohn Marino 
2329*e4b17023SJohn Marino /* Allocate or reset bitmaps for DF_WORD_LR blocks. The solution bits are
2330*e4b17023SJohn Marino    not touched unless the block is new.  */
2331*e4b17023SJohn Marino 
2332*e4b17023SJohn Marino static void
df_word_lr_alloc(bitmap all_blocks ATTRIBUTE_UNUSED)2333*e4b17023SJohn Marino df_word_lr_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
2334*e4b17023SJohn Marino {
2335*e4b17023SJohn Marino   unsigned int bb_index;
2336*e4b17023SJohn Marino   bitmap_iterator bi;
2337*e4b17023SJohn Marino   basic_block bb;
2338*e4b17023SJohn Marino   struct df_word_lr_problem_data *problem_data
2339*e4b17023SJohn Marino     = XNEW (struct df_word_lr_problem_data);
2340*e4b17023SJohn Marino 
2341*e4b17023SJohn Marino   df_word_lr->problem_data = problem_data;
2342*e4b17023SJohn Marino 
2343*e4b17023SJohn Marino   df_grow_bb_info (df_word_lr);
2344*e4b17023SJohn Marino 
2345*e4b17023SJohn Marino   /* Create the mapping from regnos to slots. This does not change
2346*e4b17023SJohn Marino      unless the problem is destroyed and recreated.  In particular, if
2347*e4b17023SJohn Marino      we end up deleting the only insn that used a subreg, we do not
2348*e4b17023SJohn Marino      want to redo the mapping because this would invalidate everything
2349*e4b17023SJohn Marino      else.  */
2350*e4b17023SJohn Marino 
2351*e4b17023SJohn Marino   bitmap_obstack_initialize (&problem_data->word_lr_bitmaps);
2352*e4b17023SJohn Marino 
2353*e4b17023SJohn Marino   FOR_EACH_BB (bb)
2354*e4b17023SJohn Marino     bitmap_set_bit (df_word_lr->out_of_date_transfer_functions, bb->index);
2355*e4b17023SJohn Marino 
2356*e4b17023SJohn Marino   bitmap_set_bit (df_word_lr->out_of_date_transfer_functions, ENTRY_BLOCK);
2357*e4b17023SJohn Marino   bitmap_set_bit (df_word_lr->out_of_date_transfer_functions, EXIT_BLOCK);
2358*e4b17023SJohn Marino 
2359*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (df_word_lr->out_of_date_transfer_functions, 0, bb_index, bi)
2360*e4b17023SJohn Marino     {
2361*e4b17023SJohn Marino       struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
2362*e4b17023SJohn Marino 
2363*e4b17023SJohn Marino       /* When bitmaps are already initialized, just clear them.  */
2364*e4b17023SJohn Marino       if (bb_info->use.obstack)
2365*e4b17023SJohn Marino 	{
2366*e4b17023SJohn Marino 	  bitmap_clear (&bb_info->def);
2367*e4b17023SJohn Marino 	  bitmap_clear (&bb_info->use);
2368*e4b17023SJohn Marino 	}
2369*e4b17023SJohn Marino       else
2370*e4b17023SJohn Marino 	{
2371*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->use, &problem_data->word_lr_bitmaps);
2372*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->def, &problem_data->word_lr_bitmaps);
2373*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->in, &problem_data->word_lr_bitmaps);
2374*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->out, &problem_data->word_lr_bitmaps);
2375*e4b17023SJohn Marino 	}
2376*e4b17023SJohn Marino     }
2377*e4b17023SJohn Marino 
2378*e4b17023SJohn Marino   df_word_lr->optional_p = true;
2379*e4b17023SJohn Marino }
2380*e4b17023SJohn Marino 
2381*e4b17023SJohn Marino 
2382*e4b17023SJohn Marino /* Reset the global solution for recalculation.  */
2383*e4b17023SJohn Marino 
2384*e4b17023SJohn Marino static void
df_word_lr_reset(bitmap all_blocks)2385*e4b17023SJohn Marino df_word_lr_reset (bitmap all_blocks)
2386*e4b17023SJohn Marino {
2387*e4b17023SJohn Marino   unsigned int bb_index;
2388*e4b17023SJohn Marino   bitmap_iterator bi;
2389*e4b17023SJohn Marino 
2390*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
2391*e4b17023SJohn Marino     {
2392*e4b17023SJohn Marino       struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
2393*e4b17023SJohn Marino       gcc_assert (bb_info);
2394*e4b17023SJohn Marino       bitmap_clear (&bb_info->in);
2395*e4b17023SJohn Marino       bitmap_clear (&bb_info->out);
2396*e4b17023SJohn Marino     }
2397*e4b17023SJohn Marino }
2398*e4b17023SJohn Marino 
2399*e4b17023SJohn Marino /* Examine REF, and if it is for a reg we're interested in, set or
2400*e4b17023SJohn Marino    clear the bits corresponding to its subwords from the bitmap
2401*e4b17023SJohn Marino    according to IS_SET.  LIVE is the bitmap we should update.  We do
2402*e4b17023SJohn Marino    not track hard regs or pseudos of any size other than 2 *
2403*e4b17023SJohn Marino    UNITS_PER_WORD.
2404*e4b17023SJohn Marino    We return true if we changed the bitmap, or if we encountered a register
2405*e4b17023SJohn Marino    we're not tracking.  */
2406*e4b17023SJohn Marino 
2407*e4b17023SJohn Marino bool
df_word_lr_mark_ref(df_ref ref,bool is_set,regset live)2408*e4b17023SJohn Marino df_word_lr_mark_ref (df_ref ref, bool is_set, regset live)
2409*e4b17023SJohn Marino {
2410*e4b17023SJohn Marino   rtx orig_reg = DF_REF_REG (ref);
2411*e4b17023SJohn Marino   rtx reg = orig_reg;
2412*e4b17023SJohn Marino   enum machine_mode reg_mode;
2413*e4b17023SJohn Marino   unsigned regno;
2414*e4b17023SJohn Marino   /* Left at -1 for whole accesses.  */
2415*e4b17023SJohn Marino   int which_subword = -1;
2416*e4b17023SJohn Marino   bool changed = false;
2417*e4b17023SJohn Marino 
2418*e4b17023SJohn Marino   if (GET_CODE (reg) == SUBREG)
2419*e4b17023SJohn Marino     reg = SUBREG_REG (orig_reg);
2420*e4b17023SJohn Marino   regno = REGNO (reg);
2421*e4b17023SJohn Marino   reg_mode = GET_MODE (reg);
2422*e4b17023SJohn Marino   if (regno < FIRST_PSEUDO_REGISTER
2423*e4b17023SJohn Marino       || GET_MODE_SIZE (reg_mode) != 2 * UNITS_PER_WORD)
2424*e4b17023SJohn Marino     return true;
2425*e4b17023SJohn Marino 
2426*e4b17023SJohn Marino   if (GET_CODE (orig_reg) == SUBREG
2427*e4b17023SJohn Marino       && df_read_modify_subreg_p (orig_reg))
2428*e4b17023SJohn Marino     {
2429*e4b17023SJohn Marino       gcc_assert (DF_REF_FLAGS_IS_SET (ref, DF_REF_PARTIAL));
2430*e4b17023SJohn Marino       if (subreg_lowpart_p (orig_reg))
2431*e4b17023SJohn Marino 	which_subword = 0;
2432*e4b17023SJohn Marino       else
2433*e4b17023SJohn Marino 	which_subword = 1;
2434*e4b17023SJohn Marino     }
2435*e4b17023SJohn Marino   if (is_set)
2436*e4b17023SJohn Marino     {
2437*e4b17023SJohn Marino       if (which_subword != 1)
2438*e4b17023SJohn Marino 	changed |= bitmap_set_bit (live, regno * 2);
2439*e4b17023SJohn Marino       if (which_subword != 0)
2440*e4b17023SJohn Marino 	changed |= bitmap_set_bit (live, regno * 2 + 1);
2441*e4b17023SJohn Marino     }
2442*e4b17023SJohn Marino   else
2443*e4b17023SJohn Marino     {
2444*e4b17023SJohn Marino       if (which_subword != 1)
2445*e4b17023SJohn Marino 	changed |= bitmap_clear_bit (live, regno * 2);
2446*e4b17023SJohn Marino       if (which_subword != 0)
2447*e4b17023SJohn Marino 	changed |= bitmap_clear_bit (live, regno * 2 + 1);
2448*e4b17023SJohn Marino     }
2449*e4b17023SJohn Marino   return changed;
2450*e4b17023SJohn Marino }
2451*e4b17023SJohn Marino 
2452*e4b17023SJohn Marino /* Compute local live register info for basic block BB.  */
2453*e4b17023SJohn Marino 
2454*e4b17023SJohn Marino static void
df_word_lr_bb_local_compute(unsigned int bb_index)2455*e4b17023SJohn Marino df_word_lr_bb_local_compute (unsigned int bb_index)
2456*e4b17023SJohn Marino {
2457*e4b17023SJohn Marino   basic_block bb = BASIC_BLOCK (bb_index);
2458*e4b17023SJohn Marino   struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
2459*e4b17023SJohn Marino   rtx insn;
2460*e4b17023SJohn Marino   df_ref *def_rec;
2461*e4b17023SJohn Marino   df_ref *use_rec;
2462*e4b17023SJohn Marino 
2463*e4b17023SJohn Marino   /* Ensure that artificial refs don't contain references to pseudos.  */
2464*e4b17023SJohn Marino   for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
2465*e4b17023SJohn Marino     {
2466*e4b17023SJohn Marino       df_ref def = *def_rec;
2467*e4b17023SJohn Marino       gcc_assert (DF_REF_REGNO (def) < FIRST_PSEUDO_REGISTER);
2468*e4b17023SJohn Marino     }
2469*e4b17023SJohn Marino 
2470*e4b17023SJohn Marino   for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
2471*e4b17023SJohn Marino     {
2472*e4b17023SJohn Marino       df_ref use = *use_rec;
2473*e4b17023SJohn Marino       gcc_assert (DF_REF_REGNO (use) < FIRST_PSEUDO_REGISTER);
2474*e4b17023SJohn Marino     }
2475*e4b17023SJohn Marino 
2476*e4b17023SJohn Marino   FOR_BB_INSNS_REVERSE (bb, insn)
2477*e4b17023SJohn Marino     {
2478*e4b17023SJohn Marino       unsigned int uid = INSN_UID (insn);
2479*e4b17023SJohn Marino 
2480*e4b17023SJohn Marino       if (!NONDEBUG_INSN_P (insn))
2481*e4b17023SJohn Marino 	continue;
2482*e4b17023SJohn Marino       for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
2483*e4b17023SJohn Marino 	{
2484*e4b17023SJohn Marino 	  df_ref def = *def_rec;
2485*e4b17023SJohn Marino 	  /* If the def is to only part of the reg, it does
2486*e4b17023SJohn Marino 	     not kill the other defs that reach here.  */
2487*e4b17023SJohn Marino 	  if (!(DF_REF_FLAGS (def) & (DF_REF_CONDITIONAL)))
2488*e4b17023SJohn Marino 	    {
2489*e4b17023SJohn Marino 	      df_word_lr_mark_ref (def, true, &bb_info->def);
2490*e4b17023SJohn Marino 	      df_word_lr_mark_ref (def, false, &bb_info->use);
2491*e4b17023SJohn Marino 	    }
2492*e4b17023SJohn Marino 	}
2493*e4b17023SJohn Marino       for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
2494*e4b17023SJohn Marino 	{
2495*e4b17023SJohn Marino 	  df_ref use = *use_rec;
2496*e4b17023SJohn Marino 	  df_word_lr_mark_ref (use, true, &bb_info->use);
2497*e4b17023SJohn Marino 	}
2498*e4b17023SJohn Marino     }
2499*e4b17023SJohn Marino }
2500*e4b17023SJohn Marino 
2501*e4b17023SJohn Marino 
2502*e4b17023SJohn Marino /* Compute local live register info for each basic block within BLOCKS.  */
2503*e4b17023SJohn Marino 
2504*e4b17023SJohn Marino static void
df_word_lr_local_compute(bitmap all_blocks ATTRIBUTE_UNUSED)2505*e4b17023SJohn Marino df_word_lr_local_compute (bitmap all_blocks ATTRIBUTE_UNUSED)
2506*e4b17023SJohn Marino {
2507*e4b17023SJohn Marino   unsigned int bb_index;
2508*e4b17023SJohn Marino   bitmap_iterator bi;
2509*e4b17023SJohn Marino 
2510*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (df_word_lr->out_of_date_transfer_functions, 0, bb_index, bi)
2511*e4b17023SJohn Marino     {
2512*e4b17023SJohn Marino       if (bb_index == EXIT_BLOCK)
2513*e4b17023SJohn Marino 	{
2514*e4b17023SJohn Marino 	  unsigned regno;
2515*e4b17023SJohn Marino 	  bitmap_iterator bi;
2516*e4b17023SJohn Marino 	  EXECUTE_IF_SET_IN_BITMAP (df->exit_block_uses, FIRST_PSEUDO_REGISTER,
2517*e4b17023SJohn Marino 				    regno, bi)
2518*e4b17023SJohn Marino 	    gcc_unreachable ();
2519*e4b17023SJohn Marino 	}
2520*e4b17023SJohn Marino       else
2521*e4b17023SJohn Marino 	df_word_lr_bb_local_compute (bb_index);
2522*e4b17023SJohn Marino     }
2523*e4b17023SJohn Marino 
2524*e4b17023SJohn Marino   bitmap_clear (df_word_lr->out_of_date_transfer_functions);
2525*e4b17023SJohn Marino }
2526*e4b17023SJohn Marino 
2527*e4b17023SJohn Marino 
2528*e4b17023SJohn Marino /* Initialize the solution vectors.  */
2529*e4b17023SJohn Marino 
2530*e4b17023SJohn Marino static void
df_word_lr_init(bitmap all_blocks)2531*e4b17023SJohn Marino df_word_lr_init (bitmap all_blocks)
2532*e4b17023SJohn Marino {
2533*e4b17023SJohn Marino   unsigned int bb_index;
2534*e4b17023SJohn Marino   bitmap_iterator bi;
2535*e4b17023SJohn Marino 
2536*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
2537*e4b17023SJohn Marino     {
2538*e4b17023SJohn Marino       struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
2539*e4b17023SJohn Marino       bitmap_copy (&bb_info->in, &bb_info->use);
2540*e4b17023SJohn Marino       bitmap_clear (&bb_info->out);
2541*e4b17023SJohn Marino     }
2542*e4b17023SJohn Marino }
2543*e4b17023SJohn Marino 
2544*e4b17023SJohn Marino 
2545*e4b17023SJohn Marino /* Confluence function that ignores fake edges.  */
2546*e4b17023SJohn Marino 
2547*e4b17023SJohn Marino static bool
df_word_lr_confluence_n(edge e)2548*e4b17023SJohn Marino df_word_lr_confluence_n (edge e)
2549*e4b17023SJohn Marino {
2550*e4b17023SJohn Marino   bitmap op1 = &df_word_lr_get_bb_info (e->src->index)->out;
2551*e4b17023SJohn Marino   bitmap op2 = &df_word_lr_get_bb_info (e->dest->index)->in;
2552*e4b17023SJohn Marino 
2553*e4b17023SJohn Marino   return bitmap_ior_into (op1, op2);
2554*e4b17023SJohn Marino }
2555*e4b17023SJohn Marino 
2556*e4b17023SJohn Marino 
2557*e4b17023SJohn Marino /* Transfer function.  */
2558*e4b17023SJohn Marino 
2559*e4b17023SJohn Marino static bool
df_word_lr_transfer_function(int bb_index)2560*e4b17023SJohn Marino df_word_lr_transfer_function (int bb_index)
2561*e4b17023SJohn Marino {
2562*e4b17023SJohn Marino   struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
2563*e4b17023SJohn Marino   bitmap in = &bb_info->in;
2564*e4b17023SJohn Marino   bitmap out = &bb_info->out;
2565*e4b17023SJohn Marino   bitmap use = &bb_info->use;
2566*e4b17023SJohn Marino   bitmap def = &bb_info->def;
2567*e4b17023SJohn Marino 
2568*e4b17023SJohn Marino   return bitmap_ior_and_compl (in, use, out, def);
2569*e4b17023SJohn Marino }
2570*e4b17023SJohn Marino 
2571*e4b17023SJohn Marino 
2572*e4b17023SJohn Marino /* Free all storage associated with the problem.  */
2573*e4b17023SJohn Marino 
2574*e4b17023SJohn Marino static void
df_word_lr_free(void)2575*e4b17023SJohn Marino df_word_lr_free (void)
2576*e4b17023SJohn Marino {
2577*e4b17023SJohn Marino   struct df_word_lr_problem_data *problem_data
2578*e4b17023SJohn Marino     = (struct df_word_lr_problem_data *)df_word_lr->problem_data;
2579*e4b17023SJohn Marino 
2580*e4b17023SJohn Marino   if (df_word_lr->block_info)
2581*e4b17023SJohn Marino     {
2582*e4b17023SJohn Marino       df_word_lr->block_info_size = 0;
2583*e4b17023SJohn Marino       free (df_word_lr->block_info);
2584*e4b17023SJohn Marino       df_word_lr->block_info = NULL;
2585*e4b17023SJohn Marino     }
2586*e4b17023SJohn Marino 
2587*e4b17023SJohn Marino   BITMAP_FREE (df_word_lr->out_of_date_transfer_functions);
2588*e4b17023SJohn Marino   bitmap_obstack_release (&problem_data->word_lr_bitmaps);
2589*e4b17023SJohn Marino   free (problem_data);
2590*e4b17023SJohn Marino   free (df_word_lr);
2591*e4b17023SJohn Marino }
2592*e4b17023SJohn Marino 
2593*e4b17023SJohn Marino 
2594*e4b17023SJohn Marino /* Debugging info at top of bb.  */
2595*e4b17023SJohn Marino 
2596*e4b17023SJohn Marino static void
df_word_lr_top_dump(basic_block bb,FILE * file)2597*e4b17023SJohn Marino df_word_lr_top_dump (basic_block bb, FILE *file)
2598*e4b17023SJohn Marino {
2599*e4b17023SJohn Marino   struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb->index);
2600*e4b17023SJohn Marino   if (!bb_info)
2601*e4b17023SJohn Marino     return;
2602*e4b17023SJohn Marino 
2603*e4b17023SJohn Marino   fprintf (file, ";; blr  in  \t");
2604*e4b17023SJohn Marino   df_print_word_regset (file, &bb_info->in);
2605*e4b17023SJohn Marino   fprintf (file, ";; blr  use \t");
2606*e4b17023SJohn Marino   df_print_word_regset (file, &bb_info->use);
2607*e4b17023SJohn Marino   fprintf (file, ";; blr  def \t");
2608*e4b17023SJohn Marino   df_print_word_regset (file, &bb_info->def);
2609*e4b17023SJohn Marino }
2610*e4b17023SJohn Marino 
2611*e4b17023SJohn Marino 
2612*e4b17023SJohn Marino /* Debugging info at bottom of bb.  */
2613*e4b17023SJohn Marino 
2614*e4b17023SJohn Marino static void
df_word_lr_bottom_dump(basic_block bb,FILE * file)2615*e4b17023SJohn Marino df_word_lr_bottom_dump (basic_block bb, FILE *file)
2616*e4b17023SJohn Marino {
2617*e4b17023SJohn Marino   struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb->index);
2618*e4b17023SJohn Marino   if (!bb_info)
2619*e4b17023SJohn Marino     return;
2620*e4b17023SJohn Marino 
2621*e4b17023SJohn Marino   fprintf (file, ";; blr  out \t");
2622*e4b17023SJohn Marino   df_print_word_regset (file, &bb_info->out);
2623*e4b17023SJohn Marino }
2624*e4b17023SJohn Marino 
2625*e4b17023SJohn Marino 
2626*e4b17023SJohn Marino /* All of the information associated with every instance of the problem.  */
2627*e4b17023SJohn Marino 
2628*e4b17023SJohn Marino static struct df_problem problem_WORD_LR =
2629*e4b17023SJohn Marino {
2630*e4b17023SJohn Marino   DF_WORD_LR,                      /* Problem id.  */
2631*e4b17023SJohn Marino   DF_BACKWARD,                     /* Direction.  */
2632*e4b17023SJohn Marino   df_word_lr_alloc,                /* Allocate the problem specific data.  */
2633*e4b17023SJohn Marino   df_word_lr_reset,                /* Reset global information.  */
2634*e4b17023SJohn Marino   df_word_lr_free_bb_info,         /* Free basic block info.  */
2635*e4b17023SJohn Marino   df_word_lr_local_compute,        /* Local compute function.  */
2636*e4b17023SJohn Marino   df_word_lr_init,                 /* Init the solution specific data.  */
2637*e4b17023SJohn Marino   df_worklist_dataflow,            /* Worklist solver.  */
2638*e4b17023SJohn Marino   NULL,                            /* Confluence operator 0.  */
2639*e4b17023SJohn Marino   df_word_lr_confluence_n,         /* Confluence operator n.  */
2640*e4b17023SJohn Marino   df_word_lr_transfer_function,    /* Transfer function.  */
2641*e4b17023SJohn Marino   NULL,                            /* Finalize function.  */
2642*e4b17023SJohn Marino   df_word_lr_free,                 /* Free all of the problem information.  */
2643*e4b17023SJohn Marino   df_word_lr_free,                 /* Remove this problem from the stack of dataflow problems.  */
2644*e4b17023SJohn Marino   NULL,                            /* Debugging.  */
2645*e4b17023SJohn Marino   df_word_lr_top_dump,             /* Debugging start block.  */
2646*e4b17023SJohn Marino   df_word_lr_bottom_dump,          /* Debugging end block.  */
2647*e4b17023SJohn Marino   NULL,                            /* Incremental solution verify start.  */
2648*e4b17023SJohn Marino   NULL,                            /* Incremental solution verify end.  */
2649*e4b17023SJohn Marino   NULL,                       /* Dependent problem.  */
2650*e4b17023SJohn Marino   sizeof (struct df_word_lr_bb_info),/* Size of entry of block_info array.  */
2651*e4b17023SJohn Marino   TV_DF_WORD_LR,                   /* Timing variable.  */
2652*e4b17023SJohn Marino   false                            /* Reset blocks on dropping out of blocks_to_analyze.  */
2653*e4b17023SJohn Marino };
2654*e4b17023SJohn Marino 
2655*e4b17023SJohn Marino 
2656*e4b17023SJohn Marino /* Create a new DATAFLOW instance and add it to an existing instance
2657*e4b17023SJohn Marino    of DF.  The returned structure is what is used to get at the
2658*e4b17023SJohn Marino    solution.  */
2659*e4b17023SJohn Marino 
2660*e4b17023SJohn Marino void
df_word_lr_add_problem(void)2661*e4b17023SJohn Marino df_word_lr_add_problem (void)
2662*e4b17023SJohn Marino {
2663*e4b17023SJohn Marino   df_add_problem (&problem_WORD_LR);
2664*e4b17023SJohn Marino   /* These will be initialized when df_scan_blocks processes each
2665*e4b17023SJohn Marino      block.  */
2666*e4b17023SJohn Marino   df_word_lr->out_of_date_transfer_functions = BITMAP_ALLOC (NULL);
2667*e4b17023SJohn Marino }
2668*e4b17023SJohn Marino 
2669*e4b17023SJohn Marino 
2670*e4b17023SJohn Marino /* Simulate the effects of the defs of INSN on LIVE.  Return true if we changed
2671*e4b17023SJohn Marino    any bits, which is used by the caller to determine whether a set is
2672*e4b17023SJohn Marino    necessary.  We also return true if there are other reasons not to delete
2673*e4b17023SJohn Marino    an insn.  */
2674*e4b17023SJohn Marino 
2675*e4b17023SJohn Marino bool
df_word_lr_simulate_defs(rtx insn,bitmap live)2676*e4b17023SJohn Marino df_word_lr_simulate_defs (rtx insn, bitmap live)
2677*e4b17023SJohn Marino {
2678*e4b17023SJohn Marino   bool changed = false;
2679*e4b17023SJohn Marino   df_ref *def_rec;
2680*e4b17023SJohn Marino   unsigned int uid = INSN_UID (insn);
2681*e4b17023SJohn Marino 
2682*e4b17023SJohn Marino   for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
2683*e4b17023SJohn Marino     {
2684*e4b17023SJohn Marino       df_ref def = *def_rec;
2685*e4b17023SJohn Marino       if (DF_REF_FLAGS (def) & DF_REF_CONDITIONAL)
2686*e4b17023SJohn Marino 	changed = true;
2687*e4b17023SJohn Marino       else
2688*e4b17023SJohn Marino 	changed |= df_word_lr_mark_ref (*def_rec, false, live);
2689*e4b17023SJohn Marino     }
2690*e4b17023SJohn Marino   return changed;
2691*e4b17023SJohn Marino }
2692*e4b17023SJohn Marino 
2693*e4b17023SJohn Marino 
2694*e4b17023SJohn Marino /* Simulate the effects of the uses of INSN on LIVE.  */
2695*e4b17023SJohn Marino 
2696*e4b17023SJohn Marino void
df_word_lr_simulate_uses(rtx insn,bitmap live)2697*e4b17023SJohn Marino df_word_lr_simulate_uses (rtx insn, bitmap live)
2698*e4b17023SJohn Marino {
2699*e4b17023SJohn Marino   df_ref *use_rec;
2700*e4b17023SJohn Marino   unsigned int uid = INSN_UID (insn);
2701*e4b17023SJohn Marino 
2702*e4b17023SJohn Marino   for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
2703*e4b17023SJohn Marino     df_word_lr_mark_ref (*use_rec, true, live);
2704*e4b17023SJohn Marino }
2705*e4b17023SJohn Marino 
2706*e4b17023SJohn Marino /*----------------------------------------------------------------------------
2707*e4b17023SJohn Marino    This problem computes REG_DEAD and REG_UNUSED notes.
2708*e4b17023SJohn Marino    ----------------------------------------------------------------------------*/
2709*e4b17023SJohn Marino 
2710*e4b17023SJohn Marino static void
df_note_alloc(bitmap all_blocks ATTRIBUTE_UNUSED)2711*e4b17023SJohn Marino df_note_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
2712*e4b17023SJohn Marino {
2713*e4b17023SJohn Marino   df_note->optional_p = true;
2714*e4b17023SJohn Marino }
2715*e4b17023SJohn Marino 
2716*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
2717*e4b17023SJohn Marino static void
df_print_note(const char * prefix,rtx insn,rtx note)2718*e4b17023SJohn Marino df_print_note (const char *prefix, rtx insn, rtx note)
2719*e4b17023SJohn Marino {
2720*e4b17023SJohn Marino   if (dump_file)
2721*e4b17023SJohn Marino     {
2722*e4b17023SJohn Marino       fprintf (dump_file, "%s %d ", prefix, INSN_UID (insn));
2723*e4b17023SJohn Marino       print_rtl (dump_file, note);
2724*e4b17023SJohn Marino       fprintf (dump_file, "\n");
2725*e4b17023SJohn Marino     }
2726*e4b17023SJohn Marino }
2727*e4b17023SJohn Marino #endif
2728*e4b17023SJohn Marino 
2729*e4b17023SJohn Marino 
2730*e4b17023SJohn Marino /* After reg-stack, the x86 floating point stack regs are difficult to
2731*e4b17023SJohn Marino    analyze because of all of the pushes, pops and rotations.  Thus, we
2732*e4b17023SJohn Marino    just leave the notes alone. */
2733*e4b17023SJohn Marino 
2734*e4b17023SJohn Marino #ifdef STACK_REGS
2735*e4b17023SJohn Marino static inline bool
df_ignore_stack_reg(int regno)2736*e4b17023SJohn Marino df_ignore_stack_reg (int regno)
2737*e4b17023SJohn Marino {
2738*e4b17023SJohn Marino   return regstack_completed
2739*e4b17023SJohn Marino     && IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG);
2740*e4b17023SJohn Marino }
2741*e4b17023SJohn Marino #else
2742*e4b17023SJohn Marino static inline bool
df_ignore_stack_reg(int regno ATTRIBUTE_UNUSED)2743*e4b17023SJohn Marino df_ignore_stack_reg (int regno ATTRIBUTE_UNUSED)
2744*e4b17023SJohn Marino {
2745*e4b17023SJohn Marino   return false;
2746*e4b17023SJohn Marino }
2747*e4b17023SJohn Marino #endif
2748*e4b17023SJohn Marino 
2749*e4b17023SJohn Marino 
2750*e4b17023SJohn Marino /* Remove all of the REG_DEAD or REG_UNUSED notes from INSN and add
2751*e4b17023SJohn Marino    them to OLD_DEAD_NOTES and OLD_UNUSED_NOTES.  Remove also
2752*e4b17023SJohn Marino    REG_EQUAL/REG_EQUIV notes referring to dead pseudos using LIVE
2753*e4b17023SJohn Marino    as the bitmap of currently live registers.  */
2754*e4b17023SJohn Marino 
2755*e4b17023SJohn Marino static void
df_kill_notes(rtx insn,bitmap live)2756*e4b17023SJohn Marino df_kill_notes (rtx insn, bitmap live)
2757*e4b17023SJohn Marino {
2758*e4b17023SJohn Marino   rtx *pprev = &REG_NOTES (insn);
2759*e4b17023SJohn Marino   rtx link = *pprev;
2760*e4b17023SJohn Marino 
2761*e4b17023SJohn Marino   while (link)
2762*e4b17023SJohn Marino     {
2763*e4b17023SJohn Marino       switch (REG_NOTE_KIND (link))
2764*e4b17023SJohn Marino 	{
2765*e4b17023SJohn Marino 	case REG_DEAD:
2766*e4b17023SJohn Marino 	  /* After reg-stack, we need to ignore any unused notes
2767*e4b17023SJohn Marino 	     for the stack registers.  */
2768*e4b17023SJohn Marino 	  if (df_ignore_stack_reg (REGNO (XEXP (link, 0))))
2769*e4b17023SJohn Marino 	    {
2770*e4b17023SJohn Marino 	      pprev = &XEXP (link, 1);
2771*e4b17023SJohn Marino 	      link = *pprev;
2772*e4b17023SJohn Marino 	    }
2773*e4b17023SJohn Marino 	  else
2774*e4b17023SJohn Marino 	    {
2775*e4b17023SJohn Marino 	      rtx next = XEXP (link, 1);
2776*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
2777*e4b17023SJohn Marino 	      df_print_note ("deleting: ", insn, link);
2778*e4b17023SJohn Marino #endif
2779*e4b17023SJohn Marino 	      free_EXPR_LIST_node (link);
2780*e4b17023SJohn Marino 	      *pprev = link = next;
2781*e4b17023SJohn Marino 	    }
2782*e4b17023SJohn Marino 	  break;
2783*e4b17023SJohn Marino 
2784*e4b17023SJohn Marino 	case REG_UNUSED:
2785*e4b17023SJohn Marino 	  /* After reg-stack, we need to ignore any unused notes
2786*e4b17023SJohn Marino 	     for the stack registers.  */
2787*e4b17023SJohn Marino 	  if (df_ignore_stack_reg (REGNO (XEXP (link, 0))))
2788*e4b17023SJohn Marino 	    {
2789*e4b17023SJohn Marino 	      pprev = &XEXP (link, 1);
2790*e4b17023SJohn Marino 	      link = *pprev;
2791*e4b17023SJohn Marino 	    }
2792*e4b17023SJohn Marino 	  else
2793*e4b17023SJohn Marino 	    {
2794*e4b17023SJohn Marino 	      rtx next = XEXP (link, 1);
2795*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
2796*e4b17023SJohn Marino 	      df_print_note ("deleting: ", insn, link);
2797*e4b17023SJohn Marino #endif
2798*e4b17023SJohn Marino 	      free_EXPR_LIST_node (link);
2799*e4b17023SJohn Marino 	      *pprev = link = next;
2800*e4b17023SJohn Marino 	    }
2801*e4b17023SJohn Marino 	  break;
2802*e4b17023SJohn Marino 
2803*e4b17023SJohn Marino 	case REG_EQUAL:
2804*e4b17023SJohn Marino 	case REG_EQUIV:
2805*e4b17023SJohn Marino 	  {
2806*e4b17023SJohn Marino 	    /* Remove the notes that refer to dead registers.  As we have at most
2807*e4b17023SJohn Marino 	       one REG_EQUAL/EQUIV note, all of EQ_USES will refer to this note
2808*e4b17023SJohn Marino 	       so we need to purge the complete EQ_USES vector when removing
2809*e4b17023SJohn Marino 	       the note using df_notes_rescan.  */
2810*e4b17023SJohn Marino 	    df_ref *use_rec;
2811*e4b17023SJohn Marino 	    bool deleted = false;
2812*e4b17023SJohn Marino 
2813*e4b17023SJohn Marino 	    for (use_rec = DF_INSN_EQ_USES (insn); *use_rec; use_rec++)
2814*e4b17023SJohn Marino 	      {
2815*e4b17023SJohn Marino 		df_ref use = *use_rec;
2816*e4b17023SJohn Marino 		if (DF_REF_REGNO (use) > FIRST_PSEUDO_REGISTER
2817*e4b17023SJohn Marino 		    && DF_REF_LOC (use)
2818*e4b17023SJohn Marino 		    && (DF_REF_FLAGS (use) & DF_REF_IN_NOTE)
2819*e4b17023SJohn Marino 		    && ! bitmap_bit_p (live, DF_REF_REGNO (use))
2820*e4b17023SJohn Marino 		    && loc_mentioned_in_p (DF_REF_LOC (use), XEXP (link, 0)))
2821*e4b17023SJohn Marino 		  {
2822*e4b17023SJohn Marino 		    deleted = true;
2823*e4b17023SJohn Marino 		    break;
2824*e4b17023SJohn Marino 		  }
2825*e4b17023SJohn Marino 	      }
2826*e4b17023SJohn Marino 	    if (deleted)
2827*e4b17023SJohn Marino 	      {
2828*e4b17023SJohn Marino 		rtx next;
2829*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
2830*e4b17023SJohn Marino 		df_print_note ("deleting: ", insn, link);
2831*e4b17023SJohn Marino #endif
2832*e4b17023SJohn Marino 		next = XEXP (link, 1);
2833*e4b17023SJohn Marino 		free_EXPR_LIST_node (link);
2834*e4b17023SJohn Marino 		*pprev = link = next;
2835*e4b17023SJohn Marino 		df_notes_rescan (insn);
2836*e4b17023SJohn Marino 	      }
2837*e4b17023SJohn Marino 	    else
2838*e4b17023SJohn Marino 	      {
2839*e4b17023SJohn Marino 		pprev = &XEXP (link, 1);
2840*e4b17023SJohn Marino 		link = *pprev;
2841*e4b17023SJohn Marino 	      }
2842*e4b17023SJohn Marino 	    break;
2843*e4b17023SJohn Marino 	  }
2844*e4b17023SJohn Marino 	default:
2845*e4b17023SJohn Marino 	  pprev = &XEXP (link, 1);
2846*e4b17023SJohn Marino 	  link = *pprev;
2847*e4b17023SJohn Marino 	  break;
2848*e4b17023SJohn Marino 	}
2849*e4b17023SJohn Marino     }
2850*e4b17023SJohn Marino }
2851*e4b17023SJohn Marino 
2852*e4b17023SJohn Marino 
2853*e4b17023SJohn Marino /* Set a NOTE_TYPE note for REG in INSN.  */
2854*e4b17023SJohn Marino 
2855*e4b17023SJohn Marino static inline void
df_set_note(enum reg_note note_type,rtx insn,rtx reg)2856*e4b17023SJohn Marino df_set_note (enum reg_note note_type, rtx insn, rtx reg)
2857*e4b17023SJohn Marino {
2858*e4b17023SJohn Marino   gcc_checking_assert (!DEBUG_INSN_P (insn));
2859*e4b17023SJohn Marino   add_reg_note (insn, note_type, reg);
2860*e4b17023SJohn Marino }
2861*e4b17023SJohn Marino 
2862*e4b17023SJohn Marino /* A subroutine of df_set_unused_notes_for_mw, with a selection of its
2863*e4b17023SJohn Marino    arguments.  Return true if the register value described by MWS's
2864*e4b17023SJohn Marino    mw_reg is known to be completely unused, and if mw_reg can therefore
2865*e4b17023SJohn Marino    be used in a REG_UNUSED note.  */
2866*e4b17023SJohn Marino 
2867*e4b17023SJohn Marino static bool
df_whole_mw_reg_unused_p(struct df_mw_hardreg * mws,bitmap live,bitmap artificial_uses)2868*e4b17023SJohn Marino df_whole_mw_reg_unused_p (struct df_mw_hardreg *mws,
2869*e4b17023SJohn Marino 			  bitmap live, bitmap artificial_uses)
2870*e4b17023SJohn Marino {
2871*e4b17023SJohn Marino   unsigned int r;
2872*e4b17023SJohn Marino 
2873*e4b17023SJohn Marino   /* If MWS describes a partial reference, create REG_UNUSED notes for
2874*e4b17023SJohn Marino      individual hard registers.  */
2875*e4b17023SJohn Marino   if (mws->flags & DF_REF_PARTIAL)
2876*e4b17023SJohn Marino     return false;
2877*e4b17023SJohn Marino 
2878*e4b17023SJohn Marino   /* Likewise if some part of the register is used.  */
2879*e4b17023SJohn Marino   for (r = mws->start_regno; r <= mws->end_regno; r++)
2880*e4b17023SJohn Marino     if (bitmap_bit_p (live, r)
2881*e4b17023SJohn Marino 	|| bitmap_bit_p (artificial_uses, r))
2882*e4b17023SJohn Marino       return false;
2883*e4b17023SJohn Marino 
2884*e4b17023SJohn Marino   gcc_assert (REG_P (mws->mw_reg));
2885*e4b17023SJohn Marino   return true;
2886*e4b17023SJohn Marino }
2887*e4b17023SJohn Marino 
2888*e4b17023SJohn Marino 
2889*e4b17023SJohn Marino /* Node of a linked list of uses of dead REGs in debug insns.  */
2890*e4b17023SJohn Marino struct dead_debug_use
2891*e4b17023SJohn Marino {
2892*e4b17023SJohn Marino   df_ref use;
2893*e4b17023SJohn Marino   struct dead_debug_use *next;
2894*e4b17023SJohn Marino };
2895*e4b17023SJohn Marino 
2896*e4b17023SJohn Marino /* Linked list of the above, with a bitmap of the REGs in the
2897*e4b17023SJohn Marino    list.  */
2898*e4b17023SJohn Marino struct dead_debug
2899*e4b17023SJohn Marino {
2900*e4b17023SJohn Marino   struct dead_debug_use *head;
2901*e4b17023SJohn Marino   bitmap used;
2902*e4b17023SJohn Marino   bitmap to_rescan;
2903*e4b17023SJohn Marino };
2904*e4b17023SJohn Marino 
2905*e4b17023SJohn Marino static void dead_debug_reset (struct dead_debug *, unsigned int);
2906*e4b17023SJohn Marino 
2907*e4b17023SJohn Marino 
2908*e4b17023SJohn Marino /* Set the REG_UNUSED notes for the multiword hardreg defs in INSN
2909*e4b17023SJohn Marino    based on the bits in LIVE.  Do not generate notes for registers in
2910*e4b17023SJohn Marino    artificial uses.  DO_NOT_GEN is updated so that REG_DEAD notes are
2911*e4b17023SJohn Marino    not generated if the reg is both read and written by the
2912*e4b17023SJohn Marino    instruction.
2913*e4b17023SJohn Marino */
2914*e4b17023SJohn Marino 
2915*e4b17023SJohn Marino static void
df_set_unused_notes_for_mw(rtx insn,struct df_mw_hardreg * mws,bitmap live,bitmap do_not_gen,bitmap artificial_uses,struct dead_debug * debug)2916*e4b17023SJohn Marino df_set_unused_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
2917*e4b17023SJohn Marino 			    bitmap live, bitmap do_not_gen,
2918*e4b17023SJohn Marino 			    bitmap artificial_uses,
2919*e4b17023SJohn Marino 			    struct dead_debug *debug)
2920*e4b17023SJohn Marino {
2921*e4b17023SJohn Marino   unsigned int r;
2922*e4b17023SJohn Marino 
2923*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
2924*e4b17023SJohn Marino   if (dump_file)
2925*e4b17023SJohn Marino     fprintf (dump_file, "mw_set_unused looking at mws[%d..%d]\n",
2926*e4b17023SJohn Marino 	     mws->start_regno, mws->end_regno);
2927*e4b17023SJohn Marino #endif
2928*e4b17023SJohn Marino 
2929*e4b17023SJohn Marino   if (df_whole_mw_reg_unused_p (mws, live, artificial_uses))
2930*e4b17023SJohn Marino     {
2931*e4b17023SJohn Marino       unsigned int regno = mws->start_regno;
2932*e4b17023SJohn Marino       df_set_note (REG_UNUSED, insn, mws->mw_reg);
2933*e4b17023SJohn Marino       dead_debug_reset (debug, regno);
2934*e4b17023SJohn Marino 
2935*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
2936*e4b17023SJohn Marino       df_print_note ("adding 1: ", insn, REG_NOTES (insn));
2937*e4b17023SJohn Marino #endif
2938*e4b17023SJohn Marino       bitmap_set_bit (do_not_gen, regno);
2939*e4b17023SJohn Marino       /* Only do this if the value is totally dead.  */
2940*e4b17023SJohn Marino     }
2941*e4b17023SJohn Marino   else
2942*e4b17023SJohn Marino     for (r = mws->start_regno; r <= mws->end_regno; r++)
2943*e4b17023SJohn Marino       {
2944*e4b17023SJohn Marino 	if (!bitmap_bit_p (live, r)
2945*e4b17023SJohn Marino 	    && !bitmap_bit_p (artificial_uses, r))
2946*e4b17023SJohn Marino 	  {
2947*e4b17023SJohn Marino 	    df_set_note (REG_UNUSED, insn, regno_reg_rtx[r]);
2948*e4b17023SJohn Marino 	    dead_debug_reset (debug, r);
2949*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
2950*e4b17023SJohn Marino 	    df_print_note ("adding 2: ", insn, REG_NOTES (insn));
2951*e4b17023SJohn Marino #endif
2952*e4b17023SJohn Marino 	  }
2953*e4b17023SJohn Marino 	bitmap_set_bit (do_not_gen, r);
2954*e4b17023SJohn Marino       }
2955*e4b17023SJohn Marino }
2956*e4b17023SJohn Marino 
2957*e4b17023SJohn Marino 
2958*e4b17023SJohn Marino /* A subroutine of df_set_dead_notes_for_mw, with a selection of its
2959*e4b17023SJohn Marino    arguments.  Return true if the register value described by MWS's
2960*e4b17023SJohn Marino    mw_reg is known to be completely dead, and if mw_reg can therefore
2961*e4b17023SJohn Marino    be used in a REG_DEAD note.  */
2962*e4b17023SJohn Marino 
2963*e4b17023SJohn Marino static bool
df_whole_mw_reg_dead_p(struct df_mw_hardreg * mws,bitmap live,bitmap artificial_uses,bitmap do_not_gen)2964*e4b17023SJohn Marino df_whole_mw_reg_dead_p (struct df_mw_hardreg *mws,
2965*e4b17023SJohn Marino 			bitmap live, bitmap artificial_uses,
2966*e4b17023SJohn Marino 			bitmap do_not_gen)
2967*e4b17023SJohn Marino {
2968*e4b17023SJohn Marino   unsigned int r;
2969*e4b17023SJohn Marino 
2970*e4b17023SJohn Marino   /* If MWS describes a partial reference, create REG_DEAD notes for
2971*e4b17023SJohn Marino      individual hard registers.  */
2972*e4b17023SJohn Marino   if (mws->flags & DF_REF_PARTIAL)
2973*e4b17023SJohn Marino     return false;
2974*e4b17023SJohn Marino 
2975*e4b17023SJohn Marino   /* Likewise if some part of the register is not dead.  */
2976*e4b17023SJohn Marino   for (r = mws->start_regno; r <= mws->end_regno; r++)
2977*e4b17023SJohn Marino     if (bitmap_bit_p (live, r)
2978*e4b17023SJohn Marino 	|| bitmap_bit_p (artificial_uses, r)
2979*e4b17023SJohn Marino 	|| bitmap_bit_p (do_not_gen, r))
2980*e4b17023SJohn Marino       return false;
2981*e4b17023SJohn Marino 
2982*e4b17023SJohn Marino   gcc_assert (REG_P (mws->mw_reg));
2983*e4b17023SJohn Marino   return true;
2984*e4b17023SJohn Marino }
2985*e4b17023SJohn Marino 
2986*e4b17023SJohn Marino /* Set the REG_DEAD notes for the multiword hardreg use in INSN based
2987*e4b17023SJohn Marino    on the bits in LIVE.  DO_NOT_GEN is used to keep REG_DEAD notes
2988*e4b17023SJohn Marino    from being set if the instruction both reads and writes the
2989*e4b17023SJohn Marino    register.  */
2990*e4b17023SJohn Marino 
2991*e4b17023SJohn Marino static void
df_set_dead_notes_for_mw(rtx insn,struct df_mw_hardreg * mws,bitmap live,bitmap do_not_gen,bitmap artificial_uses,bool * added_notes_p)2992*e4b17023SJohn Marino df_set_dead_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
2993*e4b17023SJohn Marino 			  bitmap live, bitmap do_not_gen,
2994*e4b17023SJohn Marino 			  bitmap artificial_uses, bool *added_notes_p)
2995*e4b17023SJohn Marino {
2996*e4b17023SJohn Marino   unsigned int r;
2997*e4b17023SJohn Marino   bool is_debug = *added_notes_p;
2998*e4b17023SJohn Marino 
2999*e4b17023SJohn Marino   *added_notes_p = false;
3000*e4b17023SJohn Marino 
3001*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
3002*e4b17023SJohn Marino   if (dump_file)
3003*e4b17023SJohn Marino     {
3004*e4b17023SJohn Marino       fprintf (dump_file, "mw_set_dead looking at mws[%d..%d]\n  do_not_gen =",
3005*e4b17023SJohn Marino 	       mws->start_regno, mws->end_regno);
3006*e4b17023SJohn Marino       df_print_regset (dump_file, do_not_gen);
3007*e4b17023SJohn Marino       fprintf (dump_file, "  live =");
3008*e4b17023SJohn Marino       df_print_regset (dump_file, live);
3009*e4b17023SJohn Marino       fprintf (dump_file, "  artificial uses =");
3010*e4b17023SJohn Marino       df_print_regset (dump_file, artificial_uses);
3011*e4b17023SJohn Marino     }
3012*e4b17023SJohn Marino #endif
3013*e4b17023SJohn Marino 
3014*e4b17023SJohn Marino   if (df_whole_mw_reg_dead_p (mws, live, artificial_uses, do_not_gen))
3015*e4b17023SJohn Marino     {
3016*e4b17023SJohn Marino       /* Add a dead note for the entire multi word register.  */
3017*e4b17023SJohn Marino       if (is_debug)
3018*e4b17023SJohn Marino 	{
3019*e4b17023SJohn Marino 	  *added_notes_p = true;
3020*e4b17023SJohn Marino 	  return;
3021*e4b17023SJohn Marino 	}
3022*e4b17023SJohn Marino       df_set_note (REG_DEAD, insn, mws->mw_reg);
3023*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
3024*e4b17023SJohn Marino       df_print_note ("adding 1: ", insn, REG_NOTES (insn));
3025*e4b17023SJohn Marino #endif
3026*e4b17023SJohn Marino     }
3027*e4b17023SJohn Marino   else
3028*e4b17023SJohn Marino     {
3029*e4b17023SJohn Marino       for (r = mws->start_regno; r <= mws->end_regno; r++)
3030*e4b17023SJohn Marino 	if (!bitmap_bit_p (live, r)
3031*e4b17023SJohn Marino 	    && !bitmap_bit_p (artificial_uses, r)
3032*e4b17023SJohn Marino 	    && !bitmap_bit_p (do_not_gen, r))
3033*e4b17023SJohn Marino 	  {
3034*e4b17023SJohn Marino 	    if (is_debug)
3035*e4b17023SJohn Marino 	      {
3036*e4b17023SJohn Marino 		*added_notes_p = true;
3037*e4b17023SJohn Marino 		return;
3038*e4b17023SJohn Marino 	      }
3039*e4b17023SJohn Marino 	    df_set_note (REG_DEAD, insn, regno_reg_rtx[r]);
3040*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
3041*e4b17023SJohn Marino 	    df_print_note ("adding 2: ", insn, REG_NOTES (insn));
3042*e4b17023SJohn Marino #endif
3043*e4b17023SJohn Marino 	  }
3044*e4b17023SJohn Marino     }
3045*e4b17023SJohn Marino   return;
3046*e4b17023SJohn Marino }
3047*e4b17023SJohn Marino 
3048*e4b17023SJohn Marino 
3049*e4b17023SJohn Marino /* Create a REG_UNUSED note if necessary for DEF in INSN updating
3050*e4b17023SJohn Marino    LIVE.  Do not generate notes for registers in ARTIFICIAL_USES.  */
3051*e4b17023SJohn Marino 
3052*e4b17023SJohn Marino static void
df_create_unused_note(rtx insn,df_ref def,bitmap live,bitmap artificial_uses,struct dead_debug * debug)3053*e4b17023SJohn Marino df_create_unused_note (rtx insn, df_ref def,
3054*e4b17023SJohn Marino 		       bitmap live, bitmap artificial_uses,
3055*e4b17023SJohn Marino 		       struct dead_debug *debug)
3056*e4b17023SJohn Marino {
3057*e4b17023SJohn Marino   unsigned int dregno = DF_REF_REGNO (def);
3058*e4b17023SJohn Marino 
3059*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
3060*e4b17023SJohn Marino   if (dump_file)
3061*e4b17023SJohn Marino     {
3062*e4b17023SJohn Marino       fprintf (dump_file, "  regular looking at def ");
3063*e4b17023SJohn Marino       df_ref_debug (def, dump_file);
3064*e4b17023SJohn Marino     }
3065*e4b17023SJohn Marino #endif
3066*e4b17023SJohn Marino 
3067*e4b17023SJohn Marino   if (!((DF_REF_FLAGS (def) & DF_REF_MW_HARDREG)
3068*e4b17023SJohn Marino 	|| bitmap_bit_p (live, dregno)
3069*e4b17023SJohn Marino 	|| bitmap_bit_p (artificial_uses, dregno)
3070*e4b17023SJohn Marino 	|| df_ignore_stack_reg (dregno)))
3071*e4b17023SJohn Marino     {
3072*e4b17023SJohn Marino       rtx reg = (DF_REF_LOC (def))
3073*e4b17023SJohn Marino                 ? *DF_REF_REAL_LOC (def): DF_REF_REG (def);
3074*e4b17023SJohn Marino       df_set_note (REG_UNUSED, insn, reg);
3075*e4b17023SJohn Marino       dead_debug_reset (debug, dregno);
3076*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
3077*e4b17023SJohn Marino       df_print_note ("adding 3: ", insn, REG_NOTES (insn));
3078*e4b17023SJohn Marino #endif
3079*e4b17023SJohn Marino     }
3080*e4b17023SJohn Marino 
3081*e4b17023SJohn Marino   return;
3082*e4b17023SJohn Marino }
3083*e4b17023SJohn Marino 
3084*e4b17023SJohn Marino 
3085*e4b17023SJohn Marino /* Initialize DEBUG to an empty list, and clear USED, if given.  */
3086*e4b17023SJohn Marino static inline void
dead_debug_init(struct dead_debug * debug,bitmap used)3087*e4b17023SJohn Marino dead_debug_init (struct dead_debug *debug, bitmap used)
3088*e4b17023SJohn Marino {
3089*e4b17023SJohn Marino   debug->head = NULL;
3090*e4b17023SJohn Marino   debug->used = used;
3091*e4b17023SJohn Marino   debug->to_rescan = NULL;
3092*e4b17023SJohn Marino   if (used)
3093*e4b17023SJohn Marino     bitmap_clear (used);
3094*e4b17023SJohn Marino }
3095*e4b17023SJohn Marino 
3096*e4b17023SJohn Marino /* Reset all debug insns with pending uses.  Release the bitmap in it,
3097*e4b17023SJohn Marino    unless it is USED.  USED must be the same bitmap passed to
3098*e4b17023SJohn Marino    dead_debug_init.  */
3099*e4b17023SJohn Marino static inline void
dead_debug_finish(struct dead_debug * debug,bitmap used)3100*e4b17023SJohn Marino dead_debug_finish (struct dead_debug *debug, bitmap used)
3101*e4b17023SJohn Marino {
3102*e4b17023SJohn Marino   struct dead_debug_use *head;
3103*e4b17023SJohn Marino   rtx insn = NULL;
3104*e4b17023SJohn Marino 
3105*e4b17023SJohn Marino   if (debug->used != used)
3106*e4b17023SJohn Marino     BITMAP_FREE (debug->used);
3107*e4b17023SJohn Marino 
3108*e4b17023SJohn Marino   while ((head = debug->head))
3109*e4b17023SJohn Marino     {
3110*e4b17023SJohn Marino       insn = DF_REF_INSN (head->use);
3111*e4b17023SJohn Marino       if (!head->next || DF_REF_INSN (head->next->use) != insn)
3112*e4b17023SJohn Marino 	{
3113*e4b17023SJohn Marino 	  INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
3114*e4b17023SJohn Marino 	  df_insn_rescan_debug_internal (insn);
3115*e4b17023SJohn Marino 	  if (debug->to_rescan)
3116*e4b17023SJohn Marino 	    bitmap_clear_bit (debug->to_rescan, INSN_UID (insn));
3117*e4b17023SJohn Marino 	}
3118*e4b17023SJohn Marino       debug->head = head->next;
3119*e4b17023SJohn Marino       XDELETE (head);
3120*e4b17023SJohn Marino     }
3121*e4b17023SJohn Marino 
3122*e4b17023SJohn Marino   if (debug->to_rescan)
3123*e4b17023SJohn Marino     {
3124*e4b17023SJohn Marino       bitmap_iterator bi;
3125*e4b17023SJohn Marino       unsigned int uid;
3126*e4b17023SJohn Marino 
3127*e4b17023SJohn Marino       EXECUTE_IF_SET_IN_BITMAP (debug->to_rescan, 0, uid, bi)
3128*e4b17023SJohn Marino 	{
3129*e4b17023SJohn Marino 	  struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
3130*e4b17023SJohn Marino 	  if (insn_info)
3131*e4b17023SJohn Marino 	    df_insn_rescan (insn_info->insn);
3132*e4b17023SJohn Marino 	}
3133*e4b17023SJohn Marino       BITMAP_FREE (debug->to_rescan);
3134*e4b17023SJohn Marino     }
3135*e4b17023SJohn Marino }
3136*e4b17023SJohn Marino 
3137*e4b17023SJohn Marino /* Reset DEBUG_INSNs with pending uses of DREGNO.  */
3138*e4b17023SJohn Marino static void
dead_debug_reset(struct dead_debug * debug,unsigned int dregno)3139*e4b17023SJohn Marino dead_debug_reset (struct dead_debug *debug, unsigned int dregno)
3140*e4b17023SJohn Marino {
3141*e4b17023SJohn Marino   struct dead_debug_use **tailp = &debug->head;
3142*e4b17023SJohn Marino   struct dead_debug_use **insnp = &debug->head;
3143*e4b17023SJohn Marino   struct dead_debug_use *cur;
3144*e4b17023SJohn Marino   rtx insn;
3145*e4b17023SJohn Marino 
3146*e4b17023SJohn Marino   if (!debug->used || !bitmap_clear_bit (debug->used, dregno))
3147*e4b17023SJohn Marino     return;
3148*e4b17023SJohn Marino 
3149*e4b17023SJohn Marino   while ((cur = *tailp))
3150*e4b17023SJohn Marino     {
3151*e4b17023SJohn Marino       if (DF_REF_REGNO (cur->use) == dregno)
3152*e4b17023SJohn Marino 	{
3153*e4b17023SJohn Marino 	  *tailp = cur->next;
3154*e4b17023SJohn Marino 	  insn = DF_REF_INSN (cur->use);
3155*e4b17023SJohn Marino 	  INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
3156*e4b17023SJohn Marino 	  if (debug->to_rescan == NULL)
3157*e4b17023SJohn Marino 	    debug->to_rescan = BITMAP_ALLOC (NULL);
3158*e4b17023SJohn Marino 	  bitmap_set_bit (debug->to_rescan, INSN_UID (insn));
3159*e4b17023SJohn Marino 	  XDELETE (cur);
3160*e4b17023SJohn Marino 	  /* If the current use isn't the first one attached to INSN, go back
3161*e4b17023SJohn Marino 	     to this first use.  We assume that the uses attached to an insn
3162*e4b17023SJohn Marino 	     are adjacent.  */
3163*e4b17023SJohn Marino 	  if (tailp != insnp && DF_REF_INSN ((*insnp)->use) == insn)
3164*e4b17023SJohn Marino 	    tailp = insnp;
3165*e4b17023SJohn Marino 	  /* Then remove all the other uses attached to INSN.  */
3166*e4b17023SJohn Marino 	  while ((cur = *tailp) && DF_REF_INSN (cur->use) == insn)
3167*e4b17023SJohn Marino 	    {
3168*e4b17023SJohn Marino 	      *tailp = cur->next;
3169*e4b17023SJohn Marino 	      XDELETE (cur);
3170*e4b17023SJohn Marino 	    }
3171*e4b17023SJohn Marino 	  insnp = tailp;
3172*e4b17023SJohn Marino 	}
3173*e4b17023SJohn Marino       else
3174*e4b17023SJohn Marino 	{
3175*e4b17023SJohn Marino 	  if (DF_REF_INSN ((*insnp)->use) != DF_REF_INSN (cur->use))
3176*e4b17023SJohn Marino 	    insnp = tailp;
3177*e4b17023SJohn Marino 	  tailp = &(*tailp)->next;
3178*e4b17023SJohn Marino 	}
3179*e4b17023SJohn Marino     }
3180*e4b17023SJohn Marino }
3181*e4b17023SJohn Marino 
3182*e4b17023SJohn Marino /* Add USE to DEBUG.  It must be a dead reference to UREGNO in a debug
3183*e4b17023SJohn Marino    insn.  Create a bitmap for DEBUG as needed.  */
3184*e4b17023SJohn Marino static inline void
dead_debug_add(struct dead_debug * debug,df_ref use,unsigned int uregno)3185*e4b17023SJohn Marino dead_debug_add (struct dead_debug *debug, df_ref use, unsigned int uregno)
3186*e4b17023SJohn Marino {
3187*e4b17023SJohn Marino   struct dead_debug_use *newddu = XNEW (struct dead_debug_use);
3188*e4b17023SJohn Marino 
3189*e4b17023SJohn Marino   newddu->use = use;
3190*e4b17023SJohn Marino   newddu->next = debug->head;
3191*e4b17023SJohn Marino   debug->head = newddu;
3192*e4b17023SJohn Marino 
3193*e4b17023SJohn Marino   if (!debug->used)
3194*e4b17023SJohn Marino     debug->used = BITMAP_ALLOC (NULL);
3195*e4b17023SJohn Marino 
3196*e4b17023SJohn Marino   bitmap_set_bit (debug->used, uregno);
3197*e4b17023SJohn Marino }
3198*e4b17023SJohn Marino 
3199*e4b17023SJohn Marino /* If UREGNO is referenced by any entry in DEBUG, emit a debug insn
3200*e4b17023SJohn Marino    before INSN that binds the REG to a debug temp, and replace all
3201*e4b17023SJohn Marino    uses of UREGNO in DEBUG with uses of the debug temp.  INSN must be
3202*e4b17023SJohn Marino    the insn where UREGNO dies.  */
3203*e4b17023SJohn Marino static inline void
dead_debug_insert_before(struct dead_debug * debug,unsigned int uregno,rtx insn)3204*e4b17023SJohn Marino dead_debug_insert_before (struct dead_debug *debug, unsigned int uregno,
3205*e4b17023SJohn Marino 			  rtx insn)
3206*e4b17023SJohn Marino {
3207*e4b17023SJohn Marino   struct dead_debug_use **tailp = &debug->head;
3208*e4b17023SJohn Marino   struct dead_debug_use *cur;
3209*e4b17023SJohn Marino   struct dead_debug_use *uses = NULL;
3210*e4b17023SJohn Marino   struct dead_debug_use **usesp = &uses;
3211*e4b17023SJohn Marino   rtx reg = NULL;
3212*e4b17023SJohn Marino   rtx dval;
3213*e4b17023SJohn Marino   rtx bind;
3214*e4b17023SJohn Marino 
3215*e4b17023SJohn Marino   if (!debug->used || !bitmap_clear_bit (debug->used, uregno))
3216*e4b17023SJohn Marino     return;
3217*e4b17023SJohn Marino 
3218*e4b17023SJohn Marino   /* Move all uses of uregno from debug->head to uses, setting mode to
3219*e4b17023SJohn Marino      the widest referenced mode.  */
3220*e4b17023SJohn Marino   while ((cur = *tailp))
3221*e4b17023SJohn Marino     {
3222*e4b17023SJohn Marino       if (DF_REF_REGNO (cur->use) == uregno)
3223*e4b17023SJohn Marino 	{
3224*e4b17023SJohn Marino 	  *usesp = cur;
3225*e4b17023SJohn Marino 	  usesp = &cur->next;
3226*e4b17023SJohn Marino 	  *tailp = cur->next;
3227*e4b17023SJohn Marino 	  cur->next = NULL;
3228*e4b17023SJohn Marino 	  if (!reg
3229*e4b17023SJohn Marino 	      || (GET_MODE_BITSIZE (GET_MODE (reg))
3230*e4b17023SJohn Marino 		  < GET_MODE_BITSIZE (GET_MODE (*DF_REF_REAL_LOC (cur->use)))))
3231*e4b17023SJohn Marino 	    reg = *DF_REF_REAL_LOC (cur->use);
3232*e4b17023SJohn Marino 	}
3233*e4b17023SJohn Marino       else
3234*e4b17023SJohn Marino 	tailp = &(*tailp)->next;
3235*e4b17023SJohn Marino     }
3236*e4b17023SJohn Marino 
3237*e4b17023SJohn Marino   /* We may have dangling bits in debug->used for registers that were part
3238*e4b17023SJohn Marino      of a multi-register use, one component of which has been reset.  */
3239*e4b17023SJohn Marino   if (reg == NULL)
3240*e4b17023SJohn Marino     return;
3241*e4b17023SJohn Marino 
3242*e4b17023SJohn Marino   /* Create DEBUG_EXPR (and DEBUG_EXPR_DECL).  */
3243*e4b17023SJohn Marino   dval = make_debug_expr_from_rtl (reg);
3244*e4b17023SJohn Marino 
3245*e4b17023SJohn Marino   /* Emit a debug bind insn before the insn in which reg dies.  */
3246*e4b17023SJohn Marino   bind = gen_rtx_VAR_LOCATION (GET_MODE (reg),
3247*e4b17023SJohn Marino 			       DEBUG_EXPR_TREE_DECL (dval), reg,
3248*e4b17023SJohn Marino 			       VAR_INIT_STATUS_INITIALIZED);
3249*e4b17023SJohn Marino 
3250*e4b17023SJohn Marino   bind = emit_debug_insn_before (bind, insn);
3251*e4b17023SJohn Marino   df_insn_rescan (bind);
3252*e4b17023SJohn Marino 
3253*e4b17023SJohn Marino   /* Adjust all uses.  */
3254*e4b17023SJohn Marino   while ((cur = uses))
3255*e4b17023SJohn Marino     {
3256*e4b17023SJohn Marino       if (GET_MODE (*DF_REF_REAL_LOC (cur->use)) == GET_MODE (reg))
3257*e4b17023SJohn Marino 	*DF_REF_REAL_LOC (cur->use) = dval;
3258*e4b17023SJohn Marino       else
3259*e4b17023SJohn Marino 	*DF_REF_REAL_LOC (cur->use)
3260*e4b17023SJohn Marino 	  = gen_lowpart_SUBREG (GET_MODE (*DF_REF_REAL_LOC (cur->use)), dval);
3261*e4b17023SJohn Marino       /* ??? Should we simplify subreg of subreg?  */
3262*e4b17023SJohn Marino       if (debug->to_rescan == NULL)
3263*e4b17023SJohn Marino 	debug->to_rescan = BITMAP_ALLOC (NULL);
3264*e4b17023SJohn Marino       bitmap_set_bit (debug->to_rescan, INSN_UID (DF_REF_INSN (cur->use)));
3265*e4b17023SJohn Marino       uses = cur->next;
3266*e4b17023SJohn Marino       XDELETE (cur);
3267*e4b17023SJohn Marino     }
3268*e4b17023SJohn Marino }
3269*e4b17023SJohn Marino 
3270*e4b17023SJohn Marino /* Recompute the REG_DEAD and REG_UNUSED notes and compute register
3271*e4b17023SJohn Marino    info: lifetime, bb, and number of defs and uses for basic block
3272*e4b17023SJohn Marino    BB.  The three bitvectors are scratch regs used here.  */
3273*e4b17023SJohn Marino 
3274*e4b17023SJohn Marino static void
df_note_bb_compute(unsigned int bb_index,bitmap live,bitmap do_not_gen,bitmap artificial_uses)3275*e4b17023SJohn Marino df_note_bb_compute (unsigned int bb_index,
3276*e4b17023SJohn Marino 		    bitmap live, bitmap do_not_gen, bitmap artificial_uses)
3277*e4b17023SJohn Marino {
3278*e4b17023SJohn Marino   basic_block bb = BASIC_BLOCK (bb_index);
3279*e4b17023SJohn Marino   rtx insn;
3280*e4b17023SJohn Marino   df_ref *def_rec;
3281*e4b17023SJohn Marino   df_ref *use_rec;
3282*e4b17023SJohn Marino   struct dead_debug debug;
3283*e4b17023SJohn Marino 
3284*e4b17023SJohn Marino   dead_debug_init (&debug, NULL);
3285*e4b17023SJohn Marino 
3286*e4b17023SJohn Marino   bitmap_copy (live, df_get_live_out (bb));
3287*e4b17023SJohn Marino   bitmap_clear (artificial_uses);
3288*e4b17023SJohn Marino 
3289*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
3290*e4b17023SJohn Marino   if (dump_file)
3291*e4b17023SJohn Marino     {
3292*e4b17023SJohn Marino       fprintf (dump_file, "live at bottom ");
3293*e4b17023SJohn Marino       df_print_regset (dump_file, live);
3294*e4b17023SJohn Marino     }
3295*e4b17023SJohn Marino #endif
3296*e4b17023SJohn Marino 
3297*e4b17023SJohn Marino   /* Process the artificial defs and uses at the bottom of the block
3298*e4b17023SJohn Marino      to begin processing.  */
3299*e4b17023SJohn Marino   for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
3300*e4b17023SJohn Marino     {
3301*e4b17023SJohn Marino       df_ref def = *def_rec;
3302*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
3303*e4b17023SJohn Marino       if (dump_file)
3304*e4b17023SJohn Marino 	fprintf (dump_file, "artificial def %d\n", DF_REF_REGNO (def));
3305*e4b17023SJohn Marino #endif
3306*e4b17023SJohn Marino 
3307*e4b17023SJohn Marino       if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
3308*e4b17023SJohn Marino 	bitmap_clear_bit (live, DF_REF_REGNO (def));
3309*e4b17023SJohn Marino     }
3310*e4b17023SJohn Marino 
3311*e4b17023SJohn Marino   for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
3312*e4b17023SJohn Marino     {
3313*e4b17023SJohn Marino       df_ref use = *use_rec;
3314*e4b17023SJohn Marino       if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
3315*e4b17023SJohn Marino 	{
3316*e4b17023SJohn Marino 	  unsigned int regno = DF_REF_REGNO (use);
3317*e4b17023SJohn Marino 	  bitmap_set_bit (live, regno);
3318*e4b17023SJohn Marino 
3319*e4b17023SJohn Marino 	  /* Notes are not generated for any of the artificial registers
3320*e4b17023SJohn Marino 	     at the bottom of the block.  */
3321*e4b17023SJohn Marino 	  bitmap_set_bit (artificial_uses, regno);
3322*e4b17023SJohn Marino 	}
3323*e4b17023SJohn Marino     }
3324*e4b17023SJohn Marino 
3325*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
3326*e4b17023SJohn Marino   if (dump_file)
3327*e4b17023SJohn Marino     {
3328*e4b17023SJohn Marino       fprintf (dump_file, "live before artificials out ");
3329*e4b17023SJohn Marino       df_print_regset (dump_file, live);
3330*e4b17023SJohn Marino     }
3331*e4b17023SJohn Marino #endif
3332*e4b17023SJohn Marino 
3333*e4b17023SJohn Marino   FOR_BB_INSNS_REVERSE (bb, insn)
3334*e4b17023SJohn Marino     {
3335*e4b17023SJohn Marino       unsigned int uid = INSN_UID (insn);
3336*e4b17023SJohn Marino       struct df_mw_hardreg **mws_rec;
3337*e4b17023SJohn Marino       int debug_insn;
3338*e4b17023SJohn Marino 
3339*e4b17023SJohn Marino       if (!INSN_P (insn))
3340*e4b17023SJohn Marino 	continue;
3341*e4b17023SJohn Marino 
3342*e4b17023SJohn Marino       debug_insn = DEBUG_INSN_P (insn);
3343*e4b17023SJohn Marino 
3344*e4b17023SJohn Marino       bitmap_clear (do_not_gen);
3345*e4b17023SJohn Marino       df_kill_notes (insn, live);
3346*e4b17023SJohn Marino 
3347*e4b17023SJohn Marino       /* Process the defs.  */
3348*e4b17023SJohn Marino       if (CALL_P (insn))
3349*e4b17023SJohn Marino 	{
3350*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
3351*e4b17023SJohn Marino 	  if (dump_file)
3352*e4b17023SJohn Marino 	    {
3353*e4b17023SJohn Marino 	      fprintf (dump_file, "processing call %d\n  live =", INSN_UID (insn));
3354*e4b17023SJohn Marino 	      df_print_regset (dump_file, live);
3355*e4b17023SJohn Marino 	    }
3356*e4b17023SJohn Marino #endif
3357*e4b17023SJohn Marino 	  /* We only care about real sets for calls.  Clobbers cannot
3358*e4b17023SJohn Marino 	     be depended on to really die.  */
3359*e4b17023SJohn Marino 	  mws_rec = DF_INSN_UID_MWS (uid);
3360*e4b17023SJohn Marino 	  while (*mws_rec)
3361*e4b17023SJohn Marino 	    {
3362*e4b17023SJohn Marino 	      struct df_mw_hardreg *mws = *mws_rec;
3363*e4b17023SJohn Marino 	      if ((DF_MWS_REG_DEF_P (mws))
3364*e4b17023SJohn Marino 		  && !df_ignore_stack_reg (mws->start_regno))
3365*e4b17023SJohn Marino 	      df_set_unused_notes_for_mw (insn,
3366*e4b17023SJohn Marino 					  mws, live, do_not_gen,
3367*e4b17023SJohn Marino 					  artificial_uses, &debug);
3368*e4b17023SJohn Marino 	      mws_rec++;
3369*e4b17023SJohn Marino 	    }
3370*e4b17023SJohn Marino 
3371*e4b17023SJohn Marino 	  /* All of the defs except the return value are some sort of
3372*e4b17023SJohn Marino 	     clobber.  This code is for the return.  */
3373*e4b17023SJohn Marino 	  for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
3374*e4b17023SJohn Marino 	    {
3375*e4b17023SJohn Marino 	      df_ref def = *def_rec;
3376*e4b17023SJohn Marino 	      unsigned int dregno = DF_REF_REGNO (def);
3377*e4b17023SJohn Marino 	      if (!DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))
3378*e4b17023SJohn Marino 		{
3379*e4b17023SJohn Marino 		  df_create_unused_note (insn,
3380*e4b17023SJohn Marino 					 def, live, artificial_uses, &debug);
3381*e4b17023SJohn Marino 		  bitmap_set_bit (do_not_gen, dregno);
3382*e4b17023SJohn Marino 		}
3383*e4b17023SJohn Marino 
3384*e4b17023SJohn Marino 	      if (!DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL | DF_REF_CONDITIONAL))
3385*e4b17023SJohn Marino 		bitmap_clear_bit (live, dregno);
3386*e4b17023SJohn Marino 	    }
3387*e4b17023SJohn Marino 	}
3388*e4b17023SJohn Marino       else
3389*e4b17023SJohn Marino 	{
3390*e4b17023SJohn Marino 	  /* Regular insn.  */
3391*e4b17023SJohn Marino 	  mws_rec = DF_INSN_UID_MWS (uid);
3392*e4b17023SJohn Marino 	  while (*mws_rec)
3393*e4b17023SJohn Marino 	    {
3394*e4b17023SJohn Marino 	      struct df_mw_hardreg *mws = *mws_rec;
3395*e4b17023SJohn Marino 	      if (DF_MWS_REG_DEF_P (mws))
3396*e4b17023SJohn Marino 		df_set_unused_notes_for_mw (insn,
3397*e4b17023SJohn Marino 					    mws, live, do_not_gen,
3398*e4b17023SJohn Marino 					    artificial_uses, &debug);
3399*e4b17023SJohn Marino 	      mws_rec++;
3400*e4b17023SJohn Marino 	    }
3401*e4b17023SJohn Marino 
3402*e4b17023SJohn Marino 	  for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
3403*e4b17023SJohn Marino 	    {
3404*e4b17023SJohn Marino 	      df_ref def = *def_rec;
3405*e4b17023SJohn Marino 	      unsigned int dregno = DF_REF_REGNO (def);
3406*e4b17023SJohn Marino 	      df_create_unused_note (insn,
3407*e4b17023SJohn Marino 				     def, live, artificial_uses, &debug);
3408*e4b17023SJohn Marino 
3409*e4b17023SJohn Marino 	      if (!DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))
3410*e4b17023SJohn Marino 		bitmap_set_bit (do_not_gen, dregno);
3411*e4b17023SJohn Marino 
3412*e4b17023SJohn Marino 	      if (!DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL | DF_REF_CONDITIONAL))
3413*e4b17023SJohn Marino 		bitmap_clear_bit (live, dregno);
3414*e4b17023SJohn Marino 	    }
3415*e4b17023SJohn Marino 	}
3416*e4b17023SJohn Marino 
3417*e4b17023SJohn Marino       /* Process the uses.  */
3418*e4b17023SJohn Marino       mws_rec = DF_INSN_UID_MWS (uid);
3419*e4b17023SJohn Marino       while (*mws_rec)
3420*e4b17023SJohn Marino 	{
3421*e4b17023SJohn Marino 	  struct df_mw_hardreg *mws = *mws_rec;
3422*e4b17023SJohn Marino 	  if (DF_MWS_REG_USE_P (mws)
3423*e4b17023SJohn Marino 	      && !df_ignore_stack_reg (mws->start_regno))
3424*e4b17023SJohn Marino 	    {
3425*e4b17023SJohn Marino 	      bool really_add_notes = debug_insn != 0;
3426*e4b17023SJohn Marino 
3427*e4b17023SJohn Marino 	      df_set_dead_notes_for_mw (insn,
3428*e4b17023SJohn Marino 					mws, live, do_not_gen,
3429*e4b17023SJohn Marino 					artificial_uses,
3430*e4b17023SJohn Marino 					&really_add_notes);
3431*e4b17023SJohn Marino 
3432*e4b17023SJohn Marino 	      if (really_add_notes)
3433*e4b17023SJohn Marino 		debug_insn = -1;
3434*e4b17023SJohn Marino 	    }
3435*e4b17023SJohn Marino 	  mws_rec++;
3436*e4b17023SJohn Marino 	}
3437*e4b17023SJohn Marino 
3438*e4b17023SJohn Marino       for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
3439*e4b17023SJohn Marino 	{
3440*e4b17023SJohn Marino 	  df_ref use = *use_rec;
3441*e4b17023SJohn Marino 	  unsigned int uregno = DF_REF_REGNO (use);
3442*e4b17023SJohn Marino 
3443*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
3444*e4b17023SJohn Marino 	  if (dump_file && !debug_insn)
3445*e4b17023SJohn Marino 	    {
3446*e4b17023SJohn Marino 	      fprintf (dump_file, "  regular looking at use ");
3447*e4b17023SJohn Marino 	      df_ref_debug (use, dump_file);
3448*e4b17023SJohn Marino 	    }
3449*e4b17023SJohn Marino #endif
3450*e4b17023SJohn Marino 	  if (!bitmap_bit_p (live, uregno))
3451*e4b17023SJohn Marino 	    {
3452*e4b17023SJohn Marino 	      if (debug_insn)
3453*e4b17023SJohn Marino 		{
3454*e4b17023SJohn Marino 		  if (debug_insn > 0)
3455*e4b17023SJohn Marino 		    {
3456*e4b17023SJohn Marino 		      dead_debug_add (&debug, use, uregno);
3457*e4b17023SJohn Marino 		      continue;
3458*e4b17023SJohn Marino 		    }
3459*e4b17023SJohn Marino 		  break;
3460*e4b17023SJohn Marino 		}
3461*e4b17023SJohn Marino 	      else
3462*e4b17023SJohn Marino 		dead_debug_insert_before (&debug, uregno, insn);
3463*e4b17023SJohn Marino 
3464*e4b17023SJohn Marino 	      if ( (!(DF_REF_FLAGS (use)
3465*e4b17023SJohn Marino 		      & (DF_REF_MW_HARDREG | DF_REF_READ_WRITE)))
3466*e4b17023SJohn Marino 		   && (!bitmap_bit_p (do_not_gen, uregno))
3467*e4b17023SJohn Marino 		   && (!bitmap_bit_p (artificial_uses, uregno))
3468*e4b17023SJohn Marino 		   && (!df_ignore_stack_reg (uregno)))
3469*e4b17023SJohn Marino 		{
3470*e4b17023SJohn Marino 		  rtx reg = (DF_REF_LOC (use))
3471*e4b17023SJohn Marino                             ? *DF_REF_REAL_LOC (use) : DF_REF_REG (use);
3472*e4b17023SJohn Marino 		  df_set_note (REG_DEAD, insn, reg);
3473*e4b17023SJohn Marino 
3474*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
3475*e4b17023SJohn Marino 		  df_print_note ("adding 4: ", insn, REG_NOTES (insn));
3476*e4b17023SJohn Marino #endif
3477*e4b17023SJohn Marino 		}
3478*e4b17023SJohn Marino 	      /* This register is now live.  */
3479*e4b17023SJohn Marino 	      bitmap_set_bit (live, uregno);
3480*e4b17023SJohn Marino 	    }
3481*e4b17023SJohn Marino 	}
3482*e4b17023SJohn Marino 
3483*e4b17023SJohn Marino       if (debug_insn == -1)
3484*e4b17023SJohn Marino 	{
3485*e4b17023SJohn Marino 	  /* ??? We could probably do better here, replacing dead
3486*e4b17023SJohn Marino 	     registers with their definitions.  */
3487*e4b17023SJohn Marino 	  INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
3488*e4b17023SJohn Marino 	  df_insn_rescan_debug_internal (insn);
3489*e4b17023SJohn Marino 	}
3490*e4b17023SJohn Marino     }
3491*e4b17023SJohn Marino 
3492*e4b17023SJohn Marino   dead_debug_finish (&debug, NULL);
3493*e4b17023SJohn Marino }
3494*e4b17023SJohn Marino 
3495*e4b17023SJohn Marino 
3496*e4b17023SJohn Marino /* Compute register info: lifetime, bb, and number of defs and uses.  */
3497*e4b17023SJohn Marino static void
df_note_compute(bitmap all_blocks)3498*e4b17023SJohn Marino df_note_compute (bitmap all_blocks)
3499*e4b17023SJohn Marino {
3500*e4b17023SJohn Marino   unsigned int bb_index;
3501*e4b17023SJohn Marino   bitmap_iterator bi;
3502*e4b17023SJohn Marino   bitmap_head live, do_not_gen, artificial_uses;
3503*e4b17023SJohn Marino 
3504*e4b17023SJohn Marino   bitmap_initialize (&live, &df_bitmap_obstack);
3505*e4b17023SJohn Marino   bitmap_initialize (&do_not_gen, &df_bitmap_obstack);
3506*e4b17023SJohn Marino   bitmap_initialize (&artificial_uses, &df_bitmap_obstack);
3507*e4b17023SJohn Marino 
3508*e4b17023SJohn Marino #ifdef REG_DEAD_DEBUGGING
3509*e4b17023SJohn Marino   if (dump_file)
3510*e4b17023SJohn Marino     print_rtl_with_bb (dump_file, get_insns());
3511*e4b17023SJohn Marino #endif
3512*e4b17023SJohn Marino 
3513*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
3514*e4b17023SJohn Marino   {
3515*e4b17023SJohn Marino     df_note_bb_compute (bb_index, &live, &do_not_gen, &artificial_uses);
3516*e4b17023SJohn Marino   }
3517*e4b17023SJohn Marino 
3518*e4b17023SJohn Marino   bitmap_clear (&live);
3519*e4b17023SJohn Marino   bitmap_clear (&do_not_gen);
3520*e4b17023SJohn Marino   bitmap_clear (&artificial_uses);
3521*e4b17023SJohn Marino }
3522*e4b17023SJohn Marino 
3523*e4b17023SJohn Marino 
3524*e4b17023SJohn Marino /* Free all storage associated with the problem.  */
3525*e4b17023SJohn Marino 
3526*e4b17023SJohn Marino static void
df_note_free(void)3527*e4b17023SJohn Marino df_note_free (void)
3528*e4b17023SJohn Marino {
3529*e4b17023SJohn Marino   free (df_note);
3530*e4b17023SJohn Marino }
3531*e4b17023SJohn Marino 
3532*e4b17023SJohn Marino 
3533*e4b17023SJohn Marino /* All of the information associated every instance of the problem.  */
3534*e4b17023SJohn Marino 
3535*e4b17023SJohn Marino static struct df_problem problem_NOTE =
3536*e4b17023SJohn Marino {
3537*e4b17023SJohn Marino   DF_NOTE,                    /* Problem id.  */
3538*e4b17023SJohn Marino   DF_NONE,                    /* Direction.  */
3539*e4b17023SJohn Marino   df_note_alloc,              /* Allocate the problem specific data.  */
3540*e4b17023SJohn Marino   NULL,                       /* Reset global information.  */
3541*e4b17023SJohn Marino   NULL,                       /* Free basic block info.  */
3542*e4b17023SJohn Marino   df_note_compute,            /* Local compute function.  */
3543*e4b17023SJohn Marino   NULL,                       /* Init the solution specific data.  */
3544*e4b17023SJohn Marino   NULL,                       /* Iterative solver.  */
3545*e4b17023SJohn Marino   NULL,                       /* Confluence operator 0.  */
3546*e4b17023SJohn Marino   NULL,                       /* Confluence operator n.  */
3547*e4b17023SJohn Marino   NULL,                       /* Transfer function.  */
3548*e4b17023SJohn Marino   NULL,                       /* Finalize function.  */
3549*e4b17023SJohn Marino   df_note_free,               /* Free all of the problem information.  */
3550*e4b17023SJohn Marino   df_note_free,               /* Remove this problem from the stack of dataflow problems.  */
3551*e4b17023SJohn Marino   NULL,                       /* Debugging.  */
3552*e4b17023SJohn Marino   NULL,                       /* Debugging start block.  */
3553*e4b17023SJohn Marino   NULL,                       /* Debugging end block.  */
3554*e4b17023SJohn Marino   NULL,                       /* Incremental solution verify start.  */
3555*e4b17023SJohn Marino   NULL,                       /* Incremental solution verify end.  */
3556*e4b17023SJohn Marino   &problem_LR,                /* Dependent problem.  */
3557*e4b17023SJohn Marino   sizeof (struct df_scan_bb_info),/* Size of entry of block_info array.  */
3558*e4b17023SJohn Marino   TV_DF_NOTE,                 /* Timing variable.  */
3559*e4b17023SJohn Marino   false                       /* Reset blocks on dropping out of blocks_to_analyze.  */
3560*e4b17023SJohn Marino };
3561*e4b17023SJohn Marino 
3562*e4b17023SJohn Marino 
3563*e4b17023SJohn Marino /* Create a new DATAFLOW instance and add it to an existing instance
3564*e4b17023SJohn Marino    of DF.  The returned structure is what is used to get at the
3565*e4b17023SJohn Marino    solution.  */
3566*e4b17023SJohn Marino 
3567*e4b17023SJohn Marino void
df_note_add_problem(void)3568*e4b17023SJohn Marino df_note_add_problem (void)
3569*e4b17023SJohn Marino {
3570*e4b17023SJohn Marino   df_add_problem (&problem_NOTE);
3571*e4b17023SJohn Marino }
3572*e4b17023SJohn Marino 
3573*e4b17023SJohn Marino 
3574*e4b17023SJohn Marino 
3575*e4b17023SJohn Marino 
3576*e4b17023SJohn Marino /*----------------------------------------------------------------------------
3577*e4b17023SJohn Marino    Functions for simulating the effects of single insns.
3578*e4b17023SJohn Marino 
3579*e4b17023SJohn Marino    You can either simulate in the forwards direction, starting from
3580*e4b17023SJohn Marino    the top of a block or the backwards direction from the end of the
3581*e4b17023SJohn Marino    block.  If you go backwards, defs are examined first to clear bits,
3582*e4b17023SJohn Marino    then uses are examined to set bits.  If you go forwards, defs are
3583*e4b17023SJohn Marino    examined first to set bits, then REG_DEAD and REG_UNUSED notes
3584*e4b17023SJohn Marino    are examined to clear bits.  In either case, the result of examining
3585*e4b17023SJohn Marino    a def can be undone (respectively by a use or a REG_UNUSED note).
3586*e4b17023SJohn Marino 
3587*e4b17023SJohn Marino    If you start at the top of the block, use one of DF_LIVE_IN or
3588*e4b17023SJohn Marino    DF_LR_IN.  If you start at the bottom of the block use one of
3589*e4b17023SJohn Marino    DF_LIVE_OUT or DF_LR_OUT.  BE SURE TO PASS A COPY OF THESE SETS,
3590*e4b17023SJohn Marino    THEY WILL BE DESTROYED.
3591*e4b17023SJohn Marino ----------------------------------------------------------------------------*/
3592*e4b17023SJohn Marino 
3593*e4b17023SJohn Marino 
3594*e4b17023SJohn Marino /* Find the set of DEFs for INSN.  */
3595*e4b17023SJohn Marino 
3596*e4b17023SJohn Marino void
df_simulate_find_defs(rtx insn,bitmap defs)3597*e4b17023SJohn Marino df_simulate_find_defs (rtx insn, bitmap defs)
3598*e4b17023SJohn Marino {
3599*e4b17023SJohn Marino   df_ref *def_rec;
3600*e4b17023SJohn Marino   unsigned int uid = INSN_UID (insn);
3601*e4b17023SJohn Marino 
3602*e4b17023SJohn Marino   for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
3603*e4b17023SJohn Marino     {
3604*e4b17023SJohn Marino       df_ref def = *def_rec;
3605*e4b17023SJohn Marino       bitmap_set_bit (defs, DF_REF_REGNO (def));
3606*e4b17023SJohn Marino     }
3607*e4b17023SJohn Marino }
3608*e4b17023SJohn Marino 
3609*e4b17023SJohn Marino /* Find the set of uses for INSN.  This includes partial defs.  */
3610*e4b17023SJohn Marino 
3611*e4b17023SJohn Marino static void
df_simulate_find_uses(rtx insn,bitmap uses)3612*e4b17023SJohn Marino df_simulate_find_uses (rtx insn, bitmap uses)
3613*e4b17023SJohn Marino {
3614*e4b17023SJohn Marino   df_ref *rec;
3615*e4b17023SJohn Marino   unsigned int uid = INSN_UID (insn);
3616*e4b17023SJohn Marino 
3617*e4b17023SJohn Marino   for (rec = DF_INSN_UID_DEFS (uid); *rec; rec++)
3618*e4b17023SJohn Marino     {
3619*e4b17023SJohn Marino       df_ref def = *rec;
3620*e4b17023SJohn Marino       if (DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))
3621*e4b17023SJohn Marino 	bitmap_set_bit (uses, DF_REF_REGNO (def));
3622*e4b17023SJohn Marino     }
3623*e4b17023SJohn Marino   for (rec = DF_INSN_UID_USES (uid); *rec; rec++)
3624*e4b17023SJohn Marino     {
3625*e4b17023SJohn Marino       df_ref use = *rec;
3626*e4b17023SJohn Marino       bitmap_set_bit (uses, DF_REF_REGNO (use));
3627*e4b17023SJohn Marino     }
3628*e4b17023SJohn Marino }
3629*e4b17023SJohn Marino 
3630*e4b17023SJohn Marino /* Find the set of real DEFs, which are not clobbers, for INSN.  */
3631*e4b17023SJohn Marino 
3632*e4b17023SJohn Marino void
df_simulate_find_noclobber_defs(rtx insn,bitmap defs)3633*e4b17023SJohn Marino df_simulate_find_noclobber_defs (rtx insn, bitmap defs)
3634*e4b17023SJohn Marino {
3635*e4b17023SJohn Marino   df_ref *def_rec;
3636*e4b17023SJohn Marino   unsigned int uid = INSN_UID (insn);
3637*e4b17023SJohn Marino 
3638*e4b17023SJohn Marino   for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
3639*e4b17023SJohn Marino     {
3640*e4b17023SJohn Marino       df_ref def = *def_rec;
3641*e4b17023SJohn Marino       if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
3642*e4b17023SJohn Marino 	bitmap_set_bit (defs, DF_REF_REGNO (def));
3643*e4b17023SJohn Marino     }
3644*e4b17023SJohn Marino }
3645*e4b17023SJohn Marino 
3646*e4b17023SJohn Marino 
3647*e4b17023SJohn Marino /* Simulate the effects of the defs of INSN on LIVE.  */
3648*e4b17023SJohn Marino 
3649*e4b17023SJohn Marino void
df_simulate_defs(rtx insn,bitmap live)3650*e4b17023SJohn Marino df_simulate_defs (rtx insn, bitmap live)
3651*e4b17023SJohn Marino {
3652*e4b17023SJohn Marino   df_ref *def_rec;
3653*e4b17023SJohn Marino   unsigned int uid = INSN_UID (insn);
3654*e4b17023SJohn Marino 
3655*e4b17023SJohn Marino   for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
3656*e4b17023SJohn Marino     {
3657*e4b17023SJohn Marino       df_ref def = *def_rec;
3658*e4b17023SJohn Marino       unsigned int dregno = DF_REF_REGNO (def);
3659*e4b17023SJohn Marino 
3660*e4b17023SJohn Marino       /* If the def is to only part of the reg, it does
3661*e4b17023SJohn Marino 	 not kill the other defs that reach here.  */
3662*e4b17023SJohn Marino       if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
3663*e4b17023SJohn Marino 	bitmap_clear_bit (live, dregno);
3664*e4b17023SJohn Marino     }
3665*e4b17023SJohn Marino }
3666*e4b17023SJohn Marino 
3667*e4b17023SJohn Marino 
3668*e4b17023SJohn Marino /* Simulate the effects of the uses of INSN on LIVE.  */
3669*e4b17023SJohn Marino 
3670*e4b17023SJohn Marino void
df_simulate_uses(rtx insn,bitmap live)3671*e4b17023SJohn Marino df_simulate_uses (rtx insn, bitmap live)
3672*e4b17023SJohn Marino {
3673*e4b17023SJohn Marino   df_ref *use_rec;
3674*e4b17023SJohn Marino   unsigned int uid = INSN_UID (insn);
3675*e4b17023SJohn Marino 
3676*e4b17023SJohn Marino   if (DEBUG_INSN_P (insn))
3677*e4b17023SJohn Marino     return;
3678*e4b17023SJohn Marino 
3679*e4b17023SJohn Marino   for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
3680*e4b17023SJohn Marino     {
3681*e4b17023SJohn Marino       df_ref use = *use_rec;
3682*e4b17023SJohn Marino       /* Add use to set of uses in this BB.  */
3683*e4b17023SJohn Marino       bitmap_set_bit (live, DF_REF_REGNO (use));
3684*e4b17023SJohn Marino     }
3685*e4b17023SJohn Marino }
3686*e4b17023SJohn Marino 
3687*e4b17023SJohn Marino 
3688*e4b17023SJohn Marino /* Add back the always live regs in BB to LIVE.  */
3689*e4b17023SJohn Marino 
3690*e4b17023SJohn Marino static inline void
df_simulate_fixup_sets(basic_block bb,bitmap live)3691*e4b17023SJohn Marino df_simulate_fixup_sets (basic_block bb, bitmap live)
3692*e4b17023SJohn Marino {
3693*e4b17023SJohn Marino   /* These regs are considered always live so if they end up dying
3694*e4b17023SJohn Marino      because of some def, we need to bring the back again.  */
3695*e4b17023SJohn Marino   if (bb_has_eh_pred (bb))
3696*e4b17023SJohn Marino     bitmap_ior_into (live, &df->eh_block_artificial_uses);
3697*e4b17023SJohn Marino   else
3698*e4b17023SJohn Marino     bitmap_ior_into (live, &df->regular_block_artificial_uses);
3699*e4b17023SJohn Marino }
3700*e4b17023SJohn Marino 
3701*e4b17023SJohn Marino 
3702*e4b17023SJohn Marino /*----------------------------------------------------------------------------
3703*e4b17023SJohn Marino    The following three functions are used only for BACKWARDS scanning:
3704*e4b17023SJohn Marino    i.e. they process the defs before the uses.
3705*e4b17023SJohn Marino 
3706*e4b17023SJohn Marino    df_simulate_initialize_backwards should be called first with a
3707*e4b17023SJohn Marino    bitvector copyied from the DF_LIVE_OUT or DF_LR_OUT.  Then
3708*e4b17023SJohn Marino    df_simulate_one_insn_backwards should be called for each insn in
3709*e4b17023SJohn Marino    the block, starting with the last one.  Finally,
3710*e4b17023SJohn Marino    df_simulate_finalize_backwards can be called to get a new value
3711*e4b17023SJohn Marino    of the sets at the top of the block (this is rarely used).
3712*e4b17023SJohn Marino    ----------------------------------------------------------------------------*/
3713*e4b17023SJohn Marino 
3714*e4b17023SJohn Marino /* Apply the artificial uses and defs at the end of BB in a backwards
3715*e4b17023SJohn Marino    direction.  */
3716*e4b17023SJohn Marino 
3717*e4b17023SJohn Marino void
df_simulate_initialize_backwards(basic_block bb,bitmap live)3718*e4b17023SJohn Marino df_simulate_initialize_backwards (basic_block bb, bitmap live)
3719*e4b17023SJohn Marino {
3720*e4b17023SJohn Marino   df_ref *def_rec;
3721*e4b17023SJohn Marino   df_ref *use_rec;
3722*e4b17023SJohn Marino   int bb_index = bb->index;
3723*e4b17023SJohn Marino 
3724*e4b17023SJohn Marino   for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
3725*e4b17023SJohn Marino     {
3726*e4b17023SJohn Marino       df_ref def = *def_rec;
3727*e4b17023SJohn Marino       if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
3728*e4b17023SJohn Marino 	bitmap_clear_bit (live, DF_REF_REGNO (def));
3729*e4b17023SJohn Marino     }
3730*e4b17023SJohn Marino 
3731*e4b17023SJohn Marino   for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
3732*e4b17023SJohn Marino     {
3733*e4b17023SJohn Marino       df_ref use = *use_rec;
3734*e4b17023SJohn Marino       if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
3735*e4b17023SJohn Marino 	bitmap_set_bit (live, DF_REF_REGNO (use));
3736*e4b17023SJohn Marino     }
3737*e4b17023SJohn Marino }
3738*e4b17023SJohn Marino 
3739*e4b17023SJohn Marino 
3740*e4b17023SJohn Marino /* Simulate the backwards effects of INSN on the bitmap LIVE.  */
3741*e4b17023SJohn Marino 
3742*e4b17023SJohn Marino void
df_simulate_one_insn_backwards(basic_block bb,rtx insn,bitmap live)3743*e4b17023SJohn Marino df_simulate_one_insn_backwards (basic_block bb, rtx insn, bitmap live)
3744*e4b17023SJohn Marino {
3745*e4b17023SJohn Marino   if (!NONDEBUG_INSN_P (insn))
3746*e4b17023SJohn Marino     return;
3747*e4b17023SJohn Marino 
3748*e4b17023SJohn Marino   df_simulate_defs (insn, live);
3749*e4b17023SJohn Marino   df_simulate_uses (insn, live);
3750*e4b17023SJohn Marino   df_simulate_fixup_sets (bb, live);
3751*e4b17023SJohn Marino }
3752*e4b17023SJohn Marino 
3753*e4b17023SJohn Marino 
3754*e4b17023SJohn Marino /* Apply the artificial uses and defs at the top of BB in a backwards
3755*e4b17023SJohn Marino    direction.  */
3756*e4b17023SJohn Marino 
3757*e4b17023SJohn Marino void
df_simulate_finalize_backwards(basic_block bb,bitmap live)3758*e4b17023SJohn Marino df_simulate_finalize_backwards (basic_block bb, bitmap live)
3759*e4b17023SJohn Marino {
3760*e4b17023SJohn Marino   df_ref *def_rec;
3761*e4b17023SJohn Marino #ifdef EH_USES
3762*e4b17023SJohn Marino   df_ref *use_rec;
3763*e4b17023SJohn Marino #endif
3764*e4b17023SJohn Marino   int bb_index = bb->index;
3765*e4b17023SJohn Marino 
3766*e4b17023SJohn Marino   for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
3767*e4b17023SJohn Marino     {
3768*e4b17023SJohn Marino       df_ref def = *def_rec;
3769*e4b17023SJohn Marino       if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
3770*e4b17023SJohn Marino 	bitmap_clear_bit (live, DF_REF_REGNO (def));
3771*e4b17023SJohn Marino     }
3772*e4b17023SJohn Marino 
3773*e4b17023SJohn Marino #ifdef EH_USES
3774*e4b17023SJohn Marino   for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
3775*e4b17023SJohn Marino     {
3776*e4b17023SJohn Marino       df_ref use = *use_rec;
3777*e4b17023SJohn Marino       if (DF_REF_FLAGS (use) & DF_REF_AT_TOP)
3778*e4b17023SJohn Marino 	bitmap_set_bit (live, DF_REF_REGNO (use));
3779*e4b17023SJohn Marino     }
3780*e4b17023SJohn Marino #endif
3781*e4b17023SJohn Marino }
3782*e4b17023SJohn Marino /*----------------------------------------------------------------------------
3783*e4b17023SJohn Marino    The following three functions are used only for FORWARDS scanning:
3784*e4b17023SJohn Marino    i.e. they process the defs and the REG_DEAD and REG_UNUSED notes.
3785*e4b17023SJohn Marino    Thus it is important to add the DF_NOTES problem to the stack of
3786*e4b17023SJohn Marino    problems computed before using these functions.
3787*e4b17023SJohn Marino 
3788*e4b17023SJohn Marino    df_simulate_initialize_forwards should be called first with a
3789*e4b17023SJohn Marino    bitvector copyied from the DF_LIVE_IN or DF_LR_IN.  Then
3790*e4b17023SJohn Marino    df_simulate_one_insn_forwards should be called for each insn in
3791*e4b17023SJohn Marino    the block, starting with the first one.
3792*e4b17023SJohn Marino    ----------------------------------------------------------------------------*/
3793*e4b17023SJohn Marino 
3794*e4b17023SJohn Marino /* Initialize the LIVE bitmap, which should be copied from DF_LIVE_IN or
3795*e4b17023SJohn Marino    DF_LR_IN for basic block BB, for forward scanning by marking artificial
3796*e4b17023SJohn Marino    defs live.  */
3797*e4b17023SJohn Marino 
3798*e4b17023SJohn Marino void
df_simulate_initialize_forwards(basic_block bb,bitmap live)3799*e4b17023SJohn Marino df_simulate_initialize_forwards (basic_block bb, bitmap live)
3800*e4b17023SJohn Marino {
3801*e4b17023SJohn Marino   df_ref *def_rec;
3802*e4b17023SJohn Marino   int bb_index = bb->index;
3803*e4b17023SJohn Marino 
3804*e4b17023SJohn Marino   for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
3805*e4b17023SJohn Marino     {
3806*e4b17023SJohn Marino       df_ref def = *def_rec;
3807*e4b17023SJohn Marino       if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
3808*e4b17023SJohn Marino 	bitmap_set_bit (live, DF_REF_REGNO (def));
3809*e4b17023SJohn Marino     }
3810*e4b17023SJohn Marino }
3811*e4b17023SJohn Marino 
3812*e4b17023SJohn Marino /* Simulate the forwards effects of INSN on the bitmap LIVE.  */
3813*e4b17023SJohn Marino 
3814*e4b17023SJohn Marino void
df_simulate_one_insn_forwards(basic_block bb,rtx insn,bitmap live)3815*e4b17023SJohn Marino df_simulate_one_insn_forwards (basic_block bb, rtx insn, bitmap live)
3816*e4b17023SJohn Marino {
3817*e4b17023SJohn Marino   rtx link;
3818*e4b17023SJohn Marino   if (! INSN_P (insn))
3819*e4b17023SJohn Marino     return;
3820*e4b17023SJohn Marino 
3821*e4b17023SJohn Marino   /* Make sure that DF_NOTE really is an active df problem.  */
3822*e4b17023SJohn Marino   gcc_assert (df_note);
3823*e4b17023SJohn Marino 
3824*e4b17023SJohn Marino   /* Note that this is the opposite as how the problem is defined, because
3825*e4b17023SJohn Marino      in the LR problem defs _kill_ liveness.  However, they do so backwards,
3826*e4b17023SJohn Marino      while here the scan is performed forwards!  So, first assume that the
3827*e4b17023SJohn Marino      def is live, and if this is not true REG_UNUSED notes will rectify the
3828*e4b17023SJohn Marino      situation.  */
3829*e4b17023SJohn Marino   df_simulate_find_noclobber_defs (insn, live);
3830*e4b17023SJohn Marino 
3831*e4b17023SJohn Marino   /* Clear all of the registers that go dead.  */
3832*e4b17023SJohn Marino   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
3833*e4b17023SJohn Marino     {
3834*e4b17023SJohn Marino       switch (REG_NOTE_KIND (link))
3835*e4b17023SJohn Marino 	{
3836*e4b17023SJohn Marino 	case REG_DEAD:
3837*e4b17023SJohn Marino 	case REG_UNUSED:
3838*e4b17023SJohn Marino 	  {
3839*e4b17023SJohn Marino 	    rtx reg = XEXP (link, 0);
3840*e4b17023SJohn Marino 	    int regno = REGNO (reg);
3841*e4b17023SJohn Marino 	    if (HARD_REGISTER_NUM_P (regno))
3842*e4b17023SJohn Marino 	      bitmap_clear_range (live, regno,
3843*e4b17023SJohn Marino 				  hard_regno_nregs[regno][GET_MODE (reg)]);
3844*e4b17023SJohn Marino 	    else
3845*e4b17023SJohn Marino 	      bitmap_clear_bit (live, regno);
3846*e4b17023SJohn Marino 	  }
3847*e4b17023SJohn Marino 	  break;
3848*e4b17023SJohn Marino 	default:
3849*e4b17023SJohn Marino 	  break;
3850*e4b17023SJohn Marino 	}
3851*e4b17023SJohn Marino     }
3852*e4b17023SJohn Marino   df_simulate_fixup_sets (bb, live);
3853*e4b17023SJohn Marino }
3854*e4b17023SJohn Marino 
3855*e4b17023SJohn Marino /* Used by the next two functions to encode information about the
3856*e4b17023SJohn Marino    memory references we found.  */
3857*e4b17023SJohn Marino #define MEMREF_NORMAL 1
3858*e4b17023SJohn Marino #define MEMREF_VOLATILE 2
3859*e4b17023SJohn Marino 
3860*e4b17023SJohn Marino /* A subroutine of can_move_insns_across_p called through for_each_rtx.
3861*e4b17023SJohn Marino    Return either MEMREF_NORMAL or MEMREF_VOLATILE if a memory is found.  */
3862*e4b17023SJohn Marino 
3863*e4b17023SJohn Marino static int
find_memory(rtx * px,void * data ATTRIBUTE_UNUSED)3864*e4b17023SJohn Marino find_memory (rtx *px, void *data ATTRIBUTE_UNUSED)
3865*e4b17023SJohn Marino {
3866*e4b17023SJohn Marino   rtx x = *px;
3867*e4b17023SJohn Marino 
3868*e4b17023SJohn Marino   if (GET_CODE (x) == ASM_OPERANDS && MEM_VOLATILE_P (x))
3869*e4b17023SJohn Marino     return MEMREF_VOLATILE;
3870*e4b17023SJohn Marino 
3871*e4b17023SJohn Marino   if (!MEM_P (x))
3872*e4b17023SJohn Marino     return 0;
3873*e4b17023SJohn Marino   if (MEM_VOLATILE_P (x))
3874*e4b17023SJohn Marino     return MEMREF_VOLATILE;
3875*e4b17023SJohn Marino   if (MEM_READONLY_P (x))
3876*e4b17023SJohn Marino     return 0;
3877*e4b17023SJohn Marino 
3878*e4b17023SJohn Marino   return MEMREF_NORMAL;
3879*e4b17023SJohn Marino }
3880*e4b17023SJohn Marino 
3881*e4b17023SJohn Marino /* A subroutine of can_move_insns_across_p called through note_stores.
3882*e4b17023SJohn Marino    DATA points to an integer in which we set either the bit for
3883*e4b17023SJohn Marino    MEMREF_NORMAL or the bit for MEMREF_VOLATILE if we find a MEM
3884*e4b17023SJohn Marino    of either kind.  */
3885*e4b17023SJohn Marino 
3886*e4b17023SJohn Marino static void
find_memory_stores(rtx x,const_rtx pat ATTRIBUTE_UNUSED,void * data ATTRIBUTE_UNUSED)3887*e4b17023SJohn Marino find_memory_stores (rtx x, const_rtx pat ATTRIBUTE_UNUSED,
3888*e4b17023SJohn Marino 		    void *data ATTRIBUTE_UNUSED)
3889*e4b17023SJohn Marino {
3890*e4b17023SJohn Marino   int *pflags = (int *)data;
3891*e4b17023SJohn Marino   if (GET_CODE (x) == SUBREG)
3892*e4b17023SJohn Marino     x = XEXP (x, 0);
3893*e4b17023SJohn Marino   /* Treat stores to SP as stores to memory, this will prevent problems
3894*e4b17023SJohn Marino      when there are references to the stack frame.  */
3895*e4b17023SJohn Marino   if (x == stack_pointer_rtx)
3896*e4b17023SJohn Marino     *pflags |= MEMREF_VOLATILE;
3897*e4b17023SJohn Marino   if (!MEM_P (x))
3898*e4b17023SJohn Marino     return;
3899*e4b17023SJohn Marino   *pflags |= MEM_VOLATILE_P (x) ? MEMREF_VOLATILE : MEMREF_NORMAL;
3900*e4b17023SJohn Marino }
3901*e4b17023SJohn Marino 
3902*e4b17023SJohn Marino /* Scan BB backwards, using df_simulate functions to keep track of
3903*e4b17023SJohn Marino    lifetimes, up to insn POINT.  The result is stored in LIVE.  */
3904*e4b17023SJohn Marino 
3905*e4b17023SJohn Marino void
simulate_backwards_to_point(basic_block bb,regset live,rtx point)3906*e4b17023SJohn Marino simulate_backwards_to_point (basic_block bb, regset live, rtx point)
3907*e4b17023SJohn Marino {
3908*e4b17023SJohn Marino   rtx insn;
3909*e4b17023SJohn Marino   bitmap_copy (live, df_get_live_out (bb));
3910*e4b17023SJohn Marino   df_simulate_initialize_backwards (bb, live);
3911*e4b17023SJohn Marino 
3912*e4b17023SJohn Marino   /* Scan and update life information until we reach the point we're
3913*e4b17023SJohn Marino      interested in.  */
3914*e4b17023SJohn Marino   for (insn = BB_END (bb); insn != point; insn = PREV_INSN (insn))
3915*e4b17023SJohn Marino     df_simulate_one_insn_backwards (bb, insn, live);
3916*e4b17023SJohn Marino }
3917*e4b17023SJohn Marino 
3918*e4b17023SJohn Marino /* Return true if it is safe to move a group of insns, described by
3919*e4b17023SJohn Marino    the range FROM to TO, backwards across another group of insns,
3920*e4b17023SJohn Marino    described by ACROSS_FROM to ACROSS_TO.  It is assumed that there
3921*e4b17023SJohn Marino    are no insns between ACROSS_TO and FROM, but they may be in
3922*e4b17023SJohn Marino    different basic blocks; MERGE_BB is the block from which the
3923*e4b17023SJohn Marino    insns will be moved.  The caller must pass in a regset MERGE_LIVE
3924*e4b17023SJohn Marino    which specifies the registers live after TO.
3925*e4b17023SJohn Marino 
3926*e4b17023SJohn Marino    This function may be called in one of two cases: either we try to
3927*e4b17023SJohn Marino    move identical instructions from all successor blocks into their
3928*e4b17023SJohn Marino    predecessor, or we try to move from only one successor block.  If
3929*e4b17023SJohn Marino    OTHER_BRANCH_LIVE is nonnull, it indicates that we're dealing with
3930*e4b17023SJohn Marino    the second case.  It should contain a set of registers live at the
3931*e4b17023SJohn Marino    end of ACROSS_TO which must not be clobbered by moving the insns.
3932*e4b17023SJohn Marino    In that case, we're also more careful about moving memory references
3933*e4b17023SJohn Marino    and trapping insns.
3934*e4b17023SJohn Marino 
3935*e4b17023SJohn Marino    We return false if it is not safe to move the entire group, but it
3936*e4b17023SJohn Marino    may still be possible to move a subgroup.  PMOVE_UPTO, if nonnull,
3937*e4b17023SJohn Marino    is set to point at the last moveable insn in such a case.  */
3938*e4b17023SJohn Marino 
3939*e4b17023SJohn Marino bool
can_move_insns_across(rtx from,rtx to,rtx across_from,rtx across_to,basic_block merge_bb,regset merge_live,regset other_branch_live,rtx * pmove_upto)3940*e4b17023SJohn Marino can_move_insns_across (rtx from, rtx to, rtx across_from, rtx across_to,
3941*e4b17023SJohn Marino 		       basic_block merge_bb, regset merge_live,
3942*e4b17023SJohn Marino 		       regset other_branch_live, rtx *pmove_upto)
3943*e4b17023SJohn Marino {
3944*e4b17023SJohn Marino   rtx insn, next, max_to;
3945*e4b17023SJohn Marino   bitmap merge_set, merge_use, local_merge_live;
3946*e4b17023SJohn Marino   bitmap test_set, test_use;
3947*e4b17023SJohn Marino   unsigned i, fail = 0;
3948*e4b17023SJohn Marino   bitmap_iterator bi;
3949*e4b17023SJohn Marino   int memrefs_in_across = 0;
3950*e4b17023SJohn Marino   int mem_sets_in_across = 0;
3951*e4b17023SJohn Marino   bool trapping_insns_in_across = false;
3952*e4b17023SJohn Marino 
3953*e4b17023SJohn Marino   if (pmove_upto != NULL)
3954*e4b17023SJohn Marino     *pmove_upto = NULL_RTX;
3955*e4b17023SJohn Marino 
3956*e4b17023SJohn Marino   /* Find real bounds, ignoring debug insns.  */
3957*e4b17023SJohn Marino   while (!NONDEBUG_INSN_P (from) && from != to)
3958*e4b17023SJohn Marino     from = NEXT_INSN (from);
3959*e4b17023SJohn Marino   while (!NONDEBUG_INSN_P (to) && from != to)
3960*e4b17023SJohn Marino     to = PREV_INSN (to);
3961*e4b17023SJohn Marino 
3962*e4b17023SJohn Marino   for (insn = across_to; ; insn = next)
3963*e4b17023SJohn Marino     {
3964*e4b17023SJohn Marino       if (CALL_P (insn))
3965*e4b17023SJohn Marino 	{
3966*e4b17023SJohn Marino 	  if (RTL_CONST_OR_PURE_CALL_P (insn))
3967*e4b17023SJohn Marino 	    /* Pure functions can read from memory.  Const functions can
3968*e4b17023SJohn Marino 	       read from arguments that the ABI has forced onto the stack.
3969*e4b17023SJohn Marino 	       Neither sort of read can be volatile.  */
3970*e4b17023SJohn Marino 	    memrefs_in_across |= MEMREF_NORMAL;
3971*e4b17023SJohn Marino 	  else
3972*e4b17023SJohn Marino 	    {
3973*e4b17023SJohn Marino 	      memrefs_in_across |= MEMREF_VOLATILE;
3974*e4b17023SJohn Marino 	      mem_sets_in_across |= MEMREF_VOLATILE;
3975*e4b17023SJohn Marino 	    }
3976*e4b17023SJohn Marino 	}
3977*e4b17023SJohn Marino       if (NONDEBUG_INSN_P (insn))
3978*e4b17023SJohn Marino 	{
3979*e4b17023SJohn Marino 	  memrefs_in_across |= for_each_rtx (&PATTERN (insn), find_memory,
3980*e4b17023SJohn Marino 					     NULL);
3981*e4b17023SJohn Marino 	  note_stores (PATTERN (insn), find_memory_stores,
3982*e4b17023SJohn Marino 		       &mem_sets_in_across);
3983*e4b17023SJohn Marino 	  /* This is used just to find sets of the stack pointer.  */
3984*e4b17023SJohn Marino 	  memrefs_in_across |= mem_sets_in_across;
3985*e4b17023SJohn Marino 	  trapping_insns_in_across |= may_trap_p (PATTERN (insn));
3986*e4b17023SJohn Marino 	}
3987*e4b17023SJohn Marino       next = PREV_INSN (insn);
3988*e4b17023SJohn Marino       if (insn == across_from)
3989*e4b17023SJohn Marino 	break;
3990*e4b17023SJohn Marino     }
3991*e4b17023SJohn Marino 
3992*e4b17023SJohn Marino   /* Collect:
3993*e4b17023SJohn Marino      MERGE_SET = set of registers set in MERGE_BB
3994*e4b17023SJohn Marino      MERGE_USE = set of registers used in MERGE_BB and live at its top
3995*e4b17023SJohn Marino      MERGE_LIVE = set of registers live at the point inside the MERGE
3996*e4b17023SJohn Marino      range that we've reached during scanning
3997*e4b17023SJohn Marino      TEST_SET = set of registers set between ACROSS_FROM and ACROSS_END.
3998*e4b17023SJohn Marino      TEST_USE = set of registers used between ACROSS_FROM and ACROSS_END,
3999*e4b17023SJohn Marino      and live before ACROSS_FROM.  */
4000*e4b17023SJohn Marino 
4001*e4b17023SJohn Marino   merge_set = BITMAP_ALLOC (&reg_obstack);
4002*e4b17023SJohn Marino   merge_use = BITMAP_ALLOC (&reg_obstack);
4003*e4b17023SJohn Marino   local_merge_live = BITMAP_ALLOC (&reg_obstack);
4004*e4b17023SJohn Marino   test_set = BITMAP_ALLOC (&reg_obstack);
4005*e4b17023SJohn Marino   test_use = BITMAP_ALLOC (&reg_obstack);
4006*e4b17023SJohn Marino 
4007*e4b17023SJohn Marino   /* Compute the set of registers set and used in the ACROSS range.  */
4008*e4b17023SJohn Marino   if (other_branch_live != NULL)
4009*e4b17023SJohn Marino     bitmap_copy (test_use, other_branch_live);
4010*e4b17023SJohn Marino   df_simulate_initialize_backwards (merge_bb, test_use);
4011*e4b17023SJohn Marino   for (insn = across_to; ; insn = next)
4012*e4b17023SJohn Marino     {
4013*e4b17023SJohn Marino       if (NONDEBUG_INSN_P (insn))
4014*e4b17023SJohn Marino 	{
4015*e4b17023SJohn Marino 	  df_simulate_find_defs (insn, test_set);
4016*e4b17023SJohn Marino 	  df_simulate_defs (insn, test_use);
4017*e4b17023SJohn Marino 	  df_simulate_uses (insn, test_use);
4018*e4b17023SJohn Marino 	}
4019*e4b17023SJohn Marino       next = PREV_INSN (insn);
4020*e4b17023SJohn Marino       if (insn == across_from)
4021*e4b17023SJohn Marino 	break;
4022*e4b17023SJohn Marino     }
4023*e4b17023SJohn Marino 
4024*e4b17023SJohn Marino   /* Compute an upper bound for the amount of insns moved, by finding
4025*e4b17023SJohn Marino      the first insn in MERGE that sets a register in TEST_USE, or uses
4026*e4b17023SJohn Marino      a register in TEST_SET.  We also check for calls, trapping operations,
4027*e4b17023SJohn Marino      and memory references.  */
4028*e4b17023SJohn Marino   max_to = NULL_RTX;
4029*e4b17023SJohn Marino   for (insn = from; ; insn = next)
4030*e4b17023SJohn Marino     {
4031*e4b17023SJohn Marino       if (CALL_P (insn))
4032*e4b17023SJohn Marino 	break;
4033*e4b17023SJohn Marino       if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG)
4034*e4b17023SJohn Marino 	break;
4035*e4b17023SJohn Marino       if (NONDEBUG_INSN_P (insn))
4036*e4b17023SJohn Marino 	{
4037*e4b17023SJohn Marino 	  if (may_trap_or_fault_p (PATTERN (insn))
4038*e4b17023SJohn Marino 	      && (trapping_insns_in_across || other_branch_live != NULL))
4039*e4b17023SJohn Marino 	    break;
4040*e4b17023SJohn Marino 
4041*e4b17023SJohn Marino 	  /* We cannot move memory stores past each other, or move memory
4042*e4b17023SJohn Marino 	     reads past stores, at least not without tracking them and
4043*e4b17023SJohn Marino 	     calling true_dependence on every pair.
4044*e4b17023SJohn Marino 
4045*e4b17023SJohn Marino 	     If there is no other branch and no memory references or
4046*e4b17023SJohn Marino 	     sets in the ACROSS range, we can move memory references
4047*e4b17023SJohn Marino 	     freely, even volatile ones.
4048*e4b17023SJohn Marino 
4049*e4b17023SJohn Marino 	     Otherwise, the rules are as follows: volatile memory
4050*e4b17023SJohn Marino 	     references and stores can't be moved at all, and any type
4051*e4b17023SJohn Marino 	     of memory reference can't be moved if there are volatile
4052*e4b17023SJohn Marino 	     accesses or stores in the ACROSS range.  That leaves
4053*e4b17023SJohn Marino 	     normal reads, which can be moved, as the trapping case is
4054*e4b17023SJohn Marino 	     dealt with elsewhere.  */
4055*e4b17023SJohn Marino 	  if (other_branch_live != NULL || memrefs_in_across != 0)
4056*e4b17023SJohn Marino 	    {
4057*e4b17023SJohn Marino 	      int mem_ref_flags = 0;
4058*e4b17023SJohn Marino 	      int mem_set_flags = 0;
4059*e4b17023SJohn Marino 	      note_stores (PATTERN (insn), find_memory_stores, &mem_set_flags);
4060*e4b17023SJohn Marino 	      mem_ref_flags = for_each_rtx (&PATTERN (insn), find_memory,
4061*e4b17023SJohn Marino 					    NULL);
4062*e4b17023SJohn Marino 	      /* Catch sets of the stack pointer.  */
4063*e4b17023SJohn Marino 	      mem_ref_flags |= mem_set_flags;
4064*e4b17023SJohn Marino 
4065*e4b17023SJohn Marino 	      if ((mem_ref_flags | mem_set_flags) & MEMREF_VOLATILE)
4066*e4b17023SJohn Marino 		break;
4067*e4b17023SJohn Marino 	      if ((memrefs_in_across & MEMREF_VOLATILE) && mem_ref_flags != 0)
4068*e4b17023SJohn Marino 		break;
4069*e4b17023SJohn Marino 	      if (mem_set_flags != 0
4070*e4b17023SJohn Marino 		  || (mem_sets_in_across != 0 && mem_ref_flags != 0))
4071*e4b17023SJohn Marino 		break;
4072*e4b17023SJohn Marino 	    }
4073*e4b17023SJohn Marino 	  df_simulate_find_uses (insn, merge_use);
4074*e4b17023SJohn Marino 	  /* We're only interested in uses which use a value live at
4075*e4b17023SJohn Marino 	     the top, not one previously set in this block.  */
4076*e4b17023SJohn Marino 	  bitmap_and_compl_into (merge_use, merge_set);
4077*e4b17023SJohn Marino 	  df_simulate_find_defs (insn, merge_set);
4078*e4b17023SJohn Marino 	  if (bitmap_intersect_p (merge_set, test_use)
4079*e4b17023SJohn Marino 	      || bitmap_intersect_p (merge_use, test_set))
4080*e4b17023SJohn Marino 	    break;
4081*e4b17023SJohn Marino #ifdef HAVE_cc0
4082*e4b17023SJohn Marino 	  if (!sets_cc0_p (insn))
4083*e4b17023SJohn Marino #endif
4084*e4b17023SJohn Marino 	    max_to = insn;
4085*e4b17023SJohn Marino 	}
4086*e4b17023SJohn Marino       next = NEXT_INSN (insn);
4087*e4b17023SJohn Marino       if (insn == to)
4088*e4b17023SJohn Marino 	break;
4089*e4b17023SJohn Marino     }
4090*e4b17023SJohn Marino   if (max_to != to)
4091*e4b17023SJohn Marino     fail = 1;
4092*e4b17023SJohn Marino 
4093*e4b17023SJohn Marino   if (max_to == NULL_RTX || (fail && pmove_upto == NULL))
4094*e4b17023SJohn Marino     goto out;
4095*e4b17023SJohn Marino 
4096*e4b17023SJohn Marino   /* Now, lower this upper bound by also taking into account that
4097*e4b17023SJohn Marino      a range of insns moved across ACROSS must not leave a register
4098*e4b17023SJohn Marino      live at the end that will be clobbered in ACROSS.  We need to
4099*e4b17023SJohn Marino      find a point where TEST_SET & LIVE == 0.
4100*e4b17023SJohn Marino 
4101*e4b17023SJohn Marino      Insns in the MERGE range that set registers which are also set
4102*e4b17023SJohn Marino      in the ACROSS range may still be moved as long as we also move
4103*e4b17023SJohn Marino      later insns which use the results of the set, and make the
4104*e4b17023SJohn Marino      register dead again.  This is verified by the condition stated
4105*e4b17023SJohn Marino      above.  We only need to test it for registers that are set in
4106*e4b17023SJohn Marino      the moved region.
4107*e4b17023SJohn Marino 
4108*e4b17023SJohn Marino      MERGE_LIVE is provided by the caller and holds live registers after
4109*e4b17023SJohn Marino      TO.  */
4110*e4b17023SJohn Marino   bitmap_copy (local_merge_live, merge_live);
4111*e4b17023SJohn Marino   for (insn = to; insn != max_to; insn = PREV_INSN (insn))
4112*e4b17023SJohn Marino     df_simulate_one_insn_backwards (merge_bb, insn, local_merge_live);
4113*e4b17023SJohn Marino 
4114*e4b17023SJohn Marino   /* We're not interested in registers that aren't set in the moved
4115*e4b17023SJohn Marino      region at all.  */
4116*e4b17023SJohn Marino   bitmap_and_into (local_merge_live, merge_set);
4117*e4b17023SJohn Marino   for (;;)
4118*e4b17023SJohn Marino     {
4119*e4b17023SJohn Marino       if (NONDEBUG_INSN_P (insn))
4120*e4b17023SJohn Marino 	{
4121*e4b17023SJohn Marino 	  if (!bitmap_intersect_p (test_set, local_merge_live)
4122*e4b17023SJohn Marino #ifdef HAVE_cc0
4123*e4b17023SJohn Marino 	      && !sets_cc0_p (insn)
4124*e4b17023SJohn Marino #endif
4125*e4b17023SJohn Marino 	      )
4126*e4b17023SJohn Marino 	    {
4127*e4b17023SJohn Marino 	      max_to = insn;
4128*e4b17023SJohn Marino 	      break;
4129*e4b17023SJohn Marino 	    }
4130*e4b17023SJohn Marino 
4131*e4b17023SJohn Marino 	  df_simulate_one_insn_backwards (merge_bb, insn,
4132*e4b17023SJohn Marino 					  local_merge_live);
4133*e4b17023SJohn Marino 	}
4134*e4b17023SJohn Marino       if (insn == from)
4135*e4b17023SJohn Marino 	{
4136*e4b17023SJohn Marino 	  fail = 1;
4137*e4b17023SJohn Marino 	  goto out;
4138*e4b17023SJohn Marino 	}
4139*e4b17023SJohn Marino       insn = PREV_INSN (insn);
4140*e4b17023SJohn Marino     }
4141*e4b17023SJohn Marino 
4142*e4b17023SJohn Marino   if (max_to != to)
4143*e4b17023SJohn Marino     fail = 1;
4144*e4b17023SJohn Marino 
4145*e4b17023SJohn Marino   if (pmove_upto)
4146*e4b17023SJohn Marino     *pmove_upto = max_to;
4147*e4b17023SJohn Marino 
4148*e4b17023SJohn Marino   /* For small register class machines, don't lengthen lifetimes of
4149*e4b17023SJohn Marino      hard registers before reload.  */
4150*e4b17023SJohn Marino   if (! reload_completed
4151*e4b17023SJohn Marino       && targetm.small_register_classes_for_mode_p (VOIDmode))
4152*e4b17023SJohn Marino     {
4153*e4b17023SJohn Marino       EXECUTE_IF_SET_IN_BITMAP (merge_set, 0, i, bi)
4154*e4b17023SJohn Marino 	{
4155*e4b17023SJohn Marino 	  if (i < FIRST_PSEUDO_REGISTER
4156*e4b17023SJohn Marino 	      && ! fixed_regs[i]
4157*e4b17023SJohn Marino 	      && ! global_regs[i])
4158*e4b17023SJohn Marino 	    fail = 1;
4159*e4b17023SJohn Marino 	}
4160*e4b17023SJohn Marino     }
4161*e4b17023SJohn Marino 
4162*e4b17023SJohn Marino  out:
4163*e4b17023SJohn Marino   BITMAP_FREE (merge_set);
4164*e4b17023SJohn Marino   BITMAP_FREE (merge_use);
4165*e4b17023SJohn Marino   BITMAP_FREE (local_merge_live);
4166*e4b17023SJohn Marino   BITMAP_FREE (test_set);
4167*e4b17023SJohn Marino   BITMAP_FREE (test_use);
4168*e4b17023SJohn Marino 
4169*e4b17023SJohn Marino   return !fail;
4170*e4b17023SJohn Marino }
4171*e4b17023SJohn Marino 
4172*e4b17023SJohn Marino 
4173*e4b17023SJohn Marino /*----------------------------------------------------------------------------
4174*e4b17023SJohn Marino    MULTIPLE DEFINITIONS
4175*e4b17023SJohn Marino 
4176*e4b17023SJohn Marino    Find the locations in the function reached by multiple definition sites
4177*e4b17023SJohn Marino    for a live pseudo.  In and out bitvectors are built for each basic
4178*e4b17023SJohn Marino    block.  They are restricted for efficiency to live registers.
4179*e4b17023SJohn Marino 
4180*e4b17023SJohn Marino    The gen and kill sets for the problem are obvious.  Together they
4181*e4b17023SJohn Marino    include all defined registers in a basic block; the gen set includes
4182*e4b17023SJohn Marino    registers where a partial or conditional or may-clobber definition is
4183*e4b17023SJohn Marino    last in the BB, while the kill set includes registers with a complete
4184*e4b17023SJohn Marino    definition coming last.  However, the computation of the dataflow
4185*e4b17023SJohn Marino    itself is interesting.
4186*e4b17023SJohn Marino 
4187*e4b17023SJohn Marino    The idea behind it comes from SSA form's iterated dominance frontier
4188*e4b17023SJohn Marino    criterion for inserting PHI functions.  Just like in that case, we can use
4189*e4b17023SJohn Marino    the dominance frontier to find places where multiple definitions meet;
4190*e4b17023SJohn Marino    a register X defined in a basic block BB1 has multiple definitions in
4191*e4b17023SJohn Marino    basic blocks in BB1's dominance frontier.
4192*e4b17023SJohn Marino 
4193*e4b17023SJohn Marino    So, the in-set of a basic block BB2 is not just the union of the
4194*e4b17023SJohn Marino    out-sets of BB2's predecessors, but includes some more bits that come
4195*e4b17023SJohn Marino    from the basic blocks of whose dominance frontier BB2 is part (BB1 in
4196*e4b17023SJohn Marino    the previous paragraph).  I called this set the init-set of BB2.
4197*e4b17023SJohn Marino 
4198*e4b17023SJohn Marino       (Note: I actually use the kill-set only to build the init-set.
4199*e4b17023SJohn Marino       gen bits are anyway propagated from BB1 to BB2 by dataflow).
4200*e4b17023SJohn Marino 
4201*e4b17023SJohn Marino     For example, if you have
4202*e4b17023SJohn Marino 
4203*e4b17023SJohn Marino        BB1 : r10 = 0
4204*e4b17023SJohn Marino              r11 = 0
4205*e4b17023SJohn Marino              if <...> goto BB2 else goto BB3;
4206*e4b17023SJohn Marino 
4207*e4b17023SJohn Marino        BB2 : r10 = 1
4208*e4b17023SJohn Marino              r12 = 1
4209*e4b17023SJohn Marino              goto BB3;
4210*e4b17023SJohn Marino 
4211*e4b17023SJohn Marino        BB3 :
4212*e4b17023SJohn Marino 
4213*e4b17023SJohn Marino     you have BB3 in BB2's dominance frontier but not in BB1's, so that the
4214*e4b17023SJohn Marino     init-set of BB3 includes r10 and r12, but not r11.  Note that we do
4215*e4b17023SJohn Marino     not need to iterate the dominance frontier, because we do not insert
4216*e4b17023SJohn Marino     anything like PHI functions there!  Instead, dataflow will take care of
4217*e4b17023SJohn Marino     propagating the information to BB3's successors.
4218*e4b17023SJohn Marino    ---------------------------------------------------------------------------*/
4219*e4b17023SJohn Marino 
4220*e4b17023SJohn Marino /* Private data used to verify the solution for this problem.  */
4221*e4b17023SJohn Marino struct df_md_problem_data
4222*e4b17023SJohn Marino {
4223*e4b17023SJohn Marino   /* An obstack for the bitmaps we need for this problem.  */
4224*e4b17023SJohn Marino   bitmap_obstack md_bitmaps;
4225*e4b17023SJohn Marino };
4226*e4b17023SJohn Marino 
4227*e4b17023SJohn Marino /* Scratch var used by transfer functions.  This is used to do md analysis
4228*e4b17023SJohn Marino    only for live registers.  */
4229*e4b17023SJohn Marino static bitmap_head df_md_scratch;
4230*e4b17023SJohn Marino 
4231*e4b17023SJohn Marino 
4232*e4b17023SJohn Marino static void
df_md_free_bb_info(basic_block bb ATTRIBUTE_UNUSED,void * vbb_info)4233*e4b17023SJohn Marino df_md_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
4234*e4b17023SJohn Marino                     void *vbb_info)
4235*e4b17023SJohn Marino {
4236*e4b17023SJohn Marino   struct df_md_bb_info *bb_info = (struct df_md_bb_info *) vbb_info;
4237*e4b17023SJohn Marino   if (bb_info)
4238*e4b17023SJohn Marino     {
4239*e4b17023SJohn Marino       bitmap_clear (&bb_info->kill);
4240*e4b17023SJohn Marino       bitmap_clear (&bb_info->gen);
4241*e4b17023SJohn Marino       bitmap_clear (&bb_info->init);
4242*e4b17023SJohn Marino       bitmap_clear (&bb_info->in);
4243*e4b17023SJohn Marino       bitmap_clear (&bb_info->out);
4244*e4b17023SJohn Marino     }
4245*e4b17023SJohn Marino }
4246*e4b17023SJohn Marino 
4247*e4b17023SJohn Marino 
4248*e4b17023SJohn Marino /* Allocate or reset bitmaps for DF_MD. The solution bits are
4249*e4b17023SJohn Marino    not touched unless the block is new.  */
4250*e4b17023SJohn Marino 
4251*e4b17023SJohn Marino static void
df_md_alloc(bitmap all_blocks)4252*e4b17023SJohn Marino df_md_alloc (bitmap all_blocks)
4253*e4b17023SJohn Marino {
4254*e4b17023SJohn Marino   unsigned int bb_index;
4255*e4b17023SJohn Marino   bitmap_iterator bi;
4256*e4b17023SJohn Marino   struct df_md_problem_data *problem_data;
4257*e4b17023SJohn Marino 
4258*e4b17023SJohn Marino   df_grow_bb_info (df_md);
4259*e4b17023SJohn Marino   if (df_md->problem_data)
4260*e4b17023SJohn Marino     problem_data = (struct df_md_problem_data *) df_md->problem_data;
4261*e4b17023SJohn Marino   else
4262*e4b17023SJohn Marino     {
4263*e4b17023SJohn Marino       problem_data = XNEW (struct df_md_problem_data);
4264*e4b17023SJohn Marino       df_md->problem_data = problem_data;
4265*e4b17023SJohn Marino       bitmap_obstack_initialize (&problem_data->md_bitmaps);
4266*e4b17023SJohn Marino     }
4267*e4b17023SJohn Marino   bitmap_initialize (&df_md_scratch, &problem_data->md_bitmaps);
4268*e4b17023SJohn Marino 
4269*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
4270*e4b17023SJohn Marino     {
4271*e4b17023SJohn Marino       struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
4272*e4b17023SJohn Marino       /* When bitmaps are already initialized, just clear them.  */
4273*e4b17023SJohn Marino       if (bb_info->init.obstack)
4274*e4b17023SJohn Marino         {
4275*e4b17023SJohn Marino           bitmap_clear (&bb_info->init);
4276*e4b17023SJohn Marino           bitmap_clear (&bb_info->gen);
4277*e4b17023SJohn Marino           bitmap_clear (&bb_info->kill);
4278*e4b17023SJohn Marino           bitmap_clear (&bb_info->in);
4279*e4b17023SJohn Marino           bitmap_clear (&bb_info->out);
4280*e4b17023SJohn Marino         }
4281*e4b17023SJohn Marino       else
4282*e4b17023SJohn Marino         {
4283*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->init, &problem_data->md_bitmaps);
4284*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->gen, &problem_data->md_bitmaps);
4285*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->kill, &problem_data->md_bitmaps);
4286*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->in, &problem_data->md_bitmaps);
4287*e4b17023SJohn Marino 	  bitmap_initialize (&bb_info->out, &problem_data->md_bitmaps);
4288*e4b17023SJohn Marino         }
4289*e4b17023SJohn Marino     }
4290*e4b17023SJohn Marino 
4291*e4b17023SJohn Marino   df_md->optional_p = true;
4292*e4b17023SJohn Marino }
4293*e4b17023SJohn Marino 
4294*e4b17023SJohn Marino /* Add the effect of the top artificial defs of BB to the multiple definitions
4295*e4b17023SJohn Marino    bitmap LOCAL_MD.  */
4296*e4b17023SJohn Marino 
4297*e4b17023SJohn Marino void
df_md_simulate_artificial_defs_at_top(basic_block bb,bitmap local_md)4298*e4b17023SJohn Marino df_md_simulate_artificial_defs_at_top (basic_block bb, bitmap local_md)
4299*e4b17023SJohn Marino {
4300*e4b17023SJohn Marino   int bb_index = bb->index;
4301*e4b17023SJohn Marino   df_ref *def_rec;
4302*e4b17023SJohn Marino   for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
4303*e4b17023SJohn Marino     {
4304*e4b17023SJohn Marino       df_ref def = *def_rec;
4305*e4b17023SJohn Marino       if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
4306*e4b17023SJohn Marino 	{
4307*e4b17023SJohn Marino 	  unsigned int dregno = DF_REF_REGNO (def);
4308*e4b17023SJohn Marino 	  if (DF_REF_FLAGS (def)
4309*e4b17023SJohn Marino 	      & (DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER))
4310*e4b17023SJohn Marino 	    bitmap_set_bit (local_md, dregno);
4311*e4b17023SJohn Marino 	  else
4312*e4b17023SJohn Marino 	    bitmap_clear_bit (local_md, dregno);
4313*e4b17023SJohn Marino 	}
4314*e4b17023SJohn Marino     }
4315*e4b17023SJohn Marino }
4316*e4b17023SJohn Marino 
4317*e4b17023SJohn Marino 
4318*e4b17023SJohn Marino /* Add the effect of the defs of INSN to the reaching definitions bitmap
4319*e4b17023SJohn Marino    LOCAL_MD.  */
4320*e4b17023SJohn Marino 
4321*e4b17023SJohn Marino void
df_md_simulate_one_insn(basic_block bb ATTRIBUTE_UNUSED,rtx insn,bitmap local_md)4322*e4b17023SJohn Marino df_md_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx insn,
4323*e4b17023SJohn Marino                         bitmap local_md)
4324*e4b17023SJohn Marino {
4325*e4b17023SJohn Marino   unsigned uid = INSN_UID (insn);
4326*e4b17023SJohn Marino   df_ref *def_rec;
4327*e4b17023SJohn Marino 
4328*e4b17023SJohn Marino   for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
4329*e4b17023SJohn Marino     {
4330*e4b17023SJohn Marino       df_ref def = *def_rec;
4331*e4b17023SJohn Marino       unsigned int dregno = DF_REF_REGNO (def);
4332*e4b17023SJohn Marino       if ((!(df->changeable_flags & DF_NO_HARD_REGS))
4333*e4b17023SJohn Marino           || (dregno >= FIRST_PSEUDO_REGISTER))
4334*e4b17023SJohn Marino         {
4335*e4b17023SJohn Marino           if (DF_REF_FLAGS (def)
4336*e4b17023SJohn Marino 	      & (DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER))
4337*e4b17023SJohn Marino            bitmap_set_bit (local_md, DF_REF_ID (def));
4338*e4b17023SJohn Marino          else
4339*e4b17023SJohn Marino            bitmap_clear_bit (local_md, DF_REF_ID (def));
4340*e4b17023SJohn Marino         }
4341*e4b17023SJohn Marino     }
4342*e4b17023SJohn Marino }
4343*e4b17023SJohn Marino 
4344*e4b17023SJohn Marino static void
df_md_bb_local_compute_process_def(struct df_md_bb_info * bb_info,df_ref * def_rec,int top_flag)4345*e4b17023SJohn Marino df_md_bb_local_compute_process_def (struct df_md_bb_info *bb_info,
4346*e4b17023SJohn Marino                                     df_ref *def_rec,
4347*e4b17023SJohn Marino                                     int top_flag)
4348*e4b17023SJohn Marino {
4349*e4b17023SJohn Marino   df_ref def;
4350*e4b17023SJohn Marino   bitmap_clear (&seen_in_insn);
4351*e4b17023SJohn Marino 
4352*e4b17023SJohn Marino   while ((def = *def_rec++) != NULL)
4353*e4b17023SJohn Marino     {
4354*e4b17023SJohn Marino       unsigned int dregno = DF_REF_REGNO (def);
4355*e4b17023SJohn Marino       if (((!(df->changeable_flags & DF_NO_HARD_REGS))
4356*e4b17023SJohn Marino 	    || (dregno >= FIRST_PSEUDO_REGISTER))
4357*e4b17023SJohn Marino 	  && top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
4358*e4b17023SJohn Marino 	{
4359*e4b17023SJohn Marino           if (!bitmap_bit_p (&seen_in_insn, dregno))
4360*e4b17023SJohn Marino 	    {
4361*e4b17023SJohn Marino 	      if (DF_REF_FLAGS (def)
4362*e4b17023SJohn Marino 	          & (DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER))
4363*e4b17023SJohn Marino 	        {
4364*e4b17023SJohn Marino 	          bitmap_set_bit (&bb_info->gen, dregno);
4365*e4b17023SJohn Marino 	          bitmap_clear_bit (&bb_info->kill, dregno);
4366*e4b17023SJohn Marino 	        }
4367*e4b17023SJohn Marino 	      else
4368*e4b17023SJohn Marino 	        {
4369*e4b17023SJohn Marino 		  /* When we find a clobber and a regular def,
4370*e4b17023SJohn Marino 		     make sure the regular def wins.  */
4371*e4b17023SJohn Marino 	          bitmap_set_bit (&seen_in_insn, dregno);
4372*e4b17023SJohn Marino 	          bitmap_set_bit (&bb_info->kill, dregno);
4373*e4b17023SJohn Marino 	          bitmap_clear_bit (&bb_info->gen, dregno);
4374*e4b17023SJohn Marino 	        }
4375*e4b17023SJohn Marino 	    }
4376*e4b17023SJohn Marino 	}
4377*e4b17023SJohn Marino     }
4378*e4b17023SJohn Marino }
4379*e4b17023SJohn Marino 
4380*e4b17023SJohn Marino 
4381*e4b17023SJohn Marino /* Compute local multiple def info for basic block BB.  */
4382*e4b17023SJohn Marino 
4383*e4b17023SJohn Marino static void
df_md_bb_local_compute(unsigned int bb_index)4384*e4b17023SJohn Marino df_md_bb_local_compute (unsigned int bb_index)
4385*e4b17023SJohn Marino {
4386*e4b17023SJohn Marino   basic_block bb = BASIC_BLOCK (bb_index);
4387*e4b17023SJohn Marino   struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
4388*e4b17023SJohn Marino   rtx insn;
4389*e4b17023SJohn Marino 
4390*e4b17023SJohn Marino   /* Artificials are only hard regs.  */
4391*e4b17023SJohn Marino   if (!(df->changeable_flags & DF_NO_HARD_REGS))
4392*e4b17023SJohn Marino     df_md_bb_local_compute_process_def (bb_info,
4393*e4b17023SJohn Marino                                         df_get_artificial_defs (bb_index),
4394*e4b17023SJohn Marino                                         DF_REF_AT_TOP);
4395*e4b17023SJohn Marino 
4396*e4b17023SJohn Marino   FOR_BB_INSNS (bb, insn)
4397*e4b17023SJohn Marino     {
4398*e4b17023SJohn Marino       unsigned int uid = INSN_UID (insn);
4399*e4b17023SJohn Marino       if (!INSN_P (insn))
4400*e4b17023SJohn Marino         continue;
4401*e4b17023SJohn Marino 
4402*e4b17023SJohn Marino       df_md_bb_local_compute_process_def (bb_info, DF_INSN_UID_DEFS (uid), 0);
4403*e4b17023SJohn Marino     }
4404*e4b17023SJohn Marino 
4405*e4b17023SJohn Marino   if (!(df->changeable_flags & DF_NO_HARD_REGS))
4406*e4b17023SJohn Marino     df_md_bb_local_compute_process_def (bb_info,
4407*e4b17023SJohn Marino                                         df_get_artificial_defs (bb_index),
4408*e4b17023SJohn Marino                                         0);
4409*e4b17023SJohn Marino }
4410*e4b17023SJohn Marino 
4411*e4b17023SJohn Marino /* Compute local reaching def info for each basic block within BLOCKS.  */
4412*e4b17023SJohn Marino 
4413*e4b17023SJohn Marino static void
df_md_local_compute(bitmap all_blocks)4414*e4b17023SJohn Marino df_md_local_compute (bitmap all_blocks)
4415*e4b17023SJohn Marino {
4416*e4b17023SJohn Marino   unsigned int bb_index, df_bb_index;
4417*e4b17023SJohn Marino   bitmap_iterator bi1, bi2;
4418*e4b17023SJohn Marino   basic_block bb;
4419*e4b17023SJohn Marino   bitmap_head *frontiers;
4420*e4b17023SJohn Marino 
4421*e4b17023SJohn Marino   bitmap_initialize (&seen_in_insn, &bitmap_default_obstack);
4422*e4b17023SJohn Marino 
4423*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi1)
4424*e4b17023SJohn Marino     {
4425*e4b17023SJohn Marino       df_md_bb_local_compute (bb_index);
4426*e4b17023SJohn Marino     }
4427*e4b17023SJohn Marino 
4428*e4b17023SJohn Marino   bitmap_clear (&seen_in_insn);
4429*e4b17023SJohn Marino 
4430*e4b17023SJohn Marino   frontiers = XNEWVEC (bitmap_head, last_basic_block);
4431*e4b17023SJohn Marino   FOR_ALL_BB (bb)
4432*e4b17023SJohn Marino     bitmap_initialize (&frontiers[bb->index], &bitmap_default_obstack);
4433*e4b17023SJohn Marino 
4434*e4b17023SJohn Marino   compute_dominance_frontiers (frontiers);
4435*e4b17023SJohn Marino 
4436*e4b17023SJohn Marino   /* Add each basic block's kills to the nodes in the frontier of the BB.  */
4437*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi1)
4438*e4b17023SJohn Marino     {
4439*e4b17023SJohn Marino       bitmap kill = &df_md_get_bb_info (bb_index)->kill;
4440*e4b17023SJohn Marino       EXECUTE_IF_SET_IN_BITMAP (&frontiers[bb_index], 0, df_bb_index, bi2)
4441*e4b17023SJohn Marino 	{
4442*e4b17023SJohn Marino 	  basic_block bb = BASIC_BLOCK (df_bb_index);
4443*e4b17023SJohn Marino 	  if (bitmap_bit_p (all_blocks, df_bb_index))
4444*e4b17023SJohn Marino 	    bitmap_ior_and_into (&df_md_get_bb_info (df_bb_index)->init, kill,
4445*e4b17023SJohn Marino 				 df_get_live_in (bb));
4446*e4b17023SJohn Marino 	}
4447*e4b17023SJohn Marino     }
4448*e4b17023SJohn Marino 
4449*e4b17023SJohn Marino   FOR_ALL_BB (bb)
4450*e4b17023SJohn Marino     bitmap_clear (&frontiers[bb->index]);
4451*e4b17023SJohn Marino   free (frontiers);
4452*e4b17023SJohn Marino }
4453*e4b17023SJohn Marino 
4454*e4b17023SJohn Marino 
4455*e4b17023SJohn Marino /* Reset the global solution for recalculation.  */
4456*e4b17023SJohn Marino 
4457*e4b17023SJohn Marino static void
df_md_reset(bitmap all_blocks)4458*e4b17023SJohn Marino df_md_reset (bitmap all_blocks)
4459*e4b17023SJohn Marino {
4460*e4b17023SJohn Marino   unsigned int bb_index;
4461*e4b17023SJohn Marino   bitmap_iterator bi;
4462*e4b17023SJohn Marino 
4463*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
4464*e4b17023SJohn Marino     {
4465*e4b17023SJohn Marino       struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
4466*e4b17023SJohn Marino       gcc_assert (bb_info);
4467*e4b17023SJohn Marino       bitmap_clear (&bb_info->in);
4468*e4b17023SJohn Marino       bitmap_clear (&bb_info->out);
4469*e4b17023SJohn Marino     }
4470*e4b17023SJohn Marino }
4471*e4b17023SJohn Marino 
4472*e4b17023SJohn Marino static bool
df_md_transfer_function(int bb_index)4473*e4b17023SJohn Marino df_md_transfer_function (int bb_index)
4474*e4b17023SJohn Marino {
4475*e4b17023SJohn Marino   basic_block bb = BASIC_BLOCK (bb_index);
4476*e4b17023SJohn Marino   struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
4477*e4b17023SJohn Marino   bitmap in = &bb_info->in;
4478*e4b17023SJohn Marino   bitmap out = &bb_info->out;
4479*e4b17023SJohn Marino   bitmap gen = &bb_info->gen;
4480*e4b17023SJohn Marino   bitmap kill = &bb_info->kill;
4481*e4b17023SJohn Marino 
4482*e4b17023SJohn Marino   /* We need to use a scratch set here so that the value returned from this
4483*e4b17023SJohn Marino      function invocation properly reflects whether the sets changed in a
4484*e4b17023SJohn Marino      significant way; i.e. not just because the live set was anded in.  */
4485*e4b17023SJohn Marino   bitmap_and (&df_md_scratch, gen, df_get_live_out (bb));
4486*e4b17023SJohn Marino 
4487*e4b17023SJohn Marino   /* Multiple definitions of a register are not relevant if it is not
4488*e4b17023SJohn Marino      live.  Thus we trim the result to the places where it is live.  */
4489*e4b17023SJohn Marino   bitmap_and_into (in, df_get_live_in (bb));
4490*e4b17023SJohn Marino 
4491*e4b17023SJohn Marino   return bitmap_ior_and_compl (out, &df_md_scratch, in, kill);
4492*e4b17023SJohn Marino }
4493*e4b17023SJohn Marino 
4494*e4b17023SJohn Marino /* Initialize the solution bit vectors for problem.  */
4495*e4b17023SJohn Marino 
4496*e4b17023SJohn Marino static void
df_md_init(bitmap all_blocks)4497*e4b17023SJohn Marino df_md_init (bitmap all_blocks)
4498*e4b17023SJohn Marino {
4499*e4b17023SJohn Marino   unsigned int bb_index;
4500*e4b17023SJohn Marino   bitmap_iterator bi;
4501*e4b17023SJohn Marino 
4502*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
4503*e4b17023SJohn Marino     {
4504*e4b17023SJohn Marino       struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
4505*e4b17023SJohn Marino 
4506*e4b17023SJohn Marino       bitmap_copy (&bb_info->in, &bb_info->init);
4507*e4b17023SJohn Marino       df_md_transfer_function (bb_index);
4508*e4b17023SJohn Marino     }
4509*e4b17023SJohn Marino }
4510*e4b17023SJohn Marino 
4511*e4b17023SJohn Marino static void
df_md_confluence_0(basic_block bb)4512*e4b17023SJohn Marino df_md_confluence_0 (basic_block bb)
4513*e4b17023SJohn Marino {
4514*e4b17023SJohn Marino   struct df_md_bb_info *bb_info = df_md_get_bb_info (bb->index);
4515*e4b17023SJohn Marino   bitmap_copy (&bb_info->in, &bb_info->init);
4516*e4b17023SJohn Marino }
4517*e4b17023SJohn Marino 
4518*e4b17023SJohn Marino /* In of target gets or of out of source.  */
4519*e4b17023SJohn Marino 
4520*e4b17023SJohn Marino static bool
df_md_confluence_n(edge e)4521*e4b17023SJohn Marino df_md_confluence_n (edge e)
4522*e4b17023SJohn Marino {
4523*e4b17023SJohn Marino   bitmap op1 = &df_md_get_bb_info (e->dest->index)->in;
4524*e4b17023SJohn Marino   bitmap op2 = &df_md_get_bb_info (e->src->index)->out;
4525*e4b17023SJohn Marino 
4526*e4b17023SJohn Marino   if (e->flags & EDGE_FAKE)
4527*e4b17023SJohn Marino     return false;
4528*e4b17023SJohn Marino 
4529*e4b17023SJohn Marino   if (e->flags & EDGE_EH)
4530*e4b17023SJohn Marino     return bitmap_ior_and_compl_into (op1, op2,
4531*e4b17023SJohn Marino 				      regs_invalidated_by_call_regset);
4532*e4b17023SJohn Marino   else
4533*e4b17023SJohn Marino     return bitmap_ior_into (op1, op2);
4534*e4b17023SJohn Marino }
4535*e4b17023SJohn Marino 
4536*e4b17023SJohn Marino /* Free all storage associated with the problem.  */
4537*e4b17023SJohn Marino 
4538*e4b17023SJohn Marino static void
df_md_free(void)4539*e4b17023SJohn Marino df_md_free (void)
4540*e4b17023SJohn Marino {
4541*e4b17023SJohn Marino   struct df_md_problem_data *problem_data
4542*e4b17023SJohn Marino     = (struct df_md_problem_data *) df_md->problem_data;
4543*e4b17023SJohn Marino 
4544*e4b17023SJohn Marino   bitmap_obstack_release (&problem_data->md_bitmaps);
4545*e4b17023SJohn Marino   free (problem_data);
4546*e4b17023SJohn Marino   df_md->problem_data = NULL;
4547*e4b17023SJohn Marino 
4548*e4b17023SJohn Marino   df_md->block_info_size = 0;
4549*e4b17023SJohn Marino   free (df_md->block_info);
4550*e4b17023SJohn Marino   df_md->block_info = NULL;
4551*e4b17023SJohn Marino   free (df_md);
4552*e4b17023SJohn Marino }
4553*e4b17023SJohn Marino 
4554*e4b17023SJohn Marino 
4555*e4b17023SJohn Marino /* Debugging info at top of bb.  */
4556*e4b17023SJohn Marino 
4557*e4b17023SJohn Marino static void
df_md_top_dump(basic_block bb,FILE * file)4558*e4b17023SJohn Marino df_md_top_dump (basic_block bb, FILE *file)
4559*e4b17023SJohn Marino {
4560*e4b17023SJohn Marino   struct df_md_bb_info *bb_info = df_md_get_bb_info (bb->index);
4561*e4b17023SJohn Marino   if (!bb_info)
4562*e4b17023SJohn Marino     return;
4563*e4b17023SJohn Marino 
4564*e4b17023SJohn Marino   fprintf (file, ";; md  in  \t");
4565*e4b17023SJohn Marino   df_print_regset (file, &bb_info->in);
4566*e4b17023SJohn Marino   fprintf (file, ";; md  init  \t");
4567*e4b17023SJohn Marino   df_print_regset (file, &bb_info->init);
4568*e4b17023SJohn Marino   fprintf (file, ";; md  gen \t");
4569*e4b17023SJohn Marino   df_print_regset (file, &bb_info->gen);
4570*e4b17023SJohn Marino   fprintf (file, ";; md  kill \t");
4571*e4b17023SJohn Marino   df_print_regset (file, &bb_info->kill);
4572*e4b17023SJohn Marino }
4573*e4b17023SJohn Marino 
4574*e4b17023SJohn Marino /* Debugging info at bottom of bb.  */
4575*e4b17023SJohn Marino 
4576*e4b17023SJohn Marino static void
df_md_bottom_dump(basic_block bb,FILE * file)4577*e4b17023SJohn Marino df_md_bottom_dump (basic_block bb, FILE *file)
4578*e4b17023SJohn Marino {
4579*e4b17023SJohn Marino   struct df_md_bb_info *bb_info = df_md_get_bb_info (bb->index);
4580*e4b17023SJohn Marino   if (!bb_info)
4581*e4b17023SJohn Marino     return;
4582*e4b17023SJohn Marino 
4583*e4b17023SJohn Marino   fprintf (file, ";; md  out \t");
4584*e4b17023SJohn Marino   df_print_regset (file, &bb_info->out);
4585*e4b17023SJohn Marino }
4586*e4b17023SJohn Marino 
4587*e4b17023SJohn Marino static struct df_problem problem_MD =
4588*e4b17023SJohn Marino {
4589*e4b17023SJohn Marino   DF_MD,                      /* Problem id.  */
4590*e4b17023SJohn Marino   DF_FORWARD,                 /* Direction.  */
4591*e4b17023SJohn Marino   df_md_alloc,                /* Allocate the problem specific data.  */
4592*e4b17023SJohn Marino   df_md_reset,                /* Reset global information.  */
4593*e4b17023SJohn Marino   df_md_free_bb_info,         /* Free basic block info.  */
4594*e4b17023SJohn Marino   df_md_local_compute,        /* Local compute function.  */
4595*e4b17023SJohn Marino   df_md_init,                 /* Init the solution specific data.  */
4596*e4b17023SJohn Marino   df_worklist_dataflow,       /* Worklist solver.  */
4597*e4b17023SJohn Marino   df_md_confluence_0,         /* Confluence operator 0.  */
4598*e4b17023SJohn Marino   df_md_confluence_n,         /* Confluence operator n.  */
4599*e4b17023SJohn Marino   df_md_transfer_function,    /* Transfer function.  */
4600*e4b17023SJohn Marino   NULL,                       /* Finalize function.  */
4601*e4b17023SJohn Marino   df_md_free,                 /* Free all of the problem information.  */
4602*e4b17023SJohn Marino   df_md_free,                 /* Remove this problem from the stack of dataflow problems.  */
4603*e4b17023SJohn Marino   NULL,                       /* Debugging.  */
4604*e4b17023SJohn Marino   df_md_top_dump,             /* Debugging start block.  */
4605*e4b17023SJohn Marino   df_md_bottom_dump,          /* Debugging end block.  */
4606*e4b17023SJohn Marino   NULL,			      /* Incremental solution verify start.  */
4607*e4b17023SJohn Marino   NULL,			      /* Incremental solution verify end.  */
4608*e4b17023SJohn Marino   NULL,                       /* Dependent problem.  */
4609*e4b17023SJohn Marino   sizeof (struct df_md_bb_info),/* Size of entry of block_info array.  */
4610*e4b17023SJohn Marino   TV_DF_MD,                   /* Timing variable.  */
4611*e4b17023SJohn Marino   false                       /* Reset blocks on dropping out of blocks_to_analyze.  */
4612*e4b17023SJohn Marino };
4613*e4b17023SJohn Marino 
4614*e4b17023SJohn Marino /* Create a new MD instance and add it to the existing instance
4615*e4b17023SJohn Marino    of DF.  */
4616*e4b17023SJohn Marino 
4617*e4b17023SJohn Marino void
df_md_add_problem(void)4618*e4b17023SJohn Marino df_md_add_problem (void)
4619*e4b17023SJohn Marino {
4620*e4b17023SJohn Marino   df_add_problem (&problem_MD);
4621*e4b17023SJohn Marino }
4622*e4b17023SJohn Marino 
4623*e4b17023SJohn Marino 
4624*e4b17023SJohn Marino 
4625