On 01/08/14 16:13, Jakub Jelinek wrote:
Please add a function comment for it (perhaps saying that it is like single_set but never allows more than one SET). Ok with that change.
My bad. Thanks for catching it. Attaching the installed patch for reference. Jeff
commit 12e467a657653de484178f0d0d66786a92d62ebe Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Thu Jan 9 04:42:38 2014 +0000 * ree.c (get_sub_rtx): New function, extracted from... (merge_def_and_ext): Here. (combine_reaching_defs): Use get_sub_rtx. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206454 138bc75d-0d04-0410-961f-82ee72b054a4 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f63918e..e4872f2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-01-08 Jeff Law <l...@redhat.com> + + * ree.c (get_sub_rtx): New function, extracted from... + (merge_def_and_ext): Here. + (combine_reaching_defs): Use get_sub_rtx. + 2014-01-08 Eric Botcazou <ebotca...@adacore.com> * cgraph.h (varpool_variable_node): Do not choke on null node. diff --git a/gcc/ree.c b/gcc/ree.c index ec09c7a..1c4f3ad 100644 --- a/gcc/ree.c +++ b/gcc/ree.c @@ -580,27 +580,21 @@ make_defs_and_copies_lists (rtx extend_insn, const_rtx set_pat, return ret; } -/* Merge the DEF_INSN with an extension. Calls combine_set_extension - on the SET pattern. */ - -static bool -merge_def_and_ext (ext_cand *cand, rtx def_insn, ext_state *state) +/* If DEF_INSN has single SET expression, possibly buried inside + a PARALLEL, return the address of the SET expression, else + return NULL. This is similar to single_set, except that + single_set allows multiple SETs when all but one is dead. */ +static rtx * +get_sub_rtx (rtx def_insn) { - enum machine_mode ext_src_mode; - enum rtx_code code; - rtx *sub_rtx; - rtx s_expr; - int i; - - ext_src_mode = GET_MODE (XEXP (SET_SRC (cand->expr), 0)); - code = GET_CODE (PATTERN (def_insn)); - sub_rtx = NULL; + enum rtx_code code = GET_CODE (PATTERN (def_insn)); + rtx *sub_rtx = NULL; if (code == PARALLEL) { - for (i = 0; i < XVECLEN (PATTERN (def_insn), 0); i++) + for (int i = 0; i < XVECLEN (PATTERN (def_insn), 0); i++) { - s_expr = XVECEXP (PATTERN (def_insn), 0, i); + rtx s_expr = XVECEXP (PATTERN (def_insn), 0, i); if (GET_CODE (s_expr) != SET) continue; @@ -609,7 +603,7 @@ merge_def_and_ext (ext_cand *cand, rtx def_insn, ext_state *state) else { /* PARALLEL with multiple SETs. */ - return false; + return NULL; } } } @@ -618,10 +612,27 @@ merge_def_and_ext (ext_cand *cand, rtx def_insn, ext_state *state) else { /* It is not a PARALLEL or a SET, what could it be ? */ - return false; + return NULL; } gcc_assert (sub_rtx != NULL); + return sub_rtx; +} + +/* Merge the DEF_INSN with an extension. Calls combine_set_extension + on the SET pattern. */ + +static bool +merge_def_and_ext (ext_cand *cand, rtx def_insn, ext_state *state) +{ + enum machine_mode ext_src_mode; + rtx *sub_rtx; + + ext_src_mode = GET_MODE (XEXP (SET_SRC (cand->expr), 0)); + sub_rtx = get_sub_rtx (def_insn); + + if (sub_rtx == NULL) + return false; if (REG_P (SET_DEST (*sub_rtx)) && (GET_MODE (SET_DEST (*sub_rtx)) == ext_src_mode @@ -707,8 +718,13 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state) /* If there is an overlap between the destination of DEF_INSN and CAND->insn, then this transformation is not safe. Note we have to test in the widened mode. */ + rtx *dest_sub_rtx = get_sub_rtx (def_insn); + if (dest_sub_rtx == NULL + || !REG_P (SET_DEST (*dest_sub_rtx))) + return false; + rtx tmp_reg = gen_rtx_REG (GET_MODE (SET_DEST (PATTERN (cand->insn))), - REGNO (SET_DEST (PATTERN (def_insn)))); + REGNO (SET_DEST (*dest_sub_rtx))); if (reg_overlap_mentioned_p (tmp_reg, SET_DEST (PATTERN (cand->insn)))) return false;