00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "config.h"
00032 #include "system.h"
00033 #include "coretypes.h"
00034 #include "tm.h"
00035 #include "rtl.h"
00036 #include "tm_p.h"
00037 #include "insn-config.h"
00038 #include "recog.h"
00039 #include "function.h"
00040 #include "regs.h"
00041 #include "output.h"
00042 #include "alloc-pool.h"
00043 #include "flags.h"
00044 #include "hard-reg-set.h"
00045 #include "basic-block.h"
00046 #include "sbitmap.h"
00047 #include "bitmap.h"
00048 #include "timevar.h"
00049 #include "tree.h"
00050 #include "target.h"
00051 #include "target-def.h"
00052 #include "df.h"
00053
00054 #ifndef HAVE_epilogue
00055 #define HAVE_epilogue 0
00056 #endif
00057 #ifndef HAVE_prologue
00058 #define HAVE_prologue 0
00059 #endif
00060 #ifndef HAVE_sibcall_epilogue
00061 #define HAVE_sibcall_epilogue 0
00062 #endif
00063
00064 #ifndef EPILOGUE_USES
00065 #define EPILOGUE_USES(REGNO) 0
00066 #endif
00067
00068
00069
00070
00071 static bitmap_obstack persistent_obstack;
00072
00073
00074
00075 static HARD_REG_SET elim_reg_set;
00076
00077
00078
00079
00080 bitmap df_invalidated_by_call = NULL;
00081
00082
00083
00084
00085 static void df_ref_record (struct dataflow *, rtx, rtx *,
00086 basic_block, rtx, enum df_ref_type,
00087 enum df_ref_flags, bool record_live);
00088 static void df_def_record_1 (struct dataflow *, rtx, basic_block, rtx,
00089 enum df_ref_flags, bool record_live);
00090 static void df_defs_record (struct dataflow *, rtx, basic_block, rtx);
00091 static void df_uses_record (struct dataflow *, rtx *, enum df_ref_type,
00092 basic_block, rtx, enum df_ref_flags);
00093
00094 static void df_insn_refs_record (struct dataflow *, basic_block, rtx);
00095 static void df_bb_refs_record (struct dataflow *, basic_block);
00096 static void df_refs_record (struct dataflow *, bitmap);
00097 static struct df_ref *df_ref_create_structure (struct dataflow *, rtx, rtx *,
00098 basic_block, rtx, enum df_ref_type,
00099 enum df_ref_flags);
00100 static void df_record_entry_block_defs (struct dataflow *);
00101 static void df_record_exit_block_uses (struct dataflow *);
00102 static void df_grow_reg_info (struct dataflow *, struct df_ref_info *);
00103 static void df_grow_ref_info (struct df_ref_info *, unsigned int);
00104 static void df_grow_insn_info (struct df *);
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 struct df_scan_problem_data
00118 {
00119 alloc_pool ref_pool;
00120 alloc_pool insn_pool;
00121 alloc_pool reg_pool;
00122 alloc_pool mw_reg_pool;
00123 alloc_pool mw_link_pool;
00124 };
00125
00126 typedef struct df_scan_bb_info *df_scan_bb_info_t;
00127
00128 static void
00129 df_scan_free_internal (struct dataflow *dflow)
00130 {
00131 struct df *df = dflow->df;
00132 struct df_scan_problem_data *problem_data
00133 = (struct df_scan_problem_data *) dflow->problem_data;
00134
00135 free (df->def_info.regs);
00136 free (df->def_info.refs);
00137 memset (&df->def_info, 0, (sizeof (struct df_ref_info)));
00138
00139 free (df->use_info.regs);
00140 free (df->use_info.refs);
00141 memset (&df->use_info, 0, (sizeof (struct df_ref_info)));
00142
00143 free (df->insns);
00144 df->insns = NULL;
00145 df->insns_size = 0;
00146
00147 free (dflow->block_info);
00148 dflow->block_info = NULL;
00149 dflow->block_info_size = 0;
00150
00151 BITMAP_FREE (df->hardware_regs_used);
00152 BITMAP_FREE (df->entry_block_defs);
00153 BITMAP_FREE (df->exit_block_uses);
00154
00155 free_alloc_pool (dflow->block_pool);
00156 free_alloc_pool (problem_data->ref_pool);
00157 free_alloc_pool (problem_data->insn_pool);
00158 free_alloc_pool (problem_data->reg_pool);
00159 free_alloc_pool (problem_data->mw_reg_pool);
00160 free_alloc_pool (problem_data->mw_link_pool);
00161 }
00162
00163
00164
00165
00166 struct df_scan_bb_info *
00167 df_scan_get_bb_info (struct dataflow *dflow, unsigned int index)
00168 {
00169 gcc_assert (index < dflow->block_info_size);
00170 return (struct df_scan_bb_info *) dflow->block_info[index];
00171 }
00172
00173
00174
00175
00176 static void
00177 df_scan_set_bb_info (struct dataflow *dflow, unsigned int index,
00178 struct df_scan_bb_info *bb_info)
00179 {
00180 gcc_assert (index < dflow->block_info_size);
00181 dflow->block_info[index] = (void *) bb_info;
00182 }
00183
00184
00185
00186
00187 static void
00188 df_scan_free_bb_info (struct dataflow *dflow, basic_block bb, void *vbb_info)
00189 {
00190 struct df_scan_bb_info *bb_info = (struct df_scan_bb_info *) vbb_info;
00191 if (bb_info)
00192 {
00193 df_bb_refs_delete (dflow, bb->index);
00194 pool_free (dflow->block_pool, bb_info);
00195 }
00196 }
00197
00198
00199
00200
00201
00202
00203 static void
00204 df_scan_alloc (struct dataflow *dflow, bitmap blocks_to_rescan,
00205 bitmap all_blocks ATTRIBUTE_UNUSED)
00206 {
00207 struct df *df = dflow->df;
00208 struct df_scan_problem_data *problem_data;
00209 unsigned int insn_num = get_max_uid () + 1;
00210 unsigned int block_size = 50;
00211 unsigned int bb_index;
00212 bitmap_iterator bi;
00213
00214
00215
00216 if (dflow->problem_data)
00217 df_scan_free_internal (dflow);
00218
00219 dflow->block_pool
00220 = create_alloc_pool ("df_scan_block pool",
00221 sizeof (struct df_scan_bb_info),
00222 block_size);
00223
00224 problem_data = XNEW (struct df_scan_problem_data);
00225 dflow->problem_data = problem_data;
00226
00227 problem_data->ref_pool
00228 = create_alloc_pool ("df_scan_ref pool",
00229 sizeof (struct df_ref), block_size);
00230 problem_data->insn_pool
00231 = create_alloc_pool ("df_scan_insn pool",
00232 sizeof (struct df_insn_info), block_size);
00233 problem_data->reg_pool
00234 = create_alloc_pool ("df_scan_reg pool",
00235 sizeof (struct df_reg_info), block_size);
00236 problem_data->mw_reg_pool
00237 = create_alloc_pool ("df_scan_mw_reg pool",
00238 sizeof (struct df_mw_hardreg), block_size);
00239 problem_data->mw_link_pool
00240 = create_alloc_pool ("df_scan_mw_link pool",
00241 sizeof (struct df_link), block_size);
00242
00243 insn_num += insn_num / 4;
00244 df_grow_reg_info (dflow, &df->def_info);
00245 df_grow_ref_info (&df->def_info, insn_num);
00246
00247 df_grow_reg_info (dflow, &df->use_info);
00248 df_grow_ref_info (&df->use_info, insn_num *2);
00249
00250 df_grow_insn_info (df);
00251 df_grow_bb_info (dflow);
00252
00253 EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
00254 {
00255 struct df_scan_bb_info *bb_info = df_scan_get_bb_info (dflow, bb_index);
00256 if (!bb_info)
00257 {
00258 bb_info = (struct df_scan_bb_info *) pool_alloc (dflow->block_pool);
00259 df_scan_set_bb_info (dflow, bb_index, bb_info);
00260 }
00261 bb_info->artificial_defs = NULL;
00262 bb_info->artificial_uses = NULL;
00263 }
00264
00265 df->hardware_regs_used = BITMAP_ALLOC (NULL);
00266 df->entry_block_defs = BITMAP_ALLOC (NULL);
00267 df->exit_block_uses = BITMAP_ALLOC (NULL);
00268 }
00269
00270
00271
00272
00273 static void
00274 df_scan_free (struct dataflow *dflow)
00275 {
00276 struct df *df = dflow->df;
00277
00278 if (dflow->problem_data)
00279 {
00280 df_scan_free_internal (dflow);
00281 free (dflow->problem_data);
00282 }
00283
00284 if (df->blocks_to_scan)
00285 BITMAP_FREE (df->blocks_to_scan);
00286
00287 if (df->blocks_to_analyze)
00288 BITMAP_FREE (df->blocks_to_analyze);
00289
00290 free (dflow);
00291 }
00292
00293 static void
00294 df_scan_dump (struct dataflow *dflow ATTRIBUTE_UNUSED, FILE *file ATTRIBUTE_UNUSED)
00295 {
00296 struct df *df = dflow->df;
00297 int i;
00298
00299 fprintf (file, " invalidated by call \t");
00300 dump_bitmap (file, df_invalidated_by_call);
00301 fprintf (file, " hardware regs used \t");
00302 dump_bitmap (file, df->hardware_regs_used);
00303 fprintf (file, " entry block uses \t");
00304 dump_bitmap (file, df->entry_block_defs);
00305 fprintf (file, " exit block uses \t");
00306 dump_bitmap (file, df->exit_block_uses);
00307 fprintf (file, " regs ever live \t");
00308 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00309 if (regs_ever_live[i])
00310 fprintf (file, "%d ", i);
00311 fprintf (file, "\n");
00312 }
00313
00314 static struct df_problem problem_SCAN =
00315 {
00316 DF_SCAN,
00317 DF_NONE,
00318 df_scan_alloc,
00319 NULL,
00320 df_scan_free_bb_info,
00321 NULL,
00322 NULL,
00323 NULL,
00324 NULL,
00325 NULL,
00326 NULL,
00327 NULL,
00328 df_scan_free,
00329 df_scan_dump,
00330 NULL,
00331 0
00332 };
00333
00334
00335
00336
00337
00338
00339 struct dataflow *
00340 df_scan_add_problem (struct df *df, int flags)
00341 {
00342 return df_add_problem (df, &problem_SCAN, flags);
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 static void
00358 df_grow_reg_info (struct dataflow *dflow, struct df_ref_info *ref_info)
00359 {
00360 unsigned int max_reg = max_reg_num ();
00361 unsigned int new_size = max_reg;
00362 struct df_scan_problem_data *problem_data
00363 = (struct df_scan_problem_data *) dflow->problem_data;
00364 unsigned int i;
00365
00366 if (ref_info->regs_size < new_size)
00367 {
00368 new_size += new_size / 4;
00369 ref_info->regs = xrealloc (ref_info->regs,
00370 new_size *sizeof (struct df_reg_info*));
00371 ref_info->regs_size = new_size;
00372 }
00373
00374 for (i = ref_info->regs_inited; i < max_reg; i++)
00375 {
00376 struct df_reg_info *reg_info = pool_alloc (problem_data->reg_pool);
00377 memset (reg_info, 0, sizeof (struct df_reg_info));
00378 ref_info->regs[i] = reg_info;
00379 }
00380
00381 ref_info->regs_inited = max_reg;
00382 }
00383
00384
00385
00386
00387 static void
00388 df_grow_ref_info (struct df_ref_info *ref_info, unsigned int new_size)
00389 {
00390 if (ref_info->refs_size < new_size)
00391 {
00392 ref_info->refs = xrealloc (ref_info->refs,
00393 new_size *sizeof (struct df_ref *));
00394 memset (ref_info->refs + ref_info->refs_size, 0,
00395 (new_size - ref_info->refs_size) *sizeof (struct df_ref *));
00396 ref_info->refs_size = new_size;
00397 }
00398 }
00399
00400
00401
00402
00403
00404
00405 static void
00406 df_grow_insn_info (struct df *df)
00407 {
00408 unsigned int new_size = get_max_uid () + 1;
00409 if (df->insns_size < new_size)
00410 {
00411 new_size += new_size / 4;
00412 df->insns = xrealloc (df->insns,
00413 new_size *sizeof (struct df_insn_info *));
00414 memset (df->insns + df->insns_size, 0,
00415 (new_size - df->insns_size) *sizeof (struct df_insn_info *));
00416 df->insns_size = new_size;
00417 }
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 void
00431 df_rescan_blocks (struct df *df, bitmap blocks)
00432 {
00433 bitmap local_blocks_to_scan = BITMAP_ALLOC (NULL);
00434
00435 struct dataflow *dflow = df->problems_by_index[DF_SCAN];
00436 basic_block bb;
00437
00438 df->def_info.refs_organized = false;
00439 df->use_info.refs_organized = false;
00440
00441 if (blocks)
00442 {
00443 int i;
00444 unsigned int bb_index;
00445 bitmap_iterator bi;
00446 bool cleared_bits = false;
00447
00448
00449 unsigned int insn_num = get_max_uid () + 1;
00450 insn_num += insn_num / 4;
00451
00452 df_grow_reg_info (dflow, &df->def_info);
00453 df_grow_ref_info (&df->def_info, insn_num);
00454
00455 df_grow_reg_info (dflow, &df->use_info);
00456 df_grow_ref_info (&df->use_info, insn_num *2);
00457
00458 df_grow_insn_info (df);
00459 df_grow_bb_info (dflow);
00460
00461 bitmap_copy (local_blocks_to_scan, blocks);
00462
00463 EXECUTE_IF_SET_IN_BITMAP (blocks, 0, bb_index, bi)
00464 {
00465 basic_block bb = BASIC_BLOCK (bb_index);
00466 if (!bb)
00467 {
00468 bitmap_clear_bit (local_blocks_to_scan, bb_index);
00469 cleared_bits = true;
00470 }
00471 }
00472
00473 if (cleared_bits)
00474 bitmap_copy (blocks, local_blocks_to_scan);
00475
00476 df->def_info.add_refs_inline = true;
00477 df->use_info.add_refs_inline = true;
00478
00479 for (i = df->num_problems_defined; i; i--)
00480 {
00481 bitmap blocks_to_reset = NULL;
00482 if (dflow->problem->reset_fun)
00483 {
00484 if (!blocks_to_reset)
00485 {
00486 blocks_to_reset = BITMAP_ALLOC (NULL);
00487 bitmap_copy (blocks_to_reset, local_blocks_to_scan);
00488 if (df->blocks_to_scan)
00489 bitmap_ior_into (blocks_to_reset, df->blocks_to_scan);
00490 }
00491 dflow->problem->reset_fun (dflow, blocks_to_reset);
00492 }
00493 if (blocks_to_reset)
00494 BITMAP_FREE (blocks_to_reset);
00495 }
00496
00497 df_refs_delete (dflow, local_blocks_to_scan);
00498
00499
00500
00501
00502
00503
00504 if (df->blocks_to_analyze)
00505 bitmap_ior_into (df->blocks_to_analyze, blocks);
00506 }
00507 else
00508 {
00509
00510
00511
00512 if (df->blocks_to_analyze)
00513 bitmap_copy (local_blocks_to_scan, df->blocks_to_analyze);
00514 else
00515 FOR_ALL_BB (bb)
00516 {
00517 bitmap_set_bit (local_blocks_to_scan, bb->index);
00518 }
00519 df_scan_alloc (dflow, local_blocks_to_scan, NULL);
00520
00521 df->def_info.add_refs_inline = false;
00522 df->use_info.add_refs_inline = false;
00523 }
00524
00525 df_refs_record (dflow, local_blocks_to_scan);
00526 #if 0
00527 bitmap_print (stderr, local_blocks_to_scan, "scanning: ", "\n");
00528 #endif
00529
00530 if (!df->blocks_to_scan)
00531 df->blocks_to_scan = BITMAP_ALLOC (NULL);
00532
00533 bitmap_ior_into (df->blocks_to_scan, local_blocks_to_scan);
00534 BITMAP_FREE (local_blocks_to_scan);
00535 }
00536
00537
00538
00539
00540
00541 struct df_ref *
00542 df_ref_create (struct df *df, rtx reg, rtx *loc, rtx insn,
00543 basic_block bb,
00544 enum df_ref_type ref_type,
00545 enum df_ref_flags ref_flags)
00546 {
00547 struct dataflow *dflow = df->problems_by_index[DF_SCAN];
00548 struct df_scan_bb_info *bb_info;
00549
00550 df_grow_reg_info (dflow, &df->use_info);
00551 df_grow_reg_info (dflow, &df->def_info);
00552 df_grow_bb_info (dflow);
00553
00554
00555 bb_info = df_scan_get_bb_info (dflow, bb->index);
00556 if (!bb_info)
00557 {
00558 bb_info = (struct df_scan_bb_info *) pool_alloc (dflow->block_pool);
00559 df_scan_set_bb_info (dflow, bb->index, bb_info);
00560 bb_info->artificial_defs = NULL;
00561 bb_info->artificial_uses = NULL;
00562 }
00563
00564 if (ref_type == DF_REF_REG_DEF)
00565 df->def_info.add_refs_inline = true;
00566 else
00567 df->use_info.add_refs_inline = true;
00568
00569 return df_ref_create_structure (dflow, reg, loc, bb, insn, ref_type, ref_flags);
00570 }
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 struct df_ref *
00582 df_get_artificial_defs (struct df *df, unsigned int bb_index)
00583 {
00584 struct dataflow *dflow = df->problems_by_index[DF_SCAN];
00585 return df_scan_get_bb_info (dflow, bb_index)->artificial_defs;
00586 }
00587
00588
00589
00590
00591 struct df_ref *
00592 df_get_artificial_uses (struct df *df, unsigned int bb_index)
00593 {
00594 struct dataflow *dflow = df->problems_by_index[DF_SCAN];
00595 return df_scan_get_bb_info (dflow, bb_index)->artificial_uses;
00596 }
00597
00598
00599
00600
00601 void
00602 df_reg_chain_create (struct df_reg_info *reg_info,
00603 struct df_ref *ref)
00604 {
00605 struct df_ref *head = reg_info->reg_chain;
00606 reg_info->reg_chain = ref;
00607
00608 DF_REF_NEXT_REG (ref) = head;
00609
00610
00611 DF_REF_PREV_REG (ref) = NULL;
00612
00613 if (head)
00614 DF_REF_PREV_REG (head) = ref;
00615 }
00616
00617
00618
00619
00620
00621 static struct df_ref *
00622 df_ref_unlink (struct df_ref *chain, struct df_ref *ref)
00623 {
00624 struct df_ref *orig_chain = chain;
00625 struct df_ref *prev = NULL;
00626 while (chain)
00627 {
00628 if (chain == ref)
00629 {
00630 if (prev)
00631 {
00632 prev->next_ref = ref->next_ref;
00633 ref->next_ref = NULL;
00634 return orig_chain;
00635 }
00636 else
00637 {
00638 chain = ref->next_ref;
00639 ref->next_ref = NULL;
00640 return chain;
00641 }
00642 }
00643
00644 prev = chain;
00645 chain = chain->next_ref;
00646 }
00647
00648
00649 gcc_unreachable ();
00650 return NULL;
00651 }
00652
00653
00654
00655
00656
00657
00658 struct df_ref *
00659 df_reg_chain_unlink (struct dataflow *dflow, struct df_ref *ref)
00660 {
00661 struct df *df = dflow->df;
00662 struct df_ref *next = DF_REF_NEXT_REG (ref);
00663 struct df_ref *prev = DF_REF_PREV_REG (ref);
00664 struct df_scan_problem_data *problem_data
00665 = (struct df_scan_problem_data *) dflow->problem_data;
00666 struct df_reg_info *reg_info;
00667 struct df_ref *next_ref = ref->next_ref;
00668 unsigned int id = DF_REF_ID (ref);
00669
00670 if (DF_REF_TYPE (ref) == DF_REF_REG_DEF)
00671 {
00672 reg_info = DF_REG_DEF_GET (df, DF_REF_REGNO (ref));
00673 df->def_info.bitmap_size--;
00674 if (df->def_info.refs && (id < df->def_info.refs_size))
00675 DF_DEFS_SET (df, id, NULL);
00676 }
00677 else
00678 {
00679 reg_info = DF_REG_USE_GET (df, DF_REF_REGNO (ref));
00680 df->use_info.bitmap_size--;
00681 if (df->use_info.refs && (id < df->use_info.refs_size))
00682 DF_USES_SET (df, id, NULL);
00683 }
00684
00685
00686 if (DF_REF_CHAIN (ref))
00687 df_chain_unlink (df->problems_by_index[DF_CHAIN], ref, NULL);
00688
00689 reg_info->n_refs--;
00690
00691
00692
00693 if (prev)
00694 {
00695 DF_REF_NEXT_REG (prev) = next;
00696 if (next)
00697 DF_REF_PREV_REG (next) = prev;
00698 }
00699 else
00700 {
00701 reg_info->reg_chain = next;
00702 if (next)
00703 DF_REF_PREV_REG (next) = NULL;
00704 }
00705
00706 pool_free (problem_data->ref_pool, ref);
00707 return next_ref;
00708 }
00709
00710
00711
00712
00713 void
00714 df_ref_remove (struct df *df, struct df_ref *ref)
00715 {
00716 struct dataflow *dflow = df->problems_by_index[DF_SCAN];
00717 if (DF_REF_REG_DEF_P (ref))
00718 {
00719 if (DF_REF_FLAGS (ref) & DF_REF_ARTIFICIAL)
00720 {
00721 struct df_scan_bb_info *bb_info
00722 = df_scan_get_bb_info (dflow, DF_REF_BB (ref)->index);
00723 bb_info->artificial_defs
00724 = df_ref_unlink (bb_info->artificial_defs, ref);
00725 }
00726 else
00727 DF_INSN_UID_DEFS (df, DF_REF_INSN_UID (ref))
00728 = df_ref_unlink (DF_INSN_UID_DEFS (df, DF_REF_INSN_UID (ref)), ref);
00729
00730 if (df->def_info.add_refs_inline)
00731 DF_DEFS_SET (df, DF_REF_ID (ref), NULL);
00732 }
00733 else
00734 {
00735 if (DF_REF_FLAGS (ref) & DF_REF_ARTIFICIAL)
00736 {
00737 struct df_scan_bb_info *bb_info
00738 = df_scan_get_bb_info (dflow, DF_REF_BB (ref)->index);
00739 bb_info->artificial_uses
00740 = df_ref_unlink (bb_info->artificial_uses, ref);
00741 }
00742 else
00743 DF_INSN_UID_USES (df, DF_REF_INSN_UID (ref))
00744 = df_ref_unlink (DF_INSN_UID_USES (df, DF_REF_INSN_UID (ref)), ref);
00745
00746 if (df->use_info.add_refs_inline)
00747 DF_USES_SET (df, DF_REF_ID (ref), NULL);
00748 }
00749
00750 df_reg_chain_unlink (dflow, ref);
00751 }
00752
00753
00754
00755
00756 static struct df_insn_info *
00757 df_insn_create_insn_record (struct dataflow *dflow, rtx insn)
00758 {
00759 struct df *df = dflow->df;
00760 struct df_scan_problem_data *problem_data
00761 = (struct df_scan_problem_data *) dflow->problem_data;
00762
00763 struct df_insn_info *insn_rec = DF_INSN_GET (df, insn);
00764 if (!insn_rec)
00765 {
00766 insn_rec = pool_alloc (problem_data->insn_pool);
00767 DF_INSN_SET (df, insn, insn_rec);
00768 }
00769 memset (insn_rec, 0, sizeof (struct df_insn_info));
00770
00771 return insn_rec;
00772 }
00773
00774
00775
00776
00777 void
00778 df_insn_refs_delete (struct dataflow *dflow, rtx insn)
00779 {
00780 struct df *df = dflow->df;
00781 unsigned int uid = INSN_UID (insn);
00782 struct df_insn_info *insn_info = NULL;
00783 struct df_ref *ref;
00784 struct df_scan_problem_data *problem_data
00785 = (struct df_scan_problem_data *) dflow->problem_data;
00786
00787 if (uid < df->insns_size)
00788 insn_info = DF_INSN_UID_GET (df, uid);
00789
00790 if (insn_info)
00791 {
00792 struct df_mw_hardreg *hardregs = insn_info->mw_hardregs;
00793
00794 while (hardregs)
00795 {
00796 struct df_mw_hardreg *next_hr = hardregs->next;
00797 struct df_link *link = hardregs->regs;
00798 while (link)
00799 {
00800 struct df_link *next_l = link->next;
00801 pool_free (problem_data->mw_link_pool, link);
00802 link = next_l;
00803 }
00804
00805 pool_free (problem_data->mw_reg_pool, hardregs);
00806 hardregs = next_hr;
00807 }
00808
00809 ref = insn_info->defs;
00810 while (ref)
00811 ref = df_reg_chain_unlink (dflow, ref);
00812
00813 ref = insn_info->uses;
00814 while (ref)
00815 ref = df_reg_chain_unlink (dflow, ref);
00816
00817 pool_free (problem_data->insn_pool, insn_info);
00818 DF_INSN_SET (df, insn, NULL);
00819 }
00820 }
00821
00822
00823
00824
00825 void
00826 df_bb_refs_delete (struct dataflow *dflow, int bb_index)
00827 {
00828 struct df_ref *def;
00829 struct df_ref *use;
00830
00831 struct df_scan_bb_info *bb_info
00832 = df_scan_get_bb_info (dflow, bb_index);
00833 rtx insn;
00834 basic_block bb = BASIC_BLOCK (bb_index);
00835 FOR_BB_INSNS (bb, insn)
00836 {
00837 if (INSN_P (insn))
00838 {
00839
00840 df_insn_refs_delete (dflow, insn);
00841 }
00842 }
00843
00844
00845 if (bb_info)
00846 {
00847 def = bb_info->artificial_defs;
00848 while (def)
00849 def = df_reg_chain_unlink (dflow, def);
00850 bb_info->artificial_defs = NULL;
00851 use = bb_info->artificial_uses;
00852 while (use)
00853 use = df_reg_chain_unlink (dflow, use);
00854 bb_info->artificial_uses = NULL;
00855 }
00856 }
00857
00858
00859
00860
00861 void
00862 df_refs_delete (struct dataflow *dflow, bitmap blocks)
00863 {
00864 bitmap_iterator bi;
00865 unsigned int bb_index;
00866
00867 EXECUTE_IF_SET_IN_BITMAP (blocks, 0, bb_index, bi)
00868 {
00869 df_bb_refs_delete (dflow, bb_index);
00870 }
00871 }
00872
00873
00874
00875
00876
00877 void
00878 df_reorganize_refs (struct df_ref_info *ref_info)
00879 {
00880 unsigned int m = ref_info->regs_inited;
00881 unsigned int regno;
00882 unsigned int offset = 0;
00883 unsigned int size = 0;
00884
00885 if (ref_info->refs_organized)
00886 return;
00887
00888 if (ref_info->refs_size < ref_info->bitmap_size)
00889 {
00890 int new_size = ref_info->bitmap_size + ref_info->bitmap_size / 4;
00891 df_grow_ref_info (ref_info, new_size);
00892 }
00893
00894 for (regno = 0; regno < m; regno++)
00895 {
00896 struct df_reg_info *reg_info = ref_info->regs[regno];
00897 int count = 0;
00898 if (reg_info)
00899 {
00900 struct df_ref *ref = reg_info->reg_chain;
00901 reg_info->begin = offset;
00902 while (ref)
00903 {
00904 ref_info->refs[offset] = ref;
00905 DF_REF_ID (ref) = offset++;
00906 ref = DF_REF_NEXT_REG (ref);
00907 count++;
00908 size++;
00909 }
00910 reg_info->n_refs = count;
00911 }
00912 }
00913
00914
00915
00916
00917 ref_info->bitmap_size = size;
00918 ref_info->refs_organized = true;
00919 ref_info->add_refs_inline = true;
00920 }
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930 static struct df_ref *
00931 df_ref_create_structure (struct dataflow *dflow, rtx reg, rtx *loc,
00932 basic_block bb, rtx insn,
00933 enum df_ref_type ref_type,
00934 enum df_ref_flags ref_flags)
00935 {
00936 struct df_ref *this_ref;
00937 struct df *df = dflow->df;
00938 int regno = REGNO (GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg);
00939 struct df_scan_problem_data *problem_data
00940 = (struct df_scan_problem_data *) dflow->problem_data;
00941
00942 this_ref = pool_alloc (problem_data->ref_pool);
00943 DF_REF_REG (this_ref) = reg;
00944 DF_REF_REGNO (this_ref) = regno;
00945 DF_REF_LOC (this_ref) = loc;
00946 DF_REF_INSN (this_ref) = insn;
00947 DF_REF_CHAIN (this_ref) = NULL;
00948 DF_REF_TYPE (this_ref) = ref_type;
00949 DF_REF_FLAGS (this_ref) = ref_flags;
00950 DF_REF_DATA (this_ref) = NULL;
00951 DF_REF_BB (this_ref) = bb;
00952
00953
00954
00955 switch (ref_type)
00956 {
00957 case DF_REF_REG_DEF:
00958 {
00959 struct df_reg_info *reg_info = DF_REG_DEF_GET (df, regno);
00960 reg_info->n_refs++;
00961
00962
00963 df_reg_chain_create (reg_info, this_ref);
00964 DF_REF_ID (this_ref) = df->def_info.bitmap_size;
00965 if (df->def_info.add_refs_inline)
00966 {
00967 if (DF_DEFS_SIZE (df) >= df->def_info.refs_size)
00968 {
00969 int new_size = df->def_info.bitmap_size
00970 + df->def_info.bitmap_size / 4;
00971 df_grow_ref_info (&df->def_info, new_size);
00972 }
00973
00974 DF_DEFS_SET (df, df->def_info.bitmap_size, this_ref);
00975 df->def_info.refs_organized = false;
00976 }
00977
00978 df->def_info.bitmap_size++;
00979
00980 if (DF_REF_FLAGS (this_ref) & DF_REF_ARTIFICIAL)
00981 {
00982 struct df_scan_bb_info *bb_info
00983 = df_scan_get_bb_info (dflow, bb->index);
00984 this_ref->next_ref = bb_info->artificial_defs;
00985 bb_info->artificial_defs = this_ref;
00986 }
00987 else
00988 {
00989 this_ref->next_ref = DF_INSN_GET (df, insn)->defs;
00990 DF_INSN_GET (df, insn)->defs = this_ref;
00991 }
00992 }
00993 break;
00994
00995 case DF_REF_REG_MEM_LOAD:
00996 case DF_REF_REG_MEM_STORE:
00997 case DF_REF_REG_USE:
00998 {
00999 struct df_reg_info *reg_info = DF_REG_USE_GET (df, regno);
01000 reg_info->n_refs++;
01001
01002
01003 df_reg_chain_create (reg_info, this_ref);
01004 DF_REF_ID (this_ref) = df->use_info.bitmap_size;
01005 if (df->use_info.add_refs_inline)
01006 {
01007 if (DF_USES_SIZE (df) >= df->use_info.refs_size)
01008 {
01009 int new_size = df->use_info.bitmap_size
01010 + df->use_info.bitmap_size / 4;
01011 df_grow_ref_info (&df->use_info, new_size);
01012 }
01013
01014 DF_USES_SET (df, df->use_info.bitmap_size, this_ref);
01015 df->use_info.refs_organized = false;
01016 }
01017
01018 df->use_info.bitmap_size++;
01019 if (DF_REF_FLAGS (this_ref) & DF_REF_ARTIFICIAL)
01020 {
01021 struct df_scan_bb_info *bb_info
01022 = df_scan_get_bb_info (dflow, bb->index);
01023 this_ref->next_ref = bb_info->artificial_uses;
01024 bb_info->artificial_uses = this_ref;
01025 }
01026 else
01027 {
01028 this_ref->next_ref = DF_INSN_GET (df, insn)->uses;
01029 DF_INSN_GET (df, insn)->uses = this_ref;
01030 }
01031 }
01032 break;
01033
01034 default:
01035 gcc_unreachable ();
01036
01037 }
01038 return this_ref;
01039 }
01040
01041
01042
01043
01044
01045 static void
01046 df_ref_record (struct dataflow *dflow, rtx reg, rtx *loc,
01047 basic_block bb, rtx insn,
01048 enum df_ref_type ref_type,
01049 enum df_ref_flags ref_flags,
01050 bool record_live)
01051 {
01052 struct df *df = dflow->df;
01053 rtx oldreg = reg;
01054 unsigned int regno;
01055
01056 gcc_assert (REG_P (reg) || GET_CODE (reg) == SUBREG);
01057
01058
01059
01060
01061
01062
01063 if ((dflow->flags & DF_SUBREGS) == 0
01064 && GET_CODE (reg) == SUBREG
01065 && (GET_MODE_SIZE (GET_MODE (reg)) < GET_MODE_SIZE (word_mode)
01066 || GET_MODE_SIZE (GET_MODE (reg))
01067 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (reg)))))
01068 {
01069 loc = &SUBREG_REG (reg);
01070 reg = *loc;
01071 ref_flags |= DF_REF_STRIPPED;
01072 }
01073
01074 regno = REGNO (GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg);
01075 if (regno < FIRST_PSEUDO_REGISTER)
01076 {
01077 unsigned int i;
01078 unsigned int endregno;
01079 struct df_mw_hardreg *hardreg = NULL;
01080 struct df_scan_problem_data *problem_data
01081 = (struct df_scan_problem_data *) dflow->problem_data;
01082
01083 if (!(dflow->flags & DF_HARD_REGS))
01084 return;
01085
01086
01087
01088
01089
01090
01091 endregno = hard_regno_nregs[regno][GET_MODE (reg)];
01092 if (GET_CODE (reg) == SUBREG)
01093 regno += subreg_regno_offset (regno, GET_MODE (SUBREG_REG (reg)),
01094 SUBREG_BYTE (reg), GET_MODE (reg));
01095 endregno += regno;
01096
01097
01098
01099 if ((endregno != regno + 1) && insn)
01100 {
01101 struct df_insn_info *insn_info = DF_INSN_GET (df, insn);
01102
01103
01104 if (GET_CODE (oldreg) == SUBREG)
01105 ref_flags |= DF_REF_PARTIAL;
01106 ref_flags |= DF_REF_MW_HARDREG;
01107 hardreg = pool_alloc (problem_data->mw_reg_pool);
01108 hardreg->next = insn_info->mw_hardregs;
01109 insn_info->mw_hardregs = hardreg;
01110 hardreg->type = ref_type;
01111 hardreg->flags = ref_flags;
01112 hardreg->mw_reg = reg;
01113 hardreg->regs = NULL;
01114
01115 }
01116
01117 for (i = regno; i < endregno; i++)
01118 {
01119 struct df_ref *ref;
01120
01121
01122
01123 if (ref_type == DF_REF_REG_DEF && record_live)
01124 regs_ever_live[i] = 1;
01125 else if ((ref_type == DF_REF_REG_USE
01126 || ref_type == DF_REF_REG_MEM_STORE
01127 || ref_type == DF_REF_REG_MEM_LOAD)
01128 && ((ref_flags & DF_REF_ARTIFICIAL) == 0))
01129 {
01130
01131
01132 if (!(TEST_HARD_REG_BIT (elim_reg_set, regno)
01133 && (regno == FRAME_POINTER_REGNUM
01134 || regno == ARG_POINTER_REGNUM)))
01135 regs_ever_live[i] = 1;
01136 }
01137
01138 ref = df_ref_create_structure (dflow, regno_reg_rtx[i], loc,
01139 bb, insn, ref_type, ref_flags);
01140 if (hardreg)
01141 {
01142 struct df_link *link = pool_alloc (problem_data->mw_link_pool);
01143
01144 link->next = hardreg->regs;
01145 link->ref = ref;
01146 hardreg->regs = link;
01147 }
01148 }
01149 }
01150 else
01151 {
01152 df_ref_create_structure (dflow, reg, loc,
01153 bb, insn, ref_type, ref_flags);
01154 }
01155 }
01156
01157
01158
01159
01160
01161
01162
01163 bool
01164 df_read_modify_subreg_p (rtx x)
01165 {
01166 unsigned int isize, osize;
01167 if (GET_CODE (x) != SUBREG)
01168 return false;
01169 isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
01170 osize = GET_MODE_SIZE (GET_MODE (x));
01171 return (isize > osize && isize > UNITS_PER_WORD);
01172 }
01173
01174
01175
01176
01177
01178
01179 static void
01180 df_def_record_1 (struct dataflow *dflow, rtx x,
01181 basic_block bb, rtx insn,
01182 enum df_ref_flags flags, bool record_live)
01183 {
01184 rtx *loc;
01185 rtx dst;
01186 bool dst_in_strict_lowpart = false;
01187
01188
01189
01190 if (GET_CODE (x) == EXPR_LIST || GET_CODE (x) == CLOBBER)
01191 loc = &XEXP (x, 0);
01192 else
01193 loc = &SET_DEST (x);
01194 dst = *loc;
01195
01196
01197 if (GET_CODE (dst) == PARALLEL)
01198 {
01199 int i;
01200
01201 for (i = XVECLEN (dst, 0) - 1; i >= 0; i--)
01202 {
01203 rtx temp = XVECEXP (dst, 0, i);
01204 if (GET_CODE (temp) == EXPR_LIST || GET_CODE (temp) == CLOBBER
01205 || GET_CODE (temp) == SET)
01206 df_def_record_1 (dflow, temp, bb, insn,
01207 GET_CODE (temp) == CLOBBER
01208 ? flags | DF_REF_MUST_CLOBBER : flags,
01209 record_live);
01210 }
01211 return;
01212 }
01213
01214
01215
01216 while (GET_CODE (dst) == STRICT_LOW_PART
01217 || GET_CODE (dst) == ZERO_EXTRACT
01218 || df_read_modify_subreg_p (dst))
01219 {
01220 #if 0
01221
01222
01223 if (GET_CODE (dst) == STRICT_LOW_PART)
01224 {
01225 loc = &XEXP (dst, 0);
01226 dst = *loc;
01227 }
01228 #endif
01229 loc = &XEXP (dst, 0);
01230 if (GET_CODE (dst) == STRICT_LOW_PART)
01231 dst_in_strict_lowpart = true;
01232 dst = *loc;
01233 flags |= DF_REF_READ_WRITE;
01234
01235 }
01236
01237
01238
01239
01240 if (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst))
01241 && dst_in_strict_lowpart)
01242 flags |= DF_REF_PARTIAL;
01243
01244 if (REG_P (dst)
01245 || (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst))))
01246 df_ref_record (dflow, dst, loc, bb, insn,
01247 DF_REF_REG_DEF, flags, record_live);
01248 }
01249
01250
01251
01252
01253 static void
01254 df_defs_record (struct dataflow *dflow, rtx x, basic_block bb, rtx insn)
01255 {
01256 RTX_CODE code = GET_CODE (x);
01257
01258 if (code == SET || code == CLOBBER)
01259 {
01260
01261 df_def_record_1 (dflow, x, bb, insn,
01262 code == CLOBBER ? DF_REF_MUST_CLOBBER : 0, true);
01263 }
01264 else if (code == COND_EXEC)
01265 {
01266 df_defs_record (dflow, COND_EXEC_CODE (x), bb, insn);
01267 }
01268 else if (code == PARALLEL)
01269 {
01270 int i;
01271
01272
01273 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
01274 df_defs_record (dflow, XVECEXP (x, 0, i), bb, insn);
01275 }
01276 }
01277
01278
01279
01280
01281 static void
01282 df_uses_record (struct dataflow *dflow, rtx *loc, enum df_ref_type ref_type,
01283 basic_block bb, rtx insn, enum df_ref_flags flags)
01284 {
01285 RTX_CODE code;
01286 rtx x;
01287 retry:
01288 x = *loc;
01289 if (!x)
01290 return;
01291 code = GET_CODE (x);
01292 switch (code)
01293 {
01294 case LABEL_REF:
01295 case SYMBOL_REF:
01296 case CONST_INT:
01297 case CONST:
01298 case CONST_DOUBLE:
01299 case CONST_VECTOR:
01300 case PC:
01301 case CC0:
01302 case ADDR_VEC:
01303 case ADDR_DIFF_VEC:
01304 return;
01305
01306 case CLOBBER:
01307
01308
01309 if (MEM_P (XEXP (x, 0)))
01310 df_uses_record (dflow, &XEXP (XEXP (x, 0), 0),
01311 DF_REF_REG_MEM_STORE, bb, insn, flags);
01312
01313
01314 return;
01315
01316 case MEM:
01317 df_uses_record (dflow, &XEXP (x, 0), DF_REF_REG_MEM_LOAD, bb, insn,
01318 flags & DF_REF_IN_NOTE);
01319 return;
01320
01321 case SUBREG:
01322
01323 flags |= DF_REF_PARTIAL;
01324
01325 if (!REG_P (SUBREG_REG (x)))
01326 {
01327 loc = &SUBREG_REG (x);
01328 df_uses_record (dflow, loc, ref_type, bb, insn, flags);
01329 return;
01330 }
01331
01332
01333 case REG:
01334 df_ref_record (dflow, x, loc, bb, insn, ref_type, flags, true);
01335 return;
01336
01337 case SET:
01338 {
01339 rtx dst = SET_DEST (x);
01340 gcc_assert (!(flags & DF_REF_IN_NOTE));
01341 df_uses_record (dflow, &SET_SRC (x), DF_REF_REG_USE, bb, insn, flags);
01342
01343 switch (GET_CODE (dst))
01344 {
01345 case SUBREG:
01346 if (df_read_modify_subreg_p (dst))
01347 {
01348 df_uses_record (dflow, &SUBREG_REG (dst),
01349 DF_REF_REG_USE, bb,
01350 insn, flags | DF_REF_READ_WRITE);
01351 break;
01352 }
01353
01354 case REG:
01355 case PARALLEL:
01356 case SCRATCH:
01357 case PC:
01358 case CC0:
01359 break;
01360 case MEM:
01361 df_uses_record (dflow, &XEXP (dst, 0),
01362 DF_REF_REG_MEM_STORE,
01363 bb, insn, flags);
01364 break;
01365 case STRICT_LOW_PART:
01366 {
01367 rtx *temp = &XEXP (dst, 0);
01368
01369
01370 dst = XEXP (dst, 0);
01371 df_uses_record (dflow,
01372 (GET_CODE (dst) == SUBREG)
01373 ? &SUBREG_REG (dst) : temp,
01374 DF_REF_REG_USE, bb,
01375 insn, DF_REF_READ_WRITE);
01376 }
01377 break;
01378 case ZERO_EXTRACT:
01379 case SIGN_EXTRACT:
01380 df_uses_record (dflow, &XEXP (dst, 0),
01381 DF_REF_REG_USE, bb, insn,
01382 DF_REF_READ_WRITE);
01383 df_uses_record (dflow, &XEXP (dst, 1),
01384 DF_REF_REG_USE, bb, insn, flags);
01385 df_uses_record (dflow, &XEXP (dst, 2),
01386 DF_REF_REG_USE, bb, insn, flags);
01387 dst = XEXP (dst, 0);
01388 break;
01389 default:
01390 gcc_unreachable ();
01391 }
01392 return;
01393 }
01394
01395 case RETURN:
01396 break;
01397
01398 case ASM_OPERANDS:
01399 case UNSPEC_VOLATILE:
01400 case TRAP_IF:
01401 case ASM_INPUT:
01402 {
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430 if (code == ASM_OPERANDS)
01431 {
01432 int j;
01433
01434 for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
01435 df_uses_record (dflow, &ASM_OPERANDS_INPUT (x, j),
01436 DF_REF_REG_USE, bb, insn, flags);
01437 return;
01438 }
01439 break;
01440 }
01441
01442 case PRE_DEC:
01443 case POST_DEC:
01444 case PRE_INC:
01445 case POST_INC:
01446 case PRE_MODIFY:
01447 case POST_MODIFY:
01448
01449 flags |= DF_REF_READ_WRITE;
01450 df_ref_record (dflow, XEXP (x, 0), &XEXP (x, 0), bb, insn,
01451 DF_REF_REG_DEF, flags, true);
01452
01453
01454
01455 default:
01456 break;
01457 }
01458
01459
01460 {
01461 const char *fmt = GET_RTX_FORMAT (code);
01462 int i;
01463
01464 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
01465 {
01466 if (fmt[i] == 'e')
01467 {
01468
01469 if (i == 0)
01470 {
01471 loc = &XEXP (x, 0);
01472 goto retry;
01473 }
01474 df_uses_record (dflow, &XEXP (x, i), ref_type, bb, insn, flags);
01475 }
01476 else if (fmt[i] == 'E')
01477 {
01478 int j;
01479 for (j = 0; j < XVECLEN (x, i); j++)
01480 df_uses_record (dflow, &XVECEXP (x, i, j), ref_type,
01481 bb, insn, flags);
01482 }
01483 }
01484 }
01485 }
01486
01487
01488
01489 static int
01490 df_insn_contains_asm_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
01491 {
01492 if ( !*loc)
01493 return 0;
01494 if (GET_CODE (*loc) == ASM_OPERANDS)
01495 return 1;
01496 return 0;
01497 }
01498
01499
01500
01501
01502 static int
01503 df_insn_contains_asm (rtx insn)
01504 {
01505 return for_each_rtx (&insn, df_insn_contains_asm_1, NULL);
01506 }
01507
01508
01509
01510
01511
01512 static void
01513 df_insn_refs_record (struct dataflow *dflow, basic_block bb, rtx insn)
01514 {
01515 struct df *df = dflow->df;
01516 int i;
01517
01518 if (INSN_P (insn))
01519 {
01520 rtx note;
01521
01522 if (df_insn_contains_asm (insn))
01523 DF_INSN_CONTAINS_ASM (df, insn) = true;
01524
01525
01526 df_defs_record (dflow, PATTERN (insn), bb, insn);
01527
01528 if (dflow->flags & DF_EQUIV_NOTES)
01529 for (note = REG_NOTES (insn); note;
01530 note = XEXP (note, 1))
01531 {
01532 switch (REG_NOTE_KIND (note))
01533 {
01534 case REG_EQUIV:
01535 case REG_EQUAL:
01536 df_uses_record (dflow, &XEXP (note, 0), DF_REF_REG_USE,
01537 bb, insn, DF_REF_IN_NOTE);
01538 default:
01539 break;
01540 }
01541 }
01542
01543 if (CALL_P (insn))
01544 {
01545 rtx note;
01546
01547
01548
01549 for (note = CALL_INSN_FUNCTION_USAGE (insn); note;
01550 note = XEXP (note, 1))
01551 {
01552 if (GET_CODE (XEXP (note, 0)) == USE)
01553 df_uses_record (dflow, &XEXP (XEXP (note, 0), 0),
01554 DF_REF_REG_USE,
01555 bb, insn, 0);
01556 else if (GET_CODE (XEXP (note, 0)) == CLOBBER)
01557 {
01558 df_defs_record (dflow, XEXP (note, 0), bb, insn);
01559 if (REG_P (XEXP (XEXP (note, 0), 0)))
01560 {
01561 rtx reg = XEXP (XEXP (note, 0), 0);
01562 int regno_last;
01563 int regno_first;
01564 int i;
01565
01566 regno_last = regno_first = REGNO (reg);
01567 if (regno_first < FIRST_PSEUDO_REGISTER)
01568 regno_last
01569 += hard_regno_nregs[regno_first][GET_MODE (reg)] - 1;
01570 for (i = regno_first; i <= regno_last; i++)
01571 regs_ever_live[i] = 1;
01572 }
01573 }
01574 }
01575
01576
01577 df_uses_record (dflow, ®no_reg_rtx[STACK_POINTER_REGNUM],
01578 DF_REF_REG_USE, bb, insn,
01579 0);
01580
01581 if (dflow->flags & DF_HARD_REGS)
01582 {
01583 bitmap_iterator bi;
01584 unsigned int ui;
01585
01586
01587 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01588 if (global_regs[i])
01589 df_uses_record (dflow, ®no_reg_rtx[i],
01590 DF_REF_REG_USE, bb, insn,
01591 0);
01592 EXECUTE_IF_SET_IN_BITMAP (df_invalidated_by_call, 0, ui, bi)
01593 df_ref_record (dflow, regno_reg_rtx[ui], ®no_reg_rtx[ui], bb,
01594 insn, DF_REF_REG_DEF, DF_REF_MAY_CLOBBER, false);
01595 }
01596 }
01597
01598
01599 df_uses_record (dflow, &PATTERN (insn),
01600 DF_REF_REG_USE, bb, insn, 0);
01601
01602 }
01603 }
01604
01605 static bool
01606 df_has_eh_preds (basic_block bb)
01607 {
01608 edge e;
01609 edge_iterator ei;
01610
01611 FOR_EACH_EDGE (e, ei, bb->preds)
01612 {
01613 if (e->flags & EDGE_EH)
01614 return true;
01615 }
01616 return false;
01617 }
01618
01619
01620
01621 static void
01622 df_bb_refs_record (struct dataflow *dflow, basic_block bb)
01623 {
01624 struct df *df = dflow->df;
01625 rtx insn;
01626 int luid = 0;
01627 struct df_scan_bb_info *bb_info = df_scan_get_bb_info (dflow, bb->index);
01628 bitmap artificial_uses_at_bottom = NULL;
01629
01630 if (dflow->flags & DF_HARD_REGS)
01631 artificial_uses_at_bottom = BITMAP_ALLOC (NULL);
01632
01633
01634 if (!bb_info)
01635 {
01636 bb_info = (struct df_scan_bb_info *) pool_alloc (dflow->block_pool);
01637 df_scan_set_bb_info (dflow, bb->index, bb_info);
01638 bb_info->artificial_defs = NULL;
01639 bb_info->artificial_uses = NULL;
01640 }
01641
01642
01643 FOR_BB_INSNS (bb, insn)
01644 {
01645 df_insn_create_insn_record (dflow, insn);
01646 if (INSN_P (insn))
01647 {
01648
01649 DF_INSN_LUID (df, insn) = luid++;
01650 df_insn_refs_record (dflow, bb, insn);
01651 }
01652 DF_INSN_LUID (df, insn) = luid;
01653 }
01654
01655 #ifdef EH_RETURN_DATA_REGNO
01656 if ((dflow->flags & DF_HARD_REGS)
01657 && df_has_eh_preds (bb))
01658 {
01659 unsigned int i;
01660
01661 for (i = 0; ; ++i)
01662 {
01663 unsigned regno = EH_RETURN_DATA_REGNO (i);
01664 if (regno == INVALID_REGNUM)
01665 break;
01666 df_ref_record (dflow, regno_reg_rtx[regno], ®no_reg_rtx[regno],
01667 bb, NULL,
01668 DF_REF_REG_DEF, DF_REF_ARTIFICIAL | DF_REF_AT_TOP,
01669 false);
01670 }
01671 }
01672 #endif
01673
01674
01675 if ((dflow->flags & DF_HARD_REGS)
01676 && df_has_eh_preds (bb))
01677 {
01678 #ifdef EH_USES
01679 unsigned int i;
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01692 if (EH_USES (i))
01693 df_uses_record (dflow, ®no_reg_rtx[i],
01694 DF_REF_REG_USE, bb, NULL,
01695 DF_REF_ARTIFICIAL | DF_REF_AT_TOP);
01696 #endif
01697
01698
01699
01700
01701
01702 if (reload_completed)
01703 {
01704 if (frame_pointer_needed)
01705 {
01706 bitmap_set_bit (artificial_uses_at_bottom, FRAME_POINTER_REGNUM);
01707 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
01708 bitmap_set_bit (artificial_uses_at_bottom, HARD_FRAME_POINTER_REGNUM);
01709 #endif
01710 }
01711 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
01712 if (fixed_regs[ARG_POINTER_REGNUM])
01713 bitmap_set_bit (artificial_uses_at_bottom, ARG_POINTER_REGNUM);
01714 #endif
01715 }
01716 }
01717
01718 if ((dflow->flags & DF_HARD_REGS)
01719 && bb->index >= NUM_FIXED_BLOCKS)
01720 {
01721
01722
01723
01724 if (!reload_completed)
01725 {
01726
01727
01728
01729 bitmap_set_bit (artificial_uses_at_bottom, FRAME_POINTER_REGNUM);
01730
01731 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
01732
01733
01734 if (fixed_regs[ARG_POINTER_REGNUM])
01735 bitmap_set_bit (artificial_uses_at_bottom, ARG_POINTER_REGNUM);
01736 #endif
01737
01738
01739
01740 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
01741 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
01742 bitmap_set_bit (artificial_uses_at_bottom, PIC_OFFSET_TABLE_REGNUM);
01743 }
01744
01745 bitmap_set_bit (artificial_uses_at_bottom, STACK_POINTER_REGNUM);
01746 }
01747
01748 if (dflow->flags & DF_HARD_REGS)
01749 {
01750 bitmap_iterator bi;
01751 unsigned int regno;
01752
01753 EXECUTE_IF_SET_IN_BITMAP (artificial_uses_at_bottom, 0, regno, bi)
01754 {
01755 df_uses_record (dflow, ®no_reg_rtx[regno],
01756 DF_REF_REG_USE, bb, NULL, DF_REF_ARTIFICIAL);
01757 }
01758
01759 BITMAP_FREE (artificial_uses_at_bottom);
01760 }
01761 }
01762
01763
01764
01765
01766 static void
01767 df_refs_record (struct dataflow *dflow, bitmap blocks)
01768 {
01769 unsigned int bb_index;
01770 bitmap_iterator bi;
01771
01772 EXECUTE_IF_SET_IN_BITMAP (blocks, 0, bb_index, bi)
01773 {
01774 basic_block bb = BASIC_BLOCK (bb_index);
01775 df_bb_refs_record (dflow, bb);
01776 }
01777
01778 if (bitmap_bit_p (blocks, EXIT_BLOCK))
01779 df_record_exit_block_uses (dflow);
01780
01781 if (bitmap_bit_p (blocks, ENTRY_BLOCK))
01782 df_record_entry_block_defs (dflow);
01783 }
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793 static void
01794 df_mark_reg (rtx reg, void *vset)
01795 {
01796 bitmap set = (bitmap) vset;
01797 int regno = REGNO (reg);
01798
01799 gcc_assert (GET_MODE (reg) != BLKmode);
01800
01801 bitmap_set_bit (set, regno);
01802 if (regno < FIRST_PSEUDO_REGISTER)
01803 {
01804 int n = hard_regno_nregs[regno][GET_MODE (reg)];
01805 while (--n > 0)
01806 bitmap_set_bit (set, regno + n);
01807 }
01808 }
01809
01810
01811
01812
01813
01814 static void
01815 df_record_entry_block_defs (struct dataflow *dflow)
01816 {
01817 unsigned int i;
01818 bitmap_iterator bi;
01819 rtx r;
01820 struct df *df = dflow->df;
01821
01822 bitmap_clear (df->entry_block_defs);
01823
01824 if (!(dflow->flags & DF_HARD_REGS))
01825 return;
01826
01827 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01828 {
01829 if (FUNCTION_ARG_REGNO_P (i))
01830 #ifdef INCOMING_REGNO
01831 bitmap_set_bit (df->entry_block_defs, INCOMING_REGNO (i));
01832 #else
01833 bitmap_set_bit (df->entry_block_defs, i);
01834 #endif
01835 }
01836
01837
01838
01839 if (HAVE_prologue && epilogue_completed)
01840 {
01841
01842
01843 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01844 if ((call_used_regs[i] == 0) && (regs_ever_live[i]))
01845 bitmap_set_bit (df->entry_block_defs, i);
01846 }
01847 else
01848 {
01849
01850 bitmap_set_bit (df->entry_block_defs, STACK_POINTER_REGNUM);
01851
01852 #ifdef INCOMING_RETURN_ADDR_RTX
01853 if (REG_P (INCOMING_RETURN_ADDR_RTX))
01854 bitmap_set_bit (df->entry_block_defs, REGNO (INCOMING_RETURN_ADDR_RTX));
01855 #endif
01856
01857
01858
01859
01860 #ifdef STATIC_CHAIN_INCOMING_REGNUM
01861 bitmap_set_bit (df->entry_block_defs, STATIC_CHAIN_INCOMING_REGNUM);
01862 #else
01863 #ifdef STATIC_CHAIN_REGNUM
01864 bitmap_set_bit (df->entry_block_defs, STATIC_CHAIN_REGNUM);
01865 #endif
01866 #endif
01867
01868 r = TARGET_STRUCT_VALUE_RTX (current_function_decl, true);
01869 if (r && REG_P (r))
01870 bitmap_set_bit (df->entry_block_defs, REGNO (r));
01871 }
01872
01873 if ((!reload_completed) || frame_pointer_needed)
01874 {
01875
01876
01877 bitmap_set_bit (df->entry_block_defs, FRAME_POINTER_REGNUM);
01878 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
01879
01880 if (!LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
01881 bitmap_set_bit (df->entry_block_defs, HARD_FRAME_POINTER_REGNUM);
01882 #endif
01883 }
01884
01885
01886 if (!reload_completed)
01887 {
01888 #ifdef EH_USES
01889
01890
01891 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01892 if (EH_USES (i))
01893 {
01894 bitmap_set_bit (df->entry_block_defs, i);
01895 }
01896 #endif
01897
01898 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
01899
01900
01901 if (fixed_regs[ARG_POINTER_REGNUM])
01902 bitmap_set_bit (df->entry_block_defs, ARG_POINTER_REGNUM);
01903 #endif
01904
01905 #ifdef PIC_OFFSET_TABLE_REGNUM
01906
01907
01908 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
01909 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
01910 bitmap_set_bit (df->entry_block_defs, PIC_OFFSET_TABLE_REGNUM);
01911 #endif
01912 }
01913
01914 targetm.live_on_entry (df->entry_block_defs);
01915
01916 EXECUTE_IF_SET_IN_BITMAP (df->entry_block_defs, 0, i, bi)
01917 {
01918 df_ref_record (dflow, regno_reg_rtx[i], ®no_reg_rtx[i],
01919 ENTRY_BLOCK_PTR, NULL,
01920 DF_REF_REG_DEF, DF_REF_ARTIFICIAL , false);
01921 }
01922 }
01923
01924
01925
01926
01927 static void
01928 df_record_exit_block_uses (struct dataflow *dflow)
01929 {
01930 unsigned int i;
01931 bitmap_iterator bi;
01932 struct df *df = dflow->df;
01933
01934 bitmap_clear (df->exit_block_uses);
01935
01936 if (!(dflow->flags & DF_HARD_REGS))
01937 return;
01938
01939
01940
01941 if ((HAVE_epilogue && epilogue_completed)
01942 || !EXIT_IGNORE_STACK
01943 || (!FRAME_POINTER_REQUIRED
01944 && !current_function_calls_alloca
01945 && flag_omit_frame_pointer)
01946 || current_function_sp_is_unchanging)
01947 {
01948 bitmap_set_bit (df->exit_block_uses, STACK_POINTER_REGNUM);
01949 }
01950
01951
01952
01953
01954
01955 if ((!reload_completed) || frame_pointer_needed)
01956 {
01957 bitmap_set_bit (df->exit_block_uses, FRAME_POINTER_REGNUM);
01958 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
01959
01960 if (!LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
01961 bitmap_set_bit (df->exit_block_uses, HARD_FRAME_POINTER_REGNUM);
01962 #endif
01963 }
01964
01965 #ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
01966
01967
01968
01969 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
01970 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
01971 bitmap_set_bit (df->exit_block_uses, PIC_OFFSET_TABLE_REGNUM);
01972 #endif
01973
01974
01975
01976
01977 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01978 if (global_regs[i] || EPILOGUE_USES (i))
01979 bitmap_set_bit (df->exit_block_uses, i);
01980
01981 if (HAVE_epilogue && epilogue_completed)
01982 {
01983
01984 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01985 if (regs_ever_live[i] && !LOCAL_REGNO (i)
01986 && !TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
01987 bitmap_set_bit (df->exit_block_uses, i);
01988 }
01989
01990 #ifdef EH_RETURN_DATA_REGNO
01991
01992 if (reload_completed && current_function_calls_eh_return)
01993 for (i = 0; ; ++i)
01994 {
01995 unsigned regno = EH_RETURN_DATA_REGNO (i);
01996 if (regno == INVALID_REGNUM)
01997 break;
01998 bitmap_set_bit (df->exit_block_uses, regno);
01999 }
02000 #endif
02001
02002 #ifdef EH_RETURN_STACKADJ_RTX
02003 if ((!HAVE_epilogue || ! epilogue_completed)
02004 && current_function_calls_eh_return)
02005 {
02006 rtx tmp = EH_RETURN_STACKADJ_RTX;
02007 if (tmp && REG_P (tmp))
02008 df_mark_reg (tmp, df->exit_block_uses);
02009 }
02010 #endif
02011
02012 #ifdef EH_RETURN_HANDLER_RTX
02013 if ((!HAVE_epilogue || ! epilogue_completed)
02014 && current_function_calls_eh_return)
02015 {
02016 rtx tmp = EH_RETURN_HANDLER_RTX;
02017 if (tmp && REG_P (tmp))
02018 df_mark_reg (tmp, df->exit_block_uses);
02019 }
02020 #endif
02021
02022
02023 diddle_return_value (df_mark_reg, (void*) df->exit_block_uses);
02024
02025 if (dflow->flags & DF_HARD_REGS)
02026 EXECUTE_IF_SET_IN_BITMAP (df->exit_block_uses, 0, i, bi)
02027 df_uses_record (dflow, ®no_reg_rtx[i],
02028 DF_REF_REG_USE, EXIT_BLOCK_PTR, NULL,
02029 DF_REF_ARTIFICIAL);
02030 }
02031
02032 static bool initialized = false;
02033
02034
02035
02036 void
02037 df_hard_reg_init (void)
02038 {
02039 int i;
02040 #ifdef ELIMINABLE_REGS
02041 static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
02042 #endif
02043
02044
02045
02046 if (!reload_completed)
02047 memset (regs_ever_live, 0, sizeof (regs_ever_live));
02048
02049 if (initialized)
02050 return;
02051
02052 bitmap_obstack_initialize (&persistent_obstack);
02053
02054
02055
02056 CLEAR_HARD_REG_SET (elim_reg_set);
02057
02058 #ifdef ELIMINABLE_REGS
02059 for (i = 0; i < (int) ARRAY_SIZE (eliminables); i++)
02060 SET_HARD_REG_BIT (elim_reg_set, eliminables[i].from);
02061 #else
02062 SET_HARD_REG_BIT (elim_reg_set, FRAME_POINTER_REGNUM);
02063 #endif
02064
02065 df_invalidated_by_call = BITMAP_ALLOC (&persistent_obstack);
02066
02067
02068
02069 for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
02070 if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
02071 bitmap_set_bit (df_invalidated_by_call, i);
02072
02073 initialized = true;
02074 }