rtlanal.c revision 132718
118334Speter/* Analyze RTL for C-Compiler
290075Sobrien   Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3132718Skan   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
418334Speter
590075SobrienThis file is part of GCC.
618334Speter
790075SobrienGCC is free software; you can redistribute it and/or modify it under
890075Sobrienthe terms of the GNU General Public License as published by the Free
990075SobrienSoftware Foundation; either version 2, or (at your option) any later
1090075Sobrienversion.
1118334Speter
1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590075Sobrienfor more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
1990075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
2090075Sobrien02111-1307, USA.  */
2118334Speter
2218334Speter
2318334Speter#include "config.h"
2450397Sobrien#include "system.h"
25132718Skan#include "coretypes.h"
26132718Skan#include "tm.h"
2790075Sobrien#include "toplev.h"
2818334Speter#include "rtl.h"
2990075Sobrien#include "hard-reg-set.h"
30117395Skan#include "insn-config.h"
31117395Skan#include "recog.h"
3290075Sobrien#include "tm_p.h"
33117395Skan#include "flags.h"
34117395Skan#include "basic-block.h"
35117395Skan#include "real.h"
3618334Speter
3750397Sobrien/* Forward declarations */
38132718Skanstatic int global_reg_mentioned_p_1 (rtx *, void *);
39132718Skanstatic void set_of_1 (rtx, rtx, void *);
40132718Skanstatic void insn_dependent_p_1 (rtx, rtx, void *);
41132718Skanstatic int rtx_referenced_p_1 (rtx *, void *);
42132718Skanstatic int computed_jump_p_1 (rtx);
43132718Skanstatic void parms_set (rtx, rtx, void *);
44132718Skanstatic bool hoist_test_store (rtx, rtx, regset);
45132718Skanstatic void hoist_update_store (rtx, rtx *, rtx, rtx);
4650397Sobrien
4718334Speter/* Bit flags that specify the machine subtype we are compiling for.
4818334Speter   Bits are tested using macros TARGET_... defined in the tm.h file
4918334Speter   and set by `-m...' switches.  Must be defined in rtlanal.c.  */
5018334Speter
5118334Speterint target_flags;
5218334Speter
5318334Speter/* Return 1 if the value of X is unstable
5418334Speter   (would be different at a different point in the program).
5518334Speter   The frame pointer, arg pointer, etc. are considered stable
5618334Speter   (within one function) and so is anything marked `unchanging'.  */
5718334Speter
5818334Speterint
59132718Skanrtx_unstable_p (rtx x)
6018334Speter{
6190075Sobrien  RTX_CODE code = GET_CODE (x);
6290075Sobrien  int i;
6390075Sobrien  const char *fmt;
6418334Speter
6590075Sobrien  switch (code)
6690075Sobrien    {
6790075Sobrien    case MEM:
6890075Sobrien      return ! RTX_UNCHANGING_P (x) || rtx_unstable_p (XEXP (x, 0));
6918334Speter
7090075Sobrien    case QUEUED:
7190075Sobrien      return 1;
7218334Speter
7390075Sobrien    case ADDRESSOF:
7490075Sobrien    case CONST:
7590075Sobrien    case CONST_INT:
7690075Sobrien    case CONST_DOUBLE:
7796263Sobrien    case CONST_VECTOR:
7890075Sobrien    case SYMBOL_REF:
7990075Sobrien    case LABEL_REF:
8090075Sobrien      return 0;
8118334Speter
8290075Sobrien    case REG:
8390075Sobrien      /* As in rtx_varies_p, we have to use the actual rtx, not reg number.  */
8490075Sobrien      if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
8590075Sobrien	  /* The arg pointer varies if it is not a fixed register.  */
8690075Sobrien	  || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM])
8790075Sobrien	  || RTX_UNCHANGING_P (x))
8890075Sobrien	return 0;
8990075Sobrien#ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
9090075Sobrien      /* ??? When call-clobbered, the value is stable modulo the restore
9190075Sobrien	 that must happen after a call.  This currently screws up local-alloc
9290075Sobrien	 into believing that the restore is not needed.  */
9390075Sobrien      if (x == pic_offset_table_rtx)
9490075Sobrien	return 0;
9590075Sobrien#endif
9690075Sobrien      return 1;
9718334Speter
9890075Sobrien    case ASM_OPERANDS:
9990075Sobrien      if (MEM_VOLATILE_P (x))
10090075Sobrien	return 1;
10190075Sobrien
102132718Skan      /* Fall through.  */
10390075Sobrien
10490075Sobrien    default:
10590075Sobrien      break;
10690075Sobrien    }
10790075Sobrien
10818334Speter  fmt = GET_RTX_FORMAT (code);
10918334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
11018334Speter    if (fmt[i] == 'e')
11190075Sobrien      {
11290075Sobrien	if (rtx_unstable_p (XEXP (x, i)))
11390075Sobrien	  return 1;
11490075Sobrien      }
11590075Sobrien    else if (fmt[i] == 'E')
11690075Sobrien      {
11790075Sobrien	int j;
11890075Sobrien	for (j = 0; j < XVECLEN (x, i); j++)
11990075Sobrien	  if (rtx_unstable_p (XVECEXP (x, i, j)))
12090075Sobrien	    return 1;
12190075Sobrien      }
12290075Sobrien
12318334Speter  return 0;
12418334Speter}
12518334Speter
12618334Speter/* Return 1 if X has a value that can vary even between two
12718334Speter   executions of the program.  0 means X can be compared reliably
12818334Speter   against certain constants or near-constants.
12990075Sobrien   FOR_ALIAS is nonzero if we are called from alias analysis; if it is
13090075Sobrien   zero, we are slightly more conservative.
13118334Speter   The frame pointer and the arg pointer are considered constant.  */
13218334Speter
13318334Speterint
134132718Skanrtx_varies_p (rtx x, int for_alias)
13518334Speter{
136132718Skan  RTX_CODE code;
13790075Sobrien  int i;
13890075Sobrien  const char *fmt;
13918334Speter
140132718Skan  if (!x)
141132718Skan    return 0;
142132718Skan
143132718Skan  code = GET_CODE (x);
14418334Speter  switch (code)
14518334Speter    {
14618334Speter    case MEM:
14790075Sobrien      return ! RTX_UNCHANGING_P (x) || rtx_varies_p (XEXP (x, 0), for_alias);
14890075Sobrien
14918334Speter    case QUEUED:
15018334Speter      return 1;
15118334Speter
15218334Speter    case CONST:
15318334Speter    case CONST_INT:
15418334Speter    case CONST_DOUBLE:
15596263Sobrien    case CONST_VECTOR:
15618334Speter    case SYMBOL_REF:
15718334Speter    case LABEL_REF:
15818334Speter      return 0;
15918334Speter
160132718Skan    case ADDRESSOF:
161132718Skan      /* This will resolve to some offset from the frame pointer.  */
162132718Skan      return 0;
163132718Skan
16418334Speter    case REG:
16518334Speter      /* Note that we have to test for the actual rtx used for the frame
16618334Speter	 and arg pointers and not just the register number in case we have
16718334Speter	 eliminated the frame and/or arg pointer and are using it
16818334Speter	 for pseudos.  */
16990075Sobrien      if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
17090075Sobrien	  /* The arg pointer varies if it is not a fixed register.  */
17190075Sobrien	  || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM]))
17290075Sobrien	return 0;
17390075Sobrien      if (x == pic_offset_table_rtx
17490075Sobrien#ifdef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
17590075Sobrien	  /* ??? When call-clobbered, the value is stable modulo the restore
17690075Sobrien	     that must happen after a call.  This currently screws up
17790075Sobrien	     local-alloc into believing that the restore is not needed, so we
17890075Sobrien	     must return 0 only if we are called from alias analysis.  */
17990075Sobrien	  && for_alias
18090075Sobrien#endif
18190075Sobrien	  )
18290075Sobrien	return 0;
18390075Sobrien      return 1;
18418334Speter
18518334Speter    case LO_SUM:
18618334Speter      /* The operand 0 of a LO_SUM is considered constant
18790075Sobrien	 (in fact it is related specifically to operand 1)
18890075Sobrien	 during alias analysis.  */
18990075Sobrien      return (! for_alias && rtx_varies_p (XEXP (x, 0), for_alias))
19090075Sobrien	     || rtx_varies_p (XEXP (x, 1), for_alias);
191117395Skan
19290075Sobrien    case ASM_OPERANDS:
19390075Sobrien      if (MEM_VOLATILE_P (x))
19490075Sobrien	return 1;
19590075Sobrien
196132718Skan      /* Fall through.  */
19790075Sobrien
19850397Sobrien    default:
19950397Sobrien      break;
20018334Speter    }
20118334Speter
20218334Speter  fmt = GET_RTX_FORMAT (code);
20318334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
20418334Speter    if (fmt[i] == 'e')
20590075Sobrien      {
20690075Sobrien	if (rtx_varies_p (XEXP (x, i), for_alias))
20790075Sobrien	  return 1;
20890075Sobrien      }
20990075Sobrien    else if (fmt[i] == 'E')
21090075Sobrien      {
21190075Sobrien	int j;
21290075Sobrien	for (j = 0; j < XVECLEN (x, i); j++)
21390075Sobrien	  if (rtx_varies_p (XVECEXP (x, i, j), for_alias))
21490075Sobrien	    return 1;
21590075Sobrien      }
21690075Sobrien
21718334Speter  return 0;
21818334Speter}
21918334Speter
22018334Speter/* Return 0 if the use of X as an address in a MEM can cause a trap.  */
22118334Speter
22290075Sobrienint
223132718Skanrtx_addr_can_trap_p (rtx x)
22418334Speter{
22590075Sobrien  enum rtx_code code = GET_CODE (x);
22618334Speter
22718334Speter  switch (code)
22818334Speter    {
22918334Speter    case SYMBOL_REF:
23090075Sobrien      return SYMBOL_REF_WEAK (x);
23190075Sobrien
23218334Speter    case LABEL_REF:
23318334Speter      return 0;
23418334Speter
235132718Skan    case ADDRESSOF:
236132718Skan      /* This will resolve to some offset from the frame pointer.  */
237132718Skan      return 0;
238132718Skan
23918334Speter    case REG:
24018334Speter      /* As in rtx_varies_p, we have to use the actual rtx, not reg number.  */
24190075Sobrien      if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
24290075Sobrien	  || x == stack_pointer_rtx
24390075Sobrien	  /* The arg pointer varies if it is not a fixed register.  */
24490075Sobrien	  || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM]))
24590075Sobrien	return 0;
24690075Sobrien      /* All of the virtual frame registers are stack references.  */
24790075Sobrien      if (REGNO (x) >= FIRST_VIRTUAL_REGISTER
24890075Sobrien	  && REGNO (x) <= LAST_VIRTUAL_REGISTER)
24990075Sobrien	return 0;
25090075Sobrien      return 1;
25118334Speter
25218334Speter    case CONST:
25318334Speter      return rtx_addr_can_trap_p (XEXP (x, 0));
25418334Speter
25518334Speter    case PLUS:
25618334Speter      /* An address is assumed not to trap if it is an address that can't
25790075Sobrien	 trap plus a constant integer or it is the pic register plus a
25890075Sobrien	 constant.  */
25990075Sobrien      return ! ((! rtx_addr_can_trap_p (XEXP (x, 0))
26090075Sobrien		 && GET_CODE (XEXP (x, 1)) == CONST_INT)
26190075Sobrien		|| (XEXP (x, 0) == pic_offset_table_rtx
26290075Sobrien		    && CONSTANT_P (XEXP (x, 1))));
26318334Speter
26418334Speter    case LO_SUM:
26590075Sobrien    case PRE_MODIFY:
26618334Speter      return rtx_addr_can_trap_p (XEXP (x, 1));
26790075Sobrien
26890075Sobrien    case PRE_DEC:
26990075Sobrien    case PRE_INC:
27090075Sobrien    case POST_DEC:
27190075Sobrien    case POST_INC:
27290075Sobrien    case POST_MODIFY:
27390075Sobrien      return rtx_addr_can_trap_p (XEXP (x, 0));
27490075Sobrien
27550397Sobrien    default:
27650397Sobrien      break;
27718334Speter    }
27818334Speter
27918334Speter  /* If it isn't one of the case above, it can cause a trap.  */
28018334Speter  return 1;
28118334Speter}
28218334Speter
283132718Skan/* Return true if X is an address that is known to not be zero.  */
284132718Skan
285132718Skanbool
286132718Skannonzero_address_p (rtx x)
287132718Skan{
288132718Skan  enum rtx_code code = GET_CODE (x);
289132718Skan
290132718Skan  switch (code)
291132718Skan    {
292132718Skan    case SYMBOL_REF:
293132718Skan      return !SYMBOL_REF_WEAK (x);
294132718Skan
295132718Skan    case LABEL_REF:
296132718Skan      return true;
297132718Skan
298132718Skan    case ADDRESSOF:
299132718Skan      /* This will resolve to some offset from the frame pointer.  */
300132718Skan      return true;
301132718Skan
302132718Skan    case REG:
303132718Skan      /* As in rtx_varies_p, we have to use the actual rtx, not reg number.  */
304132718Skan      if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
305132718Skan	  || x == stack_pointer_rtx
306132718Skan	  || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM]))
307132718Skan	return true;
308132718Skan      /* All of the virtual frame registers are stack references.  */
309132718Skan      if (REGNO (x) >= FIRST_VIRTUAL_REGISTER
310132718Skan	  && REGNO (x) <= LAST_VIRTUAL_REGISTER)
311132718Skan	return true;
312132718Skan      return false;
313132718Skan
314132718Skan    case CONST:
315132718Skan      return nonzero_address_p (XEXP (x, 0));
316132718Skan
317132718Skan    case PLUS:
318132718Skan      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
319132718Skan	{
320132718Skan	  /* Pointers aren't allowed to wrap.  If we've got a register
321132718Skan	     that is known to be a pointer, and a positive offset, then
322132718Skan	     the composite can't be zero.  */
323132718Skan	  if (INTVAL (XEXP (x, 1)) > 0
324132718Skan	      && REG_P (XEXP (x, 0))
325132718Skan	      && REG_POINTER (XEXP (x, 0)))
326132718Skan	    return true;
327132718Skan
328132718Skan	  return nonzero_address_p (XEXP (x, 0));
329132718Skan	}
330132718Skan      /* Handle PIC references.  */
331132718Skan      else if (XEXP (x, 0) == pic_offset_table_rtx
332132718Skan	       && CONSTANT_P (XEXP (x, 1)))
333132718Skan	return true;
334132718Skan      return false;
335132718Skan
336132718Skan    case PRE_MODIFY:
337132718Skan      /* Similar to the above; allow positive offsets.  Further, since
338132718Skan	 auto-inc is only allowed in memories, the register must be a
339132718Skan	 pointer.  */
340132718Skan      if (GET_CODE (XEXP (x, 1)) == CONST_INT
341132718Skan	  && INTVAL (XEXP (x, 1)) > 0)
342132718Skan	return true;
343132718Skan      return nonzero_address_p (XEXP (x, 0));
344132718Skan
345132718Skan    case PRE_INC:
346132718Skan      /* Similarly.  Further, the offset is always positive.  */
347132718Skan      return true;
348132718Skan
349132718Skan    case PRE_DEC:
350132718Skan    case POST_DEC:
351132718Skan    case POST_INC:
352132718Skan    case POST_MODIFY:
353132718Skan      return nonzero_address_p (XEXP (x, 0));
354132718Skan
355132718Skan    case LO_SUM:
356132718Skan      return nonzero_address_p (XEXP (x, 1));
357132718Skan
358132718Skan    default:
359132718Skan      break;
360132718Skan    }
361132718Skan
362132718Skan  /* If it isn't one of the case above, might be zero.  */
363132718Skan  return false;
364132718Skan}
365132718Skan
366117395Skan/* Return 1 if X refers to a memory location whose address
36718334Speter   cannot be compared reliably with constant addresses,
368117395Skan   or if X refers to a BLKmode memory object.
36990075Sobrien   FOR_ALIAS is nonzero if we are called from alias analysis; if it is
37090075Sobrien   zero, we are slightly more conservative.  */
37118334Speter
37218334Speterint
373132718Skanrtx_addr_varies_p (rtx x, int for_alias)
37418334Speter{
37590075Sobrien  enum rtx_code code;
37690075Sobrien  int i;
37790075Sobrien  const char *fmt;
37818334Speter
37918334Speter  if (x == 0)
38018334Speter    return 0;
38118334Speter
38218334Speter  code = GET_CODE (x);
38318334Speter  if (code == MEM)
38490075Sobrien    return GET_MODE (x) == BLKmode || rtx_varies_p (XEXP (x, 0), for_alias);
38518334Speter
38618334Speter  fmt = GET_RTX_FORMAT (code);
38718334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
38818334Speter    if (fmt[i] == 'e')
38950397Sobrien      {
39090075Sobrien	if (rtx_addr_varies_p (XEXP (x, i), for_alias))
39150397Sobrien	  return 1;
39250397Sobrien      }
39350397Sobrien    else if (fmt[i] == 'E')
39450397Sobrien      {
39550397Sobrien	int j;
39650397Sobrien	for (j = 0; j < XVECLEN (x, i); j++)
39790075Sobrien	  if (rtx_addr_varies_p (XVECEXP (x, i, j), for_alias))
39850397Sobrien	    return 1;
39950397Sobrien      }
40018334Speter  return 0;
40118334Speter}
40218334Speter
40318334Speter/* Return the value of the integer term in X, if one is apparent;
40418334Speter   otherwise return 0.
40518334Speter   Only obvious integer terms are detected.
40690075Sobrien   This is used in cse.c with the `related_value' field.  */
40718334Speter
40818334SpeterHOST_WIDE_INT
409132718Skanget_integer_term (rtx x)
41018334Speter{
41118334Speter  if (GET_CODE (x) == CONST)
41218334Speter    x = XEXP (x, 0);
41318334Speter
41418334Speter  if (GET_CODE (x) == MINUS
41518334Speter      && GET_CODE (XEXP (x, 1)) == CONST_INT)
41618334Speter    return - INTVAL (XEXP (x, 1));
41718334Speter  if (GET_CODE (x) == PLUS
41818334Speter      && GET_CODE (XEXP (x, 1)) == CONST_INT)
41918334Speter    return INTVAL (XEXP (x, 1));
42018334Speter  return 0;
42118334Speter}
42218334Speter
42318334Speter/* If X is a constant, return the value sans apparent integer term;
42418334Speter   otherwise return 0.
42518334Speter   Only obvious integer terms are detected.  */
42618334Speter
42718334Speterrtx
428132718Skanget_related_value (rtx x)
42918334Speter{
43018334Speter  if (GET_CODE (x) != CONST)
43118334Speter    return 0;
43218334Speter  x = XEXP (x, 0);
43318334Speter  if (GET_CODE (x) == PLUS
43418334Speter      && GET_CODE (XEXP (x, 1)) == CONST_INT)
43518334Speter    return XEXP (x, 0);
43618334Speter  else if (GET_CODE (x) == MINUS
43718334Speter	   && GET_CODE (XEXP (x, 1)) == CONST_INT)
43818334Speter    return XEXP (x, 0);
43918334Speter  return 0;
44018334Speter}
44118334Speter
44290075Sobrien/* Given a tablejump insn INSN, return the RTL expression for the offset
44390075Sobrien   into the jump table.  If the offset cannot be determined, then return
44490075Sobrien   NULL_RTX.
44590075Sobrien
446117395Skan   If EARLIEST is nonzero, it is a pointer to a place where the earliest
44790075Sobrien   insn used in locating the offset was found.  */
44890075Sobrien
44990075Sobrienrtx
450132718Skanget_jump_table_offset (rtx insn, rtx *earliest)
45190075Sobrien{
45290075Sobrien  rtx label;
45390075Sobrien  rtx table;
45490075Sobrien  rtx set;
45590075Sobrien  rtx old_insn;
45690075Sobrien  rtx x;
45790075Sobrien  rtx old_x;
45890075Sobrien  rtx y;
45990075Sobrien  rtx old_y;
46090075Sobrien  int i;
46190075Sobrien
462132718Skan  if (!tablejump_p (insn, &label, &table) || !(set = single_set (insn)))
46390075Sobrien    return NULL_RTX;
46490075Sobrien
46590075Sobrien  x = SET_SRC (set);
46690075Sobrien
46790075Sobrien  /* Some targets (eg, ARM) emit a tablejump that also
46890075Sobrien     contains the out-of-range target.  */
46990075Sobrien  if (GET_CODE (x) == IF_THEN_ELSE
47090075Sobrien      && GET_CODE (XEXP (x, 2)) == LABEL_REF)
47190075Sobrien    x = XEXP (x, 1);
47290075Sobrien
47390075Sobrien  /* Search backwards and locate the expression stored in X.  */
47490075Sobrien  for (old_x = NULL_RTX; GET_CODE (x) == REG && x != old_x;
47590075Sobrien       old_x = x, x = find_last_value (x, &insn, NULL_RTX, 0))
47690075Sobrien    ;
47790075Sobrien
47890075Sobrien  /* If X is an expression using a relative address then strip
47990075Sobrien     off the addition / subtraction of PC, PIC_OFFSET_TABLE_REGNUM,
48090075Sobrien     or the jump table label.  */
48190075Sobrien  if (GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC
48290075Sobrien      && (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS))
48390075Sobrien    {
48490075Sobrien      for (i = 0; i < 2; i++)
48590075Sobrien	{
48690075Sobrien	  old_insn = insn;
48790075Sobrien	  y = XEXP (x, i);
48890075Sobrien
48990075Sobrien	  if (y == pc_rtx || y == pic_offset_table_rtx)
49090075Sobrien	    break;
49190075Sobrien
49290075Sobrien	  for (old_y = NULL_RTX; GET_CODE (y) == REG && y != old_y;
49390075Sobrien	       old_y = y, y = find_last_value (y, &old_insn, NULL_RTX, 0))
49490075Sobrien	    ;
49590075Sobrien
49690075Sobrien	  if ((GET_CODE (y) == LABEL_REF && XEXP (y, 0) == label))
49790075Sobrien	    break;
49890075Sobrien	}
49990075Sobrien
50090075Sobrien      if (i >= 2)
50190075Sobrien	return NULL_RTX;
50290075Sobrien
50390075Sobrien      x = XEXP (x, 1 - i);
50490075Sobrien
50590075Sobrien      for (old_x = NULL_RTX; GET_CODE (x) == REG && x != old_x;
50690075Sobrien	   old_x = x, x = find_last_value (x, &insn, NULL_RTX, 0))
50790075Sobrien	;
50890075Sobrien    }
50990075Sobrien
51090075Sobrien  /* Strip off any sign or zero extension.  */
51190075Sobrien  if (GET_CODE (x) == SIGN_EXTEND || GET_CODE (x) == ZERO_EXTEND)
51290075Sobrien    {
51390075Sobrien      x = XEXP (x, 0);
51490075Sobrien
51590075Sobrien      for (old_x = NULL_RTX; GET_CODE (x) == REG && x != old_x;
51690075Sobrien	   old_x = x, x = find_last_value (x, &insn, NULL_RTX, 0))
51790075Sobrien	;
51890075Sobrien    }
51990075Sobrien
52090075Sobrien  /* If X isn't a MEM then this isn't a tablejump we understand.  */
52190075Sobrien  if (GET_CODE (x) != MEM)
52290075Sobrien    return NULL_RTX;
52390075Sobrien
52490075Sobrien  /* Strip off the MEM.  */
52590075Sobrien  x = XEXP (x, 0);
52690075Sobrien
52790075Sobrien  for (old_x = NULL_RTX; GET_CODE (x) == REG && x != old_x;
52890075Sobrien       old_x = x, x = find_last_value (x, &insn, NULL_RTX, 0))
52990075Sobrien    ;
53090075Sobrien
53190075Sobrien  /* If X isn't a PLUS than this isn't a tablejump we understand.  */
53290075Sobrien  if (GET_CODE (x) != PLUS)
53390075Sobrien    return NULL_RTX;
53490075Sobrien
53590075Sobrien  /* At this point we should have an expression representing the jump table
53690075Sobrien     plus an offset.  Examine each operand in order to determine which one
53790075Sobrien     represents the jump table.  Knowing that tells us that the other operand
53890075Sobrien     must represent the offset.  */
53990075Sobrien  for (i = 0; i < 2; i++)
54090075Sobrien    {
54190075Sobrien      old_insn = insn;
54290075Sobrien      y = XEXP (x, i);
54390075Sobrien
54490075Sobrien      for (old_y = NULL_RTX; GET_CODE (y) == REG && y != old_y;
54590075Sobrien	   old_y = y, y = find_last_value (y, &old_insn, NULL_RTX, 0))
54690075Sobrien	;
54790075Sobrien
54890075Sobrien      if ((GET_CODE (y) == CONST || GET_CODE (y) == LABEL_REF)
54990075Sobrien	  && reg_mentioned_p (label, y))
55090075Sobrien	break;
55190075Sobrien    }
55290075Sobrien
55390075Sobrien  if (i >= 2)
55490075Sobrien    return NULL_RTX;
55590075Sobrien
55690075Sobrien  x = XEXP (x, 1 - i);
55790075Sobrien
55890075Sobrien  /* Strip off the addition / subtraction of PIC_OFFSET_TABLE_REGNUM.  */
55990075Sobrien  if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS)
56090075Sobrien    for (i = 0; i < 2; i++)
56190075Sobrien      if (XEXP (x, i) == pic_offset_table_rtx)
56290075Sobrien	{
56390075Sobrien	  x = XEXP (x, 1 - i);
56490075Sobrien	  break;
56590075Sobrien	}
56690075Sobrien
56790075Sobrien  if (earliest)
56890075Sobrien    *earliest = insn;
56990075Sobrien
57090075Sobrien  /* Return the RTL expression representing the offset.  */
57190075Sobrien  return x;
57290075Sobrien}
57390075Sobrien
574117395Skan/* A subroutine of global_reg_mentioned_p, returns 1 if *LOC mentions
575117395Skan   a global register.  */
576117395Skan
577117395Skanstatic int
578132718Skanglobal_reg_mentioned_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
579117395Skan{
580117395Skan  int regno;
581117395Skan  rtx x = *loc;
582117395Skan
583117395Skan  if (! x)
584117395Skan    return 0;
585117395Skan
586117395Skan  switch (GET_CODE (x))
587117395Skan    {
588117395Skan    case SUBREG:
589117395Skan      if (GET_CODE (SUBREG_REG (x)) == REG)
590117395Skan	{
591117395Skan	  if (REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER
592117395Skan	      && global_regs[subreg_regno (x)])
593117395Skan	    return 1;
594117395Skan	  return 0;
595117395Skan	}
596117395Skan      break;
597117395Skan
598117395Skan    case REG:
599117395Skan      regno = REGNO (x);
600117395Skan      if (regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
601117395Skan	return 1;
602117395Skan      return 0;
603117395Skan
604117395Skan    case SCRATCH:
605117395Skan    case PC:
606117395Skan    case CC0:
607117395Skan    case CONST_INT:
608117395Skan    case CONST_DOUBLE:
609117395Skan    case CONST:
610117395Skan    case LABEL_REF:
611117395Skan      return 0;
612117395Skan
613117395Skan    case CALL:
614117395Skan      /* A non-constant call might use a global register.  */
615117395Skan      return 1;
616117395Skan
617117395Skan    default:
618117395Skan      break;
619117395Skan    }
620117395Skan
621117395Skan  return 0;
622117395Skan}
623117395Skan
624117395Skan/* Returns nonzero if X mentions a global register.  */
625117395Skan
626117395Skanint
627132718Skanglobal_reg_mentioned_p (rtx x)
628117395Skan{
629117395Skan  if (INSN_P (x))
630117395Skan    {
631117395Skan      if (GET_CODE (x) == CALL_INSN)
632117395Skan	{
633117395Skan	  if (! CONST_OR_PURE_CALL_P (x))
634117395Skan	    return 1;
635117395Skan	  x = CALL_INSN_FUNCTION_USAGE (x);
636117395Skan	  if (x == 0)
637117395Skan	    return 0;
638117395Skan	}
639117395Skan      else
640117395Skan	x = PATTERN (x);
641117395Skan    }
642117395Skan
643117395Skan  return for_each_rtx (&x, global_reg_mentioned_p_1, NULL);
644117395Skan}
645117395Skan
64690075Sobrien/* Return the number of places FIND appears within X.  If COUNT_DEST is
64790075Sobrien   zero, we do not count occurrences inside the destination of a SET.  */
64890075Sobrien
64990075Sobrienint
650132718Skancount_occurrences (rtx x, rtx find, int count_dest)
65190075Sobrien{
65290075Sobrien  int i, j;
65390075Sobrien  enum rtx_code code;
65490075Sobrien  const char *format_ptr;
65590075Sobrien  int count;
65690075Sobrien
65790075Sobrien  if (x == find)
65890075Sobrien    return 1;
65990075Sobrien
66090075Sobrien  code = GET_CODE (x);
66190075Sobrien
66290075Sobrien  switch (code)
66390075Sobrien    {
66490075Sobrien    case REG:
66590075Sobrien    case CONST_INT:
66690075Sobrien    case CONST_DOUBLE:
66796263Sobrien    case CONST_VECTOR:
66890075Sobrien    case SYMBOL_REF:
66990075Sobrien    case CODE_LABEL:
67090075Sobrien    case PC:
67190075Sobrien    case CC0:
67290075Sobrien      return 0;
67390075Sobrien
67490075Sobrien    case MEM:
67590075Sobrien      if (GET_CODE (find) == MEM && rtx_equal_p (x, find))
67690075Sobrien	return 1;
67790075Sobrien      break;
67890075Sobrien
67990075Sobrien    case SET:
68090075Sobrien      if (SET_DEST (x) == find && ! count_dest)
68190075Sobrien	return count_occurrences (SET_SRC (x), find, count_dest);
68290075Sobrien      break;
68390075Sobrien
68490075Sobrien    default:
68590075Sobrien      break;
68690075Sobrien    }
68790075Sobrien
68890075Sobrien  format_ptr = GET_RTX_FORMAT (code);
68990075Sobrien  count = 0;
69090075Sobrien
69190075Sobrien  for (i = 0; i < GET_RTX_LENGTH (code); i++)
69290075Sobrien    {
69390075Sobrien      switch (*format_ptr++)
69490075Sobrien	{
69590075Sobrien	case 'e':
69690075Sobrien	  count += count_occurrences (XEXP (x, i), find, count_dest);
69790075Sobrien	  break;
69890075Sobrien
69990075Sobrien	case 'E':
70090075Sobrien	  for (j = 0; j < XVECLEN (x, i); j++)
70190075Sobrien	    count += count_occurrences (XVECEXP (x, i, j), find, count_dest);
70290075Sobrien	  break;
70390075Sobrien	}
70490075Sobrien    }
70590075Sobrien  return count;
70690075Sobrien}
70790075Sobrien
70818334Speter/* Nonzero if register REG appears somewhere within IN.
70918334Speter   Also works if REG is not a register; in this case it checks
71018334Speter   for a subexpression of IN that is Lisp "equal" to REG.  */
71118334Speter
71218334Speterint
713132718Skanreg_mentioned_p (rtx reg, rtx in)
71418334Speter{
71590075Sobrien  const char *fmt;
71690075Sobrien  int i;
71790075Sobrien  enum rtx_code code;
71818334Speter
71918334Speter  if (in == 0)
72018334Speter    return 0;
72118334Speter
72218334Speter  if (reg == in)
72318334Speter    return 1;
72418334Speter
72518334Speter  if (GET_CODE (in) == LABEL_REF)
72618334Speter    return reg == XEXP (in, 0);
72718334Speter
72818334Speter  code = GET_CODE (in);
72918334Speter
73018334Speter  switch (code)
73118334Speter    {
73218334Speter      /* Compare registers by number.  */
73318334Speter    case REG:
73418334Speter      return GET_CODE (reg) == REG && REGNO (in) == REGNO (reg);
73518334Speter
73618334Speter      /* These codes have no constituent expressions
73718334Speter	 and are unique.  */
73818334Speter    case SCRATCH:
73918334Speter    case CC0:
74018334Speter    case PC:
74118334Speter      return 0;
74218334Speter
74318334Speter    case CONST_INT:
74496263Sobrien    case CONST_VECTOR:
74518334Speter    case CONST_DOUBLE:
74618334Speter      /* These are kept unique for a given value.  */
74718334Speter      return 0;
748117395Skan
74950397Sobrien    default:
75050397Sobrien      break;
75118334Speter    }
75218334Speter
75318334Speter  if (GET_CODE (reg) == code && rtx_equal_p (reg, in))
75418334Speter    return 1;
75518334Speter
75618334Speter  fmt = GET_RTX_FORMAT (code);
75718334Speter
75818334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
75918334Speter    {
76018334Speter      if (fmt[i] == 'E')
76118334Speter	{
76290075Sobrien	  int j;
76318334Speter	  for (j = XVECLEN (in, i) - 1; j >= 0; j--)
76418334Speter	    if (reg_mentioned_p (reg, XVECEXP (in, i, j)))
76518334Speter	      return 1;
76618334Speter	}
76718334Speter      else if (fmt[i] == 'e'
76818334Speter	       && reg_mentioned_p (reg, XEXP (in, i)))
76918334Speter	return 1;
77018334Speter    }
77118334Speter  return 0;
77218334Speter}
77318334Speter
77418334Speter/* Return 1 if in between BEG and END, exclusive of BEG and END, there is
77518334Speter   no CODE_LABEL insn.  */
77618334Speter
77718334Speterint
778132718Skanno_labels_between_p (rtx beg, rtx end)
77918334Speter{
78090075Sobrien  rtx p;
78190075Sobrien  if (beg == end)
78290075Sobrien    return 0;
78318334Speter  for (p = NEXT_INSN (beg); p != end; p = NEXT_INSN (p))
78418334Speter    if (GET_CODE (p) == CODE_LABEL)
78518334Speter      return 0;
78618334Speter  return 1;
78718334Speter}
78818334Speter
78952284Sobrien/* Return 1 if in between BEG and END, exclusive of BEG and END, there is
79052284Sobrien   no JUMP_INSN insn.  */
79152284Sobrien
79252284Sobrienint
793132718Skanno_jumps_between_p (rtx beg, rtx end)
79452284Sobrien{
79590075Sobrien  rtx p;
79652284Sobrien  for (p = NEXT_INSN (beg); p != end; p = NEXT_INSN (p))
79752284Sobrien    if (GET_CODE (p) == JUMP_INSN)
79852284Sobrien      return 0;
79952284Sobrien  return 1;
80052284Sobrien}
80152284Sobrien
80218334Speter/* Nonzero if register REG is used in an insn between
80318334Speter   FROM_INSN and TO_INSN (exclusive of those two).  */
80418334Speter
80518334Speterint
806132718Skanreg_used_between_p (rtx reg, rtx from_insn, rtx to_insn)
80718334Speter{
80890075Sobrien  rtx insn;
80918334Speter
81018334Speter  if (from_insn == to_insn)
81118334Speter    return 0;
81218334Speter
81318334Speter  for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
81490075Sobrien    if (INSN_P (insn)
81518334Speter	&& (reg_overlap_mentioned_p (reg, PATTERN (insn))
81618334Speter	   || (GET_CODE (insn) == CALL_INSN
81718334Speter	      && (find_reg_fusage (insn, USE, reg)
81818334Speter		  || find_reg_fusage (insn, CLOBBER, reg)))))
81918334Speter      return 1;
82018334Speter  return 0;
82118334Speter}
82218334Speter
82318334Speter/* Nonzero if the old value of X, a register, is referenced in BODY.  If X
82418334Speter   is entirely replaced by a new value and the only use is as a SET_DEST,
82518334Speter   we do not consider it a reference.  */
82618334Speter
82718334Speterint
828132718Skanreg_referenced_p (rtx x, rtx body)
82918334Speter{
83018334Speter  int i;
83118334Speter
83218334Speter  switch (GET_CODE (body))
83318334Speter    {
83418334Speter    case SET:
83518334Speter      if (reg_overlap_mentioned_p (x, SET_SRC (body)))
83618334Speter	return 1;
83718334Speter
83818334Speter      /* If the destination is anything other than CC0, PC, a REG or a SUBREG
83918334Speter	 of a REG that occupies all of the REG, the insn references X if
84018334Speter	 it is mentioned in the destination.  */
84118334Speter      if (GET_CODE (SET_DEST (body)) != CC0
84218334Speter	  && GET_CODE (SET_DEST (body)) != PC
84318334Speter	  && GET_CODE (SET_DEST (body)) != REG
84418334Speter	  && ! (GET_CODE (SET_DEST (body)) == SUBREG
84518334Speter		&& GET_CODE (SUBREG_REG (SET_DEST (body))) == REG
84618334Speter		&& (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (body))))
84718334Speter		      + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
84818334Speter		    == ((GET_MODE_SIZE (GET_MODE (SET_DEST (body)))
84918334Speter			 + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
85018334Speter	  && reg_overlap_mentioned_p (x, SET_DEST (body)))
85118334Speter	return 1;
85250397Sobrien      return 0;
85318334Speter
85418334Speter    case ASM_OPERANDS:
85518334Speter      for (i = ASM_OPERANDS_INPUT_LENGTH (body) - 1; i >= 0; i--)
85618334Speter	if (reg_overlap_mentioned_p (x, ASM_OPERANDS_INPUT (body, i)))
85718334Speter	  return 1;
85850397Sobrien      return 0;
85918334Speter
86018334Speter    case CALL:
86118334Speter    case USE:
86290075Sobrien    case IF_THEN_ELSE:
86318334Speter      return reg_overlap_mentioned_p (x, body);
86418334Speter
86518334Speter    case TRAP_IF:
86618334Speter      return reg_overlap_mentioned_p (x, TRAP_CONDITION (body));
86718334Speter
86890075Sobrien    case PREFETCH:
86990075Sobrien      return reg_overlap_mentioned_p (x, XEXP (body, 0));
87090075Sobrien
87118334Speter    case UNSPEC:
87218334Speter    case UNSPEC_VOLATILE:
87390075Sobrien      for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
87490075Sobrien	if (reg_overlap_mentioned_p (x, XVECEXP (body, 0, i)))
87590075Sobrien	  return 1;
87690075Sobrien      return 0;
87790075Sobrien
87818334Speter    case PARALLEL:
87918334Speter      for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
88018334Speter	if (reg_referenced_p (x, XVECEXP (body, 0, i)))
88118334Speter	  return 1;
88250397Sobrien      return 0;
883117395Skan
88490075Sobrien    case CLOBBER:
88590075Sobrien      if (GET_CODE (XEXP (body, 0)) == MEM)
88690075Sobrien	if (reg_overlap_mentioned_p (x, XEXP (XEXP (body, 0), 0)))
88790075Sobrien	  return 1;
88890075Sobrien      return 0;
88990075Sobrien
89090075Sobrien    case COND_EXEC:
89190075Sobrien      if (reg_overlap_mentioned_p (x, COND_EXEC_TEST (body)))
89290075Sobrien	return 1;
89390075Sobrien      return reg_referenced_p (x, COND_EXEC_CODE (body));
89490075Sobrien
89550397Sobrien    default:
89650397Sobrien      return 0;
89718334Speter    }
89818334Speter}
89918334Speter
90018334Speter/* Nonzero if register REG is referenced in an insn between
90118334Speter   FROM_INSN and TO_INSN (exclusive of those two).  Sets of REG do
90250397Sobrien   not count.  */
90318334Speter
90418334Speterint
905132718Skanreg_referenced_between_p (rtx reg, rtx from_insn, rtx to_insn)
90618334Speter{
90790075Sobrien  rtx insn;
90818334Speter
90918334Speter  if (from_insn == to_insn)
91018334Speter    return 0;
91118334Speter
91218334Speter  for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
91390075Sobrien    if (INSN_P (insn)
91418334Speter	&& (reg_referenced_p (reg, PATTERN (insn))
91518334Speter	   || (GET_CODE (insn) == CALL_INSN
91618334Speter	      && find_reg_fusage (insn, USE, reg))))
91718334Speter      return 1;
91818334Speter  return 0;
91918334Speter}
92018334Speter
92118334Speter/* Nonzero if register REG is set or clobbered in an insn between
92218334Speter   FROM_INSN and TO_INSN (exclusive of those two).  */
92318334Speter
92418334Speterint
925132718Skanreg_set_between_p (rtx reg, rtx from_insn, rtx to_insn)
92618334Speter{
92790075Sobrien  rtx insn;
92818334Speter
92918334Speter  if (from_insn == to_insn)
93018334Speter    return 0;
93118334Speter
93218334Speter  for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
93390075Sobrien    if (INSN_P (insn) && reg_set_p (reg, insn))
93418334Speter      return 1;
93518334Speter  return 0;
93618334Speter}
93718334Speter
93818334Speter/* Internals of reg_set_between_p.  */
93918334Speterint
940132718Skanreg_set_p (rtx reg, rtx insn)
94118334Speter{
94218334Speter  /* We can be passed an insn or part of one.  If we are passed an insn,
94318334Speter     check if a side-effect of the insn clobbers REG.  */
944132718Skan  if (INSN_P (insn)
945132718Skan      && (FIND_REG_INC_NOTE (insn, reg)
94618334Speter	  || (GET_CODE (insn) == CALL_INSN
94718334Speter	      /* We'd like to test call_used_regs here, but rtlanal.c can't
94818334Speter		 reference that variable due to its use in genattrtab.  So
94918334Speter		 we'll just be more conservative.
95018334Speter
95118334Speter		 ??? Unless we could ensure that the CALL_INSN_FUNCTION_USAGE
95218334Speter		 information holds all clobbered registers.  */
95318334Speter	      && ((GET_CODE (reg) == REG
95418334Speter		   && REGNO (reg) < FIRST_PSEUDO_REGISTER)
95518334Speter		  || GET_CODE (reg) == MEM
956132718Skan		  || find_reg_fusage (insn, CLOBBER, reg)))))
957132718Skan    return 1;
95818334Speter
95990075Sobrien  return set_of (reg, insn) != NULL_RTX;
96018334Speter}
96118334Speter
96218334Speter/* Similar to reg_set_between_p, but check all registers in X.  Return 0
96352284Sobrien   only if none of them are modified between START and END.  Do not
96452284Sobrien   consider non-registers one way or the other.  */
96552284Sobrien
96652284Sobrienint
967132718Skanregs_set_between_p (rtx x, rtx start, rtx end)
96852284Sobrien{
96952284Sobrien  enum rtx_code code = GET_CODE (x);
97090075Sobrien  const char *fmt;
97152284Sobrien  int i, j;
97252284Sobrien
97352284Sobrien  switch (code)
97452284Sobrien    {
97552284Sobrien    case CONST_INT:
97652284Sobrien    case CONST_DOUBLE:
97796263Sobrien    case CONST_VECTOR:
97852284Sobrien    case CONST:
97952284Sobrien    case SYMBOL_REF:
98052284Sobrien    case LABEL_REF:
98152284Sobrien    case PC:
98252284Sobrien    case CC0:
98352284Sobrien      return 0;
98452284Sobrien
98552284Sobrien    case REG:
98652284Sobrien      return reg_set_between_p (x, start, end);
987117395Skan
98852284Sobrien    default:
98952284Sobrien      break;
99052284Sobrien    }
99152284Sobrien
99252284Sobrien  fmt = GET_RTX_FORMAT (code);
99352284Sobrien  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
99452284Sobrien    {
99552284Sobrien      if (fmt[i] == 'e' && regs_set_between_p (XEXP (x, i), start, end))
99652284Sobrien	return 1;
99752284Sobrien
99852284Sobrien      else if (fmt[i] == 'E')
99952284Sobrien	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
100052284Sobrien	  if (regs_set_between_p (XVECEXP (x, i, j), start, end))
100152284Sobrien	    return 1;
100252284Sobrien    }
100352284Sobrien
100452284Sobrien  return 0;
100552284Sobrien}
100652284Sobrien
100752284Sobrien/* Similar to reg_set_between_p, but check all registers in X.  Return 0
100818334Speter   only if none of them are modified between START and END.  Return 1 if
1009132718Skan   X contains a MEM; this routine does usememory aliasing.  */
101018334Speter
101118334Speterint
1012132718Skanmodified_between_p (rtx x, rtx start, rtx end)
101318334Speter{
101418334Speter  enum rtx_code code = GET_CODE (x);
101590075Sobrien  const char *fmt;
101618334Speter  int i, j;
1017132718Skan  rtx insn;
101818334Speter
1019132718Skan  if (start == end)
1020132718Skan    return 0;
1021132718Skan
102218334Speter  switch (code)
102318334Speter    {
102418334Speter    case CONST_INT:
102518334Speter    case CONST_DOUBLE:
102696263Sobrien    case CONST_VECTOR:
102718334Speter    case CONST:
102818334Speter    case SYMBOL_REF:
102918334Speter    case LABEL_REF:
103018334Speter      return 0;
103118334Speter
103218334Speter    case PC:
103318334Speter    case CC0:
103418334Speter      return 1;
103518334Speter
103618334Speter    case MEM:
1037132718Skan      if (RTX_UNCHANGING_P (x))
1038132718Skan	return 0;
1039132718Skan      if (modified_between_p (XEXP (x, 0), start, end))
104018334Speter	return 1;
1041132718Skan      for (insn = NEXT_INSN (start); insn != end; insn = NEXT_INSN (insn))
1042132718Skan	if (memory_modified_in_insn_p (x, insn))
1043132718Skan	  return 1;
1044132718Skan      return 0;
104518334Speter      break;
104618334Speter
104718334Speter    case REG:
104818334Speter      return reg_set_between_p (x, start, end);
1049117395Skan
105050397Sobrien    default:
105150397Sobrien      break;
105218334Speter    }
105318334Speter
105418334Speter  fmt = GET_RTX_FORMAT (code);
105518334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
105618334Speter    {
105718334Speter      if (fmt[i] == 'e' && modified_between_p (XEXP (x, i), start, end))
105818334Speter	return 1;
105918334Speter
106090075Sobrien      else if (fmt[i] == 'E')
106118334Speter	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
106218334Speter	  if (modified_between_p (XVECEXP (x, i, j), start, end))
106318334Speter	    return 1;
106418334Speter    }
106518334Speter
106618334Speter  return 0;
106718334Speter}
106818334Speter
106918334Speter/* Similar to reg_set_p, but check all registers in X.  Return 0 only if none
107018334Speter   of them are modified in INSN.  Return 1 if X contains a MEM; this routine
1071132718Skan   does use memory aliasing.  */
107218334Speter
107318334Speterint
1074132718Skanmodified_in_p (rtx x, rtx insn)
107518334Speter{
107618334Speter  enum rtx_code code = GET_CODE (x);
107790075Sobrien  const char *fmt;
107818334Speter  int i, j;
107918334Speter
108018334Speter  switch (code)
108118334Speter    {
108218334Speter    case CONST_INT:
108318334Speter    case CONST_DOUBLE:
108496263Sobrien    case CONST_VECTOR:
108518334Speter    case CONST:
108618334Speter    case SYMBOL_REF:
108718334Speter    case LABEL_REF:
108818334Speter      return 0;
108918334Speter
109018334Speter    case PC:
109118334Speter    case CC0:
109218334Speter      return 1;
109318334Speter
109418334Speter    case MEM:
1095132718Skan      if (RTX_UNCHANGING_P (x))
1096132718Skan	return 0;
1097132718Skan      if (modified_in_p (XEXP (x, 0), insn))
109818334Speter	return 1;
1099132718Skan      if (memory_modified_in_insn_p (x, insn))
1100132718Skan	return 1;
1101132718Skan      return 0;
110218334Speter      break;
110318334Speter
110418334Speter    case REG:
110518334Speter      return reg_set_p (x, insn);
110650397Sobrien
110750397Sobrien    default:
110850397Sobrien      break;
110918334Speter    }
111018334Speter
111118334Speter  fmt = GET_RTX_FORMAT (code);
111218334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
111318334Speter    {
111418334Speter      if (fmt[i] == 'e' && modified_in_p (XEXP (x, i), insn))
111518334Speter	return 1;
111618334Speter
111790075Sobrien      else if (fmt[i] == 'E')
111818334Speter	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
111918334Speter	  if (modified_in_p (XVECEXP (x, i, j), insn))
112018334Speter	    return 1;
112118334Speter    }
112218334Speter
112318334Speter  return 0;
112418334Speter}
112590075Sobrien
112690075Sobrien/* Return true if anything in insn X is (anti,output,true) dependent on
112790075Sobrien   anything in insn Y.  */
112890075Sobrien
112990075Sobrienint
1130132718Skaninsn_dependent_p (rtx x, rtx y)
113190075Sobrien{
113290075Sobrien  rtx tmp;
113390075Sobrien
113490075Sobrien  if (! INSN_P (x) || ! INSN_P (y))
113590075Sobrien    abort ();
113690075Sobrien
113790075Sobrien  tmp = PATTERN (y);
113890075Sobrien  note_stores (PATTERN (x), insn_dependent_p_1, &tmp);
113990075Sobrien  if (tmp == NULL_RTX)
114090075Sobrien    return 1;
114190075Sobrien
114290075Sobrien  tmp = PATTERN (x);
114390075Sobrien  note_stores (PATTERN (y), insn_dependent_p_1, &tmp);
114490075Sobrien  if (tmp == NULL_RTX)
114590075Sobrien    return 1;
114690075Sobrien
114790075Sobrien  return 0;
114890075Sobrien}
114990075Sobrien
115090075Sobrien/* A helper routine for insn_dependent_p called through note_stores.  */
115190075Sobrien
115290075Sobrienstatic void
1153132718Skaninsn_dependent_p_1 (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
115490075Sobrien{
115590075Sobrien  rtx * pinsn = (rtx *) data;
115690075Sobrien
115790075Sobrien  if (*pinsn && reg_mentioned_p (x, *pinsn))
115890075Sobrien    *pinsn = NULL_RTX;
115990075Sobrien}
116018334Speter
116190075Sobrien/* Helper function for set_of.  */
116290075Sobrienstruct set_of_data
116390075Sobrien  {
116490075Sobrien    rtx found;
116590075Sobrien    rtx pat;
116690075Sobrien  };
116790075Sobrien
116890075Sobrienstatic void
1169132718Skanset_of_1 (rtx x, rtx pat, void *data1)
117090075Sobrien{
117190075Sobrien   struct set_of_data *data = (struct set_of_data *) (data1);
117290075Sobrien   if (rtx_equal_p (x, data->pat)
117390075Sobrien       || (GET_CODE (x) != MEM && reg_overlap_mentioned_p (data->pat, x)))
117490075Sobrien     data->found = pat;
117590075Sobrien}
117690075Sobrien
117790075Sobrien/* Give an INSN, return a SET or CLOBBER expression that does modify PAT
117890075Sobrien   (either directly or via STRICT_LOW_PART and similar modifiers).  */
117990075Sobrienrtx
1180132718Skanset_of (rtx pat, rtx insn)
118190075Sobrien{
118290075Sobrien  struct set_of_data data;
118390075Sobrien  data.found = NULL_RTX;
118490075Sobrien  data.pat = pat;
118590075Sobrien  note_stores (INSN_P (insn) ? PATTERN (insn) : insn, set_of_1, &data);
118690075Sobrien  return data.found;
118790075Sobrien}
118890075Sobrien
118918334Speter/* Given an INSN, return a SET expression if this insn has only a single SET.
119018334Speter   It may also have CLOBBERs, USEs, or SET whose output
119118334Speter   will not be used, which we ignore.  */
119218334Speter
119318334Speterrtx
1194132718Skansingle_set_2 (rtx insn, rtx pat)
119518334Speter{
119690075Sobrien  rtx set = NULL;
119790075Sobrien  int set_verified = 1;
119818334Speter  int i;
119918334Speter
120090075Sobrien  if (GET_CODE (pat) == PARALLEL)
120118334Speter    {
120290075Sobrien      for (i = 0; i < XVECLEN (pat, 0); i++)
120390075Sobrien	{
120490075Sobrien	  rtx sub = XVECEXP (pat, 0, i);
120590075Sobrien	  switch (GET_CODE (sub))
120690075Sobrien	    {
120790075Sobrien	    case USE:
120890075Sobrien	    case CLOBBER:
120990075Sobrien	      break;
121090075Sobrien
121190075Sobrien	    case SET:
121290075Sobrien	      /* We can consider insns having multiple sets, where all
121390075Sobrien		 but one are dead as single set insns.  In common case
121490075Sobrien		 only single set is present in the pattern so we want
121590075Sobrien		 to avoid checking for REG_UNUSED notes unless necessary.
121690075Sobrien
121790075Sobrien		 When we reach set first time, we just expect this is
121890075Sobrien		 the single set we are looking for and only when more
121990075Sobrien		 sets are found in the insn, we check them.  */
122090075Sobrien	      if (!set_verified)
122190075Sobrien		{
122290075Sobrien		  if (find_reg_note (insn, REG_UNUSED, SET_DEST (set))
122390075Sobrien		      && !side_effects_p (set))
122490075Sobrien		    set = NULL;
122590075Sobrien		  else
122690075Sobrien		    set_verified = 1;
122790075Sobrien		}
122890075Sobrien	      if (!set)
122990075Sobrien		set = sub, set_verified = 0;
123090075Sobrien	      else if (!find_reg_note (insn, REG_UNUSED, SET_DEST (sub))
123190075Sobrien		       || side_effects_p (sub))
123290075Sobrien		return NULL_RTX;
123390075Sobrien	      break;
123490075Sobrien
123590075Sobrien	    default:
123690075Sobrien	      return NULL_RTX;
123790075Sobrien	    }
123890075Sobrien	}
123918334Speter    }
124090075Sobrien  return set;
124118334Speter}
124252284Sobrien
124352284Sobrien/* Given an INSN, return nonzero if it has more than one SET, else return
124452284Sobrien   zero.  */
124552284Sobrien
124652284Sobrienint
1247132718Skanmultiple_sets (rtx insn)
124852284Sobrien{
124952284Sobrien  int found;
125052284Sobrien  int i;
1251117395Skan
125252284Sobrien  /* INSN must be an insn.  */
125390075Sobrien  if (! INSN_P (insn))
125452284Sobrien    return 0;
125552284Sobrien
125652284Sobrien  /* Only a PARALLEL can have multiple SETs.  */
125752284Sobrien  if (GET_CODE (PATTERN (insn)) == PARALLEL)
125852284Sobrien    {
125952284Sobrien      for (i = 0, found = 0; i < XVECLEN (PATTERN (insn), 0); i++)
126052284Sobrien	if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
126152284Sobrien	  {
126252284Sobrien	    /* If we have already found a SET, then return now.  */
126352284Sobrien	    if (found)
126452284Sobrien	      return 1;
126552284Sobrien	    else
126652284Sobrien	      found = 1;
126752284Sobrien	  }
126852284Sobrien    }
1269117395Skan
127052284Sobrien  /* Either zero or one SET.  */
127152284Sobrien  return 0;
127252284Sobrien}
127318334Speter
127490075Sobrien/* Return nonzero if the destination of SET equals the source
127590075Sobrien   and there are no side effects.  */
127618334Speter
127790075Sobrienint
1278132718Skanset_noop_p (rtx set)
127990075Sobrien{
128090075Sobrien  rtx src = SET_SRC (set);
128190075Sobrien  rtx dst = SET_DEST (set);
128290075Sobrien
1283132718Skan  if (dst == pc_rtx && src == pc_rtx)
1284132718Skan    return 1;
128590075Sobrien
128690075Sobrien  if (GET_CODE (dst) == MEM && GET_CODE (src) == MEM)
1287132718Skan    return rtx_equal_p (dst, src) && !side_effects_p (dst);
128890075Sobrien
128990075Sobrien  if (GET_CODE (dst) == SIGN_EXTRACT
129090075Sobrien      || GET_CODE (dst) == ZERO_EXTRACT)
129190075Sobrien    return rtx_equal_p (XEXP (dst, 0), src)
1292132718Skan	   && ! BYTES_BIG_ENDIAN && XEXP (dst, 2) == const0_rtx
1293132718Skan	   && !side_effects_p (src);
129490075Sobrien
129590075Sobrien  if (GET_CODE (dst) == STRICT_LOW_PART)
129690075Sobrien    dst = XEXP (dst, 0);
129790075Sobrien
129890075Sobrien  if (GET_CODE (src) == SUBREG && GET_CODE (dst) == SUBREG)
129990075Sobrien    {
130090075Sobrien      if (SUBREG_BYTE (src) != SUBREG_BYTE (dst))
130190075Sobrien	return 0;
130290075Sobrien      src = SUBREG_REG (src);
130390075Sobrien      dst = SUBREG_REG (dst);
130490075Sobrien    }
130590075Sobrien
130690075Sobrien  return (GET_CODE (src) == REG && GET_CODE (dst) == REG
130790075Sobrien	  && REGNO (src) == REGNO (dst));
130890075Sobrien}
130990075Sobrien
131090075Sobrien/* Return nonzero if an insn consists only of SETs, each of which only sets a
131190075Sobrien   value to itself.  */
131290075Sobrien
131390075Sobrienint
1314132718Skannoop_move_p (rtx insn)
131590075Sobrien{
131690075Sobrien  rtx pat = PATTERN (insn);
131790075Sobrien
131890075Sobrien  if (INSN_CODE (insn) == NOOP_MOVE_INSN_CODE)
131990075Sobrien    return 1;
132090075Sobrien
132190075Sobrien  /* Insns carrying these notes are useful later on.  */
132290075Sobrien  if (find_reg_note (insn, REG_EQUAL, NULL_RTX))
132390075Sobrien    return 0;
132490075Sobrien
132590075Sobrien  /* For now treat an insn with a REG_RETVAL note as a
132690075Sobrien     a special insn which should not be considered a no-op.  */
132790075Sobrien  if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
132890075Sobrien    return 0;
132990075Sobrien
133090075Sobrien  if (GET_CODE (pat) == SET && set_noop_p (pat))
133190075Sobrien    return 1;
133290075Sobrien
133390075Sobrien  if (GET_CODE (pat) == PARALLEL)
133490075Sobrien    {
133590075Sobrien      int i;
133690075Sobrien      /* If nothing but SETs of registers to themselves,
133790075Sobrien	 this insn can also be deleted.  */
133890075Sobrien      for (i = 0; i < XVECLEN (pat, 0); i++)
133990075Sobrien	{
134090075Sobrien	  rtx tem = XVECEXP (pat, 0, i);
134190075Sobrien
134290075Sobrien	  if (GET_CODE (tem) == USE
134390075Sobrien	      || GET_CODE (tem) == CLOBBER)
134490075Sobrien	    continue;
134590075Sobrien
134690075Sobrien	  if (GET_CODE (tem) != SET || ! set_noop_p (tem))
134790075Sobrien	    return 0;
134890075Sobrien	}
134990075Sobrien
135090075Sobrien      return 1;
135190075Sobrien    }
135290075Sobrien  return 0;
135390075Sobrien}
135490075Sobrien
135590075Sobrien
135690075Sobrien/* Return the last thing that X was assigned from before *PINSN.  If VALID_TO
135790075Sobrien   is not NULL_RTX then verify that the object is not modified up to VALID_TO.
135890075Sobrien   If the object was modified, if we hit a partial assignment to X, or hit a
135990075Sobrien   CODE_LABEL first, return X.  If we found an assignment, update *PINSN to
136090075Sobrien   point to it.  ALLOW_HWREG is set to 1 if hardware registers are allowed to
136190075Sobrien   be the src.  */
136290075Sobrien
136318334Speterrtx
1364132718Skanfind_last_value (rtx x, rtx *pinsn, rtx valid_to, int allow_hwreg)
136518334Speter{
136618334Speter  rtx p;
136718334Speter
136818334Speter  for (p = PREV_INSN (*pinsn); p && GET_CODE (p) != CODE_LABEL;
136918334Speter       p = PREV_INSN (p))
137090075Sobrien    if (INSN_P (p))
137118334Speter      {
137218334Speter	rtx set = single_set (p);
137318334Speter	rtx note = find_reg_note (p, REG_EQUAL, NULL_RTX);
137418334Speter
137518334Speter	if (set && rtx_equal_p (x, SET_DEST (set)))
137618334Speter	  {
137718334Speter	    rtx src = SET_SRC (set);
137818334Speter
137918334Speter	    if (note && GET_CODE (XEXP (note, 0)) != EXPR_LIST)
138018334Speter	      src = XEXP (note, 0);
138118334Speter
138290075Sobrien	    if ((valid_to == NULL_RTX
138390075Sobrien		 || ! modified_between_p (src, PREV_INSN (p), valid_to))
138418334Speter		/* Reject hard registers because we don't usually want
138518334Speter		   to use them; we'd rather use a pseudo.  */
138652284Sobrien		&& (! (GET_CODE (src) == REG
138752284Sobrien		      && REGNO (src) < FIRST_PSEUDO_REGISTER) || allow_hwreg))
138818334Speter	      {
138918334Speter		*pinsn = p;
139018334Speter		return src;
139118334Speter	      }
139218334Speter	  }
1393117395Skan
139418334Speter	/* If set in non-simple way, we don't have a value.  */
139518334Speter	if (reg_set_p (x, p))
139618334Speter	  break;
139718334Speter      }
139818334Speter
139918334Speter  return x;
1400117395Skan}
140118334Speter
140218334Speter/* Return nonzero if register in range [REGNO, ENDREGNO)
140318334Speter   appears either explicitly or implicitly in X
140418334Speter   other than being stored into.
140518334Speter
140618334Speter   References contained within the substructure at LOC do not count.
140718334Speter   LOC may be zero, meaning don't ignore anything.  */
140818334Speter
140918334Speterint
1410132718Skanrefers_to_regno_p (unsigned int regno, unsigned int endregno, rtx x,
1411132718Skan		   rtx *loc)
141218334Speter{
141390075Sobrien  int i;
141490075Sobrien  unsigned int x_regno;
141590075Sobrien  RTX_CODE code;
141690075Sobrien  const char *fmt;
141718334Speter
141818334Speter repeat:
141918334Speter  /* The contents of a REG_NONNEG note is always zero, so we must come here
142018334Speter     upon repeat in case the last REG_NOTE is a REG_NONNEG note.  */
142118334Speter  if (x == 0)
142218334Speter    return 0;
142318334Speter
142418334Speter  code = GET_CODE (x);
142518334Speter
142618334Speter  switch (code)
142718334Speter    {
142818334Speter    case REG:
142990075Sobrien      x_regno = REGNO (x);
143018334Speter
143118334Speter      /* If we modifying the stack, frame, or argument pointer, it will
143218334Speter	 clobber a virtual register.  In fact, we could be more precise,
143318334Speter	 but it isn't worth it.  */
143490075Sobrien      if ((x_regno == STACK_POINTER_REGNUM
143518334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
143690075Sobrien	   || x_regno == ARG_POINTER_REGNUM
143718334Speter#endif
143890075Sobrien	   || x_regno == FRAME_POINTER_REGNUM)
143918334Speter	  && regno >= FIRST_VIRTUAL_REGISTER && regno <= LAST_VIRTUAL_REGISTER)
144018334Speter	return 1;
144118334Speter
144290075Sobrien      return (endregno > x_regno
1443117395Skan	      && regno < x_regno + (x_regno < FIRST_PSEUDO_REGISTER
144490075Sobrien				    ? HARD_REGNO_NREGS (x_regno, GET_MODE (x))
144518334Speter			      : 1));
144618334Speter
144718334Speter    case SUBREG:
144818334Speter      /* If this is a SUBREG of a hard reg, we can see exactly which
144918334Speter	 registers are being modified.  Otherwise, handle normally.  */
145018334Speter      if (GET_CODE (SUBREG_REG (x)) == REG
145118334Speter	  && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
145218334Speter	{
145390075Sobrien	  unsigned int inner_regno = subreg_regno (x);
145490075Sobrien	  unsigned int inner_endregno
145518334Speter	    = inner_regno + (inner_regno < FIRST_PSEUDO_REGISTER
145618334Speter			     ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
145718334Speter
145818334Speter	  return endregno > inner_regno && regno < inner_endregno;
145918334Speter	}
146018334Speter      break;
146118334Speter
146218334Speter    case CLOBBER:
146318334Speter    case SET:
146418334Speter      if (&SET_DEST (x) != loc
146518334Speter	  /* Note setting a SUBREG counts as referring to the REG it is in for
146618334Speter	     a pseudo but not for hard registers since we can
146718334Speter	     treat each word individually.  */
146818334Speter	  && ((GET_CODE (SET_DEST (x)) == SUBREG
146918334Speter	       && loc != &SUBREG_REG (SET_DEST (x))
147018334Speter	       && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
147118334Speter	       && REGNO (SUBREG_REG (SET_DEST (x))) >= FIRST_PSEUDO_REGISTER
147218334Speter	       && refers_to_regno_p (regno, endregno,
147318334Speter				     SUBREG_REG (SET_DEST (x)), loc))
147418334Speter	      || (GET_CODE (SET_DEST (x)) != REG
147518334Speter		  && refers_to_regno_p (regno, endregno, SET_DEST (x), loc))))
147618334Speter	return 1;
147718334Speter
147818334Speter      if (code == CLOBBER || loc == &SET_SRC (x))
147918334Speter	return 0;
148018334Speter      x = SET_SRC (x);
148118334Speter      goto repeat;
148250397Sobrien
148350397Sobrien    default:
148450397Sobrien      break;
148518334Speter    }
148618334Speter
148718334Speter  /* X does not match, so try its subexpressions.  */
148818334Speter
148918334Speter  fmt = GET_RTX_FORMAT (code);
149018334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
149118334Speter    {
149218334Speter      if (fmt[i] == 'e' && loc != &XEXP (x, i))
149318334Speter	{
149418334Speter	  if (i == 0)
149518334Speter	    {
149618334Speter	      x = XEXP (x, 0);
149718334Speter	      goto repeat;
149818334Speter	    }
149918334Speter	  else
150018334Speter	    if (refers_to_regno_p (regno, endregno, XEXP (x, i), loc))
150118334Speter	      return 1;
150218334Speter	}
150318334Speter      else if (fmt[i] == 'E')
150418334Speter	{
150590075Sobrien	  int j;
1506132718Skan	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
150718334Speter	    if (loc != &XVECEXP (x, i, j)
150818334Speter		&& refers_to_regno_p (regno, endregno, XVECEXP (x, i, j), loc))
150918334Speter	      return 1;
151018334Speter	}
151118334Speter    }
151218334Speter  return 0;
151318334Speter}
151418334Speter
151518334Speter/* Nonzero if modifying X will affect IN.  If X is a register or a SUBREG,
151618334Speter   we check if any register number in X conflicts with the relevant register
151718334Speter   numbers.  If X is a constant, return 0.  If X is a MEM, return 1 iff IN
151818334Speter   contains a MEM (we don't bother checking for memory addresses that can't
151918334Speter   conflict because we expect this to be a rare case.  */
152018334Speter
152118334Speterint
1522132718Skanreg_overlap_mentioned_p (rtx x, rtx in)
152318334Speter{
152490075Sobrien  unsigned int regno, endregno;
152518334Speter
152650397Sobrien  /* Overly conservative.  */
1527117395Skan  if (GET_CODE (x) == STRICT_LOW_PART
1528117395Skan      || GET_CODE (x) == ZERO_EXTRACT
1529117395Skan      || GET_CODE (x) == SIGN_EXTRACT)
153050397Sobrien    x = XEXP (x, 0);
153150397Sobrien
153250397Sobrien  /* If either argument is a constant, then modifying X can not affect IN.  */
153350397Sobrien  if (CONSTANT_P (x) || CONSTANT_P (in))
153450397Sobrien    return 0;
153590075Sobrien
153690075Sobrien  switch (GET_CODE (x))
153718334Speter    {
153890075Sobrien    case SUBREG:
153918334Speter      regno = REGNO (SUBREG_REG (x));
154018334Speter      if (regno < FIRST_PSEUDO_REGISTER)
154190075Sobrien	regno = subreg_regno (x);
154290075Sobrien      goto do_reg;
154318334Speter
154490075Sobrien    case REG:
154590075Sobrien      regno = REGNO (x);
154690075Sobrien    do_reg:
154790075Sobrien      endregno = regno + (regno < FIRST_PSEUDO_REGISTER
154890075Sobrien			  ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
154990075Sobrien      return refers_to_regno_p (regno, endregno, in, (rtx*) 0);
155018334Speter
155190075Sobrien    case MEM:
155290075Sobrien      {
155390075Sobrien	const char *fmt;
155490075Sobrien	int i;
155518334Speter
155690075Sobrien	if (GET_CODE (in) == MEM)
155718334Speter	  return 1;
155818334Speter
155990075Sobrien	fmt = GET_RTX_FORMAT (GET_CODE (in));
156090075Sobrien	for (i = GET_RTX_LENGTH (GET_CODE (in)) - 1; i >= 0; i--)
156190075Sobrien	  if (fmt[i] == 'e' && reg_overlap_mentioned_p (x, XEXP (in, i)))
156290075Sobrien	    return 1;
156352284Sobrien
156490075Sobrien	return 0;
156590075Sobrien      }
156618334Speter
156790075Sobrien    case SCRATCH:
156890075Sobrien    case PC:
156990075Sobrien    case CC0:
157090075Sobrien      return reg_mentioned_p (x, in);
157118334Speter
157290075Sobrien    case PARALLEL:
157390075Sobrien      {
157490075Sobrien	int i;
157518334Speter
157690075Sobrien	/* If any register in here refers to it we return true.  */
157790075Sobrien	for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
157890075Sobrien	  if (XEXP (XVECEXP (x, 0, i), 0) != 0
157990075Sobrien	      && reg_overlap_mentioned_p (XEXP (XVECEXP (x, 0, i), 0), in))
158090075Sobrien	      return 1;
158190075Sobrien	return 0;
158290075Sobrien      }
158318334Speter
158490075Sobrien    default:
158590075Sobrien      break;
158690075Sobrien    }
158718334Speter
158890075Sobrien  abort ();
158918334Speter}
159090075Sobrien
159118334Speter/* Return the last value to which REG was set prior to INSN.  If we can't
159218334Speter   find it easily, return 0.
159318334Speter
159418334Speter   We only return a REG, SUBREG, or constant because it is too hard to
159518334Speter   check if a MEM remains unchanged.  */
159618334Speter
159718334Speterrtx
1598132718Skanreg_set_last (rtx x, rtx insn)
159918334Speter{
160018334Speter  rtx orig_insn = insn;
160118334Speter
160218334Speter  /* Scan backwards until reg_set_last_1 changed one of the above flags.
160318334Speter     Stop when we reach a label or X is a hard reg and we reach a
160418334Speter     CALL_INSN (if reg_set_last_last_regno is a hard reg).
160518334Speter
160618334Speter     If we find a set of X, ensure that its SET_SRC remains unchanged.  */
160718334Speter
160818334Speter  /* We compare with <= here, because reg_set_last_last_regno
160918334Speter     is actually the number of the first reg *not* in X.  */
161018334Speter  for (;
161118334Speter       insn && GET_CODE (insn) != CODE_LABEL
161218334Speter       && ! (GET_CODE (insn) == CALL_INSN
161390075Sobrien	     && REGNO (x) <= FIRST_PSEUDO_REGISTER);
161418334Speter       insn = PREV_INSN (insn))
161590075Sobrien    if (INSN_P (insn))
161618334Speter      {
161790075Sobrien	rtx set = set_of (x, insn);
161890075Sobrien	/* OK, this function modify our register.  See if we understand it.  */
161990075Sobrien	if (set)
162018334Speter	  {
162190075Sobrien	    rtx last_value;
162290075Sobrien	    if (GET_CODE (set) != SET || SET_DEST (set) != x)
162390075Sobrien	      return 0;
162490075Sobrien	    last_value = SET_SRC (x);
162590075Sobrien	    if (CONSTANT_P (last_value)
162690075Sobrien		|| ((GET_CODE (last_value) == REG
162790075Sobrien		     || GET_CODE (last_value) == SUBREG)
162890075Sobrien		    && ! reg_set_between_p (last_value,
162918334Speter					    insn, orig_insn)))
163090075Sobrien	      return last_value;
163118334Speter	    else
163218334Speter	      return 0;
163318334Speter	  }
163418334Speter      }
163518334Speter
163618334Speter  return 0;
163718334Speter}
163818334Speter
163918334Speter/* Call FUN on each register or MEM that is stored into or clobbered by X.
164018334Speter   (X would be the pattern of an insn).
164118334Speter   FUN receives two arguments:
164218334Speter     the REG, MEM, CC0 or PC being stored in or clobbered,
164318334Speter     the SET or CLOBBER rtx that does the store.
164418334Speter
164518334Speter  If the item being stored in or clobbered is a SUBREG of a hard register,
164618334Speter  the SUBREG will be passed.  */
1647117395Skan
164818334Spetervoid
1649132718Skannote_stores (rtx x, void (*fun) (rtx, rtx, void *), void *data)
165018334Speter{
165190075Sobrien  int i;
165290075Sobrien
165390075Sobrien  if (GET_CODE (x) == COND_EXEC)
165490075Sobrien    x = COND_EXEC_CODE (x);
165590075Sobrien
165690075Sobrien  if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
165718334Speter    {
165890075Sobrien      rtx dest = SET_DEST (x);
165990075Sobrien
166018334Speter      while ((GET_CODE (dest) == SUBREG
166118334Speter	      && (GET_CODE (SUBREG_REG (dest)) != REG
166218334Speter		  || REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
166318334Speter	     || GET_CODE (dest) == ZERO_EXTRACT
166418334Speter	     || GET_CODE (dest) == SIGN_EXTRACT
166518334Speter	     || GET_CODE (dest) == STRICT_LOW_PART)
166618334Speter	dest = XEXP (dest, 0);
166752284Sobrien
166890075Sobrien      /* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions,
166996263Sobrien	 each of whose first operand is a register.  */
167090075Sobrien      if (GET_CODE (dest) == PARALLEL)
167152284Sobrien	{
167252284Sobrien	  for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
167390075Sobrien	    if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
167496263Sobrien	      (*fun) (XEXP (XVECEXP (dest, 0, i), 0), x, data);
167552284Sobrien	}
167652284Sobrien      else
167790075Sobrien	(*fun) (dest, x, data);
167818334Speter    }
167990075Sobrien
168018334Speter  else if (GET_CODE (x) == PARALLEL)
168190075Sobrien    for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
168290075Sobrien      note_stores (XVECEXP (x, 0, i), fun, data);
168390075Sobrien}
168490075Sobrien
168590075Sobrien/* Like notes_stores, but call FUN for each expression that is being
168690075Sobrien   referenced in PBODY, a pointer to the PATTERN of an insn.  We only call
168790075Sobrien   FUN for each expression, not any interior subexpressions.  FUN receives a
168890075Sobrien   pointer to the expression and the DATA passed to this function.
168990075Sobrien
169090075Sobrien   Note that this is not quite the same test as that done in reg_referenced_p
169190075Sobrien   since that considers something as being referenced if it is being
169290075Sobrien   partially set, while we do not.  */
169390075Sobrien
169490075Sobrienvoid
1695132718Skannote_uses (rtx *pbody, void (*fun) (rtx *, void *), void *data)
169690075Sobrien{
169790075Sobrien  rtx body = *pbody;
169890075Sobrien  int i;
169990075Sobrien
170090075Sobrien  switch (GET_CODE (body))
170118334Speter    {
170290075Sobrien    case COND_EXEC:
170390075Sobrien      (*fun) (&COND_EXEC_TEST (body), data);
170490075Sobrien      note_uses (&COND_EXEC_CODE (body), fun, data);
170590075Sobrien      return;
170690075Sobrien
170790075Sobrien    case PARALLEL:
170890075Sobrien      for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
170990075Sobrien	note_uses (&XVECEXP (body, 0, i), fun, data);
171090075Sobrien      return;
171190075Sobrien
171290075Sobrien    case USE:
171390075Sobrien      (*fun) (&XEXP (body, 0), data);
171490075Sobrien      return;
171590075Sobrien
171690075Sobrien    case ASM_OPERANDS:
171790075Sobrien      for (i = ASM_OPERANDS_INPUT_LENGTH (body) - 1; i >= 0; i--)
171890075Sobrien	(*fun) (&ASM_OPERANDS_INPUT (body, i), data);
171990075Sobrien      return;
172090075Sobrien
172190075Sobrien    case TRAP_IF:
172290075Sobrien      (*fun) (&TRAP_CONDITION (body), data);
172390075Sobrien      return;
172490075Sobrien
172590075Sobrien    case PREFETCH:
172690075Sobrien      (*fun) (&XEXP (body, 0), data);
172790075Sobrien      return;
172890075Sobrien
172990075Sobrien    case UNSPEC:
173090075Sobrien    case UNSPEC_VOLATILE:
173190075Sobrien      for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
173290075Sobrien	(*fun) (&XVECEXP (body, 0, i), data);
173390075Sobrien      return;
173490075Sobrien
173590075Sobrien    case CLOBBER:
173690075Sobrien      if (GET_CODE (XEXP (body, 0)) == MEM)
173790075Sobrien	(*fun) (&XEXP (XEXP (body, 0), 0), data);
173890075Sobrien      return;
173990075Sobrien
174090075Sobrien    case SET:
174190075Sobrien      {
174290075Sobrien	rtx dest = SET_DEST (body);
174390075Sobrien
174490075Sobrien	/* For sets we replace everything in source plus registers in memory
174590075Sobrien	   expression in store and operands of a ZERO_EXTRACT.  */
174690075Sobrien	(*fun) (&SET_SRC (body), data);
174790075Sobrien
174890075Sobrien	if (GET_CODE (dest) == ZERO_EXTRACT)
174990075Sobrien	  {
175090075Sobrien	    (*fun) (&XEXP (dest, 1), data);
175190075Sobrien	    (*fun) (&XEXP (dest, 2), data);
175290075Sobrien	  }
175390075Sobrien
175490075Sobrien	while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART)
175590075Sobrien	  dest = XEXP (dest, 0);
175690075Sobrien
175790075Sobrien	if (GET_CODE (dest) == MEM)
175890075Sobrien	  (*fun) (&XEXP (dest, 0), data);
175990075Sobrien      }
176090075Sobrien      return;
176190075Sobrien
176290075Sobrien    default:
176390075Sobrien      /* All the other possibilities never store.  */
176490075Sobrien      (*fun) (pbody, data);
176590075Sobrien      return;
176618334Speter    }
176718334Speter}
176818334Speter
176918334Speter/* Return nonzero if X's old contents don't survive after INSN.
177018334Speter   This will be true if X is (cc0) or if X is a register and
177118334Speter   X dies in INSN or because INSN entirely sets X.
177218334Speter
177318334Speter   "Entirely set" means set directly and not through a SUBREG,
177418334Speter   ZERO_EXTRACT or SIGN_EXTRACT, so no trace of the old contents remains.
177518334Speter   Likewise, REG_INC does not count.
177618334Speter
177718334Speter   REG may be a hard or pseudo reg.  Renumbering is not taken into account,
177818334Speter   but for this use that makes no difference, since regs don't overlap
177918334Speter   during their lifetimes.  Therefore, this function may be used
178018334Speter   at any time after deaths have been computed (in flow.c).
178118334Speter
178218334Speter   If REG is a hard reg that occupies multiple machine registers, this
178318334Speter   function will only return 1 if each of those registers will be replaced
178418334Speter   by INSN.  */
178518334Speter
178618334Speterint
1787132718Skandead_or_set_p (rtx insn, rtx x)
178818334Speter{
178990075Sobrien  unsigned int regno, last_regno;
179090075Sobrien  unsigned int i;
179118334Speter
179218334Speter  /* Can't use cc0_rtx below since this file is used by genattrtab.c.  */
179318334Speter  if (GET_CODE (x) == CC0)
179418334Speter    return 1;
179518334Speter
179618334Speter  if (GET_CODE (x) != REG)
179718334Speter    abort ();
179818334Speter
179918334Speter  regno = REGNO (x);
180018334Speter  last_regno = (regno >= FIRST_PSEUDO_REGISTER ? regno
180118334Speter		: regno + HARD_REGNO_NREGS (regno, GET_MODE (x)) - 1);
180218334Speter
180318334Speter  for (i = regno; i <= last_regno; i++)
180418334Speter    if (! dead_or_set_regno_p (insn, i))
180518334Speter      return 0;
180618334Speter
180718334Speter  return 1;
180818334Speter}
180918334Speter
181018334Speter/* Utility function for dead_or_set_p to check an individual register.  Also
181118334Speter   called from flow.c.  */
181218334Speter
181318334Speterint
1814132718Skandead_or_set_regno_p (rtx insn, unsigned int test_regno)
181518334Speter{
181690075Sobrien  unsigned int regno, endregno;
181790075Sobrien  rtx pattern;
181818334Speter
181990075Sobrien  /* See if there is a death note for something that includes TEST_REGNO.  */
182090075Sobrien  if (find_regno_note (insn, REG_DEAD, test_regno))
182190075Sobrien    return 1;
182218334Speter
182318334Speter  if (GET_CODE (insn) == CALL_INSN
182418334Speter      && find_regno_fusage (insn, CLOBBER, test_regno))
182518334Speter    return 1;
182618334Speter
182790075Sobrien  pattern = PATTERN (insn);
182890075Sobrien
182990075Sobrien  if (GET_CODE (pattern) == COND_EXEC)
183090075Sobrien    pattern = COND_EXEC_CODE (pattern);
183190075Sobrien
183290075Sobrien  if (GET_CODE (pattern) == SET)
183318334Speter    {
1834117395Skan      rtx dest = SET_DEST (pattern);
1835117395Skan
183618334Speter      /* A value is totally replaced if it is the destination or the
183718334Speter	 destination is a SUBREG of REGNO that does not change the number of
183818334Speter	 words in it.  */
183952284Sobrien      if (GET_CODE (dest) == SUBREG
184018334Speter	  && (((GET_MODE_SIZE (GET_MODE (dest))
184118334Speter		+ UNITS_PER_WORD - 1) / UNITS_PER_WORD)
184218334Speter	      == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
184318334Speter		   + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
184418334Speter	dest = SUBREG_REG (dest);
184518334Speter
184618334Speter      if (GET_CODE (dest) != REG)
184718334Speter	return 0;
184818334Speter
184918334Speter      regno = REGNO (dest);
185018334Speter      endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
185118334Speter		  : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest)));
185218334Speter
185318334Speter      return (test_regno >= regno && test_regno < endregno);
185418334Speter    }
185590075Sobrien  else if (GET_CODE (pattern) == PARALLEL)
185618334Speter    {
185790075Sobrien      int i;
185818334Speter
185990075Sobrien      for (i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
186018334Speter	{
186190075Sobrien	  rtx body = XVECEXP (pattern, 0, i);
186218334Speter
186390075Sobrien	  if (GET_CODE (body) == COND_EXEC)
186490075Sobrien	    body = COND_EXEC_CODE (body);
186590075Sobrien
186618334Speter	  if (GET_CODE (body) == SET || GET_CODE (body) == CLOBBER)
186718334Speter	    {
186818334Speter	      rtx dest = SET_DEST (body);
186918334Speter
187018334Speter	      if (GET_CODE (dest) == SUBREG
187118334Speter		  && (((GET_MODE_SIZE (GET_MODE (dest))
187218334Speter			+ UNITS_PER_WORD - 1) / UNITS_PER_WORD)
187318334Speter		      == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
187418334Speter			   + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
187518334Speter		dest = SUBREG_REG (dest);
187618334Speter
187718334Speter	      if (GET_CODE (dest) != REG)
187818334Speter		continue;
187918334Speter
188018334Speter	      regno = REGNO (dest);
188118334Speter	      endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
188218334Speter			  : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest)));
188318334Speter
188418334Speter	      if (test_regno >= regno && test_regno < endregno)
188518334Speter		return 1;
188618334Speter	    }
188718334Speter	}
188818334Speter    }
188918334Speter
189018334Speter  return 0;
189118334Speter}
189218334Speter
189318334Speter/* Return the reg-note of kind KIND in insn INSN, if there is one.
189418334Speter   If DATUM is nonzero, look for one whose datum is DATUM.  */
189518334Speter
189618334Speterrtx
1897132718Skanfind_reg_note (rtx insn, enum reg_note kind, rtx datum)
189818334Speter{
189990075Sobrien  rtx link;
190018334Speter
190150397Sobrien  /* Ignore anything that is not an INSN, JUMP_INSN or CALL_INSN.  */
190290075Sobrien  if (! INSN_P (insn))
190350397Sobrien    return 0;
190450397Sobrien
190518334Speter  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
190618334Speter    if (REG_NOTE_KIND (link) == kind
190718334Speter	&& (datum == 0 || datum == XEXP (link, 0)))
190818334Speter      return link;
190918334Speter  return 0;
191018334Speter}
191118334Speter
191218334Speter/* Return the reg-note of kind KIND in insn INSN which applies to register
191318334Speter   number REGNO, if any.  Return 0 if there is no such reg-note.  Note that
191418334Speter   the REGNO of this NOTE need not be REGNO if REGNO is a hard register;
191518334Speter   it might be the case that the note overlaps REGNO.  */
191618334Speter
191718334Speterrtx
1918132718Skanfind_regno_note (rtx insn, enum reg_note kind, unsigned int regno)
191918334Speter{
192090075Sobrien  rtx link;
192118334Speter
192250397Sobrien  /* Ignore anything that is not an INSN, JUMP_INSN or CALL_INSN.  */
192390075Sobrien  if (! INSN_P (insn))
192450397Sobrien    return 0;
192550397Sobrien
192618334Speter  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
192718334Speter    if (REG_NOTE_KIND (link) == kind
192818334Speter	/* Verify that it is a register, so that scratch and MEM won't cause a
192918334Speter	   problem here.  */
193018334Speter	&& GET_CODE (XEXP (link, 0)) == REG
193118334Speter	&& REGNO (XEXP (link, 0)) <= regno
193218334Speter	&& ((REGNO (XEXP (link, 0))
193318334Speter	     + (REGNO (XEXP (link, 0)) >= FIRST_PSEUDO_REGISTER ? 1
193418334Speter		: HARD_REGNO_NREGS (REGNO (XEXP (link, 0)),
193518334Speter				    GET_MODE (XEXP (link, 0)))))
193618334Speter	    > regno))
193718334Speter      return link;
193818334Speter  return 0;
193918334Speter}
194018334Speter
194190075Sobrien/* Return a REG_EQUIV or REG_EQUAL note if insn has only a single set and
194290075Sobrien   has such a note.  */
194390075Sobrien
194490075Sobrienrtx
1945132718Skanfind_reg_equal_equiv_note (rtx insn)
194690075Sobrien{
1947132718Skan  rtx link;
194890075Sobrien
1949132718Skan  if (!INSN_P (insn))
195090075Sobrien    return 0;
1951132718Skan  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1952132718Skan    if (REG_NOTE_KIND (link) == REG_EQUAL
1953132718Skan	|| REG_NOTE_KIND (link) == REG_EQUIV)
1954132718Skan      {
1955132718Skan	if (single_set (insn) == 0)
1956132718Skan	  return 0;
1957132718Skan	return link;
1958132718Skan      }
1959132718Skan  return NULL;
196090075Sobrien}
196190075Sobrien
196218334Speter/* Return true if DATUM, or any overlap of DATUM, of kind CODE is found
196318334Speter   in the CALL_INSN_FUNCTION_USAGE information of INSN.  */
196418334Speter
196518334Speterint
1966132718Skanfind_reg_fusage (rtx insn, enum rtx_code code, rtx datum)
196718334Speter{
196818334Speter  /* If it's not a CALL_INSN, it can't possibly have a
196918334Speter     CALL_INSN_FUNCTION_USAGE field, so don't bother checking.  */
197018334Speter  if (GET_CODE (insn) != CALL_INSN)
197118334Speter    return 0;
197218334Speter
197318334Speter  if (! datum)
197490075Sobrien    abort ();
197518334Speter
197618334Speter  if (GET_CODE (datum) != REG)
197718334Speter    {
197890075Sobrien      rtx link;
197918334Speter
198018334Speter      for (link = CALL_INSN_FUNCTION_USAGE (insn);
1981117395Skan	   link;
198218334Speter	   link = XEXP (link, 1))
1983117395Skan	if (GET_CODE (XEXP (link, 0)) == code
198490075Sobrien	    && rtx_equal_p (datum, XEXP (XEXP (link, 0), 0)))
1985117395Skan	  return 1;
198618334Speter    }
198718334Speter  else
198818334Speter    {
198990075Sobrien      unsigned int regno = REGNO (datum);
199018334Speter
199118334Speter      /* CALL_INSN_FUNCTION_USAGE information cannot contain references
199218334Speter	 to pseudo registers, so don't bother checking.  */
199318334Speter
199418334Speter      if (regno < FIRST_PSEUDO_REGISTER)
1995117395Skan	{
199690075Sobrien	  unsigned int end_regno
199790075Sobrien	    = regno + HARD_REGNO_NREGS (regno, GET_MODE (datum));
199890075Sobrien	  unsigned int i;
199918334Speter
200018334Speter	  for (i = regno; i < end_regno; i++)
200118334Speter	    if (find_regno_fusage (insn, code, i))
200218334Speter	      return 1;
2003117395Skan	}
200418334Speter    }
200518334Speter
200618334Speter  return 0;
200718334Speter}
200818334Speter
200918334Speter/* Return true if REGNO, or any overlap of REGNO, of kind CODE is found
201018334Speter   in the CALL_INSN_FUNCTION_USAGE information of INSN.  */
201118334Speter
201218334Speterint
2013132718Skanfind_regno_fusage (rtx insn, enum rtx_code code, unsigned int regno)
201418334Speter{
201590075Sobrien  rtx link;
201618334Speter
201718334Speter  /* CALL_INSN_FUNCTION_USAGE information cannot contain references
201818334Speter     to pseudo registers, so don't bother checking.  */
201918334Speter
202018334Speter  if (regno >= FIRST_PSEUDO_REGISTER
202118334Speter      || GET_CODE (insn) != CALL_INSN )
202218334Speter    return 0;
202318334Speter
202418334Speter  for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
202590075Sobrien    {
202690075Sobrien      unsigned int regnote;
202790075Sobrien      rtx op, reg;
202818334Speter
202990075Sobrien      if (GET_CODE (op = XEXP (link, 0)) == code
203090075Sobrien	  && GET_CODE (reg = XEXP (op, 0)) == REG
203190075Sobrien	  && (regnote = REGNO (reg)) <= regno
203290075Sobrien	  && regnote + HARD_REGNO_NREGS (regnote, GET_MODE (reg)) > regno)
203390075Sobrien	return 1;
203490075Sobrien    }
203518334Speter
203618334Speter  return 0;
203718334Speter}
203896263Sobrien
203996263Sobrien/* Return true if INSN is a call to a pure function.  */
204096263Sobrien
204196263Sobrienint
2042132718Skanpure_call_p (rtx insn)
204396263Sobrien{
204496263Sobrien  rtx link;
204596263Sobrien
204696263Sobrien  if (GET_CODE (insn) != CALL_INSN || ! CONST_OR_PURE_CALL_P (insn))
204796263Sobrien    return 0;
204896263Sobrien
204996263Sobrien  /* Look for the note that differentiates const and pure functions.  */
205096263Sobrien  for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
205196263Sobrien    {
205296263Sobrien      rtx u, m;
205396263Sobrien
205496263Sobrien      if (GET_CODE (u = XEXP (link, 0)) == USE
205596263Sobrien	  && GET_CODE (m = XEXP (u, 0)) == MEM && GET_MODE (m) == BLKmode
205696263Sobrien	  && GET_CODE (XEXP (m, 0)) == SCRATCH)
205796263Sobrien	return 1;
205896263Sobrien    }
205996263Sobrien
206096263Sobrien  return 0;
206196263Sobrien}
206218334Speter
206318334Speter/* Remove register note NOTE from the REG_NOTES of INSN.  */
206418334Speter
206518334Spetervoid
2066132718Skanremove_note (rtx insn, rtx note)
206718334Speter{
206890075Sobrien  rtx link;
206918334Speter
207090075Sobrien  if (note == NULL_RTX)
207190075Sobrien    return;
207290075Sobrien
207318334Speter  if (REG_NOTES (insn) == note)
207418334Speter    {
207518334Speter      REG_NOTES (insn) = XEXP (note, 1);
207618334Speter      return;
207718334Speter    }
207818334Speter
207918334Speter  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
208018334Speter    if (XEXP (link, 1) == note)
208118334Speter      {
208218334Speter	XEXP (link, 1) = XEXP (note, 1);
208318334Speter	return;
208418334Speter      }
208518334Speter
208618334Speter  abort ();
208718334Speter}
208852284Sobrien
208990075Sobrien/* Search LISTP (an EXPR_LIST) for an entry whose first operand is NODE and
209090075Sobrien   return 1 if it is found.  A simple equality test is used to determine if
209190075Sobrien   NODE matches.  */
209252284Sobrien
209390075Sobrienint
2094132718Skanin_expr_list_p (rtx listp, rtx node)
209590075Sobrien{
209690075Sobrien  rtx x;
209752284Sobrien
209890075Sobrien  for (x = listp; x; x = XEXP (x, 1))
209990075Sobrien    if (node == XEXP (x, 0))
210090075Sobrien      return 1;
210190075Sobrien
210290075Sobrien  return 0;
210390075Sobrien}
210490075Sobrien
210590075Sobrien/* Search LISTP (an EXPR_LIST) for an entry whose first operand is NODE and
210690075Sobrien   remove that entry from the list if it is found.
210790075Sobrien
210890075Sobrien   A simple equality test is used to determine if NODE matches.  */
210990075Sobrien
211052284Sobrienvoid
2111132718Skanremove_node_from_expr_list (rtx node, rtx *listp)
211252284Sobrien{
211352284Sobrien  rtx temp = *listp;
211452284Sobrien  rtx prev = NULL_RTX;
211552284Sobrien
211652284Sobrien  while (temp)
211752284Sobrien    {
211852284Sobrien      if (node == XEXP (temp, 0))
211952284Sobrien	{
212052284Sobrien	  /* Splice the node out of the list.  */
212152284Sobrien	  if (prev)
212252284Sobrien	    XEXP (prev, 1) = XEXP (temp, 1);
212352284Sobrien	  else
212452284Sobrien	    *listp = XEXP (temp, 1);
212552284Sobrien
212652284Sobrien	  return;
212752284Sobrien	}
212890075Sobrien
212990075Sobrien      prev = temp;
213052284Sobrien      temp = XEXP (temp, 1);
213152284Sobrien    }
213252284Sobrien}
213318334Speter
213418334Speter/* Nonzero if X contains any volatile instructions.  These are instructions
213518334Speter   which may cause unpredictable machine state instructions, and thus no
213618334Speter   instructions should be moved or combined across them.  This includes
213718334Speter   only volatile asms and UNSPEC_VOLATILE instructions.  */
213818334Speter
213918334Speterint
2140132718Skanvolatile_insn_p (rtx x)
214118334Speter{
214290075Sobrien  RTX_CODE code;
214318334Speter
214418334Speter  code = GET_CODE (x);
214518334Speter  switch (code)
214618334Speter    {
214718334Speter    case LABEL_REF:
214818334Speter    case SYMBOL_REF:
214918334Speter    case CONST_INT:
215018334Speter    case CONST:
215118334Speter    case CONST_DOUBLE:
215296263Sobrien    case CONST_VECTOR:
215318334Speter    case CC0:
215418334Speter    case PC:
215518334Speter    case REG:
215618334Speter    case SCRATCH:
215718334Speter    case CLOBBER:
215818334Speter    case ADDR_VEC:
215918334Speter    case ADDR_DIFF_VEC:
216018334Speter    case CALL:
216118334Speter    case MEM:
216218334Speter      return 0;
216318334Speter
216418334Speter    case UNSPEC_VOLATILE:
216518334Speter /* case TRAP_IF: This isn't clear yet.  */
216618334Speter      return 1;
216718334Speter
2168110611Skan    case ASM_INPUT:
216918334Speter    case ASM_OPERANDS:
217018334Speter      if (MEM_VOLATILE_P (x))
217118334Speter	return 1;
217250397Sobrien
217350397Sobrien    default:
217450397Sobrien      break;
217518334Speter    }
217618334Speter
217718334Speter  /* Recursively scan the operands of this expression.  */
217818334Speter
217918334Speter  {
218090075Sobrien    const char *fmt = GET_RTX_FORMAT (code);
218190075Sobrien    int i;
2182117395Skan
218318334Speter    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
218418334Speter      {
218518334Speter	if (fmt[i] == 'e')
218618334Speter	  {
218718334Speter	    if (volatile_insn_p (XEXP (x, i)))
218818334Speter	      return 1;
218918334Speter	  }
219090075Sobrien	else if (fmt[i] == 'E')
219118334Speter	  {
219290075Sobrien	    int j;
219318334Speter	    for (j = 0; j < XVECLEN (x, i); j++)
219418334Speter	      if (volatile_insn_p (XVECEXP (x, i, j)))
219518334Speter		return 1;
219618334Speter	  }
219718334Speter      }
219818334Speter  }
219918334Speter  return 0;
220018334Speter}
220118334Speter
220218334Speter/* Nonzero if X contains any volatile memory references
220318334Speter   UNSPEC_VOLATILE operations or volatile ASM_OPERANDS expressions.  */
220418334Speter
220518334Speterint
2206132718Skanvolatile_refs_p (rtx x)
220718334Speter{
220890075Sobrien  RTX_CODE code;
220918334Speter
221018334Speter  code = GET_CODE (x);
221118334Speter  switch (code)
221218334Speter    {
221318334Speter    case LABEL_REF:
221418334Speter    case SYMBOL_REF:
221518334Speter    case CONST_INT:
221618334Speter    case CONST:
221718334Speter    case CONST_DOUBLE:
221896263Sobrien    case CONST_VECTOR:
221918334Speter    case CC0:
222018334Speter    case PC:
222118334Speter    case REG:
222218334Speter    case SCRATCH:
222318334Speter    case CLOBBER:
222418334Speter    case ADDR_VEC:
222518334Speter    case ADDR_DIFF_VEC:
222618334Speter      return 0;
222718334Speter
222818334Speter    case UNSPEC_VOLATILE:
222918334Speter      return 1;
223018334Speter
223118334Speter    case MEM:
2232110611Skan    case ASM_INPUT:
223318334Speter    case ASM_OPERANDS:
223418334Speter      if (MEM_VOLATILE_P (x))
223518334Speter	return 1;
223650397Sobrien
223750397Sobrien    default:
223850397Sobrien      break;
223918334Speter    }
224018334Speter
224118334Speter  /* Recursively scan the operands of this expression.  */
224218334Speter
224318334Speter  {
224490075Sobrien    const char *fmt = GET_RTX_FORMAT (code);
224590075Sobrien    int i;
2246117395Skan
224718334Speter    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
224818334Speter      {
224918334Speter	if (fmt[i] == 'e')
225018334Speter	  {
225118334Speter	    if (volatile_refs_p (XEXP (x, i)))
225218334Speter	      return 1;
225318334Speter	  }
225490075Sobrien	else if (fmt[i] == 'E')
225518334Speter	  {
225690075Sobrien	    int j;
225718334Speter	    for (j = 0; j < XVECLEN (x, i); j++)
225818334Speter	      if (volatile_refs_p (XVECEXP (x, i, j)))
225918334Speter		return 1;
226018334Speter	  }
226118334Speter      }
226218334Speter  }
226318334Speter  return 0;
226418334Speter}
226518334Speter
226618334Speter/* Similar to above, except that it also rejects register pre- and post-
226718334Speter   incrementing.  */
226818334Speter
226918334Speterint
2270132718Skanside_effects_p (rtx x)
227118334Speter{
227290075Sobrien  RTX_CODE code;
227318334Speter
227418334Speter  code = GET_CODE (x);
227518334Speter  switch (code)
227618334Speter    {
227718334Speter    case LABEL_REF:
227818334Speter    case SYMBOL_REF:
227918334Speter    case CONST_INT:
228018334Speter    case CONST:
228118334Speter    case CONST_DOUBLE:
228296263Sobrien    case CONST_VECTOR:
228318334Speter    case CC0:
228418334Speter    case PC:
228518334Speter    case REG:
228618334Speter    case SCRATCH:
228718334Speter    case ADDR_VEC:
228818334Speter    case ADDR_DIFF_VEC:
228918334Speter      return 0;
229018334Speter
229118334Speter    case CLOBBER:
229218334Speter      /* Reject CLOBBER with a non-VOID mode.  These are made by combine.c
229318334Speter	 when some combination can't be done.  If we see one, don't think
229418334Speter	 that we can simplify the expression.  */
229518334Speter      return (GET_MODE (x) != VOIDmode);
229618334Speter
229718334Speter    case PRE_INC:
229818334Speter    case PRE_DEC:
229918334Speter    case POST_INC:
230018334Speter    case POST_DEC:
230190075Sobrien    case PRE_MODIFY:
230290075Sobrien    case POST_MODIFY:
230318334Speter    case CALL:
230418334Speter    case UNSPEC_VOLATILE:
230518334Speter /* case TRAP_IF: This isn't clear yet.  */
230618334Speter      return 1;
230718334Speter
230818334Speter    case MEM:
2309110611Skan    case ASM_INPUT:
231018334Speter    case ASM_OPERANDS:
231118334Speter      if (MEM_VOLATILE_P (x))
231218334Speter	return 1;
231350397Sobrien
231450397Sobrien    default:
231550397Sobrien      break;
231618334Speter    }
231718334Speter
231818334Speter  /* Recursively scan the operands of this expression.  */
231918334Speter
232018334Speter  {
232190075Sobrien    const char *fmt = GET_RTX_FORMAT (code);
232290075Sobrien    int i;
2323117395Skan
232418334Speter    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
232518334Speter      {
232618334Speter	if (fmt[i] == 'e')
232718334Speter	  {
232818334Speter	    if (side_effects_p (XEXP (x, i)))
232918334Speter	      return 1;
233018334Speter	  }
233190075Sobrien	else if (fmt[i] == 'E')
233218334Speter	  {
233390075Sobrien	    int j;
233418334Speter	    for (j = 0; j < XVECLEN (x, i); j++)
233518334Speter	      if (side_effects_p (XVECEXP (x, i, j)))
233618334Speter		return 1;
233718334Speter	  }
233818334Speter      }
233918334Speter  }
234018334Speter  return 0;
234118334Speter}
234218334Speter
234318334Speter/* Return nonzero if evaluating rtx X might cause a trap.  */
234418334Speter
234518334Speterint
2346132718Skanmay_trap_p (rtx x)
234718334Speter{
234818334Speter  int i;
234918334Speter  enum rtx_code code;
235090075Sobrien  const char *fmt;
235118334Speter
235218334Speter  if (x == 0)
235318334Speter    return 0;
235418334Speter  code = GET_CODE (x);
235518334Speter  switch (code)
235618334Speter    {
235718334Speter      /* Handle these cases quickly.  */
235818334Speter    case CONST_INT:
235918334Speter    case CONST_DOUBLE:
236096263Sobrien    case CONST_VECTOR:
236118334Speter    case SYMBOL_REF:
236218334Speter    case LABEL_REF:
236318334Speter    case CONST:
236418334Speter    case PC:
236518334Speter    case CC0:
236618334Speter    case REG:
236718334Speter    case SCRATCH:
236818334Speter      return 0;
236918334Speter
237090075Sobrien    case ASM_INPUT:
237118334Speter    case UNSPEC_VOLATILE:
237218334Speter    case TRAP_IF:
237318334Speter      return 1;
237418334Speter
237590075Sobrien    case ASM_OPERANDS:
237690075Sobrien      return MEM_VOLATILE_P (x);
237790075Sobrien
237818334Speter      /* Memory ref can trap unless it's a static var or a stack slot.  */
237918334Speter    case MEM:
2380117395Skan      if (MEM_NOTRAP_P (x))
2381117395Skan	return 0;
238218334Speter      return rtx_addr_can_trap_p (XEXP (x, 0));
238318334Speter
238418334Speter      /* Division by a non-constant might trap.  */
238518334Speter    case DIV:
238618334Speter    case MOD:
238718334Speter    case UDIV:
238818334Speter    case UMOD:
2389117395Skan      if (HONOR_SNANS (GET_MODE (x)))
2390117395Skan	return 1;
239150397Sobrien      if (! CONSTANT_P (XEXP (x, 1))
2392117395Skan	  || (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
2393117395Skan	      && flag_trapping_math))
239418334Speter	return 1;
2395132718Skan      if (XEXP (x, 1) == const0_rtx)
239618334Speter	return 1;
239750397Sobrien      break;
239850397Sobrien
239918334Speter    case EXPR_LIST:
240018334Speter      /* An EXPR_LIST is used to represent a function call.  This
240118334Speter	 certainly may trap.  */
240218334Speter      return 1;
240350397Sobrien
240490075Sobrien    case GE:
240590075Sobrien    case GT:
240690075Sobrien    case LE:
240790075Sobrien    case LT:
240890075Sobrien    case COMPARE:
240990075Sobrien      /* Some floating point comparisons may trap.  */
2410117395Skan      if (!flag_trapping_math)
2411117395Skan	break;
241290075Sobrien      /* ??? There is no machine independent way to check for tests that trap
241390075Sobrien	 when COMPARE is used, though many targets do make this distinction.
241490075Sobrien	 For instance, sparc uses CCFPE for compares which generate exceptions
241590075Sobrien	 and CCFP for compares which do not generate exceptions.  */
2416117395Skan      if (HONOR_NANS (GET_MODE (x)))
241790075Sobrien	return 1;
241890075Sobrien      /* But often the compare has some CC mode, so check operand
241990075Sobrien	 modes as well.  */
2420117395Skan      if (HONOR_NANS (GET_MODE (XEXP (x, 0)))
2421117395Skan	  || HONOR_NANS (GET_MODE (XEXP (x, 1))))
242290075Sobrien	return 1;
242390075Sobrien      break;
242490075Sobrien
2425117395Skan    case EQ:
2426117395Skan    case NE:
2427117395Skan      if (HONOR_SNANS (GET_MODE (x)))
2428117395Skan	return 1;
2429117395Skan      /* Often comparison is CC mode, so check operand modes.  */
2430117395Skan      if (HONOR_SNANS (GET_MODE (XEXP (x, 0)))
2431117395Skan	  || HONOR_SNANS (GET_MODE (XEXP (x, 1))))
2432117395Skan	return 1;
2433117395Skan      break;
2434117395Skan
2435117395Skan    case FIX:
2436117395Skan      /* Conversion of floating point might trap.  */
2437117395Skan      if (flag_trapping_math && HONOR_NANS (GET_MODE (XEXP (x, 0))))
2438117395Skan	return 1;
2439117395Skan      break;
2440117395Skan
244190075Sobrien    case NEG:
244290075Sobrien    case ABS:
244390075Sobrien      /* These operations don't trap even with floating point.  */
244490075Sobrien      break;
244590075Sobrien
244618334Speter    default:
244718334Speter      /* Any floating arithmetic may trap.  */
2448117395Skan      if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
2449117395Skan	  && flag_trapping_math)
245018334Speter	return 1;
245118334Speter    }
245218334Speter
245318334Speter  fmt = GET_RTX_FORMAT (code);
245418334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
245518334Speter    {
245618334Speter      if (fmt[i] == 'e')
245718334Speter	{
245818334Speter	  if (may_trap_p (XEXP (x, i)))
245918334Speter	    return 1;
246018334Speter	}
246118334Speter      else if (fmt[i] == 'E')
246218334Speter	{
246390075Sobrien	  int j;
246418334Speter	  for (j = 0; j < XVECLEN (x, i); j++)
246518334Speter	    if (may_trap_p (XVECEXP (x, i, j)))
246618334Speter	      return 1;
246718334Speter	}
246818334Speter    }
246918334Speter  return 0;
247018334Speter}
247118334Speter
247218334Speter/* Return nonzero if X contains a comparison that is not either EQ or NE,
247318334Speter   i.e., an inequality.  */
247418334Speter
247518334Speterint
2476132718Skaninequality_comparisons_p (rtx x)
247718334Speter{
247890075Sobrien  const char *fmt;
247990075Sobrien  int len, i;
248090075Sobrien  enum rtx_code code = GET_CODE (x);
248118334Speter
248218334Speter  switch (code)
248318334Speter    {
248418334Speter    case REG:
248518334Speter    case SCRATCH:
248618334Speter    case PC:
248718334Speter    case CC0:
248818334Speter    case CONST_INT:
248918334Speter    case CONST_DOUBLE:
249096263Sobrien    case CONST_VECTOR:
249118334Speter    case CONST:
249218334Speter    case LABEL_REF:
249318334Speter    case SYMBOL_REF:
249418334Speter      return 0;
249518334Speter
249618334Speter    case LT:
249718334Speter    case LTU:
249818334Speter    case GT:
249918334Speter    case GTU:
250018334Speter    case LE:
250118334Speter    case LEU:
250218334Speter    case GE:
250318334Speter    case GEU:
250418334Speter      return 1;
2505117395Skan
250650397Sobrien    default:
250750397Sobrien      break;
250818334Speter    }
250918334Speter
251018334Speter  len = GET_RTX_LENGTH (code);
251118334Speter  fmt = GET_RTX_FORMAT (code);
251218334Speter
251318334Speter  for (i = 0; i < len; i++)
251418334Speter    {
251518334Speter      if (fmt[i] == 'e')
251618334Speter	{
251718334Speter	  if (inequality_comparisons_p (XEXP (x, i)))
251818334Speter	    return 1;
251918334Speter	}
252018334Speter      else if (fmt[i] == 'E')
252118334Speter	{
252290075Sobrien	  int j;
252318334Speter	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
252418334Speter	    if (inequality_comparisons_p (XVECEXP (x, i, j)))
252518334Speter	      return 1;
252618334Speter	}
252718334Speter    }
2528117395Skan
252918334Speter  return 0;
253018334Speter}
253118334Speter
253250397Sobrien/* Replace any occurrence of FROM in X with TO.  The function does
253350397Sobrien   not enter into CONST_DOUBLE for the replace.
253418334Speter
253518334Speter   Note that copying is not done so X must not be shared unless all copies
253618334Speter   are to be modified.  */
253718334Speter
253818334Speterrtx
2539132718Skanreplace_rtx (rtx x, rtx from, rtx to)
254018334Speter{
254190075Sobrien  int i, j;
254290075Sobrien  const char *fmt;
254318334Speter
254450397Sobrien  /* The following prevents loops occurrence when we change MEM in
254590075Sobrien     CONST_DOUBLE onto the same CONST_DOUBLE.  */
254650397Sobrien  if (x != 0 && GET_CODE (x) == CONST_DOUBLE)
254750397Sobrien    return x;
254850397Sobrien
254918334Speter  if (x == from)
255018334Speter    return to;
255118334Speter
255218334Speter  /* Allow this function to make replacements in EXPR_LISTs.  */
255318334Speter  if (x == 0)
255418334Speter    return 0;
255518334Speter
255696263Sobrien  if (GET_CODE (x) == SUBREG)
255796263Sobrien    {
255896263Sobrien      rtx new = replace_rtx (SUBREG_REG (x), from, to);
255996263Sobrien
256096263Sobrien      if (GET_CODE (new) == CONST_INT)
256196263Sobrien	{
256296263Sobrien	  x = simplify_subreg (GET_MODE (x), new,
256396263Sobrien			       GET_MODE (SUBREG_REG (x)),
256496263Sobrien			       SUBREG_BYTE (x));
256596263Sobrien	  if (! x)
256696263Sobrien	    abort ();
256796263Sobrien	}
256896263Sobrien      else
256996263Sobrien	SUBREG_REG (x) = new;
257096263Sobrien
257196263Sobrien      return x;
257296263Sobrien    }
257396263Sobrien  else if (GET_CODE (x) == ZERO_EXTEND)
257496263Sobrien    {
257596263Sobrien      rtx new = replace_rtx (XEXP (x, 0), from, to);
257696263Sobrien
257796263Sobrien      if (GET_CODE (new) == CONST_INT)
257896263Sobrien	{
257996263Sobrien	  x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
258096263Sobrien					new, GET_MODE (XEXP (x, 0)));
258196263Sobrien	  if (! x)
258296263Sobrien	    abort ();
258396263Sobrien	}
258496263Sobrien      else
258596263Sobrien	XEXP (x, 0) = new;
258696263Sobrien
258796263Sobrien      return x;
258896263Sobrien    }
258996263Sobrien
259018334Speter  fmt = GET_RTX_FORMAT (GET_CODE (x));
259118334Speter  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
259218334Speter    {
259318334Speter      if (fmt[i] == 'e')
259418334Speter	XEXP (x, i) = replace_rtx (XEXP (x, i), from, to);
259518334Speter      else if (fmt[i] == 'E')
259618334Speter	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
259718334Speter	  XVECEXP (x, i, j) = replace_rtx (XVECEXP (x, i, j), from, to);
259818334Speter    }
259918334Speter
260018334Speter  return x;
2601117395Skan}
260218334Speter
260318334Speter/* Throughout the rtx X, replace many registers according to REG_MAP.
260418334Speter   Return the replacement for X (which may be X with altered contents).
260518334Speter   REG_MAP[R] is the replacement for register R, or 0 for don't replace.
2606117395Skan   NREGS is the length of REG_MAP; regs >= NREGS are not mapped.
260718334Speter
260818334Speter   We only support REG_MAP entries of REG or SUBREG.  Also, hard registers
260918334Speter   should not be mapped to pseudos or vice versa since validate_change
261018334Speter   is not called.
261118334Speter
261218334Speter   If REPLACE_DEST is 1, replacements are also done in destinations;
261318334Speter   otherwise, only sources are replaced.  */
261418334Speter
261518334Speterrtx
2616132718Skanreplace_regs (rtx x, rtx *reg_map, unsigned int nregs, int replace_dest)
261718334Speter{
261890075Sobrien  enum rtx_code code;
261990075Sobrien  int i;
262090075Sobrien  const char *fmt;
262118334Speter
262218334Speter  if (x == 0)
262318334Speter    return x;
262418334Speter
262518334Speter  code = GET_CODE (x);
262618334Speter  switch (code)
262718334Speter    {
262818334Speter    case SCRATCH:
262918334Speter    case PC:
263018334Speter    case CC0:
263118334Speter    case CONST_INT:
263218334Speter    case CONST_DOUBLE:
263396263Sobrien    case CONST_VECTOR:
263418334Speter    case CONST:
263518334Speter    case SYMBOL_REF:
263618334Speter    case LABEL_REF:
263718334Speter      return x;
263818334Speter
263918334Speter    case REG:
264018334Speter      /* Verify that the register has an entry before trying to access it.  */
264118334Speter      if (REGNO (x) < nregs && reg_map[REGNO (x)] != 0)
264218334Speter	{
264318334Speter	  /* SUBREGs can't be shared.  Always return a copy to ensure that if
264418334Speter	     this replacement occurs more than once then each instance will
264518334Speter	     get distinct rtx.  */
264618334Speter	  if (GET_CODE (reg_map[REGNO (x)]) == SUBREG)
264718334Speter	    return copy_rtx (reg_map[REGNO (x)]);
264818334Speter	  return reg_map[REGNO (x)];
264918334Speter	}
265018334Speter      return x;
265118334Speter
265218334Speter    case SUBREG:
265318334Speter      /* Prevent making nested SUBREGs.  */
265418334Speter      if (GET_CODE (SUBREG_REG (x)) == REG && REGNO (SUBREG_REG (x)) < nregs
265518334Speter	  && reg_map[REGNO (SUBREG_REG (x))] != 0
265618334Speter	  && GET_CODE (reg_map[REGNO (SUBREG_REG (x))]) == SUBREG)
265718334Speter	{
265818334Speter	  rtx map_val = reg_map[REGNO (SUBREG_REG (x))];
265990075Sobrien	  return simplify_gen_subreg (GET_MODE (x), map_val,
2660117395Skan				      GET_MODE (SUBREG_REG (x)),
266190075Sobrien				      SUBREG_BYTE (x));
266218334Speter	}
266318334Speter      break;
266418334Speter
266518334Speter    case SET:
266618334Speter      if (replace_dest)
266718334Speter	SET_DEST (x) = replace_regs (SET_DEST (x), reg_map, nregs, 0);
266818334Speter
266918334Speter      else if (GET_CODE (SET_DEST (x)) == MEM
267018334Speter	       || GET_CODE (SET_DEST (x)) == STRICT_LOW_PART)
267118334Speter	/* Even if we are not to replace destinations, replace register if it
267218334Speter	   is CONTAINED in destination (destination is memory or
267318334Speter	   STRICT_LOW_PART).  */
267418334Speter	XEXP (SET_DEST (x), 0) = replace_regs (XEXP (SET_DEST (x), 0),
267518334Speter					       reg_map, nregs, 0);
267618334Speter      else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
267718334Speter	/* Similarly, for ZERO_EXTRACT we replace all operands.  */
267818334Speter	break;
267918334Speter
268018334Speter      SET_SRC (x) = replace_regs (SET_SRC (x), reg_map, nregs, 0);
268118334Speter      return x;
2682117395Skan
268350397Sobrien    default:
268450397Sobrien      break;
268518334Speter    }
268618334Speter
268718334Speter  fmt = GET_RTX_FORMAT (code);
268818334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
268918334Speter    {
269018334Speter      if (fmt[i] == 'e')
269118334Speter	XEXP (x, i) = replace_regs (XEXP (x, i), reg_map, nregs, replace_dest);
269290075Sobrien      else if (fmt[i] == 'E')
269318334Speter	{
269490075Sobrien	  int j;
269518334Speter	  for (j = 0; j < XVECLEN (x, i); j++)
269618334Speter	    XVECEXP (x, i, j) = replace_regs (XVECEXP (x, i, j), reg_map,
269718334Speter					      nregs, replace_dest);
269818334Speter	}
269918334Speter    }
270018334Speter  return x;
270118334Speter}
270250397Sobrien
2703132718Skan/* Replace occurrences of the old label in *X with the new one.
2704132718Skan   DATA is a REPLACE_LABEL_DATA containing the old and new labels.  */
2705132718Skan
2706132718Skanint
2707132718Skanreplace_label (rtx *x, void *data)
2708132718Skan{
2709132718Skan  rtx l = *x;
2710132718Skan  rtx old_label = ((replace_label_data *) data)->r1;
2711132718Skan  rtx new_label = ((replace_label_data *) data)->r2;
2712132718Skan  bool update_label_nuses = ((replace_label_data *) data)->update_label_nuses;
2713132718Skan
2714132718Skan  if (l == NULL_RTX)
2715132718Skan    return 0;
2716132718Skan
2717132718Skan  if (GET_CODE (l) == SYMBOL_REF
2718132718Skan      && CONSTANT_POOL_ADDRESS_P (l))
2719132718Skan    {
2720132718Skan      rtx c = get_pool_constant (l);
2721132718Skan      if (rtx_referenced_p (old_label, c))
2722132718Skan	{
2723132718Skan	  rtx new_c, new_l;
2724132718Skan	  replace_label_data *d = (replace_label_data *) data;
2725132718Skan
2726132718Skan	  /* Create a copy of constant C; replace the label inside
2727132718Skan	     but do not update LABEL_NUSES because uses in constant pool
2728132718Skan	     are not counted.  */
2729132718Skan	  new_c = copy_rtx (c);
2730132718Skan	  d->update_label_nuses = false;
2731132718Skan	  for_each_rtx (&new_c, replace_label, data);
2732132718Skan	  d->update_label_nuses = update_label_nuses;
2733132718Skan
2734132718Skan	  /* Add the new constant NEW_C to constant pool and replace
2735132718Skan	     the old reference to constant by new reference.  */
2736132718Skan	  new_l = XEXP (force_const_mem (get_pool_mode (l), new_c), 0);
2737132718Skan	  *x = replace_rtx (l, l, new_l);
2738132718Skan	}
2739132718Skan      return 0;
2740132718Skan    }
2741132718Skan
2742132718Skan  /* If this is a JUMP_INSN, then we also need to fix the JUMP_LABEL
2743132718Skan     field.  This is not handled by for_each_rtx because it doesn't
2744132718Skan     handle unprinted ('0') fields.  */
2745132718Skan  if (GET_CODE (l) == JUMP_INSN && JUMP_LABEL (l) == old_label)
2746132718Skan    JUMP_LABEL (l) = new_label;
2747132718Skan
2748132718Skan  if ((GET_CODE (l) == LABEL_REF
2749132718Skan       || GET_CODE (l) == INSN_LIST)
2750132718Skan      && XEXP (l, 0) == old_label)
2751132718Skan    {
2752132718Skan      XEXP (l, 0) = new_label;
2753132718Skan      if (update_label_nuses)
2754132718Skan	{
2755132718Skan	  ++LABEL_NUSES (new_label);
2756132718Skan	  --LABEL_NUSES (old_label);
2757132718Skan	}
2758132718Skan      return 0;
2759132718Skan    }
2760132718Skan
2761132718Skan  return 0;
2762132718Skan}
2763132718Skan
2764132718Skan/* When *BODY is equal to X or X is directly referenced by *BODY
2765132718Skan   return nonzero, thus FOR_EACH_RTX stops traversing and returns nonzero
2766132718Skan   too, otherwise FOR_EACH_RTX continues traversing *BODY.  */
2767132718Skan
2768132718Skanstatic int
2769132718Skanrtx_referenced_p_1 (rtx *body, void *x)
2770132718Skan{
2771132718Skan  rtx y = (rtx) x;
2772132718Skan
2773132718Skan  if (*body == NULL_RTX)
2774132718Skan    return y == NULL_RTX;
2775132718Skan
2776132718Skan  /* Return true if a label_ref *BODY refers to label Y.  */
2777132718Skan  if (GET_CODE (*body) == LABEL_REF && GET_CODE (y) == CODE_LABEL)
2778132718Skan    return XEXP (*body, 0) == y;
2779132718Skan
2780132718Skan  /* If *BODY is a reference to pool constant traverse the constant.  */
2781132718Skan  if (GET_CODE (*body) == SYMBOL_REF
2782132718Skan      && CONSTANT_POOL_ADDRESS_P (*body))
2783132718Skan    return rtx_referenced_p (y, get_pool_constant (*body));
2784132718Skan
2785132718Skan  /* By default, compare the RTL expressions.  */
2786132718Skan  return rtx_equal_p (*body, y);
2787132718Skan}
2788132718Skan
2789132718Skan/* Return true if X is referenced in BODY.  */
2790132718Skan
2791132718Skanint
2792132718Skanrtx_referenced_p (rtx x, rtx body)
2793132718Skan{
2794132718Skan  return for_each_rtx (&body, rtx_referenced_p_1, x);
2795132718Skan}
2796132718Skan
2797132718Skan/* If INSN is a tablejump return true and store the label (before jump table) to
2798132718Skan   *LABELP and the jump table to *TABLEP.  LABELP and TABLEP may be NULL.  */
2799132718Skan
2800132718Skanbool
2801132718Skantablejump_p (rtx insn, rtx *labelp, rtx *tablep)
2802132718Skan{
2803132718Skan  rtx label, table;
2804132718Skan
2805132718Skan  if (GET_CODE (insn) == JUMP_INSN
2806132718Skan      && (label = JUMP_LABEL (insn)) != NULL_RTX
2807132718Skan      && (table = next_active_insn (label)) != NULL_RTX
2808132718Skan      && GET_CODE (table) == JUMP_INSN
2809132718Skan      && (GET_CODE (PATTERN (table)) == ADDR_VEC
2810132718Skan	  || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
2811132718Skan    {
2812132718Skan      if (labelp)
2813132718Skan	*labelp = label;
2814132718Skan      if (tablep)
2815132718Skan	*tablep = table;
2816132718Skan      return true;
2817132718Skan    }
2818132718Skan  return false;
2819132718Skan}
2820132718Skan
282190075Sobrien/* A subroutine of computed_jump_p, return 1 if X contains a REG or MEM or
282290075Sobrien   constant that is not in the constant pool and not in the condition
282390075Sobrien   of an IF_THEN_ELSE.  */
282450397Sobrien
282550397Sobrienstatic int
2826132718Skancomputed_jump_p_1 (rtx x)
282750397Sobrien{
282850397Sobrien  enum rtx_code code = GET_CODE (x);
282950397Sobrien  int i, j;
283090075Sobrien  const char *fmt;
283150397Sobrien
283250397Sobrien  switch (code)
283350397Sobrien    {
283450397Sobrien    case LABEL_REF:
283550397Sobrien    case PC:
283650397Sobrien      return 0;
283750397Sobrien
283890075Sobrien    case CONST:
283990075Sobrien    case CONST_INT:
284090075Sobrien    case CONST_DOUBLE:
284196263Sobrien    case CONST_VECTOR:
284290075Sobrien    case SYMBOL_REF:
284350397Sobrien    case REG:
284450397Sobrien      return 1;
284550397Sobrien
284650397Sobrien    case MEM:
284750397Sobrien      return ! (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
284850397Sobrien		&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)));
284950397Sobrien
285050397Sobrien    case IF_THEN_ELSE:
285190075Sobrien      return (computed_jump_p_1 (XEXP (x, 1))
285290075Sobrien	      || computed_jump_p_1 (XEXP (x, 2)));
285350397Sobrien
285450397Sobrien    default:
285550397Sobrien      break;
285650397Sobrien    }
285750397Sobrien
285850397Sobrien  fmt = GET_RTX_FORMAT (code);
285950397Sobrien  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
286050397Sobrien    {
286150397Sobrien      if (fmt[i] == 'e'
286290075Sobrien	  && computed_jump_p_1 (XEXP (x, i)))
286350397Sobrien	return 1;
286450397Sobrien
286590075Sobrien      else if (fmt[i] == 'E')
286650397Sobrien	for (j = 0; j < XVECLEN (x, i); j++)
286790075Sobrien	  if (computed_jump_p_1 (XVECEXP (x, i, j)))
286850397Sobrien	    return 1;
286950397Sobrien    }
287050397Sobrien
287150397Sobrien  return 0;
287250397Sobrien}
287350397Sobrien
287450397Sobrien/* Return nonzero if INSN is an indirect jump (aka computed jump).
287550397Sobrien
287650397Sobrien   Tablejumps and casesi insns are not considered indirect jumps;
287790075Sobrien   we can recognize them by a (use (label_ref)).  */
287850397Sobrien
287950397Sobrienint
2880132718Skancomputed_jump_p (rtx insn)
288150397Sobrien{
288250397Sobrien  int i;
288350397Sobrien  if (GET_CODE (insn) == JUMP_INSN)
288450397Sobrien    {
288550397Sobrien      rtx pat = PATTERN (insn);
288650397Sobrien
288790075Sobrien      if (find_reg_note (insn, REG_LABEL, NULL_RTX))
288890075Sobrien	return 0;
288990075Sobrien      else if (GET_CODE (pat) == PARALLEL)
289050397Sobrien	{
289150397Sobrien	  int len = XVECLEN (pat, 0);
289250397Sobrien	  int has_use_labelref = 0;
289350397Sobrien
289450397Sobrien	  for (i = len - 1; i >= 0; i--)
289550397Sobrien	    if (GET_CODE (XVECEXP (pat, 0, i)) == USE
289650397Sobrien		&& (GET_CODE (XEXP (XVECEXP (pat, 0, i), 0))
289750397Sobrien		    == LABEL_REF))
289850397Sobrien	      has_use_labelref = 1;
289950397Sobrien
290050397Sobrien	  if (! has_use_labelref)
290150397Sobrien	    for (i = len - 1; i >= 0; i--)
290250397Sobrien	      if (GET_CODE (XVECEXP (pat, 0, i)) == SET
290350397Sobrien		  && SET_DEST (XVECEXP (pat, 0, i)) == pc_rtx
290490075Sobrien		  && computed_jump_p_1 (SET_SRC (XVECEXP (pat, 0, i))))
290550397Sobrien		return 1;
290650397Sobrien	}
290750397Sobrien      else if (GET_CODE (pat) == SET
290850397Sobrien	       && SET_DEST (pat) == pc_rtx
290990075Sobrien	       && computed_jump_p_1 (SET_SRC (pat)))
291050397Sobrien	return 1;
291150397Sobrien    }
291250397Sobrien  return 0;
291350397Sobrien}
291452284Sobrien
291552284Sobrien/* Traverse X via depth-first search, calling F for each
291652284Sobrien   sub-expression (including X itself).  F is also passed the DATA.
291752284Sobrien   If F returns -1, do not traverse sub-expressions, but continue
291852284Sobrien   traversing the rest of the tree.  If F ever returns any other
2919117395Skan   nonzero value, stop the traversal, and return the value returned
292052284Sobrien   by F.  Otherwise, return 0.  This function does not traverse inside
292152284Sobrien   tree structure that contains RTX_EXPRs, or into sub-expressions
292252284Sobrien   whose format code is `0' since it is not known whether or not those
292352284Sobrien   codes are actually RTL.
292452284Sobrien
292552284Sobrien   This routine is very general, and could (should?) be used to
292652284Sobrien   implement many of the other routines in this file.  */
292752284Sobrien
292852284Sobrienint
2929132718Skanfor_each_rtx (rtx *x, rtx_function f, void *data)
293052284Sobrien{
293152284Sobrien  int result;
293252284Sobrien  int length;
293390075Sobrien  const char *format;
293452284Sobrien  int i;
293552284Sobrien
293652284Sobrien  /* Call F on X.  */
293790075Sobrien  result = (*f) (x, data);
293852284Sobrien  if (result == -1)
293952284Sobrien    /* Do not traverse sub-expressions.  */
294052284Sobrien    return 0;
294152284Sobrien  else if (result != 0)
294252284Sobrien    /* Stop the traversal.  */
294352284Sobrien    return result;
294452284Sobrien
294552284Sobrien  if (*x == NULL_RTX)
294652284Sobrien    /* There are no sub-expressions.  */
294752284Sobrien    return 0;
294852284Sobrien
294952284Sobrien  length = GET_RTX_LENGTH (GET_CODE (*x));
295052284Sobrien  format = GET_RTX_FORMAT (GET_CODE (*x));
295152284Sobrien
2952117395Skan  for (i = 0; i < length; ++i)
295352284Sobrien    {
2954117395Skan      switch (format[i])
295552284Sobrien	{
295652284Sobrien	case 'e':
295752284Sobrien	  result = for_each_rtx (&XEXP (*x, i), f, data);
295852284Sobrien	  if (result != 0)
295952284Sobrien	    return result;
296052284Sobrien	  break;
296152284Sobrien
296252284Sobrien	case 'V':
296352284Sobrien	case 'E':
2964117395Skan	  if (XVEC (*x, i) != 0)
296552284Sobrien	    {
296652284Sobrien	      int j;
296752284Sobrien	      for (j = 0; j < XVECLEN (*x, i); ++j)
296852284Sobrien		{
296952284Sobrien		  result = for_each_rtx (&XVECEXP (*x, i, j), f, data);
297052284Sobrien		  if (result != 0)
297152284Sobrien		    return result;
297252284Sobrien		}
297352284Sobrien	    }
2974117395Skan	  break;
297552284Sobrien
297652284Sobrien	default:
297752284Sobrien	  /* Nothing to do.  */
297852284Sobrien	  break;
297952284Sobrien	}
298052284Sobrien
298152284Sobrien    }
298252284Sobrien
298352284Sobrien  return 0;
298452284Sobrien}
298552284Sobrien
298652284Sobrien/* Searches X for any reference to REGNO, returning the rtx of the
298752284Sobrien   reference found if any.  Otherwise, returns NULL_RTX.  */
298852284Sobrien
298952284Sobrienrtx
2990132718Skanregno_use_in (unsigned int regno, rtx x)
299152284Sobrien{
299290075Sobrien  const char *fmt;
299352284Sobrien  int i, j;
299452284Sobrien  rtx tem;
299552284Sobrien
299652284Sobrien  if (GET_CODE (x) == REG && REGNO (x) == regno)
299752284Sobrien    return x;
299852284Sobrien
299952284Sobrien  fmt = GET_RTX_FORMAT (GET_CODE (x));
300052284Sobrien  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
300152284Sobrien    {
300252284Sobrien      if (fmt[i] == 'e')
300352284Sobrien	{
300452284Sobrien	  if ((tem = regno_use_in (regno, XEXP (x, i))))
300552284Sobrien	    return tem;
300652284Sobrien	}
300752284Sobrien      else if (fmt[i] == 'E')
300852284Sobrien	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
300952284Sobrien	  if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
301052284Sobrien	    return tem;
301152284Sobrien    }
301252284Sobrien
301352284Sobrien  return NULL_RTX;
301452284Sobrien}
301552284Sobrien
301690075Sobrien/* Return a value indicating whether OP, an operand of a commutative
301790075Sobrien   operation, is preferred as the first or second operand.  The higher
301890075Sobrien   the value, the stronger the preference for being the first operand.
301990075Sobrien   We use negative values to indicate a preference for the first operand
302090075Sobrien   and positive values for the second operand.  */
302152284Sobrien
302290075Sobrienint
3023132718Skancommutative_operand_precedence (rtx op)
302490075Sobrien{
302590075Sobrien  /* Constants always come the second operand.  Prefer "nice" constants.  */
302690075Sobrien  if (GET_CODE (op) == CONST_INT)
302790075Sobrien    return -5;
302890075Sobrien  if (GET_CODE (op) == CONST_DOUBLE)
302990075Sobrien    return -4;
303090075Sobrien  if (CONSTANT_P (op))
303190075Sobrien    return -3;
303290075Sobrien
303390075Sobrien  /* SUBREGs of objects should come second.  */
303490075Sobrien  if (GET_CODE (op) == SUBREG
303590075Sobrien      && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op))) == 'o')
303690075Sobrien    return -2;
303790075Sobrien
303890075Sobrien  /* If only one operand is a `neg', `not',
303990075Sobrien    `mult', `plus', or `minus' expression, it will be the first
304090075Sobrien    operand.  */
304190075Sobrien  if (GET_CODE (op) == NEG || GET_CODE (op) == NOT
304290075Sobrien      || GET_CODE (op) == MULT || GET_CODE (op) == PLUS
304390075Sobrien      || GET_CODE (op) == MINUS)
304490075Sobrien    return 2;
304590075Sobrien
304690075Sobrien  /* Complex expressions should be the first, so decrease priority
304790075Sobrien     of objects.  */
304890075Sobrien  if (GET_RTX_CLASS (GET_CODE (op)) == 'o')
304990075Sobrien    return -1;
305090075Sobrien  return 0;
305190075Sobrien}
305290075Sobrien
305390075Sobrien/* Return 1 iff it is necessary to swap operands of commutative operation
305490075Sobrien   in order to canonicalize expression.  */
305590075Sobrien
305690075Sobrienint
3057132718Skanswap_commutative_operands_p (rtx x, rtx y)
305890075Sobrien{
305990075Sobrien  return (commutative_operand_precedence (x)
306090075Sobrien	  < commutative_operand_precedence (y));
306190075Sobrien}
306290075Sobrien
306352284Sobrien/* Return 1 if X is an autoincrement side effect and the register is
306452284Sobrien   not the stack pointer.  */
306552284Sobrienint
3066132718Skanauto_inc_p (rtx x)
306752284Sobrien{
306852284Sobrien  switch (GET_CODE (x))
306952284Sobrien    {
307052284Sobrien    case PRE_INC:
307152284Sobrien    case POST_INC:
307252284Sobrien    case PRE_DEC:
307352284Sobrien    case POST_DEC:
307452284Sobrien    case PRE_MODIFY:
307552284Sobrien    case POST_MODIFY:
307652284Sobrien      /* There are no REG_INC notes for SP.  */
307752284Sobrien      if (XEXP (x, 0) != stack_pointer_rtx)
307852284Sobrien	return 1;
307952284Sobrien    default:
308052284Sobrien      break;
308152284Sobrien    }
308252284Sobrien  return 0;
308352284Sobrien}
308470635Sobrien
308570635Sobrien/* Return 1 if the sequence of instructions beginning with FROM and up
308670635Sobrien   to and including TO is safe to move.  If NEW_TO is non-NULL, and
308770635Sobrien   the sequence is not already safe to move, but can be easily
308870635Sobrien   extended to a sequence which is safe, then NEW_TO will point to the
3089117395Skan   end of the extended sequence.
3090117395Skan
309170635Sobrien   For now, this function only checks that the region contains whole
309290075Sobrien   exception regions, but it could be extended to check additional
309370635Sobrien   conditions as well.  */
309470635Sobrien
309570635Sobrienint
3096132718Skaninsns_safe_to_move_p (rtx from, rtx to, rtx *new_to)
309770635Sobrien{
309870635Sobrien  int eh_region_count = 0;
309970635Sobrien  int past_to_p = 0;
310070635Sobrien  rtx r = from;
310170635Sobrien
310270635Sobrien  /* By default, assume the end of the region will be what was
310370635Sobrien     suggested.  */
310470635Sobrien  if (new_to)
310570635Sobrien    *new_to = to;
310670635Sobrien
310770635Sobrien  while (r)
310870635Sobrien    {
310970635Sobrien      if (GET_CODE (r) == NOTE)
311070635Sobrien	{
311170635Sobrien	  switch (NOTE_LINE_NUMBER (r))
311270635Sobrien	    {
311370635Sobrien	    case NOTE_INSN_EH_REGION_BEG:
311470635Sobrien	      ++eh_region_count;
311570635Sobrien	      break;
311670635Sobrien
311770635Sobrien	    case NOTE_INSN_EH_REGION_END:
311870635Sobrien	      if (eh_region_count == 0)
311970635Sobrien		/* This sequence of instructions contains the end of
312070635Sobrien		   an exception region, but not he beginning.  Moving
312170635Sobrien		   it will cause chaos.  */
312270635Sobrien		return 0;
312370635Sobrien
312470635Sobrien	      --eh_region_count;
312570635Sobrien	      break;
312670635Sobrien
312770635Sobrien	    default:
312870635Sobrien	      break;
312970635Sobrien	    }
313070635Sobrien	}
313170635Sobrien      else if (past_to_p)
313270635Sobrien	/* If we've passed TO, and we see a non-note instruction, we
313370635Sobrien	   can't extend the sequence to a movable sequence.  */
313470635Sobrien	return 0;
313570635Sobrien
313670635Sobrien      if (r == to)
313770635Sobrien	{
313870635Sobrien	  if (!new_to)
313970635Sobrien	    /* It's OK to move the sequence if there were matched sets of
314070635Sobrien	       exception region notes.  */
314170635Sobrien	    return eh_region_count == 0;
3142117395Skan
314370635Sobrien	  past_to_p = 1;
314470635Sobrien	}
314570635Sobrien
314670635Sobrien      /* It's OK to move the sequence if there were matched sets of
314770635Sobrien	 exception region notes.  */
314870635Sobrien      if (past_to_p && eh_region_count == 0)
314970635Sobrien	{
315070635Sobrien	  *new_to = r;
315170635Sobrien	  return 1;
315270635Sobrien	}
315370635Sobrien
315470635Sobrien      /* Go to the next instruction.  */
315570635Sobrien      r = NEXT_INSN (r);
315670635Sobrien    }
3157117395Skan
315870635Sobrien  return 0;
315970635Sobrien}
316090075Sobrien
3161132718Skan/* Return nonzero if IN contains a piece of rtl that has the address LOC.  */
316290075Sobrienint
3163132718Skanloc_mentioned_in_p (rtx *loc, rtx in)
316490075Sobrien{
316590075Sobrien  enum rtx_code code = GET_CODE (in);
316690075Sobrien  const char *fmt = GET_RTX_FORMAT (code);
316790075Sobrien  int i, j;
316890075Sobrien
316990075Sobrien  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
317090075Sobrien    {
3171132718Skan      if (loc == &in->u.fld[i].rtx)
317290075Sobrien	return 1;
317390075Sobrien      if (fmt[i] == 'e')
317490075Sobrien	{
317590075Sobrien	  if (loc_mentioned_in_p (loc, XEXP (in, i)))
317690075Sobrien	    return 1;
317790075Sobrien	}
317890075Sobrien      else if (fmt[i] == 'E')
317990075Sobrien	for (j = XVECLEN (in, i) - 1; j >= 0; j--)
318090075Sobrien	  if (loc_mentioned_in_p (loc, XVECEXP (in, i, j)))
318190075Sobrien	    return 1;
318290075Sobrien    }
318390075Sobrien  return 0;
318490075Sobrien}
318590075Sobrien
318690075Sobrien/* Given a subreg X, return the bit offset where the subreg begins
318790075Sobrien   (counting from the least significant bit of the reg).  */
318890075Sobrien
318990075Sobrienunsigned int
3190132718Skansubreg_lsb (rtx x)
319190075Sobrien{
319290075Sobrien  enum machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
319390075Sobrien  enum machine_mode mode = GET_MODE (x);
319490075Sobrien  unsigned int bitpos;
319590075Sobrien  unsigned int byte;
319690075Sobrien  unsigned int word;
319790075Sobrien
319890075Sobrien  /* A paradoxical subreg begins at bit position 0.  */
319990075Sobrien  if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (inner_mode))
320090075Sobrien    return 0;
320190075Sobrien
320290075Sobrien  if (WORDS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
320390075Sobrien    /* If the subreg crosses a word boundary ensure that
320490075Sobrien       it also begins and ends on a word boundary.  */
320590075Sobrien    if ((SUBREG_BYTE (x) % UNITS_PER_WORD
320690075Sobrien	 + GET_MODE_SIZE (mode)) > UNITS_PER_WORD
320790075Sobrien	&& (SUBREG_BYTE (x) % UNITS_PER_WORD
320890075Sobrien	    || GET_MODE_SIZE (mode) % UNITS_PER_WORD))
320990075Sobrien	abort ();
321090075Sobrien
321190075Sobrien  if (WORDS_BIG_ENDIAN)
321290075Sobrien    word = (GET_MODE_SIZE (inner_mode)
321390075Sobrien	    - (SUBREG_BYTE (x) + GET_MODE_SIZE (mode))) / UNITS_PER_WORD;
321490075Sobrien  else
321590075Sobrien    word = SUBREG_BYTE (x) / UNITS_PER_WORD;
321690075Sobrien  bitpos = word * BITS_PER_WORD;
321790075Sobrien
321890075Sobrien  if (BYTES_BIG_ENDIAN)
321990075Sobrien    byte = (GET_MODE_SIZE (inner_mode)
322090075Sobrien	    - (SUBREG_BYTE (x) + GET_MODE_SIZE (mode))) % UNITS_PER_WORD;
322190075Sobrien  else
322290075Sobrien    byte = SUBREG_BYTE (x) % UNITS_PER_WORD;
322390075Sobrien  bitpos += byte * BITS_PER_UNIT;
322490075Sobrien
322590075Sobrien  return bitpos;
322690075Sobrien}
322790075Sobrien
322890075Sobrien/* This function returns the regno offset of a subreg expression.
322990075Sobrien   xregno - A regno of an inner hard subreg_reg (or what will become one).
323090075Sobrien   xmode  - The mode of xregno.
323190075Sobrien   offset - The byte offset.
323290075Sobrien   ymode  - The mode of a top level SUBREG (or what may become one).
323390075Sobrien   RETURN - The regno offset which would be used.  */
323490075Sobrienunsigned int
3235132718Skansubreg_regno_offset (unsigned int xregno, enum machine_mode xmode,
3236132718Skan		     unsigned int offset, enum machine_mode ymode)
323790075Sobrien{
323890075Sobrien  int nregs_xmode, nregs_ymode;
323990075Sobrien  int mode_multiple, nregs_multiple;
324090075Sobrien  int y_offset;
324190075Sobrien
324290075Sobrien  if (xregno >= FIRST_PSEUDO_REGISTER)
324390075Sobrien    abort ();
324490075Sobrien
324590075Sobrien  nregs_xmode = HARD_REGNO_NREGS (xregno, xmode);
324690075Sobrien  nregs_ymode = HARD_REGNO_NREGS (xregno, ymode);
3247117395Skan
3248117395Skan  /* If this is a big endian paradoxical subreg, which uses more actual
3249117395Skan     hard registers than the original register, we must return a negative
3250117395Skan     offset so that we find the proper highpart of the register.  */
3251117395Skan  if (offset == 0
3252117395Skan      && nregs_ymode > nregs_xmode
3253117395Skan      && (GET_MODE_SIZE (ymode) > UNITS_PER_WORD
3254117395Skan	  ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
3255117395Skan    return nregs_xmode - nregs_ymode;
3256117395Skan
325790075Sobrien  if (offset == 0 || nregs_xmode == nregs_ymode)
325890075Sobrien    return 0;
3259117395Skan
326090075Sobrien  /* size of ymode must not be greater than the size of xmode.  */
326190075Sobrien  mode_multiple = GET_MODE_SIZE (xmode) / GET_MODE_SIZE (ymode);
326290075Sobrien  if (mode_multiple == 0)
326390075Sobrien    abort ();
326490075Sobrien
326590075Sobrien  y_offset = offset / GET_MODE_SIZE (ymode);
326690075Sobrien  nregs_multiple =  nregs_xmode / nregs_ymode;
326790075Sobrien  return (y_offset / (mode_multiple / nregs_multiple)) * nregs_ymode;
326890075Sobrien}
326990075Sobrien
3270117395Skan/* This function returns true when the offset is representable via
3271117395Skan   subreg_offset in the given regno.
3272117395Skan   xregno - A regno of an inner hard subreg_reg (or what will become one).
3273117395Skan   xmode  - The mode of xregno.
3274117395Skan   offset - The byte offset.
3275117395Skan   ymode  - The mode of a top level SUBREG (or what may become one).
3276117395Skan   RETURN - The regno offset which would be used.  */
3277117395Skanbool
3278132718Skansubreg_offset_representable_p (unsigned int xregno, enum machine_mode xmode,
3279132718Skan			       unsigned int offset, enum machine_mode ymode)
3280117395Skan{
3281117395Skan  int nregs_xmode, nregs_ymode;
3282117395Skan  int mode_multiple, nregs_multiple;
3283117395Skan  int y_offset;
3284117395Skan
3285117395Skan  if (xregno >= FIRST_PSEUDO_REGISTER)
3286117395Skan    abort ();
3287117395Skan
3288117395Skan  nregs_xmode = HARD_REGNO_NREGS (xregno, xmode);
3289117395Skan  nregs_ymode = HARD_REGNO_NREGS (xregno, ymode);
3290117395Skan
3291117395Skan  /* paradoxical subregs are always valid.  */
3292117395Skan  if (offset == 0
3293117395Skan      && nregs_ymode > nregs_xmode
3294117395Skan      && (GET_MODE_SIZE (ymode) > UNITS_PER_WORD
3295117395Skan	  ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
3296117395Skan    return true;
3297117395Skan
3298117395Skan  /* Lowpart subregs are always valid.  */
3299117395Skan  if (offset == subreg_lowpart_offset (ymode, xmode))
3300117395Skan    return true;
3301117395Skan
3302117395Skan#ifdef ENABLE_CHECKING
3303117395Skan  /* This should always pass, otherwise we don't know how to verify the
3304117395Skan     constraint.  These conditions may be relaxed but subreg_offset would
3305117395Skan     need to be redesigned.  */
3306117395Skan  if (GET_MODE_SIZE (xmode) % GET_MODE_SIZE (ymode)
3307117395Skan      || GET_MODE_SIZE (ymode) % nregs_ymode
3308117395Skan      || nregs_xmode % nregs_ymode)
3309117395Skan    abort ();
3310117395Skan#endif
3311117395Skan
3312132718Skan  /* The XMODE value can be seen as a vector of NREGS_XMODE
3313132718Skan     values.  The subreg must represent a lowpart of given field.
3314117395Skan     Compute what field it is.  */
3315132718Skan  offset -= subreg_lowpart_offset (ymode,
3316132718Skan				   mode_for_size (GET_MODE_BITSIZE (xmode)
3317132718Skan						  / nregs_xmode,
3318117395Skan						  MODE_INT, 0));
3319117395Skan
3320117395Skan  /* size of ymode must not be greater than the size of xmode.  */
3321117395Skan  mode_multiple = GET_MODE_SIZE (xmode) / GET_MODE_SIZE (ymode);
3322117395Skan  if (mode_multiple == 0)
3323117395Skan    abort ();
3324117395Skan
3325117395Skan  y_offset = offset / GET_MODE_SIZE (ymode);
3326117395Skan  nregs_multiple =  nregs_xmode / nregs_ymode;
3327117395Skan#ifdef ENABLE_CHECKING
3328117395Skan  if (offset % GET_MODE_SIZE (ymode)
3329117395Skan      || mode_multiple % nregs_multiple)
3330117395Skan    abort ();
3331117395Skan#endif
3332117395Skan  return (!(y_offset % (mode_multiple / nregs_multiple)));
3333117395Skan}
3334117395Skan
333590075Sobrien/* Return the final regno that a subreg expression refers to.  */
3336117395Skanunsigned int
3337132718Skansubreg_regno (rtx x)
333890075Sobrien{
333990075Sobrien  unsigned int ret;
334090075Sobrien  rtx subreg = SUBREG_REG (x);
334190075Sobrien  int regno = REGNO (subreg);
334290075Sobrien
3343117395Skan  ret = regno + subreg_regno_offset (regno,
3344117395Skan				     GET_MODE (subreg),
334590075Sobrien				     SUBREG_BYTE (x),
334690075Sobrien				     GET_MODE (x));
334790075Sobrien  return ret;
334890075Sobrien
334990075Sobrien}
335090075Sobrienstruct parms_set_data
335190075Sobrien{
335290075Sobrien  int nregs;
335390075Sobrien  HARD_REG_SET regs;
335490075Sobrien};
335590075Sobrien
335690075Sobrien/* Helper function for noticing stores to parameter registers.  */
335790075Sobrienstatic void
3358132718Skanparms_set (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
335990075Sobrien{
336090075Sobrien  struct parms_set_data *d = data;
336190075Sobrien  if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER
336290075Sobrien      && TEST_HARD_REG_BIT (d->regs, REGNO (x)))
336390075Sobrien    {
336490075Sobrien      CLEAR_HARD_REG_BIT (d->regs, REGNO (x));
336590075Sobrien      d->nregs--;
336690075Sobrien    }
336790075Sobrien}
336890075Sobrien
3369117395Skan/* Look backward for first parameter to be loaded.
337090075Sobrien   Do not skip BOUNDARY.  */
337190075Sobrienrtx
3372132718Skanfind_first_parameter_load (rtx call_insn, rtx boundary)
337390075Sobrien{
337490075Sobrien  struct parms_set_data parm;
337590075Sobrien  rtx p, before;
337690075Sobrien
337790075Sobrien  /* Since different machines initialize their parameter registers
337890075Sobrien     in different orders, assume nothing.  Collect the set of all
337990075Sobrien     parameter registers.  */
338090075Sobrien  CLEAR_HARD_REG_SET (parm.regs);
338190075Sobrien  parm.nregs = 0;
338290075Sobrien  for (p = CALL_INSN_FUNCTION_USAGE (call_insn); p; p = XEXP (p, 1))
338390075Sobrien    if (GET_CODE (XEXP (p, 0)) == USE
338490075Sobrien	&& GET_CODE (XEXP (XEXP (p, 0), 0)) == REG)
338590075Sobrien      {
338690075Sobrien	if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER)
338790075Sobrien	  abort ();
338890075Sobrien
338990075Sobrien	/* We only care about registers which can hold function
339090075Sobrien	   arguments.  */
339190075Sobrien	if (!FUNCTION_ARG_REGNO_P (REGNO (XEXP (XEXP (p, 0), 0))))
339290075Sobrien	  continue;
339390075Sobrien
339490075Sobrien	SET_HARD_REG_BIT (parm.regs, REGNO (XEXP (XEXP (p, 0), 0)));
339590075Sobrien	parm.nregs++;
339690075Sobrien      }
339790075Sobrien  before = call_insn;
339890075Sobrien
339990075Sobrien  /* Search backward for the first set of a register in this set.  */
340090075Sobrien  while (parm.nregs && before != boundary)
340190075Sobrien    {
340290075Sobrien      before = PREV_INSN (before);
340390075Sobrien
340490075Sobrien      /* It is possible that some loads got CSEed from one call to
340590075Sobrien         another.  Stop in that case.  */
340690075Sobrien      if (GET_CODE (before) == CALL_INSN)
340790075Sobrien	break;
340890075Sobrien
340990075Sobrien      /* Our caller needs either ensure that we will find all sets
341090075Sobrien         (in case code has not been optimized yet), or take care
341190075Sobrien         for possible labels in a way by setting boundary to preceding
341290075Sobrien         CODE_LABEL.  */
341390075Sobrien      if (GET_CODE (before) == CODE_LABEL)
341490075Sobrien	{
341590075Sobrien	  if (before != boundary)
341690075Sobrien	    abort ();
341790075Sobrien	  break;
341890075Sobrien	}
341990075Sobrien
342090075Sobrien      if (INSN_P (before))
3421117395Skan	note_stores (PATTERN (before), parms_set, &parm);
342290075Sobrien    }
342390075Sobrien  return before;
342490075Sobrien}
3425117395Skan
3426132718Skan/* Return true if we should avoid inserting code between INSN and preceding
3427117395Skan   call instruction.  */
3428117395Skan
3429117395Skanbool
3430132718Skankeep_with_call_p (rtx insn)
3431117395Skan{
3432117395Skan  rtx set;
3433117395Skan
3434117395Skan  if (INSN_P (insn) && (set = single_set (insn)) != NULL)
3435117395Skan    {
3436117395Skan      if (GET_CODE (SET_DEST (set)) == REG
3437117395Skan	  && REGNO (SET_DEST (set)) < FIRST_PSEUDO_REGISTER
3438117395Skan	  && fixed_regs[REGNO (SET_DEST (set))]
3439117395Skan	  && general_operand (SET_SRC (set), VOIDmode))
3440117395Skan	return true;
3441117395Skan      if (GET_CODE (SET_SRC (set)) == REG
3442117395Skan	  && FUNCTION_VALUE_REGNO_P (REGNO (SET_SRC (set)))
3443117395Skan	  && GET_CODE (SET_DEST (set)) == REG
3444117395Skan	  && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3445117395Skan	return true;
3446117395Skan      /* There may be a stack pop just after the call and before the store
3447117395Skan	 of the return register.  Search for the actual store when deciding
3448117395Skan	 if we can break or not.  */
3449117395Skan      if (SET_DEST (set) == stack_pointer_rtx)
3450117395Skan	{
3451117395Skan	  rtx i2 = next_nonnote_insn (insn);
3452117395Skan	  if (i2 && keep_with_call_p (i2))
3453117395Skan	    return true;
3454117395Skan	}
3455117395Skan    }
3456117395Skan  return false;
3457117395Skan}
3458117395Skan
3459117395Skan/* Return true when store to register X can be hoisted to the place
3460117395Skan   with LIVE registers (can be NULL).  Value VAL contains destination
3461117395Skan   whose value will be used.  */
3462117395Skan
3463117395Skanstatic bool
3464132718Skanhoist_test_store (rtx x, rtx val, regset live)
3465117395Skan{
3466117395Skan  if (GET_CODE (x) == SCRATCH)
3467117395Skan    return true;
3468117395Skan
3469117395Skan  if (rtx_equal_p (x, val))
3470117395Skan    return true;
3471117395Skan
3472132718Skan  /* Allow subreg of X in case it is not writing just part of multireg pseudo.
3473117395Skan     Then we would need to update all users to care hoisting the store too.
3474117395Skan     Caller may represent that by specifying whole subreg as val.  */
3475117395Skan
3476117395Skan  if (GET_CODE (x) == SUBREG && rtx_equal_p (SUBREG_REG (x), val))
3477117395Skan    {
3478117395Skan      if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) > UNITS_PER_WORD
3479117395Skan	  && GET_MODE_BITSIZE (GET_MODE (x)) <
3480117395Skan	  GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))))
3481117395Skan	return false;
3482117395Skan      return true;
3483117395Skan    }
3484117395Skan  if (GET_CODE (x) == SUBREG)
3485117395Skan    x = SUBREG_REG (x);
3486117395Skan
3487117395Skan  /* Anything except register store is not hoistable.  This includes the
3488117395Skan     partial stores to registers.  */
3489117395Skan
3490117395Skan  if (!REG_P (x))
3491117395Skan    return false;
3492117395Skan
3493132718Skan  /* Pseudo registers can be always replaced by another pseudo to avoid
3494117395Skan     the side effect, for hard register we must ensure that they are dead.
3495117395Skan     Eventually we may want to add code to try turn pseudos to hards, but it
3496132718Skan     is unlikely useful.  */
3497117395Skan
3498117395Skan  if (REGNO (x) < FIRST_PSEUDO_REGISTER)
3499117395Skan    {
3500117395Skan      int regno = REGNO (x);
3501117395Skan      int n = HARD_REGNO_NREGS (regno, GET_MODE (x));
3502117395Skan
3503117395Skan      if (!live)
3504117395Skan	return false;
3505117395Skan      if (REGNO_REG_SET_P (live, regno))
3506117395Skan	return false;
3507117395Skan      while (--n > 0)
3508117395Skan	if (REGNO_REG_SET_P (live, regno + n))
3509117395Skan	  return false;
3510117395Skan    }
3511117395Skan  return true;
3512117395Skan}
3513117395Skan
3514117395Skan
3515117395Skan/* Return true if INSN can be hoisted to place with LIVE hard registers
3516117395Skan   (LIVE can be NULL when unknown).  VAL is expected to be stored by the insn
3517117395Skan   and used by the hoisting pass.  */
3518117395Skan
3519117395Skanbool
3520132718Skancan_hoist_insn_p (rtx insn, rtx val, regset live)
3521117395Skan{
3522117395Skan  rtx pat = PATTERN (insn);
3523117395Skan  int i;
3524117395Skan
3525117395Skan  /* It probably does not worth the complexity to handle multiple
3526117395Skan     set stores.  */
3527117395Skan  if (!single_set (insn))
3528117395Skan    return false;
3529117395Skan  /* We can move CALL_INSN, but we need to check that all caller clobbered
3530117395Skan     regs are dead.  */
3531117395Skan  if (GET_CODE (insn) == CALL_INSN)
3532117395Skan    return false;
3533117395Skan  /* In future we will handle hoisting of libcall sequences, but
3534117395Skan     give up for now.  */
3535117395Skan  if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
3536117395Skan    return false;
3537117395Skan  switch (GET_CODE (pat))
3538117395Skan    {
3539117395Skan    case SET:
3540117395Skan      if (!hoist_test_store (SET_DEST (pat), val, live))
3541117395Skan	return false;
3542117395Skan      break;
3543117395Skan    case USE:
3544117395Skan      /* USES do have sick semantics, so do not move them.  */
3545117395Skan      return false;
3546117395Skan      break;
3547117395Skan    case CLOBBER:
3548117395Skan      if (!hoist_test_store (XEXP (pat, 0), val, live))
3549117395Skan	return false;
3550117395Skan      break;
3551117395Skan    case PARALLEL:
3552117395Skan      for (i = 0; i < XVECLEN (pat, 0); i++)
3553117395Skan	{
3554117395Skan	  rtx x = XVECEXP (pat, 0, i);
3555117395Skan	  switch (GET_CODE (x))
3556117395Skan	    {
3557117395Skan	    case SET:
3558117395Skan	      if (!hoist_test_store (SET_DEST (x), val, live))
3559117395Skan		return false;
3560117395Skan	      break;
3561117395Skan	    case USE:
3562117395Skan	      /* We need to fix callers to really ensure availability
3563132718Skan	         of all values insn uses, but for now it is safe to prohibit
3564132718Skan		 hoisting of any insn having such a hidden uses.  */
3565117395Skan	      return false;
3566117395Skan	      break;
3567117395Skan	    case CLOBBER:
3568117395Skan	      if (!hoist_test_store (SET_DEST (x), val, live))
3569117395Skan		return false;
3570117395Skan	      break;
3571117395Skan	    default:
3572117395Skan	      break;
3573117395Skan	    }
3574117395Skan	}
3575117395Skan      break;
3576117395Skan    default:
3577117395Skan      abort ();
3578117395Skan    }
3579117395Skan  return true;
3580117395Skan}
3581117395Skan
3582117395Skan/* Update store after hoisting - replace all stores to pseudo registers
3583117395Skan   by new ones to avoid clobbering of values except for store to VAL that will
3584117395Skan   be updated to NEW.  */
3585117395Skan
3586117395Skanstatic void
3587132718Skanhoist_update_store (rtx insn, rtx *xp, rtx val, rtx new)
3588117395Skan{
3589117395Skan  rtx x = *xp;
3590117395Skan
3591117395Skan  if (GET_CODE (x) == SCRATCH)
3592117395Skan    return;
3593117395Skan
3594117395Skan  if (GET_CODE (x) == SUBREG && SUBREG_REG (x) == val)
3595117395Skan    validate_change (insn, xp,
3596117395Skan		     simplify_gen_subreg (GET_MODE (x), new, GET_MODE (new),
3597117395Skan					  SUBREG_BYTE (x)), 1);
3598117395Skan  if (rtx_equal_p (x, val))
3599117395Skan    {
3600117395Skan      validate_change (insn, xp, new, 1);
3601117395Skan      return;
3602117395Skan    }
3603117395Skan  if (GET_CODE (x) == SUBREG)
3604117395Skan    {
3605117395Skan      xp = &SUBREG_REG (x);
3606117395Skan      x = *xp;
3607117395Skan    }
3608117395Skan
3609117395Skan  if (!REG_P (x))
3610117395Skan    abort ();
3611117395Skan
3612117395Skan  /* We've verified that hard registers are dead, so we may keep the side
3613117395Skan     effect.  Otherwise replace it by new pseudo.  */
3614117395Skan  if (REGNO (x) >= FIRST_PSEUDO_REGISTER)
3615117395Skan    validate_change (insn, xp, gen_reg_rtx (GET_MODE (x)), 1);
3616117395Skan  REG_NOTES (insn)
3617117395Skan    = alloc_EXPR_LIST (REG_UNUSED, *xp, REG_NOTES (insn));
3618117395Skan}
3619117395Skan
3620117395Skan/* Create a copy of INSN after AFTER replacing store of VAL to NEW
3621117395Skan   and each other side effect to pseudo register by new pseudo register.  */
3622117395Skan
3623117395Skanrtx
3624132718Skanhoist_insn_after (rtx insn, rtx after, rtx val, rtx new)
3625117395Skan{
3626117395Skan  rtx pat;
3627117395Skan  int i;
3628117395Skan  rtx note;
3629117395Skan
3630117395Skan  insn = emit_copy_of_insn_after (insn, after);
3631117395Skan  pat = PATTERN (insn);
3632117395Skan
3633117395Skan  /* Remove REG_UNUSED notes as we will re-emit them.  */
3634117395Skan  while ((note = find_reg_note (insn, REG_UNUSED, NULL_RTX)))
3635117395Skan    remove_note (insn, note);
3636117395Skan
3637117395Skan  /* To get this working callers must ensure to move everything referenced
3638117395Skan     by REG_EQUAL/REG_EQUIV notes too.  Lets remove them, it is probably
3639117395Skan     easier.  */
3640117395Skan  while ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)))
3641117395Skan    remove_note (insn, note);
3642117395Skan  while ((note = find_reg_note (insn, REG_EQUIV, NULL_RTX)))
3643117395Skan    remove_note (insn, note);
3644117395Skan
3645117395Skan  /* Remove REG_DEAD notes as they might not be valid anymore in case
3646117395Skan     we create redundancy.  */
3647117395Skan  while ((note = find_reg_note (insn, REG_DEAD, NULL_RTX)))
3648117395Skan    remove_note (insn, note);
3649117395Skan  switch (GET_CODE (pat))
3650117395Skan    {
3651117395Skan    case SET:
3652117395Skan      hoist_update_store (insn, &SET_DEST (pat), val, new);
3653117395Skan      break;
3654117395Skan    case USE:
3655117395Skan      break;
3656117395Skan    case CLOBBER:
3657117395Skan      hoist_update_store (insn, &XEXP (pat, 0), val, new);
3658117395Skan      break;
3659117395Skan    case PARALLEL:
3660117395Skan      for (i = 0; i < XVECLEN (pat, 0); i++)
3661117395Skan	{
3662117395Skan	  rtx x = XVECEXP (pat, 0, i);
3663117395Skan	  switch (GET_CODE (x))
3664117395Skan	    {
3665117395Skan	    case SET:
3666117395Skan	      hoist_update_store (insn, &SET_DEST (x), val, new);
3667117395Skan	      break;
3668117395Skan	    case USE:
3669117395Skan	      break;
3670117395Skan	    case CLOBBER:
3671117395Skan	      hoist_update_store (insn, &SET_DEST (x), val, new);
3672117395Skan	      break;
3673117395Skan	    default:
3674117395Skan	      break;
3675117395Skan	    }
3676117395Skan	}
3677117395Skan      break;
3678117395Skan    default:
3679117395Skan      abort ();
3680117395Skan    }
3681117395Skan  if (!apply_change_group ())
3682117395Skan    abort ();
3683117395Skan
3684117395Skan  return insn;
3685117395Skan}
3686117395Skan
3687117395Skanrtx
3688132718Skanhoist_insn_to_edge (rtx insn, edge e, rtx val, rtx new)
3689117395Skan{
3690117395Skan  rtx new_insn;
3691117395Skan
3692117395Skan  /* We cannot insert instructions on an abnormal critical edge.
3693117395Skan     It will be easier to find the culprit if we die now.  */
3694117395Skan  if ((e->flags & EDGE_ABNORMAL) && EDGE_CRITICAL_P (e))
3695117395Skan    abort ();
3696117395Skan
3697117395Skan  /* Do not use emit_insn_on_edge as we want to preserve notes and similar
3698117395Skan     stuff.  We also emit CALL_INSNS and firends.  */
3699117395Skan  if (e->insns == NULL_RTX)
3700117395Skan    {
3701117395Skan      start_sequence ();
3702132718Skan      emit_note (NOTE_INSN_DELETED);
3703117395Skan    }
3704117395Skan  else
3705117395Skan    push_to_sequence (e->insns);
3706117395Skan
3707117395Skan  new_insn = hoist_insn_after (insn, get_last_insn (), val, new);
3708117395Skan
3709117395Skan  e->insns = get_insns ();
3710117395Skan  end_sequence ();
3711117395Skan  return new_insn;
3712117395Skan}
3713132718Skan
3714132718Skan/* Return true if LABEL is a target of JUMP_INSN.  This applies only
3715132718Skan   to non-complex jumps.  That is, direct unconditional, conditional,
3716132718Skan   and tablejumps, but not computed jumps or returns.  It also does
3717132718Skan   not apply to the fallthru case of a conditional jump.  */
3718132718Skan
3719132718Skanbool
3720132718Skanlabel_is_jump_target_p (rtx label, rtx jump_insn)
3721132718Skan{
3722132718Skan  rtx tmp = JUMP_LABEL (jump_insn);
3723132718Skan
3724132718Skan  if (label == tmp)
3725132718Skan    return true;
3726132718Skan
3727132718Skan  if (tablejump_p (jump_insn, NULL, &tmp))
3728132718Skan    {
3729132718Skan      rtvec vec = XVEC (PATTERN (tmp),
3730132718Skan			GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC);
3731132718Skan      int i, veclen = GET_NUM_ELEM (vec);
3732132718Skan
3733132718Skan      for (i = 0; i < veclen; ++i)
3734132718Skan	if (XEXP (RTVEC_ELT (vec, i), 0) == label)
3735132718Skan	  return true;
3736132718Skan    }
3737132718Skan
3738132718Skan  return false;
3739132718Skan}
3740132718Skan
3741