diff options
author | John David Anglin <dave.anglin@nrc-cnrc.gc.ca> | 2003-10-08 17:55:41 +0000 |
---|---|---|
committer | John David Anglin <danglin@gcc.gnu.org> | 2003-10-08 17:55:41 +0000 |
commit | 9ab81df26115cdf383adc130c78074aa48a45ae2 (patch) | |
tree | 04d2ab8aacf304e21a4ca41a910c138798e74708 /gcc | |
parent | 85aa13b28714657d91baabd5862c92008071706b (diff) | |
download | gcc-9ab81df26115cdf383adc130c78074aa48a45ae2.zip gcc-9ab81df26115cdf383adc130c78074aa48a45ae2.tar.gz gcc-9ab81df26115cdf383adc130c78074aa48a45ae2.tar.bz2 |
re PR rtl-optimization/12142 (-fnon-call-exceptions generates incorrect code)
PR optimization/12142
* cse.c (count_reg_usage): In a SET with a REG SET_DEST, count the
uses of the register in the SET_SRC. Remove unnecessary argument.
* pa.c (legitimize_pic_address): Before reload, use a scratch register
for the intermediate result in loading the address of a SYMBOL_REF.
Set the MEM_NOTRAP_P flag for the MEM. Add a REG_EQUAL to the insn
which loads the SYMBOL_REF address.
From-SVN: r72234
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/pa/pa.c | 19 | ||||
-rw-r--r-- | gcc/cse.c | 55 |
3 files changed, 48 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 72fd7ae..626e9aa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2003-10-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> + + PR optimization/12142 + * cse.c (count_reg_usage): In a SET with a REG SET_DEST, count the + uses of the register in the SET_SRC. Remove unnecessary argument. + * pa.c (legitimize_pic_address): Before reload, use a scratch register + for the intermediate result in loading the address of a SYMBOL_REF. + Set the MEM_NOTRAP_P flag for the MEM. Add a REG_EQUAL to the insn + which loads the SYMBOL_REF address. + 2003-10-08 Timo Kokkonen <tjko@iki.fi> Eric Botcazou <ebotcazou@libertysurf.fr> diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index a438ac4..366128c 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -836,22 +836,35 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg) } if (GET_CODE (orig) == SYMBOL_REF) { + rtx insn, tmp_reg; + if (reg == 0) abort (); - emit_move_insn (reg, + /* Before reload, allocate a temporary register for the intermediate + result. This allows the sequence to be deleted when the final + result is unused and the insns are trivially dead. */ + tmp_reg = ((reload_in_progress || reload_completed) + ? reg : gen_reg_rtx (Pmode)); + + emit_move_insn (tmp_reg, gen_rtx_PLUS (word_mode, pic_offset_table_rtx, gen_rtx_HIGH (word_mode, orig))); pic_ref = gen_rtx_MEM (Pmode, - gen_rtx_LO_SUM (Pmode, reg, + gen_rtx_LO_SUM (Pmode, tmp_reg, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), 0))); current_function_uses_pic_offset_table = 1; + MEM_NOTRAP_P (pic_ref) = 1; RTX_UNCHANGING_P (pic_ref) = 1; - emit_move_insn (reg, pic_ref); + insn = emit_move_insn (reg, pic_ref); + + /* Put a REG_EQUAL note on this insn, so that it can be optimized. */ + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, orig, REG_NOTES (insn)); + return reg; } else if (GET_CODE (orig) == CONST) @@ -647,7 +647,7 @@ static void invalidate_skipped_block (rtx); static void cse_check_loop_start (rtx, rtx, void *); static void cse_set_around_loop (rtx, rtx, rtx); static rtx cse_basic_block (rtx, rtx, struct branch_path *, int); -static void count_reg_usage (rtx, int *, rtx, int); +static void count_reg_usage (rtx, int *, int); static int check_for_label_ref (rtx *, void *); extern void dump_class (struct table_elt*); static struct cse_reg_info * get_cse_reg_info (unsigned int); @@ -7301,14 +7301,10 @@ check_for_label_ref (rtx *rtl, void *data) /* Count the number of times registers are used (not set) in X. COUNTS is an array in which we accumulate the count, INCR is how much - we count each register usage. - - Don't count a usage of DEST, which is the SET_DEST of a SET which - contains X in its SET_SRC. This is because such a SET does not - modify the liveness of DEST. */ + we count each register usage. */ static void -count_reg_usage (rtx x, int *counts, rtx dest, int incr) +count_reg_usage (rtx x, int *counts, int incr) { enum rtx_code code; rtx note; @@ -7321,8 +7317,7 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr) switch (code = GET_CODE (x)) { case REG: - if (x != dest) - counts[REGNO (x)] += incr; + counts[REGNO (x)] += incr; return; case PC: @@ -7339,25 +7334,23 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr) /* If we are clobbering a MEM, mark any registers inside the address as being used. */ if (GET_CODE (XEXP (x, 0)) == MEM) - count_reg_usage (XEXP (XEXP (x, 0), 0), counts, NULL_RTX, incr); + count_reg_usage (XEXP (XEXP (x, 0), 0), counts, incr); return; case SET: /* Unless we are setting a REG, count everything in SET_DEST. */ if (GET_CODE (SET_DEST (x)) != REG) - count_reg_usage (SET_DEST (x), counts, NULL_RTX, incr); - count_reg_usage (SET_SRC (x), counts, - SET_DEST (x), - incr); + count_reg_usage (SET_DEST (x), counts, incr); + count_reg_usage (SET_SRC (x), counts, incr); return; case CALL_INSN: - count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, NULL_RTX, incr); + count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, incr); /* Fall through. */ case INSN: case JUMP_INSN: - count_reg_usage (PATTERN (x), counts, NULL_RTX, incr); + count_reg_usage (PATTERN (x), counts, incr); /* Things used in a REG_EQUAL note aren't dead since loop may try to use them. */ @@ -7372,12 +7365,12 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr) Process all the arguments. */ do { - count_reg_usage (XEXP (eqv, 0), counts, NULL_RTX, incr); + count_reg_usage (XEXP (eqv, 0), counts, incr); eqv = XEXP (eqv, 1); } while (eqv && GET_CODE (eqv) == EXPR_LIST); else - count_reg_usage (eqv, counts, NULL_RTX, incr); + count_reg_usage (eqv, counts, incr); } return; @@ -7387,19 +7380,15 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr) /* FUNCTION_USAGE expression lists may include (CLOBBER (mem /u)), involving registers in the address. */ || GET_CODE (XEXP (x, 0)) == CLOBBER) - count_reg_usage (XEXP (x, 0), counts, NULL_RTX, incr); + count_reg_usage (XEXP (x, 0), counts, incr); - count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr); + count_reg_usage (XEXP (x, 1), counts, incr); return; case ASM_OPERANDS: - /* If the asm is volatile, then this insn cannot be deleted, - and so the inputs *must* be live. */ - if (MEM_VOLATILE_P (x)) - dest = NULL_RTX; /* Iterate over just the inputs, not the constraints as well. */ for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--) - count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, dest, incr); + count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, incr); return; case INSN_LIST: @@ -7413,10 +7402,10 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr) for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') - count_reg_usage (XEXP (x, i), counts, dest, incr); + count_reg_usage (XEXP (x, i), counts, incr); else if (fmt[i] == 'E') for (j = XVECLEN (x, i) - 1; j >= 0; j--) - count_reg_usage (XVECEXP (x, i, j), counts, dest, incr); + count_reg_usage (XVECEXP (x, i, j), counts, incr); } } @@ -7508,11 +7497,11 @@ dead_libcall_p (rtx insn, int *counts) new = XEXP (note, 0); /* While changing insn, we must update the counts accordingly. */ - count_reg_usage (insn, counts, NULL_RTX, -1); + count_reg_usage (insn, counts, -1); if (validate_change (insn, &SET_SRC (set), new, 0)) { - count_reg_usage (insn, counts, NULL_RTX, 1); + count_reg_usage (insn, counts, 1); remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX)); remove_note (insn, note); return true; @@ -7523,14 +7512,14 @@ dead_libcall_p (rtx insn, int *counts) new = force_const_mem (GET_MODE (SET_DEST (set)), new); if (new && validate_change (insn, &SET_SRC (set), new, 0)) { - count_reg_usage (insn, counts, NULL_RTX, 1); + count_reg_usage (insn, counts, 1); remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX)); remove_note (insn, note); return true; } } - count_reg_usage (insn, counts, NULL_RTX, 1); + count_reg_usage (insn, counts, 1); return false; } @@ -7554,7 +7543,7 @@ delete_trivially_dead_insns (rtx insns, int nreg) /* First count the number of times each register is used. */ counts = xcalloc (nreg, sizeof (int)); for (insn = next_real_insn (insns); insn; insn = next_real_insn (insn)) - count_reg_usage (insn, counts, NULL_RTX, 1); + count_reg_usage (insn, counts, 1); do { @@ -7598,7 +7587,7 @@ delete_trivially_dead_insns (rtx insns, int nreg) if (! live_insn) { - count_reg_usage (insn, counts, NULL_RTX, -1); + count_reg_usage (insn, counts, -1); delete_insn_and_edges (insn); ndead++; } |