| OLD | NEW |
| 1 /* RTL dead code elimination. | 1 /* RTL dead code elimination. |
| 2 Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. | 2 Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. |
| 3 | 3 |
| 4 This file is part of GCC. | 4 This file is part of GCC. |
| 5 | 5 |
| 6 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
| 7 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
| 8 Software Foundation; either version 3, or (at your option) any later | 8 Software Foundation; either version 3, or (at your option) any later |
| 9 version. | 9 version. |
| 10 | 10 |
| 11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | 11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
| 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or | 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 14 for more details. | 14 for more details. |
| 15 | 15 |
| 16 You should have received a copy of the GNU General Public License | 16 You should have received a copy of the GNU General Public License |
| 17 along with GCC; see the file COPYING3. If not see | 17 along with GCC; see the file COPYING3. If not see |
| 18 <http://www.gnu.org/licenses/>. */ | 18 <http://www.gnu.org/licenses/>. */ |
| 19 | 19 |
| 20 #include "config.h" | 20 #include "config.h" |
| 21 #include "system.h" | 21 #include "system.h" |
| 22 #include "coretypes.h" | 22 #include "coretypes.h" |
| 23 #include "hashtab.h" | 23 #include "hashtab.h" |
| 24 #include "tm.h" | 24 #include "tm.h" |
| 25 #include "rtl.h" | 25 #include "rtl.h" |
| 26 #include "tree.h" | 26 #include "tree.h" |
| 27 #include "regs.h" | 27 #include "regs.h" |
| 28 #include "hard-reg-set.h" | 28 #include "hard-reg-set.h" |
| 29 #include "flags.h" | 29 #include "flags.h" |
| 30 #include "except.h" |
| 30 #include "df.h" | 31 #include "df.h" |
| 31 #include "cselib.h" | 32 #include "cselib.h" |
| 32 #include "dce.h" | 33 #include "dce.h" |
| 33 #include "timevar.h" | 34 #include "timevar.h" |
| 34 #include "tree-pass.h" | 35 #include "tree-pass.h" |
| 35 #include "dbgcnt.h" | 36 #include "dbgcnt.h" |
| 36 #include "tm_p.h" | 37 #include "tm_p.h" |
| 37 | 38 |
| 38 DEF_VEC_I(int); | |
| 39 DEF_VEC_ALLOC_I(int,heap); | |
| 40 | |
| 41 | 39 |
| 42 /* ------------------------------------------------------------------------- | 40 /* ------------------------------------------------------------------------- |
| 43 Core mark/delete routines | 41 Core mark/delete routines |
| 44 ------------------------------------------------------------------------- */ | 42 ------------------------------------------------------------------------- */ |
| 45 | 43 |
| 46 /* True if we are invoked while the df engine is running; in this case, | 44 /* True if we are invoked while the df engine is running; in this case, |
| 47 we don't want to reenter it. */ | 45 we don't want to reenter it. */ |
| 48 static bool df_in_progress = false; | 46 static bool df_in_progress = false; |
| 49 | 47 |
| 50 /* Instructions that have been marked but whose dependencies have not | 48 /* Instructions that have been marked but whose dependencies have not |
| (...skipping 23 matching lines...) Expand all Loading... |
| 74 /* The UNSPEC case was added here because the ia-64 claims that | 72 /* The UNSPEC case was added here because the ia-64 claims that |
| 75 USEs do not work after reload and generates UNSPECS rather | 73 USEs do not work after reload and generates UNSPECS rather |
| 76 than USEs. Since dce is run after reload we need to avoid | 74 than USEs. Since dce is run after reload we need to avoid |
| 77 deleting these even if they are dead. If it turns out that | 75 deleting these even if they are dead. If it turns out that |
| 78 USEs really do work after reload, the ia-64 should be | 76 USEs really do work after reload, the ia-64 should be |
| 79 changed, and the UNSPEC case can be removed. */ | 77 changed, and the UNSPEC case can be removed. */ |
| 80 case UNSPEC: | 78 case UNSPEC: |
| 81 return false; | 79 return false; |
| 82 | 80 |
| 83 default: | 81 default: |
| 84 if (volatile_refs_p (body)) | 82 return !volatile_refs_p (body); |
| 85 » return false; | |
| 86 | |
| 87 if (flag_non_call_exceptions && may_trap_p (body)) | |
| 88 » return false; | |
| 89 | |
| 90 return true; | |
| 91 } | 83 } |
| 92 } | 84 } |
| 93 | 85 |
| 94 | 86 |
| 95 /* Return true if INSN is a normal instruction that can be deleted by | 87 /* Return true if INSN is a normal instruction that can be deleted by |
| 96 the DCE pass. */ | 88 the DCE pass. */ |
| 97 | 89 |
| 98 static bool | 90 static bool |
| 99 deletable_insn_p (rtx insn, bool fast, bitmap arg_stores) | 91 deletable_insn_p (rtx insn, bool fast, bitmap arg_stores) |
| 100 { | 92 { |
| 101 rtx body, x; | 93 rtx body, x; |
| 102 int i; | 94 int i; |
| 103 | 95 |
| 104 if (CALL_P (insn) | 96 if (CALL_P (insn) |
| 105 /* We cannot delete calls inside of the recursive dce because | 97 /* We cannot delete calls inside of the recursive dce because |
| 106 this may cause basic blocks to be deleted and this messes up | 98 this may cause basic blocks to be deleted and this messes up |
| 107 the rest of the stack of optimization passes. */ | 99 the rest of the stack of optimization passes. */ |
| 108 && (!df_in_progress) | 100 && (!df_in_progress) |
| 109 /* We cannot delete pure or const sibling calls because it is | 101 /* We cannot delete pure or const sibling calls because it is |
| 110 hard to see the result. */ | 102 hard to see the result. */ |
| 111 && (!SIBLING_CALL_P (insn)) | 103 && (!SIBLING_CALL_P (insn)) |
| 112 /* We can delete dead const or pure calls as long as they do not | 104 /* We can delete dead const or pure calls as long as they do not |
| 113 infinite loop. */ | 105 infinite loop. */ |
| 114 && (RTL_CONST_OR_PURE_CALL_P (insn) | 106 && (RTL_CONST_OR_PURE_CALL_P (insn) |
| 115 && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn))) | 107 && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn))) |
| 116 return find_call_stack_args (insn, false, fast, arg_stores); | 108 return find_call_stack_args (insn, false, fast, arg_stores); |
| 117 | 109 |
| 110 /* Don't delete jumps, notes and the like. */ |
| 118 if (!NONJUMP_INSN_P (insn)) | 111 if (!NONJUMP_INSN_P (insn)) |
| 119 return false; | 112 return false; |
| 120 | 113 |
| 114 /* Don't delete insns that can throw. */ |
| 115 if (!insn_nothrow_p (insn)) |
| 116 return false; |
| 117 |
| 121 body = PATTERN (insn); | 118 body = PATTERN (insn); |
| 122 switch (GET_CODE (body)) | 119 switch (GET_CODE (body)) |
| 123 { | 120 { |
| 124 case USE: | 121 case USE: |
| 122 case VAR_LOCATION: |
| 125 return false; | 123 return false; |
| 126 | 124 |
| 127 case CLOBBER: | 125 case CLOBBER: |
| 128 if (fast) | 126 if (fast) |
| 129 { | 127 { |
| 130 /* A CLOBBER of a dead pseudo register serves no purpose. | 128 /* A CLOBBER of a dead pseudo register serves no purpose. |
| 131 That is not necessarily true for hard registers until | 129 That is not necessarily true for hard registers until |
| 132 after reload. */ | 130 after reload. */ |
| 133 x = XEXP (body, 0); | 131 x = XEXP (body, 0); |
| 134 return REG_P (x) && (!HARD_REGISTER_P (x) || reload_completed); | 132 return REG_P (x) && (!HARD_REGISTER_P (x) || reload_completed); |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 | 343 |
| 346 for (defs = DF_REF_CHAIN (*use_rec); defs; defs = defs->next) | 344 for (defs = DF_REF_CHAIN (*use_rec); defs; defs = defs->next) |
| 347 if (! DF_REF_IS_ARTIFICIAL (defs->ref)) | 345 if (! DF_REF_IS_ARTIFICIAL (defs->ref)) |
| 348 break; | 346 break; |
| 349 | 347 |
| 350 set = single_set (DF_REF_INSN (defs->ref)); | 348 set = single_set (DF_REF_INSN (defs->ref)); |
| 351 off += INTVAL (XEXP (SET_SRC (set), 1)); | 349 off += INTVAL (XEXP (SET_SRC (set), 1)); |
| 352 } | 350 } |
| 353 for (byte = off; byte < off + INTVAL (MEM_SIZE (mem)); byte++) | 351 for (byte = off; byte < off + INTVAL (MEM_SIZE (mem)); byte++) |
| 354 { | 352 { |
| 355 » gcc_assert (!bitmap_bit_p (sp_bytes, byte - min_sp_off)); | 353 » if (!bitmap_set_bit (sp_bytes, byte - min_sp_off)) |
| 356 » bitmap_set_bit (sp_bytes, byte - min_sp_off); | 354 » gcc_unreachable (); |
| 357 } | 355 } |
| 358 } | 356 } |
| 359 | 357 |
| 360 /* Walk backwards, looking for argument stores. The search stops | 358 /* Walk backwards, looking for argument stores. The search stops |
| 361 when seeing another call, sp adjustment or memory store other than | 359 when seeing another call, sp adjustment or memory store other than |
| 362 argument store. */ | 360 argument store. */ |
| 363 ret = false; | 361 ret = false; |
| 364 for (insn = PREV_INSN (call_insn); insn; insn = prev_insn) | 362 for (insn = PREV_INSN (call_insn); insn; insn = prev_insn) |
| 365 { | 363 { |
| 366 rtx set, mem, addr; | 364 rtx set, mem, addr; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 break; | 431 break; |
| 434 } | 432 } |
| 435 | 433 |
| 436 if (GET_MODE_SIZE (GET_MODE (mem)) == 0) | 434 if (GET_MODE_SIZE (GET_MODE (mem)) == 0) |
| 437 break; | 435 break; |
| 438 | 436 |
| 439 for (byte = off; byte < off + GET_MODE_SIZE (GET_MODE (mem)); byte++) | 437 for (byte = off; byte < off + GET_MODE_SIZE (GET_MODE (mem)); byte++) |
| 440 { | 438 { |
| 441 if (byte < min_sp_off | 439 if (byte < min_sp_off |
| 442 || byte >= max_sp_off | 440 || byte >= max_sp_off |
| 443 » || !bitmap_bit_p (sp_bytes, byte - min_sp_off)) | 441 » || !bitmap_clear_bit (sp_bytes, byte - min_sp_off)) |
| 444 break; | 442 break; |
| 445 bitmap_clear_bit (sp_bytes, byte - min_sp_off); | |
| 446 } | 443 } |
| 447 | 444 |
| 448 if (!deletable_insn_p (insn, fast, NULL)) | 445 if (!deletable_insn_p (insn, fast, NULL)) |
| 449 break; | 446 break; |
| 450 | 447 |
| 451 if (do_mark) | 448 if (do_mark) |
| 452 mark_insn (insn, fast); | 449 mark_insn (insn, fast); |
| 453 else | 450 else |
| 454 bitmap_set_bit (arg_stores, INSN_UID (insn)); | 451 bitmap_set_bit (arg_stores, INSN_UID (insn)); |
| 455 | 452 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 | 615 |
| 619 static void | 616 static void |
| 620 mark_artificial_uses (void) | 617 mark_artificial_uses (void) |
| 621 { | 618 { |
| 622 basic_block bb; | 619 basic_block bb; |
| 623 struct df_link *defs; | 620 struct df_link *defs; |
| 624 df_ref *use_rec; | 621 df_ref *use_rec; |
| 625 | 622 |
| 626 FOR_ALL_BB (bb) | 623 FOR_ALL_BB (bb) |
| 627 { | 624 { |
| 628 for (use_rec = df_get_artificial_uses (bb->index); | 625 for (use_rec = df_get_artificial_uses (bb->index); |
| 629 *use_rec; use_rec++) | 626 *use_rec; use_rec++) |
| 630 for (defs = DF_REF_CHAIN (*use_rec); defs; defs = defs->next) | 627 for (defs = DF_REF_CHAIN (*use_rec); defs; defs = defs->next) |
| 631 if (! DF_REF_IS_ARTIFICIAL (defs->ref)) | 628 if (! DF_REF_IS_ARTIFICIAL (defs->ref)) |
| 632 mark_insn (DF_REF_INSN (defs->ref), false); | 629 mark_insn (DF_REF_INSN (defs->ref), false); |
| 633 } | 630 } |
| 634 } | 631 } |
| 635 | 632 |
| 636 | 633 |
| 637 /* Mark every instruction that defines a register value that INSN uses. */ | 634 /* Mark every instruction that defines a register value that INSN uses. */ |
| 638 | 635 |
| 639 static void | 636 static void |
| 640 mark_reg_dependencies (rtx insn) | 637 mark_reg_dependencies (rtx insn) |
| 641 { | 638 { |
| 642 struct df_link *defs; | 639 struct df_link *defs; |
| 643 df_ref *use_rec; | 640 df_ref *use_rec; |
| 644 | 641 |
| 642 if (DEBUG_INSN_P (insn)) |
| 643 return; |
| 644 |
| 645 for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++) | 645 for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++) |
| 646 { | 646 { |
| 647 df_ref use = *use_rec; | 647 df_ref use = *use_rec; |
| 648 if (dump_file) | 648 if (dump_file) |
| 649 { | 649 { |
| 650 fprintf (dump_file, "Processing use of "); | 650 fprintf (dump_file, "Processing use of "); |
| 651 print_simple_rtl (dump_file, DF_REF_REG (use)); | 651 print_simple_rtl (dump_file, DF_REF_REG (use)); |
| 652 fprintf (dump_file, " in insn %d:\n", INSN_UID (insn)); | 652 fprintf (dump_file, " in insn %d:\n", INSN_UID (insn)); |
| 653 } | 653 } |
| 654 for (defs = DF_REF_CHAIN (use); defs; defs = defs->next) | 654 for (defs = DF_REF_CHAIN (use); defs; defs = defs->next) |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 gate_ud_dce (void) | 731 gate_ud_dce (void) |
| 732 { | 732 { |
| 733 return optimize > 1 && flag_dce | 733 return optimize > 1 && flag_dce |
| 734 && dbg_cnt (dce_ud); | 734 && dbg_cnt (dce_ud); |
| 735 } | 735 } |
| 736 | 736 |
| 737 struct rtl_opt_pass pass_ud_rtl_dce = | 737 struct rtl_opt_pass pass_ud_rtl_dce = |
| 738 { | 738 { |
| 739 { | 739 { |
| 740 RTL_PASS, | 740 RTL_PASS, |
| 741 "dce", /* name */ | 741 "ud dce", /* name */ |
| 742 gate_ud_dce, /* gate */ | 742 gate_ud_dce, /* gate */ |
| 743 rest_of_handle_ud_dce, /* execute */ | 743 rest_of_handle_ud_dce, /* execute */ |
| 744 NULL, /* sub */ | 744 NULL, /* sub */ |
| 745 NULL, /* next */ | 745 NULL, /* next */ |
| 746 0, /* static_pass_number */ | 746 0, /* static_pass_number */ |
| 747 TV_DCE, /* tv_id */ | 747 TV_DCE, /* tv_id */ |
| 748 0, /* properties_required */ | 748 0, /* properties_required */ |
| 749 0, /* properties_provided */ | 749 0, /* properties_provided */ |
| 750 0, /* properties_destroyed */ | 750 0, /* properties_destroyed */ |
| 751 0, /* todo_flags_start */ | 751 0, /* todo_flags_start */ |
| 752 TODO_dump_func | | 752 TODO_dump_func | |
| 753 TODO_df_finish | TODO_verify_rtl_sharing | | 753 TODO_df_finish | TODO_verify_rtl_sharing | |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 { | 818 { |
| 819 start += sb; | 819 start += sb; |
| 820 len = lb - sb; | 820 len = lb - sb; |
| 821 } | 821 } |
| 822 | 822 |
| 823 if (bitmap_bit_p (au, dregno)) | 823 if (bitmap_bit_p (au, dregno)) |
| 824 { | 824 { |
| 825 mark_insn (insn, true); | 825 mark_insn (insn, true); |
| 826 goto quickexit; | 826 goto quickexit; |
| 827 } | 827 } |
| 828 » | 828 |
| 829 last = start + len; | 829 last = start + len; |
| 830 while (start < last) | 830 while (start < last) |
| 831 if (bitmap_bit_p (local_live, start++)) | 831 if (bitmap_bit_p (local_live, start++)) |
| 832 { | 832 { |
| 833 mark_insn (insn, true); | 833 mark_insn (insn, true); |
| 834 goto quickexit; | 834 goto quickexit; |
| 835 } | 835 } |
| 836 } | 836 } |
| 837 » | 837 |
| 838 quickexit: | 838 quickexit: |
| 839 » | 839 |
| 840 /* No matter if the instruction is needed or not, we remove | 840 /* No matter if the instruction is needed or not, we remove |
| 841 any regno in the defs from the live set. */ | 841 any regno in the defs from the live set. */ |
| 842 df_byte_lr_simulate_defs (insn, local_live); | 842 df_byte_lr_simulate_defs (insn, local_live); |
| 843 | 843 |
| 844 /* On the other hand, we do not allow the dead uses to set | 844 /* On the other hand, we do not allow the dead uses to set |
| 845 anything in local_live. */ | 845 anything in local_live. */ |
| 846 if (marked_insn_p (insn)) | 846 if (marked_insn_p (insn)) |
| 847 df_byte_lr_simulate_uses (insn, local_live); | 847 df_byte_lr_simulate_uses (insn, local_live); |
| 848 | 848 |
| 849 if (dump_file) | 849 if (dump_file) |
| 850 { | 850 { |
| 851 » fprintf (dump_file, "finished processing insn %d live out = ", | 851 » fprintf (dump_file, "finished processing insn %d live out = ", |
| 852 INSN_UID (insn)); | 852 INSN_UID (insn)); |
| 853 df_print_byte_regset (dump_file, local_live); | 853 df_print_byte_regset (dump_file, local_live); |
| 854 } | 854 } |
| 855 } | 855 } |
| 856 | 856 |
| 857 df_byte_lr_simulate_artificial_refs_at_top (bb, local_live); | 857 df_byte_lr_simulate_artificial_refs_at_top (bb, local_live); |
| 858 | 858 |
| 859 block_changed = !bitmap_equal_p (local_live, DF_BYTE_LR_IN (bb)); | 859 block_changed = !bitmap_equal_p (local_live, DF_BYTE_LR_IN (bb)); |
| 860 if (block_changed) | 860 if (block_changed) |
| 861 bitmap_copy (DF_BYTE_LR_IN (bb), local_live); | 861 bitmap_copy (DF_BYTE_LR_IN (bb), local_live); |
| 862 BITMAP_FREE (local_live); | 862 BITMAP_FREE (local_live); |
| 863 return block_changed; | 863 return block_changed; |
| 864 } | 864 } |
| 865 | 865 |
| 866 | 866 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 bool needed = false; | 906 bool needed = false; |
| 907 | 907 |
| 908 /* The insn is needed if there is someone who uses the output. */ | 908 /* The insn is needed if there is someone who uses the output. */ |
| 909 for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) | 909 for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) |
| 910 if (bitmap_bit_p (local_live, DF_REF_REGNO (*def_rec)) | 910 if (bitmap_bit_p (local_live, DF_REF_REGNO (*def_rec)) |
| 911 || bitmap_bit_p (au, DF_REF_REGNO (*def_rec))) | 911 || bitmap_bit_p (au, DF_REF_REGNO (*def_rec))) |
| 912 { | 912 { |
| 913 needed = true; | 913 needed = true; |
| 914 break; | 914 break; |
| 915 } | 915 } |
| 916 » | 916 |
| 917 if (needed) | 917 if (needed) |
| 918 mark_insn (insn, true); | 918 mark_insn (insn, true); |
| 919 » | 919 |
| 920 /* No matter if the instruction is needed or not, we remove | 920 /* No matter if the instruction is needed or not, we remove |
| 921 any regno in the defs from the live set. */ | 921 any regno in the defs from the live set. */ |
| 922 df_simulate_defs (insn, local_live); | 922 df_simulate_defs (insn, local_live); |
| 923 | 923 |
| 924 /* On the other hand, we do not allow the dead uses to set | 924 /* On the other hand, we do not allow the dead uses to set |
| 925 anything in local_live. */ | 925 anything in local_live. */ |
| 926 if (marked_insn_p (insn)) | 926 if (marked_insn_p (insn)) |
| 927 df_simulate_uses (insn, local_live); | 927 df_simulate_uses (insn, local_live); |
| 928 } | 928 } |
| 929 | 929 |
| 930 df_simulate_finalize_backwards (bb, local_live); | 930 df_simulate_finalize_backwards (bb, local_live); |
| 931 | 931 |
| 932 block_changed = !bitmap_equal_p (local_live, DF_LR_IN (bb)); | 932 block_changed = !bitmap_equal_p (local_live, DF_LR_IN (bb)); |
| 933 if (block_changed) | 933 if (block_changed) |
| 934 bitmap_copy (DF_LR_IN (bb), local_live); | 934 bitmap_copy (DF_LR_IN (bb), local_live); |
| 935 | 935 |
| 936 BITMAP_FREE (local_live); | 936 BITMAP_FREE (local_live); |
| 937 return block_changed; | 937 return block_changed; |
| 938 } | 938 } |
| 939 | 939 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 979 basic_block bb = BASIC_BLOCK (index); | 979 basic_block bb = BASIC_BLOCK (index); |
| 980 bool local_changed; | 980 bool local_changed; |
| 981 | 981 |
| 982 if (index < NUM_FIXED_BLOCKS) | 982 if (index < NUM_FIXED_BLOCKS) |
| 983 { | 983 { |
| 984 bitmap_set_bit (processed, index); | 984 bitmap_set_bit (processed, index); |
| 985 continue; | 985 continue; |
| 986 } | 986 } |
| 987 | 987 |
| 988 if (byte_level) | 988 if (byte_level) |
| 989 » local_changed | 989 » local_changed |
| 990 = byte_dce_process_block (bb, bitmap_bit_p (redo_out, index), | 990 = byte_dce_process_block (bb, bitmap_bit_p (redo_out, index), |
| 991 bb_has_eh_pred (bb) ? au_eh : au); | 991 bb_has_eh_pred (bb) ? au_eh : au); |
| 992 else | 992 else |
| 993 » local_changed | 993 » local_changed |
| 994 = dce_process_block (bb, bitmap_bit_p (redo_out, index), | 994 = dce_process_block (bb, bitmap_bit_p (redo_out, index), |
| 995 bb_has_eh_pred (bb) ? au_eh : au); | 995 bb_has_eh_pred (bb) ? au_eh : au); |
| 996 bitmap_set_bit (processed, index); | 996 bitmap_set_bit (processed, index); |
| 997 » | 997 |
| 998 if (local_changed) | 998 if (local_changed) |
| 999 { | 999 { |
| 1000 edge e; | 1000 edge e; |
| 1001 edge_iterator ei; | 1001 edge_iterator ei; |
| 1002 FOR_EACH_EDGE (e, ei, bb->preds) | 1002 FOR_EACH_EDGE (e, ei, bb->preds) |
| 1003 if (bitmap_bit_p (processed, e->src->index)) | 1003 if (bitmap_bit_p (processed, e->src->index)) |
| 1004 /* Be tricky about when we need to iterate the | 1004 /* Be tricky about when we need to iterate the |
| 1005 analysis. We only have redo the analysis if the | 1005 analysis. We only have redo the analysis if the |
| 1006 bitmaps change at the top of a block that is the | 1006 bitmaps change at the top of a block that is the |
| 1007 entry to a loop. */ | 1007 entry to a loop. */ |
| 1008 global_changed = true; | 1008 global_changed = true; |
| 1009 else | 1009 else |
| 1010 bitmap_set_bit (redo_out, e->src->index); | 1010 bitmap_set_bit (redo_out, e->src->index); |
| 1011 } | 1011 } |
| 1012 } | 1012 } |
| 1013 | 1013 |
| 1014 if (global_changed) | 1014 if (global_changed) |
| 1015 { | 1015 { |
| 1016 /* Turn off the RUN_DCE flag to prevent recursive calls to | 1016 /* Turn off the RUN_DCE flag to prevent recursive calls to |
| 1017 dce. */ | 1017 dce. */ |
| 1018 int old_flag = df_clear_flags (DF_LR_RUN_DCE); | 1018 int old_flag = df_clear_flags (DF_LR_RUN_DCE); |
| 1019 | 1019 |
| 1020 /* So something was deleted that requires a redo. Do it on | 1020 /* So something was deleted that requires a redo. Do it on |
| 1021 the cheap. */ | 1021 the cheap. */ |
| 1022 delete_unmarked_insns (); | 1022 delete_unmarked_insns (); |
| 1023 sbitmap_zero (marked); | 1023 sbitmap_zero (marked); |
| 1024 bitmap_clear (processed); | 1024 bitmap_clear (processed); |
| 1025 bitmap_clear (redo_out); | 1025 bitmap_clear (redo_out); |
| 1026 » | 1026 |
| 1027 /* We do not need to rescan any instructions. We only need | 1027 /* We do not need to rescan any instructions. We only need |
| 1028 to redo the dataflow equations for the blocks that had a | 1028 to redo the dataflow equations for the blocks that had a |
| 1029 change at the top of the block. Then we need to redo the | 1029 change at the top of the block. Then we need to redo the |
| 1030 » iteration. */ | 1030 » iteration. */ |
| 1031 if (byte_level) | 1031 if (byte_level) |
| 1032 df_analyze_problem (df_byte_lr, all_blocks, postorder, n_blocks); | 1032 df_analyze_problem (df_byte_lr, all_blocks, postorder, n_blocks); |
| 1033 else | 1033 else |
| 1034 df_analyze_problem (df_lr, all_blocks, postorder, n_blocks); | 1034 df_analyze_problem (df_lr, all_blocks, postorder, n_blocks); |
| 1035 | 1035 |
| 1036 if (old_flag & DF_LR_RUN_DCE) | 1036 if (old_flag & DF_LR_RUN_DCE) |
| 1037 df_set_flags (DF_LR_RUN_DCE); | 1037 df_set_flags (DF_LR_RUN_DCE); |
| 1038 | 1038 |
| 1039 prescan_insns_for_dce (true); | 1039 prescan_insns_for_dce (true); |
| 1040 } | 1040 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 vectors for any other problems than LR. */ | 1083 vectors for any other problems than LR. */ |
| 1084 | 1084 |
| 1085 void | 1085 void |
| 1086 run_fast_df_dce (void) | 1086 run_fast_df_dce (void) |
| 1087 { | 1087 { |
| 1088 if (flag_dce) | 1088 if (flag_dce) |
| 1089 { | 1089 { |
| 1090 /* If dce is able to delete something, it has to happen | 1090 /* If dce is able to delete something, it has to happen |
| 1091 immediately. Otherwise there will be problems handling the | 1091 immediately. Otherwise there will be problems handling the |
| 1092 eq_notes. */ | 1092 eq_notes. */ |
| 1093 enum df_changeable_flags old_flags | 1093 int old_flags = |
| 1094 » = df_clear_flags (DF_DEFER_INSN_RESCAN + DF_NO_INSN_RESCAN); | 1094 » df_clear_flags (DF_DEFER_INSN_RESCAN + DF_NO_INSN_RESCAN); |
| 1095 | 1095 |
| 1096 df_in_progress = true; | 1096 df_in_progress = true; |
| 1097 rest_of_handle_fast_dce (); | 1097 rest_of_handle_fast_dce (); |
| 1098 df_in_progress = false; | 1098 df_in_progress = false; |
| 1099 | 1099 |
| 1100 df_set_flags (old_flags); | 1100 df_set_flags (old_flags); |
| 1101 } | 1101 } |
| 1102 } | 1102 } |
| 1103 | 1103 |
| 1104 | 1104 |
| 1105 /* Run a fast DCE pass. */ | 1105 /* Run a fast DCE pass. */ |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1116 gate_fast_dce (void) | 1116 gate_fast_dce (void) |
| 1117 { | 1117 { |
| 1118 return optimize > 0 && flag_dce | 1118 return optimize > 0 && flag_dce |
| 1119 && dbg_cnt (dce_fast); | 1119 && dbg_cnt (dce_fast); |
| 1120 } | 1120 } |
| 1121 | 1121 |
| 1122 struct rtl_opt_pass pass_fast_rtl_dce = | 1122 struct rtl_opt_pass pass_fast_rtl_dce = |
| 1123 { | 1123 { |
| 1124 { | 1124 { |
| 1125 RTL_PASS, | 1125 RTL_PASS, |
| 1126 "dce", /* name */ | 1126 "rtl dce", /* name */ |
| 1127 gate_fast_dce, /* gate */ | 1127 gate_fast_dce, /* gate */ |
| 1128 rest_of_handle_fast_dce, /* execute */ | 1128 rest_of_handle_fast_dce, /* execute */ |
| 1129 NULL, /* sub */ | 1129 NULL, /* sub */ |
| 1130 NULL, /* next */ | 1130 NULL, /* next */ |
| 1131 0, /* static_pass_number */ | 1131 0, /* static_pass_number */ |
| 1132 TV_DCE, /* tv_id */ | 1132 TV_DCE, /* tv_id */ |
| 1133 0, /* properties_required */ | 1133 0, /* properties_required */ |
| 1134 0, /* properties_provided */ | 1134 0, /* properties_provided */ |
| 1135 0, /* properties_destroyed */ | 1135 0, /* properties_destroyed */ |
| 1136 0, /* todo_flags_start */ | 1136 0, /* todo_flags_start */ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1153 TV_DCE, /* tv_id */ | 1153 TV_DCE, /* tv_id */ |
| 1154 0, /* properties_required */ | 1154 0, /* properties_required */ |
| 1155 0, /* properties_provided */ | 1155 0, /* properties_provided */ |
| 1156 0, /* properties_destroyed */ | 1156 0, /* properties_destroyed */ |
| 1157 0, /* todo_flags_start */ | 1157 0, /* todo_flags_start */ |
| 1158 TODO_dump_func | | 1158 TODO_dump_func | |
| 1159 TODO_df_finish | TODO_verify_rtl_sharing | | 1159 TODO_df_finish | TODO_verify_rtl_sharing | |
| 1160 TODO_ggc_collect /* todo_flags_finish */ | 1160 TODO_ggc_collect /* todo_flags_finish */ |
| 1161 } | 1161 } |
| 1162 }; | 1162 }; |
| OLD | NEW |