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
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 #include "config.h"
00157 #include "system.h"
00158 #include "rtl.h"
00159 #include "tm_p.h"
00160 #include "insn-config.h"
00161 #include "recog.h"
00162 #include "function.h"
00163 #include "regs.h"
00164 #include "obstack.h"
00165 #include "hard-reg-set.h"
00166 #include "basic-block.h"
00167 #include "sbitmap.h"
00168 #include "bitmap.h"
00169 #include "df.h"
00170 #include "fibheap.h"
00171
00172 #define FOR_EACH_BB_IN_BITMAP(BITMAP, MIN, BB, CODE) \
00173 do \
00174 { \
00175 unsigned int node_; \
00176 EXECUTE_IF_SET_IN_BITMAP (BITMAP, MIN, node_, \
00177 {(BB) = BASIC_BLOCK (node_); CODE;}); \
00178 } \
00179 while (0)
00180
00181 static struct obstack df_ref_obstack;
00182 static struct df *ddf;
00183
00184 static void df_reg_table_realloc PARAMS((struct df *, int));
00185 #if 0
00186 static void df_def_table_realloc PARAMS((struct df *, int));
00187 #endif
00188 static void df_insn_table_realloc PARAMS((struct df *, unsigned int));
00189 static void df_bitmaps_alloc PARAMS((struct df *, int));
00190 static void df_bitmaps_free PARAMS((struct df *, int));
00191 static void df_free PARAMS((struct df *));
00192 static void df_alloc PARAMS((struct df *, int));
00193
00194 static rtx df_reg_clobber_gen PARAMS((unsigned int));
00195 static rtx df_reg_use_gen PARAMS((unsigned int));
00196
00197 static inline struct df_link *df_link_create PARAMS((struct ref *,
00198 struct df_link *));
00199 static struct df_link *df_ref_unlink PARAMS((struct df_link **, struct ref *));
00200 static void df_def_unlink PARAMS((struct df *, struct ref *));
00201 static void df_use_unlink PARAMS((struct df *, struct ref *));
00202 static void df_insn_refs_unlink PARAMS ((struct df *, basic_block, rtx));
00203 #if 0
00204 static void df_bb_refs_unlink PARAMS ((struct df *, basic_block));
00205 static void df_refs_unlink PARAMS ((struct df *, bitmap));
00206 #endif
00207
00208 static struct ref *df_ref_create PARAMS((struct df *,
00209 rtx, rtx *, rtx,
00210 enum df_ref_type, enum df_ref_flags));
00211 static void df_ref_record_1 PARAMS((struct df *, rtx, rtx *,
00212 rtx, enum df_ref_type,
00213 enum df_ref_flags));
00214 static void df_ref_record PARAMS((struct df *, rtx, rtx *,
00215 rtx, enum df_ref_type,
00216 enum df_ref_flags));
00217 static void df_def_record_1 PARAMS((struct df *, rtx, basic_block, rtx));
00218 static void df_defs_record PARAMS((struct df *, rtx, basic_block, rtx));
00219 static void df_uses_record PARAMS((struct df *, rtx *,
00220 enum df_ref_type, basic_block, rtx,
00221 enum df_ref_flags));
00222 static void df_insn_refs_record PARAMS((struct df *, basic_block, rtx));
00223 static void df_bb_refs_record PARAMS((struct df *, basic_block));
00224 static void df_refs_record PARAMS((struct df *, bitmap));
00225
00226 static void df_bb_reg_def_chain_create PARAMS((struct df *, basic_block));
00227 static void df_reg_def_chain_create PARAMS((struct df *, bitmap));
00228 static void df_bb_reg_use_chain_create PARAMS((struct df *, basic_block));
00229 static void df_reg_use_chain_create PARAMS((struct df *, bitmap));
00230 static void df_bb_du_chain_create PARAMS((struct df *, basic_block, bitmap));
00231 static void df_du_chain_create PARAMS((struct df *, bitmap));
00232 static void df_bb_ud_chain_create PARAMS((struct df *, basic_block));
00233 static void df_ud_chain_create PARAMS((struct df *, bitmap));
00234 static void df_bb_rd_local_compute PARAMS((struct df *, basic_block));
00235 static void df_rd_local_compute PARAMS((struct df *, bitmap));
00236 static void df_bb_ru_local_compute PARAMS((struct df *, basic_block));
00237 static void df_ru_local_compute PARAMS((struct df *, bitmap));
00238 static void df_bb_lr_local_compute PARAMS((struct df *, basic_block));
00239 static void df_lr_local_compute PARAMS((struct df *, bitmap));
00240 static void df_bb_reg_info_compute PARAMS((struct df *, basic_block, bitmap));
00241 static void df_reg_info_compute PARAMS((struct df *, bitmap));
00242
00243 static int df_bb_luids_set PARAMS((struct df *df, basic_block));
00244 static int df_luids_set PARAMS((struct df *df, bitmap));
00245
00246 static int df_modified_p PARAMS ((struct df *, bitmap));
00247 static int df_refs_queue PARAMS ((struct df *));
00248 static int df_refs_process PARAMS ((struct df *));
00249 static int df_bb_refs_update PARAMS ((struct df *, basic_block));
00250 static int df_refs_update PARAMS ((struct df *));
00251 static void df_analyse_1 PARAMS((struct df *, bitmap, int, int));
00252
00253 static void df_insns_modify PARAMS((struct df *, basic_block,
00254 rtx, rtx));
00255 static int df_rtx_mem_replace PARAMS ((rtx *, void *));
00256 static int df_rtx_reg_replace PARAMS ((rtx *, void *));
00257 void df_refs_reg_replace PARAMS ((struct df *, bitmap,
00258 struct df_link *, rtx, rtx));
00259
00260 static int df_def_dominates_all_uses_p PARAMS((struct df *, struct ref *def));
00261 static int df_def_dominates_uses_p PARAMS((struct df *,
00262 struct ref *def, bitmap));
00263 static struct ref *df_bb_regno_last_use_find PARAMS((struct df *, basic_block,
00264 unsigned int));
00265 static struct ref *df_bb_regno_first_def_find PARAMS((struct df *, basic_block,
00266 unsigned int));
00267 static struct ref *df_bb_insn_regno_last_use_find PARAMS((struct df *,
00268 basic_block,
00269 rtx, unsigned int));
00270 static struct ref *df_bb_insn_regno_first_def_find PARAMS((struct df *,
00271 basic_block,
00272 rtx, unsigned int));
00273
00274 static void df_chain_dump PARAMS((struct df_link *, FILE *file));
00275 static void df_chain_dump_regno PARAMS((struct df_link *, FILE *file));
00276 static void df_regno_debug PARAMS ((struct df *, unsigned int, FILE *));
00277 static void df_ref_debug PARAMS ((struct df *, struct ref *, FILE *));
00278 static void df_rd_transfer_function PARAMS ((int, int *, bitmap, bitmap,
00279 bitmap, bitmap, void *));
00280 static void df_ru_transfer_function PARAMS ((int, int *, bitmap, bitmap,
00281 bitmap, bitmap, void *));
00282 static void df_lr_transfer_function PARAMS ((int, int *, bitmap, bitmap,
00283 bitmap, bitmap, void *));
00284 static void hybrid_search_bitmap PARAMS ((basic_block, bitmap *, bitmap *,
00285 bitmap *, bitmap *, enum df_flow_dir,
00286 enum df_confluence_op,
00287 transfer_function_bitmap,
00288 sbitmap, sbitmap, void *));
00289 static void hybrid_search_sbitmap PARAMS ((basic_block, sbitmap *, sbitmap *,
00290 sbitmap *, sbitmap *, enum df_flow_dir,
00291 enum df_confluence_op,
00292 transfer_function_sbitmap,
00293 sbitmap, sbitmap, void *));
00294 static inline bool read_modify_subreg_p PARAMS ((rtx));
00295
00296
00297
00298
00299
00300
00301
00302 static void
00303 df_insn_table_realloc (df, size)
00304 struct df *df;
00305 unsigned int size;
00306 {
00307 size++;
00308 if (size <= df->insn_size)
00309 return;
00310
00311
00312
00313 size += df->insn_size / 4;
00314
00315 df->insns = (struct insn_info *)
00316 xrealloc (df->insns, size * sizeof (struct insn_info));
00317
00318 memset (df->insns + df->insn_size, 0,
00319 (size - df->insn_size) * sizeof (struct insn_info));
00320
00321 df->insn_size = size;
00322
00323 if (! df->insns_modified)
00324 {
00325 df->insns_modified = BITMAP_XMALLOC ();
00326 bitmap_zero (df->insns_modified);
00327 }
00328 }
00329
00330
00331
00332 static void
00333 df_reg_table_realloc (df, size)
00334 struct df *df;
00335 int size;
00336 {
00337
00338 if (! size)
00339 size = df->reg_size / 4;
00340
00341 size += df->reg_size;
00342 if (size < max_reg_num ())
00343 size = max_reg_num ();
00344
00345 df->regs = (struct reg_info *)
00346 xrealloc (df->regs, size * sizeof (struct reg_info));
00347
00348
00349 memset (df->regs + df->reg_size, 0,
00350 (size - df->reg_size) * sizeof (struct reg_info));
00351
00352 df->reg_size = size;
00353 }
00354
00355
00356 #if 0
00357
00358 static void
00359 df_def_table_realloc (df, size)
00360 struct df *df;
00361 int size;
00362 {
00363 int i;
00364 struct ref *refs;
00365
00366
00367 if (! size)
00368 size = df->def_size / 4;
00369
00370 df->def_size += size;
00371 df->defs = xrealloc (df->defs,
00372 df->def_size * sizeof (*df->defs));
00373
00374
00375
00376
00377 refs = xmalloc (size * sizeof (*refs));
00378
00379
00380 for (i = 0; i < size - 1; i++)
00381 refs[i].chain = (struct df_link *) (refs + i + 1);
00382 refs[size - 1].chain = 0;
00383 }
00384 #endif
00385
00386
00387
00388
00389 static void
00390 df_bitmaps_alloc (df, flags)
00391 struct df *df;
00392 int flags;
00393 {
00394 int dflags = 0;
00395 basic_block bb;
00396
00397
00398 if ((flags & DF_LR) && df->n_regs < (unsigned int) max_reg_num ())
00399 dflags |= DF_LR | DF_RU;
00400 if ((flags & DF_RU) && df->n_uses < df->use_id)
00401 dflags |= DF_RU;
00402 if ((flags & DF_RD) && df->n_defs < df->def_id)
00403 dflags |= DF_RD;
00404
00405 if (dflags)
00406 df_bitmaps_free (df, dflags);
00407
00408 df->n_defs = df->def_id;
00409 df->n_uses = df->use_id;
00410
00411 FOR_EACH_BB (bb)
00412 {
00413 struct bb_info *bb_info = DF_BB_INFO (df, bb);
00414
00415 if (flags & DF_RD && ! bb_info->rd_in)
00416 {
00417
00418 bb_info->rd_kill = BITMAP_XMALLOC ();
00419 bitmap_zero (bb_info->rd_kill);
00420 bb_info->rd_gen = BITMAP_XMALLOC ();
00421 bitmap_zero (bb_info->rd_gen);
00422 bb_info->rd_in = BITMAP_XMALLOC ();
00423 bb_info->rd_out = BITMAP_XMALLOC ();
00424 bb_info->rd_valid = 0;
00425 }
00426
00427 if (flags & DF_RU && ! bb_info->ru_in)
00428 {
00429
00430 bb_info->ru_kill = BITMAP_XMALLOC ();
00431 bitmap_zero (bb_info->ru_kill);
00432
00433 bb_info->ru_gen = BITMAP_XMALLOC ();
00434 bitmap_zero (bb_info->ru_gen);
00435 bb_info->ru_in = BITMAP_XMALLOC ();
00436 bb_info->ru_out = BITMAP_XMALLOC ();
00437 bb_info->ru_valid = 0;
00438 }
00439
00440 if (flags & DF_LR && ! bb_info->lr_in)
00441 {
00442
00443 bb_info->lr_def = BITMAP_XMALLOC ();
00444 bitmap_zero (bb_info->lr_def);
00445 bb_info->lr_use = BITMAP_XMALLOC ();
00446 bitmap_zero (bb_info->lr_use);
00447 bb_info->lr_in = BITMAP_XMALLOC ();
00448 bb_info->lr_out = BITMAP_XMALLOC ();
00449 bb_info->lr_valid = 0;
00450 }
00451 }
00452 }
00453
00454
00455
00456 static void
00457 df_bitmaps_free (df, flags)
00458 struct df *df ATTRIBUTE_UNUSED;
00459 int flags;
00460 {
00461 basic_block bb;
00462
00463 FOR_EACH_BB (bb)
00464 {
00465 struct bb_info *bb_info = DF_BB_INFO (df, bb);
00466
00467 if (!bb_info)
00468 continue;
00469
00470 if ((flags & DF_RD) && bb_info->rd_in)
00471 {
00472
00473 BITMAP_XFREE (bb_info->rd_kill);
00474 bb_info->rd_kill = NULL;
00475 BITMAP_XFREE (bb_info->rd_gen);
00476 bb_info->rd_gen = NULL;
00477 BITMAP_XFREE (bb_info->rd_in);
00478 bb_info->rd_in = NULL;
00479 BITMAP_XFREE (bb_info->rd_out);
00480 bb_info->rd_out = NULL;
00481 }
00482
00483 if ((flags & DF_RU) && bb_info->ru_in)
00484 {
00485
00486 BITMAP_XFREE (bb_info->ru_kill);
00487 bb_info->ru_kill = NULL;
00488 BITMAP_XFREE (bb_info->ru_gen);
00489 bb_info->ru_gen = NULL;
00490 BITMAP_XFREE (bb_info->ru_in);
00491 bb_info->ru_in = NULL;
00492 BITMAP_XFREE (bb_info->ru_out);
00493 bb_info->ru_out = NULL;
00494 }
00495
00496 if ((flags & DF_LR) && bb_info->lr_in)
00497 {
00498
00499 BITMAP_XFREE (bb_info->lr_def);
00500 bb_info->lr_def = NULL;
00501 BITMAP_XFREE (bb_info->lr_use);
00502 bb_info->lr_use = NULL;
00503 BITMAP_XFREE (bb_info->lr_in);
00504 bb_info->lr_in = NULL;
00505 BITMAP_XFREE (bb_info->lr_out);
00506 bb_info->lr_out = NULL;
00507 }
00508 }
00509 df->flags &= ~(flags & (DF_RD | DF_RU | DF_LR));
00510 }
00511
00512
00513
00514 static void
00515 df_alloc (df, n_regs)
00516 struct df *df;
00517 int n_regs;
00518 {
00519 int n_insns;
00520 basic_block bb;
00521
00522 gcc_obstack_init (&df_ref_obstack);
00523
00524
00525
00526 n_insns = get_max_uid () + 1;
00527
00528 df->def_id = 0;
00529 df->n_defs = 0;
00530
00531 df->def_size = n_insns;
00532 df->defs = xmalloc (df->def_size * sizeof (*df->defs));
00533
00534 df->use_id = 0;
00535 df->n_uses = 0;
00536
00537 df->use_size = n_insns * 2;
00538 df->uses = xmalloc (df->use_size * sizeof (*df->uses));
00539
00540 df->n_regs = n_regs;
00541 df->n_bbs = last_basic_block;
00542
00543
00544 df->reg_def_last = xmalloc (df->n_regs * sizeof (struct ref *));
00545
00546 df_insn_table_realloc (df, n_insns);
00547
00548 df_reg_table_realloc (df, df->n_regs);
00549
00550 df->bbs_modified = BITMAP_XMALLOC ();
00551 bitmap_zero (df->bbs_modified);
00552
00553 df->flags = 0;
00554
00555 df->bbs = xcalloc (last_basic_block, sizeof (struct bb_info));
00556
00557 df->all_blocks = BITMAP_XMALLOC ();
00558 FOR_EACH_BB (bb)
00559 bitmap_set_bit (df->all_blocks, bb->index);
00560 }
00561
00562
00563
00564 static void
00565 df_free (df)
00566 struct df *df;
00567 {
00568 df_bitmaps_free (df, DF_ALL);
00569
00570 if (df->bbs)
00571 free (df->bbs);
00572 df->bbs = 0;
00573
00574 if (df->insns)
00575 free (df->insns);
00576 df->insns = 0;
00577 df->insn_size = 0;
00578
00579 if (df->defs)
00580 free (df->defs);
00581 df->defs = 0;
00582 df->def_size = 0;
00583 df->def_id = 0;
00584
00585 if (df->uses)
00586 free (df->uses);
00587 df->uses = 0;
00588 df->use_size = 0;
00589 df->use_id = 0;
00590
00591 if (df->regs)
00592 free (df->regs);
00593 df->regs = 0;
00594 df->reg_size = 0;
00595
00596 if (df->bbs_modified)
00597 BITMAP_XFREE (df->bbs_modified);
00598 df->bbs_modified = 0;
00599
00600 if (df->insns_modified)
00601 BITMAP_XFREE (df->insns_modified);
00602 df->insns_modified = 0;
00603
00604 BITMAP_XFREE (df->all_blocks);
00605 df->all_blocks = 0;
00606
00607 obstack_free (&df_ref_obstack, NULL);
00608 }
00609
00610
00611
00612
00613 static rtx df_reg_use_gen (regno)
00614 unsigned int regno;
00615 {
00616 rtx reg;
00617 rtx use;
00618
00619 reg = regno_reg_rtx[regno];
00620
00621 use = gen_rtx_USE (GET_MODE (reg), reg);
00622 return use;
00623 }
00624
00625
00626
00627 static rtx df_reg_clobber_gen (regno)
00628 unsigned int regno;
00629 {
00630 rtx reg;
00631 rtx use;
00632
00633 reg = regno_reg_rtx[regno];
00634
00635 use = gen_rtx_CLOBBER (GET_MODE (reg), reg);
00636 return use;
00637 }
00638
00639
00640
00641
00642 static inline struct df_link *
00643 df_link_create (ref, next)
00644 struct ref *ref;
00645 struct df_link *next;
00646 {
00647 struct df_link *link;
00648
00649 link = (struct df_link *) obstack_alloc (&df_ref_obstack,
00650 sizeof (*link));
00651 link->next = next;
00652 link->ref = ref;
00653 return link;
00654 }
00655
00656
00657
00658 static struct df_link *
00659 df_ref_unlink (phead, ref)
00660 struct df_link **phead;
00661 struct ref *ref;
00662 {
00663 struct df_link *link = *phead;
00664
00665 if (link)
00666 {
00667 if (! link->next)
00668 {
00669
00670
00671
00672 if (link->ref != ref)
00673 abort ();
00674
00675 *phead = NULL;
00676 }
00677 else
00678 {
00679
00680 if (link->ref == ref)
00681 *phead = link->next;
00682 else
00683 {
00684
00685 for (; link->next; link = link->next)
00686 {
00687 if (link->next->ref == ref)
00688 {
00689
00690 link->next = link->next->next;
00691 return link->next;
00692 }
00693 }
00694 }
00695 }
00696 }
00697 return link;
00698 }
00699
00700
00701
00702 int
00703 df_ref_remove (df, ref)
00704 struct df *df;
00705 struct ref *ref;
00706 {
00707 if (DF_REF_REG_DEF_P (ref))
00708 {
00709 df_def_unlink (df, ref);
00710 df_ref_unlink (&df->insns[DF_REF_INSN_UID (ref)].defs, ref);
00711 }
00712 else
00713 {
00714 df_use_unlink (df, ref);
00715 df_ref_unlink (&df->insns[DF_REF_INSN_UID (ref)].uses, ref);
00716 }
00717 return 1;
00718 }
00719
00720
00721
00722 static void
00723 df_def_unlink (df, def)
00724 struct df *df ATTRIBUTE_UNUSED;
00725 struct ref *def;
00726 {
00727 struct df_link *du_link;
00728 unsigned int dregno = DF_REF_REGNO (def);
00729
00730
00731 for (du_link = DF_REF_CHAIN (def); du_link; du_link = du_link->next)
00732 {
00733 struct ref *use = du_link->ref;
00734
00735
00736 df_ref_unlink (&DF_REF_CHAIN (use), def);
00737 }
00738 DF_REF_CHAIN (def) = 0;
00739
00740
00741 df_ref_unlink (&df->regs[dregno].defs, def);
00742
00743 df->defs[DF_REF_ID (def)] = 0;
00744 }
00745
00746
00747
00748 static void
00749 df_use_unlink (df, use)
00750 struct df *df ATTRIBUTE_UNUSED;
00751 struct ref *use;
00752 {
00753 struct df_link *ud_link;
00754 unsigned int uregno = DF_REF_REGNO (use);
00755
00756
00757 for (ud_link = DF_REF_CHAIN (use); ud_link; ud_link = ud_link->next)
00758 {
00759 struct ref *def = ud_link->ref;
00760
00761
00762 df_ref_unlink (&DF_REF_CHAIN (def), use);
00763 }
00764 DF_REF_CHAIN (use) = 0;
00765
00766
00767 df_ref_unlink (&df->regs[uregno].uses, use);
00768
00769 df->uses[DF_REF_ID (use)] = 0;
00770 }
00771
00772
00773
00774
00775
00776
00777 static struct ref *
00778 df_ref_create (df, reg, loc, insn, ref_type, ref_flags)
00779 struct df *df;
00780 rtx reg;
00781 rtx *loc;
00782 rtx insn;
00783 enum df_ref_type ref_type;
00784 enum df_ref_flags ref_flags;
00785 {
00786 struct ref *this_ref;
00787 unsigned int uid;
00788
00789 this_ref = (struct ref *) obstack_alloc (&df_ref_obstack,
00790 sizeof (*this_ref));
00791 DF_REF_REG (this_ref) = reg;
00792 DF_REF_LOC (this_ref) = loc;
00793 DF_REF_INSN (this_ref) = insn;
00794 DF_REF_CHAIN (this_ref) = 0;
00795 DF_REF_TYPE (this_ref) = ref_type;
00796 DF_REF_FLAGS (this_ref) = ref_flags;
00797 uid = INSN_UID (insn);
00798
00799 if (ref_type == DF_REF_REG_DEF)
00800 {
00801 if (df->def_id >= df->def_size)
00802 {
00803
00804 df->def_size += (df->def_size / 4);
00805 df->defs = xrealloc (df->defs,
00806 df->def_size * sizeof (*df->defs));
00807 }
00808 DF_REF_ID (this_ref) = df->def_id;
00809 df->defs[df->def_id++] = this_ref;
00810 }
00811 else
00812 {
00813 if (df->use_id >= df->use_size)
00814 {
00815
00816 df->use_size += (df->use_size / 4);
00817 df->uses = xrealloc (df->uses,
00818 df->use_size * sizeof (*df->uses));
00819 }
00820 DF_REF_ID (this_ref) = df->use_id;
00821 df->uses[df->use_id++] = this_ref;
00822 }
00823 return this_ref;
00824 }
00825
00826
00827
00828
00829 static void
00830 df_ref_record_1 (df, reg, loc, insn, ref_type, ref_flags)
00831 struct df *df;
00832 rtx reg;
00833 rtx *loc;
00834 rtx insn;
00835 enum df_ref_type ref_type;
00836 enum df_ref_flags ref_flags;
00837 {
00838 df_ref_create (df, reg, loc, insn, ref_type, ref_flags);
00839 }
00840
00841
00842
00843
00844 static void
00845 df_ref_record (df, reg, loc, insn, ref_type, ref_flags)
00846 struct df *df;
00847 rtx reg;
00848 rtx *loc;
00849 rtx insn;
00850 enum df_ref_type ref_type;
00851 enum df_ref_flags ref_flags;
00852 {
00853 unsigned int regno;
00854
00855 if (GET_CODE (reg) != REG && GET_CODE (reg) != SUBREG)
00856 abort ();
00857
00858
00859
00860
00861
00862
00863 if (GET_CODE (reg) == SUBREG
00864 && (GET_MODE_SIZE (GET_MODE (reg)) < GET_MODE_SIZE (word_mode)
00865 || GET_MODE_SIZE (GET_MODE (reg))
00866 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (reg)))))
00867 {
00868 loc = &SUBREG_REG (reg);
00869 reg = *loc;
00870 }
00871
00872 regno = REGNO (GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg);
00873 if (regno < FIRST_PSEUDO_REGISTER)
00874 {
00875 int i;
00876 int endregno;
00877
00878 if (! (df->flags & DF_HARD_REGS))
00879 return;
00880
00881
00882
00883
00884
00885
00886 endregno = HARD_REGNO_NREGS (regno, GET_MODE (reg));
00887 if (GET_CODE (reg) == SUBREG)
00888 regno += subreg_regno_offset (regno, GET_MODE (SUBREG_REG (reg)),
00889 SUBREG_BYTE (reg), GET_MODE (reg));
00890 endregno += regno;
00891
00892 for (i = regno; i < endregno; i++)
00893 df_ref_record_1 (df, regno_reg_rtx[i],
00894 loc, insn, ref_type, ref_flags);
00895 }
00896 else
00897 {
00898 df_ref_record_1 (df, reg, loc, insn, ref_type, ref_flags);
00899 }
00900 }
00901
00902
00903
00904
00905 static inline bool
00906 read_modify_subreg_p (x)
00907 rtx x;
00908 {
00909 unsigned int isize, osize;
00910 if (GET_CODE (x) != SUBREG)
00911 return false;
00912 isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
00913 osize = GET_MODE_SIZE (GET_MODE (x));
00914 if (isize <= osize)
00915 return true;
00916 if (isize <= UNITS_PER_WORD)
00917 return false;
00918 if (osize >= UNITS_PER_WORD)
00919 return false;
00920 return true;
00921 }
00922
00923
00924 static void
00925 df_def_record_1 (df, x, bb, insn)
00926 struct df *df;
00927 rtx x;
00928 basic_block bb;
00929 rtx insn;
00930 {
00931 rtx *loc = &SET_DEST (x);
00932 rtx dst = *loc;
00933 enum df_ref_flags flags = 0;
00934
00935
00936
00937 if (GET_CODE (dst) == PARALLEL && GET_MODE (dst) == BLKmode)
00938 {
00939 int i;
00940
00941 for (i = XVECLEN (dst, 0) - 1; i >= 0; i--)
00942 df_def_record_1 (df, XVECEXP (dst, 0, i), bb, insn);
00943 return;
00944 }
00945
00946 #ifdef CLASS_CANNOT_CHANGE_MODE
00947 if (GET_CODE (dst) == SUBREG
00948 && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (dst)),
00949 GET_MODE (dst)))
00950 flags |= DF_REF_MODE_CHANGE;
00951 #endif
00952
00953
00954
00955 while (GET_CODE (dst) == STRICT_LOW_PART
00956 || GET_CODE (dst) == ZERO_EXTRACT
00957 || GET_CODE (dst) == SIGN_EXTRACT
00958 || read_modify_subreg_p (dst))
00959 {
00960
00961
00962 if (GET_CODE (dst) == STRICT_LOW_PART)
00963 {
00964 loc = &XEXP (dst, 0);
00965 dst = *loc;
00966 }
00967 #ifdef CLASS_CANNOT_CHANGE_MODE
00968 if (GET_CODE (dst) == SUBREG
00969 && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (dst)),
00970 GET_MODE (dst)))
00971 flags |= DF_REF_MODE_CHANGE;
00972 #endif
00973 loc = &XEXP (dst, 0);
00974 dst = *loc;
00975 flags |= DF_REF_READ_WRITE;
00976 }
00977
00978 if (GET_CODE (dst) == REG
00979 || (GET_CODE (dst) == SUBREG && GET_CODE (SUBREG_REG (dst)) == REG))
00980 df_ref_record (df, dst, loc, insn, DF_REF_REG_DEF, flags);
00981 }
00982
00983
00984
00985 static void
00986 df_defs_record (df, x, bb, insn)
00987 struct df *df;
00988 rtx x;
00989 basic_block bb;
00990 rtx insn;
00991 {
00992 RTX_CODE code = GET_CODE (x);
00993
00994 if (code == SET || code == CLOBBER)
00995 {
00996
00997 df_def_record_1 (df, x, bb, insn);
00998 }
00999 else if (code == PARALLEL)
01000 {
01001 int i;
01002
01003
01004 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
01005 {
01006 code = GET_CODE (XVECEXP (x, 0, i));
01007 if (code == SET || code == CLOBBER)
01008 df_def_record_1 (df, XVECEXP (x, 0, i), bb, insn);
01009 }
01010 }
01011 }
01012
01013
01014
01015 static void
01016 df_uses_record (df, loc, ref_type, bb, insn, flags)
01017 struct df *df;
01018 rtx *loc;
01019 enum df_ref_type ref_type;
01020 basic_block bb;
01021 rtx insn;
01022 enum df_ref_flags flags;
01023 {
01024 RTX_CODE code;
01025 rtx x;
01026 retry:
01027 x = *loc;
01028 if (!x)
01029 return;
01030 code = GET_CODE (x);
01031 switch (code)
01032 {
01033 case LABEL_REF:
01034 case SYMBOL_REF:
01035 case CONST_INT:
01036 case CONST:
01037 case CONST_DOUBLE:
01038 case CONST_VECTOR:
01039 case PC:
01040 case CC0:
01041 case ADDR_VEC:
01042 case ADDR_DIFF_VEC:
01043 return;
01044
01045 case CLOBBER:
01046
01047
01048 if (GET_CODE (XEXP (x, 0)) == MEM)
01049 df_uses_record (df, &XEXP (XEXP (x, 0), 0),
01050 DF_REF_REG_MEM_STORE, bb, insn, flags);
01051
01052
01053 return;
01054
01055 case MEM:
01056 df_uses_record (df, &XEXP (x, 0), DF_REF_REG_MEM_LOAD, bb, insn, flags);
01057 return;
01058
01059 case SUBREG:
01060
01061
01062
01063 if (GET_CODE (SUBREG_REG (x)) != REG)
01064 {
01065 loc = &SUBREG_REG (x);
01066 df_uses_record (df, loc, ref_type, bb, insn, flags);
01067 return;
01068 }
01069 #ifdef CLASS_CANNOT_CHANGE_MODE
01070 if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (x),
01071 GET_MODE (SUBREG_REG (x))))
01072 flags |= DF_REF_MODE_CHANGE;
01073 #endif
01074
01075
01076
01077 case REG:
01078
01079 df_ref_record (df, x, loc, insn, ref_type, flags);
01080 return;
01081
01082 case SET:
01083 {
01084 rtx dst = SET_DEST (x);
01085
01086 df_uses_record (df, &SET_SRC (x), DF_REF_REG_USE, bb, insn, 0);
01087
01088 switch (GET_CODE (dst))
01089 {
01090 enum df_ref_flags use_flags;
01091 case SUBREG:
01092 if (read_modify_subreg_p (dst))
01093 {
01094 use_flags = DF_REF_READ_WRITE;
01095 #ifdef CLASS_CANNOT_CHANGE_MODE
01096 if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst),
01097 GET_MODE (SUBREG_REG (dst))))
01098 use_flags |= DF_REF_MODE_CHANGE;
01099 #endif
01100 df_uses_record (df, &SUBREG_REG (dst), DF_REF_REG_USE, bb,
01101 insn, use_flags);
01102 break;
01103 }
01104
01105 case REG:
01106 case PARALLEL:
01107 case PC:
01108 case CC0:
01109 break;
01110 case MEM:
01111 df_uses_record (df, &XEXP (dst, 0),
01112 DF_REF_REG_MEM_STORE,
01113 bb, insn, 0);
01114 break;
01115 case STRICT_LOW_PART:
01116
01117 dst = XEXP (dst, 0);
01118 if (GET_CODE (dst) != SUBREG)
01119 abort ();
01120 use_flags = DF_REF_READ_WRITE;
01121 #ifdef CLASS_CANNOT_CHANGE_MODE
01122 if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst),
01123 GET_MODE (SUBREG_REG (dst))))
01124 use_flags |= DF_REF_MODE_CHANGE;
01125 #endif
01126 df_uses_record (df, &SUBREG_REG (dst), DF_REF_REG_USE, bb,
01127 insn, use_flags);
01128 break;
01129 case ZERO_EXTRACT:
01130 case SIGN_EXTRACT:
01131 df_uses_record (df, &XEXP (dst, 0), DF_REF_REG_USE, bb, insn,
01132 DF_REF_READ_WRITE);
01133 df_uses_record (df, &XEXP (dst, 1), DF_REF_REG_USE, bb, insn, 0);
01134 df_uses_record (df, &XEXP (dst, 2), DF_REF_REG_USE, bb, insn, 0);
01135 dst = XEXP (dst, 0);
01136 break;
01137 default:
01138 abort ();
01139 }
01140 return;
01141 }
01142
01143 case RETURN:
01144 break;
01145
01146 case ASM_OPERANDS:
01147 case UNSPEC_VOLATILE:
01148 case TRAP_IF:
01149 case ASM_INPUT:
01150 {
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166 if (code == ASM_OPERANDS)
01167 {
01168 int j;
01169
01170 for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
01171 df_uses_record (df, &ASM_OPERANDS_INPUT (x, j),
01172 DF_REF_REG_USE, bb, insn, 0);
01173 return;
01174 }
01175 break;
01176 }
01177
01178 case PRE_DEC:
01179 case POST_DEC:
01180 case PRE_INC:
01181 case POST_INC:
01182 case PRE_MODIFY:
01183 case POST_MODIFY:
01184
01185 df_ref_record (df, XEXP (x, 0), &XEXP (x, 0), insn, DF_REF_REG_DEF, DF_REF_READ_WRITE);
01186
01187
01188
01189 default:
01190 break;
01191 }
01192
01193
01194 {
01195 const char *fmt = GET_RTX_FORMAT (code);
01196 int i;
01197
01198 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
01199 {
01200 if (fmt[i] == 'e')
01201 {
01202
01203 if (i == 0)
01204 {
01205 loc = &XEXP (x, 0);
01206 goto retry;
01207 }
01208 df_uses_record (df, &XEXP (x, i), ref_type, bb, insn, flags);
01209 }
01210 else if (fmt[i] == 'E')
01211 {
01212 int j;
01213 for (j = 0; j < XVECLEN (x, i); j++)
01214 df_uses_record (df, &XVECEXP (x, i, j), ref_type,
01215 bb, insn, flags);
01216 }
01217 }
01218 }
01219 }
01220
01221
01222
01223 static void
01224 df_insn_refs_record (df, bb, insn)
01225 struct df *df;
01226 basic_block bb;
01227 rtx insn;
01228 {
01229 int i;
01230
01231 if (INSN_P (insn))
01232 {
01233 rtx note;
01234
01235
01236 df_defs_record (df, PATTERN (insn), bb, insn);
01237
01238 if (df->flags & DF_EQUIV_NOTES)
01239 for (note = REG_NOTES (insn); note;
01240 note = XEXP (note, 1))
01241 {
01242 switch (REG_NOTE_KIND (note))
01243 {
01244 case REG_EQUIV:
01245 case REG_EQUAL:
01246 df_uses_record (df, &XEXP (note, 0), DF_REF_REG_USE,
01247 bb, insn, 0);
01248 default:
01249 break;
01250 }
01251 }
01252
01253 if (GET_CODE (insn) == CALL_INSN)
01254 {
01255 rtx note;
01256 rtx x;
01257
01258
01259 for (note = CALL_INSN_FUNCTION_USAGE (insn); note;
01260 note = XEXP (note, 1))
01261 {
01262 if (GET_CODE (XEXP (note, 0)) == USE)
01263 df_uses_record (df, &XEXP (XEXP (note, 0), 0), DF_REF_REG_USE,
01264 bb, insn, 0);
01265 }
01266
01267
01268 x = df_reg_use_gen (STACK_POINTER_REGNUM);
01269 df_uses_record (df, &XEXP (x, 0), DF_REF_REG_USE, bb, insn, 0);
01270
01271 if (df->flags & DF_HARD_REGS)
01272 {
01273
01274
01275 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01276 if (global_regs[i])
01277 {
01278 x = df_reg_use_gen (i);
01279 df_uses_record (df, &SET_DEST (x),
01280 DF_REF_REG_USE, bb, insn, 0);
01281 }
01282 }
01283 }
01284
01285
01286 df_uses_record (df, &PATTERN (insn),
01287 DF_REF_REG_USE, bb, insn, 0);
01288
01289
01290 if (GET_CODE (insn) == CALL_INSN)
01291 {
01292 rtx note;
01293
01294 if (df->flags & DF_HARD_REGS)
01295 {
01296
01297 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01298 if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
01299 {
01300 rtx reg_clob = df_reg_clobber_gen (i);
01301 df_defs_record (df, reg_clob, bb, insn);
01302 }
01303 }
01304
01305
01306 for (note = CALL_INSN_FUNCTION_USAGE (insn);
01307 note;
01308 note = XEXP (note, 1))
01309 if (GET_CODE (XEXP (note, 0)) == CLOBBER)
01310 df_defs_record (df, XEXP (note, 0), bb, insn);
01311 }
01312 }
01313 }
01314
01315
01316
01317 static void
01318 df_bb_refs_record (df, bb)
01319 struct df *df;
01320 basic_block bb;
01321 {
01322 rtx insn;
01323
01324
01325 for (insn = bb->head; ; insn = NEXT_INSN (insn))
01326 {
01327 if (INSN_P (insn))
01328 {
01329
01330 df_insn_refs_record (df, bb, insn);
01331 }
01332 if (insn == bb->end)
01333 break;
01334 }
01335 }
01336
01337
01338
01339 static void
01340 df_refs_record (df, blocks)
01341 struct df *df;
01342 bitmap blocks;
01343 {
01344 basic_block bb;
01345
01346 FOR_EACH_BB_IN_BITMAP (blocks, 0, bb,
01347 {
01348 df_bb_refs_record (df, bb);
01349 });
01350 }
01351
01352
01353
01354
01355
01356
01357 static void
01358 df_bb_reg_def_chain_create (df, bb)
01359 struct df *df;
01360 basic_block bb;
01361 {
01362 rtx insn;
01363
01364
01365
01366
01367
01368
01369 for (insn = bb->end; insn && insn != PREV_INSN (bb->head);
01370 insn = PREV_INSN (insn))
01371 {
01372 struct df_link *link;
01373 unsigned int uid = INSN_UID (insn);
01374
01375 if (! INSN_P (insn))
01376 continue;
01377
01378 for (link = df->insns[uid].defs; link; link = link->next)
01379 {
01380 struct ref *def = link->ref;
01381 unsigned int dregno = DF_REF_REGNO (def);
01382
01383
01384
01385 if (DF_REF_ID (def) < df->def_id_save)
01386 continue;
01387
01388 df->regs[dregno].defs
01389 = df_link_create (def, df->regs[dregno].defs);
01390 }
01391 }
01392 }
01393
01394
01395
01396
01397 static void
01398 df_reg_def_chain_create (df, blocks)
01399 struct df *df;
01400 bitmap blocks;
01401 {
01402 basic_block bb;
01403
01404 FOR_EACH_BB_IN_BITMAP (blocks, 0, bb,
01405 {
01406 df_bb_reg_def_chain_create (df, bb);
01407 });
01408 }
01409
01410
01411
01412
01413 static void
01414 df_bb_reg_use_chain_create (df, bb)
01415 struct df *df;
01416 basic_block bb;
01417 {
01418 rtx insn;
01419
01420
01421
01422
01423 for (insn = bb->head; insn && insn != NEXT_INSN (bb->end);
01424 insn = NEXT_INSN (insn))
01425 {
01426 struct df_link *link;
01427 unsigned int uid = INSN_UID (insn);
01428
01429 if (! INSN_P (insn))
01430 continue;
01431
01432 for (link = df->insns[uid].uses; link; link = link->next)
01433 {
01434 struct ref *use = link->ref;
01435 unsigned int uregno = DF_REF_REGNO (use);
01436
01437
01438
01439 if (DF_REF_ID (use) < df->use_id_save)
01440 continue;
01441
01442 df->regs[uregno].uses
01443 = df_link_create (use, df->regs[uregno].uses);
01444 }
01445 }
01446 }
01447
01448
01449
01450
01451 static void
01452 df_reg_use_chain_create (df, blocks)
01453 struct df *df;
01454 bitmap blocks;
01455 {
01456 basic_block bb;
01457
01458 FOR_EACH_BB_IN_BITMAP (blocks, 0, bb,
01459 {
01460 df_bb_reg_use_chain_create (df, bb);
01461 });
01462 }
01463
01464
01465
01466 static void
01467 df_bb_du_chain_create (df, bb, ru)
01468 struct df *df;
01469 basic_block bb;
01470 bitmap ru;
01471 {
01472 struct bb_info *bb_info = DF_BB_INFO (df, bb);
01473 rtx insn;
01474
01475 bitmap_copy (ru, bb_info->ru_out);
01476
01477
01478
01479 for (insn = bb->end; insn && insn != PREV_INSN (bb->head);
01480 insn = PREV_INSN (insn))
01481 {
01482 struct df_link *def_link;
01483 struct df_link *use_link;
01484 unsigned int uid = INSN_UID (insn);
01485
01486 if (! INSN_P (insn))
01487 continue;
01488
01489
01490 for (def_link = df->insns[uid].defs; def_link; def_link = def_link->next)
01491 {
01492 struct ref *def = def_link->ref;
01493 unsigned int dregno = DF_REF_REGNO (def);
01494
01495 DF_REF_CHAIN (def) = 0;
01496
01497
01498
01499
01500 for (use_link = df->regs[dregno].uses; use_link;
01501 use_link = use_link->next)
01502 {
01503 struct ref *use = use_link->ref;
01504
01505 if (bitmap_bit_p (ru, DF_REF_ID (use)))
01506 {
01507 DF_REF_CHAIN (def)
01508 = df_link_create (use, DF_REF_CHAIN (def));
01509
01510 bitmap_clear_bit (ru, DF_REF_ID (use));
01511 }
01512 }
01513 }
01514
01515
01516 for (use_link = df->insns[uid].uses; use_link; use_link = use_link->next)
01517 {
01518 struct ref *use = use_link->ref;
01519 bitmap_set_bit (ru, DF_REF_ID (use));
01520 }
01521 }
01522 }
01523
01524
01525
01526
01527 static void
01528 df_du_chain_create (df, blocks)
01529 struct df *df;
01530 bitmap blocks;
01531 {
01532 bitmap ru;
01533 basic_block bb;
01534
01535 ru = BITMAP_XMALLOC ();
01536
01537 FOR_EACH_BB_IN_BITMAP (blocks, 0, bb,
01538 {
01539 df_bb_du_chain_create (df, bb, ru);
01540 });
01541
01542 BITMAP_XFREE (ru);
01543 }
01544
01545
01546
01547 static void
01548 df_bb_ud_chain_create (df, bb)
01549 struct df *df;
01550 basic_block bb;
01551 {
01552 struct bb_info *bb_info = DF_BB_INFO (df, bb);
01553 struct ref **reg_def_last = df->reg_def_last;
01554 rtx insn;
01555
01556 memset (reg_def_last, 0, df->n_regs * sizeof (struct ref *));
01557
01558
01559
01560 for (insn = bb->head; insn && insn != NEXT_INSN (bb->end);
01561 insn = NEXT_INSN (insn))
01562 {
01563 unsigned int uid = INSN_UID (insn);
01564 struct df_link *use_link;
01565 struct df_link *def_link;
01566
01567 if (! INSN_P (insn))
01568 continue;
01569
01570
01571 for (use_link = df->insns[uid].uses; use_link; use_link = use_link->next)
01572 {
01573 struct ref *use = use_link->ref;
01574 unsigned int regno = DF_REF_REGNO (use);
01575
01576 DF_REF_CHAIN (use) = 0;
01577
01578
01579
01580
01581
01582
01583 if (reg_def_last[regno])
01584 {
01585 DF_REF_CHAIN (use)
01586 = df_link_create (reg_def_last[regno], 0);
01587 }
01588 else
01589 {
01590
01591
01592
01593
01594 for (def_link = df->regs[regno].defs; def_link;
01595 def_link = def_link->next)
01596 {
01597 struct ref *def = def_link->ref;
01598
01599 if (bitmap_bit_p (bb_info->rd_in, DF_REF_ID (def)))
01600 {
01601 DF_REF_CHAIN (use)
01602 = df_link_create (def, DF_REF_CHAIN (use));
01603 }
01604 }
01605 }
01606 }
01607
01608
01609
01610 for (def_link = df->insns[uid].defs; def_link; def_link = def_link->next)
01611 {
01612 struct ref *def = def_link->ref;
01613 int dregno = DF_REF_REGNO (def);
01614
01615 reg_def_last[dregno] = def;
01616 }
01617 }
01618 }
01619
01620
01621
01622
01623 static void
01624 df_ud_chain_create (df, blocks)
01625 struct df *df;
01626 bitmap blocks;
01627 {
01628 basic_block bb;
01629
01630 FOR_EACH_BB_IN_BITMAP (blocks, 0, bb,
01631 {
01632 df_bb_ud_chain_create (df, bb);
01633 });
01634 }
01635
01636
01637
01638 static void
01639 df_rd_transfer_function (bb, changed, in, out, gen, kill, data)
01640 int bb ATTRIBUTE_UNUSED;
01641 int *changed;
01642 bitmap in, out, gen, kill;
01643 void *data ATTRIBUTE_UNUSED;
01644 {
01645 *changed = bitmap_union_of_diff (out, gen, in, kill);
01646 }
01647 static void
01648 df_ru_transfer_function (bb, changed, in, out, gen, kill, data)
01649 int bb ATTRIBUTE_UNUSED;
01650 int *changed;
01651 bitmap in, out, gen, kill;
01652 void *data ATTRIBUTE_UNUSED;
01653 {
01654 *changed = bitmap_union_of_diff (in, gen, out, kill);
01655 }
01656
01657 static void
01658 df_lr_transfer_function (bb, changed, in, out, use, def, data)
01659 int bb ATTRIBUTE_UNUSED;
01660 int *changed;
01661 bitmap in, out, use, def;
01662 void *data ATTRIBUTE_UNUSED;
01663 {
01664 *changed = bitmap_union_of_diff (in, use, out, def);
01665 }
01666
01667
01668
01669 static void
01670 df_bb_rd_local_compute (df, bb)
01671 struct df *df;
01672 basic_block bb;
01673 {
01674 struct bb_info *bb_info = DF_BB_INFO (df, bb);
01675 rtx insn;
01676
01677 for (insn = bb->head; insn && insn != NEXT_INSN (bb->end);
01678 insn = NEXT_INSN (insn))
01679 {
01680 unsigned int uid = INSN_UID (insn);
01681 struct df_link *def_link;
01682
01683 if (! INSN_P (insn))
01684 continue;
01685
01686 for (def_link = df->insns[uid].defs; def_link; def_link = def_link->next)
01687 {
01688 struct ref *def = def_link->ref;
01689 unsigned int regno = DF_REF_REGNO (def);
01690 struct df_link *def2_link;
01691
01692 for (def2_link = df->regs[regno].defs; def2_link;
01693 def2_link = def2_link->next)
01694 {
01695 struct ref *def2 = def2_link->ref;
01696
01697
01698
01699
01700
01701 bitmap_set_bit (bb_info->rd_kill, DF_REF_ID (def2));
01702
01703
01704 bitmap_clear_bit (bb_info->rd_gen, DF_REF_ID (def2));
01705 }
01706
01707 bitmap_set_bit (bb_info->rd_gen, DF_REF_ID (def));
01708 }
01709 }
01710
01711 bb_info->rd_valid = 1;
01712 }
01713
01714
01715
01716 static void
01717 df_rd_local_compute (df, blocks)
01718 struct df *df;
01719 bitmap blocks;
01720 {
01721 basic_block bb;
01722
01723 FOR_EACH_BB_IN_BITMAP (blocks, 0, bb,
01724 {
01725 df_bb_rd_local_compute (df, bb);
01726 });
01727 }
01728
01729
01730
01731
01732 static void
01733 df_bb_ru_local_compute (df, bb)
01734 struct df *df;
01735 basic_block bb;
01736 {
01737
01738
01739
01740
01741 struct bb_info *bb_info = DF_BB_INFO (df, bb);
01742 rtx insn;
01743
01744
01745 for (insn = bb->end; insn && insn != PREV_INSN (bb->head);
01746 insn = PREV_INSN (insn))
01747 {
01748 unsigned int uid = INSN_UID (insn);
01749 struct df_link *def_link;
01750 struct df_link *use_link;
01751
01752 if (! INSN_P (insn))
01753 continue;
01754
01755 for (def_link = df->insns[uid].defs; def_link; def_link = def_link->next)
01756 {
01757 struct ref *def = def_link->ref;
01758 unsigned int dregno = DF_REF_REGNO (def);
01759
01760 for (use_link = df->regs[dregno].uses; use_link;
01761 use_link = use_link->next)
01762 {
01763 struct ref *use = use_link->ref;
01764
01765
01766
01767
01768
01769 bitmap_set_bit (bb_info->ru_kill, DF_REF_ID (use));
01770
01771
01772 bitmap_clear_bit (bb_info->ru_gen, DF_REF_ID (use));
01773 }
01774 }
01775
01776 for (use_link = df->insns[uid].uses; use_link; use_link = use_link->next)
01777 {
01778 struct ref *use = use_link->ref;
01779
01780 bitmap_set_bit (bb_info->ru_gen, DF_REF_ID (use));
01781 }
01782 }
01783 bb_info->ru_valid = 1;
01784 }
01785
01786
01787
01788
01789 static void
01790 df_ru_local_compute (df, blocks)
01791 struct df *df;
01792 bitmap blocks;
01793 {
01794 basic_block bb;
01795
01796 FOR_EACH_BB_IN_BITMAP (blocks, 0, bb,
01797 {
01798 df_bb_ru_local_compute (df, bb);
01799 });
01800 }
01801
01802
01803
01804 static void
01805 df_bb_lr_local_compute (df, bb)
01806 struct df *df;
01807 basic_block bb;
01808 {
01809 struct bb_info *bb_info = DF_BB_INFO (df, bb);
01810 rtx insn;
01811
01812 for (insn = bb->end; insn && insn != PREV_INSN (bb->head);
01813 insn = PREV_INSN (insn))
01814 {
01815 unsigned int uid = INSN_UID (insn);
01816 struct df_link *link;
01817
01818 if (! INSN_P (insn))
01819 continue;
01820
01821 for (link = df->insns[uid].defs; link; link = link->next)
01822 {
01823 struct ref *def = link->ref;
01824 unsigned int dregno = DF_REF_REGNO (def);
01825
01826
01827 bitmap_set_bit (bb_info->lr_def, dregno);
01828
01829 bitmap_clear_bit (bb_info->lr_use, dregno);
01830 }
01831
01832 for (link = df->insns[uid].uses; link; link = link->next)
01833 {
01834 struct ref *use = link->ref;
01835
01836 bitmap_set_bit (bb_info->lr_use, DF_REF_REGNO (use));
01837 }
01838 }
01839 bb_info->lr_valid = 1;
01840 }
01841
01842
01843
01844 static void
01845 df_lr_local_compute (df, blocks)
01846 struct df *df;
01847 bitmap blocks;
01848 {
01849 basic_block bb;
01850
01851 FOR_EACH_BB_IN_BITMAP (blocks, 0, bb,
01852 {
01853 df_bb_lr_local_compute (df, bb);
01854 });
01855 }
01856
01857
01858
01859
01860 static void
01861 df_bb_reg_info_compute (df, bb, live)
01862 struct df *df;
01863 basic_block bb;
01864 bitmap live;
01865 {
01866 struct reg_info *reg_info = df->regs;
01867 struct bb_info *bb_info = DF_BB_INFO (df, bb);
01868 rtx insn;
01869
01870 bitmap_copy (live, bb_info->lr_out);
01871
01872 for (insn = bb->end; insn && insn != PREV_INSN (bb->head);
01873 insn = PREV_INSN (insn))
01874 {
01875 unsigned int uid = INSN_UID (insn);
01876 unsigned int regno;
01877 struct df_link *link;
01878
01879 if (! INSN_P (insn))
01880 continue;
01881
01882 for (link = df->insns[uid].defs; link; link = link->next)
01883 {
01884 struct ref *def = link->ref;
01885 unsigned int dregno = DF_REF_REGNO (def);
01886
01887
01888 bitmap_clear_bit (live, dregno);
01889 reg_info[dregno].n_defs++;
01890 }
01891
01892 for (link = df->insns[uid].uses; link; link = link->next)
01893 {
01894 struct ref *use = link->ref;
01895 unsigned int uregno = DF_REF_REGNO (use);
01896
01897
01898 bitmap_set_bit (live, uregno);
01899 reg_info[uregno].n_uses++;
01900 }
01901
01902
01903 EXECUTE_IF_SET_IN_BITMAP (live, 0, regno,
01904 {
01905 reg_info[regno].lifetime++;
01906 });
01907 }
01908 }
01909
01910
01911
01912 static void
01913 df_reg_info_compute (df, blocks)
01914 struct df *df;
01915 bitmap blocks;
01916 {
01917 basic_block bb;
01918 bitmap live;
01919
01920 live = BITMAP_XMALLOC ();
01921
01922 FOR_EACH_BB_IN_BITMAP (blocks, 0, bb,
01923 {
01924 df_bb_reg_info_compute (df, bb, live);
01925 });
01926
01927 BITMAP_XFREE (live);
01928 }
01929
01930
01931
01932 static int
01933 df_bb_luids_set (df, bb)
01934 struct df *df;
01935 basic_block bb;
01936 {
01937 rtx insn;
01938 int luid = 0;
01939
01940
01941
01942 for (insn = bb->head; ; insn = NEXT_INSN (insn))
01943 {
01944 if (INSN_P (insn))
01945 DF_INSN_LUID (df, insn) = luid++;
01946 DF_INSN_LUID (df, insn) = luid;
01947
01948 if (insn == bb->end)
01949 break;
01950 }
01951 return luid;
01952 }
01953
01954
01955
01956 static int
01957 df_luids_set (df, blocks)
01958 struct df *df;
01959 bitmap blocks;
01960 {
01961 basic_block bb;
01962 int total = 0;
01963
01964 FOR_EACH_BB_IN_BITMAP (blocks, 0, bb,
01965 {
01966 total += df_bb_luids_set (df, bb);
01967 });
01968 return total;
01969 }
01970
01971
01972
01973 static void
01974 df_analyse_1 (df, blocks, flags, update)
01975 struct df *df;
01976 bitmap blocks;
01977 int flags;
01978 int update;
01979 {
01980 int aflags;
01981 int dflags;
01982 int i;
01983 basic_block bb;
01984
01985 dflags = 0;
01986 aflags = flags;
01987 if (flags & DF_UD_CHAIN)
01988 aflags |= DF_RD | DF_RD_CHAIN;
01989
01990 if (flags & DF_DU_CHAIN)
01991 aflags |= DF_RU;
01992
01993 if (flags & DF_RU)
01994 aflags |= DF_RU_CHAIN;
01995
01996 if (flags & DF_REG_INFO)
01997 aflags |= DF_LR;
01998
01999 if (! blocks)
02000 blocks = df->all_blocks;
02001
02002 df->flags = flags;
02003 if (update)
02004 {
02005 df_refs_update (df);
02006
02007
02008
02009 #if 0
02010 df_refs_unlink (df, blocks);
02011 #endif
02012
02013
02014
02015 }
02016 else
02017 {
02018
02019 df_refs_queue (df);
02020 df_refs_record (df, blocks);
02021
02022
02023 df_refs_process (df);
02024 }
02025
02026
02027
02028
02029 df_bitmaps_alloc (df, aflags);
02030
02031
02032 df_luids_set (df, blocks);
02033
02034
02035
02036
02037
02038 if (aflags & DF_RD_CHAIN)
02039 {
02040 df_reg_def_chain_create (df, blocks);
02041 }
02042
02043 if (aflags & DF_RU_CHAIN)
02044 {
02045 df_reg_use_chain_create (df, blocks);
02046 }
02047
02048 df->dfs_order = xmalloc (sizeof (int) * n_basic_blocks);
02049 df->rc_order = xmalloc (sizeof (int) * n_basic_blocks);
02050 df->rts_order = xmalloc (sizeof (int) * n_basic_blocks);
02051 df->inverse_dfs_map = xmalloc (sizeof (int) * last_basic_block);
02052 df->inverse_rc_map = xmalloc (sizeof (int) * last_basic_block);
02053 df->inverse_rts_map = xmalloc (sizeof (int) * last_basic_block);
02054
02055 flow_depth_first_order_compute (df->dfs_order, df->rc_order);
02056 flow_reverse_top_sort_order_compute (df->rts_order);
02057 for (i = 0; i < n_basic_blocks; i++)
02058 {
02059 df->inverse_dfs_map[df->dfs_order[i]] = i;
02060 df->inverse_rc_map[df->rc_order[i]] = i;
02061 df->inverse_rts_map[df->rts_order[i]] = i;
02062 }
02063 if (aflags & DF_RD)
02064 {
02065
02066 df_rd_local_compute (df, df->flags & DF_RD ? blocks : df->all_blocks);
02067 {
02068 bitmap *in = xmalloc (sizeof (bitmap) * last_basic_block);
02069 bitmap *out = xmalloc (sizeof (bitmap) * last_basic_block);
02070 bitmap *gen = xmalloc (sizeof (bitmap) * last_basic_block);
02071 bitmap *kill = xmalloc (sizeof (bitmap) * last_basic_block);
02072 FOR_EACH_BB (bb)
02073 {
02074 in[bb->index] = DF_BB_INFO (df, bb)->rd_in;
02075 out[bb->index] = DF_BB_INFO (df, bb)->rd_out;
02076 gen[bb->index] = DF_BB_INFO (df, bb)->rd_gen;
02077 kill[bb->index] = DF_BB_INFO (df, bb)->rd_kill;
02078 }
02079 iterative_dataflow_bitmap (in, out, gen, kill, df->all_blocks,
02080 FORWARD, UNION, df_rd_transfer_function,
02081 df->inverse_rc_map, NULL);
02082 free (in);
02083 free (out);
02084 free (gen);
02085 free (kill);
02086 }
02087 }
02088
02089 if (aflags & DF_UD_CHAIN)
02090 {
02091
02092 df_ud_chain_create (df, df->all_blocks);
02093
02094 if (! (flags & DF_RD))
02095 dflags |= DF_RD;
02096 }
02097
02098 if (aflags & DF_RU)
02099 {
02100
02101
02102 df_ru_local_compute (df, df->flags & DF_RU ? blocks : df->all_blocks);
02103 {
02104 bitmap *in = xmalloc (sizeof (bitmap) * last_basic_block);
02105 bitmap *out = xmalloc (sizeof (bitmap) * last_basic_block);
02106 bitmap *gen = xmalloc (sizeof (bitmap) * last_basic_block);
02107 bitmap *kill = xmalloc (sizeof (bitmap) * last_basic_block);
02108 FOR_EACH_BB (bb)
02109 {
02110 in[bb->index] = DF_BB_INFO (df, bb)->ru_in;
02111 out[bb->index] = DF_BB_INFO (df, bb)->ru_out;
02112 gen[bb->index] = DF_BB_INFO (df, bb)->ru_gen;
02113 kill[bb->index] = DF_BB_INFO (df, bb)->ru_kill;
02114 }
02115 iterative_dataflow_bitmap (in, out, gen, kill, df->all_blocks,
02116 BACKWARD, UNION, df_ru_transfer_function,
02117 df->inverse_rts_map, NULL);
02118 free (in);
02119 free (out);
02120 free (gen);
02121 free (kill);
02122 }
02123 }
02124
02125 if (aflags & DF_DU_CHAIN)
02126 {
02127
02128 df_du_chain_create (df, df->all_blocks);
02129
02130 if (! (flags & DF_RU))
02131 dflags |= DF_RU;
02132 }
02133
02134
02135 if (dflags)
02136 df_bitmaps_free (df, dflags);
02137
02138 if (aflags & DF_LR)
02139 {
02140
02141 df_lr_local_compute (df, df->flags & DF_LR ? blocks : df->all_blocks);
02142 {
02143 bitmap *in = xmalloc (sizeof (bitmap) * last_basic_block);
02144 bitmap *out = xmalloc (sizeof (bitmap) * last_basic_block);
02145 bitmap *use = xmalloc (sizeof (bitmap) * last_basic_block);
02146 bitmap *def = xmalloc (sizeof (bitmap) * last_basic_block);
02147 FOR_EACH_BB (bb)
02148 {
02149 in[bb->index] = DF_BB_INFO (df, bb)->lr_in;
02150 out[bb->index] = DF_BB_INFO (df, bb)->lr_out;
02151 use[bb->index] = DF_BB_INFO (df, bb)->lr_use;
02152 def[bb->index] = DF_BB_INFO (df, bb)->lr_def;
02153 }
02154 iterative_dataflow_bitmap (in, out, use, def, df->all_blocks,
02155 BACKWARD, UNION, df_lr_transfer_function,
02156 df->inverse_rts_map, NULL);
02157 free (in);
02158 free (out);
02159 free (use);
02160 free (def);
02161 }
02162 }
02163
02164 if (aflags & DF_REG_INFO)
02165 {
02166 df_reg_info_compute (df, df->all_blocks);
02167 }
02168 free (df->dfs_order);
02169 free (df->rc_order);
02170 free (df->rts_order);
02171 free (df->inverse_rc_map);
02172 free (df->inverse_dfs_map);
02173 free (df->inverse_rts_map);
02174 }
02175
02176
02177
02178 struct df *
02179 df_init ()
02180 {
02181 struct df *df;
02182
02183 df = xcalloc (1, sizeof (struct df));
02184
02185
02186 ddf = df;
02187
02188 return df;
02189 }
02190
02191
02192
02193 static int
02194 df_refs_queue (df)
02195 struct df *df;
02196 {
02197 df->def_id_save = df->def_id;
02198 df->use_id_save = df->use_id;
02199
02200
02201 return 0;
02202 }
02203
02204
02205
02206 static int
02207 df_refs_process (df)
02208 struct df *df;
02209 {
02210 unsigned int i;
02211
02212
02213 for (i = df->def_id_save; i != df->def_id; i++)
02214 {
02215 struct ref *def = df->defs[i];
02216 unsigned int uid = DF_REF_INSN_UID (def);
02217
02218
02219 df->insns[uid].defs
02220 = df_link_create (def, df->insns[uid].defs);
02221 }
02222
02223
02224 for (i = df->use_id_save; i != df->use_id; i++)
02225 {
02226 struct ref *use = df->uses[i];
02227 unsigned int uid = DF_REF_INSN_UID (use);
02228
02229
02230 df->insns[uid].uses
02231 = df_link_create (use, df->insns[uid].uses);
02232 }
02233 return 0;
02234 }
02235
02236
02237
02238 static int
02239 df_bb_refs_update (df, bb)
02240 struct df *df;
02241 basic_block bb;
02242 {
02243 rtx insn;
02244 int count = 0;
02245
02246
02247
02248
02249
02250
02251 for (insn = bb->head; ; insn = NEXT_INSN (insn))
02252 {
02253 unsigned int uid;
02254
02255 uid = INSN_UID (insn);
02256
02257 if (bitmap_bit_p (df->insns_modified, uid))
02258 {
02259
02260 df_insn_refs_unlink (df, bb, insn);
02261
02262
02263 df_insn_refs_record (df, bb, insn);
02264
02265 count++;
02266 }
02267 if (insn == bb->end)
02268 break;
02269 }
02270 return count;
02271 }
02272
02273
02274
02275 static int
02276 df_refs_update (df)
02277 struct df *df;
02278 {
02279 basic_block bb;
02280 int count = 0;
02281
02282 if ((unsigned int) max_reg_num () >= df->reg_size)
02283 df_reg_table_realloc (df, 0);
02284
02285 df_refs_queue (df);
02286
02287 FOR_EACH_BB_IN_BITMAP (df->bbs_modified, 0, bb,
02288 {
02289 count += df_bb_refs_update (df, bb);
02290 });
02291
02292 df_refs_process (df);
02293 return count;
02294 }
02295
02296
02297
02298
02299 static int
02300 df_modified_p (df, blocks)
02301 struct df *df;
02302 bitmap blocks;
02303 {
02304 int update = 0;
02305 basic_block bb;
02306
02307 if (!df->n_bbs)
02308 return 0;
02309
02310 FOR_EACH_BB (bb)
02311 if (bitmap_bit_p (df->bbs_modified, bb->index)
02312 && (! blocks || (blocks == (bitmap) -1) || bitmap_bit_p (blocks, bb->index)))
02313 {
02314 update = 1;
02315 break;
02316 }
02317
02318 return update;
02319 }
02320
02321
02322
02323
02324
02325 int
02326 df_analyse (df, blocks, flags)
02327 struct df *df;
02328 bitmap blocks;
02329 int flags;
02330 {
02331 int update;
02332
02333
02334
02335 if (df->n_bbs && df->n_bbs != (unsigned int) last_basic_block)
02336 abort ();
02337
02338 update = df_modified_p (df, blocks);
02339 if (update || (flags != df->flags))
02340 {
02341 if (! blocks)
02342 {
02343 if (df->n_bbs)
02344 {
02345
02346 df_free (df);
02347 }
02348
02349 df_alloc (df, max_reg_num ());
02350 df_analyse_1 (df, 0, flags, 0);
02351 update = 1;
02352 }
02353 else
02354 {
02355 if (blocks == (bitmap) -1)
02356 blocks = df->bbs_modified;
02357
02358 if (! df->n_bbs)
02359 abort ();
02360
02361 df_analyse_1 (df, blocks, flags, 1);
02362 bitmap_zero (df->bbs_modified);
02363 bitmap_zero (df->insns_modified);
02364 }
02365 }
02366 return update;
02367 }
02368
02369
02370
02371 void
02372 df_finish (df)
02373 struct df *df;
02374 {
02375 df_free (df);
02376 free (df);
02377 }
02378
02379
02380
02381 static void
02382 df_insn_refs_unlink (df, bb, insn)
02383 struct df *df;
02384 basic_block bb ATTRIBUTE_UNUSED;
02385 rtx insn;
02386 {
02387 struct df_link *link;
02388 unsigned int uid;
02389
02390 uid = INSN_UID (insn);
02391
02392
02393 for (link = df->insns[uid].defs; link; link = link->next)
02394 df_def_unlink (df, link->ref);
02395
02396
02397 for (link = df->insns[uid].uses; link; link = link->next)
02398 df_use_unlink (df, link->ref);
02399
02400 df->insns[uid].defs = 0;
02401 df->insns[uid].uses = 0;
02402 }
02403
02404
02405 #if 0
02406
02407 static void
02408 df_bb_refs_unlink (df, bb)
02409 struct df *df;
02410 basic_block bb;
02411 {
02412 rtx insn;
02413
02414
02415 for (insn = bb->head; ; insn = NEXT_INSN (insn))
02416 {
02417 if (INSN_P (insn))
02418 {
02419
02420 df_insn_refs_unlink (df, bb, insn);
02421 }
02422 if (insn == bb->end)
02423 break;
02424 }
02425 }
02426
02427
02428
02429
02430 static void
02431 df_refs_unlink (df, blocks)
02432 struct df *df;
02433 bitmap blocks;
02434 {
02435 basic_block bb;
02436
02437 if (blocks)
02438 {
02439 FOR_EACH_BB_IN_BITMAP (blocks, 0, bb,
02440 {
02441 df_bb_refs_unlink (df, bb);
02442 });
02443 }
02444 else
02445 {
02446 FOR_EACH_BB (bb)
02447 df_bb_refs_unlink (df, bb);
02448 }
02449 }
02450 #endif
02451
02452
02453
02454
02455
02456 rtx
02457 df_insn_delete (df, bb, insn)
02458 struct df *df;
02459 basic_block bb ATTRIBUTE_UNUSED;
02460 rtx insn;
02461 {
02462
02463
02464
02465
02466 if (insn == bb->head)
02467 abort ();
02468
02469
02470 delete_insn (insn);
02471
02472 df_insn_modify (df, bb, insn);
02473
02474 return NEXT_INSN (insn);
02475 }
02476
02477
02478
02479
02480
02481
02482 void
02483 df_insn_modify (df, bb, insn)
02484 struct df *df;
02485 basic_block bb;
02486 rtx insn;
02487 {
02488 unsigned int uid;
02489
02490 uid = INSN_UID (insn);
02491 if (uid >= df->insn_size)
02492 df_insn_table_realloc (df, uid);
02493
02494 bitmap_set_bit (df->bbs_modified, bb->index);
02495 bitmap_set_bit (df->insns_modified, uid);
02496
02497
02498
02499
02500
02501
02502 }
02503
02504
02505 typedef struct replace_args {
02506 rtx match;
02507 rtx replacement;
02508 rtx insn;
02509 int modified;
02510 } replace_args;
02511
02512
02513
02514
02515
02516
02517 static int
02518 df_rtx_mem_replace (px, data)
02519 rtx *px;
02520 void *data;
02521 {
02522 replace_args *args = (replace_args *) data;
02523 rtx mem = *px;
02524
02525 if (mem == NULL_RTX)
02526 return 0;
02527
02528 switch (GET_CODE (mem))
02529 {
02530 case MEM:
02531 break;
02532
02533 case CONST_DOUBLE:
02534
02535
02536 return -1;
02537
02538 default:
02539
02540 return 0;
02541 }
02542
02543 if (!rtx_equal_p (args->match, mem))
02544
02545 return 0;
02546
02547
02548 validate_change (args->insn, px, args->replacement, 1);
02549 args->modified++;
02550
02551 return 0;
02552 }
02553
02554
02555 int
02556 df_insn_mem_replace (df, bb, insn, mem, reg)
02557 struct df *df;
02558 basic_block bb;
02559 rtx insn;
02560 rtx mem;
02561 rtx reg;
02562 {
02563 replace_args args;
02564
02565 args.insn = insn;
02566 args.match = mem;
02567 args.replacement = reg;
02568 args.modified = 0;
02569
02570
02571 for_each_rtx (&insn, df_rtx_mem_replace, &args);
02572
02573 if (args.modified)
02574 df_insn_modify (df, bb, insn);
02575
02576
02577
02578
02579
02580
02581 return args.modified;
02582 }
02583
02584
02585
02586
02587
02588 static int
02589 df_rtx_reg_replace (px, data)
02590 rtx *px;
02591 void *data;
02592 {
02593 rtx x = *px;
02594 replace_args *args = (replace_args *) data;
02595
02596 if (x == NULL_RTX)
02597 return 0;
02598
02599 if (x == args->match)
02600 {
02601 validate_change (args->insn, px, args->replacement, 1);
02602 args->modified++;
02603 }
02604
02605 return 0;
02606 }
02607
02608
02609
02610
02611
02612 void
02613 df_refs_reg_replace (df, blocks, chain, oldreg, newreg)
02614 struct df *df;
02615 bitmap blocks;
02616 struct df_link *chain;
02617 rtx oldreg;
02618 rtx newreg;
02619 {
02620 struct df_link *link;
02621 replace_args args;
02622
02623 if (! blocks)
02624 blocks = df->all_blocks;
02625
02626 args.match = oldreg;
02627 args.replacement = newreg;
02628 args.modified = 0;
02629
02630 for (link = chain; link; link = link->next)
02631 {
02632 struct ref *ref = link->ref;
02633 rtx insn = DF_REF_INSN (ref);
02634
02635 if (! INSN_P (insn))
02636 continue;
02637
02638 if (bitmap_bit_p (blocks, DF_REF_BBNO (ref)))
02639 {
02640 df_ref_reg_replace (df, ref, oldreg, newreg);
02641
02642
02643 if ((! link->next || DF_REF_INSN (ref)
02644 != DF_REF_INSN (link->next->ref))
02645 && REG_NOTES (insn))
02646 {
02647 args.insn = insn;
02648 for_each_rtx (®_NOTES (insn), df_rtx_reg_replace, &args);
02649 }
02650 }
02651 else
02652 {
02653
02654
02655 abort ();
02656 }
02657 }
02658 }
02659
02660
02661
02662
02663
02664
02665 int
02666 df_reg_replace (df, blocks, oldreg, newreg)
02667 struct df *df;
02668 bitmap blocks;
02669 rtx oldreg;
02670 rtx newreg;
02671 {
02672 unsigned int oldregno = REGNO (oldreg);
02673
02674 df_refs_reg_replace (df, blocks, df->regs[oldregno].defs, oldreg, newreg);
02675 df_refs_reg_replace (df, blocks, df->regs[oldregno].uses, oldreg, newreg);
02676 return 1;
02677 }
02678
02679
02680
02681
02682 int
02683 df_ref_reg_replace (df, ref, oldreg, newreg)
02684 struct df *df;
02685 struct ref *ref;
02686 rtx oldreg;
02687 rtx newreg;
02688 {
02689
02690
02691 if (! INSN_P (DF_REF_INSN (ref)))
02692 return 0;
02693
02694 if (oldreg && oldreg != DF_REF_REG (ref))
02695 abort ();
02696
02697 if (! validate_change (DF_REF_INSN (ref), DF_REF_LOC (ref), newreg, 1))
02698 return 0;
02699
02700 df_insn_modify (df, DF_REF_BB (ref), DF_REF_INSN (ref));
02701 return 1;
02702 }
02703
02704
02705 struct ref*
02706 df_bb_def_use_swap (df, bb, def_insn, use_insn, regno)
02707 struct df * df;
02708 basic_block bb;
02709 rtx def_insn;
02710 rtx use_insn;
02711 unsigned int regno;
02712 {
02713 struct ref *def;
02714 struct ref *use;
02715 int def_uid;
02716 int use_uid;
02717 struct df_link *link;
02718
02719 def = df_bb_insn_regno_first_def_find (df, bb, def_insn, regno);
02720 if (! def)
02721 return 0;
02722
02723 use = df_bb_insn_regno_last_use_find (df, bb, use_insn, regno);
02724 if (! use)
02725 return 0;
02726
02727
02728 use_uid = INSN_UID (use_insn);
02729 df_use_unlink (df, use);
02730 df_ref_unlink (&df->insns[use_uid].uses, use);
02731
02732
02733
02734 def_uid = INSN_UID (def_insn);
02735 link = df_ref_unlink (&df->insns[def_uid].defs, def);
02736 link->ref = def;
02737 link->next = df->insns[use_uid].defs;
02738 df->insns[use_uid].defs = link;
02739
02740 #if 0
02741 link = df_ref_unlink (&df->regs[regno].defs, def);
02742 link->ref = def;
02743 link->next = df->regs[regno].defs;
02744 df->insns[regno].defs = link;
02745 #endif
02746
02747 DF_REF_INSN (def) = use_insn;
02748 return def;
02749 }
02750
02751
02752
02753
02754 static void
02755 df_insns_modify (df, bb, first_insn, last_insn)
02756 struct df *df;
02757 basic_block bb;
02758 rtx first_insn;
02759 rtx last_insn;
02760 {
02761 rtx insn;
02762
02763 for (insn = first_insn; ; insn = NEXT_INSN (insn))
02764 {
02765 unsigned int uid;
02766
02767
02768
02769
02770 if ((GET_CODE (insn) == CALL_INSN
02771 && ! CONST_OR_PURE_CALL_P (insn))
02772 || GET_CODE (insn) == CODE_LABEL)
02773 abort ();
02774
02775 uid = INSN_UID (insn);
02776
02777 if (uid >= df->insn_size)
02778 df_insn_table_realloc (df, uid);
02779
02780 df_insn_modify (df, bb, insn);
02781
02782 if (insn == last_insn)
02783 break;
02784 }
02785 }
02786
02787
02788
02789 rtx
02790 df_pattern_emit_before (df, pattern, bb, insn)
02791 struct df *df ATTRIBUTE_UNUSED;
02792 rtx pattern;
02793 basic_block bb;
02794 rtx insn;
02795 {
02796 rtx ret_insn;
02797 rtx prev_insn = PREV_INSN (insn);
02798
02799
02800 if (insn == bb->head)
02801 abort ();
02802 ret_insn = emit_insn_before (pattern, insn);
02803 if (ret_insn == insn)
02804 return ret_insn;
02805
02806 df_insns_modify (df, bb, NEXT_INSN (prev_insn), ret_insn);
02807 return ret_insn;
02808 }
02809
02810
02811
02812 rtx
02813 df_pattern_emit_after (df, pattern, bb, insn)
02814 struct df *df;
02815 rtx pattern;
02816 basic_block bb;
02817 rtx insn;
02818 {
02819 rtx ret_insn;
02820
02821 ret_insn = emit_insn_after (pattern, insn);
02822 if (ret_insn == insn)
02823 return ret_insn;
02824
02825 df_insns_modify (df, bb, NEXT_INSN (insn), ret_insn);
02826 return ret_insn;
02827 }
02828
02829
02830
02831 rtx
02832 df_jump_pattern_emit_after (df, pattern, bb, insn)
02833 struct df *df;
02834 rtx pattern;
02835 basic_block bb;
02836 rtx insn;
02837 {
02838 rtx ret_insn;
02839
02840 ret_insn = emit_jump_insn_after (pattern, insn);
02841 if (ret_insn == insn)
02842 return ret_insn;
02843
02844 df_insns_modify (df, bb, NEXT_INSN (insn), ret_insn);
02845 return ret_insn;
02846 }
02847
02848
02849
02850
02851
02852
02853
02854 rtx
02855 df_insn_move_before (df, bb, insn, before_bb, before_insn)
02856 struct df *df;
02857 basic_block bb;
02858 rtx insn;
02859 basic_block before_bb;
02860 rtx before_insn;
02861 {
02862 struct df_link *link;
02863 unsigned int uid;
02864
02865 if (! bb)
02866 return df_pattern_emit_before (df, insn, before_bb, before_insn);
02867
02868 uid = INSN_UID (insn);
02869
02870
02871 for (link = df->insns[uid].defs; link; link = link->next)
02872 DF_REF_BB (link->ref) = before_bb;
02873 for (link = df->insns[uid].uses; link; link = link->next)
02874 DF_REF_BB (link->ref) = before_bb;
02875
02876
02877
02878
02879
02880
02881
02882
02883 return emit_insn_before (insn, before_insn);
02884 }
02885
02886
02887
02888
02889 int
02890 df_insn_regno_def_p (df, bb, insn, regno)
02891 struct df *df;
02892 basic_block bb ATTRIBUTE_UNUSED;
02893 rtx insn;
02894 unsigned int regno;
02895 {
02896 unsigned int uid;
02897 struct df_link *link;
02898
02899 uid = INSN_UID (insn);
02900
02901 for (link = df->insns[uid].defs; link; link = link->next)
02902 {
02903 struct ref *def = link->ref;
02904
02905 if (DF_REF_REGNO (def) == regno)
02906 return 1;
02907 }
02908
02909 return 0;
02910 }
02911
02912
02913 static int
02914 df_def_dominates_all_uses_p (df, def)
02915 struct df *df ATTRIBUTE_UNUSED;
02916 struct ref *def;
02917 {
02918 struct df_link *du_link;
02919
02920
02921 for (du_link = DF_REF_CHAIN (def); du_link; du_link = du_link->next)
02922 {
02923 struct ref *use = du_link->ref;
02924 struct df_link *ud_link;
02925
02926
02927 for (ud_link = DF_REF_CHAIN (use); ud_link; ud_link = ud_link->next)
02928 if (ud_link->ref != def)
02929 return 0;
02930 }
02931 return 1;
02932 }
02933
02934
02935 int
02936 df_insn_dominates_all_uses_p (df, bb, insn)
02937 struct df *df;
02938 basic_block bb ATTRIBUTE_UNUSED;
02939 rtx insn;
02940 {
02941 unsigned int uid;
02942 struct df_link *link;
02943
02944 uid = INSN_UID (insn);
02945
02946 for (link = df->insns[uid].defs; link; link = link->next)
02947 {
02948 struct ref *def = link->ref;
02949
02950 if (! df_def_dominates_all_uses_p (df, def))
02951 return 0;
02952 }
02953
02954 return 1;
02955 }
02956
02957
02958
02959
02960 static int
02961 df_def_dominates_uses_p (df, def, blocks)
02962 struct df *df ATTRIBUTE_UNUSED;
02963 struct ref *def;
02964 bitmap blocks;
02965 {
02966 struct df_link *du_link;
02967
02968
02969 for (du_link = DF_REF_CHAIN (def); du_link; du_link = du_link->next)
02970 {
02971 struct ref *use = du_link->ref;
02972 struct df_link *ud_link;
02973
02974
02975
02976
02977 if (bitmap_bit_p (blocks, DF_REF_BBNO (use)))
02978 {
02979
02980 for (ud_link = DF_REF_CHAIN (use); ud_link; ud_link = ud_link->next)
02981 if (ud_link->ref != def)
02982 return 0;
02983 }
02984 }
02985 return 1;
02986 }
02987
02988
02989
02990
02991 int
02992 df_insn_dominates_uses_p (df, bb, insn, blocks)
02993 struct df *df;
02994 basic_block bb ATTRIBUTE_UNUSED;
02995 rtx insn;
02996 bitmap blocks;
02997 {
02998 unsigned int uid;
02999 struct df_link *link;
03000
03001 uid = INSN_UID (insn);
03002
03003 for (link = df->insns[uid].defs; link; link = link->next)
03004 {
03005 struct ref *def = link->ref;
03006
03007
03008 if (bitmap_bit_p (blocks, DF_REF_BBNO (def))
03009 && ! df_def_dominates_uses_p (df, def, blocks))
03010 return 0;
03011 }
03012 return 1;
03013 }
03014
03015
03016
03017
03018 basic_block
03019 df_regno_bb (df, regno)
03020 struct df *df;
03021 unsigned int regno;
03022 {
03023 struct df_link *defs = df->regs[regno].defs;
03024 struct df_link *uses = df->regs[regno].uses;
03025 struct ref *def = defs ? defs->ref : 0;
03026 struct ref *use = uses ? uses->ref : 0;
03027 basic_block bb_def = def ? DF_REF_BB (def) : 0;
03028 basic_block bb_use = use ? DF_REF_BB (use) : 0;
03029
03030
03031
03032 return bb_def == bb_use ? bb_def : 0;
03033 }
03034
03035
03036
03037 int
03038 df_reg_global_p (df, reg)
03039 struct df *df;
03040 rtx reg;
03041 {
03042 return df_regno_bb (df, REGNO (reg)) != 0;
03043 }
03044
03045
03046
03047 int
03048 df_reg_lifetime (df, reg)
03049 struct df *df;
03050 rtx reg;
03051 {
03052 return df->regs[REGNO (reg)].lifetime;
03053 }
03054
03055
03056
03057 int
03058 df_bb_reg_live_start_p (df, bb, reg)
03059 struct df *df ATTRIBUTE_UNUSED;
03060 basic_block bb;
03061 rtx reg;
03062 {
03063 struct bb_info *bb_info = DF_BB_INFO (df, bb);
03064
03065 #ifdef ENABLE_CHECKING
03066 if (! bb_info->lr_in)
03067 abort ();
03068 #endif
03069
03070 return bitmap_bit_p (bb_info->lr_in, REGNO (reg));
03071 }
03072
03073
03074
03075 int
03076 df_bb_reg_live_end_p (df, bb, reg)
03077 struct df *df ATTRIBUTE_UNUSED;
03078 basic_block bb;
03079 rtx reg;
03080 {
03081 struct bb_info *bb_info = DF_BB_INFO (df, bb);
03082
03083 #ifdef ENABLE_CHECKING
03084 if (! bb_info->lr_in)
03085 abort ();
03086 #endif
03087
03088 return bitmap_bit_p (bb_info->lr_out, REGNO (reg));
03089 }
03090
03091
03092
03093
03094 int
03095 df_bb_regs_lives_compare (df, bb, reg1, reg2)
03096 struct df *df;
03097 basic_block bb;
03098 rtx reg1;
03099 rtx reg2;
03100 {
03101 unsigned int regno1 = REGNO (reg1);
03102 unsigned int regno2 = REGNO (reg2);
03103 struct ref *def1;
03104 struct ref *use1;
03105 struct ref *def2;
03106 struct ref *use2;
03107
03108
03109
03110 if (df_regno_bb (df, regno1) != bb
03111 || df_regno_bb (df, regno2) != bb)
03112 abort ();
03113
03114 def2 = df_bb_regno_first_def_find (df, bb, regno2);
03115 use1 = df_bb_regno_last_use_find (df, bb, regno1);
03116
03117 if (DF_INSN_LUID (df, DF_REF_INSN (def2))
03118 > DF_INSN_LUID (df, DF_REF_INSN (use1)))
03119 return -1;
03120
03121 def1 = df_bb_regno_first_def_find (df, bb, regno1);
03122 use2 = df_bb_regno_last_use_find (df, bb, regno2);
03123
03124 if (DF_INSN_LUID (df, DF_REF_INSN (def1))
03125 > DF_INSN_LUID (df, DF_REF_INSN (use2)))
03126 return 1;
03127
03128 return 0;
03129 }
03130
03131
03132
03133 static struct ref *
03134 df_bb_regno_last_use_find (df, bb, regno)
03135 struct df * df;
03136 basic_block bb ATTRIBUTE_UNUSED;
03137 unsigned int regno;
03138 {
03139 struct df_link *link;
03140
03141
03142
03143
03144
03145 for (link = df->regs[regno].uses; link; link = link->next)
03146 {
03147 struct ref *use = link->ref;
03148
03149 if (DF_REF_BB (use) == bb)
03150 return use;
03151 }
03152 return 0;
03153 }
03154
03155
03156
03157 static struct ref *
03158 df_bb_regno_first_def_find (df, bb, regno)
03159 struct df * df;
03160 basic_block bb ATTRIBUTE_UNUSED;
03161 unsigned int regno;
03162 {
03163 struct df_link *link;
03164
03165
03166
03167
03168
03169 for (link = df->regs[regno].defs; link; link = link->next)
03170 {
03171 struct ref *def = link->ref;
03172
03173 if (DF_REF_BB (def) == bb)
03174 return def;
03175 }
03176 return 0;
03177 }
03178
03179
03180
03181 static struct ref *
03182 df_bb_insn_regno_last_use_find (df, bb, insn, regno)
03183 struct df * df;
03184 basic_block bb ATTRIBUTE_UNUSED;
03185 rtx insn;
03186 unsigned int regno;
03187 {
03188 unsigned int uid;
03189 struct df_link *link;
03190
03191 uid = INSN_UID (insn);
03192
03193 for (link = df->insns[uid].uses; link; link = link->next)
03194 {
03195 struct ref *use = link->ref;
03196
03197 if (DF_REF_REGNO (use) == regno)
03198 return use;
03199 }
03200
03201 return 0;
03202 }
03203
03204
03205
03206 static struct ref *
03207 df_bb_insn_regno_first_def_find (df, bb, insn, regno)
03208 struct df * df;
03209 basic_block bb ATTRIBUTE_UNUSED;
03210 rtx insn;
03211 unsigned int regno;
03212 {
03213 unsigned int uid;
03214 struct df_link *link;
03215
03216 uid = INSN_UID (insn);
03217
03218 for (link = df->insns[uid].defs; link; link = link->next)
03219 {
03220 struct ref *def = link->ref;
03221
03222 if (DF_REF_REGNO (def) == regno)
03223 return def;
03224 }
03225
03226 return 0;
03227 }
03228
03229
03230
03231
03232 rtx
03233 df_bb_single_def_use_insn_find (df, bb, insn, reg)
03234 struct df * df;
03235 basic_block bb;
03236 rtx insn;
03237 rtx reg;
03238 {
03239 struct ref *def;
03240 struct ref *use;
03241 struct df_link *du_link;
03242
03243 def = df_bb_insn_regno_first_def_find (df, bb, insn, REGNO (reg));
03244
03245 if (! def)
03246 abort ();
03247
03248 du_link = DF_REF_CHAIN (def);
03249
03250 if (! du_link)
03251 return NULL_RTX;
03252
03253 use = du_link->ref;
03254
03255
03256 if (! use)
03257 return NULL_RTX;
03258
03259
03260 if (du_link->next)
03261 return NULL_RTX;
03262
03263 return DF_REF_INSN (use);
03264 }
03265
03266
03267
03268
03269
03270 static void
03271 df_chain_dump (link, file)
03272 struct df_link *link;
03273 FILE *file;
03274 {
03275 fprintf (file, "{ ");
03276 for (; link; link = link->next)
03277 {
03278 fprintf (file, "%c%d ",
03279 DF_REF_REG_DEF_P (link->ref) ? 'd' : 'u',
03280 DF_REF_ID (link->ref));
03281 }
03282 fprintf (file, "}");
03283 }
03284
03285 static void
03286 df_chain_dump_regno (link, file)
03287 struct df_link *link;
03288 FILE *file;
03289 {
03290 fprintf (file, "{ ");
03291 for (; link; link = link->next)
03292 {
03293 fprintf (file, "%c%d(%d) ",
03294 DF_REF_REG_DEF_P (link->ref) ? 'd' : 'u',
03295 DF_REF_ID (link->ref),
03296 DF_REF_REGNO (link->ref));
03297 }
03298 fprintf (file, "}");
03299 }
03300
03301
03302 void
03303 df_dump (df, flags, file)
03304 struct df *df;
03305 int flags;
03306 FILE *file;
03307 {
03308 unsigned int j;
03309 basic_block bb;
03310
03311 if (! df || ! file)
03312 return;
03313
03314 fprintf (file, "\nDataflow summary:\n");
03315 fprintf (file, "n_regs = %d, n_defs = %d, n_uses = %d, n_bbs = %d\n",
03316 df->n_regs, df->n_defs, df->n_uses, df->n_bbs);
03317
03318 if (flags & DF_RD)
03319 {
03320 basic_block bb;
03321
03322 fprintf (file, "Reaching defs:\n");
03323 FOR_EACH_BB (bb)
03324 {
03325 struct bb_info *bb_info = DF_BB_INFO (df, bb);
03326
03327 if (! bb_info->rd_in)
03328 continue;
03329
03330 fprintf (file, "bb %d in \t", bb->index);
03331 dump_bitmap (file, bb_info->rd_in);
03332 fprintf (file, "bb %d gen \t", bb->index);
03333 dump_bitmap (file, bb_info->rd_gen);
03334 fprintf (file, "bb %d kill\t", bb->index);
03335 dump_bitmap (file, bb_info->rd_kill);
03336 fprintf (file, "bb %d out \t", bb->index);
03337 dump_bitmap (file, bb_info->rd_out);
03338 }
03339 }
03340
03341 if (flags & DF_UD_CHAIN)
03342 {
03343 fprintf (file, "Use-def chains:\n");
03344 for (j = 0; j < df->n_defs; j++)
03345 {
03346 if (df->defs[j])
03347 {
03348 fprintf (file, "d%d bb %d luid %d insn %d reg %d ",
03349 j, DF_REF_BBNO (df->defs[j]),
03350 DF_INSN_LUID (df, DF_REF_INSN (df->defs[j])),
03351 DF_REF_INSN_UID (df->defs[j]),
03352 DF_REF_REGNO (df->defs[j]));
03353 if (df->defs[j]->flags & DF_REF_READ_WRITE)
03354 fprintf (file, "read/write ");
03355 df_chain_dump (DF_REF_CHAIN (df->defs[j]), file);
03356 fprintf (file, "\n");
03357 }
03358 }
03359 }
03360
03361 if (flags & DF_RU)
03362 {
03363 fprintf (file, "Reaching uses:\n");
03364 FOR_EACH_BB (bb)
03365 {
03366 struct bb_info *bb_info = DF_BB_INFO (df, bb);
03367
03368 if (! bb_info->ru_in)
03369 continue;
03370
03371 fprintf (file, "bb %d in \t", bb->index);
03372 dump_bitmap (file, bb_info->ru_in);
03373 fprintf (file, "bb %d gen \t", bb->index);
03374 dump_bitmap (file, bb_info->ru_gen);
03375 fprintf (file, "bb %d kill\t", bb->index);
03376 dump_bitmap (file, bb_info->ru_kill);
03377 fprintf (file, "bb %d out \t", bb->index);
03378 dump_bitmap (file, bb_info->ru_out);
03379 }
03380 }
03381
03382 if (flags & DF_DU_CHAIN)
03383 {
03384 fprintf (file, "Def-use chains:\n");
03385 for (j = 0; j < df->n_uses; j++)
03386 {
03387 if (df->uses[j])
03388 {
03389 fprintf (file, "u%d bb %d luid %d insn %d reg %d ",
03390 j, DF_REF_BBNO (df->uses[j]),
03391 DF_INSN_LUID (df, DF_REF_INSN (df->uses[j])),
03392 DF_REF_INSN_UID (df->uses[j]),
03393 DF_REF_REGNO (df->uses[j]));
03394 if (df->uses[j]->flags & DF_REF_READ_WRITE)
03395 fprintf (file, "read/write ");
03396 df_chain_dump (DF_REF_CHAIN (df->uses[j]), file);
03397 fprintf (file, "\n");
03398 }
03399 }
03400 }
03401
03402 if (flags & DF_LR)
03403 {
03404 fprintf (file, "Live regs:\n");
03405 FOR_EACH_BB (bb)
03406 {
03407 struct bb_info *bb_info = DF_BB_INFO (df, bb);
03408
03409 if (! bb_info->lr_in)
03410 continue;
03411
03412 fprintf (file, "bb %d in \t", bb->index);
03413 dump_bitmap (file, bb_info->lr_in);
03414 fprintf (file, "bb %d use \t", bb->index);
03415 dump_bitmap (file, bb_info->lr_use);
03416 fprintf (file, "bb %d def \t", bb->index);
03417 dump_bitmap (file, bb_info->lr_def);
03418 fprintf (file, "bb %d out \t", bb->index);
03419 dump_bitmap (file, bb_info->lr_out);
03420 }
03421 }
03422
03423 if (flags & (DF_REG_INFO | DF_RD_CHAIN | DF_RU_CHAIN))
03424 {
03425 struct reg_info *reg_info = df->regs;
03426
03427 fprintf (file, "Register info:\n");
03428 for (j = 0; j < df->n_regs; j++)
03429 {
03430 if (((flags & DF_REG_INFO)
03431 && (reg_info[j].n_uses || reg_info[j].n_defs))
03432 || ((flags & DF_RD_CHAIN) && reg_info[j].defs)
03433 || ((flags & DF_RU_CHAIN) && reg_info[j].uses))
03434 {
03435 fprintf (file, "reg %d", j);
03436 if ((flags & DF_RD_CHAIN) && (flags & DF_RU_CHAIN))
03437 {
03438 basic_block bb = df_regno_bb (df, j);
03439
03440 if (bb)
03441 fprintf (file, " bb %d", bb->index);
03442 else
03443 fprintf (file, " bb ?");
03444 }
03445 if (flags & DF_REG_INFO)
03446 {
03447 fprintf (file, " life %d", reg_info[j].lifetime);
03448 }
03449
03450 if ((flags & DF_REG_INFO) || (flags & DF_RD_CHAIN))
03451 {
03452 fprintf (file, " defs ");
03453 if (flags & DF_REG_INFO)
03454 fprintf (file, "%d ", reg_info[j].n_defs);
03455 if (flags & DF_RD_CHAIN)
03456 df_chain_dump (reg_info[j].defs, file);
03457 }
03458
03459 if ((flags & DF_REG_INFO) || (flags & DF_RU_CHAIN))
03460 {
03461 fprintf (file, " uses ");
03462 if (flags & DF_REG_INFO)
03463 fprintf (file, "%d ", reg_info[j].n_uses);
03464 if (flags & DF_RU_CHAIN)
03465 df_chain_dump (reg_info[j].uses, file);
03466 }
03467
03468 fprintf (file, "\n");
03469 }
03470 }
03471 }
03472 fprintf (file, "\n");
03473 }
03474
03475
03476 void
03477 df_insn_debug (df, insn, file)
03478 struct df *df;
03479 rtx insn;
03480 FILE *file;
03481 {
03482 unsigned int uid;
03483 int bbi;
03484
03485 uid = INSN_UID (insn);
03486 if (uid >= df->insn_size)
03487 return;
03488
03489 if (df->insns[uid].defs)
03490 bbi = DF_REF_BBNO (df->insns[uid].defs->ref);
03491 else if (df->insns[uid].uses)
03492 bbi = DF_REF_BBNO (df->insns[uid].uses->ref);
03493 else
03494 bbi = -1;
03495
03496 fprintf (file, "insn %d bb %d luid %d defs ",
03497 uid, bbi, DF_INSN_LUID (df, insn));
03498 df_chain_dump (df->insns[uid].defs, file);
03499 fprintf (file, " uses ");
03500 df_chain_dump (df->insns[uid].uses, file);
03501 fprintf (file, "\n");
03502 }
03503
03504 void
03505 df_insn_debug_regno (df, insn, file)
03506 struct df *df;
03507 rtx insn;
03508 FILE *file;
03509 {
03510 unsigned int uid;
03511 int bbi;
03512
03513 uid = INSN_UID (insn);
03514 if (uid >= df->insn_size)
03515 return;
03516
03517 if (df->insns[uid].defs)
03518 bbi = DF_REF_BBNO (df->insns[uid].defs->ref);
03519 else if (df->insns[uid].uses)
03520 bbi = DF_REF_BBNO (df->insns[uid].uses->ref);
03521 else
03522 bbi = -1;
03523
03524 fprintf (file, "insn %d bb %d luid %d defs ",
03525 uid, bbi, DF_INSN_LUID (df, insn));
03526 df_chain_dump_regno (df->insns[uid].defs, file);
03527 fprintf (file, " uses ");
03528 df_chain_dump_regno (df->insns[uid].uses, file);
03529 fprintf (file, "\n");
03530 }
03531
03532 static void
03533 df_regno_debug (df, regno, file)
03534 struct df *df;
03535 unsigned int regno;
03536 FILE *file;
03537 {
03538 if (regno >= df->reg_size)
03539 return;
03540
03541 fprintf (file, "reg %d life %d defs ",
03542 regno, df->regs[regno].lifetime);
03543 df_chain_dump (df->regs[regno].defs, file);
03544 fprintf (file, " uses ");
03545 df_chain_dump (df->regs[regno].uses, file);
03546 fprintf (file, "\n");
03547 }
03548
03549
03550 static void
03551 df_ref_debug (df, ref, file)
03552 struct df *df;
03553 struct ref *ref;
03554 FILE *file;
03555 {
03556 fprintf (file, "%c%d ",
03557 DF_REF_REG_DEF_P (ref) ? 'd' : 'u',
03558 DF_REF_ID (ref));
03559 fprintf (file, "reg %d bb %d luid %d insn %d chain ",
03560 DF_REF_REGNO (ref),
03561 DF_REF_BBNO (ref),
03562 DF_INSN_LUID (df, DF_REF_INSN (ref)),
03563 INSN_UID (DF_REF_INSN (ref)));
03564 df_chain_dump (DF_REF_CHAIN (ref), file);
03565 fprintf (file, "\n");
03566 }
03567
03568
03569 void
03570 debug_df_insn (insn)
03571 rtx insn;
03572 {
03573 df_insn_debug (ddf, insn, stderr);
03574 debug_rtx (insn);
03575 }
03576
03577
03578 void
03579 debug_df_reg (reg)
03580 rtx reg;
03581 {
03582 df_regno_debug (ddf, REGNO (reg), stderr);
03583 }
03584
03585
03586 void
03587 debug_df_regno (regno)
03588 unsigned int regno;
03589 {
03590 df_regno_debug (ddf, regno, stderr);
03591 }
03592
03593
03594 void
03595 debug_df_ref (ref)
03596 struct ref *ref;
03597 {
03598 df_ref_debug (ddf, ref, stderr);
03599 }
03600
03601
03602 void
03603 debug_df_defno (defno)
03604 unsigned int defno;
03605 {
03606 df_ref_debug (ddf, ddf->defs[defno], stderr);
03607 }
03608
03609
03610 void
03611 debug_df_useno (defno)
03612 unsigned int defno;
03613 {
03614 df_ref_debug (ddf, ddf->uses[defno], stderr);
03615 }
03616
03617
03618 void
03619 debug_df_chain (link)
03620 struct df_link *link;
03621 {
03622 df_chain_dump (link, stderr);
03623 fputc ('\n', stderr);
03624 }
03625
03626
03627
03628 static void
03629 hybrid_search_bitmap (block, in, out, gen, kill, dir,
03630 conf_op, transfun, visited, pending,
03631 data)
03632 basic_block block;
03633 bitmap *in, *out, *gen, *kill;
03634 enum df_flow_dir dir;
03635 enum df_confluence_op conf_op;
03636 transfer_function_bitmap transfun;
03637 sbitmap visited;
03638 sbitmap pending;
03639 void *data;
03640 {
03641 int changed;
03642 int i = block->index;
03643 edge e;
03644 basic_block bb = block;
03645 SET_BIT (visited, block->index);
03646 if (TEST_BIT (pending, block->index))
03647 {
03648 if (dir == FORWARD)
03649 {
03650
03651 bitmap_zero (in[i]);
03652 for (e = bb->pred; e != 0; e = e->pred_next)
03653 {
03654 if (e->src == ENTRY_BLOCK_PTR)
03655 continue;
03656 switch (conf_op)
03657 {
03658 case UNION:
03659 bitmap_a_or_b (in[i], in[i], out[e->src->index]);
03660 break;
03661 case INTERSECTION:
03662 bitmap_a_and_b (in[i], in[i], out[e->src->index]);
03663 break;
03664 }
03665 }
03666 }
03667 else
03668 {
03669
03670 bitmap_zero (out[i]);
03671 for (e = bb->succ; e != 0; e = e->succ_next)
03672 {
03673 if (e->dest == EXIT_BLOCK_PTR)
03674 continue;
03675 switch (conf_op)
03676 {
03677 case UNION:
03678 bitmap_a_or_b (out[i], out[i], in[e->dest->index]);
03679 break;
03680 case INTERSECTION:
03681 bitmap_a_and_b (out[i], out[i], in[e->dest->index]);
03682 break;
03683 }
03684 }
03685 }
03686
03687 (*transfun)(i, &changed, in[i], out[i], gen[i], kill[i], data);
03688 RESET_BIT (pending, i);
03689 if (changed)
03690 {
03691 if (dir == FORWARD)
03692 {
03693 for (e = bb->succ; e != 0; e = e->succ_next)
03694 {
03695 if (e->dest == EXIT_BLOCK_PTR || e->dest->index == i)
03696 continue;
03697 SET_BIT (pending, e->dest->index);
03698 }
03699 }
03700 else
03701 {
03702 for (e = bb->pred; e != 0; e = e->pred_next)
03703 {
03704 if (e->src == ENTRY_BLOCK_PTR || e->dest->index == i)
03705 continue;
03706 SET_BIT (pending, e->src->index);
03707 }
03708 }
03709 }
03710 }
03711 if (dir == FORWARD)
03712 {
03713 for (e = bb->succ; e != 0; e = e->succ_next)
03714 {
03715 if (e->dest == EXIT_BLOCK_PTR || e->dest->index == i)
03716 continue;
03717 if (!TEST_BIT (visited, e->dest->index))
03718 hybrid_search_bitmap (e->dest, in, out, gen, kill, dir,
03719 conf_op, transfun, visited, pending,
03720 data);
03721 }
03722 }
03723 else
03724 {
03725 for (e = bb->pred; e != 0; e = e->pred_next)
03726 {
03727 if (e->src == ENTRY_BLOCK_PTR || e->src->index == i)
03728 continue;
03729 if (!TEST_BIT (visited, e->src->index))
03730 hybrid_search_bitmap (e->src, in, out, gen, kill, dir,
03731 conf_op, transfun, visited, pending,
03732 data);
03733 }
03734 }
03735 }
03736
03737
03738
03739 static void
03740 hybrid_search_sbitmap (block, in, out, gen, kill, dir,
03741 conf_op, transfun, visited, pending,
03742 data)
03743 basic_block block;
03744 sbitmap *in, *out, *gen, *kill;
03745 enum df_flow_dir dir;
03746 enum df_confluence_op conf_op;
03747 transfer_function_sbitmap transfun;
03748 sbitmap visited;
03749 sbitmap pending;
03750 void *data;
03751 {
03752 int changed;
03753 int i = block->index;
03754 edge e;
03755 basic_block bb = block;
03756 SET_BIT (visited, block->index);
03757 if (TEST_BIT (pending, block->index))
03758 {
03759 if (dir == FORWARD)
03760 {
03761
03762 sbitmap_zero (in[i]);
03763 for (e = bb->pred; e != 0; e = e->pred_next)
03764 {
03765 if (e->src == ENTRY_BLOCK_PTR)
03766 continue;
03767 switch (conf_op)
03768 {
03769 case UNION:
03770 sbitmap_a_or_b (in[i], in[i], out[e->src->index]);
03771 break;
03772 case INTERSECTION:
03773 sbitmap_a_and_b (in[i], in[i], out[e->src->index]);
03774 break;
03775 }
03776 }
03777 }
03778 else
03779 {
03780
03781 sbitmap_zero (out[i]);
03782 for (e = bb->succ; e != 0; e = e->succ_next)
03783 {
03784 if (e->dest == EXIT_BLOCK_PTR)
03785 continue;
03786 switch (conf_op)
03787 {
03788 case UNION:
03789 sbitmap_a_or_b (out[i], out[i], in[e->dest->index]);
03790 break;
03791 case INTERSECTION:
03792 sbitmap_a_and_b (out[i], out[i], in[e->dest->index]);
03793 break;
03794 }
03795 }
03796 }
03797
03798 (*transfun)(i, &changed, in[i], out[i], gen[i], kill[i], data);
03799 RESET_BIT (pending, i);
03800 if (changed)
03801 {
03802 if (dir == FORWARD)
03803 {
03804 for (e = bb->succ; e != 0; e = e->succ_next)
03805 {
03806 if (e->dest == EXIT_BLOCK_PTR || e->dest->index == i)
03807 continue;
03808 SET_BIT (pending, e->dest->index);
03809 }
03810 }
03811 else
03812 {
03813 for (e = bb->pred; e != 0; e = e->pred_next)
03814 {
03815 if (e->src == ENTRY_BLOCK_PTR || e->dest->index == i)
03816 continue;
03817 SET_BIT (pending, e->src->index);
03818 }
03819 }
03820 }
03821 }
03822 if (dir == FORWARD)
03823 {
03824 for (e = bb->succ; e != 0; e = e->succ_next)
03825 {
03826 if (e->dest == EXIT_BLOCK_PTR || e->dest->index == i)
03827 continue;
03828 if (!TEST_BIT (visited, e->dest->index))
03829 hybrid_search_sbitmap (e->dest, in, out, gen, kill, dir,
03830 conf_op, transfun, visited, pending,
03831 data);
03832 }
03833 }
03834 else
03835 {
03836 for (e = bb->pred; e != 0; e = e->pred_next)
03837 {
03838 if (e->src == ENTRY_BLOCK_PTR || e->src->index == i)
03839 continue;
03840 if (!TEST_BIT (visited, e->src->index))
03841 hybrid_search_sbitmap (e->src, in, out, gen, kill, dir,
03842 conf_op, transfun, visited, pending,
03843 data);
03844 }
03845 }
03846 }
03847
03848
03849
03850
03851
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871 void
03872 iterative_dataflow_sbitmap (in, out, gen, kill, blocks,
03873 dir, conf_op, transfun, order, data)
03874 sbitmap *in, *out, *gen, *kill;
03875 bitmap blocks;
03876 enum df_flow_dir dir;
03877 enum df_confluence_op conf_op;
03878 transfer_function_sbitmap transfun;
03879 int *order;
03880 void *data;
03881 {
03882 int i;
03883 fibheap_t worklist;
03884 basic_block bb;
03885 sbitmap visited, pending;
03886 pending = sbitmap_alloc (last_basic_block);
03887 visited = sbitmap_alloc (last_basic_block);
03888 sbitmap_zero (pending);
03889 sbitmap_zero (visited);
03890 worklist = fibheap_new ();
03891 EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i,
03892 {
03893 fibheap_insert (worklist, order[i], (void *) (size_t) i);
03894 SET_BIT (pending, i);
03895 if (dir == FORWARD)
03896 sbitmap_copy (out[i], gen[i]);
03897 else
03898 sbitmap_copy (in[i], gen[i]);
03899 });
03900 while (sbitmap_first_set_bit (pending) != -1)
03901 {
03902 while (!fibheap_empty (worklist))
03903 {
03904 i = (size_t) fibheap_extract_min (worklist);
03905 bb = BASIC_BLOCK (i);
03906 if (!TEST_BIT (visited, bb->index))
03907 hybrid_search_sbitmap (bb, in, out, gen, kill, dir,
03908 conf_op, transfun, visited, pending, data);
03909 }
03910 if (sbitmap_first_set_bit (pending) != -1)
03911 {
03912 EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i,
03913 {
03914 fibheap_insert (worklist, order[i], (void *) (size_t) i);
03915 });
03916 sbitmap_zero (visited);
03917 }
03918 else
03919 {
03920 break;
03921 }
03922 }
03923 sbitmap_free (pending);
03924 sbitmap_free (visited);
03925 fibheap_delete (worklist);
03926 }
03927
03928
03929
03930 void
03931 iterative_dataflow_bitmap (in, out, gen, kill, blocks,
03932 dir, conf_op, transfun, order, data)
03933 bitmap *in, *out, *gen, *kill;
03934 bitmap blocks;
03935 enum df_flow_dir dir;
03936 enum df_confluence_op conf_op;
03937 transfer_function_bitmap transfun;
03938 int *order;
03939 void *data;
03940 {
03941 int i;
03942 fibheap_t worklist;
03943 basic_block bb;
03944 sbitmap visited, pending;
03945 pending = sbitmap_alloc (last_basic_block);
03946 visited = sbitmap_alloc (last_basic_block);
03947 sbitmap_zero (pending);
03948 sbitmap_zero (visited);
03949 worklist = fibheap_new ();
03950 EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i,
03951 {
03952 fibheap_insert (worklist, order[i], (void *) (size_t) i);
03953 SET_BIT (pending, i);
03954 if (dir == FORWARD)
03955 bitmap_copy (out[i], gen[i]);
03956 else
03957 bitmap_copy (in[i], gen[i]);
03958 });
03959 while (sbitmap_first_set_bit (pending) != -1)
03960 {
03961 while (!fibheap_empty (worklist))
03962 {
03963 i = (size_t) fibheap_extract_min (worklist);
03964 bb = BASIC_BLOCK (i);
03965 if (!TEST_BIT (visited, bb->index))
03966 hybrid_search_bitmap (bb, in, out, gen, kill, dir,
03967 conf_op, transfun, visited, pending, data);
03968 }
03969 if (sbitmap_first_set_bit (pending) != -1)
03970 {
03971 EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i,
03972 {
03973 fibheap_insert (worklist, order[i], (void *) (size_t) i);
03974 });
03975 sbitmap_zero (visited);
03976 }
03977 else
03978 {
03979 break;
03980 }
03981 }
03982 sbitmap_free (pending);
03983 sbitmap_free (visited);
03984 fibheap_delete (worklist);
03985 }