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