regmove.c revision 52284
150397Sobrien/* Move registers around to reduce number of move instructions needed.
250397Sobrien   Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
350397Sobrien
450397SobrienThis file is part of GNU CC.
550397Sobrien
650397SobrienGNU CC is free software; you can redistribute it and/or modify
750397Sobrienit under the terms of the GNU General Public License as published by
850397Sobrienthe Free Software Foundation; either version 2, or (at your option)
950397Sobrienany later version.
1050397Sobrien
1150397SobrienGNU CC is distributed in the hope that it will be useful,
1250397Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1350397SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1450397SobrienGNU General Public License for more details.
1550397Sobrien
1650397SobrienYou should have received a copy of the GNU General Public License
1750397Sobrienalong with GNU CC; see the file COPYING.  If not, write to
1852284Sobrienthe Free Software Foundation, 59 Temple Place - Suite 330,
1952284SobrienBoston, MA 02111-1307, USA.  */
2050397Sobrien
2150397Sobrien
2250397Sobrien/* This module looks for cases where matching constraints would force
2350397Sobrien   an instruction to need a reload, and this reload would be a register
2450397Sobrien   to register move.  It then attempts to change the registers used by the
2550397Sobrien   instruction to avoid the move instruction.  */
2650397Sobrien
2750397Sobrien#include "config.h"
2850397Sobrien#include "system.h"
2952284Sobrien#include "rtl.h" /* stdio.h must precede rtl.h for FFS.  */
3050397Sobrien#include "insn-config.h"
3150397Sobrien#include "recog.h"
3250397Sobrien#include "output.h"
3350397Sobrien#include "reload.h"
3450397Sobrien#include "regs.h"
3550397Sobrien#include "hard-reg-set.h"
3650397Sobrien#include "flags.h"
3750397Sobrien#include "expr.h"
3850397Sobrien#include "insn-flags.h"
3950397Sobrien#include "basic-block.h"
4050397Sobrien#include "toplev.h"
4150397Sobrien
4250397Sobrienstatic int optimize_reg_copy_1	PROTO((rtx, rtx, rtx));
4350397Sobrienstatic void optimize_reg_copy_2	PROTO((rtx, rtx, rtx));
4450397Sobrienstatic void optimize_reg_copy_3	PROTO((rtx, rtx, rtx));
4550397Sobrienstatic rtx gen_add3_insn	PROTO((rtx, rtx, rtx));
4652284Sobrienstatic void copy_src_to_dest	PROTO((rtx, rtx, rtx, int, int));
4750397Sobrienstatic int *regmove_bb_head;
4850397Sobrien
4950397Sobrienstruct match {
5050397Sobrien  int with[MAX_RECOG_OPERANDS];
5150397Sobrien  enum { READ, WRITE, READWRITE } use[MAX_RECOG_OPERANDS];
5250397Sobrien  int commutative[MAX_RECOG_OPERANDS];
5350397Sobrien  int early_clobber[MAX_RECOG_OPERANDS];
5450397Sobrien};
5550397Sobrien
5652284Sobrienstatic rtx discover_flags_reg PROTO((void));
5752284Sobrienstatic void mark_flags_life_zones PROTO((rtx));
5852284Sobrienstatic void flags_set_1 PROTO((rtx, rtx));
5952284Sobrien
6050397Sobrienstatic int try_auto_increment PROTO((rtx, rtx, rtx, rtx, HOST_WIDE_INT, int));
6150397Sobrienstatic int find_matches PROTO((rtx, struct match *));
6250397Sobrienstatic int fixup_match_1 PROTO((rtx, rtx, rtx, rtx, rtx, int, int, int, FILE *))
6350397Sobrien;
6450397Sobrienstatic int reg_is_remote_constant_p PROTO((rtx, rtx, rtx));
6550397Sobrienstatic int stable_but_for_p PROTO((rtx, rtx, rtx));
6652284Sobrienstatic int regclass_compatible_p PROTO((int, int));
6750397Sobrienstatic int loop_depth;
6850397Sobrien
6952284Sobrien/* Return non-zero if registers with CLASS1 and CLASS2 can be merged without
7052284Sobrien   causing too much register allocation problems.  */
7152284Sobrienstatic int
7252284Sobrienregclass_compatible_p (class0, class1)
7352284Sobrien     int class0, class1;
7452284Sobrien{
7552284Sobrien  return (class0 == class1
7652284Sobrien	  || (reg_class_subset_p (class0, class1)
7752284Sobrien	      && ! CLASS_LIKELY_SPILLED_P (class0))
7852284Sobrien	  || (reg_class_subset_p (class1, class0)
7952284Sobrien	      && ! CLASS_LIKELY_SPILLED_P (class1)));
8052284Sobrien}
8152284Sobrien
8250397Sobrien/* Generate and return an insn body to add r1 and c,
8350397Sobrien   storing the result in r0.  */
8450397Sobrienstatic rtx
8550397Sobriengen_add3_insn (r0, r1, c)
8650397Sobrien     rtx r0, r1, c;
8750397Sobrien{
8850397Sobrien  int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
8950397Sobrien
9050397Sobrien    if (icode == CODE_FOR_nothing
9150397Sobrien      || ! (*insn_operand_predicate[icode][0]) (r0, insn_operand_mode[icode][0])
9250397Sobrien      || ! (*insn_operand_predicate[icode][1]) (r1, insn_operand_mode[icode][1])
9350397Sobrien      || ! (*insn_operand_predicate[icode][2]) (c, insn_operand_mode[icode][2]))
9450397Sobrien    return NULL_RTX;
9550397Sobrien
9650397Sobrien  return (GEN_FCN (icode) (r0, r1, c));
9750397Sobrien}
9850397Sobrien
9950397Sobrien
10050397Sobrien/* INC_INSN is an instruction that adds INCREMENT to REG.
10150397Sobrien   Try to fold INC_INSN as a post/pre in/decrement into INSN.
10250397Sobrien   Iff INC_INSN_SET is nonzero, inc_insn has a destination different from src.
10350397Sobrien   Return nonzero for success.  */
10450397Sobrienstatic int
10550397Sobrientry_auto_increment (insn, inc_insn, inc_insn_set, reg, increment, pre)
10650397Sobrien     rtx reg, insn, inc_insn ,inc_insn_set;
10750397Sobrien     HOST_WIDE_INT increment;
10850397Sobrien     int pre;
10950397Sobrien{
11050397Sobrien  enum rtx_code inc_code;
11150397Sobrien
11250397Sobrien  rtx pset = single_set (insn);
11350397Sobrien  if (pset)
11450397Sobrien    {
11550397Sobrien      /* Can't use the size of SET_SRC, we might have something like
11650397Sobrien	 (sign_extend:SI (mem:QI ...  */
11750397Sobrien      rtx use = find_use_as_address (pset, reg, 0);
11850397Sobrien      if (use != 0 && use != (rtx) 1)
11950397Sobrien	{
12050397Sobrien	  int size = GET_MODE_SIZE (GET_MODE (use));
12150397Sobrien	  if (0
12252284Sobrien	      || (HAVE_POST_INCREMENT
12352284Sobrien		  && pre == 0 && (inc_code = POST_INC, increment == size))
12452284Sobrien	      || (HAVE_PRE_INCREMENT
12552284Sobrien		  && pre == 1 && (inc_code = PRE_INC, increment == size))
12652284Sobrien	      || (HAVE_POST_DECREMENT
12752284Sobrien		  && pre == 0 && (inc_code = POST_DEC, increment == -size))
12852284Sobrien	      || (HAVE_PRE_DECREMENT
12952284Sobrien		  && pre == 1 && (inc_code = PRE_DEC, increment == -size))
13050397Sobrien	  )
13150397Sobrien	    {
13250397Sobrien	      if (inc_insn_set)
13350397Sobrien		validate_change
13450397Sobrien		  (inc_insn,
13550397Sobrien		   &SET_SRC (inc_insn_set),
13650397Sobrien		   XEXP (SET_SRC (inc_insn_set), 0), 1);
13750397Sobrien	      validate_change (insn, &XEXP (use, 0),
13850397Sobrien			       gen_rtx_fmt_e (inc_code, Pmode, reg), 1);
13950397Sobrien	      if (apply_change_group ())
14050397Sobrien		{
14150397Sobrien		  REG_NOTES (insn)
14250397Sobrien		    = gen_rtx_EXPR_LIST (REG_INC,
14350397Sobrien					 reg, REG_NOTES (insn));
14450397Sobrien		  if (! inc_insn_set)
14550397Sobrien		    {
14650397Sobrien		      PUT_CODE (inc_insn, NOTE);
14750397Sobrien		      NOTE_LINE_NUMBER (inc_insn) = NOTE_INSN_DELETED;
14850397Sobrien		      NOTE_SOURCE_FILE (inc_insn) = 0;
14950397Sobrien		    }
15050397Sobrien		  return 1;
15150397Sobrien		}
15250397Sobrien	    }
15350397Sobrien	}
15450397Sobrien    }
15550397Sobrien  return 0;
15650397Sobrien}
15752284Sobrien
15852284Sobrien/* Determine if the pattern generated by add_optab has a clobber,
15952284Sobrien   such as might be issued for a flags hard register.  To make the
16052284Sobrien   code elsewhere simpler, we handle cc0 in this same framework.
16150397Sobrien
16252284Sobrien   Return the register if one was discovered.  Return NULL_RTX if
16352284Sobrien   if no flags were found.  Return pc_rtx if we got confused.  */
16452284Sobrien
16552284Sobrienstatic rtx
16652284Sobriendiscover_flags_reg ()
16752284Sobrien{
16852284Sobrien  rtx tmp;
16952284Sobrien  tmp = gen_rtx_REG (word_mode, 10000);
17052284Sobrien  tmp = gen_add3_insn (tmp, tmp, GEN_INT (2));
17152284Sobrien
17252284Sobrien  /* If we get something that isn't a simple set, or a
17352284Sobrien     [(set ..) (clobber ..)], this whole function will go wrong.  */
17452284Sobrien  if (GET_CODE (tmp) == SET)
17552284Sobrien    return NULL_RTX;
17652284Sobrien  else if (GET_CODE (tmp) == PARALLEL)
17752284Sobrien    {
17852284Sobrien      int found;
17952284Sobrien
18052284Sobrien      if (XVECLEN (tmp, 0) != 2)
18152284Sobrien	return pc_rtx;
18252284Sobrien      tmp = XVECEXP (tmp, 0, 1);
18352284Sobrien      if (GET_CODE (tmp) != CLOBBER)
18452284Sobrien	return pc_rtx;
18552284Sobrien      tmp = XEXP (tmp, 0);
18652284Sobrien
18752284Sobrien      /* Don't do anything foolish if the md wanted to clobber a
18852284Sobrien	 scratch or something.  We only care about hard regs.
18952284Sobrien	 Moreover we don't like the notion of subregs of hard regs.  */
19052284Sobrien      if (GET_CODE (tmp) == SUBREG
19152284Sobrien	  && GET_CODE (SUBREG_REG (tmp)) == REG
19252284Sobrien	  && REGNO (SUBREG_REG (tmp)) < FIRST_PSEUDO_REGISTER)
19352284Sobrien	return pc_rtx;
19452284Sobrien      found = (GET_CODE (tmp) == REG && REGNO (tmp) < FIRST_PSEUDO_REGISTER);
19552284Sobrien
19652284Sobrien      return (found ? tmp : NULL_RTX);
19752284Sobrien    }
19852284Sobrien
19952284Sobrien  return pc_rtx;
20052284Sobrien}
20152284Sobrien
20252284Sobrien/* It is a tedious task identifying when the flags register is live and
20352284Sobrien   when it is safe to optimize.  Since we process the instruction stream
20452284Sobrien   multiple times, locate and record these live zones by marking the
20552284Sobrien   mode of the instructions --
20652284Sobrien
20752284Sobrien   QImode is used on the instruction at which the flags becomes live.
20852284Sobrien
20952284Sobrien   HImode is used within the range (exclusive) that the flags are
21052284Sobrien   live.  Thus the user of the flags is not marked.
21152284Sobrien
21252284Sobrien   All other instructions are cleared to VOIDmode.  */
21352284Sobrien
21452284Sobrien/* Used to communicate with flags_set_1.  */
21552284Sobrienstatic rtx flags_set_1_rtx;
21652284Sobrienstatic int flags_set_1_set;
21752284Sobrien
21852284Sobrienstatic void
21952284Sobrienmark_flags_life_zones (flags)
22052284Sobrien     rtx flags;
22152284Sobrien{
22252284Sobrien  int flags_regno;
22352284Sobrien  int flags_nregs;
22452284Sobrien  int block;
22552284Sobrien
22652284Sobrien#ifdef HAVE_cc0
22752284Sobrien  /* If we found a flags register on a cc0 host, bail.  */
22852284Sobrien  if (flags == NULL_RTX)
22952284Sobrien    flags = cc0_rtx;
23052284Sobrien  else if (flags != cc0_rtx)
23152284Sobrien    flags = pc_rtx;
23252284Sobrien#endif
23352284Sobrien
23452284Sobrien  /* Simple cases first: if no flags, clear all modes.  If confusing,
23552284Sobrien     mark the entire function as being in a flags shadow.  */
23652284Sobrien  if (flags == NULL_RTX || flags == pc_rtx)
23752284Sobrien    {
23852284Sobrien      enum machine_mode mode = (flags ? HImode : VOIDmode);
23952284Sobrien      rtx insn;
24052284Sobrien      for (insn = get_insns(); insn; insn = NEXT_INSN (insn))
24152284Sobrien	PUT_MODE (insn, mode);
24252284Sobrien      return;
24352284Sobrien    }
24452284Sobrien
24552284Sobrien#ifdef HAVE_cc0
24652284Sobrien  flags_regno = -1;
24752284Sobrien  flags_nregs = 1;
24852284Sobrien#else
24952284Sobrien  flags_regno = REGNO (flags);
25052284Sobrien  flags_nregs = HARD_REGNO_NREGS (flags_regno, GET_MODE (flags));
25152284Sobrien#endif
25252284Sobrien  flags_set_1_rtx = flags;
25352284Sobrien
25452284Sobrien  /* Process each basic block.  */
25552284Sobrien  for (block = n_basic_blocks - 1; block >= 0; block--)
25652284Sobrien    {
25752284Sobrien      rtx insn, end;
25852284Sobrien      int live;
25952284Sobrien
26052284Sobrien      insn = BLOCK_HEAD (block);
26152284Sobrien      end = BLOCK_END (block);
26252284Sobrien
26352284Sobrien      /* Look out for the (unlikely) case of flags being live across
26452284Sobrien	 basic block boundaries.  */
26552284Sobrien      live = 0;
26652284Sobrien#ifndef HAVE_cc0
26752284Sobrien      {
26852284Sobrien	int i;
26952284Sobrien	for (i = 0; i < flags_nregs; ++i)
27052284Sobrien          live |= REGNO_REG_SET_P (BASIC_BLOCK (block)->global_live_at_start,
27152284Sobrien				   flags_regno + i);
27252284Sobrien      }
27352284Sobrien#endif
27452284Sobrien
27552284Sobrien      while (1)
27652284Sobrien	{
27752284Sobrien	  /* Process liveness in reverse order of importance --
27852284Sobrien	     alive, death, birth.  This lets more important info
27952284Sobrien	     overwrite the mode of lesser info.  */
28052284Sobrien
28152284Sobrien	  if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
28252284Sobrien	    {
28352284Sobrien#ifdef HAVE_cc0
28452284Sobrien	      /* In the cc0 case, death is not marked in reg notes,
28552284Sobrien		 but is instead the mere use of cc0 when it is alive.  */
28652284Sobrien	      if (live && reg_mentioned_p (cc0_rtx, PATTERN (insn)))
28752284Sobrien		live = 0;
28852284Sobrien#else
28952284Sobrien	      /* In the hard reg case, we watch death notes.  */
29052284Sobrien	      if (live && find_regno_note (insn, REG_DEAD, flags_regno))
29152284Sobrien		live = 0;
29252284Sobrien#endif
29352284Sobrien	      PUT_MODE (insn, (live ? HImode : VOIDmode));
29452284Sobrien
29552284Sobrien	      /* In either case, birth is denoted simply by it's presence
29652284Sobrien		 as the destination of a set.  */
29752284Sobrien	      flags_set_1_set = 0;
29852284Sobrien	      note_stores (PATTERN (insn), flags_set_1);
29952284Sobrien	      if (flags_set_1_set)
30052284Sobrien		{
30152284Sobrien		  live = 1;
30252284Sobrien		  PUT_MODE (insn, QImode);
30352284Sobrien		}
30452284Sobrien	    }
30552284Sobrien	  else
30652284Sobrien	    PUT_MODE (insn, (live ? HImode : VOIDmode));
30752284Sobrien
30852284Sobrien	  if (insn == end)
30952284Sobrien	    break;
31052284Sobrien	  insn = NEXT_INSN (insn);
31152284Sobrien	}
31252284Sobrien    }
31352284Sobrien}
31452284Sobrien
31552284Sobrien/* A subroutine of mark_flags_life_zones, called through note_stores.  */
31652284Sobrien
31752284Sobrienstatic void
31852284Sobrienflags_set_1 (x, pat)
31952284Sobrien     rtx x, pat;
32052284Sobrien{
32152284Sobrien  if (GET_CODE (pat) == SET
32252284Sobrien      && reg_overlap_mentioned_p (x, flags_set_1_rtx))
32352284Sobrien    flags_set_1_set = 1;
32452284Sobrien}
32552284Sobrien
32650397Sobrienstatic int *regno_src_regno;
32750397Sobrien
32850397Sobrien/* Indicate how good a choice REG (which appears as a source) is to replace
32950397Sobrien   a destination register with.  The higher the returned value, the better
33050397Sobrien   the choice.  The main objective is to avoid using a register that is
33150397Sobrien   a candidate for tying to a hard register, since the output might in
33250397Sobrien   turn be a candidate to be tied to a different hard register.  */
33350397Sobrienint
33450397Sobrienreplacement_quality(reg)
33550397Sobrien     rtx reg;
33650397Sobrien{
33750397Sobrien  int src_regno;
33850397Sobrien
33950397Sobrien  /* Bad if this isn't a register at all.  */
34050397Sobrien  if (GET_CODE (reg) != REG)
34150397Sobrien    return 0;
34250397Sobrien
34350397Sobrien  /* If this register is not meant to get a hard register,
34450397Sobrien     it is a poor choice.  */
34550397Sobrien  if (REG_LIVE_LENGTH (REGNO (reg)) < 0)
34650397Sobrien    return 0;
34750397Sobrien
34850397Sobrien  src_regno = regno_src_regno[REGNO (reg)];
34950397Sobrien
35050397Sobrien  /* If it was not copied from another register, it is fine.  */
35150397Sobrien  if (src_regno < 0)
35250397Sobrien    return 3;
35350397Sobrien
35450397Sobrien  /* Copied from a hard register?  */
35550397Sobrien  if (src_regno < FIRST_PSEUDO_REGISTER)
35650397Sobrien    return 1;
35750397Sobrien
35850397Sobrien  /* Copied from a pseudo register - not as bad as from a hard register,
35950397Sobrien     yet still cumbersome, since the register live length will be lengthened
36050397Sobrien     when the registers get tied.  */
36150397Sobrien  return 2;
36250397Sobrien}
36350397Sobrien
36450397Sobrien/* INSN is a copy from SRC to DEST, both registers, and SRC does not die
36550397Sobrien   in INSN.
36650397Sobrien
36750397Sobrien   Search forward to see if SRC dies before either it or DEST is modified,
36850397Sobrien   but don't scan past the end of a basic block.  If so, we can replace SRC
36950397Sobrien   with DEST and let SRC die in INSN.
37050397Sobrien
37150397Sobrien   This will reduce the number of registers live in that range and may enable
37250397Sobrien   DEST to be tied to SRC, thus often saving one register in addition to a
37350397Sobrien   register-register copy.  */
37450397Sobrien
37550397Sobrienstatic int
37650397Sobrienoptimize_reg_copy_1 (insn, dest, src)
37750397Sobrien     rtx insn;
37850397Sobrien     rtx dest;
37950397Sobrien     rtx src;
38050397Sobrien{
38150397Sobrien  rtx p, q;
38250397Sobrien  rtx note;
38350397Sobrien  rtx dest_death = 0;
38450397Sobrien  int sregno = REGNO (src);
38550397Sobrien  int dregno = REGNO (dest);
38650397Sobrien
38750397Sobrien  /* We don't want to mess with hard regs if register classes are small. */
38850397Sobrien  if (sregno == dregno
38950397Sobrien      || (SMALL_REGISTER_CLASSES
39050397Sobrien	  && (sregno < FIRST_PSEUDO_REGISTER
39150397Sobrien	      || dregno < FIRST_PSEUDO_REGISTER))
39250397Sobrien      /* We don't see all updates to SP if they are in an auto-inc memory
39350397Sobrien	 reference, so we must disallow this optimization on them.  */
39450397Sobrien      || sregno == STACK_POINTER_REGNUM || dregno == STACK_POINTER_REGNUM)
39550397Sobrien    return 0;
39650397Sobrien
39750397Sobrien  for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
39850397Sobrien    {
39950397Sobrien      if (GET_CODE (p) == CODE_LABEL || GET_CODE (p) == JUMP_INSN
40050397Sobrien	  || (GET_CODE (p) == NOTE
40150397Sobrien	      && (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_BEG
40250397Sobrien		  || NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)))
40350397Sobrien	break;
40450397Sobrien
40550397Sobrien      /* ??? We can't scan past the end of a basic block without updating
40650397Sobrien	 the register lifetime info (REG_DEAD/basic_block_live_at_start).
40750397Sobrien	 A CALL_INSN might be the last insn of a basic block, if it is inside
40850397Sobrien	 an EH region.  There is no easy way to tell, so we just always break
40950397Sobrien	 when we see a CALL_INSN if flag_exceptions is nonzero.  */
41050397Sobrien      if (flag_exceptions && GET_CODE (p) == CALL_INSN)
41150397Sobrien	break;
41250397Sobrien
41350397Sobrien      if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
41450397Sobrien	continue;
41550397Sobrien
41650397Sobrien      if (reg_set_p (src, p) || reg_set_p (dest, p)
41750397Sobrien	  /* Don't change a USE of a register.  */
41850397Sobrien	  || (GET_CODE (PATTERN (p)) == USE
41950397Sobrien	      && reg_overlap_mentioned_p (src, XEXP (PATTERN (p), 0))))
42050397Sobrien	break;
42150397Sobrien
42250397Sobrien      /* See if all of SRC dies in P.  This test is slightly more
42350397Sobrien	 conservative than it needs to be.  */
42450397Sobrien      if ((note = find_regno_note (p, REG_DEAD, sregno)) != 0
42550397Sobrien	  && GET_MODE (XEXP (note, 0)) == GET_MODE (src))
42650397Sobrien	{
42750397Sobrien	  int failed = 0;
42850397Sobrien	  int d_length = 0;
42950397Sobrien	  int s_length = 0;
43050397Sobrien	  int d_n_calls = 0;
43150397Sobrien	  int s_n_calls = 0;
43250397Sobrien
43350397Sobrien	  /* We can do the optimization.  Scan forward from INSN again,
43450397Sobrien	     replacing regs as we go.  Set FAILED if a replacement can't
43550397Sobrien	     be done.  In that case, we can't move the death note for SRC.
43650397Sobrien	     This should be rare.  */
43750397Sobrien
43850397Sobrien	  /* Set to stop at next insn.  */
43950397Sobrien	  for (q = next_real_insn (insn);
44050397Sobrien	       q != next_real_insn (p);
44150397Sobrien	       q = next_real_insn (q))
44250397Sobrien	    {
44350397Sobrien	      if (reg_overlap_mentioned_p (src, PATTERN (q)))
44450397Sobrien		{
44550397Sobrien		  /* If SRC is a hard register, we might miss some
44650397Sobrien		     overlapping registers with validate_replace_rtx,
44750397Sobrien		     so we would have to undo it.  We can't if DEST is
44850397Sobrien		     present in the insn, so fail in that combination
44950397Sobrien		     of cases.  */
45050397Sobrien		  if (sregno < FIRST_PSEUDO_REGISTER
45150397Sobrien		      && reg_mentioned_p (dest, PATTERN (q)))
45250397Sobrien		    failed = 1;
45350397Sobrien
45450397Sobrien		  /* Replace all uses and make sure that the register
45550397Sobrien		     isn't still present.  */
45650397Sobrien		  else if (validate_replace_rtx (src, dest, q)
45750397Sobrien			   && (sregno >= FIRST_PSEUDO_REGISTER
45850397Sobrien			       || ! reg_overlap_mentioned_p (src,
45950397Sobrien							     PATTERN (q))))
46050397Sobrien		    {
46150397Sobrien		      /* We assume that a register is used exactly once per
46250397Sobrien			 insn in the REG_N_REFS updates below.  If this is not
46350397Sobrien			 correct, no great harm is done.
46450397Sobrien
46550397Sobrien			 Since we do not know if we will change the lifetime of
46650397Sobrien			 SREGNO or DREGNO, we must not update REG_LIVE_LENGTH
46750397Sobrien			 or REG_N_CALLS_CROSSED at this time.   */
46850397Sobrien		      if (sregno >= FIRST_PSEUDO_REGISTER)
46950397Sobrien			REG_N_REFS (sregno) -= loop_depth;
47050397Sobrien
47150397Sobrien		      if (dregno >= FIRST_PSEUDO_REGISTER)
47250397Sobrien			REG_N_REFS (dregno) += loop_depth;
47350397Sobrien		    }
47450397Sobrien		  else
47550397Sobrien		    {
47650397Sobrien		      validate_replace_rtx (dest, src, q);
47750397Sobrien		      failed = 1;
47850397Sobrien		    }
47950397Sobrien		}
48050397Sobrien
48150397Sobrien	      /* For SREGNO, count the total number of insns scanned.
48250397Sobrien		 For DREGNO, count the total number of insns scanned after
48350397Sobrien		 passing the death note for DREGNO.  */
48450397Sobrien	      s_length++;
48550397Sobrien	      if (dest_death)
48650397Sobrien		d_length++;
48750397Sobrien
48850397Sobrien	      /* If the insn in which SRC dies is a CALL_INSN, don't count it
48950397Sobrien		 as a call that has been crossed.  Otherwise, count it.  */
49050397Sobrien	      if (q != p && GET_CODE (q) == CALL_INSN)
49150397Sobrien		{
49250397Sobrien		  /* Similarly, total calls for SREGNO, total calls beyond
49350397Sobrien		     the death note for DREGNO.  */
49450397Sobrien		  s_n_calls++;
49550397Sobrien		  if (dest_death)
49650397Sobrien		    d_n_calls++;
49750397Sobrien		}
49850397Sobrien
49950397Sobrien	      /* If DEST dies here, remove the death note and save it for
50050397Sobrien		 later.  Make sure ALL of DEST dies here; again, this is
50150397Sobrien		 overly conservative.  */
50250397Sobrien	      if (dest_death == 0
50350397Sobrien		  && (dest_death = find_regno_note (q, REG_DEAD, dregno)) != 0)
50450397Sobrien		{
50550397Sobrien		  if (GET_MODE (XEXP (dest_death, 0)) != GET_MODE (dest))
50650397Sobrien		    failed = 1, dest_death = 0;
50750397Sobrien		  else
50850397Sobrien		    remove_note (q, dest_death);
50950397Sobrien		}
51050397Sobrien	    }
51150397Sobrien
51250397Sobrien	  if (! failed)
51350397Sobrien	    {
51450397Sobrien	      /* These counters need to be updated if and only if we are
51550397Sobrien		 going to move the REG_DEAD note.  */
51650397Sobrien	      if (sregno >= FIRST_PSEUDO_REGISTER)
51750397Sobrien		{
51850397Sobrien		  if (REG_LIVE_LENGTH (sregno) >= 0)
51950397Sobrien		    {
52050397Sobrien		      REG_LIVE_LENGTH (sregno) -= s_length;
52150397Sobrien		      /* REG_LIVE_LENGTH is only an approximation after
52250397Sobrien			 combine if sched is not run, so make sure that we
52350397Sobrien			 still have a reasonable value.  */
52450397Sobrien		      if (REG_LIVE_LENGTH (sregno) < 2)
52550397Sobrien			REG_LIVE_LENGTH (sregno) = 2;
52650397Sobrien		    }
52750397Sobrien
52850397Sobrien		  REG_N_CALLS_CROSSED (sregno) -= s_n_calls;
52950397Sobrien		}
53050397Sobrien
53150397Sobrien	      /* Move death note of SRC from P to INSN.  */
53250397Sobrien	      remove_note (p, note);
53350397Sobrien	      XEXP (note, 1) = REG_NOTES (insn);
53450397Sobrien	      REG_NOTES (insn) = note;
53550397Sobrien	    }
53650397Sobrien
53750397Sobrien	  /* Put death note of DEST on P if we saw it die.  */
53850397Sobrien	  if (dest_death)
53950397Sobrien	    {
54050397Sobrien	      XEXP (dest_death, 1) = REG_NOTES (p);
54150397Sobrien	      REG_NOTES (p) = dest_death;
54250397Sobrien
54350397Sobrien	      if (dregno >= FIRST_PSEUDO_REGISTER)
54450397Sobrien		{
54550397Sobrien		  /* If and only if we are moving the death note for DREGNO,
54650397Sobrien		     then we need to update its counters.  */
54750397Sobrien		  if (REG_LIVE_LENGTH (dregno) >= 0)
54850397Sobrien		    REG_LIVE_LENGTH (dregno) += d_length;
54950397Sobrien		  REG_N_CALLS_CROSSED (dregno) += d_n_calls;
55050397Sobrien		}
55150397Sobrien	    }
55250397Sobrien
55350397Sobrien	  return ! failed;
55450397Sobrien	}
55550397Sobrien
55650397Sobrien      /* If SRC is a hard register which is set or killed in some other
55750397Sobrien	 way, we can't do this optimization.  */
55850397Sobrien      else if (sregno < FIRST_PSEUDO_REGISTER
55950397Sobrien	       && dead_or_set_p (p, src))
56050397Sobrien	break;
56150397Sobrien    }
56250397Sobrien  return 0;
56350397Sobrien}
56450397Sobrien
56550397Sobrien/* INSN is a copy of SRC to DEST, in which SRC dies.  See if we now have
56650397Sobrien   a sequence of insns that modify DEST followed by an insn that sets
56750397Sobrien   SRC to DEST in which DEST dies, with no prior modification of DEST.
56850397Sobrien   (There is no need to check if the insns in between actually modify
56950397Sobrien   DEST.  We should not have cases where DEST is not modified, but
57050397Sobrien   the optimization is safe if no such modification is detected.)
57150397Sobrien   In that case, we can replace all uses of DEST, starting with INSN and
57250397Sobrien   ending with the set of SRC to DEST, with SRC.  We do not do this
57350397Sobrien   optimization if a CALL_INSN is crossed unless SRC already crosses a
57450397Sobrien   call or if DEST dies before the copy back to SRC.
57550397Sobrien
57650397Sobrien   It is assumed that DEST and SRC are pseudos; it is too complicated to do
57750397Sobrien   this for hard registers since the substitutions we may make might fail.  */
57850397Sobrien
57950397Sobrienstatic void
58050397Sobrienoptimize_reg_copy_2 (insn, dest, src)
58150397Sobrien     rtx insn;
58250397Sobrien     rtx dest;
58350397Sobrien     rtx src;
58450397Sobrien{
58550397Sobrien  rtx p, q;
58650397Sobrien  rtx set;
58750397Sobrien  int sregno = REGNO (src);
58850397Sobrien  int dregno = REGNO (dest);
58950397Sobrien
59050397Sobrien  for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
59150397Sobrien    {
59250397Sobrien      if (GET_CODE (p) == CODE_LABEL || GET_CODE (p) == JUMP_INSN
59350397Sobrien	  || (GET_CODE (p) == NOTE
59450397Sobrien	      && (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_BEG
59550397Sobrien		  || NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)))
59650397Sobrien	break;
59750397Sobrien
59850397Sobrien      /* ??? We can't scan past the end of a basic block without updating
59950397Sobrien	 the register lifetime info (REG_DEAD/basic_block_live_at_start).
60050397Sobrien	 A CALL_INSN might be the last insn of a basic block, if it is inside
60150397Sobrien	 an EH region.  There is no easy way to tell, so we just always break
60250397Sobrien	 when we see a CALL_INSN if flag_exceptions is nonzero.  */
60350397Sobrien      if (flag_exceptions && GET_CODE (p) == CALL_INSN)
60450397Sobrien	break;
60550397Sobrien
60650397Sobrien      if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
60750397Sobrien	continue;
60850397Sobrien
60950397Sobrien      set = single_set (p);
61050397Sobrien      if (set && SET_SRC (set) == dest && SET_DEST (set) == src
61150397Sobrien	  && find_reg_note (p, REG_DEAD, dest))
61250397Sobrien	{
61350397Sobrien	  /* We can do the optimization.  Scan forward from INSN again,
61450397Sobrien	     replacing regs as we go.  */
61550397Sobrien
61650397Sobrien	  /* Set to stop at next insn.  */
61750397Sobrien	  for (q = insn; q != NEXT_INSN (p); q = NEXT_INSN (q))
61850397Sobrien	    if (GET_RTX_CLASS (GET_CODE (q)) == 'i')
61950397Sobrien	      {
62050397Sobrien		if (reg_mentioned_p (dest, PATTERN (q)))
62150397Sobrien		  {
62250397Sobrien		    PATTERN (q) = replace_rtx (PATTERN (q), dest, src);
62350397Sobrien
62450397Sobrien		    /* We assume that a register is used exactly once per
62550397Sobrien		       insn in the updates below.  If this is not correct,
62650397Sobrien		       no great harm is done.  */
62750397Sobrien		    REG_N_REFS (dregno) -= loop_depth;
62850397Sobrien		    REG_N_REFS (sregno) += loop_depth;
62950397Sobrien		  }
63050397Sobrien
63150397Sobrien
63250397Sobrien	      if (GET_CODE (q) == CALL_INSN)
63350397Sobrien		{
63450397Sobrien		  REG_N_CALLS_CROSSED (dregno)--;
63550397Sobrien		  REG_N_CALLS_CROSSED (sregno)++;
63650397Sobrien		}
63750397Sobrien	      }
63850397Sobrien
63950397Sobrien	  remove_note (p, find_reg_note (p, REG_DEAD, dest));
64050397Sobrien	  REG_N_DEATHS (dregno)--;
64150397Sobrien	  remove_note (insn, find_reg_note (insn, REG_DEAD, src));
64250397Sobrien	  REG_N_DEATHS (sregno)--;
64350397Sobrien	  return;
64450397Sobrien	}
64550397Sobrien
64650397Sobrien      if (reg_set_p (src, p)
64750397Sobrien	  || find_reg_note (p, REG_DEAD, dest)
64850397Sobrien	  || (GET_CODE (p) == CALL_INSN && REG_N_CALLS_CROSSED (sregno) == 0))
64950397Sobrien	break;
65050397Sobrien    }
65150397Sobrien}
65250397Sobrien/* INSN is a ZERO_EXTEND or SIGN_EXTEND of SRC to DEST.
65350397Sobrien   Look if SRC dies there, and if it is only set once, by loading
65450397Sobrien   it from memory.  If so, try to encorporate the zero/sign extension
65550397Sobrien   into the memory read, change SRC to the mode of DEST, and alter
65650397Sobrien   the remaining accesses to use the appropriate SUBREG.  This allows
65750397Sobrien   SRC and DEST to be tied later.  */
65850397Sobrienstatic void
65950397Sobrienoptimize_reg_copy_3 (insn, dest, src)
66050397Sobrien     rtx insn;
66150397Sobrien     rtx dest;
66250397Sobrien     rtx src;
66350397Sobrien{
66450397Sobrien  rtx src_reg = XEXP (src, 0);
66550397Sobrien  int src_no = REGNO (src_reg);
66650397Sobrien  int dst_no = REGNO (dest);
66750397Sobrien  rtx p, set, subreg;
66850397Sobrien  enum machine_mode old_mode;
66950397Sobrien
67050397Sobrien  if (src_no < FIRST_PSEUDO_REGISTER
67150397Sobrien      || dst_no < FIRST_PSEUDO_REGISTER
67250397Sobrien      || ! find_reg_note (insn, REG_DEAD, src_reg)
67350397Sobrien      || REG_N_SETS (src_no) != 1)
67450397Sobrien    return;
67550397Sobrien  for (p = PREV_INSN (insn); ! reg_set_p (src_reg, p); p = PREV_INSN (p))
67650397Sobrien    {
67750397Sobrien      if (GET_CODE (p) == CODE_LABEL || GET_CODE (p) == JUMP_INSN
67850397Sobrien	  || (GET_CODE (p) == NOTE
67950397Sobrien	      && (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_BEG
68050397Sobrien		  || NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)))
68150397Sobrien	return;
68250397Sobrien
68350397Sobrien      /* ??? We can't scan past the end of a basic block without updating
68450397Sobrien	 the register lifetime info (REG_DEAD/basic_block_live_at_start).
68550397Sobrien	 A CALL_INSN might be the last insn of a basic block, if it is inside
68650397Sobrien	 an EH region.  There is no easy way to tell, so we just always break
68750397Sobrien	 when we see a CALL_INSN if flag_exceptions is nonzero.  */
68850397Sobrien      if (flag_exceptions && GET_CODE (p) == CALL_INSN)
68950397Sobrien	return;
69050397Sobrien
69150397Sobrien      if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
69250397Sobrien	continue;
69350397Sobrien    }
69450397Sobrien  if (! (set = single_set (p))
69550397Sobrien      || GET_CODE (SET_SRC (set)) != MEM
69650397Sobrien      || SET_DEST (set) != src_reg)
69750397Sobrien    return;
69852284Sobrien
69952284Sobrien  /* Be conserative: although this optimization is also valid for
70052284Sobrien     volatile memory references, that could cause trouble in later passes.  */
70152284Sobrien  if (MEM_VOLATILE_P (SET_SRC (set)))
70252284Sobrien    return;
70352284Sobrien
70452284Sobrien  /* Do not use a SUBREG to truncate from one mode to another if truncation
70552284Sobrien     is not a nop.  */
70652284Sobrien  if (GET_MODE_BITSIZE (GET_MODE (src_reg)) <= GET_MODE_BITSIZE (GET_MODE (src))
70752284Sobrien      && !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (src)),
70852284Sobrien				 GET_MODE_BITSIZE (GET_MODE (src_reg))))
70952284Sobrien    return;
71052284Sobrien
71150397Sobrien  old_mode = GET_MODE (src_reg);
71250397Sobrien  PUT_MODE (src_reg, GET_MODE (src));
71350397Sobrien  XEXP (src, 0) = SET_SRC (set);
71452284Sobrien
71552284Sobrien  /* Include this change in the group so that it's easily undone if
71652284Sobrien     one of the changes in the group is invalid.  */
71752284Sobrien  validate_change (p, &SET_SRC (set), src, 1);
71852284Sobrien
71952284Sobrien  /* Now walk forward making additional replacements.  We want to be able
72052284Sobrien     to undo all the changes if a later substitution fails.  */
72150397Sobrien  subreg = gen_rtx_SUBREG (old_mode, src_reg, 0);
72250397Sobrien  while (p = NEXT_INSN (p), p != insn)
72350397Sobrien    {
72450397Sobrien      if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
72550397Sobrien	continue;
72652284Sobrien
72752284Sobrien      /* Make a tenative change.  */
72852284Sobrien      validate_replace_rtx_group (src_reg, subreg, p);
72950397Sobrien    }
73052284Sobrien
73152284Sobrien  validate_replace_rtx_group (src, src_reg, insn);
73252284Sobrien
73352284Sobrien  /* Now see if all the changes are valid.  */
73452284Sobrien  if (! apply_change_group ())
73552284Sobrien    {
73652284Sobrien      /* One or more changes were no good.  Back out everything.  */
73752284Sobrien      PUT_MODE (src_reg, old_mode);
73852284Sobrien      XEXP (src, 0) = src_reg;
73952284Sobrien    }
74050397Sobrien}
74150397Sobrien
74250397Sobrien
74350397Sobrien/* If we were not able to update the users of src to use dest directly, try
74450397Sobrien   instead moving the value to dest directly before the operation.  */
74550397Sobrien
74650397Sobrienstatic void
74752284Sobriencopy_src_to_dest (insn, src, dest, loop_depth, old_max_uid)
74850397Sobrien     rtx insn;
74950397Sobrien     rtx src;
75050397Sobrien     rtx dest;
75150397Sobrien     int loop_depth;
75252284Sobrien     int old_max_uid;
75350397Sobrien{
75450397Sobrien  rtx seq;
75550397Sobrien  rtx link;
75650397Sobrien  rtx next;
75750397Sobrien  rtx set;
75850397Sobrien  rtx move_insn;
75950397Sobrien  rtx *p_insn_notes;
76050397Sobrien  rtx *p_move_notes;
76150397Sobrien  int src_regno;
76250397Sobrien  int dest_regno;
76350397Sobrien  int bb;
76450397Sobrien  int insn_uid;
76550397Sobrien  int move_uid;
76650397Sobrien
76750397Sobrien  /* A REG_LIVE_LENGTH of -1 indicates the register is equivalent to a constant
76850397Sobrien     or memory location and is used infrequently; a REG_LIVE_LENGTH of -2 is
76950397Sobrien     parameter when there is no frame pointer that is not allocated a register.
77050397Sobrien     For now, we just reject them, rather than incrementing the live length.  */
77150397Sobrien
77250397Sobrien  if (GET_CODE (src) == REG
77350397Sobrien      && REG_LIVE_LENGTH (REGNO (src)) > 0
77450397Sobrien      && GET_CODE (dest) == REG
77550397Sobrien      && REG_LIVE_LENGTH (REGNO (dest)) > 0
77650397Sobrien      && (set = single_set (insn)) != NULL_RTX
77750397Sobrien      && !reg_mentioned_p (dest, SET_SRC (set))
77852284Sobrien      && GET_MODE (src) == GET_MODE (dest))
77950397Sobrien    {
78052284Sobrien      int old_num_regs = reg_rtx_no;
78152284Sobrien
78250397Sobrien      /* Generate the src->dest move.  */
78350397Sobrien      start_sequence ();
78450397Sobrien      emit_move_insn (dest, src);
78550397Sobrien      seq = gen_sequence ();
78650397Sobrien      end_sequence ();
78752284Sobrien      /* If this sequence uses new registers, we may not use it.  */
78852284Sobrien      if (old_num_regs != reg_rtx_no
78952284Sobrien	  || ! validate_replace_rtx (src, dest, insn))
79052284Sobrien	{
79152284Sobrien	  /* We have to restore reg_rtx_no to its old value, lest
79252284Sobrien	     recompute_reg_usage will try to compute the usage of the
79352284Sobrien	     new regs, yet reg_n_info is not valid for them.  */
79452284Sobrien	  reg_rtx_no = old_num_regs;
79552284Sobrien	  return;
79652284Sobrien	}
79750397Sobrien      emit_insn_before (seq, insn);
79850397Sobrien      move_insn = PREV_INSN (insn);
79950397Sobrien      p_move_notes = &REG_NOTES (move_insn);
80050397Sobrien      p_insn_notes = &REG_NOTES (insn);
80150397Sobrien
80250397Sobrien      /* Move any notes mentioning src to the move instruction */
80350397Sobrien      for (link = REG_NOTES (insn); link != NULL_RTX; link = next)
80450397Sobrien	{
80550397Sobrien	  next = XEXP (link, 1);
80650397Sobrien	  if (XEXP (link, 0) == src)
80750397Sobrien	    {
80850397Sobrien	      *p_move_notes = link;
80950397Sobrien	      p_move_notes = &XEXP (link, 1);
81050397Sobrien	    }
81150397Sobrien	  else
81250397Sobrien	    {
81350397Sobrien	      *p_insn_notes = link;
81450397Sobrien	      p_insn_notes = &XEXP (link, 1);
81550397Sobrien	    }
81650397Sobrien	}
81750397Sobrien
81850397Sobrien      *p_move_notes = NULL_RTX;
81950397Sobrien      *p_insn_notes = NULL_RTX;
82050397Sobrien
82150397Sobrien      /* Is the insn the head of a basic block?  If so extend it */
82250397Sobrien      insn_uid = INSN_UID (insn);
82350397Sobrien      move_uid = INSN_UID (move_insn);
82452284Sobrien      if (insn_uid < old_max_uid)
82550397Sobrien	{
82652284Sobrien	  bb = regmove_bb_head[insn_uid];
82752284Sobrien	  if (bb >= 0)
82852284Sobrien	    {
82952284Sobrien	      BLOCK_HEAD (bb) = move_insn;
83052284Sobrien	      regmove_bb_head[insn_uid] = -1;
83152284Sobrien	    }
83250397Sobrien	}
83350397Sobrien
83450397Sobrien      /* Update the various register tables.  */
83550397Sobrien      dest_regno = REGNO (dest);
83650397Sobrien      REG_N_SETS (dest_regno) += loop_depth;
83750397Sobrien      REG_N_REFS (dest_regno) += loop_depth;
83850397Sobrien      REG_LIVE_LENGTH (dest_regno)++;
83950397Sobrien      if (REGNO_FIRST_UID (dest_regno) == insn_uid)
84050397Sobrien	REGNO_FIRST_UID (dest_regno) = move_uid;
84150397Sobrien
84250397Sobrien      src_regno = REGNO (src);
84350397Sobrien      if (! find_reg_note (move_insn, REG_DEAD, src))
84450397Sobrien	REG_LIVE_LENGTH (src_regno)++;
84550397Sobrien
84650397Sobrien      if (REGNO_FIRST_UID (src_regno) == insn_uid)
84750397Sobrien	REGNO_FIRST_UID (src_regno) = move_uid;
84850397Sobrien
84950397Sobrien      if (REGNO_LAST_UID (src_regno) == insn_uid)
85050397Sobrien	REGNO_LAST_UID (src_regno) = move_uid;
85150397Sobrien
85250397Sobrien      if (REGNO_LAST_NOTE_UID (src_regno) == insn_uid)
85350397Sobrien	REGNO_LAST_NOTE_UID (src_regno) = move_uid;
85450397Sobrien    }
85550397Sobrien}
85650397Sobrien
85750397Sobrien
85850397Sobrien/* Return whether REG is set in only one location, and is set to a
85950397Sobrien   constant, but is set in a different basic block from INSN (an
86050397Sobrien   instructions which uses REG).  In this case REG is equivalent to a
86150397Sobrien   constant, and we don't want to break that equivalence, because that
86250397Sobrien   may increase register pressure and make reload harder.  If REG is
86350397Sobrien   set in the same basic block as INSN, we don't worry about it,
86450397Sobrien   because we'll probably need a register anyhow (??? but what if REG
86550397Sobrien   is used in a different basic block as well as this one?).  FIRST is
86650397Sobrien   the first insn in the function.  */
86750397Sobrien
86850397Sobrienstatic int
86950397Sobrienreg_is_remote_constant_p (reg, insn, first)
87050397Sobrien     rtx reg;
87150397Sobrien     rtx insn;
87250397Sobrien     rtx first;
87350397Sobrien{
87450397Sobrien  register rtx p;
87550397Sobrien
87650397Sobrien  if (REG_N_SETS (REGNO (reg)) != 1)
87750397Sobrien    return 0;
87850397Sobrien
87950397Sobrien  /* Look for the set.  */
88050397Sobrien  for (p = LOG_LINKS (insn); p; p = XEXP (p, 1))
88150397Sobrien    {
88250397Sobrien      rtx s;
88350397Sobrien
88450397Sobrien      if (REG_NOTE_KIND (p) != 0)
88550397Sobrien	continue;
88650397Sobrien      s = single_set (XEXP (p, 0));
88750397Sobrien      if (s != 0
88850397Sobrien	  && GET_CODE (SET_DEST (s)) == REG
88950397Sobrien	  && REGNO (SET_DEST (s)) == REGNO (reg))
89050397Sobrien	{
89150397Sobrien	  /* The register is set in the same basic block.  */
89250397Sobrien	  return 0;
89350397Sobrien	}
89450397Sobrien    }
89550397Sobrien
89650397Sobrien  for (p = first; p && p != insn; p = NEXT_INSN (p))
89750397Sobrien    {
89850397Sobrien      rtx s;
89950397Sobrien
90050397Sobrien      if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
90150397Sobrien	continue;
90250397Sobrien      s = single_set (p);
90350397Sobrien      if (s != 0
90450397Sobrien	  && GET_CODE (SET_DEST (s)) == REG
90550397Sobrien	  && REGNO (SET_DEST (s)) == REGNO (reg))
90650397Sobrien	{
90750397Sobrien	  /* This is the instruction which sets REG.  If there is a
90850397Sobrien             REG_EQUAL note, then REG is equivalent to a constant.  */
90950397Sobrien	  if (find_reg_note (p, REG_EQUAL, NULL_RTX))
91050397Sobrien	    return 1;
91150397Sobrien	  return 0;
91250397Sobrien	}
91350397Sobrien    }
91450397Sobrien
91550397Sobrien  return 0;
91650397Sobrien}
91750397Sobrien
91850397Sobrien/* INSN is adding a CONST_INT to a REG.  We search backwards looking for
91950397Sobrien   another add immediate instruction with the same source and dest registers,
92050397Sobrien   and if we find one, we change INSN to an increment, and return 1.  If
92150397Sobrien   no changes are made, we return 0.
92250397Sobrien
92350397Sobrien   This changes
92450397Sobrien     (set (reg100) (plus reg1 offset1))
92550397Sobrien     ...
92650397Sobrien     (set (reg100) (plus reg1 offset2))
92750397Sobrien   to
92850397Sobrien     (set (reg100) (plus reg1 offset1))
92950397Sobrien     ...
93050397Sobrien     (set (reg100) (plus reg100 offset2-offset1))  */
93150397Sobrien
93250397Sobrien/* ??? What does this comment mean?  */
93350397Sobrien/* cse disrupts preincrement / postdecrement squences when it finds a
93450397Sobrien   hard register as ultimate source, like the frame pointer.  */
93550397Sobrien
93650397Sobrienint
93750397Sobrienfixup_match_2 (insn, dst, src, offset, regmove_dump_file)
93850397Sobrien     rtx insn, dst, src, offset;
93950397Sobrien     FILE *regmove_dump_file;
94050397Sobrien{
94150397Sobrien  rtx p, dst_death = 0;
94250397Sobrien  int length, num_calls = 0;
94350397Sobrien
94450397Sobrien  /* If SRC dies in INSN, we'd have to move the death note.  This is
94550397Sobrien     considered to be very unlikely, so we just skip the optimization
94650397Sobrien     in this case.  */
94750397Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (src)))
94850397Sobrien    return 0;
94950397Sobrien
95050397Sobrien  /* Scan backward to find the first instruction that sets DST.  */
95150397Sobrien
95250397Sobrien  for (length = 0, p = PREV_INSN (insn); p; p = PREV_INSN (p))
95350397Sobrien    {
95450397Sobrien      rtx pset;
95550397Sobrien
95650397Sobrien      if (GET_CODE (p) == CODE_LABEL
95750397Sobrien          || GET_CODE (p) == JUMP_INSN
95850397Sobrien          || (GET_CODE (p) == NOTE
95950397Sobrien              && (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_BEG
96050397Sobrien                  || NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)))
96150397Sobrien        break;
96250397Sobrien
96350397Sobrien      /* ??? We can't scan past the end of a basic block without updating
96450397Sobrien	 the register lifetime info (REG_DEAD/basic_block_live_at_start).
96550397Sobrien	 A CALL_INSN might be the last insn of a basic block, if it is inside
96650397Sobrien	 an EH region.  There is no easy way to tell, so we just always break
96750397Sobrien	 when we see a CALL_INSN if flag_exceptions is nonzero.  */
96850397Sobrien      if (flag_exceptions && GET_CODE (p) == CALL_INSN)
96950397Sobrien	break;
97050397Sobrien
97150397Sobrien      if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
97250397Sobrien        continue;
97350397Sobrien
97450397Sobrien      if (find_regno_note (p, REG_DEAD, REGNO (dst)))
97550397Sobrien	dst_death = p;
97650397Sobrien      if (! dst_death)
97750397Sobrien	length++;
97850397Sobrien
97950397Sobrien      pset = single_set (p);
98050397Sobrien      if (pset && SET_DEST (pset) == dst
98150397Sobrien	  && GET_CODE (SET_SRC (pset)) == PLUS
98250397Sobrien	  && XEXP (SET_SRC (pset), 0) == src
98350397Sobrien	  && GET_CODE (XEXP (SET_SRC (pset), 1)) == CONST_INT)
98450397Sobrien        {
98550397Sobrien	  HOST_WIDE_INT newconst
98650397Sobrien	    = INTVAL (offset) - INTVAL (XEXP (SET_SRC (pset), 1));
98750397Sobrien	  rtx add = gen_add3_insn (dst, dst, GEN_INT (newconst));
98850397Sobrien
98950397Sobrien	  if (add && validate_change (insn, &PATTERN (insn), add, 0))
99050397Sobrien	    {
99150397Sobrien	      /* Remove the death note for DST from DST_DEATH.  */
99250397Sobrien	      if (dst_death)
99350397Sobrien		{
99450397Sobrien		  remove_death (REGNO (dst), dst_death);
99550397Sobrien		  REG_LIVE_LENGTH (REGNO (dst)) += length;
99650397Sobrien		  REG_N_CALLS_CROSSED (REGNO (dst)) += num_calls;
99750397Sobrien		}
99850397Sobrien
99950397Sobrien	      REG_N_REFS (REGNO (dst)) += loop_depth;
100050397Sobrien	      REG_N_REFS (REGNO (src)) -= loop_depth;
100150397Sobrien
100250397Sobrien	      if (regmove_dump_file)
100350397Sobrien		fprintf (regmove_dump_file,
100450397Sobrien			 "Fixed operand of insn %d.\n",
100550397Sobrien			  INSN_UID (insn));
100650397Sobrien
100750397Sobrien#ifdef AUTO_INC_DEC
100850397Sobrien	      for (p = PREV_INSN (insn); p; p = PREV_INSN (p))
100950397Sobrien		{
101050397Sobrien		  if (GET_CODE (p) == CODE_LABEL
101150397Sobrien		      || GET_CODE (p) == JUMP_INSN
101250397Sobrien		      || (GET_CODE (p) == NOTE
101350397Sobrien			  && (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_BEG
101450397Sobrien			      || NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)))
101550397Sobrien		    break;
101650397Sobrien		  if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
101750397Sobrien		    continue;
101850397Sobrien		  if (reg_overlap_mentioned_p (dst, PATTERN (p)))
101950397Sobrien		    {
102050397Sobrien		      if (try_auto_increment (p, insn, 0, dst, newconst, 0))
102150397Sobrien			return 1;
102250397Sobrien		      break;
102350397Sobrien		    }
102450397Sobrien		}
102550397Sobrien	      for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
102650397Sobrien		{
102750397Sobrien		  if (GET_CODE (p) == CODE_LABEL
102850397Sobrien		      || GET_CODE (p) == JUMP_INSN
102950397Sobrien		      || (GET_CODE (p) == NOTE
103050397Sobrien			  && (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_BEG
103150397Sobrien			      || NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)))
103250397Sobrien		    break;
103350397Sobrien		  if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
103450397Sobrien		    continue;
103550397Sobrien		  if (reg_overlap_mentioned_p (dst, PATTERN (p)))
103650397Sobrien		    {
103750397Sobrien		      try_auto_increment (p, insn, 0, dst, newconst, 1);
103850397Sobrien		      break;
103950397Sobrien		    }
104050397Sobrien		}
104150397Sobrien#endif
104250397Sobrien	      return 1;
104350397Sobrien	    }
104450397Sobrien        }
104550397Sobrien
104650397Sobrien      if (reg_set_p (dst, PATTERN (p)))
104750397Sobrien        break;
104850397Sobrien
104950397Sobrien      /* If we have passed a call instruction, and the
105050397Sobrien         pseudo-reg SRC is not already live across a call,
105150397Sobrien         then don't perform the optimization.  */
105250397Sobrien      /* reg_set_p is overly conservative for CALL_INSNS, thinks that all
105350397Sobrien	 hard regs are clobbered.  Thus, we only use it for src for
105450397Sobrien	 non-call insns.  */
105550397Sobrien      if (GET_CODE (p) == CALL_INSN)
105650397Sobrien        {
105750397Sobrien	  if (! dst_death)
105850397Sobrien	    num_calls++;
105950397Sobrien
106050397Sobrien          if (REG_N_CALLS_CROSSED (REGNO (src)) == 0)
106150397Sobrien            break;
106250397Sobrien
106350397Sobrien	  if (call_used_regs [REGNO (dst)]
106450397Sobrien	      || find_reg_fusage (p, CLOBBER, dst))
106550397Sobrien	    break;
106650397Sobrien        }
106750397Sobrien      else if (reg_set_p (src, PATTERN (p)))
106850397Sobrien        break;
106950397Sobrien    }
107050397Sobrien
107150397Sobrien  return 0;
107250397Sobrien}
107350397Sobrien
107450397Sobrienvoid
107550397Sobrienregmove_optimize (f, nregs, regmove_dump_file)
107650397Sobrien     rtx f;
107750397Sobrien     int nregs;
107850397Sobrien     FILE *regmove_dump_file;
107950397Sobrien{
108052284Sobrien  int old_max_uid = get_max_uid ();
108150397Sobrien  rtx insn;
108250397Sobrien  struct match match;
108350397Sobrien  int pass;
108452284Sobrien  int i;
108550397Sobrien  rtx copy_src, copy_dst;
108650397Sobrien
108752284Sobrien  /* Find out where a potential flags register is live, and so that we
108852284Sobrien     can supress some optimizations in those zones.  */
108952284Sobrien  mark_flags_life_zones (discover_flags_reg ());
109050397Sobrien
109152284Sobrien  regno_src_regno = (int *)alloca (sizeof *regno_src_regno * nregs);
109252284Sobrien  for (i = nregs; --i >= 0; ) regno_src_regno[i] = -1;
109352284Sobrien
109452284Sobrien  regmove_bb_head = (int *)alloca (sizeof (int) * (old_max_uid + 1));
109552284Sobrien  for (i = old_max_uid; i >= 0; i--) regmove_bb_head[i] = -1;
109650397Sobrien  for (i = 0; i < n_basic_blocks; i++)
109752284Sobrien    regmove_bb_head[INSN_UID (BLOCK_HEAD (i))] = i;
109850397Sobrien
109950397Sobrien  /* A forward/backward pass.  Replace output operands with input operands.  */
110050397Sobrien
110150397Sobrien  loop_depth = 1;
110250397Sobrien
110350397Sobrien  for (pass = 0; pass <= 2; pass++)
110450397Sobrien    {
110550397Sobrien      if (! flag_regmove && pass >= flag_expensive_optimizations)
110650397Sobrien	return;
110750397Sobrien
110850397Sobrien      if (regmove_dump_file)
110950397Sobrien	fprintf (regmove_dump_file, "Starting %s pass...\n",
111050397Sobrien		 pass ? "backward" : "forward");
111150397Sobrien
111250397Sobrien      for (insn = pass ? get_last_insn () : f; insn;
111350397Sobrien	   insn = pass ? PREV_INSN (insn) : NEXT_INSN (insn))
111450397Sobrien	{
111550397Sobrien	  rtx set;
111652284Sobrien	  int op_no, match_no;
111750397Sobrien
111850397Sobrien	  if (GET_CODE (insn) == NOTE)
111950397Sobrien	    {
112050397Sobrien	      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
112150397Sobrien		loop_depth++;
112250397Sobrien	      else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
112350397Sobrien		loop_depth--;
112450397Sobrien	    }
112550397Sobrien
112650397Sobrien	  set = single_set (insn);
112750397Sobrien	  if (! set)
112850397Sobrien	    continue;
112950397Sobrien
113050397Sobrien	  if (flag_expensive_optimizations && ! pass
113150397Sobrien	      && (GET_CODE (SET_SRC (set)) == SIGN_EXTEND
113250397Sobrien		  || GET_CODE (SET_SRC (set)) == ZERO_EXTEND)
113350397Sobrien	      && GET_CODE (XEXP (SET_SRC (set), 0)) == REG
113450397Sobrien	      && GET_CODE (SET_DEST(set)) == REG)
113550397Sobrien	    optimize_reg_copy_3 (insn, SET_DEST (set), SET_SRC (set));
113650397Sobrien
113750397Sobrien	  if (flag_expensive_optimizations && ! pass
113850397Sobrien	      && GET_CODE (SET_SRC (set)) == REG
113950397Sobrien	      && GET_CODE (SET_DEST(set)) == REG)
114050397Sobrien	    {
114150397Sobrien	      /* If this is a register-register copy where SRC is not dead,
114250397Sobrien		 see if we can optimize it.  If this optimization succeeds,
114350397Sobrien		 it will become a copy where SRC is dead.  */
114450397Sobrien	      if ((find_reg_note (insn, REG_DEAD, SET_SRC (set))
114550397Sobrien		   || optimize_reg_copy_1 (insn, SET_DEST (set), SET_SRC (set)))
114650397Sobrien		  && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
114750397Sobrien		{
114850397Sobrien		  /* Similarly for a pseudo-pseudo copy when SRC is dead.  */
114950397Sobrien		  if (REGNO (SET_SRC (set)) >= FIRST_PSEUDO_REGISTER)
115050397Sobrien		    optimize_reg_copy_2 (insn, SET_DEST (set), SET_SRC (set));
115150397Sobrien		  if (regno_src_regno[REGNO (SET_DEST (set))] < 0
115250397Sobrien		      && SET_SRC (set) != SET_DEST (set))
115350397Sobrien		    {
115450397Sobrien		      int srcregno = REGNO (SET_SRC(set));
115550397Sobrien		      if (regno_src_regno[srcregno] >= 0)
115650397Sobrien			srcregno = regno_src_regno[srcregno];
115750397Sobrien		      regno_src_regno[REGNO (SET_DEST (set))] = srcregno;
115850397Sobrien		    }
115950397Sobrien		}
116050397Sobrien	    }
116152284Sobrien          if (! flag_regmove)
116252284Sobrien            continue;
116352284Sobrien
116450397Sobrien#ifdef REGISTER_CONSTRAINTS
116552284Sobrien	  if (! find_matches (insn, &match))
116650397Sobrien	    continue;
116750397Sobrien
116850397Sobrien	  /* Now scan through the operands looking for a source operand
116950397Sobrien	     which is supposed to match the destination operand.
117050397Sobrien	     Then scan forward for an instruction which uses the dest
117150397Sobrien	     operand.
117250397Sobrien	     If it dies there, then replace the dest in both operands with
117350397Sobrien	     the source operand.  */
117450397Sobrien
117552284Sobrien	  for (op_no = 0; op_no < recog_n_operands; op_no++)
117650397Sobrien	    {
117750397Sobrien	      rtx src, dst, src_subreg;
117850397Sobrien	      enum reg_class src_class, dst_class;
117950397Sobrien
118052284Sobrien	      match_no = match.with[op_no];
118150397Sobrien
118250397Sobrien	      /* Nothing to do if the two operands aren't supposed to match.  */
118352284Sobrien	      if (match_no < 0)
118450397Sobrien		continue;
118550397Sobrien
118652284Sobrien	      src = recog_operand[op_no];
118752284Sobrien	      dst = recog_operand[match_no];
118850397Sobrien
118950397Sobrien	      if (GET_CODE (src) != REG)
119050397Sobrien		continue;
119150397Sobrien
119250397Sobrien	      src_subreg = src;
119350397Sobrien	      if (GET_CODE (dst) == SUBREG
119450397Sobrien		  && GET_MODE_SIZE (GET_MODE (dst))
119550397Sobrien		     >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (dst))))
119650397Sobrien		{
119750397Sobrien		  src_subreg
119850397Sobrien		    = gen_rtx_SUBREG (GET_MODE (SUBREG_REG (dst)),
119950397Sobrien				      src, SUBREG_WORD (dst));
120050397Sobrien		  dst = SUBREG_REG (dst);
120150397Sobrien		}
120250397Sobrien	      if (GET_CODE (dst) != REG
120350397Sobrien		  || REGNO (dst) < FIRST_PSEUDO_REGISTER)
120450397Sobrien		continue;
120550397Sobrien
120650397Sobrien	      if (REGNO (src) < FIRST_PSEUDO_REGISTER)
120750397Sobrien		{
120852284Sobrien		  if (match.commutative[op_no] < op_no)
120950397Sobrien		    regno_src_regno[REGNO (dst)] = REGNO (src);
121050397Sobrien		  continue;
121150397Sobrien		}
121250397Sobrien
121350397Sobrien	      if (REG_LIVE_LENGTH (REGNO (src)) < 0)
121450397Sobrien		continue;
121550397Sobrien
121652284Sobrien	      /* op_no/src must be a read-only operand, and
121750397Sobrien		 match_operand/dst must be a write-only operand.  */
121852284Sobrien	      if (match.use[op_no] != READ
121952284Sobrien		  || match.use[match_no] != WRITE)
122050397Sobrien		continue;
122150397Sobrien
122252284Sobrien	      if (match.early_clobber[match_no]
122350397Sobrien		  && count_occurrences (PATTERN (insn), src) > 1)
122450397Sobrien		continue;
122550397Sobrien
122650397Sobrien	      /* Make sure match_operand is the destination.  */
122752284Sobrien	      if (recog_operand[match_no] != SET_DEST (set))
122850397Sobrien		continue;
122950397Sobrien
123050397Sobrien	      /* If the operands already match, then there is nothing to do.  */
123150397Sobrien	      /* But in the commutative case, we might find a better match.  */
123250397Sobrien	      if (operands_match_p (src, dst)
123352284Sobrien		  || (match.commutative[op_no] >= 0
123450397Sobrien		      && operands_match_p (recog_operand[match.commutative
123552284Sobrien							 [op_no]], dst)
123650397Sobrien		      && (replacement_quality (recog_operand[match.commutative
123752284Sobrien							     [op_no]])
123850397Sobrien			  >= replacement_quality (src))))
123950397Sobrien		continue;
124050397Sobrien
124150397Sobrien	      src_class = reg_preferred_class (REGNO (src));
124250397Sobrien	      dst_class = reg_preferred_class (REGNO (dst));
124352284Sobrien	      if (! regclass_compatible_p (src_class, dst_class))
124450397Sobrien		continue;
124550397Sobrien
124650397Sobrien	      if (fixup_match_1 (insn, set, src, src_subreg, dst, pass,
124752284Sobrien				 op_no, match_no,
124850397Sobrien				 regmove_dump_file))
124950397Sobrien		break;
125050397Sobrien	    }
125150397Sobrien	}
125250397Sobrien    }
125350397Sobrien
125450397Sobrien  /* A backward pass.  Replace input operands with output operands.  */
125550397Sobrien
125650397Sobrien  if (regmove_dump_file)
125750397Sobrien    fprintf (regmove_dump_file, "Starting backward pass...\n");
125850397Sobrien
125950397Sobrien  loop_depth = 1;
126050397Sobrien
126150397Sobrien  for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
126250397Sobrien    {
126350397Sobrien      if (GET_CODE (insn) == NOTE)
126450397Sobrien	{
126550397Sobrien	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
126650397Sobrien	    loop_depth++;
126750397Sobrien	  else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
126850397Sobrien	    loop_depth--;
126950397Sobrien	}
127050397Sobrien      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
127150397Sobrien	{
127252284Sobrien	  int op_no, match_no;
127350397Sobrien	  int success = 0;
127452284Sobrien
127552284Sobrien	  if (! find_matches (insn, &match))
127650397Sobrien	    continue;
127750397Sobrien
127850397Sobrien	  /* Now scan through the operands looking for a destination operand
127950397Sobrien	     which is supposed to match a source operand.
128050397Sobrien	     Then scan backward for an instruction which sets the source
128150397Sobrien	     operand.  If safe, then replace the source operand with the
128250397Sobrien	     dest operand in both instructions.  */
128350397Sobrien
128450397Sobrien	  copy_src = NULL_RTX;
128550397Sobrien	  copy_dst = NULL_RTX;
128652284Sobrien	  for (op_no = 0; op_no < recog_n_operands; op_no++)
128750397Sobrien	    {
128850397Sobrien	      rtx set, p, src, dst;
128950397Sobrien	      rtx src_note, dst_note;
129050397Sobrien	      int num_calls = 0;
129150397Sobrien	      enum reg_class src_class, dst_class;
129250397Sobrien	      int length;
129350397Sobrien
129452284Sobrien	      match_no = match.with[op_no];
129550397Sobrien
129650397Sobrien	      /* Nothing to do if the two operands aren't supposed to match.  */
129752284Sobrien	      if (match_no < 0)
129850397Sobrien		continue;
129950397Sobrien
130052284Sobrien	      dst = recog_operand[match_no];
130152284Sobrien	      src = recog_operand[op_no];
130250397Sobrien
130350397Sobrien	      if (GET_CODE (src) != REG)
130450397Sobrien		continue;
130550397Sobrien
130650397Sobrien	      if (GET_CODE (dst) != REG
130750397Sobrien		  || REGNO (dst) < FIRST_PSEUDO_REGISTER
130850397Sobrien		  || REG_LIVE_LENGTH (REGNO (dst)) < 0)
130950397Sobrien		continue;
131050397Sobrien
131150397Sobrien	      /* If the operands already match, then there is nothing to do.  */
131250397Sobrien	      if (operands_match_p (src, dst)
131352284Sobrien		  || (match.commutative[op_no] >= 0
131452284Sobrien		      && operands_match_p (recog_operand[match.commutative[op_no]], dst)))
131550397Sobrien		continue;
131650397Sobrien
131750397Sobrien	      set = single_set (insn);
131850397Sobrien	      if (! set)
131950397Sobrien		continue;
132050397Sobrien
132152284Sobrien	      /* match_no/dst must be a write-only operand, and
132250397Sobrien		 operand_operand/src must be a read-only operand.  */
132352284Sobrien	      if (match.use[op_no] != READ
132452284Sobrien		  || match.use[match_no] != WRITE)
132550397Sobrien		continue;
132650397Sobrien
132752284Sobrien	      if (match.early_clobber[match_no]
132850397Sobrien		  && count_occurrences (PATTERN (insn), src) > 1)
132950397Sobrien		continue;
133050397Sobrien
133152284Sobrien	      /* Make sure match_no is the destination.  */
133252284Sobrien	      if (recog_operand[match_no] != SET_DEST (set))
133350397Sobrien		continue;
133450397Sobrien
133550397Sobrien	      if (REGNO (src) < FIRST_PSEUDO_REGISTER)
133650397Sobrien		{
133750397Sobrien		  if (GET_CODE (SET_SRC (set)) == PLUS
133850397Sobrien		      && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT
133950397Sobrien		      && XEXP (SET_SRC (set), 0) == src
134050397Sobrien		      && fixup_match_2 (insn, dst, src,
134150397Sobrien					XEXP (SET_SRC (set), 1),
134250397Sobrien					regmove_dump_file))
134350397Sobrien		    break;
134450397Sobrien		  continue;
134550397Sobrien		}
134650397Sobrien	      src_class = reg_preferred_class (REGNO (src));
134750397Sobrien	      dst_class = reg_preferred_class (REGNO (dst));
134852284Sobrien	      if (! regclass_compatible_p (src_class, dst_class))
134950397Sobrien		{
135050397Sobrien		  if (!copy_src)
135150397Sobrien		    {
135250397Sobrien		      copy_src = src;
135350397Sobrien		      copy_dst = dst;
135450397Sobrien		    }
135550397Sobrien		  continue;
135650397Sobrien		}
135750397Sobrien
135850397Sobrien	      /* Can not modify an earlier insn to set dst if this insn
135950397Sobrien		 uses an old value in the source.  */
136050397Sobrien	      if (reg_overlap_mentioned_p (dst, SET_SRC (set)))
136150397Sobrien		{
136250397Sobrien		  if (!copy_src)
136350397Sobrien		    {
136450397Sobrien		      copy_src = src;
136550397Sobrien		      copy_dst = dst;
136650397Sobrien		    }
136750397Sobrien		  continue;
136850397Sobrien		}
136950397Sobrien
137050397Sobrien	      if (! (src_note = find_reg_note (insn, REG_DEAD, src)))
137150397Sobrien		{
137250397Sobrien		  if (!copy_src)
137350397Sobrien		    {
137450397Sobrien		      copy_src = src;
137550397Sobrien		      copy_dst = dst;
137650397Sobrien		    }
137750397Sobrien		  continue;
137850397Sobrien		}
137950397Sobrien
138050397Sobrien
138150397Sobrien	      /* If src is set once in a different basic block,
138250397Sobrien		 and is set equal to a constant, then do not use
138350397Sobrien		 it for this optimization, as this would make it
138450397Sobrien		 no longer equivalent to a constant.  */
138550397Sobrien
138650397Sobrien              if (reg_is_remote_constant_p (src, insn, f))
138750397Sobrien		{
138850397Sobrien		  if (!copy_src)
138950397Sobrien		    {
139050397Sobrien		      copy_src = src;
139150397Sobrien		      copy_dst = dst;
139250397Sobrien		    }
139350397Sobrien		  continue;
139450397Sobrien		}
139550397Sobrien
139650397Sobrien
139750397Sobrien	      if (regmove_dump_file)
139850397Sobrien		fprintf (regmove_dump_file,
139950397Sobrien			 "Could fix operand %d of insn %d matching operand %d.\n",
140052284Sobrien			 op_no, INSN_UID (insn), match_no);
140150397Sobrien
140250397Sobrien	      /* Scan backward to find the first instruction that uses
140350397Sobrien		 the input operand.  If the operand is set here, then
140452284Sobrien		 replace it in both instructions with match_no.  */
140550397Sobrien
140650397Sobrien	      for (length = 0, p = PREV_INSN (insn); p; p = PREV_INSN (p))
140750397Sobrien		{
140850397Sobrien		  rtx pset;
140950397Sobrien
141050397Sobrien		  if (GET_CODE (p) == CODE_LABEL
141150397Sobrien		      || GET_CODE (p) == JUMP_INSN
141250397Sobrien		      || (GET_CODE (p) == NOTE
141350397Sobrien			  && (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_BEG
141450397Sobrien			      || NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)))
141550397Sobrien		    break;
141650397Sobrien
141750397Sobrien		  /* ??? We can't scan past the end of a basic block without
141850397Sobrien		     updating the register lifetime info
141950397Sobrien		     (REG_DEAD/basic_block_live_at_start).
142050397Sobrien		     A CALL_INSN might be the last insn of a basic block, if
142150397Sobrien		     it is inside an EH region.  There is no easy way to tell,
142250397Sobrien		     so we just always break when we see a CALL_INSN if
142350397Sobrien		     flag_exceptions is nonzero.  */
142450397Sobrien		  if (flag_exceptions && GET_CODE (p) == CALL_INSN)
142550397Sobrien		    break;
142650397Sobrien
142750397Sobrien		  if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
142850397Sobrien		    continue;
142950397Sobrien
143050397Sobrien		  length++;
143150397Sobrien
143250397Sobrien		  /* ??? See if all of SRC is set in P.  This test is much
143350397Sobrien		     more conservative than it needs to be.  */
143450397Sobrien		  pset = single_set (p);
143550397Sobrien		  if (pset && SET_DEST (pset) == src)
143650397Sobrien		    {
143750397Sobrien		      /* We use validate_replace_rtx, in case there
143850397Sobrien			 are multiple identical source operands.  All of
143950397Sobrien			 them have to be changed at the same time.  */
144050397Sobrien		      if (validate_replace_rtx (src, dst, insn))
144150397Sobrien			{
144250397Sobrien			  if (validate_change (p, &SET_DEST (pset),
144350397Sobrien					       dst, 0))
144450397Sobrien			    success = 1;
144550397Sobrien			  else
144650397Sobrien			    {
144750397Sobrien			      /* Change all source operands back.
144850397Sobrien				 This modifies the dst as a side-effect.  */
144950397Sobrien			      validate_replace_rtx (dst, src, insn);
145050397Sobrien			      /* Now make sure the dst is right.  */
145150397Sobrien			      validate_change (insn,
145252284Sobrien					       recog_operand_loc[match_no],
145350397Sobrien					       dst, 0);
145450397Sobrien			    }
145550397Sobrien			}
145650397Sobrien		      break;
145750397Sobrien		    }
145850397Sobrien
145950397Sobrien		  if (reg_overlap_mentioned_p (src, PATTERN (p))
146050397Sobrien		      || reg_overlap_mentioned_p (dst, PATTERN (p)))
146150397Sobrien		    break;
146250397Sobrien
146350397Sobrien		  /* If we have passed a call instruction, and the
146450397Sobrien		     pseudo-reg DST is not already live across a call,
146550397Sobrien		     then don't perform the optimization.  */
146650397Sobrien		  if (GET_CODE (p) == CALL_INSN)
146750397Sobrien		    {
146850397Sobrien		      num_calls++;
146950397Sobrien
147050397Sobrien		      if (REG_N_CALLS_CROSSED (REGNO (dst)) == 0)
147150397Sobrien			break;
147250397Sobrien		    }
147350397Sobrien		}
147450397Sobrien
147550397Sobrien	      if (success)
147650397Sobrien		{
147750397Sobrien		  int dstno, srcno;
147850397Sobrien
147950397Sobrien		  /* Remove the death note for SRC from INSN.  */
148050397Sobrien		  remove_note (insn, src_note);
148150397Sobrien		  /* Move the death note for SRC to P if it is used
148250397Sobrien		     there.  */
148350397Sobrien		  if (reg_overlap_mentioned_p (src, PATTERN (p)))
148450397Sobrien		    {
148550397Sobrien		      XEXP (src_note, 1) = REG_NOTES (p);
148650397Sobrien		      REG_NOTES (p) = src_note;
148750397Sobrien		    }
148850397Sobrien		  /* If there is a REG_DEAD note for DST on P, then remove
148950397Sobrien		     it, because DST is now set there.  */
149050397Sobrien		  if ((dst_note = find_reg_note (p, REG_DEAD, dst)))
149150397Sobrien		    remove_note (p, dst_note);
149250397Sobrien
149350397Sobrien		  dstno = REGNO (dst);
149450397Sobrien		  srcno = REGNO (src);
149550397Sobrien
149650397Sobrien		  REG_N_SETS (dstno)++;
149750397Sobrien		  REG_N_SETS (srcno)--;
149850397Sobrien
149950397Sobrien		  REG_N_CALLS_CROSSED (dstno) += num_calls;
150050397Sobrien		  REG_N_CALLS_CROSSED (srcno) -= num_calls;
150150397Sobrien
150250397Sobrien		  REG_LIVE_LENGTH (dstno) += length;
150350397Sobrien		  if (REG_LIVE_LENGTH (srcno) >= 0)
150450397Sobrien		    {
150550397Sobrien		      REG_LIVE_LENGTH (srcno) -= length;
150650397Sobrien		      /* REG_LIVE_LENGTH is only an approximation after
150750397Sobrien			 combine if sched is not run, so make sure that we
150850397Sobrien			 still have a reasonable value.  */
150950397Sobrien		      if (REG_LIVE_LENGTH (srcno) < 2)
151050397Sobrien			REG_LIVE_LENGTH (srcno) = 2;
151150397Sobrien		    }
151250397Sobrien
151350397Sobrien		  /* We assume that a register is used exactly once per
151450397Sobrien		     insn in the updates above.  If this is not correct,
151550397Sobrien		     no great harm is done.  */
151650397Sobrien
151750397Sobrien		  REG_N_REFS (dstno) += 2 * loop_depth;
151850397Sobrien		  REG_N_REFS (srcno) -= 2 * loop_depth;
151950397Sobrien
152050397Sobrien                  /* If that was the only time src was set,
152150397Sobrien                     and src was not live at the start of the
152250397Sobrien                     function, we know that we have no more
152350397Sobrien                     references to src; clear REG_N_REFS so it
152450397Sobrien                     won't make reload do any work.  */
152550397Sobrien                  if (REG_N_SETS (REGNO (src)) == 0
152650397Sobrien                      && ! regno_uninitialized (REGNO (src)))
152750397Sobrien                    REG_N_REFS (REGNO (src)) = 0;
152850397Sobrien
152950397Sobrien		  if (regmove_dump_file)
153050397Sobrien		    fprintf (regmove_dump_file,
153150397Sobrien			     "Fixed operand %d of insn %d matching operand %d.\n",
153252284Sobrien			     op_no, INSN_UID (insn), match_no);
153350397Sobrien
153450397Sobrien		  break;
153550397Sobrien		}
153650397Sobrien	    }
153750397Sobrien
153850397Sobrien	  /* If we weren't able to replace any of the alternatives, try an
153950397Sobrien	     alternative appoach of copying the source to the destination.  */
154050397Sobrien	  if (!success && copy_src != NULL_RTX)
154152284Sobrien	    copy_src_to_dest (insn, copy_src, copy_dst, loop_depth,
154252284Sobrien			      old_max_uid);
154350397Sobrien
154450397Sobrien	}
154550397Sobrien    }
154650397Sobrien#endif /* REGISTER_CONSTRAINTS */
154752284Sobrien
154852284Sobrien  /* In fixup_match_1, some insns may have been inserted after basic block
154952284Sobrien     ends.  Fix that here.  */
155052284Sobrien  for (i = 0; i < n_basic_blocks; i++)
155152284Sobrien    {
155252284Sobrien      rtx end = BLOCK_END (i);
155352284Sobrien      rtx new = end;
155452284Sobrien      rtx next = NEXT_INSN (new);
155552284Sobrien      while (next != 0 && INSN_UID (next) >= old_max_uid
155652284Sobrien	     && (i == n_basic_blocks - 1 || BLOCK_HEAD (i + 1) != next))
155752284Sobrien	new = next, next = NEXT_INSN (new);
155852284Sobrien      BLOCK_END (i) = new;
155952284Sobrien    }
156050397Sobrien}
156150397Sobrien
156252284Sobrien/* Returns nonzero if INSN's pattern has matching constraints for any operand.
156352284Sobrien   Returns 0 if INSN can't be recognized, or if the alternative can't be
156452284Sobrien   determined.
156550397Sobrien
156650397Sobrien   Initialize the info in MATCHP based on the constraints.  */
156750397Sobrien
156850397Sobrienstatic int
156950397Sobrienfind_matches (insn, matchp)
157050397Sobrien     rtx insn;
157150397Sobrien     struct match *matchp;
157250397Sobrien{
157350397Sobrien  int likely_spilled[MAX_RECOG_OPERANDS];
157452284Sobrien  int op_no;
157550397Sobrien  int any_matches = 0;
157650397Sobrien
157752284Sobrien  extract_insn (insn);
157852284Sobrien  if (! constrain_operands (0))
157952284Sobrien    return 0;
158050397Sobrien
158150397Sobrien  /* Must initialize this before main loop, because the code for
158250397Sobrien     the commutative case may set matches for operands other than
158350397Sobrien     the current one.  */
158452284Sobrien  for (op_no = recog_n_operands; --op_no >= 0; )
158552284Sobrien    matchp->with[op_no] = matchp->commutative[op_no] = -1;
158650397Sobrien
158752284Sobrien  for (op_no = 0; op_no < recog_n_operands; op_no++)
158850397Sobrien    {
158952284Sobrien      const char *p;
159052284Sobrien      char c;
159150397Sobrien      int i = 0;
159250397Sobrien
159352284Sobrien      p = recog_constraints[op_no];
159450397Sobrien
159552284Sobrien      likely_spilled[op_no] = 0;
159652284Sobrien      matchp->use[op_no] = READ;
159752284Sobrien      matchp->early_clobber[op_no] = 0;
159850397Sobrien      if (*p == '=')
159952284Sobrien	matchp->use[op_no] = WRITE;
160050397Sobrien      else if (*p == '+')
160152284Sobrien	matchp->use[op_no] = READWRITE;
160250397Sobrien
160350397Sobrien      for (;*p && i < which_alternative; p++)
160450397Sobrien	if (*p == ',')
160550397Sobrien	  i++;
160650397Sobrien
160750397Sobrien      while ((c = *p++) != '\0' && c != ',')
160850397Sobrien	switch (c)
160950397Sobrien	  {
161050397Sobrien	  case '=':
161150397Sobrien	    break;
161250397Sobrien	  case '+':
161350397Sobrien	    break;
161450397Sobrien	  case '&':
161552284Sobrien	    matchp->early_clobber[op_no] = 1;
161650397Sobrien	    break;
161750397Sobrien	  case '%':
161852284Sobrien	    matchp->commutative[op_no] = op_no + 1;
161952284Sobrien	    matchp->commutative[op_no + 1] = op_no;
162050397Sobrien	    break;
162150397Sobrien	  case '0': case '1': case '2': case '3': case '4':
162250397Sobrien	  case '5': case '6': case '7': case '8': case '9':
162350397Sobrien	    c -= '0';
162452284Sobrien	    if (c < op_no && likely_spilled[(unsigned char) c])
162550397Sobrien	      break;
162652284Sobrien	    matchp->with[op_no] = c;
162750397Sobrien	    any_matches = 1;
162852284Sobrien	    if (matchp->commutative[op_no] >= 0)
162952284Sobrien	      matchp->with[matchp->commutative[op_no]] = c;
163050397Sobrien	    break;
163150397Sobrien	  case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'h':
163250397Sobrien	  case 'j': case 'k': case 'l': case 'p': case 'q': case 't': case 'u':
163350397Sobrien	  case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B':
163450397Sobrien	  case 'C': case 'D': case 'W': case 'Y': case 'Z':
163552284Sobrien	    if (CLASS_LIKELY_SPILLED_P (REG_CLASS_FROM_LETTER ((unsigned char)c)))
163652284Sobrien	      likely_spilled[op_no] = 1;
163750397Sobrien	    break;
163850397Sobrien	  }
163950397Sobrien    }
164052284Sobrien  return any_matches;
164150397Sobrien}
164250397Sobrien
164350397Sobrien/* Try to replace output operand DST in SET, with input operand SRC.  SET is
164450397Sobrien   the only set in INSN.  INSN has just been recgnized and constrained.
164550397Sobrien   SRC is operand number OPERAND_NUMBER in INSN.
164650397Sobrien   DST is operand number MATCH_NUMBER in INSN.
164750397Sobrien   If BACKWARD is nonzero, we have been called in a backward pass.
164850397Sobrien   Return nonzero for success.  */
164950397Sobrienstatic int
165050397Sobrienfixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number,
165150397Sobrien	       match_number, regmove_dump_file)
165250397Sobrien     rtx insn, set, src, src_subreg, dst;
165350397Sobrien     int backward, operand_number, match_number;
165450397Sobrien     FILE *regmove_dump_file;
165550397Sobrien{
165650397Sobrien  rtx p;
165750397Sobrien  rtx post_inc = 0, post_inc_set = 0, search_end = 0;
165850397Sobrien  int success = 0;
165950397Sobrien  int num_calls = 0, s_num_calls = 0;
166050397Sobrien  enum rtx_code code = NOTE;
166150397Sobrien  HOST_WIDE_INT insn_const, newconst;
166250397Sobrien  rtx overlap = 0; /* need to move insn ? */
166350397Sobrien  rtx src_note = find_reg_note (insn, REG_DEAD, src), dst_note;
166450397Sobrien  int length, s_length, true_loop_depth;
166550397Sobrien
166650397Sobrien  if (! src_note)
166750397Sobrien    {
166850397Sobrien      /* Look for (set (regX) (op regA constX))
166950397Sobrien		  (set (regY) (op regA constY))
167050397Sobrien	 and change that to
167150397Sobrien		  (set (regA) (op regA constX)).
167250397Sobrien		  (set (regY) (op regA constY-constX)).
167350397Sobrien	 This works for add and shift operations, if
167450397Sobrien	 regA is dead after or set by the second insn.  */
167550397Sobrien
167650397Sobrien      code = GET_CODE (SET_SRC (set));
167750397Sobrien      if ((code == PLUS || code == LSHIFTRT
167850397Sobrien	   || code == ASHIFT || code == ASHIFTRT)
167950397Sobrien	  && XEXP (SET_SRC (set), 0) == src
168050397Sobrien	  && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
168150397Sobrien	insn_const = INTVAL (XEXP (SET_SRC (set), 1));
168250397Sobrien      else if (! stable_but_for_p (SET_SRC (set), src, dst))
168350397Sobrien	return 0;
168450397Sobrien      else
168550397Sobrien	/* We might find a src_note while scanning.  */
168650397Sobrien	code = NOTE;
168750397Sobrien    }
168850397Sobrien
168950397Sobrien  if (regmove_dump_file)
169050397Sobrien    fprintf (regmove_dump_file,
169150397Sobrien	     "Could fix operand %d of insn %d matching operand %d.\n",
169250397Sobrien	     operand_number, INSN_UID (insn), match_number);
169350397Sobrien
169450397Sobrien  /* If SRC is equivalent to a constant set in a different basic block,
169550397Sobrien     then do not use it for this optimization.  We want the equivalence
169650397Sobrien     so that if we have to reload this register, we can reload the
169750397Sobrien     constant, rather than extending the lifespan of the register.  */
169850397Sobrien  if (reg_is_remote_constant_p (src, insn, get_insns ()))
169950397Sobrien    return 0;
170050397Sobrien
170150397Sobrien  /* Scan forward to find the next instruction that
170250397Sobrien     uses the output operand.  If the operand dies here,
170350397Sobrien     then replace it in both instructions with
170450397Sobrien     operand_number.  */
170550397Sobrien
170650397Sobrien  for (length = s_length = 0, p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
170750397Sobrien    {
170850397Sobrien      if (GET_CODE (p) == CODE_LABEL || GET_CODE (p) == JUMP_INSN
170950397Sobrien	  || (GET_CODE (p) == NOTE
171050397Sobrien	      && (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_BEG
171150397Sobrien		  || NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)))
171250397Sobrien	break;
171350397Sobrien
171450397Sobrien      /* ??? We can't scan past the end of a basic block without updating
171550397Sobrien	 the register lifetime info (REG_DEAD/basic_block_live_at_start).
171650397Sobrien	 A CALL_INSN might be the last insn of a basic block, if it is
171750397Sobrien	 inside an EH region.  There is no easy way to tell, so we just
171850397Sobrien	 always break when we see a CALL_INSN if flag_exceptions is nonzero.  */
171950397Sobrien      if (flag_exceptions && GET_CODE (p) == CALL_INSN)
172050397Sobrien	break;
172150397Sobrien
172250397Sobrien      if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
172350397Sobrien	continue;
172450397Sobrien
172550397Sobrien      length++;
172650397Sobrien      if (src_note)
172750397Sobrien	s_length++;
172850397Sobrien
172950397Sobrien      if (reg_set_p (src, p) || reg_set_p (dst, p)
173050397Sobrien	  || (GET_CODE (PATTERN (p)) == USE
173150397Sobrien	      && reg_overlap_mentioned_p (src, XEXP (PATTERN (p), 0))))
173250397Sobrien	break;
173350397Sobrien
173450397Sobrien      /* See if all of DST dies in P.  This test is
173550397Sobrien	 slightly more conservative than it needs to be.  */
173650397Sobrien      if ((dst_note = find_regno_note (p, REG_DEAD, REGNO (dst)))
173750397Sobrien	  && (GET_MODE (XEXP (dst_note, 0)) == GET_MODE (dst)))
173850397Sobrien	{
173950397Sobrien	  if (! src_note)
174050397Sobrien	    {
174150397Sobrien	      rtx q;
174250397Sobrien	      rtx set2;
174350397Sobrien
174450397Sobrien	      /* If an optimization is done, the value of SRC while P
174550397Sobrien		 is executed will be changed.  Check that this is OK.  */
174650397Sobrien	      if (reg_overlap_mentioned_p (src, PATTERN (p)))
174750397Sobrien		break;
174850397Sobrien	      for (q = p; q; q = NEXT_INSN (q))
174950397Sobrien		{
175050397Sobrien		  if (GET_CODE (q) == CODE_LABEL || GET_CODE (q) == JUMP_INSN
175150397Sobrien		      || (GET_CODE (q) == NOTE
175250397Sobrien			  && (NOTE_LINE_NUMBER (q) == NOTE_INSN_LOOP_BEG
175350397Sobrien			      || NOTE_LINE_NUMBER (q) == NOTE_INSN_LOOP_END)))
175450397Sobrien		    {
175550397Sobrien		      q = 0;
175650397Sobrien		      break;
175750397Sobrien		    }
175850397Sobrien
175950397Sobrien		  /* ??? We can't scan past the end of a basic block without
176050397Sobrien		     updating the register lifetime info
176150397Sobrien		     (REG_DEAD/basic_block_live_at_start).
176250397Sobrien		     A CALL_INSN might be the last insn of a basic block, if
176350397Sobrien		     it is inside an EH region.  There is no easy way to tell,
176450397Sobrien		     so we just always break when we see a CALL_INSN if
176550397Sobrien		     flag_exceptions is nonzero.  */
176650397Sobrien		  if (flag_exceptions && GET_CODE (q) == CALL_INSN)
176750397Sobrien		    {
176850397Sobrien		      q = 0;
176950397Sobrien		      break;
177050397Sobrien		    }
177150397Sobrien
177250397Sobrien		  if (GET_RTX_CLASS (GET_CODE (q)) != 'i')
177350397Sobrien		    continue;
177450397Sobrien		  if (reg_overlap_mentioned_p (src, PATTERN (q))
177550397Sobrien		      || reg_set_p (src, q))
177650397Sobrien		    break;
177750397Sobrien		}
177850397Sobrien	      if (q)
177950397Sobrien		set2 = single_set (q);
178050397Sobrien	      if (! q || ! set2 || GET_CODE (SET_SRC (set2)) != code
178150397Sobrien		  || XEXP (SET_SRC (set2), 0) != src
178250397Sobrien		  || GET_CODE (XEXP (SET_SRC (set2), 1)) != CONST_INT
178350397Sobrien		  || (SET_DEST (set2) != src
178450397Sobrien		      && ! find_reg_note (q, REG_DEAD, src)))
178550397Sobrien		{
178650397Sobrien		  /* If this is a PLUS, we can still save a register by doing
178750397Sobrien		     src += insn_const;
178850397Sobrien		     P;
178950397Sobrien		     src -= insn_const; .
179050397Sobrien		     This also gives opportunities for subsequent
179150397Sobrien		     optimizations in the backward pass, so do it there.  */
179250397Sobrien		  if (code == PLUS && backward
179352284Sobrien		      /* Don't do this if we can likely tie DST to SET_DEST
179452284Sobrien			 of P later; we can't do this tying here if we got a
179552284Sobrien			 hard register.  */
179652284Sobrien		      && ! (dst_note && ! REG_N_CALLS_CROSSED (REGNO (dst))
179752284Sobrien			    && single_set (p)
179852284Sobrien			    && GET_CODE (SET_DEST (single_set (p))) == REG
179952284Sobrien			    && (REGNO (SET_DEST (single_set (p)))
180052284Sobrien				< FIRST_PSEUDO_REGISTER))
180152284Sobrien		      /* We may only emit an insn directly after P if we
180252284Sobrien			 are not in the shadow of a live flags register.  */
180352284Sobrien		      && GET_MODE (p) == VOIDmode)
180450397Sobrien		    {
180550397Sobrien		      search_end = q;
180650397Sobrien		      q = insn;
180750397Sobrien		      set2 = set;
180850397Sobrien		      newconst = -insn_const;
180950397Sobrien		      code = MINUS;
181050397Sobrien		    }
181150397Sobrien		  else
181250397Sobrien		    break;
181350397Sobrien		}
181450397Sobrien	      else
181550397Sobrien		{
181650397Sobrien		  newconst = INTVAL (XEXP (SET_SRC (set2), 1)) - insn_const;
181750397Sobrien		  /* Reject out of range shifts.  */
181850397Sobrien		  if (code != PLUS
181950397Sobrien		      && (newconst < 0
182050397Sobrien			  || (newconst
182150397Sobrien			      >= GET_MODE_BITSIZE (GET_MODE (SET_SRC (set2))))))
182250397Sobrien		    break;
182350397Sobrien		  if (code == PLUS)
182450397Sobrien		    {
182550397Sobrien		      post_inc = q;
182650397Sobrien		      if (SET_DEST (set2) != src)
182750397Sobrien			post_inc_set = set2;
182850397Sobrien		    }
182950397Sobrien		}
183050397Sobrien	      /* We use 1 as last argument to validate_change so that all
183150397Sobrien		 changes are accepted or rejected together by apply_change_group
183250397Sobrien		 when it is called by validate_replace_rtx .  */
183350397Sobrien	      validate_change (q, &XEXP (SET_SRC (set2), 1),
183450397Sobrien			       GEN_INT (newconst), 1);
183550397Sobrien	    }
183650397Sobrien	  validate_change (insn, recog_operand_loc[match_number], src, 1);
183750397Sobrien	  if (validate_replace_rtx (dst, src_subreg, p))
183850397Sobrien	    success = 1;
183950397Sobrien	  break;
184050397Sobrien	}
184150397Sobrien
184250397Sobrien      if (reg_overlap_mentioned_p (dst, PATTERN (p)))
184350397Sobrien	break;
184450397Sobrien      if (! src_note && reg_overlap_mentioned_p (src, PATTERN (p)))
184550397Sobrien	{
184650397Sobrien	  /* INSN was already checked to be movable when
184750397Sobrien	     we found no REG_DEAD note for src on it.  */
184850397Sobrien	  overlap = p;
184950397Sobrien	  src_note = find_reg_note (p, REG_DEAD, src);
185050397Sobrien	}
185150397Sobrien
185250397Sobrien      /* If we have passed a call instruction, and the pseudo-reg SRC is not
185350397Sobrien	 already live across a call, then don't perform the optimization.  */
185450397Sobrien      if (GET_CODE (p) == CALL_INSN)
185550397Sobrien	{
185650397Sobrien	  if (REG_N_CALLS_CROSSED (REGNO (src)) == 0)
185750397Sobrien	    break;
185850397Sobrien
185950397Sobrien	  num_calls++;
186050397Sobrien
186150397Sobrien	  if (src_note)
186250397Sobrien	    s_num_calls++;
186350397Sobrien
186450397Sobrien	}
186550397Sobrien    }
186650397Sobrien
186750397Sobrien  if (! success)
186850397Sobrien    return 0;
186950397Sobrien
187050397Sobrien  true_loop_depth = backward ? 2 - loop_depth : loop_depth;
187150397Sobrien
187250397Sobrien  /* Remove the death note for DST from P.  */
187350397Sobrien  remove_note (p, dst_note);
187450397Sobrien  if (code == MINUS)
187550397Sobrien    {
187650397Sobrien      post_inc = emit_insn_after (copy_rtx (PATTERN (insn)), p);
187752284Sobrien      if ((HAVE_PRE_INCREMENT || HAVE_PRE_DECREMENT)
187852284Sobrien	  && search_end
187950397Sobrien	  && try_auto_increment (search_end, post_inc, 0, src, newconst, 1))
188050397Sobrien	post_inc = 0;
188150397Sobrien      validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (insn_const), 0);
188250397Sobrien      REG_N_SETS (REGNO (src))++;
188350397Sobrien      REG_N_REFS (REGNO (src)) += true_loop_depth;
188450397Sobrien      REG_LIVE_LENGTH (REGNO (src))++;
188550397Sobrien    }
188650397Sobrien  if (overlap)
188750397Sobrien    {
188850397Sobrien      /* The lifetime of src and dest overlap,
188950397Sobrien	 but we can change this by moving insn.  */
189050397Sobrien      rtx pat = PATTERN (insn);
189150397Sobrien      if (src_note)
189250397Sobrien	remove_note (overlap, src_note);
189352284Sobrien      if ((HAVE_POST_INCREMENT || HAVE_POST_DECREMENT)
189452284Sobrien	  && code == PLUS
189550397Sobrien	  && try_auto_increment (overlap, insn, 0, src, insn_const, 0))
189650397Sobrien	insn = overlap;
189750397Sobrien      else
189850397Sobrien	{
189950397Sobrien	  rtx notes = REG_NOTES (insn);
190050397Sobrien
190150397Sobrien	  emit_insn_after_with_line_notes (pat, PREV_INSN (p), insn);
190250397Sobrien	  PUT_CODE (insn, NOTE);
190350397Sobrien	  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
190450397Sobrien	  NOTE_SOURCE_FILE (insn) = 0;
190550397Sobrien	  /* emit_insn_after_with_line_notes has no
190650397Sobrien	     return value, so search for the new insn.  */
190750397Sobrien	  for (insn = p; PATTERN (insn) != pat; )
190850397Sobrien	    insn = PREV_INSN (insn);
190950397Sobrien
191050397Sobrien	  REG_NOTES (insn) = notes;
191150397Sobrien	}
191250397Sobrien    }
191350397Sobrien  /* Sometimes we'd generate src = const; src += n;
191450397Sobrien     if so, replace the instruction that set src
191550397Sobrien     in the first place.  */
191650397Sobrien
191750397Sobrien  if (! overlap && (code == PLUS || code == MINUS))
191850397Sobrien    {
191950397Sobrien      rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
192050397Sobrien      rtx q, set2;
192150397Sobrien      int num_calls2 = 0, s_length2 = 0;
192250397Sobrien
192350397Sobrien      if (note && CONSTANT_P (XEXP (note, 0)))
192450397Sobrien	{
192550397Sobrien	  for (q = PREV_INSN (insn); q; q = PREV_INSN(q))
192650397Sobrien	    {
192750397Sobrien	      if (GET_CODE (q) == CODE_LABEL || GET_CODE (q) == JUMP_INSN
192850397Sobrien		  || (GET_CODE (q) == NOTE
192950397Sobrien		      && (NOTE_LINE_NUMBER (q) == NOTE_INSN_LOOP_BEG
193050397Sobrien			  || NOTE_LINE_NUMBER (q) == NOTE_INSN_LOOP_END)))
193150397Sobrien		{
193250397Sobrien		  q = 0;
193350397Sobrien		  break;
193450397Sobrien		}
193550397Sobrien
193650397Sobrien	      /* ??? We can't scan past the end of a basic block without
193750397Sobrien		 updating the register lifetime info
193850397Sobrien		 (REG_DEAD/basic_block_live_at_start).
193950397Sobrien		 A CALL_INSN might be the last insn of a basic block, if
194050397Sobrien		 it is inside an EH region.  There is no easy way to tell,
194150397Sobrien		 so we just always break when we see a CALL_INSN if
194250397Sobrien		 flag_exceptions is nonzero.  */
194350397Sobrien	      if (flag_exceptions && GET_CODE (q) == CALL_INSN)
194450397Sobrien		{
194550397Sobrien		  q = 0;
194650397Sobrien		  break;
194750397Sobrien		}
194850397Sobrien
194950397Sobrien	      if (GET_RTX_CLASS (GET_CODE (q)) != 'i')
195050397Sobrien		continue;
195150397Sobrien	      s_length2++;
195250397Sobrien	      if (reg_set_p (src, q))
195350397Sobrien		{
195450397Sobrien		  set2 = single_set (q);
195550397Sobrien		  break;
195650397Sobrien		}
195750397Sobrien	      if (reg_overlap_mentioned_p (src, PATTERN (q)))
195850397Sobrien		{
195950397Sobrien		  q = 0;
196050397Sobrien		  break;
196150397Sobrien		}
196250397Sobrien	      if (GET_CODE (p) == CALL_INSN)
196350397Sobrien		num_calls2++;
196450397Sobrien	    }
196550397Sobrien	  if (q && set2 && SET_DEST (set2) == src && CONSTANT_P (SET_SRC (set2))
196650397Sobrien	      && validate_change (insn, &SET_SRC (set), XEXP (note, 0), 0))
196750397Sobrien	    {
196850397Sobrien	      PUT_CODE (q, NOTE);
196950397Sobrien	      NOTE_LINE_NUMBER (q) = NOTE_INSN_DELETED;
197050397Sobrien	      NOTE_SOURCE_FILE (q) = 0;
197150397Sobrien	      REG_N_SETS (REGNO (src))--;
197250397Sobrien	      REG_N_CALLS_CROSSED (REGNO (src)) -= num_calls2;
197350397Sobrien	      REG_N_REFS (REGNO (src)) -= true_loop_depth;
197450397Sobrien	      REG_LIVE_LENGTH (REGNO (src)) -= s_length2;
197550397Sobrien	      insn_const = 0;
197650397Sobrien	    }
197750397Sobrien	}
197850397Sobrien    }
197950397Sobrien
198052284Sobrien  if ((HAVE_PRE_INCREMENT || HAVE_PRE_DECREMENT)
198152284Sobrien	   && (code == PLUS || code == MINUS) && insn_const
198250397Sobrien	   && try_auto_increment (p, insn, 0, src, insn_const, 1))
198350397Sobrien    insn = p;
198452284Sobrien  else if ((HAVE_POST_INCREMENT || HAVE_POST_DECREMENT)
198552284Sobrien	   && post_inc
198650397Sobrien	   && try_auto_increment (p, post_inc, post_inc_set, src, newconst, 0))
198750397Sobrien    post_inc = 0;
198850397Sobrien  /* If post_inc still prevails, try to find an
198950397Sobrien     insn where it can be used as a pre-in/decrement.
199050397Sobrien     If code is MINUS, this was already tried.  */
199150397Sobrien  if (post_inc && code == PLUS
199250397Sobrien  /* Check that newconst is likely to be usable
199350397Sobrien     in a pre-in/decrement before starting the search.  */
199452284Sobrien      && ((HAVE_PRE_INCREMENT && newconst > 0 && newconst <= MOVE_MAX)
199552284Sobrien	  || (HAVE_PRE_DECREMENT && newconst < 0 && newconst >= -MOVE_MAX))
199652284Sobrien      && exact_log2 (newconst))
199750397Sobrien    {
199850397Sobrien      rtx q, inc_dest;
199950397Sobrien
200050397Sobrien      inc_dest = post_inc_set ? SET_DEST (post_inc_set) : src;
200150397Sobrien      for (q = post_inc; (q = NEXT_INSN (q)); )
200250397Sobrien	{
200350397Sobrien	  if (GET_CODE (q) == CODE_LABEL || GET_CODE (q) == JUMP_INSN
200450397Sobrien	      || (GET_CODE (q) == NOTE
200550397Sobrien		  && (NOTE_LINE_NUMBER (q) == NOTE_INSN_LOOP_BEG
200650397Sobrien		      || NOTE_LINE_NUMBER (q) == NOTE_INSN_LOOP_END)))
200750397Sobrien	    break;
200850397Sobrien
200950397Sobrien	  /* ??? We can't scan past the end of a basic block without updating
201050397Sobrien	     the register lifetime info (REG_DEAD/basic_block_live_at_start).
201150397Sobrien	     A CALL_INSN might be the last insn of a basic block, if it
201250397Sobrien	     is inside an EH region.  There is no easy way to tell so we
201350397Sobrien	     just always break when we see a CALL_INSN if flag_exceptions
201450397Sobrien	     is nonzero.  */
201550397Sobrien	  if (flag_exceptions && GET_CODE (q) == CALL_INSN)
201650397Sobrien	    break;
201750397Sobrien
201850397Sobrien	  if (GET_RTX_CLASS (GET_CODE (q)) != 'i')
201950397Sobrien	    continue;
202050397Sobrien	  if (src != inc_dest && (reg_overlap_mentioned_p (src, PATTERN (q))
202150397Sobrien				  || reg_set_p (src, q)))
202250397Sobrien	    break;
202350397Sobrien	  if (reg_set_p (inc_dest, q))
202450397Sobrien	    break;
202550397Sobrien	  if (reg_overlap_mentioned_p (inc_dest, PATTERN (q)))
202650397Sobrien	    {
202750397Sobrien	      try_auto_increment (q, post_inc,
202850397Sobrien				  post_inc_set, inc_dest, newconst, 1);
202950397Sobrien	      break;
203050397Sobrien	    }
203150397Sobrien	}
203250397Sobrien    }
203350397Sobrien  /* Move the death note for DST to INSN if it is used
203450397Sobrien     there.  */
203550397Sobrien  if (reg_overlap_mentioned_p (dst, PATTERN (insn)))
203650397Sobrien    {
203750397Sobrien      XEXP (dst_note, 1) = REG_NOTES (insn);
203850397Sobrien      REG_NOTES (insn) = dst_note;
203950397Sobrien    }
204050397Sobrien
204150397Sobrien  if (src_note)
204250397Sobrien    {
204350397Sobrien      /* Move the death note for SRC from INSN to P.  */
204450397Sobrien      if (! overlap)
204550397Sobrien	remove_note (insn, src_note);
204650397Sobrien      XEXP (src_note, 1) = REG_NOTES (p);
204750397Sobrien      REG_NOTES (p) = src_note;
204850397Sobrien
204950397Sobrien      REG_N_CALLS_CROSSED (REGNO (src)) += s_num_calls;
205050397Sobrien    }
205150397Sobrien
205250397Sobrien  REG_N_SETS (REGNO (src))++;
205350397Sobrien  REG_N_SETS (REGNO (dst))--;
205450397Sobrien
205550397Sobrien  REG_N_CALLS_CROSSED (REGNO (dst)) -= num_calls;
205650397Sobrien
205750397Sobrien  REG_LIVE_LENGTH (REGNO (src)) += s_length;
205850397Sobrien  if (REG_LIVE_LENGTH (REGNO (dst)) >= 0)
205950397Sobrien    {
206050397Sobrien      REG_LIVE_LENGTH (REGNO (dst)) -= length;
206150397Sobrien      /* REG_LIVE_LENGTH is only an approximation after
206250397Sobrien	 combine if sched is not run, so make sure that we
206350397Sobrien	 still have a reasonable value.  */
206450397Sobrien      if (REG_LIVE_LENGTH (REGNO (dst)) < 2)
206550397Sobrien	REG_LIVE_LENGTH (REGNO (dst)) = 2;
206650397Sobrien    }
206750397Sobrien
206850397Sobrien  /* We assume that a register is used exactly once per
206950397Sobrien      insn in the updates above.  If this is not correct,
207050397Sobrien      no great harm is done.  */
207150397Sobrien
207250397Sobrien  REG_N_REFS (REGNO (src)) += 2 * true_loop_depth;
207350397Sobrien  REG_N_REFS (REGNO (dst)) -= 2 * true_loop_depth;
207450397Sobrien
207550397Sobrien  /* If that was the only time dst was set,
207650397Sobrien     and dst was not live at the start of the
207750397Sobrien     function, we know that we have no more
207850397Sobrien     references to dst; clear REG_N_REFS so it
207950397Sobrien     won't make reload do any work.  */
208050397Sobrien  if (REG_N_SETS (REGNO (dst)) == 0
208150397Sobrien      && ! regno_uninitialized (REGNO (dst)))
208250397Sobrien    REG_N_REFS (REGNO (dst)) = 0;
208350397Sobrien
208450397Sobrien  if (regmove_dump_file)
208550397Sobrien    fprintf (regmove_dump_file,
208650397Sobrien	     "Fixed operand %d of insn %d matching operand %d.\n",
208750397Sobrien	     operand_number, INSN_UID (insn), match_number);
208850397Sobrien  return 1;
208950397Sobrien}
209050397Sobrien
209150397Sobrien
209250397Sobrien/* return nonzero if X is stable but for mentioning SRC or mentioning /
209350397Sobrien   changing DST .  If in doubt, presume it is unstable.  */
209450397Sobrienstatic int
209550397Sobrienstable_but_for_p (x, src, dst)
209650397Sobrien     rtx x, src, dst;
209750397Sobrien{
209850397Sobrien  RTX_CODE code = GET_CODE (x);
209950397Sobrien  switch (GET_RTX_CLASS (code))
210050397Sobrien    {
210150397Sobrien    case '<': case '1': case 'c': case '2': case 'b': case '3':
210250397Sobrien      {
210350397Sobrien	int i;
210450397Sobrien	char *fmt = GET_RTX_FORMAT (code);
210550397Sobrien	for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
210650397Sobrien	  if (fmt[i] == 'e' && ! stable_but_for_p (XEXP (x, i), src, dst))
210750397Sobrien	      return 0;
210850397Sobrien	return 1;
210950397Sobrien      }
211050397Sobrien    case 'o':
211150397Sobrien      if (x == src || x == dst)
211250397Sobrien	return 1;
211350397Sobrien      /* fall through */
211450397Sobrien    default:
211550397Sobrien      return ! rtx_unstable_p (x);
211650397Sobrien    }
211750397Sobrien}
211850397Sobrien
211950397Sobrien/* Test if regmove seems profitable for this target.  Regmove is useful only
212050397Sobrien   if some common patterns are two address, i.e. require matching constraints,
212150397Sobrien   so we check that condition here.  */
212250397Sobrien
212350397Sobrienint
212450397Sobrienregmove_profitable_p ()
212550397Sobrien{
212650397Sobrien#ifdef REGISTER_CONSTRAINTS
212750397Sobrien  struct match match;
212850397Sobrien  enum machine_mode mode;
212950397Sobrien  optab tstoptab = add_optab;
213050397Sobrien  do /* check add_optab and ashl_optab */
213150397Sobrien    for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
213250397Sobrien	   mode = GET_MODE_WIDER_MODE (mode))
213350397Sobrien	{
213450397Sobrien	  int icode = (int) tstoptab->handlers[(int) mode].insn_code;
213550397Sobrien	  rtx reg0, reg1, reg2, pat;
213650397Sobrien	  int i;
213750397Sobrien
213850397Sobrien	  if (GET_MODE_BITSIZE (mode) < 32 || icode == CODE_FOR_nothing)
213950397Sobrien	    continue;
214050397Sobrien	  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
214150397Sobrien	    if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i))
214250397Sobrien	      break;
214350397Sobrien	  if (i + 2 >= FIRST_PSEUDO_REGISTER)
214450397Sobrien	    break;
214550397Sobrien	  reg0 = gen_rtx_REG (insn_operand_mode[icode][0], i);
214650397Sobrien	  reg1 = gen_rtx_REG (insn_operand_mode[icode][1], i + 1);
214750397Sobrien	  reg2 = gen_rtx_REG (insn_operand_mode[icode][2], i + 2);
214850397Sobrien	  if (! (*insn_operand_predicate[icode][0]) (reg0, VOIDmode)
214950397Sobrien	      || ! (*insn_operand_predicate[icode][1]) (reg1, VOIDmode)
215050397Sobrien	      || ! (*insn_operand_predicate[icode][2]) (reg2, VOIDmode))
215150397Sobrien	    break;
215250397Sobrien	  pat = GEN_FCN (icode) (reg0, reg1, reg2);
215350397Sobrien	  if (! pat)
215450397Sobrien	    continue;
215550397Sobrien	  if (GET_CODE (pat) == SEQUENCE)
215650397Sobrien	    pat = XVECEXP (pat, 0,  XVECLEN (pat, 0) - 1);
215750397Sobrien	  else
215850397Sobrien	    pat = make_insn_raw (pat);
215950397Sobrien	  if (! single_set (pat)
216050397Sobrien	      || GET_CODE (SET_SRC (single_set (pat))) != tstoptab->code)
216150397Sobrien	    /* Unexpected complexity;  don't need to handle this unless
216250397Sobrien	       we find a machine where this occurs and regmove should
216350397Sobrien	       be enabled.  */
216450397Sobrien	    break;
216552284Sobrien	  if (find_matches (pat, &match))
216650397Sobrien	    return 1;
216750397Sobrien	  break;
216850397Sobrien	}
216950397Sobrien  while (tstoptab != ashl_optab && (tstoptab = ashl_optab, 1));
217050397Sobrien#endif /* REGISTER_CONSTRAINTS */
217150397Sobrien  return 0;
217250397Sobrien}
2173