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 #include "config.h"
00123 #include "system.h"
00124 #include "coretypes.h"
00125 #include "tm.h"
00126 #include "tree.h"
00127 #include "rtl.h"
00128 #include "tm_p.h"
00129 #include "hard-reg-set.h"
00130 #include "basic-block.h"
00131 #include "insn-config.h"
00132 #include "regs.h"
00133 #include "flags.h"
00134 #include "output.h"
00135 #include "function.h"
00136 #include "except.h"
00137 #include "toplev.h"
00138 #include "recog.h"
00139 #include "expr.h"
00140 #include "timevar.h"
00141
00142 #include "obstack.h"
00143 #include "splay-tree.h"
00144 #include "tree-pass.h"
00145 #include "params.h"
00146
00147 #ifndef HAVE_epilogue
00148 #define HAVE_epilogue 0
00149 #endif
00150 #ifndef HAVE_prologue
00151 #define HAVE_prologue 0
00152 #endif
00153 #ifndef HAVE_sibcall_epilogue
00154 #define HAVE_sibcall_epilogue 0
00155 #endif
00156
00157 #ifndef EPILOGUE_USES
00158 #define EPILOGUE_USES(REGNO) 0
00159 #endif
00160 #ifndef EH_USES
00161 #define EH_USES(REGNO) 0
00162 #endif
00163
00164 #ifdef HAVE_conditional_execution
00165 #ifndef REVERSE_CONDEXEC_PREDICATES_P
00166 #define REVERSE_CONDEXEC_PREDICATES_P(x, y) \
00167 (GET_CODE ((x)) == reversed_comparison_code ((y), NULL))
00168 #endif
00169 #endif
00170
00171
00172
00173
00174 #define MAX_LIVENESS_ROUNDS 20
00175
00176
00177 int flow2_completed;
00178
00179
00180
00181 int max_regno;
00182
00183
00184
00185 VEC(reg_info_p,heap) *reg_n_info;
00186
00187
00188
00189
00190 static regset regs_live_at_setjmp;
00191
00192
00193
00194
00195
00196 rtx regs_may_share;
00197
00198
00199
00200
00201 static HARD_REG_SET elim_reg_set;
00202
00203
00204 struct reg_cond_life_info
00205 {
00206
00207 rtx condition;
00208
00209 rtx orig_condition;
00210
00211
00212
00213 rtx stores;
00214
00215
00216
00217 };
00218
00219
00220
00221
00222 struct propagate_block_info
00223 {
00224
00225 basic_block bb;
00226
00227
00228 regset reg_live;
00229
00230
00231 regset new_set;
00232
00233
00234
00235 rtx *reg_next_use;
00236
00237
00238
00239 rtx mem_set_list;
00240
00241
00242
00243 regset local_set;
00244
00245
00246
00247 regset cond_local_set;
00248
00249 #ifdef HAVE_conditional_execution
00250
00251
00252 splay_tree reg_cond_dead;
00253
00254
00255 regset reg_cond_reg;
00256 #endif
00257
00258
00259 int mem_set_list_len;
00260
00261
00262 int cc0_live;
00263
00264
00265 int flags;
00266
00267 int insn_num;
00268 };
00269
00270
00271 static int ndead;
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 static int *reg_deaths;
00287
00288
00289 static int verify_wide_reg_1 (rtx *, void *);
00290 static void verify_wide_reg (int, basic_block);
00291 static void verify_local_live_at_start (regset, basic_block);
00292 static void notice_stack_pointer_modification_1 (rtx, rtx, void *);
00293 static void notice_stack_pointer_modification (void);
00294 static void mark_reg (rtx, void *);
00295 static void mark_regs_live_at_end (regset);
00296 static void calculate_global_regs_live (sbitmap, sbitmap, int);
00297 static void propagate_block_delete_insn (rtx);
00298 static rtx propagate_block_delete_libcall (rtx, rtx);
00299 static int insn_dead_p (struct propagate_block_info *, rtx, int, rtx);
00300 static int libcall_dead_p (struct propagate_block_info *, rtx, rtx);
00301 static void mark_set_regs (struct propagate_block_info *, rtx, rtx);
00302 static void mark_set_1 (struct propagate_block_info *, enum rtx_code, rtx,
00303 rtx, rtx, int);
00304 static int find_regno_partial (rtx *, void *);
00305
00306 #ifdef HAVE_conditional_execution
00307 static int mark_regno_cond_dead (struct propagate_block_info *, int, rtx);
00308 static void free_reg_cond_life_info (splay_tree_value);
00309 static int flush_reg_cond_reg_1 (splay_tree_node, void *);
00310 static void flush_reg_cond_reg (struct propagate_block_info *, int);
00311 static rtx elim_reg_cond (rtx, unsigned int);
00312 static rtx ior_reg_cond (rtx, rtx, int);
00313 static rtx not_reg_cond (rtx);
00314 static rtx and_reg_cond (rtx, rtx, int);
00315 #endif
00316 #ifdef AUTO_INC_DEC
00317 static void attempt_auto_inc (struct propagate_block_info *, rtx, rtx, rtx,
00318 rtx, rtx);
00319 static void find_auto_inc (struct propagate_block_info *, rtx, rtx);
00320 static int try_pre_increment_1 (struct propagate_block_info *, rtx);
00321 static int try_pre_increment (rtx, rtx, HOST_WIDE_INT);
00322 #endif
00323 static void mark_used_reg (struct propagate_block_info *, rtx, rtx, rtx);
00324 static void mark_used_regs (struct propagate_block_info *, rtx, rtx, rtx);
00325 void debug_flow_info (void);
00326 static void add_to_mem_set_list (struct propagate_block_info *, rtx);
00327 static int invalidate_mems_from_autoinc (rtx *, void *);
00328 static void invalidate_mems_from_set (struct propagate_block_info *, rtx);
00329 static void clear_log_links (sbitmap);
00330 static int count_or_remove_death_notes_bb (basic_block, int);
00331 static void allocate_bb_life_data (void);
00332
00333
00334
00335
00336 rtx
00337 first_insn_after_basic_block_note (basic_block block)
00338 {
00339 rtx insn;
00340
00341
00342 insn = BB_HEAD (block);
00343
00344 if (insn == NULL_RTX)
00345 return NULL_RTX;
00346 if (LABEL_P (insn))
00347 insn = NEXT_INSN (insn);
00348 gcc_assert (NOTE_INSN_BASIC_BLOCK_P (insn));
00349
00350 return NEXT_INSN (insn);
00351 }
00352
00353
00354
00355
00356 void
00357 life_analysis (int flags)
00358 {
00359 #ifdef ELIMINABLE_REGS
00360 int i;
00361 static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
00362 #endif
00363
00364
00365
00366
00367 CLEAR_HARD_REG_SET (elim_reg_set);
00368
00369 #ifdef ELIMINABLE_REGS
00370 for (i = 0; i < (int) ARRAY_SIZE (eliminables); i++)
00371 SET_HARD_REG_BIT (elim_reg_set, eliminables[i].from);
00372 #else
00373 SET_HARD_REG_BIT (elim_reg_set, FRAME_POINTER_REGNUM);
00374 #endif
00375
00376
00377 #ifdef CANNOT_CHANGE_MODE_CLASS
00378 if (flags & PROP_REG_INFO)
00379 init_subregs_of_mode ();
00380 #endif
00381
00382 if (! optimize)
00383 flags &= ~(PROP_LOG_LINKS | PROP_AUTOINC | PROP_ALLOW_CFG_CHANGES);
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 if (reload_completed)
00396 flags &= ~(PROP_REG_INFO | PROP_AUTOINC);
00397
00398
00399 if (optimize && (flags & PROP_SCAN_DEAD_STORES))
00400 init_alias_analysis ();
00401
00402
00403
00404 delete_noop_moves ();
00405
00406
00407
00408
00409 if (! reload_completed)
00410 notice_stack_pointer_modification ();
00411
00412
00413
00414 allocate_reg_life_data ();
00415 allocate_bb_life_data ();
00416
00417
00418 mark_regs_live_at_end (EXIT_BLOCK_PTR->il.rtl->global_live_at_start);
00419
00420
00421
00422
00423
00424 if (flags & PROP_REG_INFO)
00425 {
00426 memset (regs_ever_live, 0, sizeof (regs_ever_live));
00427 memset (regs_asm_clobbered, 0, sizeof (regs_asm_clobbered));
00428 }
00429 update_life_info (NULL, UPDATE_LIFE_GLOBAL, flags);
00430 if (reg_deaths)
00431 {
00432 free (reg_deaths);
00433 reg_deaths = NULL;
00434 }
00435
00436
00437 if (optimize && (flags & PROP_SCAN_DEAD_STORES))
00438 end_alias_analysis ();
00439
00440 if (dump_file)
00441 dump_flow_info (dump_file, dump_flags);
00442
00443
00444 delete_dead_jumptables ();
00445 }
00446
00447
00448
00449
00450
00451 static int
00452 verify_wide_reg_1 (rtx *px, void *pregno)
00453 {
00454 rtx x = *px;
00455 unsigned int regno = *(int *) pregno;
00456
00457 if (REG_P (x) && REGNO (x) == regno)
00458 {
00459 if (GET_MODE_BITSIZE (GET_MODE (x)) <= BITS_PER_WORD)
00460 return 2;
00461 return 1;
00462 }
00463 return 0;
00464 }
00465
00466
00467
00468
00469 static void
00470 verify_wide_reg (int regno, basic_block bb)
00471 {
00472 rtx head = BB_HEAD (bb), end = BB_END (bb);
00473
00474 while (1)
00475 {
00476 if (INSN_P (head))
00477 {
00478 int r = for_each_rtx (&PATTERN (head), verify_wide_reg_1, ®no);
00479 if (r == 1)
00480 return;
00481 if (r == 2)
00482 break;
00483 }
00484 if (head == end)
00485 break;
00486 head = NEXT_INSN (head);
00487 }
00488 if (dump_file)
00489 {
00490 fprintf (dump_file, "Register %d died unexpectedly.\n", regno);
00491 dump_bb (bb, dump_file, 0);
00492 }
00493 internal_error ("internal consistency failure");
00494 }
00495
00496
00497
00498
00499 static void
00500 verify_local_live_at_start (regset new_live_at_start, basic_block bb)
00501 {
00502 if (reload_completed)
00503 {
00504
00505
00506 if (! REG_SET_EQUAL_P (new_live_at_start,
00507 bb->il.rtl->global_live_at_start))
00508 {
00509 if (dump_file)
00510 {
00511 fprintf (dump_file,
00512 "live_at_start mismatch in bb %d, aborting\nNew:\n",
00513 bb->index);
00514 debug_bitmap_file (dump_file, new_live_at_start);
00515 fputs ("Old:\n", dump_file);
00516 dump_bb (bb, dump_file, 0);
00517 }
00518 internal_error ("internal consistency failure");
00519 }
00520 }
00521 else
00522 {
00523 unsigned i;
00524 reg_set_iterator rsi;
00525
00526
00527 XOR_REG_SET (new_live_at_start, bb->il.rtl->global_live_at_start);
00528
00529 EXECUTE_IF_SET_IN_REG_SET (new_live_at_start, 0, i, rsi)
00530 {
00531
00532 if (REGNO_REG_SET_P (bb->il.rtl->global_live_at_start, i))
00533 {
00534 if (dump_file)
00535 {
00536 fprintf (dump_file,
00537 "Register %d died unexpectedly.\n", i);
00538 dump_bb (bb, dump_file, 0);
00539 }
00540 internal_error ("internal consistency failure");
00541 }
00542
00543 verify_wide_reg (i, bb);
00544 }
00545 }
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568 int
00569 update_life_info (sbitmap blocks, enum update_life_extent extent,
00570 int prop_flags)
00571 {
00572 regset tmp;
00573 unsigned i = 0;
00574 int stabilized_prop_flags = prop_flags;
00575 basic_block bb;
00576
00577 tmp = ALLOC_REG_SET (®_obstack);
00578 ndead = 0;
00579
00580 if ((prop_flags & PROP_REG_INFO) && !reg_deaths)
00581 reg_deaths = XCNEWVEC (int, max_regno);
00582
00583 timevar_push ((extent == UPDATE_LIFE_LOCAL || blocks)
00584 ? TV_LIFE_UPDATE : TV_LIFE);
00585
00586
00587
00588 gcc_assert (!(prop_flags & PROP_ALLOW_CFG_CHANGES)
00589 || (extent != UPDATE_LIFE_LOCAL && !blocks));
00590
00591
00592 if (extent != UPDATE_LIFE_LOCAL)
00593 {
00594 for ( ; ; )
00595 {
00596 int changed = 0;
00597
00598 calculate_global_regs_live (blocks, blocks,
00599 prop_flags & (PROP_SCAN_DEAD_CODE
00600 | PROP_SCAN_DEAD_STORES
00601 | PROP_ALLOW_CFG_CHANGES));
00602
00603 if ((prop_flags & (PROP_KILL_DEAD_CODE | PROP_ALLOW_CFG_CHANGES))
00604 != (PROP_KILL_DEAD_CODE | PROP_ALLOW_CFG_CHANGES))
00605 break;
00606
00607
00608
00609 FOR_EACH_BB_REVERSE (bb)
00610 {
00611 COPY_REG_SET (tmp, bb->il.rtl->global_live_at_end);
00612 changed |= propagate_block (bb, tmp, NULL, NULL,
00613 prop_flags & (PROP_SCAN_DEAD_CODE
00614 | PROP_SCAN_DEAD_STORES
00615 | PROP_KILL_DEAD_CODE));
00616 }
00617
00618
00619
00620
00621
00622 stabilized_prop_flags
00623 &= ~(PROP_SCAN_DEAD_CODE | PROP_SCAN_DEAD_STORES
00624 | PROP_KILL_DEAD_CODE);
00625
00626 if (! changed)
00627 break;
00628
00629
00630
00631
00632
00633 cleanup_cfg (CLEANUP_EXPENSIVE);
00634
00635
00636
00637
00638 FOR_EACH_BB (bb)
00639 {
00640 CLEAR_REG_SET (bb->il.rtl->global_live_at_start);
00641 CLEAR_REG_SET (bb->il.rtl->global_live_at_end);
00642 }
00643 }
00644
00645
00646 if (extent == UPDATE_LIFE_GLOBAL_RM_NOTES)
00647 count_or_remove_death_notes (blocks,
00648 prop_flags & PROP_POST_REGSTACK ? -1 : 1);
00649 }
00650 else
00651 {
00652
00653
00654
00655
00656 if (prop_flags & PROP_DEATH_NOTES)
00657 count_or_remove_death_notes (blocks,
00658 prop_flags & PROP_POST_REGSTACK ? -1 : 1);
00659 }
00660
00661
00662
00663 if (prop_flags & PROP_LOG_LINKS)
00664 clear_log_links (blocks);
00665
00666 if (blocks)
00667 {
00668 sbitmap_iterator sbi;
00669
00670 EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i, sbi)
00671 {
00672 bb = BASIC_BLOCK (i);
00673 if (bb)
00674 {
00675
00676
00677 COPY_REG_SET (tmp, bb->il.rtl->global_live_at_end);
00678 propagate_block (bb, tmp, NULL, NULL, stabilized_prop_flags);
00679
00680 if (extent == UPDATE_LIFE_LOCAL)
00681 verify_local_live_at_start (tmp, bb);
00682 }
00683 };
00684 }
00685 else
00686 {
00687 FOR_EACH_BB_REVERSE (bb)
00688 {
00689 COPY_REG_SET (tmp, bb->il.rtl->global_live_at_end);
00690
00691 propagate_block (bb, tmp, NULL, NULL, stabilized_prop_flags);
00692
00693 if (extent == UPDATE_LIFE_LOCAL)
00694 verify_local_live_at_start (tmp, bb);
00695 }
00696 }
00697
00698 FREE_REG_SET (tmp);
00699
00700 if (prop_flags & PROP_REG_INFO)
00701 {
00702 reg_set_iterator rsi;
00703
00704
00705
00706
00707
00708 EXECUTE_IF_SET_IN_REG_SET (ENTRY_BLOCK_PTR->il.rtl->global_live_at_end,
00709 FIRST_PSEUDO_REGISTER, i, rsi)
00710 REG_BASIC_BLOCK (i) = REG_BLOCK_GLOBAL;
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 EXECUTE_IF_SET_IN_REG_SET (regs_live_at_setjmp,
00721 FIRST_PSEUDO_REGISTER, i, rsi)
00722 {
00723 if (regno_reg_rtx[i] != 0)
00724 {
00725 REG_LIVE_LENGTH (i) = -1;
00726 REG_BASIC_BLOCK (i) = REG_BLOCK_UNKNOWN;
00727 }
00728 }
00729 }
00730 if (reg_deaths)
00731 {
00732 free (reg_deaths);
00733 reg_deaths = NULL;
00734 }
00735 timevar_pop ((extent == UPDATE_LIFE_LOCAL || blocks)
00736 ? TV_LIFE_UPDATE : TV_LIFE);
00737 if (ndead && dump_file)
00738 fprintf (dump_file, "deleted %i dead insns\n", ndead);
00739 return ndead;
00740 }
00741
00742
00743
00744 int
00745 update_life_info_in_dirty_blocks (enum update_life_extent extent, int prop_flags)
00746 {
00747 sbitmap update_life_blocks = sbitmap_alloc (last_basic_block);
00748 int n = 0;
00749 basic_block bb;
00750 int retval = 0;
00751
00752 sbitmap_zero (update_life_blocks);
00753 FOR_EACH_BB (bb)
00754 {
00755 if (bb->flags & BB_DIRTY)
00756 {
00757 SET_BIT (update_life_blocks, bb->index);
00758 n++;
00759 }
00760 }
00761
00762 if (n)
00763 retval = update_life_info (update_life_blocks, extent, prop_flags);
00764
00765 sbitmap_free (update_life_blocks);
00766 return retval;
00767 }
00768
00769
00770
00771 void
00772 free_basic_block_vars (void)
00773 {
00774 if (basic_block_info)
00775 {
00776 clear_edges ();
00777 basic_block_info = NULL;
00778 }
00779 n_basic_blocks = 0;
00780 last_basic_block = 0;
00781 n_edges = 0;
00782
00783 label_to_block_map = NULL;
00784
00785 ENTRY_BLOCK_PTR->aux = NULL;
00786 ENTRY_BLOCK_PTR->il.rtl->global_live_at_end = NULL;
00787 EXIT_BLOCK_PTR->aux = NULL;
00788 EXIT_BLOCK_PTR->il.rtl->global_live_at_start = NULL;
00789 }
00790
00791
00792
00793 int
00794 delete_noop_moves (void)
00795 {
00796 rtx insn, next;
00797 basic_block bb;
00798 int nnoops = 0;
00799
00800 FOR_EACH_BB (bb)
00801 {
00802 for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb)); insn = next)
00803 {
00804 next = NEXT_INSN (insn);
00805 if (INSN_P (insn) && noop_move_p (insn))
00806 {
00807 rtx note;
00808
00809
00810
00811
00812 if ((note = find_reg_note (insn, REG_LIBCALL, NULL_RTX))
00813 && XEXP (note, 0) != insn)
00814 {
00815 rtx new_libcall_insn = next_real_insn (insn);
00816 rtx retval_note = find_reg_note (XEXP (note, 0),
00817 REG_RETVAL, NULL_RTX);
00818 REG_NOTES (new_libcall_insn)
00819 = gen_rtx_INSN_LIST (REG_LIBCALL, XEXP (note, 0),
00820 REG_NOTES (new_libcall_insn));
00821 XEXP (retval_note, 0) = new_libcall_insn;
00822 }
00823
00824 delete_insn_and_edges (insn);
00825 nnoops++;
00826 }
00827 }
00828 }
00829
00830 if (nnoops && dump_file)
00831 fprintf (dump_file, "deleted %i noop moves\n", nnoops);
00832
00833 return nnoops;
00834 }
00835
00836
00837
00838
00839
00840 void
00841 delete_dead_jumptables (void)
00842 {
00843 basic_block bb;
00844
00845
00846
00847 FOR_EACH_BB (bb)
00848 {
00849 rtx insn, next;
00850
00851 for (insn = NEXT_INSN (BB_END (bb));
00852 insn && !NOTE_INSN_BASIC_BLOCK_P (insn);
00853 insn = next)
00854 {
00855 next = NEXT_INSN (insn);
00856 if (LABEL_P (insn)
00857 && LABEL_NUSES (insn) == LABEL_PRESERVE_P (insn)
00858 && JUMP_P (next)
00859 && (GET_CODE (PATTERN (next)) == ADDR_VEC
00860 || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
00861 {
00862 rtx label = insn, jump = next;
00863
00864 if (dump_file)
00865 fprintf (dump_file, "Dead jumptable %i removed\n",
00866 INSN_UID (insn));
00867
00868 next = NEXT_INSN (next);
00869 delete_insn (jump);
00870 delete_insn (label);
00871 }
00872 }
00873 }
00874 }
00875
00876
00877
00878
00879 static void
00880 notice_stack_pointer_modification_1 (rtx x, rtx pat ATTRIBUTE_UNUSED,
00881 void *data ATTRIBUTE_UNUSED)
00882 {
00883 if (x == stack_pointer_rtx
00884
00885
00886
00887 || (MEM_P (x)
00888 && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == RTX_AUTOINC
00889 && XEXP (XEXP (x, 0), 0) == stack_pointer_rtx))
00890 current_function_sp_is_unchanging = 0;
00891 }
00892
00893 static void
00894 notice_stack_pointer_modification (void)
00895 {
00896 basic_block bb;
00897 rtx insn;
00898
00899
00900
00901 current_function_sp_is_unchanging = !current_function_calls_alloca;
00902 if (! current_function_sp_is_unchanging)
00903 return;
00904
00905 FOR_EACH_BB (bb)
00906 FOR_BB_INSNS (bb, insn)
00907 {
00908 if (INSN_P (insn))
00909 {
00910
00911 note_stores (PATTERN (insn),
00912 notice_stack_pointer_modification_1,
00913 NULL);
00914 if (! current_function_sp_is_unchanging)
00915 return;
00916 }
00917 }
00918 }
00919
00920
00921
00922
00923 static void
00924 mark_reg (rtx reg, void *xset)
00925 {
00926 regset set = (regset) xset;
00927 int regno = REGNO (reg);
00928
00929 gcc_assert (GET_MODE (reg) != BLKmode);
00930
00931 SET_REGNO_REG_SET (set, regno);
00932 if (regno < FIRST_PSEUDO_REGISTER)
00933 {
00934 int n = hard_regno_nregs[regno][GET_MODE (reg)];
00935 while (--n > 0)
00936 SET_REGNO_REG_SET (set, regno + n);
00937 }
00938 }
00939
00940
00941
00942
00943 static void
00944 mark_regs_live_at_end (regset set)
00945 {
00946 unsigned int i;
00947
00948
00949
00950 if ((HAVE_epilogue && epilogue_completed)
00951 || ! EXIT_IGNORE_STACK
00952 || (! FRAME_POINTER_REQUIRED
00953 && ! current_function_calls_alloca
00954 && flag_omit_frame_pointer)
00955 || current_function_sp_is_unchanging)
00956 {
00957 SET_REGNO_REG_SET (set, STACK_POINTER_REGNUM);
00958 }
00959
00960
00961
00962
00963
00964 if (! reload_completed || frame_pointer_needed)
00965 {
00966 SET_REGNO_REG_SET (set, FRAME_POINTER_REGNUM);
00967 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
00968
00969 if (! LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
00970 SET_REGNO_REG_SET (set, HARD_FRAME_POINTER_REGNUM);
00971 #endif
00972 }
00973
00974 #ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
00975
00976
00977
00978 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
00979 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
00980 SET_REGNO_REG_SET (set, PIC_OFFSET_TABLE_REGNUM);
00981 #endif
00982
00983
00984
00985
00986 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00987 if (global_regs[i] || EPILOGUE_USES (i))
00988 SET_REGNO_REG_SET (set, i);
00989
00990 if (HAVE_epilogue && epilogue_completed)
00991 {
00992
00993 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00994 if (regs_ever_live[i] && ! LOCAL_REGNO (i)
00995 && ! TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
00996 SET_REGNO_REG_SET (set, i);
00997 }
00998
00999 #ifdef EH_RETURN_DATA_REGNO
01000
01001 if (reload_completed && current_function_calls_eh_return)
01002 for (i = 0; ; ++i)
01003 {
01004 unsigned regno = EH_RETURN_DATA_REGNO(i);
01005 if (regno == INVALID_REGNUM)
01006 break;
01007 SET_REGNO_REG_SET (set, regno);
01008 }
01009 #endif
01010 #ifdef EH_RETURN_STACKADJ_RTX
01011 if ((! HAVE_epilogue || ! epilogue_completed)
01012 && current_function_calls_eh_return)
01013 {
01014 rtx tmp = EH_RETURN_STACKADJ_RTX;
01015 if (tmp && REG_P (tmp))
01016 mark_reg (tmp, set);
01017 }
01018 #endif
01019 #ifdef EH_RETURN_HANDLER_RTX
01020 if ((! HAVE_epilogue || ! epilogue_completed)
01021 && current_function_calls_eh_return)
01022 {
01023 rtx tmp = EH_RETURN_HANDLER_RTX;
01024 if (tmp && REG_P (tmp))
01025 mark_reg (tmp, set);
01026 }
01027 #endif
01028
01029
01030 diddle_return_value (mark_reg, set);
01031 }
01032
01033
01034
01035
01036
01037
01038
01039 static void
01040 calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags)
01041 {
01042 basic_block *queue, *qhead, *qtail, *qend, bb;
01043 regset tmp, new_live_at_end, invalidated_by_eh_edge;
01044 regset registers_made_dead;
01045 bool failure_strategy_required = false;
01046 int *block_accesses;
01047
01048
01049 regset *local_sets;
01050
01051
01052
01053 regset *cond_local_sets;
01054
01055 unsigned int i;
01056
01057
01058
01059 #ifdef ENABLE_CHECKING
01060 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
01061 gcc_assert (!bb->aux);
01062 #endif
01063
01064 tmp = ALLOC_REG_SET (®_obstack);
01065 new_live_at_end = ALLOC_REG_SET (®_obstack);
01066 invalidated_by_eh_edge = ALLOC_REG_SET (®_obstack);
01067 registers_made_dead = ALLOC_REG_SET (®_obstack);
01068
01069
01070 for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
01071 if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
01072 SET_REGNO_REG_SET (invalidated_by_eh_edge, i);
01073
01074
01075 #ifdef EH_RETURN_DATA_REGNO
01076 for (i = 0; ; ++i)
01077 {
01078 unsigned regno = EH_RETURN_DATA_REGNO (i);
01079 if (regno == INVALID_REGNUM)
01080 break;
01081 SET_REGNO_REG_SET (invalidated_by_eh_edge, regno);
01082 }
01083 #endif
01084
01085
01086 local_sets = XCNEWVEC (bitmap, last_basic_block);
01087 cond_local_sets = XCNEWVEC (bitmap, last_basic_block);
01088
01089
01090
01091 queue = XNEWVEC (basic_block, n_basic_blocks + 1);
01092 qtail = queue;
01093 qhead = qend = queue + n_basic_blocks;
01094
01095
01096
01097
01098 if (blocks_in)
01099 {
01100 FOR_EACH_BB (bb)
01101 if (TEST_BIT (blocks_in, bb->index))
01102 {
01103 *--qhead = bb;
01104 bb->aux = bb;
01105 }
01106 }
01107 else
01108 {
01109 FOR_EACH_BB (bb)
01110 {
01111 *--qhead = bb;
01112 bb->aux = bb;
01113 }
01114 }
01115
01116 block_accesses = XCNEWVEC (int, last_basic_block);
01117
01118
01119
01120
01121 ENTRY_BLOCK_PTR->aux = EXIT_BLOCK_PTR->aux = NULL;
01122
01123 if (blocks_out)
01124 sbitmap_zero (blocks_out);
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178 while (qhead != qtail)
01179 {
01180 int rescan, changed;
01181 basic_block bb;
01182 edge e;
01183 edge_iterator ei;
01184
01185 bb = *qhead++;
01186 if (qhead == qend)
01187 qhead = queue;
01188 bb->aux = NULL;
01189
01190
01191 if (bb != ENTRY_BLOCK_PTR)
01192 {
01193 int max_liveness_rounds =
01194 MAX (MAX_LIVENESS_ROUNDS, cfun->max_loop_depth);
01195
01196 block_accesses[bb->index]++;
01197 if (block_accesses[bb->index] > max_liveness_rounds)
01198 failure_strategy_required = true;
01199 }
01200
01201
01202 CLEAR_REG_SET (new_live_at_end);
01203
01204 if (EDGE_COUNT (bb->succs) > 0)
01205 FOR_EACH_EDGE (e, ei, bb->succs)
01206 {
01207 basic_block sb = e->dest;
01208
01209
01210
01211
01212
01213 if (e->flags & EDGE_EH)
01214 bitmap_ior_and_compl_into (new_live_at_end,
01215 sb->il.rtl->global_live_at_start,
01216 invalidated_by_eh_edge);
01217 else
01218 IOR_REG_SET (new_live_at_end, sb->il.rtl->global_live_at_start);
01219
01220
01221
01222 if (e->flags & EDGE_EH)
01223 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01224 if (EH_USES (i))
01225 SET_REGNO_REG_SET (new_live_at_end, i);
01226 }
01227 else
01228 {
01229
01230
01231
01232 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01233 if (EH_USES (i))
01234 SET_REGNO_REG_SET (new_live_at_end, i);
01235 }
01236
01237
01238 SET_REGNO_REG_SET (new_live_at_end, STACK_POINTER_REGNUM);
01239
01240
01241
01242
01243 if (! reload_completed)
01244 {
01245
01246
01247 SET_REGNO_REG_SET (new_live_at_end, FRAME_POINTER_REGNUM);
01248
01249 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
01250
01251
01252 if (fixed_regs[ARG_POINTER_REGNUM])
01253 SET_REGNO_REG_SET (new_live_at_end, ARG_POINTER_REGNUM);
01254 #endif
01255
01256
01257
01258 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
01259 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
01260 SET_REGNO_REG_SET (new_live_at_end, PIC_OFFSET_TABLE_REGNUM);
01261 }
01262
01263 if (bb == ENTRY_BLOCK_PTR)
01264 {
01265 COPY_REG_SET (bb->il.rtl->global_live_at_end, new_live_at_end);
01266 continue;
01267 }
01268
01269
01270
01271
01272
01273
01274 if (local_sets[bb->index] == NULL)
01275 {
01276 local_sets[bb->index] = ALLOC_REG_SET (®_obstack);
01277 cond_local_sets[bb->index] = ALLOC_REG_SET (®_obstack);
01278 rescan = 1;
01279 }
01280 else
01281 {
01282
01283
01284
01285
01286 rescan = bitmap_intersect_compl_p (bb->il.rtl->global_live_at_end,
01287 new_live_at_end);
01288
01289 if (!rescan)
01290 {
01291 regset cond_local_set;
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301 cond_local_set = cond_local_sets[bb->index];
01302 rescan = bitmap_intersect_p (new_live_at_end, cond_local_set);
01303 }
01304
01305 if (!rescan)
01306 {
01307 regset local_set;
01308
01309
01310
01311 bitmap_xor (tmp, bb->il.rtl->global_live_at_end, new_live_at_end);
01312 if (bitmap_empty_p (tmp))
01313 continue;
01314
01315
01316
01317 local_set = local_sets[bb->index];
01318 rescan = bitmap_intersect_p (tmp, local_set);
01319 }
01320 }
01321
01322
01323
01324 if (blocks_out)
01325 SET_BIT (blocks_out, bb->index);
01326
01327 if (! rescan)
01328 {
01329
01330
01331
01332 changed = bitmap_ior_and_compl_into (bb->il.rtl->global_live_at_start,
01333 new_live_at_end,
01334 bb->il.rtl->global_live_at_end);
01335 COPY_REG_SET (bb->il.rtl->global_live_at_end, new_live_at_end);
01336 if (! changed)
01337 continue;
01338 }
01339 else
01340 {
01341 COPY_REG_SET (bb->il.rtl->global_live_at_end, new_live_at_end);
01342
01343
01344
01345 propagate_block (bb, new_live_at_end,
01346 local_sets[bb->index],
01347 cond_local_sets[bb->index],
01348 flags);
01349
01350
01351 if (REG_SET_EQUAL_P (bb->il.rtl->global_live_at_start,
01352 new_live_at_end))
01353 continue;
01354
01355 if (failure_strategy_required)
01356 {
01357
01358
01359 bitmap_and_compl (tmp, bb->il.rtl->global_live_at_start,
01360 new_live_at_end);
01361 if (!bitmap_empty_p (tmp))
01362 {
01363 bool pbb_changed;
01364 basic_block pbb;
01365
01366
01367
01368
01369 pbb_changed = bitmap_ior_into (registers_made_dead, tmp);
01370 gcc_assert (pbb_changed);
01371
01372
01373 FOR_EACH_BB (pbb)
01374 {
01375 pbb_changed = false;
01376
01377 pbb_changed
01378 |= bitmap_and_compl_into
01379 (pbb->il.rtl->global_live_at_start,
01380 registers_made_dead);
01381 pbb_changed
01382 |= bitmap_and_compl_into
01383 (pbb->il.rtl->global_live_at_end,
01384 registers_made_dead);
01385 if (!pbb_changed)
01386 continue;
01387
01388
01389 if (blocks_out)
01390 SET_BIT (blocks_out, pbb->index);
01391
01392
01393 if (local_sets[pbb->index])
01394 {
01395 FREE_REG_SET (local_sets[pbb->index]);
01396 FREE_REG_SET (cond_local_sets[pbb->index]);
01397 local_sets[pbb->index] = 0;
01398 }
01399
01400
01401 if (pbb->aux == NULL)
01402 {
01403 *qtail++ = pbb;
01404 if (qtail == qend)
01405 qtail = queue;
01406 pbb->aux = pbb;
01407 }
01408 }
01409 continue;
01410 }
01411 }
01412
01413 COPY_REG_SET (bb->il.rtl->global_live_at_start, new_live_at_end);
01414 }
01415
01416
01417
01418 FOR_EACH_EDGE (e, ei, bb->preds)
01419 {
01420 basic_block pb = e->src;
01421
01422 gcc_assert ((e->flags & EDGE_FAKE) == 0);
01423
01424 if (pb->aux == NULL)
01425 {
01426 *qtail++ = pb;
01427 if (qtail == qend)
01428 qtail = queue;
01429 pb->aux = pb;
01430 }
01431 }
01432 }
01433
01434 FREE_REG_SET (tmp);
01435 FREE_REG_SET (new_live_at_end);
01436 FREE_REG_SET (invalidated_by_eh_edge);
01437 FREE_REG_SET (registers_made_dead);
01438
01439 if (blocks_out)
01440 {
01441 sbitmap_iterator sbi;
01442
01443 EXECUTE_IF_SET_IN_SBITMAP (blocks_out, 0, i, sbi)
01444 {
01445 basic_block bb = BASIC_BLOCK (i);
01446 FREE_REG_SET (local_sets[bb->index]);
01447 FREE_REG_SET (cond_local_sets[bb->index]);
01448 };
01449 }
01450 else
01451 {
01452 FOR_EACH_BB (bb)
01453 {
01454 FREE_REG_SET (local_sets[bb->index]);
01455 FREE_REG_SET (cond_local_sets[bb->index]);
01456 }
01457 }
01458
01459 free (block_accesses);
01460 free (queue);
01461 free (cond_local_sets);
01462 free (local_sets);
01463 }
01464
01465
01466
01467
01468
01469
01470
01471 typedef struct {
01472 unsigned regno_to_find;
01473 rtx retval;
01474 } find_regno_partial_param;
01475
01476
01477
01478
01479
01480 static int
01481 find_regno_partial (rtx *ptr, void *data)
01482 {
01483 find_regno_partial_param *param = (find_regno_partial_param *)data;
01484 unsigned reg = param->regno_to_find;
01485 param->retval = NULL_RTX;
01486
01487 if (*ptr == NULL_RTX)
01488 return 0;
01489
01490 switch (GET_CODE (*ptr))
01491 {
01492 case ZERO_EXTRACT:
01493 case SIGN_EXTRACT:
01494 case STRICT_LOW_PART:
01495 if (REG_P (XEXP (*ptr, 0)) && REGNO (XEXP (*ptr, 0)) == reg)
01496 {
01497 param->retval = XEXP (*ptr, 0);
01498 return 1;
01499 }
01500 break;
01501
01502 case SUBREG:
01503 if (REG_P (SUBREG_REG (*ptr))
01504 && REGNO (SUBREG_REG (*ptr)) == reg)
01505 {
01506 param->retval = SUBREG_REG (*ptr);
01507 return 1;
01508 }
01509 break;
01510
01511 default:
01512 break;
01513 }
01514
01515 return 0;
01516 }
01517
01518
01519
01520
01521
01522
01523
01524
01525 static int
01526 initialize_uninitialized_subregs (void)
01527 {
01528 rtx insn;
01529 edge e;
01530 unsigned reg, did_something = 0;
01531 find_regno_partial_param param;
01532 edge_iterator ei;
01533
01534 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
01535 {
01536 basic_block bb = e->dest;
01537 regset map = bb->il.rtl->global_live_at_start;
01538 reg_set_iterator rsi;
01539
01540 EXECUTE_IF_SET_IN_REG_SET (map, FIRST_PSEUDO_REGISTER, reg, rsi)
01541 {
01542 int uid = REGNO_FIRST_UID (reg);
01543 rtx i;
01544
01545
01546
01547
01548
01549
01550 for (i = get_insns (); i && INSN_UID (i) != uid; i = NEXT_INSN (i))
01551 ;
01552 if (i != NULL_RTX)
01553 {
01554
01555 param.regno_to_find = reg;
01556 for_each_rtx (&i, find_regno_partial, ¶m);
01557 if (param.retval != NULL_RTX)
01558 {
01559 start_sequence ();
01560 emit_move_insn (param.retval,
01561 CONST0_RTX (GET_MODE (param.retval)));
01562 insn = get_insns ();
01563 end_sequence ();
01564 insert_insn_on_edge (insn, e);
01565 did_something = 1;
01566 }
01567 }
01568 }
01569 }
01570
01571 if (did_something)
01572 commit_edge_insertions ();
01573 return did_something;
01574 }
01575
01576
01577
01578
01579
01580
01581
01582 static void
01583 allocate_bb_life_data (void)
01584 {
01585 basic_block bb;
01586
01587 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
01588 {
01589 if (bb->il.rtl->global_live_at_start)
01590 {
01591 CLEAR_REG_SET (bb->il.rtl->global_live_at_start);
01592 CLEAR_REG_SET (bb->il.rtl->global_live_at_end);
01593 }
01594 else
01595 {
01596 bb->il.rtl->global_live_at_start = ALLOC_REG_SET (®_obstack);
01597 bb->il.rtl->global_live_at_end = ALLOC_REG_SET (®_obstack);
01598 }
01599 }
01600
01601 regs_live_at_setjmp = ALLOC_REG_SET (®_obstack);
01602 }
01603
01604 void
01605 allocate_reg_life_data (void)
01606 {
01607 int i;
01608
01609 max_regno = max_reg_num ();
01610 gcc_assert (!reg_deaths);
01611 reg_deaths = XCNEWVEC (int, max_regno);
01612
01613
01614
01615 allocate_reg_info (max_regno, FALSE, FALSE);
01616
01617
01618
01619 for (i = 0; i < max_regno; i++)
01620 {
01621 REG_N_SETS (i) = 0;
01622 REG_N_REFS (i) = 0;
01623 REG_N_DEATHS (i) = 0;
01624 REG_N_CALLS_CROSSED (i) = 0;
01625 REG_N_THROWING_CALLS_CROSSED (i) = 0;
01626 REG_LIVE_LENGTH (i) = 0;
01627 REG_FREQ (i) = 0;
01628 REG_BASIC_BLOCK (i) = REG_BLOCK_UNKNOWN;
01629 }
01630 }
01631
01632
01633
01634 static void
01635 propagate_block_delete_insn (rtx insn)
01636 {
01637 rtx inote = find_reg_note (insn, REG_LABEL, NULL_RTX);
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649 if (inote && LABEL_P (inote))
01650 {
01651 rtx label = XEXP (inote, 0);
01652 rtx next;
01653
01654
01655
01656
01657 if (LABEL_NUSES (label) == 1 + LABEL_PRESERVE_P (label)
01658 && (next = next_nonnote_insn (label)) != NULL
01659 && JUMP_P (next)
01660 && (GET_CODE (PATTERN (next)) == ADDR_VEC
01661 || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
01662 {
01663 rtx pat = PATTERN (next);
01664 int diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
01665 int len = XVECLEN (pat, diff_vec_p);
01666 int i;
01667
01668 for (i = 0; i < len; i++)
01669 LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0))--;
01670
01671 delete_insn_and_edges (next);
01672 ndead++;
01673 }
01674 }
01675
01676 delete_insn_and_edges (insn);
01677 ndead++;
01678 }
01679
01680
01681
01682
01683 static rtx
01684 propagate_block_delete_libcall (rtx insn, rtx note)
01685 {
01686 rtx first = XEXP (note, 0);
01687 rtx before = PREV_INSN (first);
01688
01689 delete_insn_chain_and_edges (first, insn);
01690 ndead++;
01691 return before;
01692 }
01693
01694
01695
01696 rtx
01697 propagate_one_insn (struct propagate_block_info *pbi, rtx insn)
01698 {
01699 rtx prev = PREV_INSN (insn);
01700 int flags = pbi->flags;
01701 int insn_is_dead = 0;
01702 int libcall_is_dead = 0;
01703 rtx note;
01704 unsigned i;
01705
01706 if (! INSN_P (insn))
01707 return prev;
01708
01709 note = find_reg_note (insn, REG_RETVAL, NULL_RTX);
01710 if (flags & PROP_SCAN_DEAD_CODE)
01711 {
01712 insn_is_dead = insn_dead_p (pbi, PATTERN (insn), 0, REG_NOTES (insn));
01713 libcall_is_dead = (insn_is_dead && note != 0
01714 && libcall_dead_p (pbi, note, insn));
01715 }
01716
01717
01718
01719 if ((flags & PROP_KILL_DEAD_CODE) && insn_is_dead)
01720 {
01721
01722
01723
01724
01725
01726 if (reload_completed
01727 && !(TREE_CODE (TREE_TYPE (current_function_decl)) == FUNCTION_TYPE
01728 && (TYPE_RETURNS_STACK_DEPRESSED
01729 (TREE_TYPE (current_function_decl))))
01730 && (((HAVE_epilogue || HAVE_prologue)
01731 && prologue_epilogue_contains (insn))
01732 || (HAVE_sibcall_epilogue
01733 && sibcall_epilogue_contains (insn)))
01734 && find_reg_note (insn, REG_MAYBE_DEAD, NULL_RTX) == 0)
01735 fatal_insn ("Attempt to delete prologue/epilogue insn:", insn);
01736
01737
01738
01739
01740
01741 pbi->flags |= PROP_DEAD_INSN;
01742 mark_set_regs (pbi, PATTERN (insn), insn);
01743 pbi->flags &= ~PROP_DEAD_INSN;
01744
01745
01746
01747
01748 pbi->cc0_live = 0;
01749
01750 if (libcall_is_dead)
01751 prev = propagate_block_delete_libcall (insn, note);
01752 else
01753 {
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765 if (note)
01766 {
01767 rtx libcall_note;
01768
01769 libcall_note
01770 = find_reg_note (XEXP (note, 0), REG_LIBCALL, NULL_RTX);
01771 remove_note (XEXP (note, 0), libcall_note);
01772 }
01773
01774
01775
01776 note = find_reg_note (insn, REG_LIBCALL, NULL_RTX);
01777 if (note)
01778 {
01779 rtx retval_note;
01780
01781 retval_note
01782 = find_reg_note (XEXP (note, 0), REG_RETVAL, NULL_RTX);
01783 remove_note (XEXP (note, 0), retval_note);
01784 }
01785
01786
01787 propagate_block_delete_insn (insn);
01788 }
01789
01790 return prev;
01791 }
01792
01793
01794
01795 #ifdef AUTO_INC_DEC
01796 {
01797 rtx x = single_set (insn);
01798
01799
01800 if ((flags & PROP_AUTOINC)
01801 && x != 0
01802 && REG_P (SET_DEST (x))
01803 && (GET_CODE (SET_SRC (x)) == PLUS
01804 || GET_CODE (SET_SRC (x)) == MINUS)
01805 && XEXP (SET_SRC (x), 0) == SET_DEST (x)
01806 && GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
01807
01808
01809
01810
01811 && try_pre_increment_1 (pbi, insn))
01812 return prev;
01813 }
01814 #endif
01815
01816 CLEAR_REG_SET (pbi->new_set);
01817
01818
01819
01820
01821 if (libcall_is_dead)
01822 {
01823
01824 mark_set_regs (pbi, PATTERN (insn), insn);
01825
01826 insn = XEXP (note, 0);
01827 return PREV_INSN (insn);
01828 }
01829 else if (GET_CODE (PATTERN (insn)) == SET
01830 && SET_DEST (PATTERN (insn)) == stack_pointer_rtx
01831 && GET_CODE (SET_SRC (PATTERN (insn))) == PLUS
01832 && XEXP (SET_SRC (PATTERN (insn)), 0) == stack_pointer_rtx
01833 && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
01834 {
01835
01836
01837
01838
01839
01840
01841 invalidate_mems_from_set (pbi, stack_pointer_rtx);
01842
01843
01844 mark_set_regs (pbi, PATTERN (insn), insn);
01845 }
01846 else
01847 {
01848
01849
01850
01851
01852 if (CALL_P (insn) && (flags & PROP_REG_INFO))
01853 {
01854 reg_set_iterator rsi;
01855 EXECUTE_IF_SET_IN_REG_SET (pbi->reg_live, 0, i, rsi)
01856 REG_N_CALLS_CROSSED (i)++;
01857 if (can_throw_internal (insn))
01858 EXECUTE_IF_SET_IN_REG_SET (pbi->reg_live, 0, i, rsi)
01859 REG_N_THROWING_CALLS_CROSSED (i)++;
01860 }
01861
01862
01863
01864 mark_set_regs (pbi, PATTERN (insn), insn);
01865
01866 if (CALL_P (insn))
01867 {
01868 regset live_at_end;
01869 bool sibcall_p;
01870 rtx note, cond;
01871 int i;
01872
01873 cond = NULL_RTX;
01874 if (GET_CODE (PATTERN (insn)) == COND_EXEC)
01875 cond = COND_EXEC_TEST (PATTERN (insn));
01876
01877
01878
01879
01880 if (! CONST_OR_PURE_CALL_P (insn))
01881 {
01882 free_EXPR_LIST_list (&pbi->mem_set_list);
01883 pbi->mem_set_list_len = 0;
01884 }
01885 else
01886 invalidate_mems_from_set (pbi, stack_pointer_rtx);
01887
01888
01889 for (note = CALL_INSN_FUNCTION_USAGE (insn);
01890 note;
01891 note = XEXP (note, 1))
01892 if (GET_CODE (XEXP (note, 0)) == CLOBBER)
01893 mark_set_1 (pbi, CLOBBER, XEXP (XEXP (note, 0), 0),
01894 cond, insn, pbi->flags);
01895
01896
01897
01898
01899
01900 sibcall_p = SIBLING_CALL_P (insn);
01901 live_at_end = EXIT_BLOCK_PTR->il.rtl->global_live_at_start;
01902 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01903 if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i)
01904 && ! (sibcall_p
01905 && REGNO_REG_SET_P (live_at_end, i)
01906 && ! refers_to_regno_p (i, i+1,
01907 current_function_return_rtx,
01908 (rtx *) 0)))
01909 {
01910 enum rtx_code code = global_regs[i] ? SET : CLOBBER;
01911
01912 mark_set_1 (pbi, code, regno_reg_rtx[i], cond, insn,
01913 pbi->flags & ~(PROP_DEATH_NOTES | PROP_REG_INFO));
01914 }
01915 }
01916
01917
01918
01919
01920 pbi->cc0_live = 0;
01921
01922
01923 if (! insn_is_dead)
01924 mark_used_regs (pbi, PATTERN (insn), NULL_RTX, insn);
01925
01926
01927
01928 #ifdef AUTO_INC_DEC
01929 prev = PREV_INSN (insn);
01930 #endif
01931
01932 if (! insn_is_dead && CALL_P (insn))
01933 {
01934 int i;
01935 rtx note, cond;
01936
01937 cond = NULL_RTX;
01938 if (GET_CODE (PATTERN (insn)) == COND_EXEC)
01939 cond = COND_EXEC_TEST (PATTERN (insn));
01940
01941
01942
01943 for (note = CALL_INSN_FUNCTION_USAGE (insn);
01944 note;
01945 note = XEXP (note, 1))
01946
01947
01948 mark_used_regs (pbi, XEXP (XEXP (note, 0), 0), cond, insn);
01949
01950
01951 if ((flags & PROP_REG_INFO)
01952 && !REGNO_REG_SET_P (pbi->reg_live, STACK_POINTER_REGNUM))
01953 reg_deaths[STACK_POINTER_REGNUM] = pbi->insn_num;
01954 SET_REGNO_REG_SET (pbi->reg_live, STACK_POINTER_REGNUM);
01955
01956
01957
01958 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01959 if (global_regs[i])
01960 mark_used_reg (pbi, regno_reg_rtx[i], cond, insn);
01961 }
01962 }
01963
01964 pbi->insn_num++;
01965
01966 return prev;
01967 }
01968
01969
01970
01971
01972
01973 struct propagate_block_info *
01974 init_propagate_block_info (basic_block bb, regset live, regset local_set,
01975 regset cond_local_set, int flags)
01976 {
01977 struct propagate_block_info *pbi = XNEW (struct propagate_block_info);
01978
01979 pbi->bb = bb;
01980 pbi->reg_live = live;
01981 pbi->mem_set_list = NULL_RTX;
01982 pbi->mem_set_list_len = 0;
01983 pbi->local_set = local_set;
01984 pbi->cond_local_set = cond_local_set;
01985 pbi->cc0_live = 0;
01986 pbi->flags = flags;
01987 pbi->insn_num = 0;
01988
01989 if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
01990 pbi->reg_next_use = XCNEWVEC (rtx, max_reg_num ());
01991 else
01992 pbi->reg_next_use = NULL;
01993
01994 pbi->new_set = BITMAP_ALLOC (NULL);
01995
01996 #ifdef HAVE_conditional_execution
01997 pbi->reg_cond_dead = splay_tree_new (splay_tree_compare_ints, NULL,
01998 free_reg_cond_life_info);
01999 pbi->reg_cond_reg = BITMAP_ALLOC (NULL);
02000
02001
02002
02003
02004 if (JUMP_P (BB_END (bb))
02005 && any_condjump_p (BB_END (bb)))
02006 {
02007 regset diff = ALLOC_REG_SET (®_obstack);
02008 basic_block bb_true, bb_false;
02009 unsigned i;
02010
02011
02012 bb_true = EDGE_SUCC (bb, 0)->dest;
02013 if (!single_succ_p (bb))
02014 {
02015 bb_false = EDGE_SUCC (bb, 1)->dest;
02016
02017 if (EDGE_SUCC (bb, 0)->flags & EDGE_FALLTHRU)
02018 {
02019 basic_block t = bb_false;
02020 bb_false = bb_true;
02021 bb_true = t;
02022 }
02023 else
02024 gcc_assert (EDGE_SUCC (bb, 1)->flags & EDGE_FALLTHRU);
02025 }
02026 else
02027 {
02028
02029 gcc_assert (JUMP_LABEL (BB_END (bb)) == BB_HEAD (bb_true));
02030
02031
02032 bb_false = bb_true;
02033 }
02034
02035
02036 bitmap_xor (diff, bb_true->il.rtl->global_live_at_start,
02037 bb_false->il.rtl->global_live_at_start);
02038
02039 if (!bitmap_empty_p (diff))
02040 {
02041
02042 rtx set_src = SET_SRC (pc_set (BB_END (bb)));
02043 rtx cond_true = XEXP (set_src, 0);
02044 rtx reg = XEXP (cond_true, 0);
02045 enum rtx_code inv_cond;
02046
02047 if (GET_CODE (reg) == SUBREG)
02048 reg = SUBREG_REG (reg);
02049
02050
02051
02052
02053
02054 inv_cond = reversed_comparison_code (cond_true, BB_END (bb));
02055 if (inv_cond != UNKNOWN
02056 && REG_P (reg)
02057 && XEXP (cond_true, 1) == const0_rtx)
02058 {
02059 rtx cond_false
02060 = gen_rtx_fmt_ee (inv_cond,
02061 GET_MODE (cond_true), XEXP (cond_true, 0),
02062 XEXP (cond_true, 1));
02063 reg_set_iterator rsi;
02064
02065 if (GET_CODE (XEXP (set_src, 1)) == PC)
02066 {
02067 rtx t = cond_false;
02068 cond_false = cond_true;
02069 cond_true = t;
02070 }
02071
02072 SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (reg));
02073
02074
02075 EXECUTE_IF_SET_IN_REG_SET (diff, 0, i, rsi)
02076 {
02077 struct reg_cond_life_info *rcli;
02078 rtx cond;
02079
02080 rcli = XNEW (struct reg_cond_life_info);
02081
02082 if (REGNO_REG_SET_P (bb_true->il.rtl->global_live_at_start,
02083 i))
02084 cond = cond_false;
02085 else
02086 cond = cond_true;
02087 rcli->condition = cond;
02088 rcli->stores = const0_rtx;
02089 rcli->orig_condition = cond;
02090
02091 splay_tree_insert (pbi->reg_cond_dead, i,
02092 (splay_tree_value) rcli);
02093 }
02094 }
02095 }
02096
02097 FREE_REG_SET (diff);
02098 }
02099 #endif
02100
02101
02102
02103
02104
02105 if (optimize
02106 && ! (TREE_CODE (TREE_TYPE (current_function_decl)) == FUNCTION_TYPE
02107 && (TYPE_RETURNS_STACK_DEPRESSED
02108 (TREE_TYPE (current_function_decl))))
02109 && (flags & PROP_SCAN_DEAD_STORES)
02110 && (EDGE_COUNT (bb->succs) == 0
02111 || (single_succ_p (bb)
02112 && single_succ (bb) == EXIT_BLOCK_PTR
02113 && ! current_function_calls_eh_return)))
02114 {
02115 rtx insn, set;
02116 for (insn = BB_END (bb); insn != BB_HEAD (bb); insn = PREV_INSN (insn))
02117 if (NONJUMP_INSN_P (insn)
02118 && (set = single_set (insn))
02119 && MEM_P (SET_DEST (set)))
02120 {
02121 rtx mem = SET_DEST (set);
02122 rtx canon_mem = canon_rtx (mem);
02123
02124 if (XEXP (canon_mem, 0) == frame_pointer_rtx
02125 || (GET_CODE (XEXP (canon_mem, 0)) == PLUS
02126 && XEXP (XEXP (canon_mem, 0), 0) == frame_pointer_rtx
02127 && GET_CODE (XEXP (XEXP (canon_mem, 0), 1)) == CONST_INT))
02128 add_to_mem_set_list (pbi, canon_mem);
02129 }
02130 }
02131
02132 return pbi;
02133 }
02134
02135
02136
02137 void
02138 free_propagate_block_info (struct propagate_block_info *pbi)
02139 {
02140 free_EXPR_LIST_list (&pbi->mem_set_list);
02141
02142 BITMAP_FREE (pbi->new_set);
02143
02144 #ifdef HAVE_conditional_execution
02145 splay_tree_delete (pbi->reg_cond_dead);
02146 BITMAP_FREE (pbi->reg_cond_reg);
02147 #endif
02148
02149 if (pbi->flags & PROP_REG_INFO)
02150 {
02151 int num = pbi->insn_num;
02152 unsigned i;
02153 reg_set_iterator rsi;
02154
02155 EXECUTE_IF_SET_IN_REG_SET (pbi->reg_live, 0, i, rsi)
02156 {
02157 REG_LIVE_LENGTH (i) += num - reg_deaths[i];
02158 reg_deaths[i] = 0;
02159 }
02160 }
02161 if (pbi->reg_next_use)
02162 free (pbi->reg_next_use);
02163
02164 free (pbi);
02165 }
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185 int
02186 propagate_block (basic_block bb, regset live, regset local_set,
02187 regset cond_local_set, int flags)
02188 {
02189 struct propagate_block_info *pbi;
02190 rtx insn, prev;
02191 int changed;
02192
02193 pbi = init_propagate_block_info (bb, live, local_set, cond_local_set, flags);
02194
02195 if (flags & PROP_REG_INFO)
02196 {
02197 unsigned i;
02198 reg_set_iterator rsi;
02199
02200
02201
02202 EXECUTE_IF_SET_IN_REG_SET (live, 0, i, rsi)
02203 REG_BASIC_BLOCK (i) = REG_BLOCK_GLOBAL;
02204 }
02205
02206
02207
02208 changed = 0;
02209 for (insn = BB_END (bb); ; insn = prev)
02210 {
02211
02212
02213 if ((flags & PROP_REG_INFO)
02214 && CALL_P (insn)
02215 && find_reg_note (insn, REG_SETJMP, NULL))
02216 IOR_REG_SET (regs_live_at_setjmp, pbi->reg_live);
02217
02218 prev = propagate_one_insn (pbi, insn);
02219 if (!prev)
02220 changed |= insn != get_insns ();
02221 else
02222 changed |= NEXT_INSN (prev) != insn;
02223
02224 if (insn == BB_HEAD (bb))
02225 break;
02226 }
02227
02228 #ifdef EH_RETURN_DATA_REGNO
02229 if (bb_has_eh_pred (bb))
02230 {
02231 unsigned int i;
02232 for (i = 0; ; ++i)
02233 {
02234 unsigned regno = EH_RETURN_DATA_REGNO (i);
02235 if (regno == INVALID_REGNUM)
02236 break;
02237 if (pbi->local_set)
02238 {
02239 CLEAR_REGNO_REG_SET (pbi->cond_local_set, regno);
02240 SET_REGNO_REG_SET (pbi->local_set, regno);
02241 }
02242 if (REGNO_REG_SET_P (pbi->reg_live, regno))
02243 SET_REGNO_REG_SET (pbi->new_set, regno);
02244
02245 regs_ever_live[regno] = 1;
02246 }
02247 }
02248 #endif
02249
02250 free_propagate_block_info (pbi);
02251
02252 return changed;
02253 }
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264 static int
02265 insn_dead_p (struct propagate_block_info *pbi, rtx x, int call_ok,
02266 rtx notes ATTRIBUTE_UNUSED)
02267 {
02268 enum rtx_code code = GET_CODE (x);
02269
02270
02271 if (flag_non_call_exceptions && may_trap_p (x))
02272 return 0;
02273
02274 #ifdef AUTO_INC_DEC
02275
02276
02277 for (; notes; notes = XEXP (notes, 1))
02278 {
02279 if (REG_NOTE_KIND (notes) == REG_INC)
02280 {
02281 int regno = REGNO (XEXP (notes, 0));
02282
02283
02284 if ((regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
02285 || REGNO_REG_SET_P (pbi->reg_live, regno))
02286 return 0;
02287 }
02288 }
02289 #endif
02290
02291
02292
02293
02294 if (code == SET)
02295 {
02296 rtx r = SET_DEST (x);
02297
02298 #ifdef HAVE_cc0
02299 if (GET_CODE (r) == CC0)
02300 return ! pbi->cc0_live;
02301 #endif
02302
02303
02304 if (GET_CODE (SET_SRC (x)) == CALL)
02305 {
02306 if (! call_ok)
02307 return 0;
02308 }
02309
02310
02311 else if (volatile_refs_p (SET_SRC (x)))
02312 return 0;
02313
02314 if (MEM_P (r))
02315 {
02316 rtx temp, canon_r;
02317
02318 if (MEM_VOLATILE_P (r) || GET_MODE (r) == BLKmode)
02319 return 0;
02320
02321 canon_r = canon_rtx (r);
02322
02323
02324
02325
02326
02327
02328
02329 for (temp = pbi->mem_set_list; temp != 0; temp = XEXP (temp, 1))
02330 if (anti_dependence (r, XEXP (temp, 0)))
02331 {
02332 rtx mem = XEXP (temp, 0);
02333
02334 if (rtx_equal_p (XEXP (canon_r, 0), XEXP (mem, 0))
02335 && (GET_MODE_SIZE (GET_MODE (canon_r))
02336 <= GET_MODE_SIZE (GET_MODE (mem))))
02337 return 1;
02338
02339 #ifdef AUTO_INC_DEC
02340
02341
02342 if (GET_MODE (mem) == GET_MODE (r)
02343 && (GET_CODE (XEXP (mem, 0)) == POST_DEC
02344 || GET_CODE (XEXP (mem, 0)) == POST_INC
02345 || GET_CODE (XEXP (mem, 0)) == POST_MODIFY)
02346 && GET_MODE (XEXP (mem, 0)) == GET_MODE (r)
02347 && rtx_equal_p (XEXP (XEXP (mem, 0), 0), XEXP (r, 0)))
02348 return 1;
02349 #endif
02350 }
02351 }
02352 else
02353 {
02354 while (GET_CODE (r) == SUBREG
02355 || GET_CODE (r) == STRICT_LOW_PART
02356 || GET_CODE (r) == ZERO_EXTRACT)
02357 r = XEXP (r, 0);
02358
02359 if (REG_P (r))
02360 {
02361 int regno = REGNO (r);
02362
02363
02364 if (REGNO_REG_SET_P (pbi->reg_live, regno))
02365 return 0;
02366
02367
02368
02369 if (regno < FIRST_PSEUDO_REGISTER)
02370 {
02371 int n = hard_regno_nregs[regno][GET_MODE (r)];
02372
02373 while (--n > 0)
02374 if (REGNO_REG_SET_P (pbi->reg_live, regno+n))
02375 return 0;
02376 }
02377
02378
02379 if (regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
02380 return 0;
02381
02382
02383 if (regno == STACK_POINTER_REGNUM)
02384 return 0;
02385
02386
02387
02388
02389
02390
02391 if (regno == FRAME_POINTER_REGNUM
02392 && (! reload_completed || frame_pointer_needed))
02393 return 0;
02394 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
02395 if (regno == HARD_FRAME_POINTER_REGNUM
02396 && (! reload_completed || frame_pointer_needed))
02397 return 0;
02398 #endif
02399
02400 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
02401
02402
02403
02404 if (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
02405 return 0;
02406 #endif
02407
02408
02409 return 1;
02410 }
02411 }
02412 }
02413
02414
02415
02416
02417
02418 else if (code == PARALLEL)
02419 {
02420 int i = XVECLEN (x, 0);
02421
02422 for (i--; i >= 0; i--)
02423 if (GET_CODE (XVECEXP (x, 0, i)) != CLOBBER
02424 && GET_CODE (XVECEXP (x, 0, i)) != USE
02425 && ! insn_dead_p (pbi, XVECEXP (x, 0, i), call_ok, NULL_RTX))
02426 return 0;
02427
02428 return 1;
02429 }
02430
02431
02432
02433 else if (code == CLOBBER)
02434 {
02435 if (REG_P (XEXP (x, 0))
02436 && (REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER
02437 || reload_completed)
02438 && ! REGNO_REG_SET_P (pbi->reg_live, REGNO (XEXP (x, 0))))
02439 return 1;
02440 }
02441
02442
02443
02444
02445
02446
02447
02448 return 0;
02449 }
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466 static int
02467 libcall_dead_p (struct propagate_block_info *pbi, rtx note, rtx insn)
02468 {
02469 rtx x = single_set (insn);
02470
02471 if (x)
02472 {
02473 rtx r = SET_SRC (x);
02474
02475 if (REG_P (r) || GET_CODE (r) == SUBREG)
02476 {
02477 rtx call = XEXP (note, 0);
02478 rtx call_pat;
02479 int i;
02480
02481
02482 while (call != insn && !CALL_P (call))
02483 call = NEXT_INSN (call);
02484
02485
02486
02487 if (call == insn)
02488 return 0;
02489
02490
02491
02492 call_pat = PATTERN (call);
02493 if (GET_CODE (call_pat) == PARALLEL)
02494 {
02495 for (i = XVECLEN (call_pat, 0) - 1; i >= 0; i--)
02496 if (GET_CODE (XVECEXP (call_pat, 0, i)) == SET
02497 && GET_CODE (SET_SRC (XVECEXP (call_pat, 0, i))) == CALL)
02498 break;
02499
02500
02501
02502
02503 if (i < 0)
02504 return 0;
02505
02506 call_pat = XVECEXP (call_pat, 0, i);
02507 }
02508
02509 if (! insn_dead_p (pbi, call_pat, 1, REG_NOTES (call)))
02510 return 0;
02511
02512 while ((insn = PREV_INSN (insn)) != call)
02513 {
02514 if (! INSN_P (insn))
02515 continue;
02516 if (! insn_dead_p (pbi, PATTERN (insn), 0, REG_NOTES (insn)))
02517 return 0;
02518 }
02519 return 1;
02520 }
02521 }
02522 return 0;
02523 }
02524
02525
02526
02527
02528
02529 int
02530 regno_clobbered_at_setjmp (int regno)
02531 {
02532 if (n_basic_blocks == NUM_FIXED_BLOCKS)
02533 return 0;
02534
02535 return ((REG_N_SETS (regno) > 1
02536 || REGNO_REG_SET_P (ENTRY_BLOCK_PTR->il.rtl->global_live_at_end,
02537 regno))
02538 && REGNO_REG_SET_P (regs_live_at_setjmp, regno));
02539 }
02540
02541
02542
02543 static void
02544 add_to_mem_set_list (struct propagate_block_info *pbi, rtx mem)
02545 {
02546 rtx i;
02547
02548
02549
02550 if (GET_MODE (mem) == BLKmode)
02551 return;
02552
02553 for (i = pbi->mem_set_list; i ; i = XEXP (i, 1))
02554 {
02555 rtx e = XEXP (i, 0);
02556 if (rtx_equal_p (XEXP (mem, 0), XEXP (e, 0)))
02557 {
02558 if (GET_MODE_SIZE (GET_MODE (mem)) > GET_MODE_SIZE (GET_MODE (e)))
02559 {
02560 #ifdef AUTO_INC_DEC
02561
02562
02563 if (pbi->flags & PROP_AUTOINC)
02564 PUT_MODE (e, GET_MODE (mem));
02565 else
02566 #endif
02567 XEXP (i, 0) = mem;
02568 }
02569 return;
02570 }
02571 }
02572
02573 if (pbi->mem_set_list_len < PARAM_VALUE (PARAM_MAX_FLOW_MEMORY_LOCATIONS))
02574 {
02575 #ifdef AUTO_INC_DEC
02576
02577
02578 if (pbi->flags & PROP_AUTOINC)
02579 mem = shallow_copy_rtx (mem);
02580 #endif
02581 pbi->mem_set_list = alloc_EXPR_LIST (0, mem, pbi->mem_set_list);
02582 pbi->mem_set_list_len++;
02583 }
02584 }
02585
02586
02587
02588
02589
02590 static int
02591 invalidate_mems_from_autoinc (rtx *px, void *data)
02592 {
02593 rtx x = *px;
02594 struct propagate_block_info *pbi = data;
02595
02596 if (GET_RTX_CLASS (GET_CODE (x)) == RTX_AUTOINC)
02597 {
02598 invalidate_mems_from_set (pbi, XEXP (x, 0));
02599 return -1;
02600 }
02601
02602 return 0;
02603 }
02604
02605
02606
02607
02608 static void
02609 invalidate_mems_from_set (struct propagate_block_info *pbi, rtx exp)
02610 {
02611 rtx temp = pbi->mem_set_list;
02612 rtx prev = NULL_RTX;
02613 rtx next;
02614
02615 while (temp)
02616 {
02617 next = XEXP (temp, 1);
02618 if ((REG_P (exp) && reg_overlap_mentioned_p (exp, XEXP (temp, 0)))
02619
02620
02621
02622 || (MEM_P (exp)
02623 && reg_overlap_mentioned_p (exp, XEXP (XEXP (temp, 0), 0))))
02624 {
02625
02626 if (prev)
02627 XEXP (prev, 1) = next;
02628 else
02629 pbi->mem_set_list = next;
02630 free_EXPR_LIST_node (temp);
02631 pbi->mem_set_list_len--;
02632 }
02633 else
02634 prev = temp;
02635 temp = next;
02636 }
02637 }
02638
02639
02640
02641
02642
02643
02644
02645
02646 static void
02647 mark_set_regs (struct propagate_block_info *pbi, rtx x, rtx insn)
02648 {
02649 rtx cond = NULL_RTX;
02650 rtx link;
02651 enum rtx_code code;
02652 int flags = pbi->flags;
02653
02654 if (insn)
02655 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
02656 {
02657 if (REG_NOTE_KIND (link) == REG_INC)
02658 mark_set_1 (pbi, SET, XEXP (link, 0),
02659 (GET_CODE (x) == COND_EXEC
02660 ? COND_EXEC_TEST (x) : NULL_RTX),
02661 insn, flags);
02662 }
02663 retry:
02664 switch (code = GET_CODE (x))
02665 {
02666 case SET:
02667 if (GET_CODE (XEXP (x, 1)) == ASM_OPERANDS)
02668 flags |= PROP_ASM_SCAN;
02669
02670 case CLOBBER:
02671 mark_set_1 (pbi, code, SET_DEST (x), cond, insn, flags);
02672 return;
02673
02674 case COND_EXEC:
02675 cond = COND_EXEC_TEST (x);
02676 x = COND_EXEC_CODE (x);
02677 goto retry;
02678
02679 case PARALLEL:
02680 {
02681 int i;
02682
02683
02684
02685 for (i = 0; i < XVECLEN (x, 0); i++)
02686 {
02687 rtx sub = XVECEXP (x, 0, i);
02688 switch (code = GET_CODE (sub))
02689 {
02690 case COND_EXEC:
02691 gcc_assert (!cond);
02692
02693 cond = COND_EXEC_TEST (sub);
02694 sub = COND_EXEC_CODE (sub);
02695 if (GET_CODE (sub) == SET)
02696 goto mark_set;
02697 if (GET_CODE (sub) == CLOBBER)
02698 goto mark_clob;
02699 break;
02700
02701 case SET:
02702 mark_set:
02703 if (GET_CODE (XEXP (sub, 1)) == ASM_OPERANDS)
02704 flags |= PROP_ASM_SCAN;
02705
02706 case CLOBBER:
02707 mark_clob:
02708 mark_set_1 (pbi, code, SET_DEST (sub), cond, insn, flags);
02709 break;
02710
02711 case ASM_OPERANDS:
02712 flags |= PROP_ASM_SCAN;
02713 break;
02714
02715 default:
02716 break;
02717 }
02718 }
02719 break;
02720 }
02721
02722 default:
02723 break;
02724 }
02725 }
02726
02727
02728
02729
02730
02731
02732
02733 static void
02734 mark_set_1 (struct propagate_block_info *pbi, enum rtx_code code, rtx reg, rtx cond, rtx insn, int flags)
02735 {
02736 int regno_first = -1, regno_last = -1;
02737 unsigned long not_dead = 0;
02738 int i;
02739
02740
02741
02742
02743
02744 switch (GET_CODE (reg))
02745 {
02746 case PARALLEL:
02747
02748
02749
02750 for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
02751 if (XEXP (XVECEXP (reg, 0, i), 0) != 0)
02752 mark_set_1 (pbi, code, XEXP (XVECEXP (reg, 0, i), 0), cond, insn,
02753 flags);
02754 return;
02755
02756 case SIGN_EXTRACT:
02757
02758 gcc_unreachable ();
02759
02760 case ZERO_EXTRACT:
02761 case STRICT_LOW_PART:
02762
02763 do
02764 reg = XEXP (reg, 0);
02765 while (GET_CODE (reg) == SUBREG
02766 || GET_CODE (reg) == ZERO_EXTRACT
02767 || GET_CODE (reg) == STRICT_LOW_PART);
02768 if (MEM_P (reg))
02769 break;
02770 not_dead = (unsigned long) REGNO_REG_SET_P (pbi->reg_live, REGNO (reg));
02771
02772
02773 case REG:
02774 regno_last = regno_first = REGNO (reg);
02775 if (regno_first < FIRST_PSEUDO_REGISTER)
02776 regno_last += hard_regno_nregs[regno_first][GET_MODE (reg)] - 1;
02777 break;
02778
02779 case SUBREG:
02780 if (REG_P (SUBREG_REG (reg)))
02781 {
02782 enum machine_mode outer_mode = GET_MODE (reg);
02783 enum machine_mode inner_mode = GET_MODE (SUBREG_REG (reg));
02784
02785
02786
02787
02788 regno_last = regno_first = REGNO (SUBREG_REG (reg));
02789 if (regno_first < FIRST_PSEUDO_REGISTER)
02790 {
02791 regno_first += subreg_regno_offset (regno_first, inner_mode,
02792 SUBREG_BYTE (reg),
02793 outer_mode);
02794 regno_last = (regno_first
02795 + hard_regno_nregs[regno_first][outer_mode] - 1);
02796
02797
02798
02799
02800
02801 reg = gen_rtx_REG (outer_mode, regno_first);
02802 }
02803 else
02804 {
02805
02806
02807
02808
02809
02810
02811 if (((GET_MODE_SIZE (outer_mode)
02812 + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
02813 < ((GET_MODE_SIZE (inner_mode)
02814 + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
02815 not_dead = (unsigned long) REGNO_REG_SET_P (pbi->reg_live,
02816 regno_first);
02817
02818 reg = SUBREG_REG (reg);
02819 }
02820 }
02821 else
02822 reg = SUBREG_REG (reg);
02823 break;
02824
02825 default:
02826 break;
02827 }
02828
02829
02830
02831
02832 if (optimize && (flags & PROP_SCAN_DEAD_STORES))
02833 {
02834 if (REG_P (reg) || MEM_P (reg))
02835 invalidate_mems_from_set (pbi, reg);
02836
02837
02838
02839
02840 if (insn && MEM_P (reg))
02841 for_each_rtx (&PATTERN (insn), invalidate_mems_from_autoinc, pbi);
02842
02843 if (MEM_P (reg) && ! side_effects_p (reg)
02844
02845 && ! cond)
02846 add_to_mem_set_list (pbi, canon_rtx (reg));
02847 }
02848
02849 if (REG_P (reg)
02850 && ! (regno_first == FRAME_POINTER_REGNUM
02851 && (! reload_completed || frame_pointer_needed))
02852 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
02853 && ! (regno_first == HARD_FRAME_POINTER_REGNUM
02854 && (! reload_completed || frame_pointer_needed))
02855 #endif
02856 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
02857 && ! (regno_first == ARG_POINTER_REGNUM && fixed_regs[regno_first])
02858 #endif
02859 )
02860 {
02861 int some_was_live = 0, some_was_dead = 0;
02862
02863 for (i = regno_first; i <= regno_last; ++i)
02864 {
02865 int needed_regno = REGNO_REG_SET_P (pbi->reg_live, i);
02866 if (pbi->local_set)
02867 {
02868
02869
02870 CLEAR_REGNO_REG_SET (pbi->cond_local_set, i);
02871 if (cond != NULL_RTX
02872 && ! REGNO_REG_SET_P (pbi->local_set, i))
02873 SET_REGNO_REG_SET (pbi->cond_local_set, i);
02874 else
02875 SET_REGNO_REG_SET (pbi->local_set, i);
02876 }
02877 if (code != CLOBBER || needed_regno)
02878 SET_REGNO_REG_SET (pbi->new_set, i);
02879
02880 some_was_live |= needed_regno;
02881 some_was_dead |= ! needed_regno;
02882 }
02883
02884 #ifdef HAVE_conditional_execution
02885
02886
02887 if (some_was_live && ! not_dead
02888
02889
02890
02891
02892 && regno_first != STACK_POINTER_REGNUM)
02893 {
02894 for (i = regno_first; i <= regno_last; ++i)
02895 if (! mark_regno_cond_dead (pbi, i, cond))
02896 not_dead |= ((unsigned long) 1) << (i - regno_first);
02897 }
02898 #endif
02899
02900
02901 if (flags & (PROP_LOG_LINKS | PROP_REG_INFO
02902 | PROP_DEATH_NOTES | PROP_AUTOINC))
02903 {
02904 rtx y;
02905 int blocknum = pbi->bb->index;
02906
02907 y = NULL_RTX;
02908 if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
02909 {
02910 y = pbi->reg_next_use[regno_first];
02911
02912
02913 for (i = regno_first; i <= regno_last; ++i)
02914 pbi->reg_next_use[i] = 0;
02915 }
02916
02917 if (flags & PROP_REG_INFO)
02918 {
02919 for (i = regno_first; i <= regno_last; ++i)
02920 {
02921
02922
02923 REG_N_SETS (i) += 1;
02924 REG_N_REFS (i) += 1;
02925 REG_FREQ (i) += REG_FREQ_FROM_BB (pbi->bb);
02926
02927
02928
02929
02930
02931 REG_LIVE_LENGTH (i) += 1;
02932 }
02933
02934
02935 if (regno_first < FIRST_PSEUDO_REGISTER)
02936 {
02937 for (i = regno_first; i <= regno_last; i++)
02938 regs_ever_live[i] = 1;
02939 if (flags & PROP_ASM_SCAN)
02940 for (i = regno_first; i <= regno_last; i++)
02941 regs_asm_clobbered[i] = 1;
02942 }
02943 else
02944 {
02945
02946 if (REG_BASIC_BLOCK (regno_first) == REG_BLOCK_UNKNOWN)
02947 REG_BASIC_BLOCK (regno_first) = blocknum;
02948 else if (REG_BASIC_BLOCK (regno_first) != blocknum)
02949 REG_BASIC_BLOCK (regno_first) = REG_BLOCK_GLOBAL;
02950 }
02951 }
02952
02953 if (! some_was_dead)
02954 {
02955 if (flags & PROP_LOG_LINKS)
02956 {
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971 if (y && (BLOCK_NUM (y) == blocknum)
02972 && (regno_first >= FIRST_PSEUDO_REGISTER
02973 || (asm_noperands (PATTERN (y)) < 0
02974 && ! ((CALL_P (insn)
02975 || CALL_P (y))
02976 && global_regs[regno_first]))))
02977 LOG_LINKS (y) = alloc_INSN_LIST (insn, LOG_LINKS (y));
02978 }
02979 }
02980 else if (not_dead)
02981 ;
02982 else if (! some_was_live)
02983 {
02984 if (flags & PROP_REG_INFO)
02985 REG_N_DEATHS (regno_first) += 1;
02986
02987 if (flags & PROP_DEATH_NOTES
02988 #ifdef STACK_REGS
02989 && (!(flags & PROP_POST_REGSTACK)
02990 || !IN_RANGE (REGNO (reg), FIRST_STACK_REG,
02991 LAST_STACK_REG))
02992 #endif
02993 )
02994 {
02995
02996
02997
02998
02999
03000 REG_NOTES (insn)
03001 = alloc_EXPR_LIST (REG_UNUSED, reg, REG_NOTES (insn));
03002 }
03003 }
03004 else
03005 {
03006 if (flags & PROP_DEATH_NOTES
03007 #ifdef STACK_REGS
03008 && (!(flags & PROP_POST_REGSTACK)
03009 || !IN_RANGE (REGNO (reg), FIRST_STACK_REG,
03010 LAST_STACK_REG))
03011 #endif
03012 )
03013 {
03014
03015
03016
03017
03018
03019
03020 for (i = regno_first; i <= regno_last; ++i)
03021 if (! REGNO_REG_SET_P (pbi->reg_live, i))
03022 REG_NOTES (insn)
03023 = alloc_EXPR_LIST (REG_UNUSED,
03024 regno_reg_rtx[i],
03025 REG_NOTES (insn));
03026 }
03027 }
03028 }
03029
03030
03031 if (some_was_live
03032
03033
03034
03035
03036 && regno_first != STACK_POINTER_REGNUM)
03037 {
03038 for (i = regno_first; i <= regno_last; ++i)
03039 if (!(not_dead & (((unsigned long) 1) << (i - regno_first))))
03040 {
03041 if ((pbi->flags & PROP_REG_INFO)
03042 && REGNO_REG_SET_P (pbi->reg_live, i))
03043 {
03044 REG_LIVE_LENGTH (i) += pbi->insn_num - reg_deaths[i];
03045 reg_deaths[i] = 0;
03046 }
03047 CLEAR_REGNO_REG_SET (pbi->reg_live, i);
03048 }
03049 if (flags & PROP_DEAD_INSN)
03050 emit_insn_after (gen_rtx_CLOBBER (VOIDmode, reg), insn);
03051 }
03052 }
03053 else if (REG_P (reg))
03054 {
03055 if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
03056 pbi->reg_next_use[regno_first] = 0;
03057
03058 if ((flags & PROP_REG_INFO) != 0
03059 && (flags & PROP_ASM_SCAN) != 0
03060 && regno_first < FIRST_PSEUDO_REGISTER)
03061 {
03062 for (i = regno_first; i <= regno_last; i++)
03063 regs_asm_clobbered[i] = 1;
03064 }
03065 }
03066
03067
03068
03069 else if (GET_CODE (reg) == SCRATCH)
03070 {
03071 if (flags & PROP_DEATH_NOTES
03072 #ifdef STACK_REGS
03073 && (!(flags & PROP_POST_REGSTACK)
03074 || !IN_RANGE (REGNO (reg), FIRST_STACK_REG, LAST_STACK_REG))
03075 #endif
03076 )
03077 REG_NOTES (insn)
03078 = alloc_EXPR_LIST (REG_UNUSED, reg, REG_NOTES (insn));
03079 }
03080 }
03081
03082 #ifdef HAVE_conditional_execution
03083
03084
03085
03086 static int
03087 mark_regno_cond_dead (struct propagate_block_info *pbi, int regno, rtx cond)
03088 {
03089
03090
03091
03092
03093
03094 if (REGNO_REG_SET_P (pbi->reg_cond_reg, regno))
03095 flush_reg_cond_reg (pbi, regno);
03096
03097
03098
03099 if (cond == NULL_RTX)
03100 splay_tree_remove (pbi->reg_cond_dead, regno);
03101 else
03102 {
03103 splay_tree_node node;
03104 struct reg_cond_life_info *rcli;
03105 rtx ncond;
03106
03107
03108
03109
03110
03111 node = splay_tree_lookup (pbi->reg_cond_dead, regno);
03112 if (node == NULL)
03113 {
03114
03115
03116
03117 rcli = XNEW (struct reg_cond_life_info);
03118 rcli->condition = cond;
03119 rcli->stores = cond;
03120 rcli->orig_condition = const0_rtx;
03121 splay_tree_insert (pbi->reg_cond_dead, regno,
03122 (splay_tree_value) rcli);
03123
03124 SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (XEXP (cond, 0)));
03125
03126
03127 return 0;
03128 }
03129 else
03130 {
03131
03132
03133 rcli = (struct reg_cond_life_info *) node->value;
03134 ncond = rcli->condition;
03135 ncond = ior_reg_cond (ncond, cond, 1);
03136 if (rcli->stores == const0_rtx)
03137 rcli->stores = cond;
03138 else if (rcli->stores != const1_rtx)
03139 rcli->stores = ior_reg_cond (rcli->stores, cond, 1);
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149 if (ncond == const1_rtx
03150 || (ncond == rcli->orig_condition && rcli->stores == const1_rtx))
03151 splay_tree_remove (pbi->reg_cond_dead, regno);
03152 else
03153 {
03154 rcli->condition = ncond;
03155
03156 SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (XEXP (cond, 0)));
03157
03158
03159 return 0;
03160 }
03161 }
03162 }
03163
03164 return 1;
03165 }
03166
03167
03168
03169 static void
03170 free_reg_cond_life_info (splay_tree_value value)
03171 {
03172 struct reg_cond_life_info *rcli = (struct reg_cond_life_info *) value;
03173 free (rcli);
03174 }
03175
03176
03177
03178 static int
03179 flush_reg_cond_reg_1 (splay_tree_node node, void *data)
03180 {
03181 struct reg_cond_life_info *rcli;
03182 int *xdata = (int *) data;
03183 unsigned int regno = xdata[0];
03184
03185
03186
03187 if (xdata[1] >= (int) node->key)
03188 return 0;
03189
03190
03191 rcli = (struct reg_cond_life_info *) node->value;
03192 rcli->condition = elim_reg_cond (rcli->condition, regno);
03193 if (rcli->stores != const0_rtx && rcli->stores != const1_rtx)
03194 rcli->stores = elim_reg_cond (rcli->stores, regno);
03195
03196
03197 if (rcli->condition == const0_rtx)
03198 {
03199 xdata[1] = node->key;
03200 return -1;
03201 }
03202 else
03203 gcc_assert (rcli->condition != const1_rtx);
03204
03205 return 0;
03206 }
03207
03208
03209
03210 static void
03211 flush_reg_cond_reg (struct propagate_block_info *pbi, int regno)
03212 {
03213 int pair[2];
03214
03215 pair[0] = regno;
03216 pair[1] = -1;
03217 while (splay_tree_foreach (pbi->reg_cond_dead,
03218 flush_reg_cond_reg_1, pair) == -1)
03219 splay_tree_remove (pbi->reg_cond_dead, pair[1]);
03220
03221 CLEAR_REGNO_REG_SET (pbi->reg_cond_reg, regno);
03222 }
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233 static rtx
03234 ior_reg_cond (rtx old, rtx x, int add)
03235 {
03236 rtx op0, op1;
03237
03238 if (COMPARISON_P (old))
03239 {
03240 if (COMPARISON_P (x)
03241 && REVERSE_CONDEXEC_PREDICATES_P (x, old)
03242 && REGNO (XEXP (x, 0)) == REGNO (XEXP (old, 0)))
03243 return const1_rtx;
03244 if (GET_CODE (x) == GET_CODE (old)
03245 && REGNO (XEXP (x, 0)) == REGNO (XEXP (old, 0)))
03246 return old;
03247 if (! add)
03248 return NULL;
03249 return gen_rtx_IOR (0, old, x);
03250 }
03251
03252 switch (GET_CODE (old))
03253 {
03254 case IOR:
03255 op0 = ior_reg_cond (XEXP (old, 0), x, 0);
03256 op1 = ior_reg_cond (XEXP (old, 1), x, 0);
03257 if (op0 != NULL || op1 != NULL)
03258 {
03259 if (op0 == const0_rtx)
03260 return op1 ? op1 : gen_rtx_IOR (0, XEXP (old, 1), x);
03261 if (op1 == const0_rtx)
03262 return op0 ? op0 : gen_rtx_IOR (0, XEXP (old, 0), x);
03263 if (op0 == const1_rtx || op1 == const1_rtx)
03264 return const1_rtx;
03265 if (op0 == NULL)
03266 op0 = gen_rtx_IOR (0, XEXP (old, 0), x);
03267 else if (rtx_equal_p (x, op0))
03268
03269 return old;
03270 if (op1 == NULL)
03271 op1 = gen_rtx_IOR (0, XEXP (old, 1), x);
03272 else if (rtx_equal_p (x, op1))
03273
03274 return old;
03275 return gen_rtx_IOR (0, op0, op1);
03276 }
03277 if (! add)
03278 return NULL;
03279 return gen_rtx_IOR (0, old, x);
03280
03281 case AND:
03282 op0 = ior_reg_cond (XEXP (old, 0), x, 0);
03283 op1 = ior_reg_cond (XEXP (old, 1), x, 0);
03284 if (op0 != NULL || op1 != NULL)
03285 {
03286 if (op0 == const1_rtx)
03287 return op1 ? op1 : gen_rtx_IOR (0, XEXP (old, 1), x);
03288 if (op1 == const1_rtx)
03289 return op0 ? op0 : gen_rtx_IOR (0, XEXP (old, 0), x);
03290 if (op0 == const0_rtx || op1 == const0_rtx)
03291 return const0_rtx;
03292 if (op0 == NULL)
03293 op0 = gen_rtx_IOR (0, XEXP (old, 0), x);
03294 else if (rtx_equal_p (x, op0))
03295
03296 return op0;
03297 if (op1 == NULL)
03298 op1 = gen_rtx_IOR (0, XEXP (old, 1), x);
03299 else if (rtx_equal_p (x, op1))
03300
03301 return op1;
03302 return gen_rtx_AND (0, op0, op1);
03303 }
03304 if (! add)
03305 return NULL;
03306 return gen_rtx_IOR (0, old, x);
03307
03308 case NOT:
03309 op0 = and_reg_cond (XEXP (old, 0), not_reg_cond (x), 0);
03310 if (op0 != NULL)
03311 return not_reg_cond (op0);
03312 if (! add)
03313 return NULL;
03314 return gen_rtx_IOR (0, old, x);
03315
03316 default:
03317 gcc_unreachable ();
03318 }
03319 }
03320
03321 static rtx
03322 not_reg_cond (rtx x)
03323 {
03324 if (x == const0_rtx)
03325 return const1_rtx;
03326 else if (x == const1_rtx)
03327 return const0_rtx;
03328 if (GET_CODE (x) == NOT)
03329 return XEXP (x, 0);
03330 if (COMPARISON_P (x)
03331 && REG_P (XEXP (x, 0)))
03332 {
03333 gcc_assert (XEXP (x, 1) == const0_rtx);
03334
03335 return gen_rtx_fmt_ee (reversed_comparison_code (x, NULL),
03336 VOIDmode, XEXP (x, 0), const0_rtx);
03337 }
03338 return gen_rtx_NOT (0, x);
03339 }
03340
03341 static rtx
03342 and_reg_cond (rtx old, rtx x, int add)
03343 {
03344 rtx op0, op1;
03345
03346 if (COMPARISON_P (old))
03347 {
03348 if (COMPARISON_P (x)
03349 && GET_CODE (x) == reversed_comparison_code (old, NULL)
03350 && REGNO (XEXP (x, 0)) == REGNO (XEXP (old, 0)))
03351 return const0_rtx;
03352 if (GET_CODE (x) == GET_CODE (old)
03353 && REGNO (XEXP (x, 0)) == REGNO (XEXP (old, 0)))
03354 return old;
03355 if (! add)
03356 return NULL;
03357 return gen_rtx_AND (0, old, x);
03358 }
03359
03360 switch (GET_CODE (old))
03361 {
03362 case IOR:
03363 op0 = and_reg_cond (XEXP (old, 0), x, 0);
03364 op1 = and_reg_cond (XEXP (old, 1), x, 0);
03365 if (op0 != NULL || op1 != NULL)
03366 {
03367 if (op0 == const0_rtx)
03368 return op1 ? op1 : gen_rtx_AND (0, XEXP (old, 1), x);
03369 if (op1 == const0_rtx)
03370 return op0 ? op0 : gen_rtx_AND (0, XEXP (old, 0), x);
03371 if (op0 == const1_rtx || op1 == const1_rtx)
03372 return const1_rtx;
03373 if (op0 == NULL)
03374 op0 = gen_rtx_AND (0, XEXP (old, 0), x);
03375 else if (rtx_equal_p (x, op0))
03376
03377 return op0;
03378 if (op1 == NULL)
03379 op1 = gen_rtx_AND (0, XEXP (old, 1), x);
03380 else if (rtx_equal_p (x, op1))
03381
03382 return op1;
03383 return gen_rtx_IOR (0, op0, op1);
03384 }
03385 if (! add)
03386 return NULL;
03387 return gen_rtx_AND (0, old, x);
03388
03389 case AND:
03390 op0 = and_reg_cond (XEXP (old, 0), x, 0);
03391 op1 = and_reg_cond (XEXP (old, 1), x, 0);
03392 if (op0 != NULL || op1 != NULL)
03393 {
03394 if (op0 == const1_rtx)
03395 return op1 ? op1 : gen_rtx_AND (0, XEXP (old, 1), x);
03396 if (op1 == const1_rtx)
03397 return op0 ? op0 : gen_rtx_AND (0, XEXP (old, 0), x);
03398 if (op0 == const0_rtx || op1 == const0_rtx)
03399 return const0_rtx;
03400 if (op0 == NULL)
03401 op0 = gen_rtx_AND (0, XEXP (old, 0), x);
03402 else if (rtx_equal_p (x, op0))
03403
03404 return old;
03405 if (op1 == NULL)
03406 op1 = gen_rtx_AND (0, XEXP (old, 1), x);
03407 else if (rtx_equal_p (x, op1))
03408
03409 return old;
03410 return gen_rtx_AND (0, op0, op1);
03411 }
03412 if (! add)
03413 return NULL;
03414 return gen_rtx_AND (0, old, x);
03415
03416 case NOT:
03417 op0 = ior_reg_cond (XEXP (old, 0), not_reg_cond (x), 0);
03418 if (op0 != NULL)
03419 return not_reg_cond (op0);
03420 if (! add)
03421 return NULL;
03422 return gen_rtx_AND (0, old, x);
03423
03424 default:
03425 gcc_unreachable ();
03426 }
03427 }
03428
03429
03430
03431
03432
03433
03434 static rtx
03435 elim_reg_cond (rtx x, unsigned int regno)
03436 {
03437 rtx op0, op1;
03438
03439 if (COMPARISON_P (x))
03440 {
03441 if (REGNO (XEXP (x, 0)) == regno)
03442 return const0_rtx;
03443 return x;
03444 }
03445
03446 switch (GET_CODE (x))
03447 {
03448 case AND:
03449 op0 = elim_reg_cond (XEXP (x, 0), regno);
03450 op1 = elim_reg_cond (XEXP (x, 1), regno);
03451 if (op0 == const0_rtx || op1 == const0_rtx)
03452 return const0_rtx;
03453 if (op0 == const1_rtx)
03454 return op1;
03455 if (op1 == const1_rtx)
03456 return op0;
03457 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
03458 return x;
03459 return gen_rtx_AND (0, op0, op1);
03460
03461 case IOR:
03462 op0 = elim_reg_cond (XEXP (x, 0), regno);
03463 op1 = elim_reg_cond (XEXP (x, 1), regno);
03464 if (op0 == const1_rtx || op1 == const1_rtx)
03465 return const1_rtx;
03466 if (op0 == const0_rtx)
03467 return op1;
03468 if (op1 == const0_rtx)
03469 return op0;
03470 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
03471 return x;
03472 return gen_rtx_IOR (0, op0, op1);
03473
03474 case NOT:
03475 op0 = elim_reg_cond (XEXP (x, 0), regno);
03476 if (op0 == const0_rtx)
03477 return const1_rtx;
03478 if (op0 == const1_rtx)
03479 return const0_rtx;
03480 if (op0 != XEXP (x, 0))
03481 return not_reg_cond (op0);
03482 return x;
03483
03484 default:
03485 gcc_unreachable ();
03486 }
03487 }
03488 #endif
03489
03490 #ifdef AUTO_INC_DEC
03491
03492
03493
03494
03495
03496
03497
03498 static void
03499 attempt_auto_inc (struct propagate_block_info *pbi, rtx inc, rtx insn,
03500 rtx mem, rtx incr, rtx incr_reg)
03501 {
03502 int regno = REGNO (incr_reg);
03503 rtx set = single_set (incr);
03504 rtx q = SET_DEST (set);
03505 rtx y = SET_SRC (set);
03506 int opnum = XEXP (y, 0) == incr_reg ? 0 : 1;
03507 int changed;
03508
03509
03510 if (count_occurrences (PATTERN (insn), incr_reg, 1) != 1)
03511 return;
03512
03513 if (dead_or_set_p (incr, incr_reg)
03514
03515 && (regno >= FIRST_PSEUDO_REGISTER
03516 || ! TEST_HARD_REG_BIT (elim_reg_set, regno)))
03517 {
03518
03519
03520
03521 if (! validate_change (insn, &XEXP (mem, 0), inc, 0))
03522 return;
03523 }
03524 else if (REG_P (q)
03525
03526
03527 && ! reg_used_between_p (q, PREV_INSN (insn), incr)
03528
03529
03530
03531 && ! reg_set_between_p (q, PREV_INSN (insn), incr))
03532 {
03533
03534
03535
03536
03537
03538 rtx insns, temp;
03539
03540 start_sequence ();
03541 emit_move_insn (q, incr_reg);
03542 insns = get_insns ();
03543 end_sequence ();
03544
03545
03546
03547
03548
03549
03550 XEXP (inc, 0) = q;
03551 validate_change (insn, &XEXP (mem, 0), inc, 1);
03552 validate_change (incr, &XEXP (y, opnum), q, 1);
03553 if (! apply_change_group ())
03554 return;
03555
03556
03557
03558 emit_insn_before (insns, insn);
03559
03560 if (BB_HEAD (pbi->bb) == insn)
03561 BB_HEAD (pbi->bb) = insns;
03562
03563
03564
03565
03566
03567 if (NONJUMP_INSN_P (PREV_INSN (insn))
03568 && GET_CODE (PATTERN (PREV_INSN (insn))) == SET
03569 && SET_SRC (PATTERN (PREV_INSN (insn))) == incr_reg)
03570 pbi->reg_next_use[regno] = PREV_INSN (insn);
03571 else
03572 pbi->reg_next_use[regno] = 0;
03573
03574 incr_reg = q;
03575 regno = REGNO (q);
03576
03577 if ((pbi->flags & PROP_REG_INFO)
03578 && !REGNO_REG_SET_P (pbi->reg_live, regno))
03579 reg_deaths[regno] = pbi->insn_num;
03580
03581
03582
03583
03584
03585 SET_REGNO_REG_SET (pbi->reg_live, regno);
03586
03587
03588
03589 for (temp = insn; temp != incr; temp = NEXT_INSN (temp))
03590 if (CALL_P (temp))
03591 {
03592 REG_N_CALLS_CROSSED (regno)++;
03593 if (can_throw_internal (temp))
03594 REG_N_THROWING_CALLS_CROSSED (regno)++;
03595 }
03596
03597
03598 clear_reg_alias_info (q);
03599 }
03600 else
03601 return;
03602
03603
03604
03605
03606
03607 REG_NOTES (insn) = alloc_EXPR_LIST (REG_INC, incr_reg, REG_NOTES (insn));
03608
03609
03610
03611 changed = validate_change (incr, &SET_SRC (set), incr_reg, 0);
03612 gcc_assert (changed);
03613
03614
03615
03616
03617 if (REGNO (SET_DEST (set)) == REGNO (incr_reg))
03618 {
03619
03620 rtx note;
03621
03622 while ((note = find_reg_note (incr, REG_DEAD, NULL_RTX)) != NULL_RTX)
03623 {
03624 remove_note (incr, note);
03625 if (XEXP (note, 0) != incr_reg)
03626 {
03627 unsigned int regno = REGNO (XEXP (note, 0));
03628
03629 if ((pbi->flags & PROP_REG_INFO)
03630 && REGNO_REG_SET_P (pbi->reg_live, regno))
03631 {
03632 REG_LIVE_LENGTH (regno) += pbi->insn_num - reg_deaths[regno];
03633 reg_deaths[regno] = 0;
03634 }
03635 CLEAR_REGNO_REG_SET (pbi->reg_live, REGNO (XEXP (note, 0)));
03636 }
03637 }
03638
03639 SET_INSN_DELETED (incr);
03640 }
03641
03642 if (regno >= FIRST_PSEUDO_REGISTER)
03643 {
03644
03645
03646
03647 REG_FREQ (regno) += REG_FREQ_FROM_BB (pbi->bb);
03648
03649
03650
03651 REG_N_SETS (regno)++;
03652 }
03653 }
03654
03655
03656
03657
03658 static void
03659 find_auto_inc (struct propagate_block_info *pbi, rtx x, rtx insn)
03660 {
03661 rtx addr = XEXP (x, 0);
03662 HOST_WIDE_INT offset = 0;
03663 rtx set, y, incr, inc_val;
03664 int regno;
03665 int size = GET_MODE_SIZE (GET_MODE (x));
03666
03667 if (JUMP_P (insn))
03668 return;
03669
03670
03671
03672
03673 if (GET_CODE (addr) == PLUS && GET_CODE (XEXP (addr, 1)) == CONST_INT)
03674 offset = INTVAL (XEXP (addr, 1)), addr = XEXP (addr, 0);
03675
03676 if (!REG_P (addr))
03677 return;
03678
03679 regno = REGNO (addr);
03680
03681
03682 incr = pbi->reg_next_use[regno];
03683 if (incr == 0 || BLOCK_NUM (incr) != BLOCK_NUM (insn))
03684 return;
03685 set = single_set (incr);
03686 if (set == 0 || GET_CODE (set) != SET)
03687 return;
03688 y = SET_SRC (set);
03689
03690 if (GET_CODE (y) != PLUS)
03691 return;
03692
03693 if (REG_P (XEXP (y, 0)) && REGNO (XEXP (y, 0)) == REGNO (addr))
03694 inc_val = XEXP (y, 1);
03695 else if (REG_P (XEXP (y, 1)) && REGNO (XEXP (y, 1)) == REGNO (addr))
03696 inc_val = XEXP (y, 0);
03697 else
03698 return;
03699
03700 if (GET_CODE (inc_val) == CONST_INT)
03701 {
03702 if (HAVE_POST_INCREMENT
03703 && (INTVAL (inc_val) == size && offset == 0))
03704 attempt_auto_inc (pbi, gen_rtx_POST_INC (Pmode, addr), insn, x,
03705 incr, addr);
03706 else if (HAVE_POST_DECREMENT
03707 && (INTVAL (inc_val) == -size && offset == 0))
03708 attempt_auto_inc (pbi, gen_rtx_POST_DEC (Pmode, addr), insn, x,
03709 incr, addr);
03710 else if (HAVE_PRE_INCREMENT
03711 && (INTVAL (inc_val) == size && offset == size))
03712 attempt_auto_inc (pbi, gen_rtx_PRE_INC (Pmode, addr), insn, x,
03713 incr, addr);
03714 else if (HAVE_PRE_DECREMENT
03715 && (INTVAL (inc_val) == -size && offset == -size))
03716 attempt_auto_inc (pbi, gen_rtx_PRE_DEC (Pmode, addr), insn, x,
03717 incr, addr);
03718 else if (HAVE_POST_MODIFY_DISP && offset == 0)
03719 attempt_auto_inc (pbi, gen_rtx_POST_MODIFY (Pmode, addr,
03720 gen_rtx_PLUS (Pmode,
03721 addr,
03722 inc_val)),
03723 insn, x, incr, addr);
03724 else if (HAVE_PRE_MODIFY_DISP && offset == INTVAL (inc_val))
03725 attempt_auto_inc (pbi, gen_rtx_PRE_MODIFY (Pmode, addr,
03726 gen_rtx_PLUS (Pmode,
03727 addr,
03728 inc_val)),
03729 insn, x, incr, addr);
03730 }
03731 else if (REG_P (inc_val)
03732 && ! reg_set_between_p (inc_val, PREV_INSN (insn),
03733 NEXT_INSN (incr)))
03734
03735 {
03736 if (HAVE_POST_MODIFY_REG && offset == 0)
03737 attempt_auto_inc (pbi, gen_rtx_POST_MODIFY (Pmode, addr,
03738 gen_rtx_PLUS (Pmode,
03739 addr,
03740 inc_val)),
03741 insn, x, incr, addr);
03742 }
03743 }
03744
03745 #endif
03746
03747 static void
03748 mark_used_reg (struct propagate_block_info *pbi, rtx reg,
03749 rtx cond ATTRIBUTE_UNUSED, rtx insn)
03750 {
03751 unsigned int regno_first, regno_last, i;
03752 int some_was_live, some_was_dead, some_not_set;
03753
03754 regno_last = regno_first = REGNO (reg);
03755 if (regno_first < FIRST_PSEUDO_REGISTER)
03756 regno_last += hard_regno_nregs[regno_first][GET_MODE (reg)] - 1;
03757
03758
03759 some_was_live = some_was_dead = 0;
03760 for (i = regno_first; i <= regno_last; ++i)
03761 {
03762 int needed_regno = REGNO_REG_SET_P (pbi->reg_live, i);
03763 some_was_live |= needed_regno;
03764 some_was_dead |= ! needed_regno;
03765 }
03766
03767
03768 some_not_set = 0;
03769 for (i = regno_first; i <= regno_last; ++i)
03770 some_not_set |= ! REGNO_REG_SET_P (pbi->new_set, i);
03771
03772 if (pbi->flags & (PROP_LOG_LINKS | PROP_AUTOINC))
03773 {
03774
03775
03776 pbi->reg_next_use[regno_first] = insn;
03777 }
03778
03779 if (pbi->flags & PROP_REG_INFO)
03780 {
03781 if (regno_first < FIRST_PSEUDO_REGISTER)
03782 {
03783
03784
03785
03786
03787
03788
03789
03790
03791
03792
03793
03794
03795 if (! (TEST_HARD_REG_BIT (elim_reg_set, regno_first)
03796 && (regno_first == FRAME_POINTER_REGNUM
03797 || regno_first == ARG_POINTER_REGNUM)))
03798 for (i = regno_first; i <= regno_last; ++i)
03799 regs_ever_live[i] = 1;
03800 }
03801 else
03802 {
03803
03804
03805 int blocknum = pbi->bb->index;
03806 if (REG_BASIC_BLOCK (regno_first) == REG_BLOCK_UNKNOWN)
03807 REG_BASIC_BLOCK (regno_first) = blocknum;
03808 else if (REG_BASIC_BLOCK (regno_first) != blocknum)
03809 REG_BASIC_BLOCK (regno_first) = REG_BLOCK_GLOBAL;
03810
03811
03812 REG_FREQ (regno_first) += REG_FREQ_FROM_BB (pbi->bb);
03813 REG_N_REFS (regno_first)++;
03814 }
03815 for (i = regno_first; i <= regno_last; ++i)
03816 if (! REGNO_REG_SET_P (pbi->reg_live, i))
03817 {
03818 gcc_assert (!reg_deaths[i]);
03819 reg_deaths[i] = pbi->insn_num;
03820 }
03821 }
03822
03823
03824
03825
03826
03827 if ((pbi->flags & (PROP_DEATH_NOTES | PROP_REG_INFO))
03828 && some_was_dead
03829 && some_not_set)
03830 {
03831
03832
03833 if (regno_first != regno_last)
03834 for (i = regno_first; i <= regno_last; ++i)
03835 some_was_live |= REGNO_REG_SET_P (pbi->new_set, i);
03836
03837
03838
03839 if (! some_was_live)
03840 {
03841 if ((pbi->flags & PROP_DEATH_NOTES)
03842 #ifdef STACK_REGS
03843 && (!(pbi->flags & PROP_POST_REGSTACK)
03844 || !IN_RANGE (REGNO (reg), FIRST_STACK_REG, LAST_STACK_REG))
03845 #endif
03846 && ! find_regno_note (insn, REG_DEAD, regno_first))
03847 REG_NOTES (insn)
03848 = alloc_EXPR_LIST (REG_DEAD, reg, REG_NOTES (insn));
03849
03850 if (pbi->flags & PROP_REG_INFO)
03851 REG_N_DEATHS (regno_first)++;
03852 }
03853 else
03854 {
03855
03856
03857 for (i = regno_first; i <= regno_last; ++i)
03858 if (! REGNO_REG_SET_P (pbi->reg_live, i)
03859 && ! dead_or_set_regno_p (insn, i))
03860 REG_NOTES (insn)
03861 = alloc_EXPR_LIST (REG_DEAD,
03862 regno_reg_rtx[i],
03863 REG_NOTES (insn));
03864 }
03865 }
03866
03867
03868 for (i = regno_first; i <= regno_last; ++i)
03869 {
03870 #ifdef HAVE_conditional_execution
03871 int this_was_live = REGNO_REG_SET_P (pbi->reg_live, i);
03872 #endif
03873
03874 SET_REGNO_REG_SET (pbi->reg_live, i);
03875
03876 #ifdef HAVE_conditional_execution
03877
03878
03879 if (cond != NULL_RTX)
03880 {
03881 splay_tree_node node;
03882 struct reg_cond_life_info *rcli;
03883 rtx ncond;
03884
03885 if (this_was_live)
03886 {
03887 node = splay_tree_lookup (pbi->reg_cond_dead, i);
03888 if (node == NULL)
03889 {
03890
03891
03892 }
03893 else
03894 {
03895
03896
03897 rcli = (struct reg_cond_life_info *) node->value;
03898 ncond = rcli->condition;
03899 ncond = and_reg_cond (ncond, not_reg_cond (cond), 1);
03900
03901
03902
03903 if (ncond == const0_rtx)
03904 splay_tree_remove (pbi->reg_cond_dead, i);
03905 else
03906 {
03907 rcli->condition = ncond;
03908 SET_REGNO_REG_SET (pbi->reg_cond_reg,
03909 REGNO (XEXP (cond, 0)));
03910 }
03911 }
03912 }
03913 else
03914 {
03915
03916
03917 rcli = XNEW (struct reg_cond_life_info);
03918 rcli->condition = not_reg_cond (cond);
03919 rcli->stores = const0_rtx;
03920 rcli->orig_condition = const0_rtx;
03921 splay_tree_insert (pbi->reg_cond_dead, i,
03922 (splay_tree_value) rcli);
03923
03924 SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (XEXP (cond, 0)));
03925 }
03926 }
03927 else if (this_was_live)
03928 {
03929
03930
03931
03932
03933 splay_tree_remove (pbi->reg_cond_dead, i);
03934 }
03935 #endif
03936 }
03937 }
03938
03939
03940
03941
03942
03943 static bool
03944 mark_used_dest_regs (struct propagate_block_info *pbi, rtx x, rtx cond, rtx insn)
03945 {
03946 int regno;
03947 bool mark_dest = false;
03948 rtx dest = x;
03949
03950
03951
03952
03953 if (GET_CODE (x) == EXPR_LIST
03954 && GET_CODE (XEXP (x, 1)) == CONST_INT)
03955 x = XEXP (x, 0);
03956
03957 if (x == NULL_RTX)
03958 return false;
03959
03960
03961
03962 if (MEM_P (x))
03963 {
03964 #ifdef AUTO_INC_DEC
03965 if (pbi->flags & PROP_AUTOINC)
03966 find_auto_inc (pbi, x, insn);
03967 #endif
03968 mark_used_regs (pbi, XEXP (x, 0), cond, insn);
03969 return true;
03970 }
03971
03972
03973
03974
03975
03976
03977
03978
03979 while (GET_CODE (x) == STRICT_LOW_PART
03980 || GET_CODE (x) == ZERO_EXTRACT
03981 || GET_CODE (x) == SUBREG)
03982 {
03983 #ifdef CANNOT_CHANGE_MODE_CLASS
03984 if ((pbi->flags & PROP_REG_INFO) && GET_CODE (x) == SUBREG)
03985 record_subregs_of_mode (x);
03986 #endif
03987
03988
03989
03990
03991 if (GET_CODE (x) == SUBREG
03992 && !((REG_BYTES (SUBREG_REG (x))
03993 + UNITS_PER_WORD - 1) / UNITS_PER_WORD
03994 > (REG_BYTES (x)
03995 + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
03996 ;
03997 else
03998 mark_dest = true;
03999
04000 x = XEXP (x, 0);
04001 }
04002
04003
04004
04005 if (REG_P (x)
04006 && (regno = REGNO (x),
04007 !(regno == FRAME_POINTER_REGNUM
04008 && (!reload_completed || frame_pointer_needed)))
04009 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
04010 && !(regno == HARD_FRAME_POINTER_REGNUM
04011 && (!reload_completed || frame_pointer_needed))
04012 #endif
04013 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
04014 && !(regno == ARG_POINTER_REGNUM && fixed_regs[regno])
04015 #endif
04016 )
04017 {
04018 if (mark_dest)
04019 mark_used_regs (pbi, dest, cond, insn);
04020 return true;
04021 }
04022 return false;
04023 }
04024
04025
04026
04027
04028
04029
04030
04031
04032 static void
04033 mark_used_regs (struct propagate_block_info *pbi, rtx x, rtx cond, rtx insn)
04034 {
04035 RTX_CODE code;
04036 int flags = pbi->flags;
04037
04038 retry:
04039 if (!x)
04040 return;
04041 code = GET_CODE (x);
04042 switch (code)
04043 {
04044 case LABEL_REF:
04045 case SYMBOL_REF:
04046 case CONST_INT:
04047 case CONST:
04048 case CONST_DOUBLE:
04049 case CONST_VECTOR:
04050 case PC:
04051 case ADDR_VEC:
04052 case ADDR_DIFF_VEC:
04053 return;
04054
04055 #ifdef HAVE_cc0
04056 case CC0:
04057 pbi->cc0_live = 1;
04058 return;
04059 #endif
04060
04061 case CLOBBER:
04062
04063
04064 if (MEM_P (XEXP (x, 0)))
04065 mark_used_regs (pbi, XEXP (XEXP (x, 0), 0), cond, insn);
04066 return;
04067
04068 case MEM:
04069
04070
04071 if (optimize && (flags & PROP_SCAN_DEAD_STORES))
04072 {
04073
04074
04075 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
04076 && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
04077
04078 ;
04079 else
04080 {
04081 rtx temp = pbi->mem_set_list;
04082 rtx prev = NULL_RTX;
04083 rtx next;
04084
04085 while (temp)
04086 {
04087 next = XEXP (temp, 1);
04088 if (anti_dependence (XEXP (temp, 0), x))
04089 {
04090
04091 if (prev)
04092 XEXP (prev, 1) = next;
04093 else
04094 pbi->mem_set_list = next;
04095 free_EXPR_LIST_node (temp);
04096 pbi->mem_set_list_len--;
04097 }
04098 else
04099 prev = temp;
04100 temp = next;
04101 }
04102 }
04103
04104
04105
04106
04107 if (insn)
04108 for_each_rtx (&PATTERN (insn), invalidate_mems_from_autoinc, pbi);
04109 }
04110
04111 #ifdef AUTO_INC_DEC
04112 if (flags & PROP_AUTOINC)
04113 find_auto_inc (pbi, x, insn);
04114 #endif
04115 break;
04116
04117 case SUBREG:
04118 #ifdef CANNOT_CHANGE_MODE_CLASS
04119 if (flags & PROP_REG_INFO)
04120 record_subregs_of_mode (x);
04121 #endif
04122
04123
04124 x = SUBREG_REG (x);
04125 if (!REG_P (x))
04126 goto retry;
04127
04128
04129 case REG:
04130
04131 mark_used_reg (pbi, x, cond, insn);
04132 return;
04133
04134 case SET:
04135 {
04136 rtx dest = SET_DEST (x);
04137 int i;
04138 bool ret = false;
04139
04140 if (GET_CODE (dest) == PARALLEL)
04141 for (i = 0; i < XVECLEN (dest, 0); i++)
04142 ret |= mark_used_dest_regs (pbi, XVECEXP (dest, 0, i), cond, insn);
04143 else
04144 ret = mark_used_dest_regs (pbi, dest, cond, insn);
04145
04146 if (ret)
04147 {
04148 mark_used_regs (pbi, SET_SRC (x), cond, insn);
04149 return;
04150 }
04151 }
04152 break;
04153
04154 case ASM_OPERANDS:
04155 case UNSPEC_VOLATILE:
04156 case TRAP_IF:
04157 case ASM_INPUT:
04158 {
04159
04160
04161
04162
04163
04164
04165
04166
04167
04168
04169
04170
04171
04172
04173 if (code != ASM_OPERANDS || MEM_VOLATILE_P (x))
04174 {
04175 free_EXPR_LIST_list (&pbi->mem_set_list);
04176 pbi->mem_set_list_len = 0;
04177 }
04178
04179
04180
04181
04182
04183 if (code == ASM_OPERANDS)
04184 {
04185 int j;
04186
04187 for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
04188 mark_used_regs (pbi, ASM_OPERANDS_INPUT (x, j), cond, insn);
04189 }
04190 break;
04191 }
04192
04193 case COND_EXEC:
04194 gcc_assert (!cond);
04195
04196 mark_used_regs (pbi, COND_EXEC_TEST (x), NULL_RTX, insn);
04197
04198 cond = COND_EXEC_TEST (x);
04199 x = COND_EXEC_CODE (x);
04200 goto retry;
04201
04202 default:
04203 break;
04204 }
04205
04206
04207
04208 {
04209 const char * const fmt = GET_RTX_FORMAT (code);
04210 int i;
04211
04212 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
04213 {
04214 if (fmt[i] == 'e')
04215 {
04216
04217 if (i == 0)
04218 {
04219 x = XEXP (x, 0);
04220 goto retry;
04221 }
04222 mark_used_regs (pbi, XEXP (x, i), cond, insn);
04223 }
04224 else if (fmt[i] == 'E')
04225 {
04226 int j;
04227 for (j = 0; j < XVECLEN (x, i); j++)
04228 mark_used_regs (pbi, XVECEXP (x, i, j), cond, insn);
04229 }
04230 }
04231 }
04232 }
04233
04234 #ifdef AUTO_INC_DEC
04235
04236 static int
04237 try_pre_increment_1 (struct propagate_block_info *pbi, rtx insn)
04238 {
04239
04240
04241 rtx x = single_set (insn);
04242 HOST_WIDE_INT amount = ((GET_CODE (SET_SRC (x)) == PLUS ? 1 : -1)
04243 * INTVAL (XEXP (SET_SRC (x), 1)));
04244 int regno = REGNO (SET_DEST (x));
04245 rtx y = pbi->reg_next_use[regno];
04246 if (y != 0
04247 && SET_DEST (x) != stack_pointer_rtx
04248 && BLOCK_NUM (y) == BLOCK_NUM (insn)
04249
04250
04251 && ! dead_or_set_p (y, SET_DEST (x))
04252 && try_pre_increment (y, SET_DEST (x), amount))
04253 {
04254
04255
04256 propagate_block_delete_insn (insn);
04257
04258
04259
04260
04261 if (regno >= FIRST_PSEUDO_REGISTER)
04262 {
04263 REG_FREQ (regno) += REG_FREQ_FROM_BB (pbi->bb);
04264 REG_N_SETS (regno)++;
04265 }
04266
04267
04268
04269 invalidate_mems_from_set (pbi, SET_DEST (x));
04270
04271 return 1;
04272 }
04273 return 0;
04274 }
04275
04276
04277
04278
04279
04280
04281
04282 static int
04283 try_pre_increment (rtx insn, rtx reg, HOST_WIDE_INT amount)
04284 {
04285 rtx use;
04286
04287
04288
04289 int pre_ok = 0;
04290
04291
04292
04293
04294 int post_ok = 0;
04295
04296
04297 int do_post = 0;
04298
04299
04300
04301 if (HAVE_PRE_INCREMENT && amount > 0)
04302 pre_ok = 1;
04303 if (HAVE_POST_INCREMENT && amount > 0)
04304 post_ok = 1;
04305
04306 if (HAVE_PRE_DECREMENT && amount < 0)
04307 pre_ok = 1;
04308 if (HAVE_POST_DECREMENT && amount < 0)
04309 post_ok = 1;
04310
04311 if (! (pre_ok || post_ok))
04312 return 0;
04313
04314
04315
04316
04317
04318 if (JUMP_P (insn))
04319 return 0;
04320
04321 use = 0;
04322 if (pre_ok)
04323 use = find_use_as_address (PATTERN (insn), reg, 0);
04324 if (post_ok && (use == 0 || use == (rtx) (size_t) 1))
04325 {
04326 use = find_use_as_address (PATTERN (insn), reg, -amount);
04327 do_post = 1;
04328 }
04329
04330 if (use == 0 || use == (rtx) (size_t) 1)
04331 return 0;
04332
04333 if (GET_MODE_SIZE (GET_MODE (use)) != (amount > 0 ? amount : - amount))
04334 return 0;
04335
04336
04337 if (! validate_change (insn, &XEXP (use, 0),
04338 gen_rtx_fmt_e (amount > 0
04339 ? (do_post ? POST_INC : PRE_INC)
04340 : (do_post ? POST_DEC : PRE_DEC),
04341 Pmode, reg), 0))
04342 return 0;
04343
04344
04345 REG_NOTES (insn) = alloc_EXPR_LIST (REG_INC, reg, REG_NOTES (insn));
04346 return 1;
04347 }
04348
04349 #endif
04350
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360 rtx
04361 find_use_as_address (rtx x, rtx reg, HOST_WIDE_INT plusconst)
04362 {
04363 enum rtx_code code = GET_CODE (x);
04364 const char * const fmt = GET_RTX_FORMAT (code);
04365 int i;
04366 rtx value = 0;
04367 rtx tem;
04368
04369 if (code == MEM && XEXP (x, 0) == reg && plusconst == 0)
04370 return x;
04371
04372 if (code == MEM && GET_CODE (XEXP (x, 0)) == PLUS
04373 && XEXP (XEXP (x, 0), 0) == reg
04374 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
04375 && INTVAL (XEXP (XEXP (x, 0), 1)) == plusconst)
04376 return x;
04377
04378 if (code == SIGN_EXTRACT || code == ZERO_EXTRACT)
04379 {
04380
04381
04382 if (find_use_as_address (XEXP (x, 0), reg, 0) != 0)
04383 return (rtx) (size_t) 1;
04384 }
04385
04386 if (x == reg)
04387 return (rtx) (size_t) 1;
04388
04389 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
04390 {
04391 if (fmt[i] == 'e')
04392 {
04393 tem = find_use_as_address (XEXP (x, i), reg, plusconst);
04394 if (value == 0)
04395 value = tem;
04396 else if (tem != 0)
04397 return (rtx) (size_t) 1;
04398 }
04399 else if (fmt[i] == 'E')
04400 {
04401 int j;
04402 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
04403 {
04404 tem = find_use_as_address (XVECEXP (x, i, j), reg, plusconst);
04405 if (value == 0)
04406 value = tem;
04407 else if (tem != 0)
04408 return (rtx) (size_t) 1;
04409 }
04410 }
04411 }
04412
04413 return value;
04414 }
04415
04416
04417
04418
04419 void
04420 dump_regset (regset r, FILE *outf)
04421 {
04422 unsigned i;
04423 reg_set_iterator rsi;
04424
04425 if (r == NULL)
04426 {
04427 fputs (" (nil)", outf);
04428 return;
04429 }
04430
04431 EXECUTE_IF_SET_IN_REG_SET (r, 0, i, rsi)
04432 {
04433 fprintf (outf, " %d", i);
04434 if (i < FIRST_PSEUDO_REGISTER)
04435 fprintf (outf, " [%s]",
04436 reg_names[i]);
04437 }
04438 }
04439
04440
04441
04442
04443
04444 void
04445 debug_regset (regset r)
04446 {
04447 dump_regset (r, stderr);
04448 putc ('\n', stderr);
04449 }
04450
04451
04452
04453
04454
04455
04456
04457
04458
04459
04460
04461
04462
04463
04464 static unsigned int
04465 recompute_reg_usage (void)
04466 {
04467 allocate_reg_life_data ();
04468
04469
04470
04471
04472 update_life_info (NULL, UPDATE_LIFE_LOCAL, PROP_REG_INFO | PROP_DEATH_NOTES);
04473
04474 if (dump_file)
04475 dump_flow_info (dump_file, dump_flags);
04476 return 0;
04477 }
04478
04479 struct tree_opt_pass pass_recompute_reg_usage =
04480 {
04481 "life2",
04482 NULL,
04483 recompute_reg_usage,
04484 NULL,
04485 NULL,
04486 0,
04487 0,
04488 0,
04489 0,
04490 0,
04491 0,
04492 TODO_dump_func,
04493 'f'
04494 };
04495
04496
04497
04498
04499
04500
04501
04502 int
04503 count_or_remove_death_notes (sbitmap blocks, int kill)
04504 {
04505 int count = 0;
04506 unsigned int i = 0;
04507 basic_block bb;
04508
04509
04510
04511
04512
04513
04514
04515
04516 if (blocks)
04517 {
04518 sbitmap_iterator sbi;
04519
04520 EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i, sbi)
04521 {
04522 basic_block bb = BASIC_BLOCK (i);
04523
04524
04525 if (bb)
04526 count += count_or_remove_death_notes_bb (bb, kill);
04527 };
04528 }
04529 else
04530 {
04531 FOR_EACH_BB (bb)
04532 {
04533 count += count_or_remove_death_notes_bb (bb, kill);
04534 }
04535 }
04536
04537 return count;
04538 }
04539
04540
04541
04542
04543 static int
04544 count_or_remove_death_notes_bb (basic_block bb, int kill)
04545 {
04546 int count = 0;
04547 rtx insn;
04548
04549 for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
04550 {
04551 if (INSN_P (insn))
04552 {
04553 rtx *pprev = ®_NOTES (insn);
04554 rtx link = *pprev;
04555
04556 while (link)
04557 {
04558 switch (REG_NOTE_KIND (link))
04559 {
04560 case REG_DEAD:
04561 if (REG_P (XEXP (link, 0)))
04562 {
04563 rtx reg = XEXP (link, 0);
04564 int n;
04565
04566 if (REGNO (reg) >= FIRST_PSEUDO_REGISTER)
04567 n = 1;
04568 else
04569 n = hard_regno_nregs[REGNO (reg)][GET_MODE (reg)];
04570 count += n;
04571 }
04572
04573
04574
04575 case REG_UNUSED:
04576 if (kill > 0
04577 || (kill
04578 #ifdef STACK_REGS
04579 && (!REG_P (XEXP (link, 0))
04580 || !IN_RANGE (REGNO (XEXP (link, 0)),
04581 FIRST_STACK_REG, LAST_STACK_REG))
04582 #endif
04583 ))
04584 {
04585 rtx next = XEXP (link, 1);
04586 free_EXPR_LIST_node (link);
04587 *pprev = link = next;
04588 break;
04589 }
04590
04591
04592 default:
04593 pprev = &XEXP (link, 1);
04594 link = *pprev;
04595 break;
04596 }
04597 }
04598 }
04599
04600 if (insn == BB_END (bb))
04601 break;
04602 }
04603
04604 return count;
04605 }
04606
04607
04608
04609
04610 static void
04611 clear_log_links (sbitmap blocks)
04612 {
04613 rtx insn;
04614
04615 if (!blocks)
04616 {
04617 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
04618 if (INSN_P (insn))
04619 free_INSN_LIST_list (&LOG_LINKS (insn));
04620 }
04621 else
04622 {
04623 unsigned int i = 0;
04624 sbitmap_iterator sbi;
04625
04626 EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i, sbi)
04627 {
04628 basic_block bb = BASIC_BLOCK (i);
04629
04630 for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
04631 insn = NEXT_INSN (insn))
04632 if (INSN_P (insn))
04633 free_INSN_LIST_list (&LOG_LINKS (insn));
04634 }
04635 }
04636 }
04637
04638
04639
04640
04641
04642
04643 void
04644 reg_set_to_hard_reg_set (HARD_REG_SET *to, bitmap from)
04645 {
04646 unsigned i;
04647 bitmap_iterator bi;
04648
04649 EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
04650 {
04651 if (i >= FIRST_PSEUDO_REGISTER)
04652 return;
04653 SET_HARD_REG_BIT (*to, i);
04654 }
04655 }
04656
04657
04658 static bool
04659 gate_remove_death_notes (void)
04660 {
04661 return flag_profile_values;
04662 }
04663
04664 static unsigned int
04665 rest_of_handle_remove_death_notes (void)
04666 {
04667 count_or_remove_death_notes (NULL, 1);
04668 return 0;
04669 }
04670
04671 struct tree_opt_pass pass_remove_death_notes =
04672 {
04673 "ednotes",
04674 gate_remove_death_notes,
04675 rest_of_handle_remove_death_notes,
04676 NULL,
04677 NULL,
04678 0,
04679 0,
04680 0,
04681 0,
04682 0,
04683 0,
04684 0,
04685 0
04686 };
04687
04688
04689 static unsigned int
04690 rest_of_handle_life (void)
04691 {
04692 regclass_init ();
04693
04694 life_analysis (PROP_FINAL);
04695 if (optimize)
04696 cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE | CLEANUP_LOG_LINKS
04697 | (flag_thread_jumps ? CLEANUP_THREADING : 0));
04698
04699 if (extra_warnings)
04700 {
04701 setjmp_vars_warning (DECL_INITIAL (current_function_decl));
04702 setjmp_args_warning ();
04703 }
04704
04705 if (optimize)
04706 {
04707 if (initialize_uninitialized_subregs ())
04708 {
04709
04710
04711 allocate_reg_life_data ();
04712 update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
04713 PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES);
04714 }
04715 }
04716
04717 no_new_pseudos = 1;
04718 return 0;
04719 }
04720
04721 struct tree_opt_pass pass_life =
04722 {
04723 "life1",
04724 NULL,
04725 rest_of_handle_life,
04726 NULL,
04727 NULL,
04728 0,
04729 TV_FLOW,
04730 0,
04731 0,
04732 0,
04733 TODO_verify_flow,
04734 TODO_dump_func |
04735 TODO_ggc_collect,
04736 'f'
04737 };
04738
04739 static unsigned int
04740 rest_of_handle_flow2 (void)
04741 {
04742
04743 #ifndef STACK_REGS
04744 if (optimize > 0)
04745 #endif
04746 split_all_insns (0);
04747
04748 if (flag_branch_target_load_optimize)
04749 branch_target_load_optimize (epilogue_completed);
04750
04751 if (optimize)
04752 cleanup_cfg (CLEANUP_EXPENSIVE);
04753
04754
04755
04756
04757
04758 thread_prologue_and_epilogue_insns (get_insns ());
04759 epilogue_completed = 1;
04760 flow2_completed = 1;
04761 return 0;
04762 }
04763
04764 struct tree_opt_pass pass_flow2 =
04765 {
04766 "flow2",
04767 NULL,
04768 rest_of_handle_flow2,
04769 NULL,
04770 NULL,
04771 0,
04772 TV_FLOW2,
04773 0,
04774 0,
04775 0,
04776 TODO_verify_flow,
04777 TODO_dump_func |
04778 TODO_ggc_collect,
04779 'w'
04780 };
04781