summaryrefslogtreecommitdiff
path: root/gcc/rtlanal.c
diff options
context:
space:
mode:
authorzlomek <zlomek@138bc75d-0d04-0410-961f-82ee72b054a4>2003-03-15 22:51:37 +0000
committerzlomek <zlomek@138bc75d-0d04-0410-961f-82ee72b054a4>2003-03-15 22:51:37 +0000
commitcda612f51f852f48bc928685c509036fb8a469db (patch)
tree2b611926dbc72532503869b1479e8eecd0fc8e96 /gcc/rtlanal.c
parent0653bda398261b7f4b9d2bbaa8e1caf5c9123175 (diff)
downloadgcc-cda612f51f852f48bc928685c509036fb8a469db.tar.gz
* rtl.h (subrtx_p): Renamed to rtx_referenced_p.
(rtx_pair): Added new element update_label_nuses, renamed to replace_label_data. * cfgcleanup.c (outgoing_edges_match, try_crossjump_to_edge): Use replace_label_data instead of rtx_pair. * loop.c (load_mems): Likewise. * rtlanal.c (replace_label): Replace label in pool constants and in INSN_LIST (in REG_LABEL note). (subrtx_p): Renamed to rtx_referenced_p. (subrtx_p_1): Renamed to rtx_referenced_p_1, compare the interior of LABEL_REF with CODE_LABEL, traverse constants from pool. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@64419 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/rtlanal.c')
-rw-r--r--gcc/rtlanal.c95
1 files changed, 71 insertions, 24 deletions
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 85b193e4cbb..dc87e451ac3 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -38,7 +38,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
static int global_reg_mentioned_p_1 PARAMS ((rtx *, void *));
static void set_of_1 PARAMS ((rtx, rtx, void *));
static void insn_dependent_p_1 PARAMS ((rtx, rtx, void *));
-static int subrtx_p_1 PARAMS ((rtx *, void *));
+static int rtx_referenced_p_1 PARAMS ((rtx *, void *));
static int computed_jump_p_1 PARAMS ((rtx));
static void parms_set PARAMS ((rtx, rtx, void *));
static bool hoist_test_store PARAMS ((rtx, rtx, regset));
@@ -2796,7 +2796,7 @@ replace_regs (x, reg_map, nregs, replace_dest)
}
/* Replace occurrences of the old label in *X with the new one.
- DATA is an rtx_pair containing the old and new labels, respectively. */
+ DATA is a REPLACE_LABEL_DATA containing the old and new labels. */
int
replace_label (x, data)
@@ -2804,51 +2804,98 @@ replace_label (x, data)
void *data;
{
rtx l = *x;
- rtx old_label = ((rtx_pair *) data)->r1;
- rtx new_label = ((rtx_pair *) data)->r2;
+ rtx tmp;
+ 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) == MEM
+ && (tmp = XEXP (l, 0)) != NULL_RTX
+ && GET_CODE (tmp) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (tmp))
+ {
+ rtx c = get_pool_constant (tmp);
+ if (rtx_referenced_p (old_label, c))
+ {
+ 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 = force_const_mem (get_pool_mode (tmp), new_c);
+ *x = replace_rtx (l, l, new_l);
+ }
+ return 0;
+ }
+
/* 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
handle unprinted ('0') fields. */
if (GET_CODE (l) == JUMP_INSN && JUMP_LABEL (l) == old_label)
JUMP_LABEL (l) = new_label;
-
- if (GET_CODE (l) != LABEL_REF)
- return 0;
-
- if (XEXP (l, 0) != old_label)
- return 0;
- XEXP (l, 0) = new_label;
- ++LABEL_NUSES (new_label);
- --LABEL_NUSES (old_label);
+ if ((GET_CODE (l) == LABEL_REF
+ || GET_CODE (l) == INSN_LIST)
+ && XEXP (l, 0) == old_label)
+ {
+ XEXP (l, 0) = new_label;
+ if (update_label_nuses)
+ {
+ ++LABEL_NUSES (new_label);
+ --LABEL_NUSES (old_label);
+ }
+ return 0;
+ }
return 0;
}
-/* Return RTX_EQUAL_P (*PX, SUBX). If *PX and SUBX are not equal
- FOR_EACH_RTX continues traversing, if they are equal FOR_EACH_RTX
- stops traversing and returns the same value as this function. */
+/* When *BODY is equal to X or X is directly referenced by *BODY
+ return nonzero, thus FOR_EACH_RTX stops traversing and returns nonzero
+ too, otherwise FOR_EACH_RTX continues traversing *BODY. */
static int
-subrtx_p_1 (px, subx)
- rtx *px;
- void *subx;
+rtx_referenced_p_1 (body, x)
+ rtx *body;
+ void *x;
{
- return rtx_equal_p (*px, (rtx) subx);
+ rtx y = (rtx) x;
+
+ if (*body == NULL_RTX)
+ return y == NULL_RTX;
+
+ /* Return true if a label_ref *BODY refers to label Y. */
+ if (GET_CODE (*body) == LABEL_REF && GET_CODE (y) == CODE_LABEL)
+ return XEXP (*body, 0) == y;
+
+ /* If *BODY is a reference to pool constant traverse the constant. */
+ if (GET_CODE (*body) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (*body))
+ return rtx_referenced_p (y, get_pool_constant (*body));
+
+ /* By default, compare the RTL expressions. */
+ return rtx_equal_p (*body, y);
}
-/* Return true if SUBX is equal to some subexpression of X. */
+/* Return true if X is referenced in BODY. */
int
-subrtx_p (subx, x)
- rtx subx;
+rtx_referenced_p (x, body)
rtx x;
+ rtx body;
{
- return for_each_rtx (&x, subrtx_p_1, subx);
+ return for_each_rtx (&body, rtx_referenced_p_1, x);
}
/* If INSN is a jump to jumptable insn rturn true and store the label (which