diff options
author | Richard Sandiford <rdsandiford@googlemail.com> | 2014-08-28 06:24:27 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2014-08-28 06:24:27 +0000 |
commit | a2b7026c2e31369f7b1d63f4ba3b71cefed64268 (patch) | |
tree | 09debe30d0cb53a1873133e0ac379d655e8affcc | |
parent | e08cf836163a847ddfa4ffb8514a16be6d747dff (diff) | |
download | gcc-a2b7026c2e31369f7b1d63f4ba3b71cefed64268.zip gcc-a2b7026c2e31369f7b1d63f4ba3b71cefed64268.tar.gz gcc-a2b7026c2e31369f7b1d63f4ba3b71cefed64268.tar.bz2 |
rtl.h (replace_label_data): Delete.
gcc/
* rtl.h (replace_label_data): Delete.
(replace_label): Take the old label, new label and update-nuses flag
as direct arguments. Return void.
* cfgcleanup.c (outgoing_edges_match): Update accordingly.
* rtlanal.c (replace_label): Update interface as above. Handle
JUMP_TABLE_DATA as a special case. Handle JUMPs outside the
iterator. Use FOR_EACH_SUBRTX_PTR.
From-SVN: r214655
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cfgcleanup.c | 16 | ||||
-rw-r--r-- | gcc/rtl.h | 11 | ||||
-rw-r--r-- | gcc/rtlanal.c | 111 |
4 files changed, 82 insertions, 66 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9481150..57a3085 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2014-08-28 Richard Sandiford <rdsandiford@googlemail.com> + * rtl.h (replace_label_data): Delete. + (replace_label): Take the old label, new label and update-nuses flag + as direct arguments. Return void. + * cfgcleanup.c (outgoing_edges_match): Update accordingly. + * rtlanal.c (replace_label): Update interface as above. Handle + JUMP_TABLE_DATA as a special case. Handle JUMPs outside the + iterator. Use FOR_EACH_SUBRTX_PTR. + +2014-08-28 Richard Sandiford <rdsandiford@googlemail.com> + * rtl.h (get_pool_constant, rtx_referenced_p): Replace rtx parameters with const_rtx parameters. * varasm.c (get_pool_constant): Likewise. diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index 7dfed09..a008168 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -1719,15 +1719,11 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2) if (identical) { - replace_label_data rr; bool match; /* Temporarily replace references to LABEL1 with LABEL2 in BB1->END so that we could compare the instructions. */ - rr.r1 = label1; - rr.r2 = label2; - rr.update_label_nuses = false; - for_each_rtx_in_insn (&BB_END (bb1), replace_label, &rr); + replace_label_in_insn (BB_END (bb1), label1, label2, false); match = (old_insns_match_p (mode, BB_END (bb1), BB_END (bb2)) == dir_both); @@ -1739,9 +1735,7 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2) /* Set the original label in BB1->END because when deleting a block whose end is a tablejump, the tablejump referenced from the instruction is deleted too. */ - rr.r1 = label2; - rr.r2 = label1; - for_each_rtx_in_insn (&BB_END (bb1), replace_label, &rr); + replace_label_in_insn (BB_END (bb1), label2, label1, false); return match; } @@ -1988,20 +1982,16 @@ try_crossjump_to_edge (int mode, edge e1, edge e2, && tablejump_p (BB_END (osrc2), &label2, &table2) && label1 != label2) { - replace_label_data rr; rtx_insn *insn; /* Replace references to LABEL1 with LABEL2. */ - rr.r1 = label1; - rr.r2 = label2; - rr.update_label_nuses = true; for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) { /* Do not replace the label in SRC1->END because when deleting a block whose end is a tablejump, the tablejump referenced from the instruction is deleted too. */ if (insn != BB_END (osrc1)) - for_each_rtx_in_insn (&insn, replace_label, &rr); + replace_label_in_insn (insn, label1, label2, true); } } } @@ -2723,14 +2723,6 @@ extern void set_insn_deleted (rtx); : NULL_RTX) #define single_set_1(I) single_set_2 (I, PATTERN (I)) -/* Structure used for passing data to REPLACE_LABEL. */ -struct replace_label_data -{ - rtx r1; - rtx r2; - bool update_label_nuses; -}; - extern enum machine_mode get_address_mode (rtx mem); extern int rtx_addr_can_trap_p (const_rtx); extern bool nonzero_address_p (const_rtx); @@ -2799,7 +2791,8 @@ extern void copy_reg_eh_region_note_forward (rtx, rtx, rtx); extern void copy_reg_eh_region_note_backward (rtx, rtx, rtx); extern int inequality_comparisons_p (const_rtx); extern rtx replace_rtx (rtx, rtx, rtx); -extern int replace_label (rtx *, void *); +extern void replace_label (rtx *, rtx, rtx, bool); +extern void replace_label_in_insn (rtx_insn *, rtx, rtx, bool); extern bool rtx_referenced_p (const_rtx, const_rtx); extern bool tablejump_p (const_rtx, rtx *, rtx_jump_table_data **); extern int computed_jump_p (const_rtx); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 0e80426..f1cb224 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -2770,65 +2770,88 @@ replace_rtx (rtx x, rtx from, rtx to) return x; } -/* Replace occurrences of the old label in *X with the new one. - DATA is a REPLACE_LABEL_DATA containing the old and new labels. */ +/* Replace occurrences of the OLD_LABEL in *LOC with NEW_LABEL. Also track + the change in LABEL_NUSES if UPDATE_LABEL_NUSES. */ -int -replace_label (rtx *x, void *data) +void +replace_label (rtx *loc, rtx old_label, rtx new_label, bool update_label_nuses) { - rtx l = *x; - rtx old_label = ((replace_label_data *) data)->r1; - rtx new_label = ((replace_label_data *) data)->r2; - bool update_label_nuses = ((replace_label_data *) data)->update_label_nuses; - - if (l == NULL_RTX) - return 0; - - if (GET_CODE (l) == SYMBOL_REF - && CONSTANT_POOL_ADDRESS_P (l)) + /* Handle jump tables specially, since ADDR_{DIFF_,}VECs can be long. */ + rtx x = *loc; + if (JUMP_TABLE_DATA_P (x)) { - rtx c = get_pool_constant (l); - if (rtx_referenced_p (old_label, c)) + x = PATTERN (x); + rtvec vec = XVEC (x, GET_CODE (x) == ADDR_DIFF_VEC); + int len = GET_NUM_ELEM (vec); + for (int i = 0; i < len; ++i) { - rtx new_c, new_l; - replace_label_data *d = (replace_label_data *) data; - - /* Create a copy of constant C; replace the label inside - but do not update LABEL_NUSES because uses in constant pool - are not counted. */ - new_c = copy_rtx (c); - d->update_label_nuses = false; - for_each_rtx (&new_c, replace_label, data); - d->update_label_nuses = update_label_nuses; - - /* Add the new constant NEW_C to constant pool and replace - the old reference to constant by new reference. */ - new_l = XEXP (force_const_mem (get_pool_mode (l), new_c), 0); - *x = replace_rtx (l, l, new_l); + rtx ref = RTVEC_ELT (vec, i); + if (XEXP (ref, 0) == old_label) + { + XEXP (ref, 0) = new_label; + if (update_label_nuses) + { + ++LABEL_NUSES (new_label); + --LABEL_NUSES (old_label); + } + } } - return 0; + return; } /* If this is a JUMP_INSN, then we also need to fix the JUMP_LABEL - field. This is not handled by for_each_rtx because it doesn't + field. This is not handled by the iterator because it doesn't handle unprinted ('0') fields. */ - if (JUMP_P (l) && JUMP_LABEL (l) == old_label) - JUMP_LABEL (l) = new_label; + if (JUMP_P (x) && JUMP_LABEL (x) == old_label) + JUMP_LABEL (x) = new_label; - if ((GET_CODE (l) == LABEL_REF - || GET_CODE (l) == INSN_LIST) - && XEXP (l, 0) == old_label) + subrtx_ptr_iterator::array_type array; + FOR_EACH_SUBRTX_PTR (iter, array, loc, ALL) { - XEXP (l, 0) = new_label; - if (update_label_nuses) + rtx *loc = *iter; + if (rtx x = *loc) { - ++LABEL_NUSES (new_label); - --LABEL_NUSES (old_label); + if (GET_CODE (x) == SYMBOL_REF + && CONSTANT_POOL_ADDRESS_P (x)) + { + rtx c = get_pool_constant (x); + if (rtx_referenced_p (old_label, c)) + { + /* Create a copy of constant C; replace the label inside + but do not update LABEL_NUSES because uses in constant pool + are not counted. */ + rtx new_c = copy_rtx (c); + replace_label (&new_c, old_label, new_label, false); + + /* Add the new constant NEW_C to constant pool and replace + the old reference to constant by new reference. */ + rtx new_mem = force_const_mem (get_pool_mode (x), new_c); + *loc = replace_rtx (x, x, XEXP (new_mem, 0)); + } + } + + if ((GET_CODE (x) == LABEL_REF + || GET_CODE (x) == INSN_LIST) + && XEXP (x, 0) == old_label) + { + XEXP (x, 0) = new_label; + if (update_label_nuses) + { + ++LABEL_NUSES (new_label); + --LABEL_NUSES (old_label); + } + } } - return 0; } +} - return 0; +void +replace_label_in_insn (rtx_insn *insn, rtx old_label, rtx new_label, + bool update_label_nuses) +{ + rtx insn_as_rtx = insn; + replace_label (&insn_as_rtx, old_label, new_label, update_label_nuses); + gcc_checking_assert (insn_as_rtx == insn); } /* Return true if X is referenced in BODY. */ |