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 #ifndef GCC_DF_H
00028 #define GCC_DF_H
00029
00030 #include "bitmap.h"
00031 #include "basic-block.h"
00032 #include "alloc-pool.h"
00033
00034 struct dataflow;
00035 struct df;
00036 struct df_problem;
00037 struct df_link;
00038
00039
00040
00041
00042
00043 #define DF_SCAN 0
00044 #define DF_RU 1
00045 #define DF_RD 2
00046 #define DF_LR 3
00047 #define DF_UR 4
00048 #define DF_UREC 5
00049 #define DF_CHAIN 6
00050 #define DF_RI 7
00051 #define DF_LAST_PROBLEM_PLUS1 (DF_RI + 1)
00052
00053
00054
00055 enum df_flow_dir
00056 {
00057 DF_NONE,
00058 DF_FORWARD,
00059 DF_BACKWARD
00060 };
00061
00062
00063
00064
00065
00066 enum df_ref_type {DF_REF_REG_DEF, DF_REF_REG_USE, DF_REF_REG_MEM_LOAD,
00067 DF_REF_REG_MEM_STORE};
00068
00069 #define DF_REF_TYPE_NAMES {"def", "use", "mem load", "mem store"}
00070
00071 enum df_ref_flags
00072 {
00073
00074
00075
00076 DF_REF_READ_WRITE = 1,
00077
00078
00079
00080
00081 DF_REF_STRIPPED = 2,
00082
00083
00084
00085 DF_REF_ARTIFICIAL = 4,
00086
00087
00088
00089
00090
00091
00092 DF_REF_AT_TOP = 8,
00093
00094
00095 DF_REF_IN_NOTE = 16,
00096
00097
00098
00099
00100
00101
00102 DF_REF_MAY_CLOBBER = 32,
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 DF_REF_MUST_CLOBBER = 64,
00114
00115
00116 DF_REF_MW_HARDREG = 128,
00117
00118
00119
00120 DF_REF_PARTIAL = 256
00121 };
00122
00123
00124
00125
00126
00127 typedef void (*df_alloc_function) (struct dataflow *, bitmap, bitmap);
00128
00129
00130
00131
00132
00133
00134
00135 typedef void (*df_reset_function) (struct dataflow *, bitmap);
00136
00137
00138
00139 typedef void (*df_free_bb_function) (struct dataflow *, basic_block, void *);
00140
00141
00142 typedef void (*df_local_compute_function) (struct dataflow *, bitmap, bitmap);
00143
00144
00145 typedef void (*df_init_function) (struct dataflow *, bitmap);
00146
00147
00148 typedef void (*df_dataflow_function) (struct dataflow *, bitmap, bitmap,
00149 int *, int, bool);
00150
00151
00152 typedef void (*df_confluence_function_0) (struct dataflow *, basic_block);
00153
00154
00155 typedef void (*df_confluence_function_n) (struct dataflow *, edge);
00156
00157
00158 typedef bool (*df_transfer_function) (struct dataflow *, int);
00159
00160
00161 typedef void (*df_finalizer_function) (struct dataflow*, bitmap);
00162
00163
00164 typedef void (*df_free_function) (struct dataflow *);
00165
00166
00167 typedef void (*df_dump_problem_function) (struct dataflow *, FILE *);
00168
00169
00170
00171 typedef struct dataflow * (*df_dependent_problem_function) (struct df *, int);
00172
00173
00174
00175
00176 struct df_problem {
00177
00178
00179 unsigned int id;
00180 enum df_flow_dir dir;
00181 df_alloc_function alloc_fun;
00182 df_reset_function reset_fun;
00183 df_free_bb_function free_bb_fun;
00184 df_local_compute_function local_compute_fun;
00185 df_init_function init_fun;
00186 df_dataflow_function dataflow_fun;
00187 df_confluence_function_0 con_fun_0;
00188 df_confluence_function_n con_fun_n;
00189 df_transfer_function trans_fun;
00190 df_finalizer_function finalize_fun;
00191 df_free_function free_fun;
00192 df_dump_problem_function dump_fun;
00193 df_dependent_problem_function dependent_problem_fun;
00194
00195
00196 int changeable_flags;
00197 };
00198
00199
00200
00201 struct dataflow
00202 {
00203 struct df *df;
00204 struct df_problem *problem;
00205
00206
00207 sbitmap visited, pending, considered;
00208
00209
00210
00211 void **block_info;
00212 unsigned int block_info_size;
00213
00214
00215 alloc_pool block_pool;
00216
00217
00218
00219
00220 #define DF_HARD_REGS 1
00221 #define DF_EQUIV_NOTES 2
00222 #define DF_SUBREGS 4
00223
00224 #define DF_DU_CHAIN 1
00225 #define DF_UD_CHAIN 2
00226
00227 #define DF_RI_LIFE 1
00228
00229 int flags;
00230
00231
00232
00233
00234
00235 void *problem_data;
00236 };
00237
00238
00239
00240
00241
00242
00243 struct df_mw_hardreg
00244 {
00245 rtx mw_reg;
00246 enum df_ref_type type;
00247 enum df_ref_flags flags;
00248 struct df_link *regs;
00249
00250 struct df_mw_hardreg *next;
00251 };
00252
00253
00254
00255 struct df_insn_info
00256 {
00257 struct df_ref *defs;
00258 struct df_ref *uses;
00259 struct df_mw_hardreg *mw_hardregs;
00260
00261
00262 int luid;
00263 bool contains_asm;
00264 };
00265
00266
00267
00268
00269 struct df_reg_info
00270 {
00271 struct df_ref *reg_chain;
00272 unsigned int begin;
00273 unsigned int n_refs;
00274 };
00275
00276
00277
00278
00279 struct df_ref
00280 {
00281 rtx reg;
00282 unsigned int regno;
00283 basic_block bb;
00284
00285
00286
00287 rtx insn;
00288 rtx *loc;
00289 struct df_link *chain;
00290 unsigned int id;
00291 enum df_ref_type type;
00292 enum df_ref_flags flags;
00293
00294
00295
00296
00297 struct df_ref *next_reg;
00298 struct df_ref *prev_reg;
00299
00300
00301
00302 struct df_ref *next_ref;
00303 void *data;
00304 };
00305
00306
00307
00308
00309 struct df_link
00310 {
00311 struct df_ref *ref;
00312 struct df_link *next;
00313 };
00314
00315
00316
00317 struct df_ref_info
00318 {
00319 struct df_reg_info **regs;
00320 unsigned int regs_size;
00321 unsigned int regs_inited;
00322 struct df_ref **refs;
00323 unsigned int refs_size;
00324 unsigned int bitmap_size;
00325
00326
00327
00328 bool refs_organized;
00329
00330
00331 bool add_refs_inline;
00332 };
00333
00334
00335
00336
00337
00338
00339
00340
00341 struct df
00342 {
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 struct dataflow *problems_in_order [DF_LAST_PROBLEM_PLUS1];
00353 struct dataflow *problems_by_index [DF_LAST_PROBLEM_PLUS1];
00354 int num_problems_defined;
00355
00356
00357
00358
00359
00360 bitmap blocks_to_scan;
00361
00362
00363
00364 bitmap blocks_to_analyze;
00365
00366
00367
00368
00369 struct df_ref_info def_info;
00370 struct df_ref_info use_info;
00371 struct df_insn_info **insns;
00372 unsigned int insns_size;
00373 bitmap hardware_regs_used;
00374 bitmap entry_block_defs;
00375 bitmap exit_block_uses;
00376 };
00377
00378 #define DF_SCAN_BB_INFO(DF, BB) (df_scan_get_bb_info((DF)->problems_by_index[DF_SCAN],(BB)->index))
00379 #define DF_RU_BB_INFO(DF, BB) (df_ru_get_bb_info((DF)->problems_by_index[DF_RU],(BB)->index))
00380 #define DF_RD_BB_INFO(DF, BB) (df_rd_get_bb_info((DF)->problems_by_index[DF_RD],(BB)->index))
00381 #define DF_LR_BB_INFO(DF, BB) (df_lr_get_bb_info((DF)->problems_by_index[DF_LR],(BB)->index))
00382 #define DF_UR_BB_INFO(DF, BB) (df_ur_get_bb_info((DF)->problems_by_index[DF_UR],(BB)->index))
00383 #define DF_UREC_BB_INFO(DF, BB) (df_urec_get_bb_info((DF)->problems_by_index[DF_UREC],(BB)->index))
00384
00385
00386
00387
00388 #define DF_LIVE_IN(DF, BB) (DF_UR_BB_INFO(DF, BB)->in)
00389 #define DF_LIVE_OUT(DF, BB) (DF_UR_BB_INFO(DF, BB)->out)
00390
00391
00392
00393 #define DF_RA_LIVE_IN(DF, BB) (DF_UREC_BB_INFO(DF, BB)->in)
00394 #define DF_RA_LIVE_OUT(DF, BB) (DF_UREC_BB_INFO(DF, BB)->out)
00395
00396
00397
00398
00399 #define DF_UPWARD_LIVE_IN(DF, BB) (DF_LR_BB_INFO(DF, BB)->in)
00400 #define DF_UPWARD_LIVE_OUT(DF, BB) (DF_LR_BB_INFO(DF, BB)->out)
00401
00402
00403
00404
00405
00406 #define DF_REF_REAL_REG(REF) (GET_CODE ((REF)->reg) == SUBREG \
00407 ? SUBREG_REG ((REF)->reg) : ((REF)->reg))
00408 #define DF_REF_REGNO(REF) ((REF)->regno)
00409 #define DF_REF_REAL_LOC(REF) (GET_CODE ((REF)->reg) == SUBREG \
00410 ? &SUBREG_REG ((REF)->reg) : ((REF)->loc))
00411 #define DF_REF_REG(REF) ((REF)->reg)
00412 #define DF_REF_LOC(REF) ((REF)->loc)
00413 #define DF_REF_BB(REF) ((REF)->bb)
00414 #define DF_REF_BBNO(REF) (DF_REF_BB (REF)->index)
00415 #define DF_REF_INSN(REF) ((REF)->insn)
00416 #define DF_REF_INSN_UID(REF) (INSN_UID ((REF)->insn))
00417 #define DF_REF_TYPE(REF) ((REF)->type)
00418 #define DF_REF_CHAIN(REF) ((REF)->chain)
00419 #define DF_REF_ID(REF) ((REF)->id)
00420 #define DF_REF_FLAGS(REF) ((REF)->flags)
00421 #define DF_REF_NEXT_REG(REF) ((REF)->next_reg)
00422 #define DF_REF_PREV_REG(REF) ((REF)->prev_reg)
00423 #define DF_REF_NEXT_REF(REF) ((REF)->next_ref)
00424 #define DF_REF_DATA(REF) ((REF)->data)
00425
00426
00427
00428 #define DF_REF_REG_DEF_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_DEF)
00429 #define DF_REF_REG_USE_P(REF) ((REF) && !DF_REF_REG_DEF_P (REF))
00430 #define DF_REF_REG_MEM_STORE_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_MEM_STORE)
00431 #define DF_REF_REG_MEM_LOAD_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_MEM_LOAD)
00432 #define DF_REF_REG_MEM_P(REF) (DF_REF_REG_MEM_STORE_P (REF) \
00433 || DF_REF_REG_MEM_LOAD_P (REF))
00434
00435
00436 #define DF_DEFS_SIZE(DF) ((DF)->def_info.bitmap_size)
00437 #define DF_DEFS_GET(DF,ID) ((DF)->def_info.refs[(ID)])
00438 #define DF_DEFS_SET(DF,ID,VAL) ((DF)->def_info.refs[(ID)]=(VAL))
00439 #define DF_USES_SIZE(DF) ((DF)->use_info.bitmap_size)
00440 #define DF_USES_GET(DF,ID) ((DF)->use_info.refs[(ID)])
00441 #define DF_USES_SET(DF,ID,VAL) ((DF)->use_info.refs[(ID)]=(VAL))
00442
00443
00444
00445 #define DF_REG_SIZE(DF) ((DF)->def_info.regs_inited)
00446 #define DF_REG_DEF_GET(DF, REG) ((DF)->def_info.regs[(REG)])
00447 #define DF_REG_DEF_SET(DF, REG, VAL) ((DF)->def_info.regs[(REG)]=(VAL))
00448 #define DF_REG_DEF_COUNT(DF, REG) ((DF)->def_info.regs[(REG)]->n_refs)
00449 #define DF_REG_USE_GET(DF, REG) ((DF)->use_info.regs[(REG)])
00450 #define DF_REG_USE_SET(DF, REG, VAL) ((DF)->use_info.regs[(REG)]=(VAL))
00451 #define DF_REG_USE_COUNT(DF, REG) ((DF)->use_info.regs[(REG)]->n_refs)
00452
00453
00454
00455 #define DF_REGNO_FIRST_DEF(DF, REGNUM) \
00456 (DF_REG_DEF_GET(DF, REGNUM) ? DF_REG_DEF_GET(DF, REGNUM) : 0)
00457 #define DF_REGNO_LAST_USE(DF, REGNUM) \
00458 (DF_REG_USE_GET(DF, REGNUM) ? DF_REG_USE_GET(DF, REGNUM) : 0)
00459
00460
00461
00462 #define DF_INSN_SIZE(DF) ((DF)->insns_size)
00463 #define DF_INSN_GET(DF,INSN) ((DF)->insns[(INSN_UID(INSN))])
00464 #define DF_INSN_SET(DF,INSN,VAL) ((DF)->insns[(INSN_UID (INSN))]=(VAL))
00465 #define DF_INSN_CONTAINS_ASM(DF, INSN) (DF_INSN_GET(DF,INSN)->contains_asm)
00466 #define DF_INSN_LUID(DF, INSN) (DF_INSN_GET(DF,INSN)->luid)
00467 #define DF_INSN_DEFS(DF, INSN) (DF_INSN_GET(DF,INSN)->defs)
00468 #define DF_INSN_USES(DF, INSN) (DF_INSN_GET(DF,INSN)->uses)
00469
00470 #define DF_INSN_UID_GET(DF,UID) ((DF)->insns[(UID)])
00471 #define DF_INSN_UID_LUID(DF, INSN) (DF_INSN_UID_GET(DF,INSN)->luid)
00472 #define DF_INSN_UID_DEFS(DF, INSN) (DF_INSN_UID_GET(DF,INSN)->defs)
00473 #define DF_INSN_UID_USES(DF, INSN) (DF_INSN_UID_GET(DF,INSN)->uses)
00474 #define DF_INSN_UID_MWS(DF, INSN) (DF_INSN_UID_GET(DF,INSN)->mw_hardregs)
00475
00476
00477
00478
00479 extern bitmap df_invalidated_by_call;
00480
00481
00482
00483 struct df_scan_bb_info
00484 {
00485
00486
00487 struct df_ref *artificial_defs;
00488
00489
00490 struct df_ref *artificial_uses;
00491 };
00492
00493
00494
00495
00496 struct df_ru_bb_info
00497 {
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 bitmap kill;
00509 bitmap sparse_kill;
00510 bitmap gen;
00511
00512
00513 bitmap in;
00514 bitmap out;
00515 };
00516
00517
00518
00519
00520 struct df_rd_bb_info
00521 {
00522
00523
00524 bitmap kill;
00525 bitmap sparse_kill;
00526 bitmap gen;
00527
00528
00529 bitmap in;
00530 bitmap out;
00531 };
00532
00533
00534
00535 struct df_lr_bb_info
00536 {
00537
00538 bitmap def;
00539 bitmap use;
00540
00541
00542 bitmap in;
00543 bitmap out;
00544 };
00545
00546
00547
00548 struct df_ur_bb_info
00549 {
00550
00551 bitmap kill;
00552
00553 bitmap gen;
00554
00555
00556 bitmap in;
00557 bitmap out;
00558 };
00559
00560
00561 struct df_urec_bb_info
00562 {
00563
00564 bitmap earlyclobber;
00565
00566
00567 bitmap kill;
00568 bitmap gen;
00569
00570
00571 bitmap in;
00572 bitmap out;
00573 };
00574
00575
00576 #define df_finish(df) {df_finish1(df); df=NULL;}
00577
00578
00579
00580 extern struct df *df_init (int);
00581 extern struct dataflow *df_add_problem (struct df *, struct df_problem *, int);
00582 extern int df_set_flags (struct dataflow *, int);
00583 extern int df_clear_flags (struct dataflow *, int);
00584 extern void df_set_blocks (struct df*, bitmap);
00585 extern void df_delete_basic_block (struct df *, int);
00586 extern void df_finish1 (struct df *);
00587 extern void df_analyze_problem (struct dataflow *, bitmap, bitmap, bitmap, int *, int, bool);
00588 extern void df_analyze (struct df *);
00589 extern void df_compact_blocks (struct df *);
00590 extern void df_bb_replace (struct df *, int, basic_block);
00591 extern struct df_ref *df_bb_regno_last_use_find (struct df *, basic_block, unsigned int);
00592 extern struct df_ref *df_bb_regno_first_def_find (struct df *, basic_block, unsigned int);
00593 extern struct df_ref *df_bb_regno_last_def_find (struct df *, basic_block, unsigned int);
00594 extern bool df_insn_regno_def_p (struct df *, rtx, unsigned int);
00595 extern struct df_ref *df_find_def (struct df *, rtx, rtx);
00596 extern bool df_reg_defined (struct df *, rtx, rtx);
00597 extern struct df_ref *df_find_use (struct df *, rtx, rtx);
00598 extern bool df_reg_used (struct df *, rtx, rtx);
00599 extern void df_iterative_dataflow (struct dataflow *, bitmap, bitmap, int *, int, bool);
00600 extern void df_dump (struct df *, FILE *);
00601 extern void df_refs_chain_dump (struct df_ref *, bool, FILE *);
00602 extern void df_regs_chain_dump (struct df *, struct df_ref *, FILE *);
00603 extern void df_insn_debug (struct df *, rtx, bool, FILE *);
00604 extern void df_insn_debug_regno (struct df *, rtx, FILE *);
00605 extern void df_regno_debug (struct df *, unsigned int, FILE *);
00606 extern void df_ref_debug (struct df_ref *, FILE *);
00607 extern void debug_df_insn (rtx);
00608 extern void debug_df_regno (unsigned int);
00609 extern void debug_df_reg (rtx);
00610 extern void debug_df_defno (unsigned int);
00611 extern void debug_df_useno (unsigned int);
00612 extern void debug_df_ref (struct df_ref *);
00613 extern void debug_df_chain (struct df_link *);
00614
00615 extern struct df *shared_df;
00616
00617
00618
00619
00620 extern struct df_link *df_chain_create (struct dataflow *, struct df_ref *, struct df_ref *);
00621 extern void df_chain_unlink (struct dataflow *, struct df_ref *, struct df_link *);
00622 extern void df_chain_copy (struct dataflow *, struct df_ref *, struct df_link *);
00623 extern bitmap df_get_live_in (struct df *, basic_block);
00624 extern bitmap df_get_live_out (struct df *, basic_block);
00625 extern void df_grow_bb_info (struct dataflow *);
00626 extern void df_chain_dump (struct df_link *, FILE *);
00627 extern void df_print_bb_index (basic_block bb, FILE *file);
00628 extern struct dataflow *df_ru_add_problem (struct df *, int);
00629 extern struct df_ru_bb_info *df_ru_get_bb_info (struct dataflow *, unsigned int);
00630 extern struct dataflow *df_rd_add_problem (struct df *, int);
00631 extern struct df_rd_bb_info *df_rd_get_bb_info (struct dataflow *, unsigned int);
00632 extern struct dataflow *df_lr_add_problem (struct df *, int);
00633 extern struct df_lr_bb_info *df_lr_get_bb_info (struct dataflow *, unsigned int);
00634 extern struct dataflow *df_ur_add_problem (struct df *, int);
00635 extern struct df_ur_bb_info *df_ur_get_bb_info (struct dataflow *, unsigned int);
00636 extern struct dataflow *df_urec_add_problem (struct df *, int);
00637 extern struct df_urec_bb_info *df_urec_get_bb_info (struct dataflow *, unsigned int);
00638 extern struct dataflow *df_chain_add_problem (struct df *, int);
00639 extern struct dataflow *df_ri_add_problem (struct df *, int);
00640
00641
00642
00643
00644 extern struct df_scan_bb_info *df_scan_get_bb_info (struct dataflow *, unsigned int);
00645 extern struct dataflow *df_scan_add_problem (struct df *, int);
00646 extern void df_rescan_blocks (struct df *, bitmap);
00647 extern struct df_ref *df_ref_create (struct df *, rtx, rtx *, rtx,basic_block,enum df_ref_type, enum df_ref_flags);
00648 extern struct df_ref *df_get_artificial_defs (struct df *, unsigned int);
00649 extern struct df_ref *df_get_artificial_uses (struct df *, unsigned int);
00650 extern void df_reg_chain_create (struct df_reg_info *, struct df_ref *);
00651 extern struct df_ref *df_reg_chain_unlink (struct dataflow *, struct df_ref *);
00652 extern void df_ref_remove (struct df *, struct df_ref *);
00653 extern void df_insn_refs_delete (struct dataflow *, rtx);
00654 extern void df_bb_refs_delete (struct dataflow *, int);
00655 extern void df_refs_delete (struct dataflow *, bitmap);
00656 extern void df_reorganize_refs (struct df_ref_info *);
00657 extern void df_hard_reg_init (void);
00658 extern bool df_read_modify_subreg_p (rtx);
00659
00660
00661
00662
00663
00664 struct web_entry
00665 {
00666
00667 struct web_entry *pred;
00668
00669 rtx reg;
00670 void* extra_info;
00671 };
00672
00673 extern struct web_entry *unionfind_root (struct web_entry *);
00674 extern bool unionfind_union (struct web_entry *, struct web_entry *);
00675 extern void union_defs (struct df *, struct df_ref *,
00676 struct web_entry *, struct web_entry *,
00677 bool (*fun) (struct web_entry *, struct web_entry *));
00678
00679
00680 #endif