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 = ®_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 (®_obstack);
4002*e4b17023SJohn Marino merge_use = BITMAP_ALLOC (®_obstack);
4003*e4b17023SJohn Marino local_merge_live = BITMAP_ALLOC (®_obstack);
4004*e4b17023SJohn Marino test_set = BITMAP_ALLOC (®_obstack);
4005*e4b17023SJohn Marino test_use = BITMAP_ALLOC (®_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