From 792760b9e9c015cabd3d5f1f7cf4942081f646d6 Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Wed, 4 Jul 2001 17:43:18 +0000 Subject: [PATCH] emit-rtl.c (replace_equiv_address): New function. * emit-rtl.c (replace_equiv_address): New function. * expr.h (replace_equiv_address): New declaration. * explow.c (validize_mem): Call it instead of change_address and also call if -fforce-addr and address is constant. * expr.c: Replace more calls to change_address with adjust_address and/or replace_equiv_address or to validize_mem. * function.c, regmove.c, config/alpha/alpha.c: Likewise. * config/arm/arm.md, config/clipper/clipper.md: Likewise. * config/dsp16xx/dsp16xx.md, config/fr30/fr30.c: Likewise. * config/i370/i370.md, config/i860/i860.md: Likewise. * config/i960/i960.md, config/mips/mips.c: Likewise. * config/mips/mips.md, config/pa/pa.md: Likewise. * config/pdp11/pdp11.md, config/rs6000/rs6000.c: Likewise. * config/rs6000/rs6000.md, config/sh/sh.md: Likewise. From-SVN: r43762 --- gcc/ChangeLog | 17 +++++++++ gcc/config/alpha/alpha.c | 15 +++----- gcc/config/arm/arm.md | 50 ++++++++++++------------ gcc/config/clipper/clipper.md | 4 +- gcc/config/dsp16xx/dsp16xx.md | 4 +- gcc/config/fr30/fr30.c | 7 ++-- gcc/config/i370/i370.md | 21 +---------- gcc/config/i860/i860.md | 14 ++++--- gcc/config/i960/i960.md | 15 ++++---- gcc/config/mips/mips.c | 22 +++++------ gcc/config/mips/mips.md | 4 +- gcc/config/pa/pa.md | 8 ++-- gcc/config/pdp11/pdp11.md | 8 ++-- gcc/config/rs6000/rs6000.c | 10 +++-- gcc/config/rs6000/rs6000.md | 18 ++++----- gcc/config/sh/sh.md | 2 +- gcc/emit-rtl.c | 16 ++++++++ gcc/explow.c | 6 ++- gcc/expr.c | 71 ++++++++++++++++------------------- gcc/expr.h | 6 +++ gcc/function.c | 2 +- gcc/regmove.c | 5 ++- 22 files changed, 170 insertions(+), 155 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2b66dcb05d3..dc2a6fa9010 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +Wed Jul 4 13:40:02 2001 Richard Kenner + + * emit-rtl.c (replace_equiv_address): New function. + * expr.h (replace_equiv_address): New declaration. + * explow.c (validize_mem): Call it instead of change_address and + also call if -fforce-addr and address is constant. + * expr.c: Replace more calls to change_address with adjust_address + and/or replace_equiv_address or to validize_mem. + * function.c, regmove.c, config/alpha/alpha.c: Likewise. + * config/arm/arm.md, config/clipper/clipper.md: Likewise. + * config/dsp16xx/dsp16xx.md, config/fr30/fr30.c: Likewise. + * config/i370/i370.md, config/i860/i860.md: Likewise. + * config/i960/i960.md, config/mips/mips.c: Likewise. + * config/mips/mips.md, config/pa/pa.md: Likewise. + * config/pdp11/pdp11.md, config/rs6000/rs6000.c: Likewise. + * config/rs6000/rs6000.md, config/sh/sh.md: Likewise. + 2001-07-04 Kaveh R. Ghazi * bitmap.c (bitmap_union_of_diff): Don't use BITMAP_ALLOCA. diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index ffd378674d0..3ddd7f3d9e1 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -2930,8 +2930,8 @@ alpha_expand_block_move (operands) } /* No appropriate mode; fall back on memory. */ - orig_src = change_address (orig_src, GET_MODE (orig_src), - copy_addr_to_reg (XEXP (orig_src, 0))); + orig_src = replace_equiv_address (orig_src, + copy_addr_to_reg (XEXP (orig_src, 0))); src_align = GET_MODE_BITSIZE (GET_MODE (tmp)); } @@ -2961,9 +2961,7 @@ alpha_expand_block_move (operands) for (i = 0; i < words; ++i) emit_move_insn (data_regs[nregs + i], - change_address (orig_src, SImode, - plus_constant (XEXP (orig_src, 0), - ofs + i * 4))); + adjust_address (orig_src, SImode, ofs + i * 4)); nregs += words; bytes -= words * 4; @@ -3076,8 +3074,8 @@ alpha_expand_block_move (operands) /* No appropriate mode; fall back on memory. We can speed things up by recognizing extra alignment information. */ - orig_dst = change_address (orig_dst, GET_MODE (orig_dst), - copy_addr_to_reg (XEXP (orig_dst, 0))); + orig_dst = replace_equiv_address (orig_dst, + copy_addr_to_reg (XEXP (orig_dst, 0))); dst_align = GET_MODE_BITSIZE (GET_MODE (tmp)); } @@ -3229,8 +3227,7 @@ alpha_expand_block_clear (operands) } /* No appropriate mode; fall back on memory. */ - orig_dst = change_address (orig_dst, GET_MODE (orig_dst), - copy_addr_to_reg (tmp)); + orig_dst = replace_equiv_address (orig_dst, copy_addr_to_reg (tmp)); align = GET_MODE_BITSIZE (GET_MODE (XEXP (tmp, 0))); } diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 663877de3e4..fea195483d5 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -4282,15 +4282,15 @@ "TARGET_ARM" " { - rtx addr = XEXP (operands[1], 0); + rtx op1 = operands[1]; + rtx addr = XEXP (op1, 0); enum rtx_code code = GET_CODE (addr); if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT) || code == MINUS) - addr = force_reg (SImode, addr); + op1 = replace_equiv_address (operands[1], force_reg (SImode, addr)); - operands[4] = change_address (operands[1], QImode, - plus_constant (addr, 1)); + operands[4] = adjust_address (op1, QImode, 1); operands[1] = adjust_address (operands[1], QImode, 0); operands[3] = gen_lowpart (QImode, operands[0]); operands[0] = gen_lowpart (SImode, operands[0]); @@ -4306,15 +4306,15 @@ "TARGET_ARM" " { - rtx addr = XEXP (operands[1], 0); + rtx op1 = operands[1]; + rtx addr = XEXP (op1, 0); enum rtx_code code = GET_CODE (addr); if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT) || code == MINUS) - addr = force_reg (SImode, addr); + op1 = replace_equiv_address (op1, force_reg (SImode, addr)); - operands[4] = change_address (operands[1], QImode, - plus_constant (addr, 1)); + operands[4] = adjust_address (op1, QImode, 1); operands[1] = adjust_address (operands[1], QImode, 0); operands[3] = gen_lowpart (QImode, operands[0]); operands[0] = gen_lowpart (SImode, operands[0]); @@ -4332,11 +4332,12 @@ { HOST_WIDE_INT value = INTVAL (operands[1]); rtx addr = XEXP (operands[0], 0); + rtx op0 = operands[0]; enum rtx_code code = GET_CODE (addr); if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT) || code == MINUS) - addr = force_reg (SImode, addr); + op0 = replace_equiv_address (op0, force_reg (SImode, addr)); operands[1] = gen_reg_rtx (SImode); if (BYTES_BIG_ENDIAN) @@ -4362,8 +4363,7 @@ } } - operands[3] = change_address (operands[0], QImode, - plus_constant (addr, 1)); + operands[3] = adjust_address (op0, QImode, 1); operands[0] = adjust_address (operands[0], QImode, 0); }" ) @@ -4550,18 +4550,16 @@ if (GET_CODE (operands[0]) == MEM && !memory_address_p (GET_MODE (operands[0]), XEXP (operands[0], 0))) - { - rtx temp = copy_to_reg (XEXP (operands[0], 0)); - operands[0] = change_address (operands[0], VOIDmode, temp); - } + operands[0] + = replace_equiv_address (operands[0], + copy_to_reg (XEXP (operands[0], 0))); if (GET_CODE (operands[1]) == MEM && !memory_address_p (GET_MODE (operands[1]), XEXP (operands[1], 0))) - { - rtx temp = copy_to_reg (XEXP (operands[1], 0)); - operands[1] = change_address (operands[1], VOIDmode, temp); - } + operands[1] + = replace_equiv_address (operands[1], + copy_to_reg (XEXP (operands[1], 0))); } /* Handle loading a large integer during reload */ else if (GET_CODE (operands[1]) == CONST_INT @@ -4850,17 +4848,15 @@ if (GET_CODE (operands[0]) == MEM && !memory_address_p (GET_MODE (operands[0]), XEXP (operands[0], 0))) - { - rtx temp = copy_to_reg (XEXP (operands[0], 0)); - operands[0] = change_address (operands[0], VOIDmode, temp); - } + operands[0] + = replace_equiv_address (operands[0], + copy_to_reg (XEXP (operands[0], 0))); if (GET_CODE (operands[1]) == MEM && !memory_address_p (GET_MODE (operands[1]), XEXP (operands[1], 0))) - { - rtx temp = copy_to_reg (XEXP (operands[1], 0)); - operands[1] = change_address (operands[1], VOIDmode, temp); - } + operands[1] + = replace_equiv_address (operands[1], + copy_to_reg (XEXP (operands[1], 0))); } /* Handle loading a large integer during reload */ else if (GET_CODE (operands[1]) == CONST_INT diff --git a/gcc/config/clipper/clipper.md b/gcc/config/clipper/clipper.md index 95f402ed7bd..2d2a504d6b8 100644 --- a/gcc/config/clipper/clipper.md +++ b/gcc/config/clipper/clipper.md @@ -531,8 +531,8 @@ operands[6] = addr0; operands[7] = addr1; - operands[0] = change_address (operands[0], VOIDmode, addr0); - operands[1] = change_address (operands[1], VOIDmode, addr1); + operands[0] = replace_equiv_address (operands[0], addr0); + operands[1] = replace_equiv_address (operands[1], addr1); if (GET_CODE (operands[2]) != CONST_INT) operands[2] = force_reg (SImode, operands[2]); diff --git a/gcc/config/dsp16xx/dsp16xx.md b/gcc/config/dsp16xx/dsp16xx.md index 2d821b5504a..4e851554b27 100644 --- a/gcc/config/dsp16xx/dsp16xx.md +++ b/gcc/config/dsp16xx/dsp16xx.md @@ -1131,8 +1131,8 @@ operands[5] = addr0; operands[6] = addr1; - operands[0] = change_address (operands[0], VOIDmode, addr0); - operands[1] = change_address (operands[1], VOIDmode, addr1); + operands[0] = replace_equiv_address (operands[0], VOIDmode, addr0); + operands[1] = replace_equiv_address (operands[1], VOIDmode, addr1); }") (define_insn "" diff --git a/gcc/config/fr30/fr30.c b/gcc/config/fr30/fr30.c index 0c18c652e11..8fcad88314a 100644 --- a/gcc/config/fr30/fr30.c +++ b/gcc/config/fr30/fr30.c @@ -1007,7 +1007,7 @@ fr30_move_double (operands) if (reverse) { emit_insn (gen_rtx_SET (VOIDmode, dest1, - change_address (src, SImode, addr))); + adjust_address (src, SImode, 0))); emit_insn (gen_rtx_SET (SImode, dest0, gen_rtx_REG (SImode, REGNO (addr)))); emit_insn (gen_rtx_SET (SImode, dest0, @@ -1021,7 +1021,7 @@ fr30_move_double (operands) else { emit_insn (gen_rtx_SET (VOIDmode, dest0, - change_address (src, SImode, addr))); + adjust_address (src, SImode, 0))); emit_insn (gen_rtx_SET (SImode, dest1, gen_rtx_REG (SImode, REGNO (addr)))); emit_insn (gen_rtx_SET (SImode, dest1, @@ -1058,8 +1058,7 @@ fr30_move_double (operands) src0 = operand_subword (src, 0, TRUE, mode); src1 = operand_subword (src, 1, TRUE, mode); - emit_insn (gen_rtx_SET (VOIDmode, - change_address (dest, SImode, addr), + emit_insn (gen_rtx_SET (VOIDmode, adjust_address (dest, SImode, 0), src0)); if (REGNO (addr) == STACK_POINTER_REGNUM diff --git a/gcc/config/i370/i370.md b/gcc/config/i370/i370.md index 7ef666e4323..c0d05e6e791 100644 --- a/gcc/config/i370/i370.md +++ b/gcc/config/i370/i370.md @@ -1380,21 +1380,6 @@ check_label_emit (); "" " { -/* - XXX bogus, i think, unless change_address has a side effet we need - rtx op0; - - op0 = XEXP (operands[0], 0); - if (GET_CODE (op0) == REG - || (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == REG - && GET_CODE (XEXP (op0, 1)) == CONST_INT - && (unsigned) INTVAL (XEXP (op0, 1)) < 4096)) - op0 = operands[0]; - else - op0 = change_address (operands[0], VOIDmode, - copy_to_mode_reg (SImode, op0)); - -*/ { /* implementation suggested by Richard Henderson */ rtx reg1 = gen_reg_rtx (DImode); @@ -1442,8 +1427,7 @@ check_label_emit (); && (unsigned) INTVAL (XEXP (op0, 1)) < 4096)) op0 = operands[0]; else - op0 = change_address (operands[0], VOIDmode, - copy_to_mode_reg (SImode, op0)); + op0 = replace_equiv_address (operands[0], copy_to_mode_reg (SImode, op0)); op1 = XEXP (operands[1], 0); if (GET_CODE (op1) == REG @@ -1452,8 +1436,7 @@ check_label_emit (); && (unsigned) INTVAL (XEXP (op1, 1)) < 4096)) op1 = operands[1]; else - op1 = change_address (operands[1], VOIDmode, - copy_to_mode_reg (SImode, op1)); + op1 = replace_equiv_address (operands[1], copy_to_mode_reg (SImode, op1)); if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 256) emit_insn (gen_rtx_PARALLEL (VOIDmode, diff --git a/gcc/config/i860/i860.md b/gcc/config/i860/i860.md index beeabe6927b..eda051c5b57 100644 --- a/gcc/config/i860/i860.md +++ b/gcc/config/i860/i860.md @@ -1022,8 +1022,8 @@ operands[7] = copy_to_mode_reg (SImode, XEXP (operands[0], 0)); operands[8] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); - operands[0] = change_address (operands[0], VOIDmode, operands[7]); - operands[1] = change_address (operands[1], VOIDmode, operands[8]); + operands[0] = replace_equiv_address (operands[0], operands[7]); + operands[1] = replace_equiv_address (operands[1], operands[8]); }") (define_insn "" @@ -2127,8 +2127,9 @@ fmul.ss %1,%0,%4\;fmul.ss %3,%4,%0\"; /* Make sure the address is just one reg and will stay that way. */ if (! call_insn_operand (operands[0], QImode)) operands[0] - = change_address (operands[0], VOIDmode, - copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); + = replace_equiv_address (operands[0], + copy_to_mode_reg (Pmode, + XEXP (operands[0], 0))); if (INTVAL (operands[1]) > 0) { emit_move_insn (arg_pointer_rtx, stack_pointer_rtx); @@ -2195,8 +2196,9 @@ fmul.ss %1,%0,%4\;fmul.ss %3,%4,%0\"; /* Make sure the address is just one reg and will stay that way. */ if (! call_insn_operand (operands[1], QImode)) operands[1] - = change_address (operands[1], VOIDmode, - copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); + = replace_equiv_address (operands[1], + copy_to_mode_reg (Pmode, + XEXP (operands[1], 0))); if (INTVAL (operands[2]) > 0) { emit_move_insn (arg_pointer_rtx, stack_pointer_rtx); diff --git a/gcc/config/i960/i960.md b/gcc/config/i960/i960.md index 341d13c540c..282297d5a7d 100644 --- a/gcc/config/i960/i960.md +++ b/gcc/config/i960/i960.md @@ -1004,7 +1004,7 @@ { int regno; int count; - rtx from; + int offset = 0; if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != REG @@ -1016,30 +1016,29 @@ FAIL; regno = REGNO (operands[1]); - from = memory_address (SImode, XEXP (operands[0], 0)); while (count >= 4 && ((regno & 3) == 0)) { - emit_move_insn (change_address (operands[0], TImode, from), + emit_move_insn (adjust_address (operands[0], TImode, offset), gen_rtx_REG (TImode, regno)); count -= 4; regno += 4; - from = memory_address (TImode, plus_constant (from, 16)); + offset += 16; } while (count >= 2 && ((regno & 1) == 0)) { - emit_move_insn (change_address (operands[0], DImode, from), + emit_move_insn (adjust_address (operands[0], DImode, offset), gen_rtx_REG (DImode, regno)); count -= 2; regno += 2; - from = memory_address (DImode, plus_constant (from, 8)); + offset += 8; } while (count > 0) { - emit_move_insn (change_address (operands[0], SImode, from), + emit_move_insn (adjust_address (operands[0], SImode, offset), gen_rtx_REG (SImode, regno)); count -= 1; regno += 1; - from = memory_address (SImode, plus_constant (from, 4)); + offset += 4; } DONE; }") diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 0a614d90098..37cb19bc31b 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -3248,11 +3248,11 @@ block_move_loop (dest_reg, src_reg, bytes, align, orig_dest, orig_src) rtx src_reg; /* register holding source address */ unsigned int bytes; /* # bytes to move */ int align; /* alignment */ - rtx orig_dest; /* original dest for change_address */ + rtx orig_dest; /* original dest */ rtx orig_src; /* original source for making a reg note */ { - rtx dest_mem = change_address (orig_dest, BLKmode, dest_reg); - rtx src_mem = change_address (orig_src, BLKmode, src_reg); + rtx dest_mem = replace_equiv_address (orig_dest, dest_reg); + rtx src_mem = replace_equiv_address (orig_src, src_reg); rtx align_rtx = GEN_INT (align); rtx label; rtx final_src; @@ -3383,10 +3383,10 @@ expand_block_move (operands) move_by_pieces (orig_dest, orig_src, bytes, align * BITS_PER_WORD); else if (constp && bytes <= (unsigned)2 * MAX_MOVE_BYTES) - emit_insn (gen_movstrsi_internal (change_address (orig_dest, BLKmode, - dest_reg), - change_address (orig_src, BLKmode, - src_reg), + emit_insn (gen_movstrsi_internal (replace_equiv_address (orig_dest, + dest_reg), + replace_equiv_address (orig_src, + src_reg), bytes_rtx, align_rtx)); else if (constp && align >= (unsigned) UNITS_PER_WORD && optimize) @@ -3433,10 +3433,10 @@ expand_block_move (operands) /* Bytes at the end of the loop. */ if (leftover) - emit_insn (gen_movstrsi_internal (change_address (orig_dest, BLKmode, - dest_reg), - change_address (orig_src, BLKmode, - src_reg), + emit_insn (gen_movstrsi_internal (replace_equiv_address (orig_dest, + dest_reg), + replace_equiv_address (orig_src, + src_reg), GEN_INT (leftover), GEN_INT (align))); } diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index bba9645b4eb..c55c128f331 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -5066,7 +5066,7 @@ move\\t%0,%z4\\n\\ { rtx memword, offword, hi_word, lo_word; rtx addr = find_replacement (&XEXP (operands[1], 0)); - rtx op1 = change_address (operands[1], VOIDmode, addr); + rtx op1 = replace_equiv_address (operands[1], addr); scratch = gen_rtx_REG (SImode, REGNO (scratch)); memword = adjust_address (op1, SImode, 0); @@ -5146,7 +5146,7 @@ move\\t%0,%z4\\n\\ { rtx scratch, memword, offword, hi_word, lo_word; rtx addr = find_replacement (&XEXP (operands[0], 0)); - rtx op0 = change_address (operands[0], VOIDmode, addr); + rtx op0 = replace_equiv_address (operands[0], addr); scratch = gen_rtx_REG (SImode, REGNO (operands[2])); memword = adjust_address (op0, SImode, 0); diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index ab587b391b6..59b4c766fa2 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -2814,11 +2814,11 @@ /* Fall through means we're going to use our block move pattern. */ operands[0] - = change_address (operands[0], VOIDmode, - copy_to_mode_reg (SImode, XEXP (operands[0], 0))); + = replace_equiv_address (operands[0], + copy_to_mode_reg (SImode, XEXP (operands[0], 0))); operands[1] - = change_address (operands[1], VOIDmode, - copy_to_mode_reg (SImode, XEXP (operands[1], 0))); + = replace_equiv_address (operands[1], + copy_to_mode_reg (SImode, XEXP (operands[1], 0))); operands[4] = gen_reg_rtx (SImode); operands[5] = gen_reg_rtx (SImode); operands[6] = gen_reg_rtx (SImode); diff --git a/gcc/config/pdp11/pdp11.md b/gcc/config/pdp11/pdp11.md index 93fac95be81..98a10c01e48 100644 --- a/gcc/config/pdp11/pdp11.md +++ b/gcc/config/pdp11/pdp11.md @@ -696,11 +696,11 @@ " { operands[0] - = change_address (operands[0], VOIDmode, - copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); + = replace_equiv_address (operands[0], + copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); operands[1] - = change_address (operands[1], VOIDmode, - copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); + = replace_equiv_address (operands[1], + copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); operands[5] = XEXP (operands[0], 0); operands[6] = XEXP (operands[1], 0); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index b9f2348c5ef..2f35583bb34 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1866,14 +1866,16 @@ rs6000_emit_move (dest, source, mode) if (GET_CODE (operands[0]) == MEM && GET_CODE (XEXP (operands[0], 0)) != REG && ! reload_in_progress) - operands[0] = change_address (operands[0], TImode, - copy_addr_to_reg (XEXP (operands[0], 0))); + operands[0] + = replace_equiv_address (operands[0], + copy_addr_to_reg (XEXP (operands[0], 0))); if (GET_CODE (operands[1]) == MEM && GET_CODE (XEXP (operands[1], 0)) != REG && ! reload_in_progress) - operands[1] = change_address (operands[1], TImode, - copy_addr_to_reg (XEXP (operands[1], 0))); + operands[1] + = replace_equiv_address (operands[1], + copy_addr_to_reg (XEXP (operands[1], 0))); break; default: diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 5be801da94b..e23e289ec33 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -1,6 +1,6 @@ ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler ;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, -;; 1999, 2000 Free Software Foundation, Inc. +;; 1999, 2000, 2001 Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ;; This file is part of GNU CC. @@ -8257,7 +8257,7 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32); { int regno; int count; - rtx from; + rtx op1; int i; /* Support only loading a constant number of fixed-point registers from @@ -8275,13 +8275,13 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32); regno = REGNO (operands[0]); operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); - from = force_reg (SImode, XEXP (operands[1], 0)); + op1 = replace_equiv_address (operands[1], + force_reg (SImode, XEXP (operands[1], 0))); for (i = 0; i < count; i++) XVECEXP (operands[3], 0, i) = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, regno + i), - change_address (operands[1], SImode, - plus_constant (from, i * 4))); + adjust_address (op1, SImode, i * 4)); }") (define_insn "" @@ -8354,6 +8354,7 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32); int regno; int count; rtx to; + rtx op0; int i; /* Support only storing a constant number of fixed-point registers to @@ -8372,18 +8373,17 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32); operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1)); to = force_reg (SImode, XEXP (operands[0], 0)); + op0 = replace_equiv_address (operands[0], to); XVECEXP (operands[3], 0, 0) - = gen_rtx_SET (VOIDmode, change_address (operands[0], SImode, to), - operands[1]); + = gen_rtx_SET (VOIDmode, op0, operands[1]); XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)); for (i = 1; i < count; i++) XVECEXP (operands[3], 0, i + 1) = gen_rtx_SET (VOIDmode, - change_address (operands[0], SImode, - plus_constant (to, i * 4)), + adjust_address (op0, SImode, i * 4), gen_rtx_REG (SImode, regno + i)); }") diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index eb3c88b0c61..c625b702a05 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -5028,7 +5028,7 @@ emit_insn (gen_movsi (shift_reg, operands[3])); addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1)); - operands[0] = change_address (operands[0], QImode, addr_target); + operands[0] = replace_equiv_address (operands[0], addr_target); emit_insn (gen_movqi (operands[0], gen_rtx_SUBREG (QImode, shift_reg, 0))); while (size -= 1) diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 861e73bf3ad..deca99b7459 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -1601,6 +1601,7 @@ change_address (memref, mode, addr) MEM_COPY_ATTRIBUTES (new, memref); return new; } + /* Return a memory reference like MEMREF, but with its mode changed to MODE and its address offset by OFFSET bytes. */ @@ -1615,6 +1616,21 @@ adjust_address (memref, mode, offset) return change_address (memref, mode, plus_constant (XEXP (memref, 0), offset)); } + +/* Return a memory reference like MEMREF, but with its address changed to + ADDR. The caller is asserting that the actual piece of memory pointed + to is the same, just the form of the address is being changed, such as + by putting something into a register. */ + +rtx +replace_equiv_address (memref, addr) + rtx memref; + rtx addr; +{ + /* For now, this is just a wrapper for change_address, but eventually + will do memref tracking. */ + return change_address (memref, VOIDmode, addr); +} /* Return a newly created CODE_LABEL rtx with a unique label number. */ diff --git a/gcc/explow.c b/gcc/explow.c index 1acb834709a..68394598271 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -610,10 +610,12 @@ validize_mem (ref) { if (GET_CODE (ref) != MEM) return ref; - if (memory_address_p (GET_MODE (ref), XEXP (ref, 0))) + if (! (flag_force_addr && CONSTANT_ADDRESS_P (XEXP (ref, 0))) + && memory_address_p (GET_MODE (ref), XEXP (ref, 0))) return ref; + /* Don't alter REF itself, since that is probably a stack slot. */ - return change_address (ref, GET_MODE (ref), XEXP (ref, 0)); + return replace_equiv_address (ref, XEXP (ref, 0)); } /* Given REF, either a MEM or a REG, and T, either the type of X or diff --git a/gcc/expr.c b/gcc/expr.c index 6eb90a643f0..3264aca2080 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -1879,8 +1879,7 @@ move_block_from_reg (regno, x, nregs, size) if (size <= UNITS_PER_WORD && (mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0)) != BLKmode) { - emit_move_insn (change_address (x, mode, NULL), - gen_rtx_REG (mode, regno)); + emit_move_insn (adjust_address (x, mode, 0), gen_rtx_REG (mode, regno)); return; } @@ -2746,13 +2745,13 @@ emit_move_insn (x, y) && ! push_operand (x, GET_MODE (x))) || (flag_force_addr && CONSTANT_ADDRESS_P (XEXP (x, 0))))) - x = change_address (x, VOIDmode, XEXP (x, 0)); + x = validize_mem (x); if (GET_CODE (y) == MEM && (! memory_address_p (GET_MODE (y), XEXP (y, 0)) || (flag_force_addr && CONSTANT_ADDRESS_P (XEXP (y, 0))))) - y = change_address (y, VOIDmode, XEXP (y, 0)); + y = validize_mem (y); if (mode == BLKmode) abort (); @@ -3752,9 +3751,9 @@ expand_assignment (to, from, want_value, suggest_reg) if (GET_CODE (XEXP (temp, 0)) == REG) to_rtx = temp; else - to_rtx = change_address (to_rtx, mode1, - force_reg (GET_MODE (XEXP (temp, 0)), - XEXP (temp, 0))); + to_rtx = (replace_equiv_address + (to_rtx, force_reg (GET_MODE (XEXP (temp, 0)), + XEXP (temp, 0)))); bitpos = 0; } @@ -5331,14 +5330,13 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, && GET_CODE (XEXP (addr, 1)) == CONST_INT && (XEXP (addr, 0) == virtual_incoming_args_rtx || XEXP (addr, 0) == virtual_stack_vars_rtx))) - addr = copy_to_reg (addr); + target = replace_equiv_address (target, copy_to_reg (addr)); /* Now build a reference to just the desired component. */ - to_rtx = copy_rtx (change_address (target, mode, - plus_constant (addr, - (bitpos - / BITS_PER_UNIT)))); + to_rtx = copy_rtx (adjust_address (target, mode, + bitpos / BITS_PER_UNIT)); + MEM_SET_IN_STRUCT_P (to_rtx, 1); /* If the address of the structure varies, then it might be on the stack. And, stack slots may be shared across scopes. @@ -5683,13 +5681,12 @@ save_noncopied_parts (lhs, list) | TYPE_QUAL_CONST)), 0, 1, 1); - if (! memory_address_p (TYPE_MODE (part_type), XEXP (target, 0))) - target = change_address (target, TYPE_MODE (part_type), NULL_RTX); parts = tree_cons (to_be_saved, build (RTL_EXPR, part_type, NULL_TREE, - (tree) target), + (tree) validize_mem (target)), parts); - store_expr (TREE_PURPOSE (parts), RTL_EXPR_RTL (TREE_VALUE (parts)), 0); + store_expr (TREE_PURPOSE (parts), + RTL_EXPR_RTL (TREE_VALUE (parts)), 0); } return parts; } @@ -6342,12 +6339,13 @@ expand_expr (exp, target, tmode, modifier) abort (); addr = XEXP (DECL_RTL (exp), 0); if (GET_CODE (addr) == MEM) - addr = change_address (addr, Pmode, - fix_lexical_addr (XEXP (addr, 0), exp)); + addr + = replace_equiv_address (addr, + fix_lexical_addr (XEXP (addr, 0), exp)); else addr = fix_lexical_addr (addr, exp); - temp = change_address (DECL_RTL (exp), mode, addr); + temp = replace_equiv_address (DECL_RTL (exp), addr); } /* This is the case of an array whose size is to be determined @@ -6356,8 +6354,7 @@ expand_expr (exp, target, tmode, modifier) else if (GET_CODE (DECL_RTL (exp)) == MEM && GET_CODE (XEXP (DECL_RTL (exp), 0)) == REG) - temp = change_address (DECL_RTL (exp), GET_MODE (DECL_RTL (exp)), - XEXP (DECL_RTL (exp), 0)); + temp = validize_mem (DECL_RTL (exp)); /* If DECL_RTL is memory, we are in the normal case and either the address is not valid or it is not a register and -fforce-addr @@ -6371,8 +6368,8 @@ expand_expr (exp, target, tmode, modifier) XEXP (DECL_RTL (exp), 0)) || (flag_force_addr && GET_CODE (XEXP (DECL_RTL (exp), 0)) != REG))) - temp = change_address (DECL_RTL (exp), VOIDmode, - copy_rtx (XEXP (DECL_RTL (exp), 0))); + temp = replace_equiv_address (DECL_RTL (exp), + copy_rtx (XEXP (DECL_RTL (exp), 0))); /* If we got something, return it. But first, set the alignment if the address is a register. */ @@ -6441,8 +6438,8 @@ expand_expr (exp, target, tmode, modifier) && (! memory_address_p (mode, XEXP (TREE_CST_RTL (exp), 0)) || (flag_force_addr && GET_CODE (XEXP (TREE_CST_RTL (exp), 0)) != REG))) - return change_address (TREE_CST_RTL (exp), VOIDmode, - copy_rtx (XEXP (TREE_CST_RTL (exp), 0))); + return replace_equiv_address (TREE_CST_RTL (exp), + copy_rtx (XEXP (TREE_CST_RTL (exp), 0))); return TREE_CST_RTL (exp); case EXPR_WITH_FILE_LOCATION: @@ -6491,8 +6488,9 @@ expand_expr (exp, target, tmode, modifier) } if (temp == 0 || GET_CODE (temp) != MEM) abort (); - return change_address (temp, mode, - fix_lexical_addr (XEXP (temp, 0), exp)); + return + replace_equiv_address (temp, + fix_lexical_addr (XEXP (temp, 0), exp)); } if (SAVE_EXPR_RTL (exp) == 0) { @@ -6747,13 +6745,9 @@ expand_expr (exp, target, tmode, modifier) if (modifier != EXPAND_CONST_ADDRESS && modifier != EXPAND_INITIALIZER - && modifier != EXPAND_SUM - && (! memory_address_p (GET_MODE (constructor), - XEXP (constructor, 0)) - || (flag_force_addr - && GET_CODE (XEXP (constructor, 0)) != REG))) - constructor = change_address (constructor, VOIDmode, - XEXP (constructor, 0)); + && modifier != EXPAND_SUM) + constructor = validize_mem (constructor); + return constructor; } else @@ -7095,9 +7089,10 @@ expand_expr (exp, target, tmode, modifier) if (GET_CODE (XEXP (temp, 0)) == REG) op0 = temp; else - op0 = change_address (op0, mode1, - force_reg (GET_MODE (XEXP (temp, 0)), - XEXP (temp, 0))); + op0 = (replace_equiv_address + (op0, + force_reg (GET_MODE (XEXP (temp, 0)), + XEXP (temp, 0)))); bitpos = 0; } @@ -9400,7 +9395,7 @@ expand_increment (exp, post, ignore) : copy_to_reg (XEXP (op0, 0))); rtx temp, result; - op0 = change_address (op0, VOIDmode, addr); + op0 = replace_equiv_address (op0, addr); temp = force_reg (GET_MODE (op0), op0); if (! (*insn_data[icode].operand[2].predicate) (op1, mode)) op1 = force_reg (mode, op1); diff --git a/gcc/expr.h b/gcc/expr.h index 9dff8e931a8..0e8f875113b 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -1154,6 +1154,12 @@ extern rtx change_address PARAMS ((rtx, enum machine_mode, rtx)); to MODE and its address offset by OFFSET bytes. */ extern rtx adjust_address PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT)); +/* Return a memory reference like MEMREF, but with its address changed to + ADDR. The caller is asserting that the actual piece of memory pointed + to is the same, just the form of the address is being changed, such as + by putting something into a register. */ +extern rtx replace_equiv_address PARAMS ((rtx, rtx)); + /* Return a memory reference like MEMREF, but which is known to have a valid address. */ extern rtx validize_mem PARAMS ((rtx)); diff --git a/gcc/function.c b/gcc/function.c index 8ab0037fcf3..4e0c4f8c265 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2617,7 +2617,7 @@ fixup_stack_1 (x, insn) seq = gen_sequence (); end_sequence (); emit_insn_before (seq, insn); - return change_address (x, VOIDmode, temp); + return replace_equiv_address (x, temp); } return x; } diff --git a/gcc/regmove.c b/gcc/regmove.c index 85ca4efaa7d..5d3f18eba84 100644 --- a/gcc/regmove.c +++ b/gcc/regmove.c @@ -2458,8 +2458,9 @@ combine_stack_adjustments_for_block (bb) && ! reg_mentioned_p (stack_pointer_rtx, src) && memory_address_p (GET_MODE (dest), stack_pointer_rtx) && validate_change (insn, &SET_DEST (set), - change_address (dest, VOIDmode, - stack_pointer_rtx), 0)) + replace_equiv_address (dest, + stack_pointer_rtx), + 0)) { if (last_sp_set == bb->head) bb->head = NEXT_INSN (last_sp_set);