diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-25 19:29:43 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-25 19:29:43 +0000 |
commit | 46dfcc3ee85a4a02abce4d45ee619f240c116af6 (patch) | |
tree | 6c3dc3d53cd17d62447673b81abbcfc69bacd2f3 /gcc/jump.c | |
parent | 2a8624373adc103f943e22e781c2d6fadb828eae (diff) | |
download | gcc-46dfcc3ee85a4a02abce4d45ee619f240c116af6.tar.gz |
2011-08-25 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 178073 using svnmerge.
2011-08-25 Basile Starynkevitch <basile@starynkevitch.net>
* gcc/melt-runtime.c (melt_linemap_compute_current_location): Use the
linemap_position_for_column function for GCC 4.7 when merging with
GCC trunk rev 178073.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@178087 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/jump.c')
-rw-r--r-- | gcc/jump.c | 85 |
1 files changed, 53 insertions, 32 deletions
diff --git a/gcc/jump.c b/gcc/jump.c index 0d29f0fcb18..8dc78f2aceb 100644 --- a/gcc/jump.c +++ b/gcc/jump.c @@ -1,7 +1,7 @@ /* Optimize jump instructions, for GNU compiler. Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997 - 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. + 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, + 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -970,6 +970,15 @@ onlyjump_p (const_rtx insn) return 1; } +/* Return true iff INSN is a jump and its JUMP_LABEL is a label, not + NULL or a return. */ +bool +jump_to_label_p (rtx insn) +{ + return (JUMP_P (insn) + && JUMP_LABEL (insn) != NULL && !ANY_RETURN_P (JUMP_LABEL (insn))); +} + #ifdef HAVE_cc0 /* Return nonzero if X is an RTX that only sets the condition codes @@ -1030,6 +1039,7 @@ sets_cc0_p (const_rtx x) notes. If INSN is an INSN or a CALL_INSN or non-target operands of a JUMP_INSN, and there is at least one CODE_LABEL referenced in INSN, add a REG_LABEL_OPERAND note containing that label to INSN. + For returnjumps, the JUMP_LABEL will also be set as appropriate. Note that two labels separated by a loop-beginning note must be kept distinct if we have not yet done loop-optimization, @@ -1072,6 +1082,14 @@ mark_jump_label_1 (rtx x, rtx insn, bool in_mem, bool is_target) case CALL: return; + case RETURN: + if (is_target) + { + gcc_assert (JUMP_LABEL (insn) == NULL || JUMP_LABEL (insn) == x); + JUMP_LABEL (insn) = x; + } + return; + case MEM: in_mem = true; break; @@ -1233,7 +1251,7 @@ delete_related_insns (rtx insn) /* If deleting a jump, decrement the count of the label, and delete the label if it is now unused. */ - if (JUMP_P (insn) && JUMP_LABEL (insn)) + if (jump_to_label_p (insn)) { rtx lab = JUMP_LABEL (insn), lab_next; @@ -1364,6 +1382,18 @@ delete_for_peephole (rtx from, rtx to) is also an unconditional jump in that case. */ } +/* A helper function for redirect_exp_1; examines its input X and returns + either a LABEL_REF around a label, or a RETURN if X was NULL. */ +static rtx +redirect_target (rtx x) +{ + if (x == NULL_RTX) + return ret_rtx; + if (!ANY_RETURN_P (x)) + return gen_rtx_LABEL_REF (Pmode, x); + return x; +} + /* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or NLABEL as a return. Accrue modifications into the change group. */ @@ -1375,37 +1405,22 @@ redirect_exp_1 (rtx *loc, rtx olabel, rtx nlabel, rtx insn) int i; const char *fmt; - if (code == LABEL_REF) - { - if (XEXP (x, 0) == olabel) - { - rtx n; - if (nlabel) - n = gen_rtx_LABEL_REF (Pmode, nlabel); - else - n = ret_rtx; - - validate_change (insn, loc, n, 1); - return; - } - } - else if (code == RETURN && olabel == 0) + if ((code == LABEL_REF && XEXP (x, 0) == olabel) + || x == olabel) { - if (nlabel) - x = gen_rtx_LABEL_REF (Pmode, nlabel); - else - x = ret_rtx; - if (loc == &PATTERN (insn)) - x = gen_rtx_SET (VOIDmode, pc_rtx, x); + x = redirect_target (nlabel); + if (GET_CODE (x) == LABEL_REF && loc == &PATTERN (insn)) + x = gen_rtx_SET (VOIDmode, pc_rtx, x); validate_change (insn, loc, x, 1); return; } - if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx + if (code == SET && SET_DEST (x) == pc_rtx + && ANY_RETURN_P (nlabel) && GET_CODE (SET_SRC (x)) == LABEL_REF && XEXP (SET_SRC (x), 0) == olabel) { - validate_change (insn, loc, ret_rtx, 1); + validate_change (insn, loc, nlabel, 1); return; } @@ -1442,6 +1457,7 @@ redirect_jump_1 (rtx jump, rtx nlabel) int ochanges = num_validated_changes (); rtx *loc, asmop; + gcc_assert (nlabel != NULL_RTX); asmop = extract_asm_operands (PATTERN (jump)); if (asmop) { @@ -1463,17 +1479,20 @@ redirect_jump_1 (rtx jump, rtx nlabel) jump target label is unused as a result, it and the code following it may be deleted. - If NLABEL is zero, we are to turn the jump into a (possibly conditional) - RETURN insn. + Normally, NLABEL will be a label, but it may also be a RETURN rtx; + in that case we are to turn the jump into a (possibly conditional) + return insn. The return value will be 1 if the change was made, 0 if it wasn't - (this can only occur for NLABEL == 0). */ + (this can only occur when trying to produce return insns). */ int redirect_jump (rtx jump, rtx nlabel, int delete_unused) { rtx olabel = JUMP_LABEL (jump); + gcc_assert (nlabel != NULL_RTX); + if (nlabel == olabel) return 1; @@ -1501,13 +1520,14 @@ redirect_jump_2 (rtx jump, rtx olabel, rtx nlabel, int delete_unused, about this. */ gcc_assert (delete_unused >= 0); JUMP_LABEL (jump) = nlabel; - if (nlabel) + if (!ANY_RETURN_P (nlabel)) ++LABEL_NUSES (nlabel); /* Update labels in any REG_EQUAL note. */ if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX) { - if (!nlabel || (invert && !invert_exp_1 (XEXP (note, 0), jump))) + if (ANY_RETURN_P (nlabel) + || (invert && !invert_exp_1 (XEXP (note, 0), jump))) remove_note (jump, note); else { @@ -1516,7 +1536,8 @@ redirect_jump_2 (rtx jump, rtx olabel, rtx nlabel, int delete_unused, } } - if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused > 0 + if (!ANY_RETURN_P (olabel) + && --LABEL_NUSES (olabel) == 0 && delete_unused > 0 /* Undefined labels will remain outside the insn stream. */ && INSN_UID (olabel)) delete_related_insns (olabel); |