]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/df-scan.c
re PR rtl-optimization/44691 (ICE: RTL check: expected code 'reg', have 'plus' in...
[thirdparty/gcc.git] / gcc / df-scan.c
CommitLineData
4d779342 1/* Scanning of rtl for dataflow analysis.
63642d5a 2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
c75c517d 3 2008, 2009, 2010 Free Software Foundation, Inc.
b8698a0f 4 Originally contributed by Michael P. Hayes
4d779342
DB
5 (m.hayes@elec.canterbury.ac.nz, mhayes@redhat.com)
6 Major rewrite contributed by Danny Berlin (dberlin@dberlin.org)
7 and Kenneth Zadeck (zadeck@naturalbridge.com).
8
9This file is part of GCC.
10
11GCC is free software; you can redistribute it and/or modify it under
12the terms of the GNU General Public License as published by the Free
9dcd6f09 13Software Foundation; either version 3, or (at your option) any later
4d779342
DB
14version.
15
16GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17WARRANTY; without even the implied warranty of MERCHANTABILITY or
18FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19for more details.
20
21You should have received a copy of the GNU General Public License
9dcd6f09
NC
22along with GCC; see the file COPYING3. If not see
23<http://www.gnu.org/licenses/>. */
4d779342
DB
24
25#include "config.h"
26#include "system.h"
27#include "coretypes.h"
28#include "tm.h"
29#include "rtl.h"
30#include "tm_p.h"
31#include "insn-config.h"
32#include "recog.h"
33#include "function.h"
34#include "regs.h"
35#include "output.h"
36#include "alloc-pool.h"
37#include "flags.h"
38#include "hard-reg-set.h"
39#include "basic-block.h"
40#include "sbitmap.h"
41#include "bitmap.h"
42#include "timevar.h"
912f2dac
DB
43#include "tree.h"
44#include "target.h"
45#include "target-def.h"
4d779342 46#include "df.h"
6fb5fa3c 47#include "tree-pass.h"
5936d944 48#include "emit-rtl.h" /* FIXME: Can go away once crtl is moved to rtl.h. */
4d779342 49
c2569604
ILT
50DEF_VEC_P(df_ref);
51DEF_VEC_ALLOC_P_STACK(df_ref);
52
53#define VEC_df_ref_stack_alloc(alloc) VEC_stack_alloc (df_ref, alloc)
54
55typedef struct df_mw_hardreg *df_mw_hardreg_ptr;
56
57DEF_VEC_P(df_mw_hardreg_ptr);
58DEF_VEC_ALLOC_P_STACK(df_mw_hardreg_ptr);
59
60#define VEC_df_mw_hardreg_ptr_stack_alloc(alloc) \
61 VEC_stack_alloc (df_mw_hardreg_ptr, alloc)
62
4d779342
DB
63#ifndef HAVE_epilogue
64#define HAVE_epilogue 0
65#endif
66#ifndef HAVE_prologue
67#define HAVE_prologue 0
68#endif
69#ifndef HAVE_sibcall_epilogue
70#define HAVE_sibcall_epilogue 0
71#endif
72
73#ifndef EPILOGUE_USES
74#define EPILOGUE_USES(REGNO) 0
75#endif
76
370f38e8
KZ
77/* The following two macros free the vecs that hold either the refs or
78 the mw refs. They are a little tricky because the vec has 0
b8698a0f 79 elements is special and is not to be freed. */
370f38e8
KZ
80#define df_scan_free_ref_vec(V) \
81 do { \
82 if (V && *V) \
83 free (V); \
84 } while (0)
85
86#define df_scan_free_mws_vec(V) \
87 do { \
88 if (V && *V) \
89 free (V); \
90 } while (0)
91
4d779342
DB
92/* The set of hard registers in eliminables[i].from. */
93
94static HARD_REG_SET elim_reg_set;
95
4d779342
DB
96/* Initialize ur_in and ur_out as if all hard registers were partially
97 available. */
98
6fb5fa3c
DB
99struct df_collection_rec
100{
c2569604
ILT
101 VEC(df_ref,stack) *def_vec;
102 VEC(df_ref,stack) *use_vec;
103 VEC(df_ref,stack) *eq_use_vec;
104 VEC(df_mw_hardreg_ptr,stack) *mw_vec;
6fb5fa3c
DB
105};
106
57512f53 107static df_ref df_null_ref_rec[1];
6fb5fa3c
DB
108static struct df_mw_hardreg * df_null_mw_rec[1];
109
57512f53 110static void df_ref_record (enum df_ref_class, struct df_collection_rec *,
b8698a0f 111 rtx, rtx *,
50e94c7e 112 basic_block, struct df_insn_info *,
bbbbb16a 113 enum df_ref_type, int ref_flags,
50e94c7e
SB
114 int, int, enum machine_mode);
115static void df_def_record_1 (struct df_collection_rec *, rtx,
116 basic_block, struct df_insn_info *,
bbbbb16a 117 int ref_flags);
50e94c7e
SB
118static void df_defs_record (struct df_collection_rec *, rtx,
119 basic_block, struct df_insn_info *,
bbbbb16a 120 int ref_flags);
57512f53 121static void df_uses_record (enum df_ref_class, struct df_collection_rec *,
6fb5fa3c 122 rtx *, enum df_ref_type,
50e94c7e 123 basic_block, struct df_insn_info *,
b8698a0f 124 int ref_flags,
cc806ac1 125 int, int, enum machine_mode);
4d779342 126
b8698a0f
L
127static df_ref df_ref_create_structure (enum df_ref_class,
128 struct df_collection_rec *, rtx, rtx *,
57512f53 129 basic_block, struct df_insn_info *,
bbbbb16a 130 enum df_ref_type, int ref_flags,
57512f53 131 int, int, enum machine_mode);
6fb5fa3c 132
b8698a0f
L
133static void df_insn_refs_collect (struct df_collection_rec*,
134 basic_block, struct df_insn_info *);
6fb5fa3c
DB
135static void df_canonize_collection_rec (struct df_collection_rec *);
136
137static void df_get_regular_block_artificial_uses (bitmap);
138static void df_get_eh_block_artificial_uses (bitmap);
139
140static void df_record_entry_block_defs (bitmap);
141static void df_record_exit_block_uses (bitmap);
142static void df_get_exit_block_use_set (bitmap);
143static void df_get_entry_block_def_set (bitmap);
4d779342 144static void df_grow_ref_info (struct df_ref_info *, unsigned int);
57512f53
KZ
145static void df_ref_chain_delete_du_chain (df_ref *);
146static void df_ref_chain_delete (df_ref *);
4d779342 147
b8698a0f 148static void df_refs_add_to_chains (struct df_collection_rec *,
6fb5fa3c
DB
149 basic_block, rtx);
150
151static bool df_insn_refs_verify (struct df_collection_rec *, basic_block, rtx, bool);
152static void df_entry_block_defs_collect (struct df_collection_rec *, bitmap);
153static void df_exit_block_uses_collect (struct df_collection_rec *, bitmap);
b8698a0f 154static void df_install_ref (df_ref, struct df_reg_info *,
6fb5fa3c
DB
155 struct df_ref_info *, bool);
156
157static int df_ref_compare (const void *, const void *);
158static int df_mw_compare (const void *, const void *);
159
160/* Indexed by hardware reg number, is true if that register is ever
161 used in the current function.
162
163 In df-scan.c, this is set up to record the hard regs used
164 explicitly. Reload adds in the hard regs used for holding pseudo
165 regs. Final uses it to generate the code in the function prologue
166 and epilogue to save and restore registers as needed. */
167
168static bool regs_ever_live[FIRST_PSEUDO_REGISTER];
4d779342
DB
169\f
170/*----------------------------------------------------------------------------
171 SCANNING DATAFLOW PROBLEM
172
173 There are several ways in which scanning looks just like the other
174 dataflow problems. It shares the all the mechanisms for local info
175 as well as basic block info. Where it differs is when and how often
176 it gets run. It also has no need for the iterative solver.
177----------------------------------------------------------------------------*/
178
179/* Problem data for the scanning dataflow function. */
180struct df_scan_problem_data
181{
57512f53
KZ
182 alloc_pool ref_base_pool;
183 alloc_pool ref_artificial_pool;
184 alloc_pool ref_regular_pool;
ca9052ce 185 alloc_pool ref_extract_pool;
4d779342
DB
186 alloc_pool insn_pool;
187 alloc_pool reg_pool;
23249ac4 188 alloc_pool mw_reg_pool;
6fb5fa3c
DB
189 bitmap_obstack reg_bitmaps;
190 bitmap_obstack insn_bitmaps;
4d779342
DB
191};
192
193typedef struct df_scan_bb_info *df_scan_bb_info_t;
194
370f38e8
KZ
195
196/* Internal function to shut down the scanning problem. */
b8698a0f 197static void
6fb5fa3c 198df_scan_free_internal (void)
4d779342 199{
23249ac4 200 struct df_scan_problem_data *problem_data
6fb5fa3c 201 = (struct df_scan_problem_data *) df_scan->problem_data;
370f38e8
KZ
202 unsigned int i;
203 basic_block bb;
204
205 /* The vectors that hold the refs are not pool allocated because
206 they come in many sizes. This makes them impossible to delete
207 all at once. */
208 for (i = 0; i < DF_INSN_SIZE(); i++)
209 {
210 struct df_insn_info *insn_info = DF_INSN_UID_GET(i);
211 /* Skip the insns that have no insn_info or have been
212 deleted. */
213 if (insn_info)
214 {
215 df_scan_free_ref_vec (insn_info->defs);
216 df_scan_free_ref_vec (insn_info->uses);
217 df_scan_free_ref_vec (insn_info->eq_uses);
218 df_scan_free_mws_vec (insn_info->mw_hardregs);
219 }
220 }
221
222 FOR_ALL_BB (bb)
223 {
224 unsigned int bb_index = bb->index;
225 struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb_index);
226 if (bb_info)
227 {
228 df_scan_free_ref_vec (bb_info->artificial_defs);
229 df_scan_free_ref_vec (bb_info->artificial_uses);
230 }
231 }
4d779342 232
4d779342 233 free (df->def_info.refs);
6fb5fa3c
DB
234 free (df->def_info.begin);
235 free (df->def_info.count);
4d779342
DB
236 memset (&df->def_info, 0, (sizeof (struct df_ref_info)));
237
4d779342 238 free (df->use_info.refs);
6fb5fa3c
DB
239 free (df->use_info.begin);
240 free (df->use_info.count);
4d779342
DB
241 memset (&df->use_info, 0, (sizeof (struct df_ref_info)));
242
6fb5fa3c
DB
243 free (df->def_regs);
244 df->def_regs = NULL;
245 free (df->use_regs);
246 df->use_regs = NULL;
247 free (df->eq_use_regs);
248 df->eq_use_regs = NULL;
249 df->regs_size = 0;
250 DF_REG_SIZE(df) = 0;
251
4d779342
DB
252 free (df->insns);
253 df->insns = NULL;
6fb5fa3c 254 DF_INSN_SIZE () = 0;
4d779342 255
6fb5fa3c
DB
256 free (df_scan->block_info);
257 df_scan->block_info = NULL;
258 df_scan->block_info_size = 0;
4d779342 259
a7e3698d
JH
260 bitmap_clear (&df->hardware_regs_used);
261 bitmap_clear (&df->regular_block_artificial_uses);
262 bitmap_clear (&df->eh_block_artificial_uses);
912f2dac 263 BITMAP_FREE (df->entry_block_defs);
4d779342 264 BITMAP_FREE (df->exit_block_uses);
a7e3698d
JH
265 bitmap_clear (&df->insns_to_delete);
266 bitmap_clear (&df->insns_to_rescan);
267 bitmap_clear (&df->insns_to_notes_rescan);
4d779342 268
57512f53
KZ
269 free_alloc_pool (problem_data->ref_base_pool);
270 free_alloc_pool (problem_data->ref_artificial_pool);
271 free_alloc_pool (problem_data->ref_regular_pool);
ca9052ce 272 free_alloc_pool (problem_data->ref_extract_pool);
4d779342
DB
273 free_alloc_pool (problem_data->insn_pool);
274 free_alloc_pool (problem_data->reg_pool);
23249ac4 275 free_alloc_pool (problem_data->mw_reg_pool);
6fb5fa3c
DB
276 bitmap_obstack_release (&problem_data->reg_bitmaps);
277 bitmap_obstack_release (&problem_data->insn_bitmaps);
278 free (df_scan->problem_data);
4d779342
DB
279}
280
281
4d779342
DB
282/* Free basic block info. */
283
284static void
6fb5fa3c 285df_scan_free_bb_info (basic_block bb, void *vbb_info)
4d779342
DB
286{
287 struct df_scan_bb_info *bb_info = (struct df_scan_bb_info *) vbb_info;
6fb5fa3c 288 unsigned int bb_index = bb->index;
e285df08
JH
289
290 /* See if bb_info is initialized. */
291 if (bb_info->artificial_defs)
3b8266e2 292 {
6fb5fa3c
DB
293 rtx insn;
294 FOR_BB_INSNS (bb, insn)
295 {
296 if (INSN_P (insn))
297 /* Record defs within INSN. */
298 df_insn_delete (bb, INSN_UID (insn));
299 }
b8698a0f 300
6fb5fa3c
DB
301 if (bb_index < df_scan->block_info_size)
302 bb_info = df_scan_get_bb_info (bb_index);
b8698a0f 303
6fb5fa3c 304 /* Get rid of any artificial uses or defs. */
e285df08
JH
305 if (bb_info->artificial_defs)
306 {
307 df_ref_chain_delete_du_chain (bb_info->artificial_defs);
308 df_ref_chain_delete_du_chain (bb_info->artificial_uses);
309 df_ref_chain_delete (bb_info->artificial_defs);
310 df_ref_chain_delete (bb_info->artificial_uses);
311 bb_info->artificial_defs = NULL;
312 bb_info->artificial_uses = NULL;
313 }
3b8266e2 314 }
4d779342
DB
315}
316
317
318/* Allocate the problem data for the scanning problem. This should be
319 called when the problem is created or when the entire function is to
320 be rescanned. */
b8698a0f 321void
6fb5fa3c 322df_scan_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
4d779342 323{
4d779342
DB
324 struct df_scan_problem_data *problem_data;
325 unsigned int insn_num = get_max_uid () + 1;
6fb5fa3c
DB
326 unsigned int block_size = 400;
327 basic_block bb;
4d779342
DB
328
329 /* Given the number of pools, this is really faster than tearing
330 everything apart. */
6fb5fa3c
DB
331 if (df_scan->problem_data)
332 df_scan_free_internal ();
4d779342 333
5ed6ace5 334 problem_data = XNEW (struct df_scan_problem_data);
6fb5fa3c
DB
335 df_scan->problem_data = problem_data;
336 df_scan->computed = true;
4d779342 337
b8698a0f
L
338 problem_data->ref_base_pool
339 = create_alloc_pool ("df_scan ref base",
57512f53 340 sizeof (struct df_base_ref), block_size);
b8698a0f
L
341 problem_data->ref_artificial_pool
342 = create_alloc_pool ("df_scan ref artificial",
57512f53 343 sizeof (struct df_artificial_ref), block_size);
b8698a0f
L
344 problem_data->ref_regular_pool
345 = create_alloc_pool ("df_scan ref regular",
57512f53 346 sizeof (struct df_regular_ref), block_size);
b8698a0f
L
347 problem_data->ref_extract_pool
348 = create_alloc_pool ("df_scan ref extract",
57512f53 349 sizeof (struct df_extract_ref), block_size);
b8698a0f
L
350 problem_data->insn_pool
351 = create_alloc_pool ("df_scan insn",
4d779342 352 sizeof (struct df_insn_info), block_size);
b8698a0f
L
353 problem_data->reg_pool
354 = create_alloc_pool ("df_scan reg",
4d779342 355 sizeof (struct df_reg_info), block_size);
b8698a0f
L
356 problem_data->mw_reg_pool
357 = create_alloc_pool ("df_scan mw_reg",
23249ac4 358 sizeof (struct df_mw_hardreg), block_size);
4d779342 359
6fb5fa3c
DB
360 bitmap_obstack_initialize (&problem_data->reg_bitmaps);
361 bitmap_obstack_initialize (&problem_data->insn_bitmaps);
4d779342 362
b8698a0f 363 insn_num += insn_num / 4;
6fb5fa3c 364 df_grow_reg_info ();
4d779342 365
6fb5fa3c
DB
366 df_grow_insn_info ();
367 df_grow_bb_info (df_scan);
4d779342 368
6fb5fa3c 369 FOR_ALL_BB (bb)
4d779342 370 {
6fb5fa3c
DB
371 unsigned int bb_index = bb->index;
372 struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb_index);
4d779342
DB
373 bb_info->artificial_defs = NULL;
374 bb_info->artificial_uses = NULL;
375 }
376
a7e3698d
JH
377 bitmap_initialize (&df->hardware_regs_used, &problem_data->reg_bitmaps);
378 bitmap_initialize (&df->regular_block_artificial_uses, &problem_data->reg_bitmaps);
379 bitmap_initialize (&df->eh_block_artificial_uses, &problem_data->reg_bitmaps);
6fb5fa3c
DB
380 df->entry_block_defs = BITMAP_ALLOC (&problem_data->reg_bitmaps);
381 df->exit_block_uses = BITMAP_ALLOC (&problem_data->reg_bitmaps);
a7e3698d
JH
382 bitmap_initialize (&df->insns_to_delete, &problem_data->insn_bitmaps);
383 bitmap_initialize (&df->insns_to_rescan, &problem_data->insn_bitmaps);
384 bitmap_initialize (&df->insns_to_notes_rescan, &problem_data->insn_bitmaps);
89a95777 385 df_scan->optional_p = false;
4d779342
DB
386}
387
388
389/* Free all of the data associated with the scan problem. */
390
b8698a0f 391static void
6fb5fa3c 392df_scan_free (void)
4d779342 393{
6fb5fa3c
DB
394 if (df_scan->problem_data)
395 df_scan_free_internal ();
3b8266e2 396
4d779342 397 if (df->blocks_to_analyze)
6fb5fa3c
DB
398 {
399 BITMAP_FREE (df->blocks_to_analyze);
400 df->blocks_to_analyze = NULL;
401 }
4d779342 402
6fb5fa3c 403 free (df_scan);
4d779342
DB
404}
405
6fb5fa3c 406/* Dump the preamble for DF_SCAN dump. */
b8698a0f 407static void
6fb5fa3c 408df_scan_start_dump (FILE *file ATTRIBUTE_UNUSED)
4d779342 409{
4d779342 410 int i;
57512f53
KZ
411 int dcount = 0;
412 int ucount = 0;
413 int ecount = 0;
414 int icount = 0;
415 int ccount = 0;
416 basic_block bb;
417 rtx insn;
4d779342 418
6fb5fa3c 419 fprintf (file, ";; invalidated by call \t");
f2ecb626 420 df_print_regset (file, regs_invalidated_by_call_regset);
6fb5fa3c 421 fprintf (file, ";; hardware regs used \t");
a7e3698d 422 df_print_regset (file, &df->hardware_regs_used);
6fb5fa3c 423 fprintf (file, ";; regular block artificial uses \t");
a7e3698d 424 df_print_regset (file, &df->regular_block_artificial_uses);
6fb5fa3c 425 fprintf (file, ";; eh block artificial uses \t");
a7e3698d 426 df_print_regset (file, &df->eh_block_artificial_uses);
6fb5fa3c
DB
427 fprintf (file, ";; entry block defs \t");
428 df_print_regset (file, df->entry_block_defs);
429 fprintf (file, ";; exit block uses \t");
430 df_print_regset (file, df->exit_block_uses);
431 fprintf (file, ";; regs ever live \t");
4d779342 432 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
6fb5fa3c
DB
433 if (df_regs_ever_live_p (i))
434 fprintf (file, " %d[%s]", i, reg_names[i]);
57512f53 435 fprintf (file, "\n;; ref usage \t");
b8698a0f 436
57512f53
KZ
437 for (i = 0; i < (int)df->regs_inited; i++)
438 if (DF_REG_DEF_COUNT (i) || DF_REG_USE_COUNT (i) || DF_REG_EQ_USE_COUNT (i))
439 {
440 const char * sep = "";
441
442 fprintf (file, "r%d={", i);
443 if (DF_REG_DEF_COUNT (i))
444 {
445 fprintf (file, "%dd", DF_REG_DEF_COUNT (i));
446 sep = ",";
447 dcount += DF_REG_DEF_COUNT (i);
448 }
449 if (DF_REG_USE_COUNT (i))
450 {
451 fprintf (file, "%s%du", sep, DF_REG_USE_COUNT (i));
452 sep = ",";
453 ucount += DF_REG_USE_COUNT (i);
454 }
455 if (DF_REG_EQ_USE_COUNT (i))
456 {
457 fprintf (file, "%s%dd", sep, DF_REG_EQ_USE_COUNT (i));
458 ecount += DF_REG_EQ_USE_COUNT (i);
459 }
460 fprintf (file, "} ");
461 }
6fb5fa3c 462
57512f53
KZ
463 FOR_EACH_BB (bb)
464 FOR_BB_INSNS (bb, insn)
465 if (INSN_P (insn))
466 {
467 if (CALL_P (insn))
468 ccount++;
469 else
470 icount++;
471 }
472
b8698a0f 473 fprintf (file, "\n;; total ref usage %d{%dd,%du,%de} in %d{%d regular + %d call} insns.\n",
57512f53 474 dcount + ucount + ecount, dcount, ucount, ecount, icount + ccount, icount, ccount);
4d779342
DB
475}
476
6fb5fa3c 477/* Dump the bb_info for a given basic block. */
b8698a0f 478static void
6fb5fa3c
DB
479df_scan_start_block (basic_block bb, FILE *file)
480{
481 struct df_scan_bb_info *bb_info
482 = df_scan_get_bb_info (bb->index);
483
484 if (bb_info)
485 {
486 fprintf (file, ";; bb %d artificial_defs: ", bb->index);
487 df_refs_chain_dump (bb_info->artificial_defs, true, file);
488 fprintf (file, "\n;; bb %d artificial_uses: ", bb->index);
489 df_refs_chain_dump (bb_info->artificial_uses, true, file);
490 fprintf (file, "\n");
491 }
492#if 0
493 {
494 rtx insn;
495 FOR_BB_INSNS (bb, insn)
496 if (INSN_P (insn))
497 df_insn_debug (insn, false, file);
498 }
499#endif
500}
501
4d779342
DB
502static struct df_problem problem_SCAN =
503{
504 DF_SCAN, /* Problem id. */
505 DF_NONE, /* Direction. */
506 df_scan_alloc, /* Allocate the problem specific data. */
30cb87a0 507 NULL, /* Reset global information. */
4d779342
DB
508 df_scan_free_bb_info, /* Free basic block info. */
509 NULL, /* Local compute function. */
510 NULL, /* Init the solution specific data. */
511 NULL, /* Iterative solver. */
b8698a0f
L
512 NULL, /* Confluence operator 0. */
513 NULL, /* Confluence operator n. */
4d779342
DB
514 NULL, /* Transfer function. */
515 NULL, /* Finalize function. */
516 df_scan_free, /* Free all of the problem information. */
6fb5fa3c
DB
517 NULL, /* Remove this problem from the stack of dataflow problems. */
518 df_scan_start_dump, /* Debugging. */
519 df_scan_start_block, /* Debugging start block. */
520 NULL, /* Debugging end block. */
521 NULL, /* Incremental solution verify start. */
6ed3da00 522 NULL, /* Incremental solution verify end. */
23249ac4 523 NULL, /* Dependent problem. */
e285df08 524 sizeof (struct df_scan_bb_info),/* Size of entry of block_info array. */
89a95777
KZ
525 TV_DF_SCAN, /* Timing variable. */
526 false /* Reset blocks on dropping out of blocks_to_analyze. */
4d779342
DB
527};
528
529
530/* Create a new DATAFLOW instance and add it to an existing instance
531 of DF. The returned structure is what is used to get at the
532 solution. */
533
6fb5fa3c
DB
534void
535df_scan_add_problem (void)
4d779342 536{
6fb5fa3c 537 df_add_problem (&problem_SCAN);
4d779342
DB
538}
539
6fb5fa3c 540\f
4d779342
DB
541/*----------------------------------------------------------------------------
542 Storage Allocation Utilities
543----------------------------------------------------------------------------*/
544
545
546/* First, grow the reg_info information. If the current size is less than
fa10beec 547 the number of pseudos, grow to 25% more than the number of
b8698a0f 548 pseudos.
4d779342
DB
549
550 Second, assure that all of the slots up to max_reg_num have been
551 filled with reg_info structures. */
552
b8698a0f 553void
6fb5fa3c 554df_grow_reg_info (void)
4d779342
DB
555{
556 unsigned int max_reg = max_reg_num ();
557 unsigned int new_size = max_reg;
23249ac4 558 struct df_scan_problem_data *problem_data
6fb5fa3c 559 = (struct df_scan_problem_data *) df_scan->problem_data;
4d779342
DB
560 unsigned int i;
561
6fb5fa3c 562 if (df->regs_size < new_size)
4d779342
DB
563 {
564 new_size += new_size / 4;
f883e0a7
KG
565 df->def_regs = XRESIZEVEC (struct df_reg_info *, df->def_regs, new_size);
566 df->use_regs = XRESIZEVEC (struct df_reg_info *, df->use_regs, new_size);
567 df->eq_use_regs = XRESIZEVEC (struct df_reg_info *, df->eq_use_regs,
568 new_size);
569 df->def_info.begin = XRESIZEVEC (unsigned, df->def_info.begin, new_size);
570 df->def_info.count = XRESIZEVEC (unsigned, df->def_info.count, new_size);
571 df->use_info.begin = XRESIZEVEC (unsigned, df->use_info.begin, new_size);
572 df->use_info.count = XRESIZEVEC (unsigned, df->use_info.count, new_size);
6fb5fa3c 573 df->regs_size = new_size;
4d779342
DB
574 }
575
6fb5fa3c 576 for (i = df->regs_inited; i < max_reg; i++)
4d779342 577 {
6fb5fa3c
DB
578 struct df_reg_info *reg_info;
579
f883e0a7 580 reg_info = (struct df_reg_info *) pool_alloc (problem_data->reg_pool);
6fb5fa3c
DB
581 memset (reg_info, 0, sizeof (struct df_reg_info));
582 df->def_regs[i] = reg_info;
f883e0a7 583 reg_info = (struct df_reg_info *) pool_alloc (problem_data->reg_pool);
6fb5fa3c
DB
584 memset (reg_info, 0, sizeof (struct df_reg_info));
585 df->use_regs[i] = reg_info;
f883e0a7 586 reg_info = (struct df_reg_info *) pool_alloc (problem_data->reg_pool);
4d779342 587 memset (reg_info, 0, sizeof (struct df_reg_info));
6fb5fa3c
DB
588 df->eq_use_regs[i] = reg_info;
589 df->def_info.begin[i] = 0;
590 df->def_info.count[i] = 0;
591 df->use_info.begin[i] = 0;
592 df->use_info.count[i] = 0;
4d779342 593 }
b8698a0f 594
6fb5fa3c 595 df->regs_inited = max_reg;
4d779342
DB
596}
597
598
599/* Grow the ref information. */
600
b8698a0f 601static void
4d779342
DB
602df_grow_ref_info (struct df_ref_info *ref_info, unsigned int new_size)
603{
604 if (ref_info->refs_size < new_size)
605 {
57512f53 606 ref_info->refs = XRESIZEVEC (df_ref, ref_info->refs, new_size);
4d779342 607 memset (ref_info->refs + ref_info->refs_size, 0,
57512f53 608 (new_size - ref_info->refs_size) *sizeof (df_ref));
4d779342
DB
609 ref_info->refs_size = new_size;
610 }
611}
612
613
6fb5fa3c
DB
614/* Check and grow the ref information if necessary. This routine
615 guarantees total_size + BITMAP_ADDEND amount of entries in refs
616 array. It updates ref_info->refs_size only and does not change
617 ref_info->total_size. */
618
619static void
b8698a0f 620df_check_and_grow_ref_info (struct df_ref_info *ref_info,
6fb5fa3c
DB
621 unsigned bitmap_addend)
622{
623 if (ref_info->refs_size < ref_info->total_size + bitmap_addend)
624 {
625 int new_size = ref_info->total_size + bitmap_addend;
626 new_size += ref_info->total_size / 4;
627 df_grow_ref_info (ref_info, new_size);
628 }
629}
630
631
4d779342
DB
632/* Grow the ref information. If the current size is less than the
633 number of instructions, grow to 25% more than the number of
634 instructions. */
635
b8698a0f 636void
6fb5fa3c 637df_grow_insn_info (void)
4d779342
DB
638{
639 unsigned int new_size = get_max_uid () + 1;
6fb5fa3c 640 if (DF_INSN_SIZE () < new_size)
4d779342
DB
641 {
642 new_size += new_size / 4;
f883e0a7 643 df->insns = XRESIZEVEC (struct df_insn_info *, df->insns, new_size);
4d779342 644 memset (df->insns + df->insns_size, 0,
6fb5fa3c
DB
645 (new_size - DF_INSN_SIZE ()) *sizeof (struct df_insn_info *));
646 DF_INSN_SIZE () = new_size;
4d779342
DB
647 }
648}
649
650
651
652\f
653/*----------------------------------------------------------------------------
654 PUBLIC INTERFACES FOR SMALL GRAIN CHANGES TO SCANNING.
655----------------------------------------------------------------------------*/
656
6fb5fa3c
DB
657/* Rescan all of the block_to_analyze or all of the blocks in the
658 function if df_set_blocks if blocks_to_analyze is NULL; */
4d779342
DB
659
660void
6fb5fa3c 661df_scan_blocks (void)
4d779342 662{
4d779342
DB
663 basic_block bb;
664
6fb5fa3c
DB
665 df->def_info.ref_order = DF_REF_ORDER_NO_TABLE;
666 df->use_info.ref_order = DF_REF_ORDER_NO_TABLE;
23249ac4 667
a7e3698d
JH
668 df_get_regular_block_artificial_uses (&df->regular_block_artificial_uses);
669 df_get_eh_block_artificial_uses (&df->eh_block_artificial_uses);
4d779342 670
a7e3698d
JH
671 bitmap_ior_into (&df->eh_block_artificial_uses,
672 &df->regular_block_artificial_uses);
30cb87a0 673
6fb5fa3c
DB
674 /* ENTRY and EXIT blocks have special defs/uses. */
675 df_get_entry_block_def_set (df->entry_block_defs);
676 df_record_entry_block_defs (df->entry_block_defs);
677 df_get_exit_block_use_set (df->exit_block_uses);
678 df_record_exit_block_uses (df->exit_block_uses);
679 df_set_bb_dirty (BASIC_BLOCK (ENTRY_BLOCK));
680 df_set_bb_dirty (BASIC_BLOCK (EXIT_BLOCK));
4d779342 681
6fb5fa3c
DB
682 /* Regular blocks */
683 FOR_EACH_BB (bb)
4d779342 684 {
6fb5fa3c
DB
685 unsigned int bb_index = bb->index;
686 df_bb_refs_record (bb_index, true);
4d779342 687 }
4d779342
DB
688}
689
23249ac4 690
4d779342 691/* Create a new ref of type DF_REF_TYPE for register REG at address
b8698a0f 692 LOC within INSN of BB. This function is only used externally.
ca9052ce
KZ
693
694 If the REF_FLAGS field contain DF_REF_SIGN_EXTRACT or
cc806ac1
RS
695 DF_REF_ZERO_EXTRACT. WIDTH, OFFSET and MODE are used to access the
696 fields if they were constants. Otherwise they should be -1 if
697 those flags were set. */
4d779342 698
b8698a0f
L
699df_ref
700df_ref_create (rtx reg, rtx *loc, rtx insn,
4d779342 701 basic_block bb,
b8698a0f 702 enum df_ref_type ref_type,
bbbbb16a 703 int ref_flags,
cc806ac1 704 int width, int offset, enum machine_mode mode)
4d779342 705{
57512f53 706 df_ref ref;
6fb5fa3c
DB
707 struct df_reg_info **reg_info;
708 struct df_ref_info *ref_info;
57512f53
KZ
709 df_ref *ref_rec;
710 df_ref **ref_rec_ptr;
6fb5fa3c
DB
711 unsigned int count = 0;
712 bool add_to_table;
57512f53 713 enum df_ref_class cl;
4d779342 714
6fb5fa3c 715 df_grow_reg_info ();
4d779342 716
6fb5fa3c
DB
717 /* You cannot hack artificial refs. */
718 gcc_assert (insn);
57512f53
KZ
719
720 if (width != -1 || offset != -1)
721 cl = DF_REF_EXTRACT;
722 else if (loc)
723 cl = DF_REF_REGULAR;
724 else
725 cl = DF_REF_BASE;
726 ref = df_ref_create_structure (cl, NULL, reg, loc, bb, DF_INSN_INFO_GET (insn),
b8698a0f 727 ref_type, ref_flags,
cc806ac1 728 width, offset, mode);
4d779342 729
57512f53 730 if (DF_REF_REG_DEF_P (ref))
6fb5fa3c
DB
731 {
732 reg_info = df->def_regs;
733 ref_info = &df->def_info;
734 ref_rec_ptr = &DF_INSN_DEFS (insn);
735 add_to_table = ref_info->ref_order != DF_REF_ORDER_NO_TABLE;
736 }
737 else if (DF_REF_FLAGS (ref) & DF_REF_IN_NOTE)
738 {
739 reg_info = df->eq_use_regs;
740 ref_info = &df->use_info;
741 ref_rec_ptr = &DF_INSN_EQ_USES (insn);
742 switch (ref_info->ref_order)
743 {
744 case DF_REF_ORDER_UNORDERED_WITH_NOTES:
745 case DF_REF_ORDER_BY_REG_WITH_NOTES:
746 case DF_REF_ORDER_BY_INSN_WITH_NOTES:
747 add_to_table = true;
748 break;
749 default:
750 add_to_table = false;
751 break;
752 }
753 }
754 else
755 {
756 reg_info = df->use_regs;
757 ref_info = &df->use_info;
758 ref_rec_ptr = &DF_INSN_USES (insn);
759 add_to_table = ref_info->ref_order != DF_REF_ORDER_NO_TABLE;
760 }
4d779342 761
6fb5fa3c
DB
762 /* Do not add if ref is not in the right blocks. */
763 if (add_to_table && df->analyze_subset)
764 add_to_table = bitmap_bit_p (df->blocks_to_analyze, bb->index);
4d779342 765
6fb5fa3c 766 df_install_ref (ref, reg_info[DF_REF_REGNO (ref)], ref_info, add_to_table);
b8698a0f 767
6fb5fa3c
DB
768 if (add_to_table)
769 switch (ref_info->ref_order)
770 {
771 case DF_REF_ORDER_UNORDERED_WITH_NOTES:
772 case DF_REF_ORDER_BY_REG_WITH_NOTES:
773 case DF_REF_ORDER_BY_INSN_WITH_NOTES:
774 ref_info->ref_order = DF_REF_ORDER_UNORDERED_WITH_NOTES;
775 break;
776 default:
777 ref_info->ref_order = DF_REF_ORDER_UNORDERED;
778 break;
779 }
4d779342 780
6fb5fa3c
DB
781 ref_rec = *ref_rec_ptr;
782 while (*ref_rec)
783 {
784 count++;
785 ref_rec++;
786 }
4d779342 787
6fb5fa3c
DB
788 ref_rec = *ref_rec_ptr;
789 if (count)
4d779342 790 {
57512f53 791 ref_rec = XRESIZEVEC (df_ref, ref_rec, count+2);
6fb5fa3c
DB
792 *ref_rec_ptr = ref_rec;
793 ref_rec[count] = ref;
794 ref_rec[count+1] = NULL;
57512f53 795 qsort (ref_rec, count + 1, sizeof (df_ref), df_ref_compare);
6fb5fa3c
DB
796 }
797 else
798 {
57512f53 799 df_ref *ref_rec = XNEWVEC (df_ref, 2);
6fb5fa3c
DB
800 ref_rec[0] = ref;
801 ref_rec[1] = NULL;
802 *ref_rec_ptr = ref_rec;
803 }
4d779342 804
6fb5fa3c
DB
805#if 0
806 if (dump_file)
807 {
808 fprintf (dump_file, "adding ref ");
809 df_ref_debug (ref, dump_file);
4d779342 810 }
6fb5fa3c
DB
811#endif
812 /* By adding the ref directly, df_insn_rescan my not find any
813 differences even though the block will have changed. So we need
b8698a0f 814 to mark the block dirty ourselves. */
d785e46f
AO
815 if (!DEBUG_INSN_P (DF_REF_INSN (ref)))
816 df_set_bb_dirty (bb);
4d779342 817
6fb5fa3c 818 return ref;
4d779342
DB
819}
820
821
6fb5fa3c
DB
822\f
823/*----------------------------------------------------------------------------
824 UTILITIES TO CREATE AND DESTROY REFS AND CHAINS.
825----------------------------------------------------------------------------*/
826
ca9052ce 827static void
57512f53 828df_free_ref (df_ref ref)
ca9052ce
KZ
829{
830 struct df_scan_problem_data *problem_data
831 = (struct df_scan_problem_data *) df_scan->problem_data;
832
57512f53
KZ
833 switch (DF_REF_CLASS (ref))
834 {
835 case DF_REF_BASE:
836 pool_free (problem_data->ref_base_pool, ref);
837 break;
838
839 case DF_REF_ARTIFICIAL:
840 pool_free (problem_data->ref_artificial_pool, ref);
841 break;
842
843 case DF_REF_REGULAR:
844 pool_free (problem_data->ref_regular_pool, ref);
845 break;
846
847 case DF_REF_EXTRACT:
848 pool_free (problem_data->ref_extract_pool, ref);
849 break;
850 }
ca9052ce
KZ
851}
852
4d779342 853
6fb5fa3c
DB
854/* Unlink and delete REF at the reg_use, reg_eq_use or reg_def chain.
855 Also delete the def-use or use-def chain if it exists. */
856
857static void
b8698a0f 858df_reg_chain_unlink (df_ref ref)
4d779342 859{
b8698a0f 860 df_ref next = DF_REF_NEXT_REG (ref);
57512f53 861 df_ref prev = DF_REF_PREV_REG (ref);
6fb5fa3c 862 int id = DF_REF_ID (ref);
4d779342 863 struct df_reg_info *reg_info;
57512f53 864 df_ref *refs = NULL;
4d779342 865
57512f53 866 if (DF_REF_REG_DEF_P (ref))
4d779342 867 {
57512f53
KZ
868 int regno = DF_REF_REGNO (ref);
869 reg_info = DF_REG_DEF_GET (regno);
6fb5fa3c 870 refs = df->def_info.refs;
4d779342 871 }
b8698a0f 872 else
4d779342 873 {
6fb5fa3c
DB
874 if (DF_REF_FLAGS (ref) & DF_REF_IN_NOTE)
875 {
876 reg_info = DF_REG_EQ_USE_GET (DF_REF_REGNO (ref));
877 switch (df->use_info.ref_order)
878 {
879 case DF_REF_ORDER_UNORDERED_WITH_NOTES:
880 case DF_REF_ORDER_BY_REG_WITH_NOTES:
881 case DF_REF_ORDER_BY_INSN_WITH_NOTES:
882 refs = df->use_info.refs;
883 break;
884 default:
885 break;
886 }
887 }
888 else
889 {
890 reg_info = DF_REG_USE_GET (DF_REF_REGNO (ref));
891 refs = df->use_info.refs;
892 }
893 }
894
895 if (refs)
896 {
897 if (df->analyze_subset)
898 {
57512f53 899 if (bitmap_bit_p (df->blocks_to_analyze, DF_REF_BBNO (ref)))
6fb5fa3c
DB
900 refs[id] = NULL;
901 }
902 else
903 refs[id] = NULL;
4d779342 904 }
b8698a0f 905
6fb5fa3c
DB
906 /* Delete any def-use or use-def chains that start here. It is
907 possible that there is trash in this field. This happens for
908 insns that have been deleted when rescanning has been deferred
909 and the chain problem has also been deleted. The chain tear down
910 code skips deleted insns. */
911 if (df_chain && DF_REF_CHAIN (ref))
912 df_chain_unlink (ref);
b8698a0f 913
4d779342 914 reg_info->n_refs--;
6fb5fa3c
DB
915 if (DF_REF_FLAGS_IS_SET (ref, DF_HARD_REG_LIVE))
916 {
917 gcc_assert (DF_REF_REGNO (ref) < FIRST_PSEUDO_REGISTER);
918 df->hard_regs_live_count[DF_REF_REGNO (ref)]--;
919 }
4d779342
DB
920
921 /* Unlink from the reg chain. If there is no prev, this is the
922 first of the list. If not, just join the next and prev. */
923 if (prev)
6fb5fa3c 924 DF_REF_NEXT_REG (prev) = next;
4d779342
DB
925 else
926 {
6fb5fa3c 927 gcc_assert (reg_info->reg_chain == ref);
4d779342 928 reg_info->reg_chain = next;
4d779342 929 }
6fb5fa3c
DB
930 if (next)
931 DF_REF_PREV_REG (next) = prev;
4d779342 932
ca9052ce 933 df_free_ref (ref);
6fb5fa3c
DB
934}
935
936
937/* Remove REF from VEC. */
938
939static void
57512f53 940df_ref_compress_rec (df_ref **vec_ptr, df_ref ref)
6fb5fa3c 941{
57512f53 942 df_ref *vec = *vec_ptr;
6fb5fa3c
DB
943
944 if (vec[1])
945 {
946 while (*vec && *vec != ref)
947 vec++;
b8698a0f 948
6fb5fa3c
DB
949 while (*vec)
950 {
951 *vec = *(vec+1);
952 vec++;
953 }
954 }
955 else
956 {
957 free (vec);
958 *vec_ptr = df_null_ref_rec;
959 }
4d779342
DB
960}
961
962
963/* Unlink REF from all def-use/use-def chains, etc. */
964
965void
57512f53 966df_ref_remove (df_ref ref)
4d779342 967{
6fb5fa3c
DB
968#if 0
969 if (dump_file)
970 {
971 fprintf (dump_file, "removing ref ");
972 df_ref_debug (ref, dump_file);
973 }
974#endif
975
4d779342
DB
976 if (DF_REF_REG_DEF_P (ref))
977 {
6fb5fa3c 978 if (DF_REF_IS_ARTIFICIAL (ref))
4d779342 979 {
b8698a0f 980 struct df_scan_bb_info *bb_info
57512f53 981 = df_scan_get_bb_info (DF_REF_BBNO (ref));
6fb5fa3c 982 df_ref_compress_rec (&bb_info->artificial_defs, ref);
4d779342
DB
983 }
984 else
6fb5fa3c
DB
985 {
986 unsigned int uid = DF_REF_INSN_UID (ref);
987 struct df_insn_info *insn_rec = DF_INSN_UID_GET (uid);
988 df_ref_compress_rec (&insn_rec->defs, ref);
989 }
4d779342
DB
990 }
991 else
992 {
6fb5fa3c 993 if (DF_REF_IS_ARTIFICIAL (ref))
4d779342 994 {
b8698a0f 995 struct df_scan_bb_info *bb_info
57512f53 996 = df_scan_get_bb_info (DF_REF_BBNO (ref));
6fb5fa3c
DB
997 df_ref_compress_rec (&bb_info->artificial_uses, ref);
998 }
b8698a0f 999 else
6fb5fa3c
DB
1000 {
1001 unsigned int uid = DF_REF_INSN_UID (ref);
1002 struct df_insn_info *insn_rec = DF_INSN_UID_GET (uid);
1003
1004 if (DF_REF_FLAGS (ref) & DF_REF_IN_NOTE)
1005 df_ref_compress_rec (&insn_rec->eq_uses, ref);
1006 else
1007 df_ref_compress_rec (&insn_rec->uses, ref);
4d779342 1008 }
4d779342
DB
1009 }
1010
6fb5fa3c
DB
1011 /* By deleting the ref directly, df_insn_rescan my not find any
1012 differences even though the block will have changed. So we need
b8698a0f 1013 to mark the block dirty ourselves. */
d785e46f
AO
1014 if (!DEBUG_INSN_P (DF_REF_INSN (ref)))
1015 df_set_bb_dirty (DF_REF_BB (ref));
6fb5fa3c 1016 df_reg_chain_unlink (ref);
4d779342
DB
1017}
1018
1019
6fb5fa3c
DB
1020/* Create the insn record for INSN. If there was one there, zero it
1021 out. */
4d779342 1022
6fb5fa3c
DB
1023struct df_insn_info *
1024df_insn_create_insn_record (rtx insn)
4d779342 1025{
23249ac4 1026 struct df_scan_problem_data *problem_data
6fb5fa3c
DB
1027 = (struct df_scan_problem_data *) df_scan->problem_data;
1028 struct df_insn_info *insn_rec;
4d779342 1029
6fb5fa3c 1030 df_grow_insn_info ();
50e94c7e 1031 insn_rec = DF_INSN_INFO_GET (insn);
4d779342
DB
1032 if (!insn_rec)
1033 {
f883e0a7 1034 insn_rec = (struct df_insn_info *) pool_alloc (problem_data->insn_pool);
50e94c7e 1035 DF_INSN_INFO_SET (insn, insn_rec);
4d779342
DB
1036 }
1037 memset (insn_rec, 0, sizeof (struct df_insn_info));
6fb5fa3c 1038 insn_rec->insn = insn;
4d779342
DB
1039 return insn_rec;
1040}
1041
3b8266e2 1042
6fb5fa3c 1043/* Delete all du chain (DF_REF_CHAIN()) of all refs in the ref chain. */
4d779342 1044
6fb5fa3c 1045static void
57512f53 1046df_ref_chain_delete_du_chain (df_ref *ref_rec)
4d779342 1047{
6fb5fa3c 1048 while (*ref_rec)
4d779342 1049 {
57512f53 1050 df_ref ref = *ref_rec;
b8698a0f 1051 /* CHAIN is allocated by DF_CHAIN. So make sure to
6fb5fa3c
DB
1052 pass df_scan instance for the problem. */
1053 if (DF_REF_CHAIN (ref))
1054 df_chain_unlink (ref);
1055 ref_rec++;
1056 }
1057}
23249ac4 1058
4d779342 1059
6fb5fa3c
DB
1060/* Delete all refs in the ref chain. */
1061
1062static void
57512f53 1063df_ref_chain_delete (df_ref *ref_rec)
6fb5fa3c 1064{
57512f53 1065 df_ref *start = ref_rec;
6fb5fa3c
DB
1066 while (*ref_rec)
1067 {
1068 df_reg_chain_unlink (*ref_rec);
1069 ref_rec++;
1070 }
1071
1072 /* If the list is empty, it has a special shared element that is not
1073 to be deleted. */
1074 if (*start)
1075 free (start);
1076}
1077
1078
1079/* Delete the hardreg chain. */
1080
1081static void
1082df_mw_hardreg_chain_delete (struct df_mw_hardreg **hardregs)
1083{
1084 struct df_scan_problem_data *problem_data;
1085
1086 if (!hardregs)
1087 return;
1088
1089 problem_data = (struct df_scan_problem_data *) df_scan->problem_data;
1090
1091 while (*hardregs)
1092 {
1093 pool_free (problem_data->mw_reg_pool, *hardregs);
1094 hardregs++;
1095 }
1096}
1097
1098
1099/* Delete all of the refs information from INSN. BB must be passed in
1100 except when called from df_process_deferred_rescans to mark the block
1101 as dirty. */
1102
b8698a0f 1103void
6fb5fa3c
DB
1104df_insn_delete (basic_block bb, unsigned int uid)
1105{
1106 struct df_insn_info *insn_info = NULL;
1107 if (!df)
1108 return;
1109
1110 df_grow_bb_info (df_scan);
1111 df_grow_reg_info ();
1112
1113 /* The block must be marked as dirty now, rather than later as in
1114 df_insn_rescan and df_notes_rescan because it may not be there at
1115 rescanning time and the mark would blow up. */
1116 if (bb)
1117 df_set_bb_dirty (bb);
1118
1119 insn_info = DF_INSN_UID_SAFE_GET (uid);
1120
0a41f3b2 1121 /* The client has deferred rescanning. */
6fb5fa3c
DB
1122 if (df->changeable_flags & DF_DEFER_INSN_RESCAN)
1123 {
1124 if (insn_info)
1125 {
a7e3698d
JH
1126 bitmap_clear_bit (&df->insns_to_rescan, uid);
1127 bitmap_clear_bit (&df->insns_to_notes_rescan, uid);
1128 bitmap_set_bit (&df->insns_to_delete, uid);
6fb5fa3c
DB
1129 }
1130 if (dump_file)
b718216c 1131 fprintf (dump_file, "deferring deletion of insn with uid = %d.\n", uid);
6fb5fa3c
DB
1132 return;
1133 }
1134
1135 if (dump_file)
1136 fprintf (dump_file, "deleting insn with uid = %d.\n", uid);
1137
a7e3698d
JH
1138 bitmap_clear_bit (&df->insns_to_delete, uid);
1139 bitmap_clear_bit (&df->insns_to_rescan, uid);
1140 bitmap_clear_bit (&df->insns_to_notes_rescan, uid);
6fb5fa3c
DB
1141 if (insn_info)
1142 {
b8698a0f 1143 struct df_scan_problem_data *problem_data
6fb5fa3c
DB
1144 = (struct df_scan_problem_data *) df_scan->problem_data;
1145
1146 /* In general, notes do not have the insn_info fields
1147 initialized. However, combine deletes insns by changing them
1148 to notes. How clever. So we cannot just check if it is a
1149 valid insn before short circuiting this code, we need to see
1150 if we actually initialized it. */
1151 if (insn_info->defs)
1152 {
1153 df_mw_hardreg_chain_delete (insn_info->mw_hardregs);
b8698a0f 1154
6fb5fa3c
DB
1155 if (df_chain)
1156 {
1157 df_ref_chain_delete_du_chain (insn_info->defs);
b8698a0f 1158 df_ref_chain_delete_du_chain (insn_info->uses);
6fb5fa3c
DB
1159 df_ref_chain_delete_du_chain (insn_info->eq_uses);
1160 }
b8698a0f 1161
6fb5fa3c
DB
1162 df_ref_chain_delete (insn_info->defs);
1163 df_ref_chain_delete (insn_info->uses);
1164 df_ref_chain_delete (insn_info->eq_uses);
1165 }
4d779342 1166 pool_free (problem_data->insn_pool, insn_info);
6fb5fa3c 1167 DF_INSN_UID_SET (uid, NULL);
4d779342
DB
1168 }
1169}
1170
1171
6fb5fa3c 1172/* Free all of the refs and the mw_hardregs in COLLECTION_REC. */
3b8266e2 1173
6fb5fa3c
DB
1174static void
1175df_free_collection_rec (struct df_collection_rec *collection_rec)
3b8266e2 1176{
c2569604 1177 unsigned int ix;
b8698a0f 1178 struct df_scan_problem_data *problem_data
6fb5fa3c 1179 = (struct df_scan_problem_data *) df_scan->problem_data;
c2569604
ILT
1180 df_ref ref;
1181 struct df_mw_hardreg *mw;
1182
1183 for (ix = 0; VEC_iterate (df_ref, collection_rec->def_vec, ix, ref); ++ix)
1184 df_free_ref (ref);
1185 for (ix = 0; VEC_iterate (df_ref, collection_rec->use_vec, ix, ref); ++ix)
1186 df_free_ref (ref);
1187 for (ix = 0; VEC_iterate (df_ref, collection_rec->eq_use_vec, ix, ref); ++ix)
1188 df_free_ref (ref);
1189 for (ix = 0;
1190 VEC_iterate (df_mw_hardreg_ptr, collection_rec->mw_vec, ix, mw);
1191 ++ix)
1192 pool_free (problem_data->mw_reg_pool, mw);
1193
1194 VEC_free (df_ref, stack, collection_rec->def_vec);
1195 VEC_free (df_ref, stack, collection_rec->use_vec);
1196 VEC_free (df_ref, stack, collection_rec->eq_use_vec);
1197 VEC_free (df_mw_hardreg_ptr, stack, collection_rec->mw_vec);
6fb5fa3c 1198}
3b8266e2 1199
6fb5fa3c
DB
1200/* Rescan INSN. Return TRUE if the rescanning produced any changes. */
1201
b8698a0f 1202bool
6fb5fa3c
DB
1203df_insn_rescan (rtx insn)
1204{
1205 unsigned int uid = INSN_UID (insn);
1206 struct df_insn_info *insn_info = NULL;
1207 basic_block bb = BLOCK_FOR_INSN (insn);
1208 struct df_collection_rec collection_rec;
6fb5fa3c
DB
1209
1210 if ((!df) || (!INSN_P (insn)))
1211 return false;
1212
1213 if (!bb)
3b8266e2 1214 {
6fb5fa3c
DB
1215 if (dump_file)
1216 fprintf (dump_file, "no bb for insn with uid = %d.\n", uid);
1217 return false;
1218 }
1219
1220 /* The client has disabled rescanning and plans to do it itself. */
1221 if (df->changeable_flags & DF_NO_INSN_RESCAN)
1222 return false;
1223
1224 df_grow_bb_info (df_scan);
1225 df_grow_reg_info ();
1226
1227 insn_info = DF_INSN_UID_SAFE_GET (uid);
1228
0a41f3b2 1229 /* The client has deferred rescanning. */
6fb5fa3c
DB
1230 if (df->changeable_flags & DF_DEFER_INSN_RESCAN)
1231 {
1232 if (!insn_info)
1233 {
1234 insn_info = df_insn_create_insn_record (insn);
1235 insn_info->defs = df_null_ref_rec;
1236 insn_info->uses = df_null_ref_rec;
1237 insn_info->eq_uses = df_null_ref_rec;
1238 insn_info->mw_hardregs = df_null_mw_rec;
1239 }
1240 if (dump_file)
b718216c 1241 fprintf (dump_file, "deferring rescan insn with uid = %d.\n", uid);
b8698a0f 1242
a7e3698d
JH
1243 bitmap_clear_bit (&df->insns_to_delete, uid);
1244 bitmap_clear_bit (&df->insns_to_notes_rescan, uid);
1245 bitmap_set_bit (&df->insns_to_rescan, INSN_UID (insn));
6fb5fa3c
DB
1246 return false;
1247 }
1248
c2569604
ILT
1249 collection_rec.def_vec = VEC_alloc (df_ref, stack, 128);
1250 collection_rec.use_vec = VEC_alloc (df_ref, stack, 32);
1251 collection_rec.eq_use_vec = VEC_alloc (df_ref, stack, 32);
1252 collection_rec.mw_vec = VEC_alloc (df_mw_hardreg_ptr, stack, 32);
1253
a7e3698d
JH
1254 bitmap_clear_bit (&df->insns_to_delete, uid);
1255 bitmap_clear_bit (&df->insns_to_rescan, uid);
1256 bitmap_clear_bit (&df->insns_to_notes_rescan, uid);
6fb5fa3c
DB
1257 if (insn_info)
1258 {
4a81774c 1259 int luid;
6fb5fa3c
DB
1260 bool the_same = df_insn_refs_verify (&collection_rec, bb, insn, false);
1261 /* If there's no change, return false. */
1262 if (the_same)
3b8266e2 1263 {
6fb5fa3c
DB
1264 df_free_collection_rec (&collection_rec);
1265 if (dump_file)
1266 fprintf (dump_file, "verify found no changes in insn with uid = %d.\n", uid);
1267 return false;
3b8266e2 1268 }
6fb5fa3c
DB
1269 if (dump_file)
1270 fprintf (dump_file, "rescanning insn with uid = %d.\n", uid);
1271
4a81774c
SB
1272 /* There's change - we need to delete the existing info.
1273 Since the insn isn't moved, we can salvage its LUID. */
1274 luid = DF_INSN_LUID (insn);
6fb5fa3c
DB
1275 df_insn_delete (NULL, uid);
1276 df_insn_create_insn_record (insn);
4a81774c 1277 DF_INSN_LUID (insn) = luid;
6fb5fa3c
DB
1278 }
1279 else
1280 {
50e94c7e
SB
1281 struct df_insn_info *insn_info = df_insn_create_insn_record (insn);
1282 df_insn_refs_collect (&collection_rec, bb, insn_info);
6fb5fa3c
DB
1283 if (dump_file)
1284 fprintf (dump_file, "scanning new insn with uid = %d.\n", uid);
1285 }
1286
1287 df_refs_add_to_chains (&collection_rec, bb, insn);
c23cd1d6
JJ
1288 if (DEBUG_INSN_P (insn))
1289 df_set_bb_dirty_nonlr (bb);
1290 else
1291 df_set_bb_dirty (bb);
c2569604
ILT
1292
1293 VEC_free (df_ref, stack, collection_rec.def_vec);
1294 VEC_free (df_ref, stack, collection_rec.use_vec);
1295 VEC_free (df_ref, stack, collection_rec.eq_use_vec);
1296 VEC_free (df_mw_hardreg_ptr, stack, collection_rec.mw_vec);
1297
6fb5fa3c
DB
1298 return true;
1299}
1300
b5b8b0ac
AO
1301/* Same as df_insn_rescan, but don't mark the basic block as
1302 dirty. */
1303
1304bool
1305df_insn_rescan_debug_internal (rtx insn)
1306{
1307 unsigned int uid = INSN_UID (insn);
1308 struct df_insn_info *insn_info;
1309
a099f7d4
RG
1310 gcc_assert (DEBUG_INSN_P (insn)
1311 && VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn)));
b5b8b0ac
AO
1312
1313 if (!df)
1314 return false;
1315
1316 insn_info = DF_INSN_UID_SAFE_GET (INSN_UID (insn));
1317 if (!insn_info)
1318 return false;
1319
1320 if (dump_file)
1321 fprintf (dump_file, "deleting debug_insn with uid = %d.\n", uid);
1322
a7e3698d
JH
1323 bitmap_clear_bit (&df->insns_to_delete, uid);
1324 bitmap_clear_bit (&df->insns_to_rescan, uid);
1325 bitmap_clear_bit (&df->insns_to_notes_rescan, uid);
b5b8b0ac
AO
1326
1327 if (!insn_info->defs)
1328 return false;
1329
1330 if (insn_info->defs == df_null_ref_rec
1331 && insn_info->uses == df_null_ref_rec
1332 && insn_info->eq_uses == df_null_ref_rec
1333 && insn_info->mw_hardregs == df_null_mw_rec)
1334 return false;
1335
1336 df_mw_hardreg_chain_delete (insn_info->mw_hardregs);
1337
1338 if (df_chain)
1339 {
1340 df_ref_chain_delete_du_chain (insn_info->defs);
1341 df_ref_chain_delete_du_chain (insn_info->uses);
1342 df_ref_chain_delete_du_chain (insn_info->eq_uses);
1343 }
1344
1345 df_ref_chain_delete (insn_info->defs);
1346 df_ref_chain_delete (insn_info->uses);
1347 df_ref_chain_delete (insn_info->eq_uses);
1348
1349 insn_info->defs = df_null_ref_rec;
1350 insn_info->uses = df_null_ref_rec;
1351 insn_info->eq_uses = df_null_ref_rec;
1352 insn_info->mw_hardregs = df_null_mw_rec;
1353
1354 return true;
1355}
1356
6fb5fa3c
DB
1357
1358/* Rescan all of the insns in the function. Note that the artificial
1359 uses and defs are not touched. This function will destroy def-se
1360 or use-def chains. */
1361
1362void
1363df_insn_rescan_all (void)
1364{
1365 bool no_insn_rescan = false;
1366 bool defer_insn_rescan = false;
1367 basic_block bb;
1368 bitmap_iterator bi;
1369 unsigned int uid;
a7e3698d
JH
1370 bitmap_head tmp;
1371
1372 bitmap_initialize (&tmp, &df_bitmap_obstack);
b8698a0f 1373
6fb5fa3c
DB
1374 if (df->changeable_flags & DF_NO_INSN_RESCAN)
1375 {
1376 df_clear_flags (DF_NO_INSN_RESCAN);
1377 no_insn_rescan = true;
3b8266e2 1378 }
b8698a0f 1379
6fb5fa3c 1380 if (df->changeable_flags & DF_DEFER_INSN_RESCAN)
3b8266e2 1381 {
6fb5fa3c
DB
1382 df_clear_flags (DF_DEFER_INSN_RESCAN);
1383 defer_insn_rescan = true;
1384 }
1385
a7e3698d
JH
1386 bitmap_copy (&tmp, &df->insns_to_delete);
1387 EXECUTE_IF_SET_IN_BITMAP (&tmp, 0, uid, bi)
6fb5fa3c
DB
1388 {
1389 struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
1390 if (insn_info)
1391 df_insn_delete (NULL, uid);
3b8266e2 1392 }
6fb5fa3c 1393
a7e3698d
JH
1394 bitmap_clear (&tmp);
1395 bitmap_clear (&df->insns_to_delete);
1396 bitmap_clear (&df->insns_to_rescan);
1397 bitmap_clear (&df->insns_to_notes_rescan);
6fb5fa3c 1398
b8698a0f 1399 FOR_EACH_BB (bb)
6fb5fa3c
DB
1400 {
1401 rtx insn;
1402 FOR_BB_INSNS (bb, insn)
1403 {
1404 df_insn_rescan (insn);
1405 }
1406 }
1407
1408 if (no_insn_rescan)
1409 df_set_flags (DF_NO_INSN_RESCAN);
1410 if (defer_insn_rescan)
1411 df_set_flags (DF_DEFER_INSN_RESCAN);
3b8266e2
KZ
1412}
1413
1414
0a41f3b2 1415/* Process all of the deferred rescans or deletions. */
4d779342 1416
6fb5fa3c
DB
1417void
1418df_process_deferred_rescans (void)
4d779342 1419{
6fb5fa3c
DB
1420 bool no_insn_rescan = false;
1421 bool defer_insn_rescan = false;
4d779342 1422 bitmap_iterator bi;
6fb5fa3c 1423 unsigned int uid;
a7e3698d
JH
1424 bitmap_head tmp;
1425
1426 bitmap_initialize (&tmp, &df_bitmap_obstack);
b8698a0f 1427
6fb5fa3c
DB
1428 if (df->changeable_flags & DF_NO_INSN_RESCAN)
1429 {
1430 df_clear_flags (DF_NO_INSN_RESCAN);
1431 no_insn_rescan = true;
1432 }
b8698a0f 1433
6fb5fa3c
DB
1434 if (df->changeable_flags & DF_DEFER_INSN_RESCAN)
1435 {
1436 df_clear_flags (DF_DEFER_INSN_RESCAN);
1437 defer_insn_rescan = true;
1438 }
1439
1440 if (dump_file)
0a41f3b2 1441 fprintf (dump_file, "starting the processing of deferred insns\n");
6fb5fa3c 1442
a7e3698d
JH
1443 bitmap_copy (&tmp, &df->insns_to_delete);
1444 EXECUTE_IF_SET_IN_BITMAP (&tmp, 0, uid, bi)
6fb5fa3c
DB
1445 {
1446 struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
1447 if (insn_info)
1448 df_insn_delete (NULL, uid);
1449 }
1450
a7e3698d
JH
1451 bitmap_copy (&tmp, &df->insns_to_rescan);
1452 EXECUTE_IF_SET_IN_BITMAP (&tmp, 0, uid, bi)
6fb5fa3c
DB
1453 {
1454 struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
1455 if (insn_info)
1456 df_insn_rescan (insn_info->insn);
1457 }
1458
a7e3698d
JH
1459 bitmap_copy (&tmp, &df->insns_to_notes_rescan);
1460 EXECUTE_IF_SET_IN_BITMAP (&tmp, 0, uid, bi)
6fb5fa3c
DB
1461 {
1462 struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
1463 if (insn_info)
1464 df_notes_rescan (insn_info->insn);
1465 }
1466
1467 if (dump_file)
0a41f3b2 1468 fprintf (dump_file, "ending the processing of deferred insns\n");
6fb5fa3c 1469
a7e3698d
JH
1470 bitmap_clear (&tmp);
1471 bitmap_clear (&df->insns_to_delete);
1472 bitmap_clear (&df->insns_to_rescan);
1473 bitmap_clear (&df->insns_to_notes_rescan);
6fb5fa3c
DB
1474
1475 if (no_insn_rescan)
1476 df_set_flags (DF_NO_INSN_RESCAN);
1477 if (defer_insn_rescan)
1478 df_set_flags (DF_DEFER_INSN_RESCAN);
1479
1480 /* If someone changed regs_ever_live during this pass, fix up the
1481 entry and exit blocks. */
1482 if (df->redo_entry_and_exit)
1483 {
1484 df_update_entry_exit_and_calls ();
1485 df->redo_entry_and_exit = false;
1486 }
1487}
1488
4d779342 1489
6fb5fa3c
DB
1490/* Count the number of refs. Include the defs if INCLUDE_DEFS. Include
1491 the uses if INCLUDE_USES. Include the eq_uses if
1492 INCLUDE_EQ_USES. */
1493
1494static unsigned int
b8698a0f 1495df_count_refs (bool include_defs, bool include_uses,
6fb5fa3c
DB
1496 bool include_eq_uses)
1497{
1498 unsigned int regno;
1499 int size = 0;
1500 unsigned int m = df->regs_inited;
b8698a0f 1501
6fb5fa3c 1502 for (regno = 0; regno < m; regno++)
4d779342 1503 {
6fb5fa3c
DB
1504 if (include_defs)
1505 size += DF_REG_DEF_COUNT (regno);
1506 if (include_uses)
1507 size += DF_REG_USE_COUNT (regno);
1508 if (include_eq_uses)
1509 size += DF_REG_EQ_USE_COUNT (regno);
4d779342 1510 }
6fb5fa3c 1511 return size;
4d779342
DB
1512}
1513
1514
1515/* Take build ref table for either the uses or defs from the reg-use
6fb5fa3c
DB
1516 or reg-def chains. This version processes the refs in reg order
1517 which is likely to be best if processing the whole function. */
4d779342 1518
b8698a0f 1519static void
6fb5fa3c 1520df_reorganize_refs_by_reg_by_reg (struct df_ref_info *ref_info,
b8698a0f
L
1521 bool include_defs,
1522 bool include_uses,
6fb5fa3c 1523 bool include_eq_uses)
4d779342 1524{
6fb5fa3c 1525 unsigned int m = df->regs_inited;
4d779342
DB
1526 unsigned int regno;
1527 unsigned int offset = 0;
6fb5fa3c 1528 unsigned int start;
4d779342 1529
6fb5fa3c
DB
1530 if (df->changeable_flags & DF_NO_HARD_REGS)
1531 {
1532 start = FIRST_PSEUDO_REGISTER;
1533 memset (ref_info->begin, 0, sizeof (int) * FIRST_PSEUDO_REGISTER);
1534 memset (ref_info->count, 0, sizeof (int) * FIRST_PSEUDO_REGISTER);
4d779342 1535 }
6fb5fa3c
DB
1536 else
1537 start = 0;
4d779342 1538
b8698a0f 1539 ref_info->total_size
6fb5fa3c
DB
1540 = df_count_refs (include_defs, include_uses, include_eq_uses);
1541
1542 df_check_and_grow_ref_info (ref_info, 1);
1543
1544 for (regno = start; regno < m; regno++)
4d779342 1545 {
4d779342 1546 int count = 0;
6fb5fa3c
DB
1547 ref_info->begin[regno] = offset;
1548 if (include_defs)
1549 {
57512f53 1550 df_ref ref = DF_REG_DEF_CHAIN (regno);
b8698a0f 1551 while (ref)
6fb5fa3c
DB
1552 {
1553 ref_info->refs[offset] = ref;
1554 DF_REF_ID (ref) = offset++;
1555 count++;
1556 ref = DF_REF_NEXT_REG (ref);
7a40b8b1 1557 gcc_checking_assert (offset < ref_info->refs_size);
6fb5fa3c
DB
1558 }
1559 }
1560 if (include_uses)
4d779342 1561 {
57512f53 1562 df_ref ref = DF_REG_USE_CHAIN (regno);
b8698a0f 1563 while (ref)
4d779342
DB
1564 {
1565 ref_info->refs[offset] = ref;
1566 DF_REF_ID (ref) = offset++;
6fb5fa3c 1567 count++;
4d779342 1568 ref = DF_REF_NEXT_REG (ref);
7a40b8b1 1569 gcc_checking_assert (offset < ref_info->refs_size);
6fb5fa3c
DB
1570 }
1571 }
1572 if (include_eq_uses)
1573 {
57512f53 1574 df_ref ref = DF_REG_EQ_USE_CHAIN (regno);
b8698a0f 1575 while (ref)
6fb5fa3c
DB
1576 {
1577 ref_info->refs[offset] = ref;
1578 DF_REF_ID (ref) = offset++;
4d779342 1579 count++;
6fb5fa3c 1580 ref = DF_REF_NEXT_REG (ref);
7a40b8b1 1581 gcc_checking_assert (offset < ref_info->refs_size);
4d779342 1582 }
4d779342 1583 }
6fb5fa3c 1584 ref_info->count[regno] = count;
4d779342 1585 }
b8698a0f 1586
4d779342
DB
1587 /* The bitmap size is not decremented when refs are deleted. So
1588 reset it now that we have squished out all of the empty
1589 slots. */
6fb5fa3c 1590 ref_info->table_size = offset;
4d779342
DB
1591}
1592
4d779342 1593
6fb5fa3c
DB
1594/* Take build ref table for either the uses or defs from the reg-use
1595 or reg-def chains. This version processes the refs in insn order
1596 which is likely to be best if processing some segment of the
1597 function. */
4d779342 1598
b8698a0f 1599static void
6fb5fa3c 1600df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info,
b8698a0f
L
1601 bool include_defs,
1602 bool include_uses,
6fb5fa3c 1603 bool include_eq_uses)
4d779342 1604{
6fb5fa3c
DB
1605 bitmap_iterator bi;
1606 unsigned int bb_index;
1607 unsigned int m = df->regs_inited;
1608 unsigned int offset = 0;
1609 unsigned int r;
b8698a0f 1610 unsigned int start
6fb5fa3c 1611 = (df->changeable_flags & DF_NO_HARD_REGS) ? FIRST_PSEUDO_REGISTER : 0;
4d779342 1612
6fb5fa3c
DB
1613 memset (ref_info->begin, 0, sizeof (int) * df->regs_inited);
1614 memset (ref_info->count, 0, sizeof (int) * df->regs_inited);
1615
1616 ref_info->total_size = df_count_refs (include_defs, include_uses, include_eq_uses);
1617 df_check_and_grow_ref_info (ref_info, 1);
4d779342 1618
6fb5fa3c 1619 EXECUTE_IF_SET_IN_BITMAP (df->blocks_to_analyze, 0, bb_index, bi)
4d779342 1620 {
6fb5fa3c
DB
1621 basic_block bb = BASIC_BLOCK (bb_index);
1622 rtx insn;
57512f53 1623 df_ref *ref_rec;
6fb5fa3c
DB
1624
1625 if (include_defs)
1626 for (ref_rec = df_get_artificial_defs (bb_index); *ref_rec; ref_rec++)
23249ac4 1627 {
6fb5fa3c
DB
1628 unsigned int regno = DF_REF_REGNO (*ref_rec);
1629 ref_info->count[regno]++;
23249ac4 1630 }
6fb5fa3c
DB
1631 if (include_uses)
1632 for (ref_rec = df_get_artificial_uses (bb_index); *ref_rec; ref_rec++)
23249ac4 1633 {
6fb5fa3c
DB
1634 unsigned int regno = DF_REF_REGNO (*ref_rec);
1635 ref_info->count[regno]++;
23249ac4 1636 }
4d779342 1637
6fb5fa3c
DB
1638 FOR_BB_INSNS (bb, insn)
1639 {
1640 if (INSN_P (insn))
1641 {
1642 unsigned int uid = INSN_UID (insn);
b8698a0f 1643
6fb5fa3c
DB
1644 if (include_defs)
1645 for (ref_rec = DF_INSN_UID_DEFS (uid); *ref_rec; ref_rec++)
1646 {
1647 unsigned int regno = DF_REF_REGNO (*ref_rec);
1648 ref_info->count[regno]++;
1649 }
1650 if (include_uses)
1651 for (ref_rec = DF_INSN_UID_USES (uid); *ref_rec; ref_rec++)
1652 {
1653 unsigned int regno = DF_REF_REGNO (*ref_rec);
1654 ref_info->count[regno]++;
1655 }
1656 if (include_eq_uses)
1657 for (ref_rec = DF_INSN_UID_EQ_USES (uid); *ref_rec; ref_rec++)
1658 {
1659 unsigned int regno = DF_REF_REGNO (*ref_rec);
1660 ref_info->count[regno]++;
1661 }
1662 }
1663 }
1664 }
1665
1666 for (r = start; r < m; r++)
1667 {
1668 ref_info->begin[r] = offset;
1669 offset += ref_info->count[r];
1670 ref_info->count[r] = 0;
1671 }
b8698a0f 1672
6fb5fa3c
DB
1673 EXECUTE_IF_SET_IN_BITMAP (df->blocks_to_analyze, 0, bb_index, bi)
1674 {
1675 basic_block bb = BASIC_BLOCK (bb_index);
1676 rtx insn;
57512f53 1677 df_ref *ref_rec;
6fb5fa3c
DB
1678
1679 if (include_defs)
1680 for (ref_rec = df_get_artificial_defs (bb_index); *ref_rec; ref_rec++)
23249ac4 1681 {
57512f53 1682 df_ref ref = *ref_rec;
6fb5fa3c
DB
1683 unsigned int regno = DF_REF_REGNO (ref);
1684 if (regno >= start)
23249ac4 1685 {
6fb5fa3c
DB
1686 unsigned int id
1687 = ref_info->begin[regno] + ref_info->count[regno]++;
1688 DF_REF_ID (ref) = id;
1689 ref_info->refs[id] = ref;
23249ac4 1690 }
23249ac4 1691 }
6fb5fa3c
DB
1692 if (include_uses)
1693 for (ref_rec = df_get_artificial_uses (bb_index); *ref_rec; ref_rec++)
23249ac4 1694 {
57512f53 1695 df_ref ref = *ref_rec;
6fb5fa3c
DB
1696 unsigned int regno = DF_REF_REGNO (ref);
1697 if (regno >= start)
1698 {
1699 unsigned int id
1700 = ref_info->begin[regno] + ref_info->count[regno]++;
1701 DF_REF_ID (ref) = id;
1702 ref_info->refs[id] = ref;
1703 }
23249ac4 1704 }
6fb5fa3c
DB
1705
1706 FOR_BB_INSNS (bb, insn)
1707 {
1708 if (INSN_P (insn))
1709 {
1710 unsigned int uid = INSN_UID (insn);
b8698a0f 1711
6fb5fa3c
DB
1712 if (include_defs)
1713 for (ref_rec = DF_INSN_UID_DEFS (uid); *ref_rec; ref_rec++)
1714 {
57512f53 1715 df_ref ref = *ref_rec;
6fb5fa3c
DB
1716 unsigned int regno = DF_REF_REGNO (ref);
1717 if (regno >= start)
1718 {
1719 unsigned int id
1720 = ref_info->begin[regno] + ref_info->count[regno]++;
1721 DF_REF_ID (ref) = id;
1722 ref_info->refs[id] = ref;
1723 }
1724 }
1725 if (include_uses)
1726 for (ref_rec = DF_INSN_UID_USES (uid); *ref_rec; ref_rec++)
1727 {
57512f53 1728 df_ref ref = *ref_rec;
6fb5fa3c
DB
1729 unsigned int regno = DF_REF_REGNO (ref);
1730 if (regno >= start)
1731 {
1732 unsigned int id
1733 = ref_info->begin[regno] + ref_info->count[regno]++;
1734 DF_REF_ID (ref) = id;
1735 ref_info->refs[id] = ref;
1736 }
1737 }
1738 if (include_eq_uses)
1739 for (ref_rec = DF_INSN_UID_EQ_USES (uid); *ref_rec; ref_rec++)
1740 {
57512f53 1741 df_ref ref = *ref_rec;
6fb5fa3c
DB
1742 unsigned int regno = DF_REF_REGNO (ref);
1743 if (regno >= start)
1744 {
1745 unsigned int id
1746 = ref_info->begin[regno] + ref_info->count[regno]++;
1747 DF_REF_ID (ref) = id;
1748 ref_info->refs[id] = ref;
1749 }
1750 }
1751 }
1752 }
1753 }
1754
1755 /* The bitmap size is not decremented when refs are deleted. So
1756 reset it now that we have squished out all of the empty
1757 slots. */
1758
1759 ref_info->table_size = offset;
1760}
1761
1762/* Take build ref table for either the uses or defs from the reg-use
1763 or reg-def chains. */
1764
b8698a0f 1765static void
6fb5fa3c 1766df_reorganize_refs_by_reg (struct df_ref_info *ref_info,
b8698a0f
L
1767 bool include_defs,
1768 bool include_uses,
6fb5fa3c
DB
1769 bool include_eq_uses)
1770{
1771 if (df->analyze_subset)
b8698a0f 1772 df_reorganize_refs_by_reg_by_insn (ref_info, include_defs,
6fb5fa3c
DB
1773 include_uses, include_eq_uses);
1774 else
b8698a0f 1775 df_reorganize_refs_by_reg_by_reg (ref_info, include_defs,
6fb5fa3c
DB
1776 include_uses, include_eq_uses);
1777}
1778
1779
1780/* Add the refs in REF_VEC to the table in REF_INFO starting at OFFSET. */
b8698a0f
L
1781static unsigned int
1782df_add_refs_to_table (unsigned int offset,
1783 struct df_ref_info *ref_info,
57512f53 1784 df_ref *ref_vec)
6fb5fa3c
DB
1785{
1786 while (*ref_vec)
1787 {
57512f53 1788 df_ref ref = *ref_vec;
6fb5fa3c
DB
1789 if ((!(df->changeable_flags & DF_NO_HARD_REGS))
1790 || (DF_REF_REGNO (ref) >= FIRST_PSEUDO_REGISTER))
1791 {
1792 ref_info->refs[offset] = ref;
1793 DF_REF_ID (*ref_vec) = offset++;
1794 }
1795 ref_vec++;
1796 }
1797 return offset;
1798}
1799
1800
1801/* Count the number of refs in all of the insns of BB. Include the
1802 defs if INCLUDE_DEFS. Include the uses if INCLUDE_USES. Include the
1803 eq_uses if INCLUDE_EQ_USES. */
1804
1805static unsigned int
b8698a0f 1806df_reorganize_refs_by_insn_bb (basic_block bb, unsigned int offset,
6fb5fa3c 1807 struct df_ref_info *ref_info,
b8698a0f 1808 bool include_defs, bool include_uses,
6fb5fa3c
DB
1809 bool include_eq_uses)
1810{
1811 rtx insn;
1812
1813 if (include_defs)
b8698a0f 1814 offset = df_add_refs_to_table (offset, ref_info,
6fb5fa3c
DB
1815 df_get_artificial_defs (bb->index));
1816 if (include_uses)
b8698a0f 1817 offset = df_add_refs_to_table (offset, ref_info,
6fb5fa3c
DB
1818 df_get_artificial_uses (bb->index));
1819
1820 FOR_BB_INSNS (bb, insn)
1821 if (INSN_P (insn))
1822 {
1823 unsigned int uid = INSN_UID (insn);
1824 if (include_defs)
b8698a0f 1825 offset = df_add_refs_to_table (offset, ref_info,
6fb5fa3c
DB
1826 DF_INSN_UID_DEFS (uid));
1827 if (include_uses)
b8698a0f 1828 offset = df_add_refs_to_table (offset, ref_info,
6fb5fa3c
DB
1829 DF_INSN_UID_USES (uid));
1830 if (include_eq_uses)
b8698a0f 1831 offset = df_add_refs_to_table (offset, ref_info,
6fb5fa3c 1832 DF_INSN_UID_EQ_USES (uid));
23249ac4 1833 }
6fb5fa3c
DB
1834 return offset;
1835}
1836
1837
0d52bcc1 1838/* Organize the refs by insn into the table in REF_INFO. If
6fb5fa3c
DB
1839 blocks_to_analyze is defined, use that set, otherwise the entire
1840 program. Include the defs if INCLUDE_DEFS. Include the uses if
1841 INCLUDE_USES. Include the eq_uses if INCLUDE_EQ_USES. */
1842
1843static void
1844df_reorganize_refs_by_insn (struct df_ref_info *ref_info,
b8698a0f 1845 bool include_defs, bool include_uses,
6fb5fa3c
DB
1846 bool include_eq_uses)
1847{
1848 basic_block bb;
1849 unsigned int offset = 0;
1850
1851 ref_info->total_size = df_count_refs (include_defs, include_uses, include_eq_uses);
1852 df_check_and_grow_ref_info (ref_info, 1);
1853 if (df->blocks_to_analyze)
1854 {
1855 bitmap_iterator bi;
1856 unsigned int index;
1857
1858 EXECUTE_IF_SET_IN_BITMAP (df->blocks_to_analyze, 0, index, bi)
1859 {
b8698a0f
L
1860 offset = df_reorganize_refs_by_insn_bb (BASIC_BLOCK (index), offset, ref_info,
1861 include_defs, include_uses,
6fb5fa3c
DB
1862 include_eq_uses);
1863 }
1864
1865 ref_info->table_size = offset;
1866 }
1867 else
1868 {
1869 FOR_ALL_BB (bb)
b8698a0f
L
1870 offset = df_reorganize_refs_by_insn_bb (bb, offset, ref_info,
1871 include_defs, include_uses,
6fb5fa3c
DB
1872 include_eq_uses);
1873 ref_info->table_size = offset;
1874 }
1875}
1876
1877
1878/* If the use refs in DF are not organized, reorganize them. */
1879
b8698a0f 1880void
6fb5fa3c
DB
1881df_maybe_reorganize_use_refs (enum df_ref_order order)
1882{
1883 if (order == df->use_info.ref_order)
1884 return;
1885
1886 switch (order)
1887 {
1888 case DF_REF_ORDER_BY_REG:
1889 df_reorganize_refs_by_reg (&df->use_info, false, true, false);
1890 break;
1891
1892 case DF_REF_ORDER_BY_REG_WITH_NOTES:
1893 df_reorganize_refs_by_reg (&df->use_info, false, true, true);
1894 break;
1895
1896 case DF_REF_ORDER_BY_INSN:
1897 df_reorganize_refs_by_insn (&df->use_info, false, true, false);
1898 break;
1899
1900 case DF_REF_ORDER_BY_INSN_WITH_NOTES:
1901 df_reorganize_refs_by_insn (&df->use_info, false, true, true);
1902 break;
1903
1904 case DF_REF_ORDER_NO_TABLE:
1905 free (df->use_info.refs);
1906 df->use_info.refs = NULL;
1907 df->use_info.refs_size = 0;
1908 break;
1909
1910 case DF_REF_ORDER_UNORDERED:
1911 case DF_REF_ORDER_UNORDERED_WITH_NOTES:
1912 gcc_unreachable ();
1913 break;
1914 }
b8698a0f 1915
6fb5fa3c
DB
1916 df->use_info.ref_order = order;
1917}
1918
1919
1920/* If the def refs in DF are not organized, reorganize them. */
1921
b8698a0f 1922void
6fb5fa3c
DB
1923df_maybe_reorganize_def_refs (enum df_ref_order order)
1924{
1925 if (order == df->def_info.ref_order)
1926 return;
1927
1928 switch (order)
1929 {
1930 case DF_REF_ORDER_BY_REG:
1931 df_reorganize_refs_by_reg (&df->def_info, true, false, false);
1932 break;
1933
1934 case DF_REF_ORDER_BY_INSN:
1935 df_reorganize_refs_by_insn (&df->def_info, true, false, false);
1936 break;
1937
1938 case DF_REF_ORDER_NO_TABLE:
1939 free (df->def_info.refs);
1940 df->def_info.refs = NULL;
1941 df->def_info.refs_size = 0;
1942 break;
1943
1944 case DF_REF_ORDER_BY_INSN_WITH_NOTES:
1945 case DF_REF_ORDER_BY_REG_WITH_NOTES:
1946 case DF_REF_ORDER_UNORDERED:
1947 case DF_REF_ORDER_UNORDERED_WITH_NOTES:
1948 gcc_unreachable ();
1949 break;
1950 }
b8698a0f 1951
6fb5fa3c
DB
1952 df->def_info.ref_order = order;
1953}
1954
1955
6fb5fa3c 1956/* Change all of the basic block references in INSN to use the insn's
b8698a0f
L
1957 current basic block. This function is called from routines that move
1958 instructions from one block to another. */
6fb5fa3c
DB
1959
1960void
63642d5a 1961df_insn_change_bb (rtx insn, basic_block new_bb)
6fb5fa3c 1962{
63642d5a 1963 basic_block old_bb = BLOCK_FOR_INSN (insn);
6fb5fa3c
DB
1964 struct df_insn_info *insn_info;
1965 unsigned int uid = INSN_UID (insn);
1966
63642d5a
AO
1967 if (old_bb == new_bb)
1968 return;
1969
1970 set_block_for_insn (insn, new_bb);
1971
6fb5fa3c
DB
1972 if (!df)
1973 return;
1974
1975 if (dump_file)
1976 fprintf (dump_file, "changing bb of uid %d\n", uid);
1977
1978 insn_info = DF_INSN_UID_SAFE_GET (uid);
1979 if (insn_info == NULL)
1980 {
1981 if (dump_file)
1982 fprintf (dump_file, " unscanned insn\n");
1983 df_insn_rescan (insn);
1984 return;
1985 }
1986
1987 if (!INSN_P (insn))
1988 return;
1989
6fb5fa3c
DB
1990 df_set_bb_dirty (new_bb);
1991 if (old_bb)
1992 {
1993 if (dump_file)
b8698a0f 1994 fprintf (dump_file, " from %d to %d\n",
6fb5fa3c
DB
1995 old_bb->index, new_bb->index);
1996 df_set_bb_dirty (old_bb);
1997 }
1998 else
1999 if (dump_file)
2000 fprintf (dump_file, " to %d\n", new_bb->index);
2001}
2002
2003
2004/* Helper function for df_ref_change_reg_with_loc. */
2005
2006static void
b8698a0f 2007df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df,
57512f53 2008 struct df_reg_info *new_df,
6fb5fa3c
DB
2009 int new_regno, rtx loc)
2010{
57512f53 2011 df_ref the_ref = old_df->reg_chain;
6fb5fa3c
DB
2012
2013 while (the_ref)
2014 {
57512f53
KZ
2015 if ((!DF_REF_IS_ARTIFICIAL (the_ref))
2016 && (DF_REF_LOC (the_ref))
2017 && (*DF_REF_LOC (the_ref) == loc))
6fb5fa3c 2018 {
57512f53
KZ
2019 df_ref next_ref = DF_REF_NEXT_REG (the_ref);
2020 df_ref prev_ref = DF_REF_PREV_REG (the_ref);
2021 df_ref *ref_vec, *ref_vec_t;
2022 struct df_insn_info *insn_info = DF_REF_INSN_INFO (the_ref);
6fb5fa3c
DB
2023 unsigned int count = 0;
2024
2025 DF_REF_REGNO (the_ref) = new_regno;
2026 DF_REF_REG (the_ref) = regno_reg_rtx[new_regno];
2027
2028 /* Pull the_ref out of the old regno chain. */
2029 if (prev_ref)
57512f53 2030 DF_REF_NEXT_REG (prev_ref) = next_ref;
6fb5fa3c 2031 else
60564289 2032 old_df->reg_chain = next_ref;
6fb5fa3c 2033 if (next_ref)
57512f53 2034 DF_REF_PREV_REG (next_ref) = prev_ref;
60564289 2035 old_df->n_refs--;
6fb5fa3c
DB
2036
2037 /* Put the ref into the new regno chain. */
57512f53
KZ
2038 DF_REF_PREV_REG (the_ref) = NULL;
2039 DF_REF_NEXT_REG (the_ref) = new_df->reg_chain;
60564289 2040 if (new_df->reg_chain)
57512f53 2041 DF_REF_PREV_REG (new_df->reg_chain) = the_ref;
60564289
KG
2042 new_df->reg_chain = the_ref;
2043 new_df->n_refs++;
5288f999
KZ
2044 if (DF_REF_BB (the_ref))
2045 df_set_bb_dirty (DF_REF_BB (the_ref));
6fb5fa3c 2046
57512f53
KZ
2047 /* Need to sort the record again that the ref was in because
2048 the regno is a sorting key. First, find the right
2049 record. */
2050 if (DF_REF_FLAGS (the_ref) & DF_REF_IN_NOTE)
2051 ref_vec = insn_info->eq_uses;
6fb5fa3c 2052 else
57512f53
KZ
2053 ref_vec = insn_info->uses;
2054 if (dump_file)
b8698a0f
L
2055 fprintf (dump_file, "changing reg in insn %d\n",
2056 DF_REF_INSN_UID (the_ref));
2057
6fb5fa3c 2058 ref_vec_t = ref_vec;
b8698a0f 2059
6fb5fa3c
DB
2060 /* Find the length. */
2061 while (*ref_vec_t)
2062 {
2063 count++;
2064 ref_vec_t++;
2065 }
57512f53 2066 qsort (ref_vec, count, sizeof (df_ref ), df_ref_compare);
6fb5fa3c
DB
2067
2068 the_ref = next_ref;
2069 }
2070 else
57512f53 2071 the_ref = DF_REF_NEXT_REG (the_ref);
6fb5fa3c
DB
2072 }
2073}
2074
2075
2076/* Change the regno of all refs that contained LOC from OLD_REGNO to
57512f53
KZ
2077 NEW_REGNO. Refs that do not match LOC are not changed which means
2078 that artificial refs are not changed since they have no loc. This
2079 call is to support the SET_REGNO macro. */
6fb5fa3c
DB
2080
2081void
2082df_ref_change_reg_with_loc (int old_regno, int new_regno, rtx loc)
2083{
2084 if ((!df) || (old_regno == -1) || (old_regno == new_regno))
2085 return;
2086
2087 df_grow_reg_info ();
2088
b8698a0f 2089 df_ref_change_reg_with_loc_1 (DF_REG_DEF_GET (old_regno),
6fb5fa3c 2090 DF_REG_DEF_GET (new_regno), new_regno, loc);
b8698a0f 2091 df_ref_change_reg_with_loc_1 (DF_REG_USE_GET (old_regno),
6fb5fa3c 2092 DF_REG_USE_GET (new_regno), new_regno, loc);
b8698a0f 2093 df_ref_change_reg_with_loc_1 (DF_REG_EQ_USE_GET (old_regno),
6fb5fa3c
DB
2094 DF_REG_EQ_USE_GET (new_regno), new_regno, loc);
2095}
2096
2097
2098/* Delete the mw_hardregs that point into the eq_notes. */
2099
2100static unsigned int
2101df_mw_hardreg_chain_delete_eq_uses (struct df_insn_info *insn_info)
2102{
2103 struct df_mw_hardreg **mw_vec = insn_info->mw_hardregs;
2104 unsigned int deleted = 0;
2105 unsigned int count = 0;
b8698a0f 2106 struct df_scan_problem_data *problem_data
6fb5fa3c
DB
2107 = (struct df_scan_problem_data *) df_scan->problem_data;
2108
2109 if (!*mw_vec)
2110 return 0;
2111
2112 while (*mw_vec)
2113 {
2114 if ((*mw_vec)->flags & DF_REF_IN_NOTE)
2115 {
2116 struct df_mw_hardreg **temp_vec = mw_vec;
2117
2118 pool_free (problem_data->mw_reg_pool, *mw_vec);
2119 temp_vec = mw_vec;
2120 /* Shove the remaining ones down one to fill the gap. While
2121 this looks n**2, it is highly unusual to have any mw regs
2122 in eq_notes and the chances of more than one are almost
b8698a0f 2123 non existent. */
6fb5fa3c
DB
2124 while (*temp_vec)
2125 {
2126 *temp_vec = *(temp_vec + 1);
2127 temp_vec++;
2128 }
2129 deleted++;
2130 }
2131 else
2132 {
2133 mw_vec++;
2134 count++;
2135 }
2136 }
2137
2138 if (count == 0)
2139 {
370f38e8 2140 df_scan_free_mws_vec (insn_info->mw_hardregs);
6fb5fa3c
DB
2141 insn_info->mw_hardregs = df_null_mw_rec;
2142 return 0;
2143 }
2144 return deleted;
2145}
2146
2147
2148/* Rescan only the REG_EQUIV/REG_EQUAL notes part of INSN. */
2149
2150void
2151df_notes_rescan (rtx insn)
2152{
2153 struct df_insn_info *insn_info;
2154 unsigned int uid = INSN_UID (insn);
2155
2156 if (!df)
2157 return;
2158
2159 /* The client has disabled rescanning and plans to do it itself. */
2160 if (df->changeable_flags & DF_NO_INSN_RESCAN)
2161 return;
2162
c9b69ba2
RS
2163 /* Do nothing if the insn hasn't been emitted yet. */
2164 if (!BLOCK_FOR_INSN (insn))
2165 return;
2166
6fb5fa3c
DB
2167 df_grow_bb_info (df_scan);
2168 df_grow_reg_info ();
2169
2170 insn_info = DF_INSN_UID_SAFE_GET (INSN_UID(insn));
2171
0a41f3b2 2172 /* The client has deferred rescanning. */
6fb5fa3c
DB
2173 if (df->changeable_flags & DF_DEFER_INSN_RESCAN)
2174 {
2175 if (!insn_info)
2176 {
2177 insn_info = df_insn_create_insn_record (insn);
2178 insn_info->defs = df_null_ref_rec;
2179 insn_info->uses = df_null_ref_rec;
2180 insn_info->eq_uses = df_null_ref_rec;
2181 insn_info->mw_hardregs = df_null_mw_rec;
2182 }
b8698a0f 2183
a7e3698d 2184 bitmap_clear_bit (&df->insns_to_delete, uid);
6fb5fa3c
DB
2185 /* If the insn is set to be rescanned, it does not need to also
2186 be notes rescanned. */
a7e3698d
JH
2187 if (!bitmap_bit_p (&df->insns_to_rescan, uid))
2188 bitmap_set_bit (&df->insns_to_notes_rescan, INSN_UID (insn));
6fb5fa3c
DB
2189 return;
2190 }
2191
a7e3698d
JH
2192 bitmap_clear_bit (&df->insns_to_delete, uid);
2193 bitmap_clear_bit (&df->insns_to_notes_rescan, uid);
6fb5fa3c
DB
2194
2195 if (insn_info)
2196 {
2197 basic_block bb = BLOCK_FOR_INSN (insn);
2198 rtx note;
2199 struct df_collection_rec collection_rec;
2200 unsigned int num_deleted;
c2569604 2201 unsigned int mw_len;
6fb5fa3c
DB
2202
2203 memset (&collection_rec, 0, sizeof (struct df_collection_rec));
c2569604
ILT
2204 collection_rec.eq_use_vec = VEC_alloc (df_ref, stack, 32);
2205 collection_rec.mw_vec = VEC_alloc (df_mw_hardreg_ptr, stack, 32);
6fb5fa3c
DB
2206
2207 num_deleted = df_mw_hardreg_chain_delete_eq_uses (insn_info);
2208 df_ref_chain_delete (insn_info->eq_uses);
2209 insn_info->eq_uses = NULL;
2210
2211 /* Process REG_EQUIV/REG_EQUAL notes */
2212 for (note = REG_NOTES (insn); note;
2213 note = XEXP (note, 1))
2214 {
2215 switch (REG_NOTE_KIND (note))
2216 {
2217 case REG_EQUIV:
2218 case REG_EQUAL:
57512f53 2219 df_uses_record (DF_REF_REGULAR, &collection_rec,
6fb5fa3c 2220 &XEXP (note, 0), DF_REF_REG_USE,
bbbbb16a 2221 bb, insn_info, DF_REF_IN_NOTE, -1, -1, VOIDmode);
6fb5fa3c
DB
2222 default:
2223 break;
2224 }
2225 }
2226
2227 /* Find some place to put any new mw_hardregs. */
2228 df_canonize_collection_rec (&collection_rec);
c2569604
ILT
2229 mw_len = VEC_length (df_mw_hardreg_ptr, collection_rec.mw_vec);
2230 if (mw_len)
6fb5fa3c
DB
2231 {
2232 unsigned int count = 0;
2233 struct df_mw_hardreg **mw_rec = insn_info->mw_hardregs;
2234 while (*mw_rec)
2235 {
2236 count++;
2237 mw_rec++;
2238 }
2239
2240 if (count)
2241 {
2242 /* Append to the end of the existing record after
2243 expanding it if necessary. */
c2569604 2244 if (mw_len > num_deleted)
6fb5fa3c 2245 {
b8698a0f 2246 insn_info->mw_hardregs =
4dc6c528 2247 XRESIZEVEC (struct df_mw_hardreg *,
c2569604
ILT
2248 insn_info->mw_hardregs,
2249 count + 1 + mw_len);
6fb5fa3c 2250 }
c2569604 2251 memcpy (&insn_info->mw_hardregs[count],
b8698a0f 2252 VEC_address (df_mw_hardreg_ptr, collection_rec.mw_vec),
c2569604
ILT
2253 mw_len * sizeof (struct df_mw_hardreg *));
2254 insn_info->mw_hardregs[count + mw_len] = NULL;
b8698a0f 2255 qsort (insn_info->mw_hardregs, count + mw_len,
6fb5fa3c
DB
2256 sizeof (struct df_mw_hardreg *), df_mw_compare);
2257 }
2258 else
2259 {
b8698a0f
L
2260 /* No vector there. */
2261 insn_info->mw_hardregs
c2569604
ILT
2262 = XNEWVEC (struct df_mw_hardreg*, 1 + mw_len);
2263 memcpy (insn_info->mw_hardregs,
2264 VEC_address (df_mw_hardreg_ptr, collection_rec.mw_vec),
2265 mw_len * sizeof (struct df_mw_hardreg *));
2266 insn_info->mw_hardregs[mw_len] = NULL;
6fb5fa3c
DB
2267 }
2268 }
2269 /* Get rid of the mw_rec so that df_refs_add_to_chains will
2270 ignore it. */
c2569604 2271 VEC_free (df_mw_hardreg_ptr, stack, collection_rec.mw_vec);
6fb5fa3c 2272 df_refs_add_to_chains (&collection_rec, bb, insn);
c2569604 2273 VEC_free (df_ref, stack, collection_rec.eq_use_vec);
6fb5fa3c
DB
2274 }
2275 else
2276 df_insn_rescan (insn);
2277
2278}
2279
2280\f
2281/*----------------------------------------------------------------------------
2282 Hard core instruction scanning code. No external interfaces here,
2283 just a lot of routines that look inside insns.
2284----------------------------------------------------------------------------*/
2285
2286
b8698a0f 2287/* Return true if the contents of two df_ref's are identical.
6fb5fa3c
DB
2288 It ignores DF_REF_MARKER. */
2289
2290static bool
57512f53 2291df_ref_equal_p (df_ref ref1, df_ref ref2)
6fb5fa3c
DB
2292{
2293 if (!ref2)
2294 return false;
b8698a0f 2295
57512f53
KZ
2296 if (ref1 == ref2)
2297 return true;
2298
2299 if (DF_REF_CLASS (ref1) != DF_REF_CLASS (ref2)
2300 || DF_REF_REGNO (ref1) != DF_REF_REGNO (ref2)
2301 || DF_REF_REG (ref1) != DF_REF_REG (ref2)
2302 || DF_REF_TYPE (ref1) != DF_REF_TYPE (ref2)
b8698a0f 2303 || ((DF_REF_FLAGS (ref1) & ~(DF_REF_REG_MARKER + DF_REF_MW_HARDREG))
57512f53
KZ
2304 != (DF_REF_FLAGS (ref2) & ~(DF_REF_REG_MARKER + DF_REF_MW_HARDREG)))
2305 || DF_REF_BB (ref1) != DF_REF_BB (ref2)
2306 || DF_REF_INSN_INFO (ref1) != DF_REF_INSN_INFO (ref2))
2307 return false;
b8698a0f 2308
57512f53
KZ
2309 switch (DF_REF_CLASS (ref1))
2310 {
2311 case DF_REF_ARTIFICIAL:
2312 case DF_REF_BASE:
2313 return true;
ca9052ce 2314
57512f53
KZ
2315 case DF_REF_EXTRACT:
2316 if ((DF_REF_EXTRACT_OFFSET (ref1) != DF_REF_EXTRACT_OFFSET (ref2))
cc806ac1 2317 || (DF_REF_EXTRACT_WIDTH (ref1) != DF_REF_EXTRACT_WIDTH (ref2))
57512f53
KZ
2318 || (DF_REF_EXTRACT_MODE (ref1) != DF_REF_EXTRACT_MODE (ref2)))
2319 return false;
2320 /* fallthru. */
2321
2322 case DF_REF_REGULAR:
2323 return DF_REF_LOC (ref1) == DF_REF_LOC (ref2);
ca9052ce 2324
57512f53
KZ
2325 default:
2326 gcc_unreachable ();
2327 }
2328 return false;
6fb5fa3c
DB
2329}
2330
2331
2332/* Compare REF1 and REF2 for sorting. This is only called from places
2333 where all of the refs are of the same type, in the same insn, and
2334 have the same bb. So these fields are not checked. */
2335
2336static int
2337df_ref_compare (const void *r1, const void *r2)
2338{
57512f53
KZ
2339 const df_ref ref1 = *(const df_ref *)r1;
2340 const df_ref ref2 = *(const df_ref *)r2;
6fb5fa3c
DB
2341
2342 if (ref1 == ref2)
2343 return 0;
2344
57512f53
KZ
2345 if (DF_REF_CLASS (ref1) != DF_REF_CLASS (ref2))
2346 return (int)DF_REF_CLASS (ref1) - (int)DF_REF_CLASS (ref2);
2347
6fb5fa3c
DB
2348 if (DF_REF_REGNO (ref1) != DF_REF_REGNO (ref2))
2349 return (int)DF_REF_REGNO (ref1) - (int)DF_REF_REGNO (ref2);
b8698a0f 2350
6fb5fa3c
DB
2351 if (DF_REF_TYPE (ref1) != DF_REF_TYPE (ref2))
2352 return (int)DF_REF_TYPE (ref1) - (int)DF_REF_TYPE (ref2);
2353
57512f53
KZ
2354 if (DF_REF_REG (ref1) != DF_REF_REG (ref2))
2355 return (int)DF_REF_ORDER (ref1) - (int)DF_REF_ORDER (ref2);
2356
2357 /* Cannot look at the LOC field on artificial refs. */
2358 if (DF_REF_CLASS (ref1) != DF_REF_ARTIFICIAL
2359 && DF_REF_LOC (ref1) != DF_REF_LOC (ref2))
6fb5fa3c
DB
2360 return (int)DF_REF_ORDER (ref1) - (int)DF_REF_ORDER (ref2);
2361
2362 if (DF_REF_FLAGS (ref1) != DF_REF_FLAGS (ref2))
2363 {
2364 /* If two refs are identical except that one of them has is from
2365 a mw and one is not, we need to have the one with the mw
2366 first. */
2367 if (DF_REF_FLAGS_IS_SET (ref1, DF_REF_MW_HARDREG) ==
2368 DF_REF_FLAGS_IS_SET (ref2, DF_REF_MW_HARDREG))
2369 return DF_REF_FLAGS (ref1) - DF_REF_FLAGS (ref2);
2370 else if (DF_REF_FLAGS_IS_SET (ref1, DF_REF_MW_HARDREG))
2371 return -1;
2372 else
2373 return 1;
2374 }
ca9052ce 2375
57512f53 2376 /* The classes are the same at this point so it is safe to only look
ca9052ce 2377 at ref1. */
57512f53 2378 if (DF_REF_CLASS (ref1) == DF_REF_EXTRACT)
ca9052ce 2379 {
57512f53
KZ
2380 if (DF_REF_EXTRACT_OFFSET (ref1) != DF_REF_EXTRACT_OFFSET (ref2))
2381 return DF_REF_EXTRACT_OFFSET (ref1) - DF_REF_EXTRACT_OFFSET (ref2);
2382 if (DF_REF_EXTRACT_WIDTH (ref1) != DF_REF_EXTRACT_WIDTH (ref2))
2383 return DF_REF_EXTRACT_WIDTH (ref1) - DF_REF_EXTRACT_WIDTH (ref2);
2384 if (DF_REF_EXTRACT_MODE (ref1) != DF_REF_EXTRACT_MODE (ref2))
2385 return DF_REF_EXTRACT_MODE (ref1) - DF_REF_EXTRACT_MODE (ref2);
ca9052ce 2386 }
5797be12 2387 return (int)DF_REF_ORDER (ref1) - (int)DF_REF_ORDER (ref2);
6fb5fa3c
DB
2388}
2389
2390static void
c2569604 2391df_swap_refs (VEC(df_ref,stack) **ref_vec, int i, int j)
6fb5fa3c 2392{
c2569604
ILT
2393 df_ref tmp = VEC_index (df_ref, *ref_vec, i);
2394 VEC_replace (df_ref, *ref_vec, i, VEC_index (df_ref, *ref_vec, j));
2395 VEC_replace (df_ref, *ref_vec, j, tmp);
6fb5fa3c
DB
2396}
2397
2398/* Sort and compress a set of refs. */
2399
c2569604
ILT
2400static void
2401df_sort_and_compress_refs (VEC(df_ref,stack) **ref_vec)
6fb5fa3c 2402{
c2569604 2403 unsigned int count;
6fb5fa3c
DB
2404 unsigned int i;
2405 unsigned int dist = 0;
2406
c2569604
ILT
2407 count = VEC_length (df_ref, *ref_vec);
2408
6fb5fa3c
DB
2409 /* If there are 1 or 0 elements, there is nothing to do. */
2410 if (count < 2)
c2569604 2411 return;
6fb5fa3c
DB
2412 else if (count == 2)
2413 {
c2569604
ILT
2414 df_ref r0 = VEC_index (df_ref, *ref_vec, 0);
2415 df_ref r1 = VEC_index (df_ref, *ref_vec, 1);
2416 if (df_ref_compare (&r0, &r1) > 0)
6fb5fa3c
DB
2417 df_swap_refs (ref_vec, 0, 1);
2418 }
2419 else
2420 {
2421 for (i = 0; i < count - 1; i++)
c2569604
ILT
2422 {
2423 df_ref r0 = VEC_index (df_ref, *ref_vec, i);
2424 df_ref r1 = VEC_index (df_ref, *ref_vec, i + 1);
2425 if (df_ref_compare (&r0, &r1) >= 0)
2426 break;
2427 }
6fb5fa3c
DB
2428 /* If the array is already strictly ordered,
2429 which is the most common case for large COUNT case
2430 (which happens for CALL INSNs),
2431 no need to sort and filter out duplicate.
b8698a0f 2432 Simply return the count.
6fb5fa3c
DB
2433 Make sure DF_GET_ADD_REFS adds refs in the increasing order
2434 of DF_REF_COMPARE. */
2435 if (i == count - 1)
c2569604
ILT
2436 return;
2437 qsort (VEC_address (df_ref, *ref_vec), count, sizeof (df_ref),
2438 df_ref_compare);
6fb5fa3c
DB
2439 }
2440
2441 for (i=0; i<count-dist; i++)
2442 {
2443 /* Find the next ref that is not equal to the current ref. */
c2569604
ILT
2444 while (i + dist + 1 < count
2445 && df_ref_equal_p (VEC_index (df_ref, *ref_vec, i),
2446 VEC_index (df_ref, *ref_vec, i + dist + 1)))
6fb5fa3c 2447 {
c2569604 2448 df_free_ref (VEC_index (df_ref, *ref_vec, i + dist + 1));
6fb5fa3c
DB
2449 dist++;
2450 }
2451 /* Copy it down to the next position. */
c2569604
ILT
2452 if (dist && i + dist + 1 < count)
2453 VEC_replace (df_ref, *ref_vec, i + 1,
2454 VEC_index (df_ref, *ref_vec, i + dist + 1));
6fb5fa3c
DB
2455 }
2456
2457 count -= dist;
c2569604 2458 VEC_truncate (df_ref, *ref_vec, count);
6fb5fa3c
DB
2459}
2460
2461
b8698a0f 2462/* Return true if the contents of two df_ref's are identical.
6fb5fa3c
DB
2463 It ignores DF_REF_MARKER. */
2464
2465static bool
2466df_mw_equal_p (struct df_mw_hardreg *mw1, struct df_mw_hardreg *mw2)
2467{
2468 if (!mw2)
2469 return false;
2470 return (mw1 == mw2) ||
2471 (mw1->mw_reg == mw2->mw_reg
2472 && mw1->type == mw2->type
2473 && mw1->flags == mw2->flags
2474 && mw1->start_regno == mw2->start_regno
2475 && mw1->end_regno == mw2->end_regno);
2476}
2477
2478
2479/* Compare MW1 and MW2 for sorting. */
2480
2481static int
2482df_mw_compare (const void *m1, const void *m2)
2483{
5f754896
KG
2484 const struct df_mw_hardreg *const mw1 = *(const struct df_mw_hardreg *const*)m1;
2485 const struct df_mw_hardreg *const mw2 = *(const struct df_mw_hardreg *const*)m2;
6fb5fa3c
DB
2486
2487 if (mw1 == mw2)
2488 return 0;
2489
2490 if (mw1->type != mw2->type)
2491 return mw1->type - mw2->type;
2492
2493 if (mw1->flags != mw2->flags)
2494 return mw1->flags - mw2->flags;
2495
2496 if (mw1->start_regno != mw2->start_regno)
2497 return mw1->start_regno - mw2->start_regno;
2498
2499 if (mw1->end_regno != mw2->end_regno)
2500 return mw1->end_regno - mw2->end_regno;
2501
2502 if (mw1->mw_reg != mw2->mw_reg)
2503 return mw1->mw_order - mw2->mw_order;
2504
2505 return 0;
2506}
2507
2508
2509/* Sort and compress a set of refs. */
2510
c2569604
ILT
2511static void
2512df_sort_and_compress_mws (VEC(df_mw_hardreg_ptr,stack) **mw_vec)
6fb5fa3c 2513{
c2569604 2514 unsigned int count;
b8698a0f 2515 struct df_scan_problem_data *problem_data
6fb5fa3c
DB
2516 = (struct df_scan_problem_data *) df_scan->problem_data;
2517 unsigned int i;
2518 unsigned int dist = 0;
6fb5fa3c 2519
c2569604 2520 count = VEC_length (df_mw_hardreg_ptr, *mw_vec);
6fb5fa3c 2521 if (count < 2)
c2569604 2522 return;
6fb5fa3c
DB
2523 else if (count == 2)
2524 {
c2569604
ILT
2525 struct df_mw_hardreg *m0 = VEC_index (df_mw_hardreg_ptr, *mw_vec, 0);
2526 struct df_mw_hardreg *m1 = VEC_index (df_mw_hardreg_ptr, *mw_vec, 1);
2527 if (df_mw_compare (&m0, &m1) > 0)
6fb5fa3c 2528 {
c2569604
ILT
2529 struct df_mw_hardreg *tmp = VEC_index (df_mw_hardreg_ptr,
2530 *mw_vec, 0);
2531 VEC_replace (df_mw_hardreg_ptr, *mw_vec, 0,
2532 VEC_index (df_mw_hardreg_ptr, *mw_vec, 1));
2533 VEC_replace (df_mw_hardreg_ptr, *mw_vec, 1, tmp);
6fb5fa3c
DB
2534 }
2535 }
2536 else
c2569604
ILT
2537 qsort (VEC_address (df_mw_hardreg_ptr, *mw_vec), count,
2538 sizeof (struct df_mw_hardreg *), df_mw_compare);
6fb5fa3c
DB
2539
2540 for (i=0; i<count-dist; i++)
2541 {
2542 /* Find the next ref that is not equal to the current ref. */
c2569604
ILT
2543 while (i + dist + 1 < count
2544 && df_mw_equal_p (VEC_index (df_mw_hardreg_ptr, *mw_vec, i),
2545 VEC_index (df_mw_hardreg_ptr, *mw_vec,
2546 i + dist + 1)))
6fb5fa3c 2547 {
c2569604
ILT
2548 pool_free (problem_data->mw_reg_pool,
2549 VEC_index (df_mw_hardreg_ptr, *mw_vec, i + dist + 1));
6fb5fa3c
DB
2550 dist++;
2551 }
2552 /* Copy it down to the next position. */
c2569604
ILT
2553 if (dist && i + dist + 1 < count)
2554 VEC_replace (df_mw_hardreg_ptr, *mw_vec, i + 1,
2555 VEC_index (df_mw_hardreg_ptr, *mw_vec, i + dist + 1));
6fb5fa3c
DB
2556 }
2557
2558 count -= dist;
c2569604 2559 VEC_truncate (df_mw_hardreg_ptr, *mw_vec, count);
6fb5fa3c
DB
2560}
2561
2562
2563/* Sort and remove duplicates from the COLLECTION_REC. */
2564
2565static void
2566df_canonize_collection_rec (struct df_collection_rec *collection_rec)
2567{
c2569604
ILT
2568 df_sort_and_compress_refs (&collection_rec->def_vec);
2569 df_sort_and_compress_refs (&collection_rec->use_vec);
2570 df_sort_and_compress_refs (&collection_rec->eq_use_vec);
2571 df_sort_and_compress_mws (&collection_rec->mw_vec);
6fb5fa3c
DB
2572}
2573
2574
2575/* Add the new df_ref to appropriate reg_info/ref_info chains. */
2576
2577static void
b8698a0f
L
2578df_install_ref (df_ref this_ref,
2579 struct df_reg_info *reg_info,
6fb5fa3c
DB
2580 struct df_ref_info *ref_info,
2581 bool add_to_table)
2582{
2583 unsigned int regno = DF_REF_REGNO (this_ref);
2584 /* Add the ref to the reg_{def,use,eq_use} chain. */
57512f53 2585 df_ref head = reg_info->reg_chain;
6fb5fa3c
DB
2586
2587 reg_info->reg_chain = this_ref;
2588 reg_info->n_refs++;
2589
2590 if (DF_REF_FLAGS_IS_SET (this_ref, DF_HARD_REG_LIVE))
2591 {
2592 gcc_assert (regno < FIRST_PSEUDO_REGISTER);
2593 df->hard_regs_live_count[regno]++;
2594 }
2595
7a40b8b1
JH
2596 gcc_checking_assert (DF_REF_NEXT_REG (this_ref) == NULL
2597 && DF_REF_PREV_REG (this_ref) == NULL);
6fb5fa3c
DB
2598
2599 DF_REF_NEXT_REG (this_ref) = head;
2600
2601 /* We cannot actually link to the head of the chain. */
2602 DF_REF_PREV_REG (this_ref) = NULL;
2603
2604 if (head)
2605 DF_REF_PREV_REG (head) = this_ref;
b8698a0f 2606
6fb5fa3c
DB
2607 if (add_to_table)
2608 {
2609 gcc_assert (ref_info->ref_order != DF_REF_ORDER_NO_TABLE);
2610 df_check_and_grow_ref_info (ref_info, 1);
2611 DF_REF_ID (this_ref) = ref_info->table_size;
2612 /* Add the ref to the big array of defs. */
2613 ref_info->refs[ref_info->table_size] = this_ref;
2614 ref_info->table_size++;
b8698a0f 2615 }
6fb5fa3c
DB
2616 else
2617 DF_REF_ID (this_ref) = -1;
b8698a0f 2618
6fb5fa3c
DB
2619 ref_info->total_size++;
2620}
2621
2622
2623/* This function takes one of the groups of refs (defs, uses or
2624 eq_uses) and installs the entire group into the insn. It also adds
2625 each of these refs into the appropriate chains. */
2626
57512f53 2627static df_ref *
6fb5fa3c 2628df_install_refs (basic_block bb,
c2569604 2629 VEC(df_ref,stack)* old_vec,
b8698a0f 2630 struct df_reg_info **reg_info,
6fb5fa3c
DB
2631 struct df_ref_info *ref_info,
2632 bool is_notes)
2633{
c2569604
ILT
2634 unsigned int count;
2635
2636 count = VEC_length (df_ref, old_vec);
6fb5fa3c
DB
2637 if (count)
2638 {
57512f53 2639 df_ref *new_vec = XNEWVEC (df_ref, count + 1);
6fb5fa3c 2640 bool add_to_table;
c2569604
ILT
2641 df_ref this_ref;
2642 unsigned int ix;
6fb5fa3c
DB
2643
2644 switch (ref_info->ref_order)
2645 {
2646 case DF_REF_ORDER_UNORDERED_WITH_NOTES:
2647 case DF_REF_ORDER_BY_REG_WITH_NOTES:
2648 case DF_REF_ORDER_BY_INSN_WITH_NOTES:
2649 ref_info->ref_order = DF_REF_ORDER_UNORDERED_WITH_NOTES;
2650 add_to_table = true;
2651 break;
2652 case DF_REF_ORDER_UNORDERED:
2653 case DF_REF_ORDER_BY_REG:
2654 case DF_REF_ORDER_BY_INSN:
2655 ref_info->ref_order = DF_REF_ORDER_UNORDERED;
2656 add_to_table = !is_notes;
2657 break;
2658 default:
2659 add_to_table = false;
2660 break;
2661 }
2662
2663 /* Do not add if ref is not in the right blocks. */
2664 if (add_to_table && df->analyze_subset)
2665 add_to_table = bitmap_bit_p (df->blocks_to_analyze, bb->index);
2666
c2569604 2667 for (ix = 0; VEC_iterate (df_ref, old_vec, ix, this_ref); ++ix)
6fb5fa3c 2668 {
c2569604 2669 new_vec[ix] = this_ref;
b8698a0f 2670 df_install_ref (this_ref, reg_info[DF_REF_REGNO (this_ref)],
6fb5fa3c
DB
2671 ref_info, add_to_table);
2672 }
b8698a0f 2673
6fb5fa3c
DB
2674 new_vec[count] = NULL;
2675 return new_vec;
2676 }
2677 else
2678 return df_null_ref_rec;
2679}
2680
2681
2682/* This function takes the mws installs the entire group into the
2683 insn. */
2684
2685static struct df_mw_hardreg **
c2569604 2686df_install_mws (VEC(df_mw_hardreg_ptr,stack) *old_vec)
6fb5fa3c 2687{
c2569604
ILT
2688 unsigned int count;
2689
2690 count = VEC_length (df_mw_hardreg_ptr, old_vec);
6fb5fa3c
DB
2691 if (count)
2692 {
b8698a0f 2693 struct df_mw_hardreg **new_vec
6fb5fa3c 2694 = XNEWVEC (struct df_mw_hardreg*, count + 1);
b8698a0f 2695 memcpy (new_vec, VEC_address (df_mw_hardreg_ptr, old_vec),
c2569604
ILT
2696 sizeof (struct df_mw_hardreg*) * count);
2697 new_vec[count] = NULL;
6fb5fa3c
DB
2698 return new_vec;
2699 }
2700 else
2701 return df_null_mw_rec;
2702}
2703
2704
2705/* Add a chain of df_refs to appropriate ref chain/reg_info/ref_info
2706 chains and update other necessary information. */
2707
2708static void
b8698a0f 2709df_refs_add_to_chains (struct df_collection_rec *collection_rec,
6fb5fa3c
DB
2710 basic_block bb, rtx insn)
2711{
2712 if (insn)
2713 {
50e94c7e 2714 struct df_insn_info *insn_rec = DF_INSN_INFO_GET (insn);
6fb5fa3c
DB
2715 /* If there is a vector in the collection rec, add it to the
2716 insn. A null rec is a signal that the caller will handle the
2717 chain specially. */
2718 if (collection_rec->def_vec)
2719 {
370f38e8 2720 df_scan_free_ref_vec (insn_rec->defs);
b8698a0f 2721 insn_rec->defs
c2569604 2722 = df_install_refs (bb, collection_rec->def_vec,
6fb5fa3c
DB
2723 df->def_regs,
2724 &df->def_info, false);
2725 }
2726 if (collection_rec->use_vec)
2727 {
370f38e8 2728 df_scan_free_ref_vec (insn_rec->uses);
b8698a0f
L
2729 insn_rec->uses
2730 = df_install_refs (bb, collection_rec->use_vec,
6fb5fa3c
DB
2731 df->use_regs,
2732 &df->use_info, false);
2733 }
2734 if (collection_rec->eq_use_vec)
2735 {
370f38e8 2736 df_scan_free_ref_vec (insn_rec->eq_uses);
b8698a0f
L
2737 insn_rec->eq_uses
2738 = df_install_refs (bb, collection_rec->eq_use_vec,
6fb5fa3c
DB
2739 df->eq_use_regs,
2740 &df->use_info, true);
2741 }
2742 if (collection_rec->mw_vec)
2743 {
370f38e8 2744 df_scan_free_mws_vec (insn_rec->mw_hardregs);
b8698a0f 2745 insn_rec->mw_hardregs
c2569604 2746 = df_install_mws (collection_rec->mw_vec);
6fb5fa3c
DB
2747 }
2748 }
2749 else
2750 {
2751 struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index);
2752
370f38e8 2753 df_scan_free_ref_vec (bb_info->artificial_defs);
b8698a0f 2754 bb_info->artificial_defs
c2569604 2755 = df_install_refs (bb, collection_rec->def_vec,
6fb5fa3c
DB
2756 df->def_regs,
2757 &df->def_info, false);
370f38e8 2758 df_scan_free_ref_vec (bb_info->artificial_uses);
b8698a0f
L
2759 bb_info->artificial_uses
2760 = df_install_refs (bb, collection_rec->use_vec,
6fb5fa3c
DB
2761 df->use_regs,
2762 &df->use_info, false);
2763 }
2764}
4d779342 2765
4d779342 2766
b8698a0f 2767/* Allocate a ref and initialize its fields.
ca9052ce
KZ
2768
2769 If the REF_FLAGS field contain DF_REF_SIGN_EXTRACT or
cc806ac1 2770 DF_REF_ZERO_EXTRACT. WIDTH, OFFSET and MODE are used to access the fields
ca9052ce
KZ
2771 if they were constants. Otherwise they should be -1 if those flags
2772 were set. */
6fb5fa3c 2773
b8698a0f
L
2774static df_ref
2775df_ref_create_structure (enum df_ref_class cl,
57512f53 2776 struct df_collection_rec *collection_rec,
b8698a0f 2777 rtx reg, rtx *loc,
50e94c7e 2778 basic_block bb, struct df_insn_info *info,
b8698a0f 2779 enum df_ref_type ref_type,
bbbbb16a 2780 int ref_flags,
cc806ac1 2781 int width, int offset, enum machine_mode mode)
6fb5fa3c 2782{
57512f53 2783 df_ref this_ref = NULL;
6fb5fa3c
DB
2784 int regno = REGNO (GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg);
2785 struct df_scan_problem_data *problem_data
2786 = (struct df_scan_problem_data *) df_scan->problem_data;
2787
57512f53 2788 switch (cl)
ca9052ce 2789 {
57512f53
KZ
2790 case DF_REF_BASE:
2791 this_ref = (df_ref) pool_alloc (problem_data->ref_base_pool);
7a40b8b1 2792 gcc_checking_assert (loc == NULL);
57512f53
KZ
2793 break;
2794
2795 case DF_REF_ARTIFICIAL:
2796 this_ref = (df_ref) pool_alloc (problem_data->ref_artificial_pool);
2797 this_ref->artificial_ref.bb = bb;
7a40b8b1 2798 gcc_checking_assert (loc == NULL);
57512f53
KZ
2799 break;
2800
2801 case DF_REF_REGULAR:
2802 this_ref = (df_ref) pool_alloc (problem_data->ref_regular_pool);
2803 this_ref->regular_ref.loc = loc;
7a40b8b1 2804 gcc_checking_assert (loc);
57512f53
KZ
2805 break;
2806
2807 case DF_REF_EXTRACT:
2808 this_ref = (df_ref) pool_alloc (problem_data->ref_extract_pool);
cc806ac1
RS
2809 DF_REF_EXTRACT_WIDTH (this_ref) = width;
2810 DF_REF_EXTRACT_OFFSET (this_ref) = offset;
2811 DF_REF_EXTRACT_MODE (this_ref) = mode;
57512f53 2812 this_ref->regular_ref.loc = loc;
7a40b8b1 2813 gcc_checking_assert (loc);
57512f53 2814 break;
ca9052ce 2815 }
57512f53
KZ
2816
2817 DF_REF_CLASS (this_ref) = cl;
6fb5fa3c
DB
2818 DF_REF_ID (this_ref) = -1;
2819 DF_REF_REG (this_ref) = reg;
2820 DF_REF_REGNO (this_ref) = regno;
57512f53 2821 DF_REF_TYPE (this_ref) = ref_type;
50e94c7e 2822 DF_REF_INSN_INFO (this_ref) = info;
6fb5fa3c 2823 DF_REF_CHAIN (this_ref) = NULL;
6fb5fa3c 2824 DF_REF_FLAGS (this_ref) = ref_flags;
6fb5fa3c
DB
2825 DF_REF_NEXT_REG (this_ref) = NULL;
2826 DF_REF_PREV_REG (this_ref) = NULL;
2827 DF_REF_ORDER (this_ref) = df->ref_order++;
2828
2829 /* We need to clear this bit because fwprop, and in the future
2830 possibly other optimizations sometimes create new refs using ond
2831 refs as the model. */
2832 DF_REF_FLAGS_CLEAR (this_ref, DF_HARD_REG_LIVE);
2833
2834 /* See if this ref needs to have DF_HARD_REG_LIVE bit set. */
b8698a0f 2835 if ((regno < FIRST_PSEUDO_REGISTER)
6fb5fa3c
DB
2836 && (!DF_REF_IS_ARTIFICIAL (this_ref)))
2837 {
57512f53 2838 if (DF_REF_REG_DEF_P (this_ref))
6fb5fa3c
DB
2839 {
2840 if (!DF_REF_FLAGS_IS_SET (this_ref, DF_REF_MAY_CLOBBER))
2841 DF_REF_FLAGS_SET (this_ref, DF_HARD_REG_LIVE);
2842 }
2843 else if (!(TEST_HARD_REG_BIT (elim_reg_set, regno)
2844 && (regno == FRAME_POINTER_REGNUM
2845 || regno == ARG_POINTER_REGNUM)))
2846 DF_REF_FLAGS_SET (this_ref, DF_HARD_REG_LIVE);
2847 }
2848
2849 if (collection_rec)
2850 {
57512f53 2851 if (DF_REF_REG_DEF_P (this_ref))
c2569604 2852 VEC_safe_push (df_ref, stack, collection_rec->def_vec, this_ref);
6fb5fa3c 2853 else if (DF_REF_FLAGS (this_ref) & DF_REF_IN_NOTE)
c2569604 2854 VEC_safe_push (df_ref, stack, collection_rec->eq_use_vec, this_ref);
6fb5fa3c 2855 else
c2569604 2856 VEC_safe_push (df_ref, stack, collection_rec->use_vec, this_ref);
4d779342 2857 }
6fb5fa3c 2858
4d779342
DB
2859 return this_ref;
2860}
2861
2862
2863/* Create new references of type DF_REF_TYPE for each part of register REG
b8698a0f 2864 at address LOC within INSN of BB.
ca9052ce
KZ
2865
2866 If the REF_FLAGS field contain DF_REF_SIGN_EXTRACT or
cc806ac1
RS
2867 DF_REF_ZERO_EXTRACT. WIDTH, OFFSET and MODE are used to access the
2868 fields if they were constants. Otherwise they should be -1 if
2869 those flags were set. */
ca9052ce 2870
4d779342
DB
2871
2872static void
b8698a0f 2873df_ref_record (enum df_ref_class cl,
57512f53 2874 struct df_collection_rec *collection_rec,
b8698a0f 2875 rtx reg, rtx *loc,
50e94c7e 2876 basic_block bb, struct df_insn_info *insn_info,
b8698a0f 2877 enum df_ref_type ref_type,
bbbbb16a 2878 int ref_flags,
b8698a0f 2879 int width, int offset, enum machine_mode mode)
4d779342 2880{
23249ac4 2881 unsigned int regno;
4d779342 2882
7a40b8b1 2883 gcc_checking_assert (REG_P (reg) || GET_CODE (reg) == SUBREG);
4d779342 2884
4d779342
DB
2885 regno = REGNO (GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg);
2886 if (regno < FIRST_PSEUDO_REGISTER)
2887 {
23249ac4
DB
2888 struct df_mw_hardreg *hardreg = NULL;
2889 struct df_scan_problem_data *problem_data
6fb5fa3c
DB
2890 = (struct df_scan_problem_data *) df_scan->problem_data;
2891 unsigned int i;
2892 unsigned int endregno;
57512f53 2893 df_ref ref;
4d779342 2894
4d779342 2895 if (GET_CODE (reg) == SUBREG)
f1f4e530
JM
2896 {
2897 regno += subreg_regno_offset (regno, GET_MODE (SUBREG_REG (reg)),
2898 SUBREG_BYTE (reg), GET_MODE (reg));
09e18274 2899 endregno = regno + subreg_nregs (reg);
f1f4e530
JM
2900 }
2901 else
09e18274 2902 endregno = END_HARD_REGNO (reg);
4d779342 2903
6fb5fa3c
DB
2904 /* If this is a multiword hardreg, we create some extra
2905 datastructures that will enable us to easily build REG_DEAD
2906 and REG_UNUSED notes. */
50e94c7e 2907 if ((endregno != regno + 1) && insn_info)
23249ac4 2908 {
b8698a0f 2909 /* Sets to a subreg of a multiword register are partial.
23249ac4 2910 Sets to a non-subreg of a multiword register are not. */
6f5c1520 2911 if (GET_CODE (reg) == SUBREG)
23249ac4
DB
2912 ref_flags |= DF_REF_PARTIAL;
2913 ref_flags |= DF_REF_MW_HARDREG;
6fb5fa3c 2914
f883e0a7 2915 hardreg = (struct df_mw_hardreg *) pool_alloc (problem_data->mw_reg_pool);
23249ac4
DB
2916 hardreg->type = ref_type;
2917 hardreg->flags = ref_flags;
2918 hardreg->mw_reg = reg;
6fb5fa3c
DB
2919 hardreg->start_regno = regno;
2920 hardreg->end_regno = endregno - 1;
2921 hardreg->mw_order = df->ref_order++;
c2569604
ILT
2922 VEC_safe_push (df_mw_hardreg_ptr, stack, collection_rec->mw_vec,
2923 hardreg);
23249ac4
DB
2924 }
2925
4d779342
DB
2926 for (i = regno; i < endregno; i++)
2927 {
b8698a0f
L
2928 ref = df_ref_create_structure (cl, collection_rec, regno_reg_rtx[i], loc,
2929 bb, insn_info, ref_type, ref_flags,
cc806ac1 2930 width, offset, mode);
23249ac4 2931
6fb5fa3c 2932 gcc_assert (ORIGINAL_REGNO (DF_REF_REG (ref)) == i);
4d779342
DB
2933 }
2934 }
2935 else
2936 {
b8698a0f 2937 df_ref_create_structure (cl, collection_rec, reg, loc, bb, insn_info,
57512f53 2938 ref_type, ref_flags, width, offset, mode);
4d779342
DB
2939 }
2940}
2941
2942
2943/* A set to a non-paradoxical SUBREG for which the number of word_mode units
2944 covered by the outer mode is smaller than that covered by the inner mode,
2945 is a read-modify-write operation.
2946 This function returns true iff the SUBREG X is such a SUBREG. */
2947
2948bool
2949df_read_modify_subreg_p (rtx x)
2950{
2951 unsigned int isize, osize;
2952 if (GET_CODE (x) != SUBREG)
2953 return false;
2954 isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
2955 osize = GET_MODE_SIZE (GET_MODE (x));
7bb3ae2f
RZ
2956 return isize > osize
2957 && isize > REGMODE_NATURAL_SIZE (GET_MODE (SUBREG_REG (x)));
4d779342
DB
2958}
2959
2960
2961/* Process all the registers defined in the rtx, X.
2962 Autoincrement/decrement definitions will be picked up by
2963 df_uses_record. */
2964
2965static void
6fb5fa3c 2966df_def_record_1 (struct df_collection_rec *collection_rec,
50e94c7e 2967 rtx x, basic_block bb, struct df_insn_info *insn_info,
bbbbb16a 2968 int flags)
4d779342
DB
2969{
2970 rtx *loc;
2971 rtx dst;
ca9052ce
KZ
2972 int offset = -1;
2973 int width = -1;
81f40b79 2974 enum machine_mode mode = VOIDmode;
57512f53 2975 enum df_ref_class cl = DF_REF_REGULAR;
4d779342
DB
2976
2977 /* We may recursively call ourselves on EXPR_LIST when dealing with PARALLEL
2978 construct. */
2979 if (GET_CODE (x) == EXPR_LIST || GET_CODE (x) == CLOBBER)
2980 loc = &XEXP (x, 0);
2981 else
2982 loc = &SET_DEST (x);
2983 dst = *loc;
2984
b5642e20
DB
2985 /* It is legal to have a set destination be a parallel. */
2986 if (GET_CODE (dst) == PARALLEL)
4d779342
DB
2987 {
2988 int i;
2989
2990 for (i = XVECLEN (dst, 0) - 1; i >= 0; i--)
2991 {
2992 rtx temp = XVECEXP (dst, 0, i);
2993 if (GET_CODE (temp) == EXPR_LIST || GET_CODE (temp) == CLOBBER
2994 || GET_CODE (temp) == SET)
6fb5fa3c 2995 df_def_record_1 (collection_rec,
b8698a0f
L
2996 temp, bb, insn_info,
2997 GET_CODE (temp) == CLOBBER
6fb5fa3c 2998 ? flags | DF_REF_MUST_CLOBBER : flags);
4d779342
DB
2999 }
3000 return;
3001 }
3002
ca9052ce 3003 if (GET_CODE (dst) == STRICT_LOW_PART)
4d779342 3004 {
ca9052ce
KZ
3005 flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL | DF_REF_STRICT_LOW_PART;
3006
3007 loc = &XEXP (dst, 0);
3008 dst = *loc;
3009 }
3010
3011 if (GET_CODE (dst) == ZERO_EXTRACT)
3012 {
3013 flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL | DF_REF_ZERO_EXTRACT;
b8698a0f 3014
481683e1
SZ
3015 if (CONST_INT_P (XEXP (dst, 1))
3016 && CONST_INT_P (XEXP (dst, 2)))
ca9052ce
KZ
3017 {
3018 width = INTVAL (XEXP (dst, 1));
3019 offset = INTVAL (XEXP (dst, 2));
cc806ac1 3020 mode = GET_MODE (dst);
57512f53 3021 cl = DF_REF_EXTRACT;
ca9052ce 3022 }
ba49cb7b 3023
4d779342
DB
3024 loc = &XEXP (dst, 0);
3025 dst = *loc;
4d779342
DB
3026 }
3027
ba49cb7b
KZ
3028 /* At this point if we do not have a reg or a subreg, just return. */
3029 if (REG_P (dst))
3030 {
b8698a0f
L
3031 df_ref_record (cl, collection_rec,
3032 dst, loc, bb, insn_info, DF_REF_REG_DEF, flags,
cc806ac1 3033 width, offset, mode);
ba49cb7b
KZ
3034
3035 /* We want to keep sp alive everywhere - by making all
3036 writes to sp also use of sp. */
3037 if (REGNO (dst) == STACK_POINTER_REGNUM)
57512f53 3038 df_ref_record (DF_REF_BASE, collection_rec,
b8698a0f 3039 dst, NULL, bb, insn_info, DF_REF_REG_USE, flags,
cc806ac1 3040 width, offset, mode);
ba49cb7b
KZ
3041 }
3042 else if (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst)))
3043 {
3044 if (df_read_modify_subreg_p (dst))
3045 flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL;
7bb3ae2f 3046
ba49cb7b 3047 flags |= DF_REF_SUBREG;
47220f03 3048
b8698a0f
L
3049 df_ref_record (cl, collection_rec,
3050 dst, loc, bb, insn_info, DF_REF_REG_DEF, flags,
cc806ac1 3051 width, offset, mode);
ba49cb7b 3052 }
4d779342
DB
3053}
3054
3055
3056/* Process all the registers defined in the pattern rtx, X. */
3057
3058static void
b8698a0f 3059df_defs_record (struct df_collection_rec *collection_rec,
50e94c7e 3060 rtx x, basic_block bb, struct df_insn_info *insn_info,
bbbbb16a 3061 int flags)
4d779342
DB
3062{
3063 RTX_CODE code = GET_CODE (x);
3064
3065 if (code == SET || code == CLOBBER)
3066 {
3067 /* Mark the single def within the pattern. */
32e8bb8e 3068 int clobber_flags = flags;
6fb5fa3c 3069 clobber_flags |= (code == CLOBBER) ? DF_REF_MUST_CLOBBER : 0;
50e94c7e 3070 df_def_record_1 (collection_rec, x, bb, insn_info, clobber_flags);
4d779342
DB
3071 }
3072 else if (code == COND_EXEC)
3073 {
b8698a0f 3074 df_defs_record (collection_rec, COND_EXEC_CODE (x),
50e94c7e 3075 bb, insn_info, DF_REF_CONDITIONAL);
4d779342
DB
3076 }
3077 else if (code == PARALLEL)
3078 {
3079 int i;
3080
3081 /* Mark the multiple defs within the pattern. */
3082 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
50e94c7e 3083 df_defs_record (collection_rec, XVECEXP (x, 0, i), bb, insn_info, flags);
4d779342
DB
3084 }
3085}
3086
3087
b8698a0f 3088/* Process all the registers used in the rtx at address LOC.
ca9052ce
KZ
3089
3090 If the REF_FLAGS field contain DF_REF_SIGN_EXTRACT or
cc806ac1
RS
3091 DF_REF_ZERO_EXTRACT. WIDTH, OFFSET and MODE are used to access the
3092 fields if they were constants. Otherwise they should be -1 if
3093 those flags were set. */
4d779342
DB
3094
3095static void
57512f53 3096df_uses_record (enum df_ref_class cl, struct df_collection_rec *collection_rec,
6fb5fa3c 3097 rtx *loc, enum df_ref_type ref_type,
50e94c7e 3098 basic_block bb, struct df_insn_info *insn_info,
bbbbb16a 3099 int flags,
cc806ac1 3100 int width, int offset, enum machine_mode mode)
4d779342
DB
3101{
3102 RTX_CODE code;
3103 rtx x;
6fb5fa3c 3104
4d779342
DB
3105 retry:
3106 x = *loc;
3107 if (!x)
3108 return;
3109 code = GET_CODE (x);
3110 switch (code)
3111 {
3112 case LABEL_REF:
3113 case SYMBOL_REF:
3114 case CONST_INT:
3115 case CONST:
3116 case CONST_DOUBLE:
091a3ac7 3117 case CONST_FIXED:
4d779342
DB
3118 case CONST_VECTOR:
3119 case PC:
3120 case CC0:
3121 case ADDR_VEC:
3122 case ADDR_DIFF_VEC:
3123 return;
3124
3125 case CLOBBER:
3126 /* If we are clobbering a MEM, mark any registers inside the address
3127 as being used. */
3128 if (MEM_P (XEXP (x, 0)))
57512f53 3129 df_uses_record (cl, collection_rec,
6fb5fa3c 3130 &XEXP (XEXP (x, 0), 0),
50e94c7e
SB
3131 DF_REF_REG_MEM_STORE,
3132 bb, insn_info,
3133 flags, width, offset, mode);
4d779342
DB
3134
3135 /* If we're clobbering a REG then we have a def so ignore. */
3136 return;
3137
3138 case MEM:
57512f53 3139 df_uses_record (cl, collection_rec,
b8698a0f
L
3140 &XEXP (x, 0), DF_REF_REG_MEM_LOAD,
3141 bb, insn_info, flags & DF_REF_IN_NOTE,
cc806ac1 3142 width, offset, mode);
4d779342
DB
3143 return;
3144
3145 case SUBREG:
3146 /* While we're here, optimize this case. */
23249ac4 3147 flags |= DF_REF_PARTIAL;
4d779342
DB
3148 /* In case the SUBREG is not of a REG, do not optimize. */
3149 if (!REG_P (SUBREG_REG (x)))
3150 {
3151 loc = &SUBREG_REG (x);
b8698a0f 3152 df_uses_record (cl, collection_rec, loc, ref_type, bb, insn_info, flags,
cc806ac1 3153 width, offset, mode);
4d779342
DB
3154 return;
3155 }
3156 /* ... Fall through ... */
3157
3158 case REG:
b8698a0f 3159 df_ref_record (cl, collection_rec,
50e94c7e 3160 x, loc, bb, insn_info,
b8698a0f 3161 ref_type, flags,
cc806ac1 3162 width, offset, mode);
4d779342
DB
3163 return;
3164
ca9052ce
KZ
3165 case SIGN_EXTRACT:
3166 case ZERO_EXTRACT:
3167 {
3168 /* If the parameters to the zero or sign extract are
3169 constants, strip them off and recurse, otherwise there is
3170 no information that we can gain from this operation. */
481683e1
SZ
3171 if (CONST_INT_P (XEXP (x, 1))
3172 && CONST_INT_P (XEXP (x, 2)))
ca9052ce
KZ
3173 {
3174 width = INTVAL (XEXP (x, 1));
3175 offset = INTVAL (XEXP (x, 2));
cc806ac1 3176 mode = GET_MODE (x);
ca9052ce
KZ
3177
3178 if (code == ZERO_EXTRACT)
3179 flags |= DF_REF_ZERO_EXTRACT;
3180 else
3181 flags |= DF_REF_SIGN_EXTRACT;
3182
57512f53 3183 df_uses_record (DF_REF_EXTRACT, collection_rec,
b8698a0f 3184 &XEXP (x, 0), ref_type, bb, insn_info, flags,
cc806ac1 3185 width, offset, mode);
ca9052ce
KZ
3186 return;
3187 }
3188 }
3189 break;
3190
4d779342
DB
3191 case SET:
3192 {
3193 rtx dst = SET_DEST (x);
3194 gcc_assert (!(flags & DF_REF_IN_NOTE));
57512f53 3195 df_uses_record (cl, collection_rec,
b8698a0f 3196 &SET_SRC (x), DF_REF_REG_USE, bb, insn_info, flags,
cc806ac1 3197 width, offset, mode);
4d779342
DB
3198
3199 switch (GET_CODE (dst))
3200 {
3201 case SUBREG:
3202 if (df_read_modify_subreg_p (dst))
3203 {
b8698a0f
L
3204 df_uses_record (cl, collection_rec, &SUBREG_REG (dst),
3205 DF_REF_REG_USE, bb, insn_info,
3206 flags | DF_REF_READ_WRITE | DF_REF_SUBREG,
cc806ac1 3207 width, offset, mode);
4d779342
DB
3208 break;
3209 }
3210 /* Fall through. */
3211 case REG:
3212 case PARALLEL:
3213 case SCRATCH:
3214 case PC:
3215 case CC0:
3216 break;
3217 case MEM:
57512f53 3218 df_uses_record (cl, collection_rec, &XEXP (dst, 0),
b8698a0f 3219 DF_REF_REG_MEM_STORE, bb, insn_info, flags,
cc806ac1 3220 width, offset, mode);
4d779342
DB
3221 break;
3222 case STRICT_LOW_PART:
3223 {
3224 rtx *temp = &XEXP (dst, 0);
3225 /* A strict_low_part uses the whole REG and not just the
3226 SUBREG. */
3227 dst = XEXP (dst, 0);
b8698a0f
L
3228 df_uses_record (cl, collection_rec,
3229 (GET_CODE (dst) == SUBREG) ? &SUBREG_REG (dst) : temp,
50e94c7e 3230 DF_REF_REG_USE, bb, insn_info,
b8698a0f 3231 DF_REF_READ_WRITE | DF_REF_STRICT_LOW_PART,
cc806ac1 3232 width, offset, mode);
4d779342
DB
3233 }
3234 break;
3235 case ZERO_EXTRACT:
ca9052ce 3236 {
481683e1
SZ
3237 if (CONST_INT_P (XEXP (dst, 1))
3238 && CONST_INT_P (XEXP (dst, 2)))
ca9052ce
KZ
3239 {
3240 width = INTVAL (XEXP (dst, 1));
3241 offset = INTVAL (XEXP (dst, 2));
cc806ac1 3242 mode = GET_MODE (dst);
4f2da32b
KZ
3243 if (GET_CODE (XEXP (dst,0)) == MEM)
3244 {
3245 /* Handle the case of zero_extract(mem(...)) in the set dest.
b8698a0f 3246 This special case is allowed only if the mem is a single byte and
4f2da32b
KZ
3247 is useful to set a bitfield in memory. */
3248 df_uses_record (DF_REF_EXTRACT, collection_rec, &XEXP (XEXP (dst,0), 0),
3249 DF_REF_REG_MEM_STORE, bb, insn_info,
3250 DF_REF_ZERO_EXTRACT,
3251 width, offset, mode);
3252 }
3253 else
3254 {
b8698a0f
L
3255 df_uses_record (DF_REF_EXTRACT, collection_rec, &XEXP (dst, 0),
3256 DF_REF_REG_USE, bb, insn_info,
3257 DF_REF_READ_WRITE | DF_REF_ZERO_EXTRACT,
4f2da32b
KZ
3258 width, offset, mode);
3259 }
ca9052ce 3260 }
b8698a0f 3261 else
ca9052ce 3262 {
b8698a0f
L
3263 df_uses_record (cl, collection_rec, &XEXP (dst, 1),
3264 DF_REF_REG_USE, bb, insn_info, flags,
cc806ac1 3265 width, offset, mode);
b8698a0f
L
3266 df_uses_record (cl, collection_rec, &XEXP (dst, 2),
3267 DF_REF_REG_USE, bb, insn_info, flags,
cc806ac1 3268 width, offset, mode);
b8698a0f
L
3269 df_uses_record (cl, collection_rec, &XEXP (dst, 0),
3270 DF_REF_REG_USE, bb, insn_info,
3271 DF_REF_READ_WRITE | DF_REF_ZERO_EXTRACT,
57512f53 3272 width, offset, mode);
ca9052ce
KZ
3273 }
3274
ca9052ce 3275 }
4d779342 3276 break;
ca9052ce 3277
4d779342
DB
3278 default:
3279 gcc_unreachable ();
3280 }
3281 return;
3282 }
3283
3284 case RETURN:
3285 break;
3286
3287 case ASM_OPERANDS:
3288 case UNSPEC_VOLATILE:
3289 case TRAP_IF:
3290 case ASM_INPUT:
3291 {
3292 /* Traditional and volatile asm instructions must be
3293 considered to use and clobber all hard registers, all
3294 pseudo-registers and all of memory. So must TRAP_IF and
3295 UNSPEC_VOLATILE operations.
3296
3297 Consider for instance a volatile asm that changes the fpu
3298 rounding mode. An insn should not be moved across this
3299 even if it only uses pseudo-regs because it might give an
3300 incorrectly rounded result.
3301
3302 However, flow.c's liveness computation did *not* do this,
3303 giving the reasoning as " ?!? Unfortunately, marking all
3304 hard registers as live causes massive problems for the
3305 register allocator and marking all pseudos as live creates
3306 mountains of uninitialized variable warnings."
3307
3308 In order to maintain the status quo with regard to liveness
3309 and uses, we do what flow.c did and just mark any regs we
6fb5fa3c
DB
3310 can find in ASM_OPERANDS as used. In global asm insns are
3311 scanned and regs_asm_clobbered is filled out.
4d779342
DB
3312
3313 For all ASM_OPERANDS, we must traverse the vector of input
3314 operands. We can not just fall through here since then we
3315 would be confused by the ASM_INPUT rtx inside ASM_OPERANDS,
3316 which do not indicate traditional asms unlike their normal
3317 usage. */
3318 if (code == ASM_OPERANDS)
3319 {
3320 int j;
3321
3322 for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
57512f53 3323 df_uses_record (cl, collection_rec, &ASM_OPERANDS_INPUT (x, j),
b8698a0f 3324 DF_REF_REG_USE, bb, insn_info, flags,
cc806ac1 3325 width, offset, mode);
4d779342
DB
3326 return;
3327 }
3328 break;
3329 }
3330
b5b8b0ac
AO
3331 case VAR_LOCATION:
3332 df_uses_record (cl, collection_rec,
3333 &PAT_VAR_LOCATION_LOC (x),
3334 DF_REF_REG_USE, bb, insn_info,
3335 flags, width, offset, mode);
3336 return;
3337
4d779342
DB
3338 case PRE_DEC:
3339 case POST_DEC:
3340 case PRE_INC:
3341 case POST_INC:
3342 case PRE_MODIFY:
3343 case POST_MODIFY:
b5b8b0ac 3344 gcc_assert (!DEBUG_INSN_P (insn_info->insn));
4d779342 3345 /* Catch the def of the register being modified. */
57512f53 3346 df_ref_record (cl, collection_rec, XEXP (x, 0), &XEXP (x, 0),
b8698a0f 3347 bb, insn_info,
203927fc 3348 DF_REF_REG_DEF,
b8698a0f 3349 flags | DF_REF_READ_WRITE | DF_REF_PRE_POST_MODIFY,
cc806ac1 3350 width, offset, mode);
4d779342
DB
3351
3352 /* ... Fall through to handle uses ... */
3353
3354 default:
3355 break;
3356 }
3357
3358 /* Recursively scan the operands of this expression. */
3359 {
3360 const char *fmt = GET_RTX_FORMAT (code);
3361 int i;
3362
3363 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3364 {
3365 if (fmt[i] == 'e')
3366 {
3367 /* Tail recursive case: save a function call level. */
3368 if (i == 0)
3369 {
3370 loc = &XEXP (x, 0);
3371 goto retry;
3372 }
b8698a0f
L
3373 df_uses_record (cl, collection_rec, &XEXP (x, i), ref_type,
3374 bb, insn_info, flags,
cc806ac1 3375 width, offset, mode);
4d779342
DB
3376 }
3377 else if (fmt[i] == 'E')
3378 {
3379 int j;
3380 for (j = 0; j < XVECLEN (x, i); j++)
57512f53 3381 df_uses_record (cl, collection_rec,
b8698a0f
L
3382 &XVECEXP (x, i, j), ref_type,
3383 bb, insn_info, flags,
cc806ac1 3384 width, offset, mode);
4d779342
DB
3385 }
3386 }
3387 }
4d779342 3388
6fb5fa3c 3389 return;
4d779342
DB
3390}
3391
3392
6fb5fa3c 3393/* For all DF_REF_CONDITIONAL defs, add a corresponding uses. */
4d779342 3394
6fb5fa3c
DB
3395static void
3396df_get_conditional_uses (struct df_collection_rec *collection_rec)
4d779342 3397{
c2569604
ILT
3398 unsigned int ix;
3399 df_ref ref;
3400
3401 for (ix = 0; VEC_iterate (df_ref, collection_rec->def_vec, ix, ref); ++ix)
6fb5fa3c 3402 {
6fb5fa3c
DB
3403 if (DF_REF_FLAGS_IS_SET (ref, DF_REF_CONDITIONAL))
3404 {
ca9052ce
KZ
3405 int width = -1;
3406 int offset = -1;
81f40b79 3407 enum machine_mode mode = VOIDmode;
57512f53 3408 df_ref use;
ca9052ce
KZ
3409
3410 if (DF_REF_FLAGS_IS_SET (ref, DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT))
3411 {
cc806ac1
RS
3412 width = DF_REF_EXTRACT_WIDTH (ref);
3413 offset = DF_REF_EXTRACT_OFFSET (ref);
3414 mode = DF_REF_EXTRACT_MODE (ref);
ca9052ce
KZ
3415 }
3416
57512f53 3417 use = df_ref_create_structure (DF_REF_CLASS (ref), collection_rec, DF_REF_REG (ref),
ca9052ce 3418 DF_REF_LOC (ref), DF_REF_BB (ref),
50e94c7e 3419 DF_REF_INSN_INFO (ref), DF_REF_REG_USE,
ca9052ce 3420 DF_REF_FLAGS (ref) & ~DF_REF_CONDITIONAL,
cc806ac1 3421 width, offset, mode);
6fb5fa3c
DB
3422 DF_REF_REGNO (use) = DF_REF_REGNO (ref);
3423 }
3424 }
4d779342
DB
3425}
3426
3427
6fb5fa3c 3428/* Get call's extra defs and uses. */
4d779342
DB
3429
3430static void
6fb5fa3c 3431df_get_call_refs (struct df_collection_rec * collection_rec,
b8698a0f 3432 basic_block bb,
50e94c7e 3433 struct df_insn_info *insn_info,
bbbbb16a 3434 int flags)
4d779342 3435{
6fb5fa3c
DB
3436 rtx note;
3437 bitmap_iterator bi;
3438 unsigned int ui;
3439 bool is_sibling_call;
3440 unsigned int i;
c2569604 3441 df_ref def;
a7e3698d
JH
3442 bitmap_head defs_generated;
3443
3444 bitmap_initialize (&defs_generated, &df_bitmap_obstack);
4d779342 3445
6fb5fa3c
DB
3446 /* Do not generate clobbers for registers that are the result of the
3447 call. This causes ordering problems in the chain building code
3448 depending on which def is seen first. */
c2569604 3449 for (i = 0; VEC_iterate (df_ref, collection_rec->def_vec, i, def); ++i)
a7e3698d 3450 bitmap_set_bit (&defs_generated, DF_REF_REGNO (def));
4d779342 3451
6fb5fa3c
DB
3452 /* Record the registers used to pass arguments, and explicitly
3453 noted as clobbered. */
50e94c7e 3454 for (note = CALL_INSN_FUNCTION_USAGE (insn_info->insn); note;
6fb5fa3c
DB
3455 note = XEXP (note, 1))
3456 {
3457 if (GET_CODE (XEXP (note, 0)) == USE)
57512f53 3458 df_uses_record (DF_REF_REGULAR, collection_rec, &XEXP (XEXP (note, 0), 0),
bbbbb16a
ILT
3459 DF_REF_REG_USE, bb, insn_info, flags, -1, -1,
3460 VOIDmode);
6fb5fa3c
DB
3461 else if (GET_CODE (XEXP (note, 0)) == CLOBBER)
3462 {
7e657ec2
EB
3463 if (REG_P (XEXP (XEXP (note, 0), 0)))
3464 {
3465 unsigned int regno = REGNO (XEXP (XEXP (note, 0), 0));
a7e3698d 3466 if (!bitmap_bit_p (&defs_generated, regno))
7e657ec2 3467 df_defs_record (collection_rec, XEXP (note, 0), bb,
50e94c7e 3468 insn_info, flags);
7e657ec2
EB
3469 }
3470 else
57512f53 3471 df_uses_record (DF_REF_REGULAR, collection_rec, &XEXP (note, 0),
bbbbb16a
ILT
3472 DF_REF_REG_USE, bb, insn_info, flags, -1, -1,
3473 VOIDmode);
6fb5fa3c
DB
3474 }
3475 }
4d779342 3476
6fb5fa3c 3477 /* The stack ptr is used (honorarily) by a CALL insn. */
57512f53 3478 df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[STACK_POINTER_REGNUM],
50e94c7e 3479 NULL, bb, insn_info, DF_REF_REG_USE,
b8698a0f 3480 DF_REF_CALL_STACK_USAGE | flags,
bbbbb16a 3481 -1, -1, VOIDmode);
4d779342 3482
6fb5fa3c
DB
3483 /* Calls may also reference any of the global registers,
3484 so they are recorded as used. */
3485 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3486 if (global_regs[i])
f1688176 3487 {
57512f53 3488 df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i],
bbbbb16a
ILT
3489 NULL, bb, insn_info, DF_REF_REG_USE, flags, -1, -1,
3490 VOIDmode);
57512f53 3491 df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i],
bbbbb16a
ILT
3492 NULL, bb, insn_info, DF_REF_REG_DEF, flags, -1, -1,
3493 VOIDmode);
f1688176 3494 }
4d779342 3495
50e94c7e 3496 is_sibling_call = SIBLING_CALL_P (insn_info->insn);
f2ecb626 3497 EXECUTE_IF_SET_IN_BITMAP (regs_invalidated_by_call_regset, 0, ui, bi)
6fb5fa3c 3498 {
f1688176 3499 if (!global_regs[ui]
a7e3698d 3500 && (!bitmap_bit_p (&defs_generated, ui))
6fb5fa3c
DB
3501 && (!is_sibling_call
3502 || !bitmap_bit_p (df->exit_block_uses, ui)
b8698a0f 3503 || refers_to_regno_p (ui, ui+1,
38173d38 3504 crtl->return_rtx, NULL)))
b8698a0f 3505 df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[ui],
50e94c7e 3506 NULL, bb, insn_info, DF_REF_REG_DEF,
b8698a0f 3507 DF_REF_MAY_CLOBBER | flags,
bbbbb16a 3508 -1, -1, VOIDmode);
6fb5fa3c
DB
3509 }
3510
a7e3698d 3511 bitmap_clear (&defs_generated);
6fb5fa3c
DB
3512 return;
3513}
4d779342 3514
6fb5fa3c
DB
3515/* Collect all refs in the INSN. This function is free of any
3516 side-effect - it will create and return a lists of df_ref's in the
3517 COLLECTION_REC without putting those refs into existing ref chains
3518 and reg chains. */
4d779342 3519
6fb5fa3c 3520static void
b8698a0f
L
3521df_insn_refs_collect (struct df_collection_rec* collection_rec,
3522 basic_block bb, struct df_insn_info *insn_info)
6fb5fa3c
DB
3523{
3524 rtx note;
50e94c7e 3525 bool is_cond_exec = (GET_CODE (PATTERN (insn_info->insn)) == COND_EXEC);
4d779342 3526
6fb5fa3c 3527 /* Clear out the collection record. */
c2569604
ILT
3528 VEC_truncate (df_ref, collection_rec->def_vec, 0);
3529 VEC_truncate (df_ref, collection_rec->use_vec, 0);
3530 VEC_truncate (df_ref, collection_rec->eq_use_vec, 0);
3531 VEC_truncate (df_mw_hardreg_ptr, collection_rec->mw_vec, 0);
4d779342 3532
6fb5fa3c 3533 /* Record register defs. */
50e94c7e 3534 df_defs_record (collection_rec, PATTERN (insn_info->insn), bb, insn_info, 0);
6fb5fa3c 3535
50e94c7e
SB
3536 /* Process REG_EQUIV/REG_EQUAL notes. */
3537 for (note = REG_NOTES (insn_info->insn); note;
6fb5fa3c
DB
3538 note = XEXP (note, 1))
3539 {
3540 switch (REG_NOTE_KIND (note))
3541 {
3542 case REG_EQUIV:
3543 case REG_EQUAL:
57512f53 3544 df_uses_record (DF_REF_REGULAR, collection_rec,
6fb5fa3c 3545 &XEXP (note, 0), DF_REF_REG_USE,
bbbbb16a 3546 bb, insn_info, DF_REF_IN_NOTE, -1, -1, VOIDmode);
6fb5fa3c
DB
3547 break;
3548 case REG_NON_LOCAL_GOTO:
3549 /* The frame ptr is used by a non-local goto. */
57512f53 3550 df_ref_record (DF_REF_BASE, collection_rec,
6fb5fa3c 3551 regno_reg_rtx[FRAME_POINTER_REGNUM],
50e94c7e 3552 NULL, bb, insn_info,
bbbbb16a 3553 DF_REF_REG_USE, 0, -1, -1, VOIDmode);
6fb5fa3c 3554#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
57512f53 3555 df_ref_record (DF_REF_BASE, collection_rec,
6fb5fa3c 3556 regno_reg_rtx[HARD_FRAME_POINTER_REGNUM],
50e94c7e 3557 NULL, bb, insn_info,
bbbbb16a 3558 DF_REF_REG_USE, 0, -1, -1, VOIDmode);
6fb5fa3c
DB
3559#endif
3560 break;
3561 default:
3562 break;
3563 }
4d779342 3564 }
6fb5fa3c 3565
50e94c7e 3566 if (CALL_P (insn_info->insn))
b8698a0f 3567 df_get_call_refs (collection_rec, bb, insn_info,
6fb5fa3c
DB
3568 (is_cond_exec) ? DF_REF_CONDITIONAL : 0);
3569
3570 /* Record the register uses. */
57512f53 3571 df_uses_record (DF_REF_REGULAR, collection_rec,
b8698a0f 3572 &PATTERN (insn_info->insn), DF_REF_REG_USE, bb, insn_info, 0,
bbbbb16a 3573 -1, -1, VOIDmode);
6fb5fa3c
DB
3574
3575 /* DF_REF_CONDITIONAL needs corresponding USES. */
3576 if (is_cond_exec)
3577 df_get_conditional_uses (collection_rec);
3578
3579 df_canonize_collection_rec (collection_rec);
4d779342
DB
3580}
3581
6fb5fa3c
DB
3582/* Recompute the luids for the insns in BB. */
3583
3584void
3585df_recompute_luids (basic_block bb)
4d779342 3586{
4d779342
DB
3587 rtx insn;
3588 int luid = 0;
23249ac4 3589
6fb5fa3c 3590 df_grow_insn_info ();
4d779342
DB
3591
3592 /* Scan the block an insn at a time from beginning to end. */
3593 FOR_BB_INSNS (bb, insn)
3594 {
50e94c7e 3595 struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
6fb5fa3c
DB
3596 /* Inserting labels does not always trigger the incremental
3597 rescanning. */
3598 if (!insn_info)
4d779342 3599 {
6fb5fa3c 3600 gcc_assert (!INSN_P (insn));
50e94c7e 3601 insn_info = df_insn_create_insn_record (insn);
4d779342 3602 }
6fb5fa3c 3603
50e94c7e 3604 DF_INSN_INFO_LUID (insn_info) = luid;
6fb5fa3c
DB
3605 if (INSN_P (insn))
3606 luid++;
3607 }
3608}
3609
3610
6fb5fa3c
DB
3611/* Collect all artificial refs at the block level for BB and add them
3612 to COLLECTION_REC. */
3613
3614static void
3615df_bb_refs_collect (struct df_collection_rec *collection_rec, basic_block bb)
3616{
c2569604
ILT
3617 VEC_truncate (df_ref, collection_rec->def_vec, 0);
3618 VEC_truncate (df_ref, collection_rec->use_vec, 0);
3619 VEC_truncate (df_ref, collection_rec->eq_use_vec, 0);
3620 VEC_truncate (df_mw_hardreg_ptr, collection_rec->mw_vec, 0);
6fb5fa3c
DB
3621
3622 if (bb->index == ENTRY_BLOCK)
3623 {
3624 df_entry_block_defs_collect (collection_rec, df->entry_block_defs);
3625 return;
3626 }
3627 else if (bb->index == EXIT_BLOCK)
3628 {
3629 df_exit_block_uses_collect (collection_rec, df->exit_block_uses);
3630 return;
4d779342
DB
3631 }
3632
3633#ifdef EH_RETURN_DATA_REGNO
ba49cb7b 3634 if (bb_has_eh_pred (bb))
4d779342
DB
3635 {
3636 unsigned int i;
3637 /* Mark the registers that will contain data for the handler. */
912f2dac
DB
3638 for (i = 0; ; ++i)
3639 {
3640 unsigned regno = EH_RETURN_DATA_REGNO (i);
3641 if (regno == INVALID_REGNUM)
3642 break;
57512f53 3643 df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[regno], NULL,
bbbbb16a
ILT
3644 bb, NULL, DF_REF_REG_DEF, DF_REF_AT_TOP, -1, -1,
3645 VOIDmode);
912f2dac 3646 }
4d779342
DB
3647 }
3648#endif
3649
6fb5fa3c
DB
3650 /* Add the hard_frame_pointer if this block is the target of a
3651 non-local goto. */
3652 if (bb->flags & BB_NON_LOCAL_GOTO_TARGET)
57512f53 3653 df_ref_record (DF_REF_ARTIFICIAL, collection_rec, hard_frame_pointer_rtx, NULL,
bbbbb16a 3654 bb, NULL, DF_REF_REG_DEF, DF_REF_AT_TOP, -1, -1, VOIDmode);
b8698a0f 3655
6fb5fa3c
DB
3656 /* Add the artificial uses. */
3657 if (bb->index >= NUM_FIXED_BLOCKS)
23249ac4
DB
3658 {
3659 bitmap_iterator bi;
3660 unsigned int regno;
b8698a0f 3661 bitmap au = bb_has_eh_pred (bb)
a7e3698d
JH
3662 ? &df->eh_block_artificial_uses
3663 : &df->regular_block_artificial_uses;
23249ac4 3664
6fb5fa3c 3665 EXECUTE_IF_SET_IN_BITMAP (au, 0, regno, bi)
23249ac4 3666 {
57512f53 3667 df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[regno], NULL,
bbbbb16a 3668 bb, NULL, DF_REF_REG_USE, 0, -1, -1, VOIDmode);
23249ac4 3669 }
4d779342 3670 }
6fb5fa3c
DB
3671
3672 df_canonize_collection_rec (collection_rec);
4d779342
DB
3673}
3674
268886f3 3675
6fb5fa3c
DB
3676/* Record all the refs within the basic block BB_INDEX and scan the instructions if SCAN_INSNS. */
3677
3678void
3679df_bb_refs_record (int bb_index, bool scan_insns)
268886f3 3680{
6fb5fa3c
DB
3681 basic_block bb = BASIC_BLOCK (bb_index);
3682 rtx insn;
3683 int luid = 0;
6fb5fa3c 3684 struct df_collection_rec collection_rec;
268886f3 3685
6fb5fa3c 3686 if (!df)
268886f3
ZD
3687 return;
3688
e285df08 3689 df_grow_bb_info (df_scan);
c2569604
ILT
3690 collection_rec.def_vec = VEC_alloc (df_ref, stack, 128);
3691 collection_rec.use_vec = VEC_alloc (df_ref, stack, 32);
3692 collection_rec.eq_use_vec = VEC_alloc (df_ref, stack, 32);
3693 collection_rec.mw_vec = VEC_alloc (df_mw_hardreg_ptr, stack, 32);
3694
6fb5fa3c
DB
3695 if (scan_insns)
3696 /* Scan the block an insn at a time from beginning to end. */
3697 FOR_BB_INSNS (bb, insn)
3698 {
50e94c7e 3699 struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
6fb5fa3c
DB
3700 gcc_assert (!insn_info);
3701
50e94c7e 3702 insn_info = df_insn_create_insn_record (insn);
6fb5fa3c
DB
3703 if (INSN_P (insn))
3704 {
3705 /* Record refs within INSN. */
50e94c7e
SB
3706 DF_INSN_INFO_LUID (insn_info) = luid++;
3707 df_insn_refs_collect (&collection_rec, bb, DF_INSN_INFO_GET (insn));
6fb5fa3c
DB
3708 df_refs_add_to_chains (&collection_rec, bb, insn);
3709 }
50e94c7e 3710 DF_INSN_INFO_LUID (insn_info) = luid;
6fb5fa3c
DB
3711 }
3712
3713 /* Other block level artificial refs */
3714 df_bb_refs_collect (&collection_rec, bb);
3715 df_refs_add_to_chains (&collection_rec, bb, NULL);
3716
c2569604
ILT
3717 VEC_free (df_ref, stack, collection_rec.def_vec);
3718 VEC_free (df_ref, stack, collection_rec.use_vec);
3719 VEC_free (df_ref, stack, collection_rec.eq_use_vec);
3720 VEC_free (df_mw_hardreg_ptr, stack, collection_rec.mw_vec);
3721
6fb5fa3c 3722 /* Now that the block has been processed, set the block as dirty so
05c219bb 3723 LR and LIVE will get it processed. */
6fb5fa3c 3724 df_set_bb_dirty (bb);
268886f3 3725}
4d779342 3726
6fb5fa3c
DB
3727
3728/* Get the artificial use set for a regular (i.e. non-exit/non-entry)
3729 block. */
4d779342
DB
3730
3731static void
6fb5fa3c 3732df_get_regular_block_artificial_uses (bitmap regular_block_artificial_uses)
4d779342 3733{
60d52d0d
JJ
3734#ifdef EH_USES
3735 unsigned int i;
3736#endif
3737
6fb5fa3c 3738 bitmap_clear (regular_block_artificial_uses);
4d779342 3739
6fb5fa3c 3740 if (reload_completed)
4d779342 3741 {
6fb5fa3c
DB
3742 if (frame_pointer_needed)
3743 bitmap_set_bit (regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM);
3744 }
3745 else
3746 /* Before reload, there are a few registers that must be forced
3747 live everywhere -- which might not already be the case for
3748 blocks within infinite loops. */
3749 {
3750 /* Any reference to any pseudo before reload is a potential
3751 reference of the frame pointer. */
3752 bitmap_set_bit (regular_block_artificial_uses, FRAME_POINTER_REGNUM);
b8698a0f 3753
6fb5fa3c
DB
3754#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
3755 bitmap_set_bit (regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM);
3756#endif
3757
3758#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
3759 /* Pseudos with argument area equivalences may require
3760 reloading via the argument pointer. */
3761 if (fixed_regs[ARG_POINTER_REGNUM])
3762 bitmap_set_bit (regular_block_artificial_uses, ARG_POINTER_REGNUM);
3763#endif
b8698a0f 3764
6fb5fa3c
DB
3765 /* Any constant, or pseudo with constant equivalences, may
3766 require reloading from memory using the pic register. */
3767 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
3768 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
3769 bitmap_set_bit (regular_block_artificial_uses, PIC_OFFSET_TABLE_REGNUM);
4d779342 3770 }
6fb5fa3c
DB
3771 /* The all-important stack pointer must always be live. */
3772 bitmap_set_bit (regular_block_artificial_uses, STACK_POINTER_REGNUM);
60d52d0d
JJ
3773
3774#ifdef EH_USES
3775 /* EH_USES registers are used:
3776 1) at all insns that might throw (calls or with -fnon-call-exceptions
3777 trapping insns)
3778 2) in all EH edges
3779 3) to support backtraces and/or debugging, anywhere between their
3780 initialization and where they the saved registers are restored
3781 from them, including the cases where we don't reach the epilogue
3782 (noreturn call or infinite loop). */
3783 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3784 if (EH_USES (i))
3785 bitmap_set_bit (regular_block_artificial_uses, i);
3786#endif
6fb5fa3c
DB
3787}
3788
4d779342 3789
6fb5fa3c 3790/* Get the artificial use set for an eh block. */
912f2dac 3791
6fb5fa3c
DB
3792static void
3793df_get_eh_block_artificial_uses (bitmap eh_block_artificial_uses)
3794{
3795 bitmap_clear (eh_block_artificial_uses);
268886f3 3796
6ed3da00 3797 /* The following code (down thru the arg_pointer setting APPEARS
6fb5fa3c
DB
3798 to be necessary because there is nothing that actually
3799 describes what the exception handling code may actually need
3800 to keep alive. */
3801 if (reload_completed)
3802 {
3803 if (frame_pointer_needed)
3804 {
3805 bitmap_set_bit (eh_block_artificial_uses, FRAME_POINTER_REGNUM);
3806#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
3807 bitmap_set_bit (eh_block_artificial_uses, HARD_FRAME_POINTER_REGNUM);
3808#endif
3809 }
3810#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
3811 if (fixed_regs[ARG_POINTER_REGNUM])
3812 bitmap_set_bit (eh_block_artificial_uses, ARG_POINTER_REGNUM);
3813#endif
3814 }
4d779342
DB
3815}
3816
3817
6fb5fa3c 3818\f
4d779342
DB
3819/*----------------------------------------------------------------------------
3820 Specialized hard register scanning functions.
3821----------------------------------------------------------------------------*/
3822
6fb5fa3c 3823
4d779342
DB
3824/* Mark a register in SET. Hard registers in large modes get all
3825 of their component registers set as well. */
3826
3827static void
3828df_mark_reg (rtx reg, void *vset)
3829{
3830 bitmap set = (bitmap) vset;
3831 int regno = REGNO (reg);
3832
3833 gcc_assert (GET_MODE (reg) != BLKmode);
3834
4d779342
DB
3835 if (regno < FIRST_PSEUDO_REGISTER)
3836 {
3837 int n = hard_regno_nregs[regno][GET_MODE (reg)];
a099f7d4 3838 bitmap_set_range (set, regno, n);
4d779342 3839 }
a099f7d4
RG
3840 else
3841 bitmap_set_bit (set, regno);
4d779342
DB
3842}
3843
912f2dac 3844
6fb5fa3c 3845/* Set the bit for regs that are considered being defined at the entry. */
912f2dac
DB
3846
3847static void
6fb5fa3c 3848df_get_entry_block_def_set (bitmap entry_block_defs)
912f2dac 3849{
912f2dac 3850 rtx r;
6fb5fa3c 3851 int i;
912f2dac 3852
6fb5fa3c 3853 bitmap_clear (entry_block_defs);
912f2dac
DB
3854
3855 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3856 {
3857 if (FUNCTION_ARG_REGNO_P (i))
3858#ifdef INCOMING_REGNO
6fb5fa3c 3859 bitmap_set_bit (entry_block_defs, INCOMING_REGNO (i));
912f2dac 3860#else
6fb5fa3c 3861 bitmap_set_bit (entry_block_defs, i);
912f2dac
DB
3862#endif
3863 }
b8698a0f 3864
1d489435
RS
3865 /* The always important stack pointer. */
3866 bitmap_set_bit (entry_block_defs, STACK_POINTER_REGNUM);
3867
912f2dac
DB
3868 /* Once the prologue has been generated, all of these registers
3869 should just show up in the first regular block. */
3870 if (HAVE_prologue && epilogue_completed)
3871 {
3872 /* Defs for the callee saved registers are inserted so that the
3873 pushes have some defining location. */
3874 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
6fb5fa3c
DB
3875 if ((call_used_regs[i] == 0) && (df_regs_ever_live_p (i)))
3876 bitmap_set_bit (entry_block_defs, i);
912f2dac 3877 }
912f2dac 3878
bff98546
JJ
3879 r = targetm.calls.struct_value_rtx (current_function_decl, true);
3880 if (r && REG_P (r))
3881 bitmap_set_bit (entry_block_defs, REGNO (r));
3882
531ca746
RH
3883 /* If the function has an incoming STATIC_CHAIN, it has to show up
3884 in the entry def set. */
3885 r = targetm.calls.static_chain (current_function_decl, true);
3886 if (r && REG_P (r))
3887 bitmap_set_bit (entry_block_defs, REGNO (r));
3888
23249ac4 3889 if ((!reload_completed) || frame_pointer_needed)
912f2dac
DB
3890 {
3891 /* Any reference to any pseudo before reload is a potential
3892 reference of the frame pointer. */
6fb5fa3c 3893 bitmap_set_bit (entry_block_defs, FRAME_POINTER_REGNUM);
23249ac4
DB
3894#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
3895 /* If they are different, also mark the hard frame pointer as live. */
3896 if (!LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
6fb5fa3c 3897 bitmap_set_bit (entry_block_defs, HARD_FRAME_POINTER_REGNUM);
23249ac4
DB
3898#endif
3899 }
912f2dac 3900
23249ac4
DB
3901 /* These registers are live everywhere. */
3902 if (!reload_completed)
3903 {
912f2dac
DB
3904#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
3905 /* Pseudos with argument area equivalences may require
3906 reloading via the argument pointer. */
3907 if (fixed_regs[ARG_POINTER_REGNUM])
6fb5fa3c 3908 bitmap_set_bit (entry_block_defs, ARG_POINTER_REGNUM);
912f2dac 3909#endif
b8698a0f 3910
912f2dac
DB
3911#ifdef PIC_OFFSET_TABLE_REGNUM
3912 /* Any constant, or pseudo with constant equivalences, may
3913 require reloading from memory using the pic register. */
3914 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
3915 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
6fb5fa3c
DB
3916 bitmap_set_bit (entry_block_defs, PIC_OFFSET_TABLE_REGNUM);
3917#endif
3918 }
3919
3920#ifdef INCOMING_RETURN_ADDR_RTX
3921 if (REG_P (INCOMING_RETURN_ADDR_RTX))
3922 bitmap_set_bit (entry_block_defs, REGNO (INCOMING_RETURN_ADDR_RTX));
3923#endif
b8698a0f 3924
38f8b050 3925 targetm.extra_live_on_entry (entry_block_defs);
6fb5fa3c
DB
3926}
3927
3928
3929/* Return the (conservative) set of hard registers that are defined on
b8698a0f
L
3930 entry to the function.
3931 It uses df->entry_block_defs to determine which register
6fb5fa3c
DB
3932 reference to include. */
3933
3934static void
b8698a0f 3935df_entry_block_defs_collect (struct df_collection_rec *collection_rec,
6fb5fa3c
DB
3936 bitmap entry_block_defs)
3937{
b8698a0f 3938 unsigned int i;
6fb5fa3c
DB
3939 bitmap_iterator bi;
3940
3941 EXECUTE_IF_SET_IN_BITMAP (entry_block_defs, 0, i, bi)
3942 {
b8698a0f 3943 df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[i], NULL,
bbbbb16a
ILT
3944 ENTRY_BLOCK_PTR, NULL, DF_REF_REG_DEF, 0, -1, -1,
3945 VOIDmode);
6fb5fa3c
DB
3946 }
3947
3948 df_canonize_collection_rec (collection_rec);
3949}
3950
3951
3952/* Record the (conservative) set of hard registers that are defined on
3953 entry to the function. */
3954
3955static void
3956df_record_entry_block_defs (bitmap entry_block_defs)
3957{
3958 struct df_collection_rec collection_rec;
3959 memset (&collection_rec, 0, sizeof (struct df_collection_rec));
c2569604 3960 collection_rec.def_vec = VEC_alloc (df_ref, stack, FIRST_PSEUDO_REGISTER);
6fb5fa3c
DB
3961 df_entry_block_defs_collect (&collection_rec, entry_block_defs);
3962
3963 /* Process bb_refs chain */
3964 df_refs_add_to_chains (&collection_rec, BASIC_BLOCK (ENTRY_BLOCK), NULL);
c2569604 3965 VEC_free (df_ref, stack, collection_rec.def_vec);
6fb5fa3c
DB
3966}
3967
3968
15dc95cb 3969/* Update the defs in the entry block. */
6fb5fa3c
DB
3970
3971void
3972df_update_entry_block_defs (void)
3973{
a7e3698d 3974 bitmap_head refs;
6fb5fa3c 3975 bool changed = false;
912f2dac 3976
a7e3698d
JH
3977 bitmap_initialize (&refs, &df_bitmap_obstack);
3978 df_get_entry_block_def_set (&refs);
6fb5fa3c
DB
3979 if (df->entry_block_defs)
3980 {
a7e3698d 3981 if (!bitmap_equal_p (df->entry_block_defs, &refs))
6fb5fa3c
DB
3982 {
3983 struct df_scan_bb_info *bb_info = df_scan_get_bb_info (ENTRY_BLOCK);
3984 df_ref_chain_delete_du_chain (bb_info->artificial_defs);
3985 df_ref_chain_delete (bb_info->artificial_defs);
3986 bb_info->artificial_defs = NULL;
3987 changed = true;
3988 }
3989 }
3990 else
3991 {
3992 struct df_scan_problem_data *problem_data
3993 = (struct df_scan_problem_data *) df_scan->problem_data;
a7e3698d 3994 gcc_unreachable ();
6fb5fa3c
DB
3995 df->entry_block_defs = BITMAP_ALLOC (&problem_data->reg_bitmaps);
3996 changed = true;
3997 }
912f2dac 3998
6fb5fa3c 3999 if (changed)
912f2dac 4000 {
a7e3698d
JH
4001 df_record_entry_block_defs (&refs);
4002 bitmap_copy (df->entry_block_defs, &refs);
6fb5fa3c 4003 df_set_bb_dirty (BASIC_BLOCK (ENTRY_BLOCK));
912f2dac 4004 }
a7e3698d 4005 bitmap_clear (&refs);
912f2dac
DB
4006}
4007
4008
6fb5fa3c 4009/* Set the bit for regs that are considered being used at the exit. */
4d779342
DB
4010
4011static void
6fb5fa3c 4012df_get_exit_block_use_set (bitmap exit_block_uses)
4d779342 4013{
b8698a0f 4014 unsigned int i;
4d779342 4015
6fb5fa3c 4016 bitmap_clear (exit_block_uses);
b718216c
SP
4017
4018 /* Stack pointer is always live at the exit. */
4019 bitmap_set_bit (exit_block_uses, STACK_POINTER_REGNUM);
b8698a0f 4020
4d779342
DB
4021 /* Mark the frame pointer if needed at the end of the function.
4022 If we end up eliminating it, it will be removed from the live
4023 list of each basic block by reload. */
b8698a0f 4024
23249ac4 4025 if ((!reload_completed) || frame_pointer_needed)
4d779342 4026 {
6fb5fa3c 4027 bitmap_set_bit (exit_block_uses, FRAME_POINTER_REGNUM);
4d779342
DB
4028#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
4029 /* If they are different, also mark the hard frame pointer as live. */
23249ac4 4030 if (!LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
6fb5fa3c 4031 bitmap_set_bit (exit_block_uses, HARD_FRAME_POINTER_REGNUM);
4d779342
DB
4032#endif
4033 }
4034
4035#ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
4036 /* Many architectures have a GP register even without flag_pic.
4037 Assume the pic register is not in use, or will be handled by
4038 other means, if it is not fixed. */
4039 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
4040 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
6fb5fa3c 4041 bitmap_set_bit (exit_block_uses, PIC_OFFSET_TABLE_REGNUM);
4d779342 4042#endif
b8698a0f 4043
4d779342
DB
4044 /* Mark all global registers, and all registers used by the
4045 epilogue as being live at the end of the function since they
4046 may be referenced by our caller. */
4047 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4048 if (global_regs[i] || EPILOGUE_USES (i))
6fb5fa3c 4049 bitmap_set_bit (exit_block_uses, i);
b8698a0f 4050
4d779342
DB
4051 if (HAVE_epilogue && epilogue_completed)
4052 {
4053 /* Mark all call-saved registers that we actually used. */
4054 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
6fb5fa3c 4055 if (df_regs_ever_live_p (i) && !LOCAL_REGNO (i)
23249ac4 4056 && !TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
6fb5fa3c 4057 bitmap_set_bit (exit_block_uses, i);
4d779342 4058 }
b8698a0f 4059
4d779342
DB
4060#ifdef EH_RETURN_DATA_REGNO
4061 /* Mark the registers that will contain data for the handler. */
e3b5732b 4062 if (reload_completed && crtl->calls_eh_return)
4d779342
DB
4063 for (i = 0; ; ++i)
4064 {
4065 unsigned regno = EH_RETURN_DATA_REGNO (i);
4066 if (regno == INVALID_REGNUM)
4067 break;
6fb5fa3c 4068 bitmap_set_bit (exit_block_uses, regno);
4d779342
DB
4069 }
4070#endif
4071
4072#ifdef EH_RETURN_STACKADJ_RTX
23249ac4 4073 if ((!HAVE_epilogue || ! epilogue_completed)
e3b5732b 4074 && crtl->calls_eh_return)
4d779342
DB
4075 {
4076 rtx tmp = EH_RETURN_STACKADJ_RTX;
4077 if (tmp && REG_P (tmp))
6fb5fa3c 4078 df_mark_reg (tmp, exit_block_uses);
4d779342
DB
4079 }
4080#endif
4081
4082#ifdef EH_RETURN_HANDLER_RTX
23249ac4 4083 if ((!HAVE_epilogue || ! epilogue_completed)
e3b5732b 4084 && crtl->calls_eh_return)
4d779342
DB
4085 {
4086 rtx tmp = EH_RETURN_HANDLER_RTX;
4087 if (tmp && REG_P (tmp))
6fb5fa3c 4088 df_mark_reg (tmp, exit_block_uses);
4d779342 4089 }
b8698a0f 4090#endif
6fb5fa3c 4091
4d779342 4092 /* Mark function return value. */
6fb5fa3c
DB
4093 diddle_return_value (df_mark_reg, (void*) exit_block_uses);
4094}
4095
4096
b8698a0f 4097/* Return the refs of hard registers that are used in the exit block.
6fb5fa3c
DB
4098 It uses df->exit_block_uses to determine register to include. */
4099
4100static void
4101df_exit_block_uses_collect (struct df_collection_rec *collection_rec, bitmap exit_block_uses)
4102{
b8698a0f 4103 unsigned int i;
6fb5fa3c
DB
4104 bitmap_iterator bi;
4105
4106 EXECUTE_IF_SET_IN_BITMAP (exit_block_uses, 0, i, bi)
57512f53 4107 df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[i], NULL,
bbbbb16a 4108 EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0, -1, -1, VOIDmode);
4d779342 4109
6fb5fa3c
DB
4110#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
4111 /* It is deliberate that this is not put in the exit block uses but
4112 I do not know why. */
b8698a0f 4113 if (reload_completed
6fb5fa3c 4114 && !bitmap_bit_p (exit_block_uses, ARG_POINTER_REGNUM)
ba49cb7b 4115 && bb_has_eh_pred (EXIT_BLOCK_PTR)
6fb5fa3c 4116 && fixed_regs[ARG_POINTER_REGNUM])
57512f53 4117 df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[ARG_POINTER_REGNUM], NULL,
bbbbb16a 4118 EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0, -1, -1, VOIDmode);
6fb5fa3c
DB
4119#endif
4120
4121 df_canonize_collection_rec (collection_rec);
4122}
4123
4124
b8698a0f 4125/* Record the set of hard registers that are used in the exit block.
6fb5fa3c
DB
4126 It uses df->exit_block_uses to determine which bit to include. */
4127
4128static void
4129df_record_exit_block_uses (bitmap exit_block_uses)
4130{
4131 struct df_collection_rec collection_rec;
4132 memset (&collection_rec, 0, sizeof (struct df_collection_rec));
c2569604 4133 collection_rec.use_vec = VEC_alloc (df_ref, stack, FIRST_PSEUDO_REGISTER);
6fb5fa3c
DB
4134
4135 df_exit_block_uses_collect (&collection_rec, exit_block_uses);
4136
4137 /* Process bb_refs chain */
4138 df_refs_add_to_chains (&collection_rec, BASIC_BLOCK (EXIT_BLOCK), NULL);
c2569604 4139 VEC_free (df_ref, stack, collection_rec.use_vec);
6fb5fa3c
DB
4140}
4141
4142
4143/* Update the uses in the exit block. */
4144
4145void
4146df_update_exit_block_uses (void)
4147{
a7e3698d 4148 bitmap_head refs;
6fb5fa3c
DB
4149 bool changed = false;
4150
a7e3698d
JH
4151 bitmap_initialize (&refs, &df_bitmap_obstack);
4152 df_get_exit_block_use_set (&refs);
6fb5fa3c
DB
4153 if (df->exit_block_uses)
4154 {
a7e3698d 4155 if (!bitmap_equal_p (df->exit_block_uses, &refs))
6fb5fa3c
DB
4156 {
4157 struct df_scan_bb_info *bb_info = df_scan_get_bb_info (EXIT_BLOCK);
4158 df_ref_chain_delete_du_chain (bb_info->artificial_uses);
4159 df_ref_chain_delete (bb_info->artificial_uses);
4160 bb_info->artificial_uses = NULL;
4161 changed = true;
4162 }
4163 }
4164 else
4165 {
4166 struct df_scan_problem_data *problem_data
4167 = (struct df_scan_problem_data *) df_scan->problem_data;
a7e3698d 4168 gcc_unreachable ();
6fb5fa3c
DB
4169 df->exit_block_uses = BITMAP_ALLOC (&problem_data->reg_bitmaps);
4170 changed = true;
4171 }
4172
4173 if (changed)
4174 {
a7e3698d
JH
4175 df_record_exit_block_uses (&refs);
4176 bitmap_copy (df->exit_block_uses,& refs);
6fb5fa3c
DB
4177 df_set_bb_dirty (BASIC_BLOCK (EXIT_BLOCK));
4178 }
a7e3698d 4179 bitmap_clear (&refs);
4d779342
DB
4180}
4181
4182static bool initialized = false;
4183
6fb5fa3c 4184
4d779342
DB
4185/* Initialize some platform specific structures. */
4186
b8698a0f 4187void
4d779342
DB
4188df_hard_reg_init (void)
4189{
fcfd0ebb 4190#ifdef ELIMINABLE_REGS
7bda4a1d 4191 int i;
4d779342
DB
4192 static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
4193#endif
4d779342
DB
4194 if (initialized)
4195 return;
4196
4d779342
DB
4197 /* Record which registers will be eliminated. We use this in
4198 mark_used_regs. */
4199 CLEAR_HARD_REG_SET (elim_reg_set);
b8698a0f 4200
4d779342
DB
4201#ifdef ELIMINABLE_REGS
4202 for (i = 0; i < (int) ARRAY_SIZE (eliminables); i++)
4203 SET_HARD_REG_BIT (elim_reg_set, eliminables[i].from);
4204#else
4205 SET_HARD_REG_BIT (elim_reg_set, FRAME_POINTER_REGNUM);
4206#endif
b8698a0f 4207
4d779342
DB
4208 initialized = true;
4209}
6fb5fa3c
DB
4210
4211
4212/* Recompute the parts of scanning that are based on regs_ever_live
b8698a0f 4213 because something changed in that array. */
6fb5fa3c 4214
b8698a0f 4215void
6fb5fa3c
DB
4216df_update_entry_exit_and_calls (void)
4217{
4218 basic_block bb;
4219
4220 df_update_entry_block_defs ();
4221 df_update_exit_block_uses ();
4222
4223 /* The call insns need to be rescanned because there may be changes
4224 in the set of registers clobbered across the call. */
b8698a0f 4225 FOR_EACH_BB (bb)
6fb5fa3c
DB
4226 {
4227 rtx insn;
4228 FOR_BB_INSNS (bb, insn)
4229 {
4230 if (INSN_P (insn) && CALL_P (insn))
4231 df_insn_rescan (insn);
4232 }
4233 }
4234}
4235
4236
4237/* Return true if hard REG is actually used in the some instruction.
4238 There are a fair number of conditions that affect the setting of
4239 this array. See the comment in df.h for df->hard_regs_live_count
4240 for the conditions that this array is set. */
4241
b8698a0f 4242bool
6fb5fa3c
DB
4243df_hard_reg_used_p (unsigned int reg)
4244{
6fb5fa3c
DB
4245 return df->hard_regs_live_count[reg] != 0;
4246}
4247
4248
4249/* A count of the number of times REG is actually used in the some
4250 instruction. There are a fair number of conditions that affect the
4251 setting of this array. See the comment in df.h for
4252 df->hard_regs_live_count for the conditions that this array is
4253 set. */
4254
4255
4256unsigned int
4257df_hard_reg_used_count (unsigned int reg)
4258{
6fb5fa3c
DB
4259 return df->hard_regs_live_count[reg];
4260}
4261
4262
4263/* Get the value of regs_ever_live[REGNO]. */
4264
b8698a0f 4265bool
6fb5fa3c
DB
4266df_regs_ever_live_p (unsigned int regno)
4267{
4268 return regs_ever_live[regno];
4269}
4270
4271
4272/* Set regs_ever_live[REGNO] to VALUE. If this cause regs_ever_live
4273 to change, schedule that change for the next update. */
4274
b8698a0f 4275void
6fb5fa3c
DB
4276df_set_regs_ever_live (unsigned int regno, bool value)
4277{
4278 if (regs_ever_live[regno] == value)
4279 return;
4280
4281 regs_ever_live[regno] = value;
4282 if (df)
4283 df->redo_entry_and_exit = true;
4284}
4285
4286
4287/* Compute "regs_ever_live" information from the underlying df
4288 information. Set the vector to all false if RESET. */
4289
4290void
4291df_compute_regs_ever_live (bool reset)
4292{
4293 unsigned int i;
4294 bool changed = df->redo_entry_and_exit;
b8698a0f 4295
6fb5fa3c
DB
4296 if (reset)
4297 memset (regs_ever_live, 0, sizeof (regs_ever_live));
4298
4299 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4300 if ((!regs_ever_live[i]) && df_hard_reg_used_p (i))
4301 {
4302 regs_ever_live[i] = true;
4303 changed = true;
4304 }
4305 if (changed)
4306 df_update_entry_exit_and_calls ();
4307 df->redo_entry_and_exit = false;
4308}
4309
4310\f
4311/*----------------------------------------------------------------------------
4312 Dataflow ref information verification functions.
4313
4314 df_reg_chain_mark (refs, regno, is_def, is_eq_use)
4315 df_reg_chain_verify_unmarked (refs)
c2569604 4316 df_refs_verify (VEC(stack,df_ref)*, ref*, bool)
6fb5fa3c
DB
4317 df_mws_verify (mw*, mw*, bool)
4318 df_insn_refs_verify (collection_rec, bb, insn, bool)
4319 df_bb_refs_verify (bb, refs, bool)
4320 df_bb_verify (bb)
4321 df_exit_block_bitmap_verify (bool)
4322 df_entry_block_bitmap_verify (bool)
4323 df_scan_verify ()
4324----------------------------------------------------------------------------*/
4325
4326
4327/* Mark all refs in the reg chain. Verify that all of the registers
b8698a0f 4328are in the correct chain. */
6fb5fa3c
DB
4329
4330static unsigned int
b8698a0f 4331df_reg_chain_mark (df_ref refs, unsigned int regno,
6fb5fa3c
DB
4332 bool is_def, bool is_eq_use)
4333{
4334 unsigned int count = 0;
57512f53 4335 df_ref ref;
6fb5fa3c
DB
4336 for (ref = refs; ref; ref = DF_REF_NEXT_REG (ref))
4337 {
4338 gcc_assert (!DF_REF_IS_REG_MARKED (ref));
4339
4340 /* If there are no def-use or use-def chains, make sure that all
4341 of the chains are clear. */
4342 if (!df_chain)
4343 gcc_assert (!DF_REF_CHAIN (ref));
4344
4345 /* Check to make sure the ref is in the correct chain. */
4346 gcc_assert (DF_REF_REGNO (ref) == regno);
4347 if (is_def)
57512f53 4348 gcc_assert (DF_REF_REG_DEF_P (ref));
6fb5fa3c 4349 else
57512f53 4350 gcc_assert (!DF_REF_REG_DEF_P (ref));
6fb5fa3c
DB
4351
4352 if (is_eq_use)
4353 gcc_assert ((DF_REF_FLAGS (ref) & DF_REF_IN_NOTE));
4354 else
4355 gcc_assert ((DF_REF_FLAGS (ref) & DF_REF_IN_NOTE) == 0);
4356
57512f53
KZ
4357 if (DF_REF_NEXT_REG (ref))
4358 gcc_assert (DF_REF_PREV_REG (DF_REF_NEXT_REG (ref)) == ref);
6fb5fa3c
DB
4359 count++;
4360 DF_REF_REG_MARK (ref);
4361 }
4362 return count;
4363}
4364
4365
b8698a0f 4366/* Verify that all of the registers in the chain are unmarked. */
6fb5fa3c
DB
4367
4368static void
57512f53 4369df_reg_chain_verify_unmarked (df_ref refs)
6fb5fa3c 4370{
57512f53 4371 df_ref ref;
6fb5fa3c
DB
4372 for (ref = refs; ref; ref = DF_REF_NEXT_REG (ref))
4373 gcc_assert (!DF_REF_IS_REG_MARKED (ref));
4374}
4375
4376
4377/* Verify that NEW_REC and OLD_REC have exactly the same members. */
4378
4379static bool
c2569604 4380df_refs_verify (VEC(df_ref,stack) *new_rec, df_ref *old_rec,
6fb5fa3c
DB
4381 bool abort_if_fail)
4382{
c2569604
ILT
4383 unsigned int ix;
4384 df_ref new_ref;
4385
4386 for (ix = 0; VEC_iterate (df_ref, new_rec, ix, new_ref); ++ix)
6fb5fa3c 4387 {
c2569604 4388 if (*old_rec == NULL || !df_ref_equal_p (new_ref, *old_rec))
6fb5fa3c
DB
4389 {
4390 if (abort_if_fail)
4391 gcc_assert (0);
4392 else
4393 return false;
4394 }
4395
4396 /* Abort if fail is called from the function level verifier. If
4397 that is the context, mark this reg as being seem. */
4398 if (abort_if_fail)
4399 {
4400 gcc_assert (DF_REF_IS_REG_MARKED (*old_rec));
4401 DF_REF_REG_UNMARK (*old_rec);
4402 }
4403
6fb5fa3c
DB
4404 old_rec++;
4405 }
4406
4407 if (abort_if_fail)
c2569604 4408 gcc_assert (*old_rec == NULL);
6fb5fa3c 4409 else
c2569604 4410 return *old_rec == NULL;
6fb5fa3c
DB
4411 return false;
4412}
4413
4414
4415/* Verify that NEW_REC and OLD_REC have exactly the same members. */
4416
4417static bool
c2569604
ILT
4418df_mws_verify (VEC(df_mw_hardreg_ptr,stack) *new_rec,
4419 struct df_mw_hardreg **old_rec,
6fb5fa3c
DB
4420 bool abort_if_fail)
4421{
c2569604
ILT
4422 unsigned int ix;
4423 struct df_mw_hardreg *new_reg;
4424
4425 for (ix = 0; VEC_iterate (df_mw_hardreg_ptr, new_rec, ix, new_reg); ++ix)
6fb5fa3c 4426 {
c2569604 4427 if (*old_rec == NULL || !df_mw_equal_p (new_reg, *old_rec))
6fb5fa3c
DB
4428 {
4429 if (abort_if_fail)
4430 gcc_assert (0);
4431 else
4432 return false;
4433 }
6fb5fa3c
DB
4434 old_rec++;
4435 }
4436
4437 if (abort_if_fail)
c2569604 4438 gcc_assert (*old_rec == NULL);
6fb5fa3c 4439 else
c2569604 4440 return *old_rec == NULL;
6fb5fa3c
DB
4441 return false;
4442}
4443
4444
4445/* Return true if the existing insn refs information is complete and
4446 correct. Otherwise (i.e. if there's any missing or extra refs),
b8698a0f 4447 return the correct df_ref chain in REFS_RETURN.
6fb5fa3c
DB
4448
4449 If ABORT_IF_FAIL, leave the refs that are verified (already in the
4450 ref chain) as DF_REF_MARKED(). If it's false, then it's a per-insn
4451 verification mode instead of the whole function, so unmark
4452 everything.
4453
4454 If ABORT_IF_FAIL is set, this function never returns false. */
4455
4456static bool
4457df_insn_refs_verify (struct df_collection_rec *collection_rec,
b8698a0f 4458 basic_block bb,
6fb5fa3c
DB
4459 rtx insn,
4460 bool abort_if_fail)
4461{
4462 bool ret1, ret2, ret3, ret4;
4463 unsigned int uid = INSN_UID (insn);
50e94c7e 4464 struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
6fb5fa3c 4465
50e94c7e 4466 df_insn_refs_collect (collection_rec, bb, insn_info);
6fb5fa3c
DB
4467
4468 if (!DF_INSN_UID_DEFS (uid))
4469 {
4470 /* The insn_rec was created but it was never filled out. */
4471 if (abort_if_fail)
4472 gcc_assert (0);
b8698a0f 4473 else
6fb5fa3c
DB
4474 return false;
4475 }
4476
4477 /* Unfortunately we cannot opt out early if one of these is not
4478 right because the marks will not get cleared. */
b8698a0f 4479 ret1 = df_refs_verify (collection_rec->def_vec, DF_INSN_UID_DEFS (uid),
6fb5fa3c 4480 abort_if_fail);
b8698a0f 4481 ret2 = df_refs_verify (collection_rec->use_vec, DF_INSN_UID_USES (uid),
6fb5fa3c 4482 abort_if_fail);
b8698a0f 4483 ret3 = df_refs_verify (collection_rec->eq_use_vec, DF_INSN_UID_EQ_USES (uid),
6fb5fa3c 4484 abort_if_fail);
b8698a0f 4485 ret4 = df_mws_verify (collection_rec->mw_vec, DF_INSN_UID_MWS (uid),
6fb5fa3c
DB
4486 abort_if_fail);
4487 return (ret1 && ret2 && ret3 && ret4);
4488}
4489
4490
4491/* Return true if all refs in the basic block are correct and complete.
4492 Due to df_ref_chain_verify, it will cause all refs
4493 that are verified to have DF_REF_MARK bit set. */
4494
4495static bool
4496df_bb_verify (basic_block bb)
4497{
4498 rtx insn;
4499 struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index);
4500 struct df_collection_rec collection_rec;
b8698a0f 4501
6fb5fa3c 4502 memset (&collection_rec, 0, sizeof (struct df_collection_rec));
c2569604
ILT
4503 collection_rec.def_vec = VEC_alloc (df_ref, stack, 128);
4504 collection_rec.use_vec = VEC_alloc (df_ref, stack, 32);
4505 collection_rec.eq_use_vec = VEC_alloc (df_ref, stack, 32);
4506 collection_rec.mw_vec = VEC_alloc (df_mw_hardreg_ptr, stack, 32);
6fb5fa3c
DB
4507
4508 gcc_assert (bb_info);
4509
57512f53 4510 /* Scan the block, one insn at a time, from beginning to end. */
6fb5fa3c
DB
4511 FOR_BB_INSNS_REVERSE (bb, insn)
4512 {
4513 if (!INSN_P (insn))
4514 continue;
4515 df_insn_refs_verify (&collection_rec, bb, insn, true);
4516 df_free_collection_rec (&collection_rec);
4517 }
4518
4519 /* Do the artificial defs and uses. */
4520 df_bb_refs_collect (&collection_rec, bb);
4521 df_refs_verify (collection_rec.def_vec, df_get_artificial_defs (bb->index), true);
4522 df_refs_verify (collection_rec.use_vec, df_get_artificial_uses (bb->index), true);
4523 df_free_collection_rec (&collection_rec);
b8698a0f 4524
6fb5fa3c
DB
4525 return true;
4526}
4527
4528
b8698a0f 4529/* Returns true if the entry block has correct and complete df_ref set.
6fb5fa3c
DB
4530 If not it either aborts if ABORT_IF_FAIL is true or returns false. */
4531
4532static bool
4533df_entry_block_bitmap_verify (bool abort_if_fail)
4534{
a7e3698d 4535 bitmap_head entry_block_defs;
6fb5fa3c
DB
4536 bool is_eq;
4537
a7e3698d
JH
4538 bitmap_initialize (&entry_block_defs, &df_bitmap_obstack);
4539 df_get_entry_block_def_set (&entry_block_defs);
6fb5fa3c 4540
a7e3698d 4541 is_eq = bitmap_equal_p (&entry_block_defs, df->entry_block_defs);
6fb5fa3c
DB
4542
4543 if (!is_eq && abort_if_fail)
4544 {
4545 print_current_pass (stderr);
4546 fprintf (stderr, "entry_block_defs = ");
a7e3698d 4547 df_print_regset (stderr, &entry_block_defs);
6fb5fa3c
DB
4548 fprintf (stderr, "df->entry_block_defs = ");
4549 df_print_regset (stderr, df->entry_block_defs);
4550 gcc_assert (0);
4551 }
4552
a7e3698d 4553 bitmap_clear (&entry_block_defs);
6fb5fa3c
DB
4554
4555 return is_eq;
4556}
4557
4558
b8698a0f 4559/* Returns true if the exit block has correct and complete df_ref set.
6fb5fa3c
DB
4560 If not it either aborts if ABORT_IF_FAIL is true or returns false. */
4561
4562static bool
4563df_exit_block_bitmap_verify (bool abort_if_fail)
4564{
a7e3698d 4565 bitmap_head exit_block_uses;
6fb5fa3c
DB
4566 bool is_eq;
4567
a7e3698d
JH
4568 bitmap_initialize (&exit_block_uses, &df_bitmap_obstack);
4569 df_get_exit_block_use_set (&exit_block_uses);
6fb5fa3c 4570
a7e3698d 4571 is_eq = bitmap_equal_p (&exit_block_uses, df->exit_block_uses);
6fb5fa3c
DB
4572
4573 if (!is_eq && abort_if_fail)
4574 {
4575 print_current_pass (stderr);
4576 fprintf (stderr, "exit_block_uses = ");
a7e3698d 4577 df_print_regset (stderr, &exit_block_uses);
6fb5fa3c
DB
4578 fprintf (stderr, "df->exit_block_uses = ");
4579 df_print_regset (stderr, df->exit_block_uses);
4580 gcc_assert (0);
4581 }
4582
a7e3698d 4583 bitmap_clear (&exit_block_uses);
6fb5fa3c
DB
4584
4585 return is_eq;
4586}
4587
4588
cc806ac1
RS
4589/* Return true if df_ref information for all insns in all blocks are
4590 correct and complete. */
6fb5fa3c
DB
4591
4592void
4593df_scan_verify (void)
4594{
4595 unsigned int i;
4596 basic_block bb;
a7e3698d
JH
4597 bitmap_head regular_block_artificial_uses;
4598 bitmap_head eh_block_artificial_uses;
6fb5fa3c
DB
4599
4600 if (!df)
4601 return;
4602
6fb5fa3c
DB
4603 /* Verification is a 4 step process. */
4604
4605 /* (1) All of the refs are marked by going thru the reg chains. */
4606 for (i = 0; i < DF_REG_SIZE (df); i++)
4607 {
b8698a0f 4608 gcc_assert (df_reg_chain_mark (DF_REG_DEF_CHAIN (i), i, true, false)
6fb5fa3c 4609 == DF_REG_DEF_COUNT(i));
b8698a0f 4610 gcc_assert (df_reg_chain_mark (DF_REG_USE_CHAIN (i), i, false, false)
6fb5fa3c 4611 == DF_REG_USE_COUNT(i));
b8698a0f 4612 gcc_assert (df_reg_chain_mark (DF_REG_EQ_USE_CHAIN (i), i, false, true)
6fb5fa3c
DB
4613 == DF_REG_EQ_USE_COUNT(i));
4614 }
4615
4616 /* (2) There are various bitmaps whose value may change over the
4617 course of the compilation. This step recomputes them to make
4618 sure that they have not slipped out of date. */
a7e3698d
JH
4619 bitmap_initialize (&regular_block_artificial_uses, &df_bitmap_obstack);
4620 bitmap_initialize (&eh_block_artificial_uses, &df_bitmap_obstack);
6fb5fa3c 4621
a7e3698d
JH
4622 df_get_regular_block_artificial_uses (&regular_block_artificial_uses);
4623 df_get_eh_block_artificial_uses (&eh_block_artificial_uses);
6fb5fa3c 4624
a7e3698d
JH
4625 bitmap_ior_into (&eh_block_artificial_uses,
4626 &regular_block_artificial_uses);
6fb5fa3c
DB
4627
4628 /* Check artificial_uses bitmaps didn't change. */
a7e3698d
JH
4629 gcc_assert (bitmap_equal_p (&regular_block_artificial_uses,
4630 &df->regular_block_artificial_uses));
4631 gcc_assert (bitmap_equal_p (&eh_block_artificial_uses,
4632 &df->eh_block_artificial_uses));
6fb5fa3c 4633
a7e3698d
JH
4634 bitmap_clear (&regular_block_artificial_uses);
4635 bitmap_clear (&eh_block_artificial_uses);
6fb5fa3c
DB
4636
4637 /* Verify entry block and exit block. These only verify the bitmaps,
4638 the refs are verified in df_bb_verify. */
4639 df_entry_block_bitmap_verify (true);
4640 df_exit_block_bitmap_verify (true);
b8698a0f 4641
6fb5fa3c
DB
4642 /* (3) All of the insns in all of the blocks are traversed and the
4643 marks are cleared both in the artificial refs attached to the
4644 blocks and the real refs inside the insns. It is a failure to
4645 clear a mark that has not been set as this means that the ref in
4646 the block or insn was not in the reg chain. */
4647
4648 FOR_ALL_BB (bb)
4649 df_bb_verify (bb);
4650
4651 /* (4) See if all reg chains are traversed a second time. This time
4652 a check is made that the marks are clear. A set mark would be a
4653 from a reg that is not in any insn or basic block. */
4654
4655 for (i = 0; i < DF_REG_SIZE (df); i++)
4656 {
4657 df_reg_chain_verify_unmarked (DF_REG_DEF_CHAIN (i));
4658 df_reg_chain_verify_unmarked (DF_REG_USE_CHAIN (i));
4659 df_reg_chain_verify_unmarked (DF_REG_EQ_USE_CHAIN (i));
4660 }
4661}