Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#include "config.h"
#include "system.h"
-#include <setjmp.h>
#include "rtl.h"
#include "tm_p.h"
static void add_mem_for_addr PARAMS ((cselib_val *, cselib_val *,
rtx));
static cselib_val *cselib_lookup_mem PARAMS ((rtx, int));
-static rtx cselib_subst_to_values PARAMS ((rtx));
static void cselib_invalidate_regno PARAMS ((unsigned int,
enum machine_mode));
static int cselib_mem_conflict_p PARAMS ((rtx, rtx));
const char *fmt;
unsigned int hash = 0;
- /* repeat is used to turn tail-recursion into iteration. */
- repeat:
code = GET_CODE (x);
hash += (unsigned) code + (unsigned) GET_MODE (x);
if (fmt[i] == 'e')
{
rtx tem = XEXP (x, i);
- unsigned int tem_hash;
+ unsigned int tem_hash = hash_rtx (tem, 0, create);
- /* If we are about to do the last recursive call
- needed at this level, change it into iteration.
- This function is called enough to be worth it. */
- if (i == 0)
- {
- x = tem;
- goto repeat;
- }
-
- tem_hash = hash_rtx (tem, 0, create);
if (tem_hash == 0)
return 0;
cselib_val *addr_elt, *mem_elt;
rtx x;
{
- rtx new;
struct elt_loc_list *l;
/* Avoid duplicates. */
&& CSELIB_VAL_PTR (XEXP (l->loc, 0)) == addr_elt)
return;
- new = gen_rtx_MEM (GET_MODE (x), addr_elt->u.val_rtx);
- MEM_COPY_ATTRIBUTES (new, x);
-
addr_elt->addr_list = new_elt_list (addr_elt->addr_list, mem_elt);
- mem_elt->locs = new_elt_loc_list (mem_elt->locs, new);
+ mem_elt->locs
+ = new_elt_loc_list (mem_elt->locs,
+ replace_equiv_address_nv (x, addr_elt->u.val_rtx));
}
/* Subroutine of cselib_lookup. Return a value for X, which is a MEM rtx.
X isn't actually modified; if modifications are needed, new rtl is
allocated. However, the return value can share rtl with X. */
-static rtx
+rtx
cselib_subst_to_values (x)
rtx x;
{
case MEM:
e = cselib_lookup_mem (x, 0);
if (! e)
- abort ();
+ {
+ /* This happens for autoincrements. Assign a value that doesn't
+ match any other. */
+ e = new_cselib_val (++next_unknown_value, GET_MODE (x));
+ }
return e->u.val_rtx;
- /* CONST_DOUBLEs must be special-cased here so that we won't try to
- look up the CONST_DOUBLE_MEM inside. */
case CONST_DOUBLE:
case CONST_INT:
return x;
+ case POST_INC:
+ case PRE_INC:
+ case POST_DEC:
+ case PRE_DEC:
+ case POST_MODIFY:
+ case PRE_MODIFY:
+ e = new_cselib_val (++next_unknown_value, GET_MODE (x));
+ return e->u.val_rtx;
+
default:
break;
}
code = GET_CODE (val);
switch (code)
{
- /* Get rid of a few simple cases quickly. */
+ /* Get rid of a few simple cases quickly. */
case REG:
case PC:
case CC0:
int i;
struct set sets[MAX_SETS];
rtx body = PATTERN (insn);
+ rtx cond = 0;
body = PATTERN (insn);
+ if (GET_CODE (body) == COND_EXEC)
+ {
+ cond = COND_EXEC_TEST (body);
+ body = COND_EXEC_CODE (body);
+ }
+
/* Find all sets. */
if (GET_CODE (body) == SET)
{
/* We don't know how to record anything but REG or MEM. */
if (GET_CODE (dest) == REG || GET_CODE (dest) == MEM)
{
+ rtx src = sets[i].src;
+ if (cond)
+ src = gen_rtx_IF_THEN_ELSE (GET_MODE (src), cond, src, dest);
sets[i].src_elt = cselib_lookup (sets[i].src, GET_MODE (dest), 1);
if (GET_CODE (dest) == MEM)
sets[i].dest_addr_elt = cselib_lookup (XEXP (dest, 0), Pmode, 1);
/* Forget everything at a CODE_LABEL, a volatile asm, or a setjmp. */
if (GET_CODE (insn) == CODE_LABEL
- || (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
+ || (GET_CODE (insn) == CALL_INSN
+ && find_reg_note (insn, REG_SETJMP, NULL))
|| (GET_CODE (insn) == INSN
&& GET_CODE (PATTERN (insn)) == ASM_OPERANDS
&& MEM_VOLATILE_P (PATTERN (insn))))
if (call_used_regs[i])
cselib_invalidate_regno (i, VOIDmode);
- if (! CONST_CALL_P (insn))
+ if (! CONST_OR_PURE_CALL_P (insn))
cselib_invalidate_mem (callmem);
}