diff options
author | Jeffrey A Law <law@cygnus.com> | 1997-09-22 00:49:32 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1997-09-21 18:49:32 -0600 |
commit | 2a1777af229bc5e9e738fd5bb8285ac0c1e24a7d (patch) | |
tree | 18e02cdfa9330785934ec403168033e5f85505e6 /gcc/rtlanal.c | |
parent | 37842442c3a0fc8e10d227cd7af112fdd4ef14e7 (diff) | |
download | gcc-2a1777af229bc5e9e738fd5bb8285ac0c1e24a7d.zip gcc-2a1777af229bc5e9e738fd5bb8285ac0c1e24a7d.tar.gz gcc-2a1777af229bc5e9e738fd5bb8285ac0c1e24a7d.tar.bz2 |
jump.c (jmp_uses_reg_or_mem): Deleted unused function.
* jump.c (jmp_uses_reg_or_mem): Deleted unused function.
(find_basic_blocks): Use computed_jump_p to determine if a
particular JUMP_INSN is a computed jump.
* reg-stack.c (find_blocks): Use computed_jump_p to determine
if a particular JUMP_INSN is a computed jump.
* rtlanal.c (jmp_uses_reg_or_mem): New function.
(computed_jump_p): Likewise.
* rtl.h (computed_jump_p): Declare.
* genattrtab.c (pc_rtx): Define and initialize.
* loop.c (loop_optimize): Always determine if the current
function has a computed jump.
(indirect_jump_in_function_p): Use computed_jump_p to determine
if a particular JUMP_INSN is a computed jump.
General (and haifa) cleanups.
From-SVN: r15615
Diffstat (limited to 'gcc/rtlanal.c')
-rw-r--r-- | gcc/rtlanal.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 3e6b4ae..069c5e8 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -25,6 +25,10 @@ Boston, MA 02111-1307, USA. */ void note_stores (); int reg_set_p (); + +/* Forward declarations */ +static int jmp_uses_reg_or_mem PROTO((rtx)); + /* Bit flags that specify the machine subtype we are compiling for. Bits are tested using macros TARGET_... defined in the tm.h file and set by `-m...' switches. Must be defined in rtlanal.c. */ @@ -1847,3 +1851,95 @@ replace_regs (x, reg_map, nregs, replace_dest) } return x; } + + +/* Return 1 if X, the SRC_SRC of SET of (pc) contain a REG or MEM that is + not in the constant pool and not in the condition of an IF_THEN_ELSE. */ + +static int +jmp_uses_reg_or_mem (x) + rtx x; +{ + enum rtx_code code = GET_CODE (x); + int i, j; + char *fmt; + + switch (code) + { + case CONST: + case LABEL_REF: + case PC: + return 0; + + case REG: + return 1; + + case MEM: + return ! (GET_CODE (XEXP (x, 0)) == SYMBOL_REF + && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0))); + + case IF_THEN_ELSE: + return (jmp_uses_reg_or_mem (XEXP (x, 1)) + || jmp_uses_reg_or_mem (XEXP (x, 2))); + + case PLUS: case MINUS: case MULT: + return (jmp_uses_reg_or_mem (XEXP (x, 0)) + || jmp_uses_reg_or_mem (XEXP (x, 1))); + } + + fmt = GET_RTX_FORMAT (code); + for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) + { + if (fmt[i] == 'e' + && jmp_uses_reg_or_mem (XEXP (x, i))) + return 1; + + if (fmt[i] == 'E') + for (j = 0; j < XVECLEN (x, i); j++) + if (jmp_uses_reg_or_mem (XVECEXP (x, i, j))) + return 1; + } + + return 0; +} + +/* Return nonzero if INSN is an indirect jump (aka computed jump). + + Tablejumps and casesi insns are not considered indirect jumps; + we can recognize them by a (use (lael_ref)). */ + +int +computed_jump_p (insn) + rtx insn; +{ + int i; + if (GET_CODE (insn) == JUMP_INSN) + { + rtx pat = PATTERN (insn); + int computed_jump = 0; + + if (GET_CODE (pat) == PARALLEL) + { + int len = XVECLEN (pat, 0); + int has_use_labelref = 0; + + for (i = len - 1; i >= 0; i--) + if (GET_CODE (XVECEXP (pat, 0, i)) == USE + && (GET_CODE (XEXP (XVECEXP (pat, 0, i), 0)) + == LABEL_REF)) + has_use_labelref = 1; + + if (! has_use_labelref) + for (i = len - 1; i >= 0; i--) + if (GET_CODE (XVECEXP (pat, 0, i)) == SET + && SET_DEST (XVECEXP (pat, 0, i)) == pc_rtx + && jmp_uses_reg_or_mem (SET_SRC (XVECEXP (pat, 0, 1)))) + return 1; + } + else if (GET_CODE (pat) == SET + && SET_DEST (pat) == pc_rtx + && jmp_uses_reg_or_mem (SET_SRC (pat))) + return 1; + } + return 0; +} |