Mercurial > hg > CbC > CbC_gcc
comparison gcc/cse.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
1 /* Common subexpression elimination for GNU compiler. | 1 /* Common subexpression elimination for GNU compiler. |
2 Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998 | 2 Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998 |
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 | 3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 |
4 Free Software Foundation, Inc. | 4 Free Software Foundation, Inc. |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
8 GCC is free software; you can redistribute it and/or modify it under | 8 GCC is free software; you can redistribute it and/or modify it under |
31 #include "flags.h" | 31 #include "flags.h" |
32 #include "insn-config.h" | 32 #include "insn-config.h" |
33 #include "recog.h" | 33 #include "recog.h" |
34 #include "function.h" | 34 #include "function.h" |
35 #include "expr.h" | 35 #include "expr.h" |
36 #include "diagnostic-core.h" | |
36 #include "toplev.h" | 37 #include "toplev.h" |
37 #include "output.h" | 38 #include "output.h" |
38 #include "ggc.h" | 39 #include "ggc.h" |
39 #include "timevar.h" | 40 #include "timevar.h" |
40 #include "except.h" | 41 #include "except.h" |
2283 failure to do so leads to failure to simplify 0<100 type of | 2284 failure to do so leads to failure to simplify 0<100 type of |
2284 conditionals. | 2285 conditionals. |
2285 | 2286 |
2286 On all machines, we can't record any global registers. | 2287 On all machines, we can't record any global registers. |
2287 Nor should we record any register that is in a small | 2288 Nor should we record any register that is in a small |
2288 class, as defined by CLASS_LIKELY_SPILLED_P. */ | 2289 class, as defined by TARGET_CLASS_LIKELY_SPILLED_P. */ |
2289 bool record; | 2290 bool record; |
2290 | 2291 |
2291 if (regno >= FIRST_PSEUDO_REGISTER) | 2292 if (regno >= FIRST_PSEUDO_REGISTER) |
2292 record = true; | 2293 record = true; |
2293 else if (x == frame_pointer_rtx | 2294 else if (x == frame_pointer_rtx |
2302 record = true; | 2303 record = true; |
2303 else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC) | 2304 else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC) |
2304 record = true; | 2305 record = true; |
2305 else if (targetm.small_register_classes_for_mode_p (GET_MODE (x))) | 2306 else if (targetm.small_register_classes_for_mode_p (GET_MODE (x))) |
2306 record = false; | 2307 record = false; |
2307 else if (CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (regno))) | 2308 else if (targetm.class_likely_spilled_p (REGNO_REG_CLASS (regno))) |
2308 record = false; | 2309 record = false; |
2309 else | 2310 else |
2310 record = true; | 2311 record = true; |
2311 | 2312 |
2312 if (!record) | 2313 if (!record) |
2667 } | 2668 } |
2668 | 2669 |
2669 case MEM: | 2670 case MEM: |
2670 if (for_gcse) | 2671 if (for_gcse) |
2671 { | 2672 { |
2673 /* Can't merge two expressions in different alias sets, since we | |
2674 can decide that the expression is transparent in a block when | |
2675 it isn't, due to it being set with the different alias set. */ | |
2676 if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y)) | |
2677 return 0; | |
2678 | |
2672 /* A volatile mem should not be considered equivalent to any | 2679 /* A volatile mem should not be considered equivalent to any |
2673 other. */ | 2680 other. */ |
2674 if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y)) | 2681 if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y)) |
2675 return 0; | |
2676 | |
2677 /* Can't merge two expressions in different alias sets, since we | |
2678 can decide that the expression is transparent in a block when | |
2679 it isn't, due to it being set with the different alias set. | |
2680 | |
2681 Also, can't merge two expressions with different MEM_ATTRS. | |
2682 They could e.g. be two different entities allocated into the | |
2683 same space on the stack (see e.g. PR25130). In that case, the | |
2684 MEM addresses can be the same, even though the two MEMs are | |
2685 absolutely not equivalent. | |
2686 | |
2687 But because really all MEM attributes should be the same for | |
2688 equivalent MEMs, we just use the invariant that MEMs that have | |
2689 the same attributes share the same mem_attrs data structure. */ | |
2690 if (MEM_ATTRS (x) != MEM_ATTRS (y)) | |
2691 return 0; | 2682 return 0; |
2692 } | 2683 } |
2693 break; | 2684 break; |
2694 | 2685 |
2695 /* For commutative operations, check both orders. */ | 2686 /* For commutative operations, check both orders. */ |
4345 else if (GET_CODE (x) == CLOBBER) | 4336 else if (GET_CODE (x) == CLOBBER) |
4346 { | 4337 { |
4347 if (MEM_P (XEXP (x, 0))) | 4338 if (MEM_P (XEXP (x, 0))) |
4348 canon_reg (XEXP (x, 0), insn); | 4339 canon_reg (XEXP (x, 0), insn); |
4349 } | 4340 } |
4350 | |
4351 /* Canonicalize a USE of a pseudo register or memory location. */ | 4341 /* Canonicalize a USE of a pseudo register or memory location. */ |
4352 else if (GET_CODE (x) == USE | 4342 else if (GET_CODE (x) == USE |
4353 && ! (REG_P (XEXP (x, 0)) | 4343 && ! (REG_P (XEXP (x, 0)) |
4354 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)) | 4344 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)) |
4355 canon_reg (XEXP (x, 0), insn); | 4345 canon_reg (x, insn); |
4346 else if (GET_CODE (x) == ASM_OPERANDS) | |
4347 { | |
4348 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--) | |
4349 { | |
4350 rtx input = ASM_OPERANDS_INPUT (x, i); | |
4351 if (!(REG_P (input) && REGNO (input) < FIRST_PSEUDO_REGISTER)) | |
4352 { | |
4353 input = canon_reg (input, insn); | |
4354 validate_change (insn, &ASM_OPERANDS_INPUT (x, i), input, 1); | |
4355 } | |
4356 } | |
4357 } | |
4356 else if (GET_CODE (x) == CALL) | 4358 else if (GET_CODE (x) == CALL) |
4357 { | 4359 { |
4358 /* The result of apply_change_group can be ignored; see canon_reg. */ | 4360 /* The result of apply_change_group can be ignored; see canon_reg. */ |
4359 canon_reg (x, insn); | 4361 canon_reg (x, insn); |
4360 apply_change_group (); | 4362 apply_change_group (); |
5022 | 5024 |
5023 src = canon_rtx (trial); | 5025 src = canon_rtx (trial); |
5024 dest = canon_rtx (SET_DEST (sets[i].rtl)); | 5026 dest = canon_rtx (SET_DEST (sets[i].rtl)); |
5025 | 5027 |
5026 if (!MEM_P (src) || !MEM_P (dest) | 5028 if (!MEM_P (src) || !MEM_P (dest) |
5027 || !nonoverlapping_memrefs_p (src, dest)) | 5029 || !nonoverlapping_memrefs_p (src, dest, false)) |
5028 break; | 5030 break; |
5029 } | 5031 } |
5030 | 5032 |
5031 /* Try to optimize | 5033 /* Try to optimize |
5032 (set (reg:M N) (const_int A)) | 5034 (set (reg:M N) (const_int A)) |
6313 if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) | 6315 if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) |
6314 invalidate (DF_REF_REG (def), GET_MODE (DF_REF_REG (def))); | 6316 invalidate (DF_REF_REG (def), GET_MODE (DF_REF_REG (def))); |
6315 } | 6317 } |
6316 } | 6318 } |
6317 | 6319 |
6320 optimize_this_for_speed_p = optimize_bb_for_speed_p (bb); | |
6318 FOR_BB_INSNS (bb, insn) | 6321 FOR_BB_INSNS (bb, insn) |
6319 { | 6322 { |
6320 optimize_this_for_speed_p = optimize_bb_for_speed_p (bb); | |
6321 /* If we have processed 1,000 insns, flush the hash table to | 6323 /* If we have processed 1,000 insns, flush the hash table to |
6322 avoid extreme quadratic behavior. We must not include NOTEs | 6324 avoid extreme quadratic behavior. We must not include NOTEs |
6323 in the count since there may be more of them when generating | 6325 in the count since there may be more of them when generating |
6324 debugging information. If we clear the table at different | 6326 debugging information. If we clear the table at different |
6325 times, code generated with -g -O might be different than code | 6327 times, code generated with -g -O might be different than code |
6355 && for_each_rtx (&PATTERN (insn), check_for_label_ref, | 6357 && for_each_rtx (&PATTERN (insn), check_for_label_ref, |
6356 (void *) insn)) | 6358 (void *) insn)) |
6357 recorded_label_ref = true; | 6359 recorded_label_ref = true; |
6358 | 6360 |
6359 #ifdef HAVE_cc0 | 6361 #ifdef HAVE_cc0 |
6360 /* If the previous insn set CC0 and this insn no longer | 6362 if (NONDEBUG_INSN_P (insn)) |
6361 references CC0, delete the previous insn. Here we use | |
6362 fact that nothing expects CC0 to be valid over an insn, | |
6363 which is true until the final pass. */ | |
6364 { | |
6365 rtx prev_insn, tem; | |
6366 | |
6367 prev_insn = PREV_INSN (insn); | |
6368 if (prev_insn && NONJUMP_INSN_P (prev_insn) | |
6369 && (tem = single_set (prev_insn)) != 0 | |
6370 && SET_DEST (tem) == cc0_rtx | |
6371 && ! reg_mentioned_p (cc0_rtx, PATTERN (insn))) | |
6372 delete_insn (prev_insn); | |
6373 } | |
6374 | |
6375 /* If this insn is not the last insn in the basic block, | |
6376 it will be PREV_INSN(insn) in the next iteration. If | |
6377 we recorded any CC0-related information for this insn, | |
6378 remember it. */ | |
6379 if (insn != BB_END (bb)) | |
6380 { | 6363 { |
6381 prev_insn_cc0 = this_insn_cc0; | 6364 /* If the previous insn sets CC0 and this insn no |
6382 prev_insn_cc0_mode = this_insn_cc0_mode; | 6365 longer references CC0, delete the previous insn. |
6366 Here we use fact that nothing expects CC0 to be | |
6367 valid over an insn, which is true until the final | |
6368 pass. */ | |
6369 rtx prev_insn, tem; | |
6370 | |
6371 prev_insn = prev_nonnote_nondebug_insn (insn); | |
6372 if (prev_insn && NONJUMP_INSN_P (prev_insn) | |
6373 && (tem = single_set (prev_insn)) != NULL_RTX | |
6374 && SET_DEST (tem) == cc0_rtx | |
6375 && ! reg_mentioned_p (cc0_rtx, PATTERN (insn))) | |
6376 delete_insn (prev_insn); | |
6377 | |
6378 /* If this insn is not the last insn in the basic | |
6379 block, it will be PREV_INSN(insn) in the next | |
6380 iteration. If we recorded any CC0-related | |
6381 information for this insn, remember it. */ | |
6382 if (insn != BB_END (bb)) | |
6383 { | |
6384 prev_insn_cc0 = this_insn_cc0; | |
6385 prev_insn_cc0_mode = this_insn_cc0_mode; | |
6386 } | |
6383 } | 6387 } |
6384 #endif | 6388 #endif |
6385 } | 6389 } |
6386 } | 6390 } |
6387 | 6391 |
6388 /* With non-call exceptions, we are not always able to update | 6392 /* With non-call exceptions, we are not always able to update |
6389 the CFG properly inside cse_insn. So clean up possibly | 6393 the CFG properly inside cse_insn. So clean up possibly |
6390 redundant EH edges here. */ | 6394 redundant EH edges here. */ |
6391 if (flag_non_call_exceptions && have_eh_succ_edges (bb)) | 6395 if (cfun->can_throw_non_call_exceptions && have_eh_succ_edges (bb)) |
6392 cse_cfg_altered |= purge_dead_edges (bb); | 6396 cse_cfg_altered |= purge_dead_edges (bb); |
6393 | 6397 |
6394 /* If we changed a conditional jump, we may have terminated | 6398 /* If we changed a conditional jump, we may have terminated |
6395 the path we are following. Check that by verifying that | 6399 the path we are following. Check that by verifying that |
6396 the edge we would take still exists. If the edge does | 6400 the edge we would take still exists. If the edge does |
6569 we count each register usage. | 6573 we count each register usage. |
6570 | 6574 |
6571 Don't count a usage of DEST, which is the SET_DEST of a SET which | 6575 Don't count a usage of DEST, which is the SET_DEST of a SET which |
6572 contains X in its SET_SRC. This is because such a SET does not | 6576 contains X in its SET_SRC. This is because such a SET does not |
6573 modify the liveness of DEST. | 6577 modify the liveness of DEST. |
6574 DEST is set to pc_rtx for a trapping insn, which means that we must count | 6578 DEST is set to pc_rtx for a trapping insn, or for an insn with side effects. |
6575 uses of a SET_DEST regardless because the insn can't be deleted here. */ | 6579 We must then count uses of a SET_DEST regardless, because the insn can't be |
6580 deleted here. */ | |
6576 | 6581 |
6577 static void | 6582 static void |
6578 count_reg_usage (rtx x, int *counts, rtx dest, int incr) | 6583 count_reg_usage (rtx x, int *counts, rtx dest, int incr) |
6579 { | 6584 { |
6580 enum rtx_code code; | 6585 enum rtx_code code; |
6623 return; | 6628 return; |
6624 | 6629 |
6625 case CALL_INSN: | 6630 case CALL_INSN: |
6626 case INSN: | 6631 case INSN: |
6627 case JUMP_INSN: | 6632 case JUMP_INSN: |
6628 /* We expect dest to be NULL_RTX here. If the insn may trap, mark | 6633 /* We expect dest to be NULL_RTX here. If the insn may trap, |
6629 this fact by setting DEST to pc_rtx. */ | 6634 or if it cannot be deleted due to side-effects, mark this fact |
6630 if (insn_could_throw_p (x)) | 6635 by setting DEST to pc_rtx. */ |
6636 if (insn_could_throw_p (x) || side_effects_p (PATTERN (x))) | |
6631 dest = pc_rtx; | 6637 dest = pc_rtx; |
6632 if (code == CALL_INSN) | 6638 if (code == CALL_INSN) |
6633 count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, dest, incr); | 6639 count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, dest, incr); |
6634 count_reg_usage (PATTERN (x), counts, dest, incr); | 6640 count_reg_usage (PATTERN (x), counts, dest, incr); |
6635 | 6641 |
6665 | 6671 |
6666 count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr); | 6672 count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr); |
6667 return; | 6673 return; |
6668 | 6674 |
6669 case ASM_OPERANDS: | 6675 case ASM_OPERANDS: |
6670 /* If the asm is volatile, then this insn cannot be deleted, | |
6671 and so the inputs *must* be live. */ | |
6672 if (MEM_VOLATILE_P (x)) | |
6673 dest = NULL_RTX; | |
6674 /* Iterate over just the inputs, not the constraints as well. */ | 6676 /* Iterate over just the inputs, not the constraints as well. */ |
6675 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--) | 6677 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--) |
6676 count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, dest, incr); | 6678 count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, dest, incr); |
6677 return; | 6679 return; |
6678 | 6680 |
6692 for (j = XVECLEN (x, i) - 1; j >= 0; j--) | 6694 for (j = XVECLEN (x, i) - 1; j >= 0; j--) |
6693 count_reg_usage (XVECEXP (x, i, j), counts, dest, incr); | 6695 count_reg_usage (XVECEXP (x, i, j), counts, dest, incr); |
6694 } | 6696 } |
6695 } | 6697 } |
6696 | 6698 |
6697 /* Return true if a register is dead. Can be used in for_each_rtx. */ | 6699 /* Return true if X is a dead register. */ |
6698 | 6700 |
6699 static int | 6701 static inline int |
6700 is_dead_reg (rtx *loc, void *data) | 6702 is_dead_reg (rtx x, int *counts) |
6701 { | 6703 { |
6702 rtx x = *loc; | |
6703 int *counts = (int *)data; | |
6704 | |
6705 return (REG_P (x) | 6704 return (REG_P (x) |
6706 && REGNO (x) >= FIRST_PSEUDO_REGISTER | 6705 && REGNO (x) >= FIRST_PSEUDO_REGISTER |
6707 && counts[REGNO (x)] == 0); | 6706 && counts[REGNO (x)] == 0); |
6708 } | 6707 } |
6709 | 6708 |
6720 ; | 6719 ; |
6721 | 6720 |
6722 #ifdef HAVE_cc0 | 6721 #ifdef HAVE_cc0 |
6723 else if (GET_CODE (SET_DEST (set)) == CC0 | 6722 else if (GET_CODE (SET_DEST (set)) == CC0 |
6724 && !side_effects_p (SET_SRC (set)) | 6723 && !side_effects_p (SET_SRC (set)) |
6725 && ((tem = next_nonnote_insn (insn)) == 0 | 6724 && ((tem = next_nonnote_nondebug_insn (insn)) == NULL_RTX |
6726 || !INSN_P (tem) | 6725 || !INSN_P (tem) |
6727 || !reg_referenced_p (cc0_rtx, PATTERN (tem)))) | 6726 || !reg_referenced_p (cc0_rtx, PATTERN (tem)))) |
6728 return false; | 6727 return false; |
6729 #endif | 6728 #endif |
6730 else if (!is_dead_reg (&SET_DEST (set), counts) | 6729 else if (!is_dead_reg (SET_DEST (set), counts) |
6731 || side_effects_p (SET_SRC (set))) | 6730 || side_effects_p (SET_SRC (set))) |
6732 return true; | 6731 return true; |
6733 return false; | 6732 return false; |
6734 } | 6733 } |
6735 | 6734 |
6769 else if (!DEBUG_INSN_P (next)) | 6768 else if (!DEBUG_INSN_P (next)) |
6770 return true; | 6769 return true; |
6771 else if (INSN_VAR_LOCATION_DECL (insn) == INSN_VAR_LOCATION_DECL (next)) | 6770 else if (INSN_VAR_LOCATION_DECL (insn) == INSN_VAR_LOCATION_DECL (next)) |
6772 return false; | 6771 return false; |
6773 | 6772 |
6774 /* If this debug insn references a dead register, drop the | |
6775 location expression for now. ??? We could try to find the | |
6776 def and see if propagation is possible. */ | |
6777 if (for_each_rtx (&INSN_VAR_LOCATION_LOC (insn), is_dead_reg, counts)) | |
6778 { | |
6779 INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC (); | |
6780 df_insn_rescan (insn); | |
6781 } | |
6782 | |
6783 return true; | 6773 return true; |
6784 } | 6774 } |
6785 else | 6775 else |
6786 return true; | 6776 return true; |
6777 } | |
6778 | |
6779 /* Count the number of stores into pseudo. Callback for note_stores. */ | |
6780 | |
6781 static void | |
6782 count_stores (rtx x, const_rtx set ATTRIBUTE_UNUSED, void *data) | |
6783 { | |
6784 int *counts = (int *) data; | |
6785 if (REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER) | |
6786 counts[REGNO (x)]++; | |
6787 } | |
6788 | |
6789 struct dead_debug_insn_data | |
6790 { | |
6791 int *counts; | |
6792 rtx *replacements; | |
6793 bool seen_repl; | |
6794 }; | |
6795 | |
6796 /* Return if a DEBUG_INSN needs to be reset because some dead | |
6797 pseudo doesn't have a replacement. Callback for for_each_rtx. */ | |
6798 | |
6799 static int | |
6800 is_dead_debug_insn (rtx *loc, void *data) | |
6801 { | |
6802 rtx x = *loc; | |
6803 struct dead_debug_insn_data *ddid = (struct dead_debug_insn_data *) data; | |
6804 | |
6805 if (is_dead_reg (x, ddid->counts)) | |
6806 { | |
6807 if (ddid->replacements && ddid->replacements[REGNO (x)] != NULL_RTX) | |
6808 ddid->seen_repl = true; | |
6809 else | |
6810 return 1; | |
6811 } | |
6812 return 0; | |
6813 } | |
6814 | |
6815 /* Replace a dead pseudo in a DEBUG_INSN with replacement DEBUG_EXPR. | |
6816 Callback for simplify_replace_fn_rtx. */ | |
6817 | |
6818 static rtx | |
6819 replace_dead_reg (rtx x, const_rtx old_rtx ATTRIBUTE_UNUSED, void *data) | |
6820 { | |
6821 rtx *replacements = (rtx *) data; | |
6822 | |
6823 if (REG_P (x) | |
6824 && REGNO (x) >= FIRST_PSEUDO_REGISTER | |
6825 && replacements[REGNO (x)] != NULL_RTX) | |
6826 { | |
6827 if (GET_MODE (x) == GET_MODE (replacements[REGNO (x)])) | |
6828 return replacements[REGNO (x)]; | |
6829 return lowpart_subreg (GET_MODE (x), replacements[REGNO (x)], | |
6830 GET_MODE (replacements[REGNO (x)])); | |
6831 } | |
6832 return NULL_RTX; | |
6787 } | 6833 } |
6788 | 6834 |
6789 /* Scan all the insns and delete any that are dead; i.e., they store a register | 6835 /* Scan all the insns and delete any that are dead; i.e., they store a register |
6790 that is never used or they copy a register to itself. | 6836 that is never used or they copy a register to itself. |
6791 | 6837 |
6797 int | 6843 int |
6798 delete_trivially_dead_insns (rtx insns, int nreg) | 6844 delete_trivially_dead_insns (rtx insns, int nreg) |
6799 { | 6845 { |
6800 int *counts; | 6846 int *counts; |
6801 rtx insn, prev; | 6847 rtx insn, prev; |
6848 rtx *replacements = NULL; | |
6802 int ndead = 0; | 6849 int ndead = 0; |
6803 | 6850 |
6804 timevar_push (TV_DELETE_TRIVIALLY_DEAD); | 6851 timevar_push (TV_DELETE_TRIVIALLY_DEAD); |
6805 /* First count the number of times each register is used. */ | 6852 /* First count the number of times each register is used. */ |
6806 counts = XCNEWVEC (int, nreg); | 6853 if (MAY_HAVE_DEBUG_INSNS) |
6807 for (insn = insns; insn; insn = NEXT_INSN (insn)) | 6854 { |
6808 if (INSN_P (insn)) | 6855 counts = XCNEWVEC (int, nreg * 3); |
6809 count_reg_usage (insn, counts, NULL_RTX, 1); | 6856 for (insn = insns; insn; insn = NEXT_INSN (insn)) |
6810 | 6857 if (DEBUG_INSN_P (insn)) |
6858 count_reg_usage (INSN_VAR_LOCATION_LOC (insn), counts + nreg, | |
6859 NULL_RTX, 1); | |
6860 else if (INSN_P (insn)) | |
6861 { | |
6862 count_reg_usage (insn, counts, NULL_RTX, 1); | |
6863 note_stores (PATTERN (insn), count_stores, counts + nreg * 2); | |
6864 } | |
6865 /* If there can be debug insns, COUNTS are 3 consecutive arrays. | |
6866 First one counts how many times each pseudo is used outside | |
6867 of debug insns, second counts how many times each pseudo is | |
6868 used in debug insns and third counts how many times a pseudo | |
6869 is stored. */ | |
6870 } | |
6871 else | |
6872 { | |
6873 counts = XCNEWVEC (int, nreg); | |
6874 for (insn = insns; insn; insn = NEXT_INSN (insn)) | |
6875 if (INSN_P (insn)) | |
6876 count_reg_usage (insn, counts, NULL_RTX, 1); | |
6877 /* If no debug insns can be present, COUNTS is just an array | |
6878 which counts how many times each pseudo is used. */ | |
6879 } | |
6811 /* Go from the last insn to the first and delete insns that only set unused | 6880 /* Go from the last insn to the first and delete insns that only set unused |
6812 registers or copy a register to itself. As we delete an insn, remove | 6881 registers or copy a register to itself. As we delete an insn, remove |
6813 usage counts for registers it uses. | 6882 usage counts for registers it uses. |
6814 | 6883 |
6815 The first jump optimization pass may leave a real insn as the last | 6884 The first jump optimization pass may leave a real insn as the last |
6816 insn in the function. We must not skip that insn or we may end | 6885 insn in the function. We must not skip that insn or we may end |
6817 up deleting code that is not really dead. */ | 6886 up deleting code that is not really dead. |
6887 | |
6888 If some otherwise unused register is only used in DEBUG_INSNs, | |
6889 try to create a DEBUG_EXPR temporary and emit a DEBUG_INSN before | |
6890 the setter. Then go through DEBUG_INSNs and if a DEBUG_EXPR | |
6891 has been created for the unused register, replace it with | |
6892 the DEBUG_EXPR, otherwise reset the DEBUG_INSN. */ | |
6818 for (insn = get_last_insn (); insn; insn = prev) | 6893 for (insn = get_last_insn (); insn; insn = prev) |
6819 { | 6894 { |
6820 int live_insn = 0; | 6895 int live_insn = 0; |
6821 | 6896 |
6822 prev = PREV_INSN (insn); | 6897 prev = PREV_INSN (insn); |
6828 /* If this is a dead insn, delete it and show registers in it aren't | 6903 /* If this is a dead insn, delete it and show registers in it aren't |
6829 being used. */ | 6904 being used. */ |
6830 | 6905 |
6831 if (! live_insn && dbg_cnt (delete_trivial_dead)) | 6906 if (! live_insn && dbg_cnt (delete_trivial_dead)) |
6832 { | 6907 { |
6833 count_reg_usage (insn, counts, NULL_RTX, -1); | 6908 if (DEBUG_INSN_P (insn)) |
6909 count_reg_usage (INSN_VAR_LOCATION_LOC (insn), counts + nreg, | |
6910 NULL_RTX, -1); | |
6911 else | |
6912 { | |
6913 rtx set; | |
6914 if (MAY_HAVE_DEBUG_INSNS | |
6915 && (set = single_set (insn)) != NULL_RTX | |
6916 && is_dead_reg (SET_DEST (set), counts) | |
6917 /* Used at least once in some DEBUG_INSN. */ | |
6918 && counts[REGNO (SET_DEST (set)) + nreg] > 0 | |
6919 /* And set exactly once. */ | |
6920 && counts[REGNO (SET_DEST (set)) + nreg * 2] == 1 | |
6921 && !side_effects_p (SET_SRC (set)) | |
6922 && asm_noperands (PATTERN (insn)) < 0) | |
6923 { | |
6924 rtx dval, bind; | |
6925 | |
6926 /* Create DEBUG_EXPR (and DEBUG_EXPR_DECL). */ | |
6927 dval = make_debug_expr_from_rtl (SET_DEST (set)); | |
6928 | |
6929 /* Emit a debug bind insn before the insn in which | |
6930 reg dies. */ | |
6931 bind = gen_rtx_VAR_LOCATION (GET_MODE (SET_DEST (set)), | |
6932 DEBUG_EXPR_TREE_DECL (dval), | |
6933 SET_SRC (set), | |
6934 VAR_INIT_STATUS_INITIALIZED); | |
6935 count_reg_usage (bind, counts + nreg, NULL_RTX, 1); | |
6936 | |
6937 bind = emit_debug_insn_before (bind, insn); | |
6938 df_insn_rescan (bind); | |
6939 | |
6940 if (replacements == NULL) | |
6941 replacements = XCNEWVEC (rtx, nreg); | |
6942 replacements[REGNO (SET_DEST (set))] = dval; | |
6943 } | |
6944 | |
6945 count_reg_usage (insn, counts, NULL_RTX, -1); | |
6946 ndead++; | |
6947 } | |
6834 delete_insn_and_edges (insn); | 6948 delete_insn_and_edges (insn); |
6835 ndead++; | 6949 } |
6836 } | 6950 } |
6951 | |
6952 if (MAY_HAVE_DEBUG_INSNS) | |
6953 { | |
6954 struct dead_debug_insn_data ddid; | |
6955 ddid.counts = counts; | |
6956 ddid.replacements = replacements; | |
6957 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn)) | |
6958 if (DEBUG_INSN_P (insn)) | |
6959 { | |
6960 /* If this debug insn references a dead register that wasn't replaced | |
6961 with an DEBUG_EXPR, reset the DEBUG_INSN. */ | |
6962 ddid.seen_repl = false; | |
6963 if (for_each_rtx (&INSN_VAR_LOCATION_LOC (insn), | |
6964 is_dead_debug_insn, &ddid)) | |
6965 { | |
6966 INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC (); | |
6967 df_insn_rescan (insn); | |
6968 } | |
6969 else if (ddid.seen_repl) | |
6970 { | |
6971 INSN_VAR_LOCATION_LOC (insn) | |
6972 = simplify_replace_fn_rtx (INSN_VAR_LOCATION_LOC (insn), | |
6973 NULL_RTX, replace_dead_reg, | |
6974 replacements); | |
6975 df_insn_rescan (insn); | |
6976 } | |
6977 } | |
6978 if (replacements) | |
6979 free (replacements); | |
6837 } | 6980 } |
6838 | 6981 |
6839 if (dump_file && ndead) | 6982 if (dump_file && ndead) |
6840 fprintf (dump_file, "Deleted %i trivially dead insns\n", | 6983 fprintf (dump_file, "Deleted %i trivially dead insns\n", |
6841 ndead); | 6984 ndead); |