diff options
author | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1993-09-06 17:27:22 +0000 |
---|---|---|
committer | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1993-09-06 17:27:22 +0000 |
commit | 2c18b47c7ca72ecf66a0c1495c966337f406b1c1 (patch) | |
tree | 7cf17357ba91b8735d3dfb33067ac90aa301c828 /gcc/rtlanal.c | |
parent | d21e4486fe476c46a2e6b996a1c371ede1626941 (diff) | |
download | gcc-2c18b47c7ca72ecf66a0c1495c966337f406b1c1.tar.gz |
(modified_between_p): Handle vectors.
(modified_in_p): New function.
(refers_to_regno_p): If setting AP, FP, or SP, we clobber the virtual
registers.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@5267 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/rtlanal.c')
-rw-r--r-- | gcc/rtlanal.c | 78 |
1 files changed, 74 insertions, 4 deletions
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 549f9054f6e..82ac3afd3df 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -1,5 +1,5 @@ /* Analyze RTL for C-Compiler - Copyright (C) 1987, 1988, 1991, 1992 Free Software Foundation, Inc. + Copyright (C) 1987, 1988, 1991, 1992, 1993 Free Software Foundation, Inc. This file is part of GNU CC. @@ -472,7 +472,7 @@ modified_between_p (x, start, end) { enum rtx_code code = GET_CODE (x); char *fmt; - int i; + int i, j; switch (code) { @@ -500,10 +500,68 @@ modified_between_p (x, start, end) fmt = GET_RTX_FORMAT (code); for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - if (fmt[i] == 'e' - && modified_between_p (XEXP (x, i), start, end)) + { + if (fmt[i] == 'e' && modified_between_p (XEXP (x, i), start, end)) + return 1; + + if (fmt[i] == 'E') + for (j = XVECLEN (x, i) - 1; j >= 0; j--) + if (modified_between_p (XVECEXP (x, i, j), start, end)) + return 1; + } + + return 0; +} + +/* Similar to reg_set_p, but check all registers in X. Return 0 only if none + of them are modified in INSN. Return 1 if X contains a MEM; this routine + does not perform any memory aliasing. */ + +int +modified_in_p (x, insn) + rtx x; + rtx insn; +{ + enum rtx_code code = GET_CODE (x); + char *fmt; + int i, j; + + switch (code) + { + case CONST_INT: + case CONST_DOUBLE: + case CONST: + case SYMBOL_REF: + case LABEL_REF: + return 0; + + case PC: + case CC0: return 1; + case MEM: + /* If the memory is not constant, assume it is modified. If it is + constant, we still have to check the address. */ + if (! RTX_UNCHANGING_P (x)) + return 1; + break; + + case REG: + return reg_set_p (x, insn); + } + + fmt = GET_RTX_FORMAT (code); + for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) + { + if (fmt[i] == 'e' && modified_in_p (XEXP (x, i), insn)) + return 1; + + if (fmt[i] == 'E') + for (j = XVECLEN (x, i) - 1; j >= 0; j--) + if (modified_in_p (XVECEXP (x, i, j), insn)) + return 1; + } + return 0; } @@ -618,6 +676,18 @@ refers_to_regno_p (regno, endregno, x, loc) { case REG: i = REGNO (x); + + /* If we modifying the stack, frame, or argument pointer, it will + clobber a virtual register. In fact, we could be more precise, + but it isn't worth it. */ + if ((i == STACK_POINTER_REGNUM +#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM + || i == ARG_POINTER_REGNUM +#endif + || i == FRAME_POINTER_REGNUM) + && regno >= FIRST_VIRTUAL_REGISTER && regno <= LAST_VIRTUAL_REGISTER) + return 1; + return (endregno > i && regno < i + (i < FIRST_PSEUDO_REGISTER ? HARD_REGNO_NREGS (i, GET_MODE (x)) |