150397Sobrien/* Move registers around to reduce number of move instructions needed.
290075Sobrien   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3169689Skan   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
450397Sobrien
590075SobrienThis file is part of GCC.
650397Sobrien
790075SobrienGCC is free software; you can redistribute it and/or modify it under
890075Sobrienthe terms of the GNU General Public License as published by the Free
990075SobrienSoftware Foundation; either version 2, or (at your option) any later
1090075Sobrienversion.
1150397Sobrien
1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590075Sobrienfor more details.
1650397Sobrien
1750397SobrienYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan02110-1301, USA.  */
2150397Sobrien
2250397Sobrien
2350397Sobrien/* This module looks for cases where matching constraints would force
2450397Sobrien   an instruction to need a reload, and this reload would be a register
2550397Sobrien   to register move.  It then attempts to change the registers used by the
2650397Sobrien   instruction to avoid the move instruction.  */
2750397Sobrien
2850397Sobrien#include "config.h"
2950397Sobrien#include "system.h"
30132718Skan#include "coretypes.h"
31132718Skan#include "tm.h"
3252284Sobrien#include "rtl.h" /* stdio.h must precede rtl.h for FFS.  */
3390075Sobrien#include "tm_p.h"
3450397Sobrien#include "insn-config.h"
3550397Sobrien#include "recog.h"
3650397Sobrien#include "output.h"
3750397Sobrien#include "regs.h"
3850397Sobrien#include "hard-reg-set.h"
3950397Sobrien#include "flags.h"
4090075Sobrien#include "function.h"
4150397Sobrien#include "expr.h"
4250397Sobrien#include "basic-block.h"
4390075Sobrien#include "except.h"
4450397Sobrien#include "toplev.h"
4590075Sobrien#include "reload.h"
46169689Skan#include "timevar.h"
47169689Skan#include "tree-pass.h"
4850397Sobrien
4990075Sobrien
5090075Sobrien/* Turn STACK_GROWS_DOWNWARD into a boolean.  */
5190075Sobrien#ifdef STACK_GROWS_DOWNWARD
5290075Sobrien#undef STACK_GROWS_DOWNWARD
5390075Sobrien#define STACK_GROWS_DOWNWARD 1
5490075Sobrien#else
5590075Sobrien#define STACK_GROWS_DOWNWARD 0
5690075Sobrien#endif
5790075Sobrien
58132718Skanstatic int perhaps_ends_bb_p (rtx);
59132718Skanstatic int optimize_reg_copy_1 (rtx, rtx, rtx);
60132718Skanstatic void optimize_reg_copy_2 (rtx, rtx, rtx);
61132718Skanstatic void optimize_reg_copy_3 (rtx, rtx, rtx);
62132718Skanstatic void copy_src_to_dest (rtx, rtx, rtx, int);
6350397Sobrienstatic int *regmove_bb_head;
6450397Sobrien
6550397Sobrienstruct match {
6650397Sobrien  int with[MAX_RECOG_OPERANDS];
6750397Sobrien  enum { READ, WRITE, READWRITE } use[MAX_RECOG_OPERANDS];
6850397Sobrien  int commutative[MAX_RECOG_OPERANDS];
6950397Sobrien  int early_clobber[MAX_RECOG_OPERANDS];
7050397Sobrien};
7150397Sobrien
72132718Skanstatic rtx discover_flags_reg (void);
73132718Skanstatic void mark_flags_life_zones (rtx);
74132718Skanstatic void flags_set_1 (rtx, rtx, void *);
7552284Sobrien
76132718Skanstatic int try_auto_increment (rtx, rtx, rtx, rtx, HOST_WIDE_INT, int);
77132718Skanstatic int find_matches (rtx, struct match *);
78132718Skanstatic void replace_in_call_usage (rtx *, unsigned int, rtx, rtx);
79169689Skanstatic int fixup_match_1 (rtx, rtx, rtx, rtx, rtx, int, int, int);
80132718Skanstatic int stable_and_no_regs_but_for_p (rtx, rtx, rtx);
81132718Skanstatic int regclass_compatible_p (int, int);
82132718Skanstatic int replacement_quality (rtx);
83169689Skanstatic int fixup_match_2 (rtx, rtx, rtx, rtx);
8450397Sobrien
85117395Skan/* Return nonzero if registers with CLASS1 and CLASS2 can be merged without
8652284Sobrien   causing too much register allocation problems.  */
8752284Sobrienstatic int
88132718Skanregclass_compatible_p (int class0, int class1)
8952284Sobrien{
9052284Sobrien  return (class0 == class1
9152284Sobrien	  || (reg_class_subset_p (class0, class1)
9252284Sobrien	      && ! CLASS_LIKELY_SPILLED_P (class0))
9352284Sobrien	  || (reg_class_subset_p (class1, class0)
9452284Sobrien	      && ! CLASS_LIKELY_SPILLED_P (class1)));
9552284Sobrien}
9652284Sobrien
9750397Sobrien/* INC_INSN is an instruction that adds INCREMENT to REG.
9850397Sobrien   Try to fold INC_INSN as a post/pre in/decrement into INSN.
9950397Sobrien   Iff INC_INSN_SET is nonzero, inc_insn has a destination different from src.
10050397Sobrien   Return nonzero for success.  */
10150397Sobrienstatic int
102132718Skantry_auto_increment (rtx insn, rtx inc_insn, rtx inc_insn_set, rtx reg,
103132718Skan		    HOST_WIDE_INT increment, int pre)
10450397Sobrien{
10550397Sobrien  enum rtx_code inc_code;
10650397Sobrien
10750397Sobrien  rtx pset = single_set (insn);
10850397Sobrien  if (pset)
10950397Sobrien    {
11050397Sobrien      /* Can't use the size of SET_SRC, we might have something like
11150397Sobrien	 (sign_extend:SI (mem:QI ...  */
11250397Sobrien      rtx use = find_use_as_address (pset, reg, 0);
11390075Sobrien      if (use != 0 && use != (rtx) (size_t) 1)
11450397Sobrien	{
11550397Sobrien	  int size = GET_MODE_SIZE (GET_MODE (use));
11650397Sobrien	  if (0
11752284Sobrien	      || (HAVE_POST_INCREMENT
11852284Sobrien		  && pre == 0 && (inc_code = POST_INC, increment == size))
11952284Sobrien	      || (HAVE_PRE_INCREMENT
12052284Sobrien		  && pre == 1 && (inc_code = PRE_INC, increment == size))
12152284Sobrien	      || (HAVE_POST_DECREMENT
12252284Sobrien		  && pre == 0 && (inc_code = POST_DEC, increment == -size))
12352284Sobrien	      || (HAVE_PRE_DECREMENT
12452284Sobrien		  && pre == 1 && (inc_code = PRE_DEC, increment == -size))
12550397Sobrien	  )
12650397Sobrien	    {
12750397Sobrien	      if (inc_insn_set)
12850397Sobrien		validate_change
12990075Sobrien		  (inc_insn,
13050397Sobrien		   &SET_SRC (inc_insn_set),
13150397Sobrien		   XEXP (SET_SRC (inc_insn_set), 0), 1);
13250397Sobrien	      validate_change (insn, &XEXP (use, 0),
13350397Sobrien			       gen_rtx_fmt_e (inc_code, Pmode, reg), 1);
13450397Sobrien	      if (apply_change_group ())
13550397Sobrien		{
13690075Sobrien		  /* If there is a REG_DEAD note on this insn, we must
13790075Sobrien		     change this not to REG_UNUSED meaning that the register
13890075Sobrien		     is set, but the value is dead.  Failure to do so will
139169689Skan		     result in a sched1 dieing -- when it recomputes lifetime
14090075Sobrien		     information, the number of REG_DEAD notes will have
14190075Sobrien		     changed.  */
14290075Sobrien		  rtx note = find_reg_note (insn, REG_DEAD, reg);
14390075Sobrien		  if (note)
14490075Sobrien		    PUT_MODE (note, REG_UNUSED);
14590075Sobrien
14650397Sobrien		  REG_NOTES (insn)
14750397Sobrien		    = gen_rtx_EXPR_LIST (REG_INC,
14850397Sobrien					 reg, REG_NOTES (insn));
14950397Sobrien		  if (! inc_insn_set)
15090075Sobrien		    delete_insn (inc_insn);
15150397Sobrien		  return 1;
15250397Sobrien		}
15350397Sobrien	    }
15450397Sobrien	}
15550397Sobrien    }
15650397Sobrien  return 0;
15750397Sobrien}
15852284Sobrien
15952284Sobrien/* Determine if the pattern generated by add_optab has a clobber,
16052284Sobrien   such as might be issued for a flags hard register.  To make the
16152284Sobrien   code elsewhere simpler, we handle cc0 in this same framework.
16250397Sobrien
16352284Sobrien   Return the register if one was discovered.  Return NULL_RTX if
16452284Sobrien   if no flags were found.  Return pc_rtx if we got confused.  */
16552284Sobrien
16652284Sobrienstatic rtx
167132718Skandiscover_flags_reg (void)
16852284Sobrien{
16952284Sobrien  rtx tmp;
17052284Sobrien  tmp = gen_rtx_REG (word_mode, 10000);
171169689Skan  tmp = gen_add3_insn (tmp, tmp, const2_rtx);
17252284Sobrien
17390075Sobrien  /* If we get something that isn't a simple set, or a
17452284Sobrien     [(set ..) (clobber ..)], this whole function will go wrong.  */
17552284Sobrien  if (GET_CODE (tmp) == SET)
17652284Sobrien    return NULL_RTX;
17752284Sobrien  else if (GET_CODE (tmp) == PARALLEL)
17852284Sobrien    {
17952284Sobrien      int found;
18052284Sobrien
18152284Sobrien      if (XVECLEN (tmp, 0) != 2)
18252284Sobrien	return pc_rtx;
18352284Sobrien      tmp = XVECEXP (tmp, 0, 1);
18452284Sobrien      if (GET_CODE (tmp) != CLOBBER)
18552284Sobrien	return pc_rtx;
18652284Sobrien      tmp = XEXP (tmp, 0);
18752284Sobrien
18852284Sobrien      /* Don't do anything foolish if the md wanted to clobber a
18952284Sobrien	 scratch or something.  We only care about hard regs.
19052284Sobrien	 Moreover we don't like the notion of subregs of hard regs.  */
19152284Sobrien      if (GET_CODE (tmp) == SUBREG
192169689Skan	  && REG_P (SUBREG_REG (tmp))
19352284Sobrien	  && REGNO (SUBREG_REG (tmp)) < FIRST_PSEUDO_REGISTER)
19452284Sobrien	return pc_rtx;
195169689Skan      found = (REG_P (tmp) && REGNO (tmp) < FIRST_PSEUDO_REGISTER);
19652284Sobrien
19752284Sobrien      return (found ? tmp : NULL_RTX);
19852284Sobrien    }
19952284Sobrien
20052284Sobrien  return pc_rtx;
20152284Sobrien}
20252284Sobrien
20352284Sobrien/* It is a tedious task identifying when the flags register is live and
20452284Sobrien   when it is safe to optimize.  Since we process the instruction stream
20552284Sobrien   multiple times, locate and record these live zones by marking the
20690075Sobrien   mode of the instructions --
20752284Sobrien
20852284Sobrien   QImode is used on the instruction at which the flags becomes live.
20952284Sobrien
21052284Sobrien   HImode is used within the range (exclusive) that the flags are
21152284Sobrien   live.  Thus the user of the flags is not marked.
21252284Sobrien
21352284Sobrien   All other instructions are cleared to VOIDmode.  */
21452284Sobrien
21552284Sobrien/* Used to communicate with flags_set_1.  */
21652284Sobrienstatic rtx flags_set_1_rtx;
21752284Sobrienstatic int flags_set_1_set;
21852284Sobrien
21952284Sobrienstatic void
220132718Skanmark_flags_life_zones (rtx flags)
22152284Sobrien{
22252284Sobrien  int flags_regno;
22352284Sobrien  int flags_nregs;
224117395Skan  basic_block 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
23390075Sobrien
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;
24090075Sobrien      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);
250169689Skan  flags_nregs = hard_regno_nregs[flags_regno][GET_MODE (flags)];
25152284Sobrien#endif
25252284Sobrien  flags_set_1_rtx = flags;
25352284Sobrien
25452284Sobrien  /* Process each basic block.  */
255117395Skan  FOR_EACH_BB_REVERSE (block)
25652284Sobrien    {
25752284Sobrien      rtx insn, end;
25852284Sobrien      int live;
25952284Sobrien
260132718Skan      insn = BB_HEAD (block);
261132718Skan      end = BB_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)
270169689Skan	  live |= REGNO_REG_SET_P (block->il.rtl->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
28190075Sobrien	  if (INSN_P (insn))
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
295169689Skan	      /* In either case, birth is denoted simply by its presence
29652284Sobrien		 as the destination of a set.  */
29752284Sobrien	      flags_set_1_set = 0;
29890075Sobrien	      note_stores (PATTERN (insn), flags_set_1, NULL);
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
318132718Skanflags_set_1 (rtx x, rtx pat, void *data ATTRIBUTE_UNUSED)
31952284Sobrien{
32052284Sobrien  if (GET_CODE (pat) == SET
32152284Sobrien      && reg_overlap_mentioned_p (x, flags_set_1_rtx))
32252284Sobrien    flags_set_1_set = 1;
32352284Sobrien}
32452284Sobrien
32550397Sobrienstatic int *regno_src_regno;
32650397Sobrien
32750397Sobrien/* Indicate how good a choice REG (which appears as a source) is to replace
32850397Sobrien   a destination register with.  The higher the returned value, the better
32950397Sobrien   the choice.  The main objective is to avoid using a register that is
33050397Sobrien   a candidate for tying to a hard register, since the output might in
33150397Sobrien   turn be a candidate to be tied to a different hard register.  */
33290075Sobrienstatic int
333132718Skanreplacement_quality (rtx reg)
33450397Sobrien{
33550397Sobrien  int src_regno;
33650397Sobrien
33750397Sobrien  /* Bad if this isn't a register at all.  */
338169689Skan  if (!REG_P (reg))
33950397Sobrien    return 0;
34050397Sobrien
34150397Sobrien  /* If this register is not meant to get a hard register,
34250397Sobrien     it is a poor choice.  */
34350397Sobrien  if (REG_LIVE_LENGTH (REGNO (reg)) < 0)
34450397Sobrien    return 0;
34550397Sobrien
34650397Sobrien  src_regno = regno_src_regno[REGNO (reg)];
34750397Sobrien
34850397Sobrien  /* If it was not copied from another register, it is fine.  */
34950397Sobrien  if (src_regno < 0)
35050397Sobrien    return 3;
35150397Sobrien
35250397Sobrien  /* Copied from a hard register?  */
35350397Sobrien  if (src_regno < FIRST_PSEUDO_REGISTER)
35450397Sobrien    return 1;
35550397Sobrien
35650397Sobrien  /* Copied from a pseudo register - not as bad as from a hard register,
35750397Sobrien     yet still cumbersome, since the register live length will be lengthened
35850397Sobrien     when the registers get tied.  */
35950397Sobrien  return 2;
36050397Sobrien}
36190075Sobrien
36290075Sobrien/* Return 1 if INSN might end a basic block.  */
36350397Sobrien
364132718Skanstatic int perhaps_ends_bb_p (rtx insn)
36590075Sobrien{
36690075Sobrien  switch (GET_CODE (insn))
36790075Sobrien    {
36890075Sobrien    case CODE_LABEL:
36990075Sobrien    case JUMP_INSN:
37090075Sobrien      /* These always end a basic block.  */
37190075Sobrien      return 1;
37290075Sobrien
37390075Sobrien    case CALL_INSN:
37490075Sobrien      /* A CALL_INSN might be the last insn of a basic block, if it is inside
37590075Sobrien	 an EH region or if there are nonlocal gotos.  Note that this test is
37690075Sobrien	 very conservative.  */
37790075Sobrien      if (nonlocal_goto_handler_labels)
37890075Sobrien	return 1;
379132718Skan      /* Fall through.  */
38090075Sobrien    default:
38190075Sobrien      return can_throw_internal (insn);
38290075Sobrien    }
38390075Sobrien}
38490075Sobrien
38550397Sobrien/* INSN is a copy from SRC to DEST, both registers, and SRC does not die
38650397Sobrien   in INSN.
38750397Sobrien
38850397Sobrien   Search forward to see if SRC dies before either it or DEST is modified,
38950397Sobrien   but don't scan past the end of a basic block.  If so, we can replace SRC
39090075Sobrien   with DEST and let SRC die in INSN.
39150397Sobrien
39250397Sobrien   This will reduce the number of registers live in that range and may enable
39350397Sobrien   DEST to be tied to SRC, thus often saving one register in addition to a
39450397Sobrien   register-register copy.  */
39550397Sobrien
39650397Sobrienstatic int
397132718Skanoptimize_reg_copy_1 (rtx insn, rtx dest, rtx src)
39850397Sobrien{
39950397Sobrien  rtx p, q;
40050397Sobrien  rtx note;
40150397Sobrien  rtx dest_death = 0;
40250397Sobrien  int sregno = REGNO (src);
40350397Sobrien  int dregno = REGNO (dest);
40450397Sobrien
40590075Sobrien  /* We don't want to mess with hard regs if register classes are small.  */
40650397Sobrien  if (sregno == dregno
40750397Sobrien      || (SMALL_REGISTER_CLASSES
40850397Sobrien	  && (sregno < FIRST_PSEUDO_REGISTER
40950397Sobrien	      || dregno < FIRST_PSEUDO_REGISTER))
41050397Sobrien      /* We don't see all updates to SP if they are in an auto-inc memory
41150397Sobrien	 reference, so we must disallow this optimization on them.  */
41250397Sobrien      || sregno == STACK_POINTER_REGNUM || dregno == STACK_POINTER_REGNUM)
41350397Sobrien    return 0;
41450397Sobrien
41550397Sobrien  for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
41650397Sobrien    {
41750397Sobrien      /* ??? We can't scan past the end of a basic block without updating
41890075Sobrien	 the register lifetime info (REG_DEAD/basic_block_live_at_start).  */
41990075Sobrien      if (perhaps_ends_bb_p (p))
42050397Sobrien	break;
42190075Sobrien      else if (! INSN_P (p))
42250397Sobrien	continue;
42350397Sobrien
42450397Sobrien      if (reg_set_p (src, p) || reg_set_p (dest, p)
425117395Skan	  /* If SRC is an asm-declared register, it must not be replaced
426117395Skan	     in any asm.  Unfortunately, the REG_EXPR tree for the asm
427117395Skan	     variable may be absent in the SRC rtx, so we can't check the
428117395Skan	     actual register declaration easily (the asm operand will have
429117395Skan	     it, though).  To avoid complicating the test for a rare case,
430117395Skan	     we just don't perform register replacement for a hard reg
431117395Skan	     mentioned in an asm.  */
432117395Skan	  || (sregno < FIRST_PSEUDO_REGISTER
433117395Skan	      && asm_noperands (PATTERN (p)) >= 0
434117395Skan	      && reg_overlap_mentioned_p (src, PATTERN (p)))
435169689Skan	  /* Don't change hard registers used by a call.  */
436169689Skan	  || (CALL_P (p) && sregno < FIRST_PSEUDO_REGISTER
437169689Skan	      && find_reg_fusage (p, USE, src))
43850397Sobrien	  /* Don't change a USE of a register.  */
43950397Sobrien	  || (GET_CODE (PATTERN (p)) == USE
44050397Sobrien	      && reg_overlap_mentioned_p (src, XEXP (PATTERN (p), 0))))
44150397Sobrien	break;
44250397Sobrien
44350397Sobrien      /* See if all of SRC dies in P.  This test is slightly more
44450397Sobrien	 conservative than it needs to be.  */
44550397Sobrien      if ((note = find_regno_note (p, REG_DEAD, sregno)) != 0
44650397Sobrien	  && GET_MODE (XEXP (note, 0)) == GET_MODE (src))
44750397Sobrien	{
44850397Sobrien	  int failed = 0;
44950397Sobrien	  int d_length = 0;
45050397Sobrien	  int s_length = 0;
45150397Sobrien	  int d_n_calls = 0;
45250397Sobrien	  int s_n_calls = 0;
45350397Sobrien
45450397Sobrien	  /* We can do the optimization.  Scan forward from INSN again,
45550397Sobrien	     replacing regs as we go.  Set FAILED if a replacement can't
45650397Sobrien	     be done.  In that case, we can't move the death note for SRC.
45750397Sobrien	     This should be rare.  */
45850397Sobrien
45950397Sobrien	  /* Set to stop at next insn.  */
46050397Sobrien	  for (q = next_real_insn (insn);
46150397Sobrien	       q != next_real_insn (p);
46250397Sobrien	       q = next_real_insn (q))
46350397Sobrien	    {
46450397Sobrien	      if (reg_overlap_mentioned_p (src, PATTERN (q)))
46550397Sobrien		{
46650397Sobrien		  /* If SRC is a hard register, we might miss some
46750397Sobrien		     overlapping registers with validate_replace_rtx,
46850397Sobrien		     so we would have to undo it.  We can't if DEST is
46950397Sobrien		     present in the insn, so fail in that combination
47050397Sobrien		     of cases.  */
47150397Sobrien		  if (sregno < FIRST_PSEUDO_REGISTER
47250397Sobrien		      && reg_mentioned_p (dest, PATTERN (q)))
47350397Sobrien		    failed = 1;
47450397Sobrien
47550397Sobrien		  /* Replace all uses and make sure that the register
47650397Sobrien		     isn't still present.  */
47750397Sobrien		  else if (validate_replace_rtx (src, dest, q)
47850397Sobrien			   && (sregno >= FIRST_PSEUDO_REGISTER
47950397Sobrien			       || ! reg_overlap_mentioned_p (src,
48050397Sobrien							     PATTERN (q))))
48190075Sobrien		    ;
48250397Sobrien		  else
48350397Sobrien		    {
48450397Sobrien		      validate_replace_rtx (dest, src, q);
48550397Sobrien		      failed = 1;
48650397Sobrien		    }
48750397Sobrien		}
48850397Sobrien
48950397Sobrien	      /* For SREGNO, count the total number of insns scanned.
49050397Sobrien		 For DREGNO, count the total number of insns scanned after
49150397Sobrien		 passing the death note for DREGNO.  */
49250397Sobrien	      s_length++;
49350397Sobrien	      if (dest_death)
49450397Sobrien		d_length++;
49550397Sobrien
49650397Sobrien	      /* If the insn in which SRC dies is a CALL_INSN, don't count it
49750397Sobrien		 as a call that has been crossed.  Otherwise, count it.  */
498169689Skan	      if (q != p && CALL_P (q))
49950397Sobrien		{
50050397Sobrien		  /* Similarly, total calls for SREGNO, total calls beyond
50150397Sobrien		     the death note for DREGNO.  */
50250397Sobrien		  s_n_calls++;
50350397Sobrien		  if (dest_death)
50450397Sobrien		    d_n_calls++;
50550397Sobrien		}
50650397Sobrien
50750397Sobrien	      /* If DEST dies here, remove the death note and save it for
50850397Sobrien		 later.  Make sure ALL of DEST dies here; again, this is
50950397Sobrien		 overly conservative.  */
51050397Sobrien	      if (dest_death == 0
51150397Sobrien		  && (dest_death = find_regno_note (q, REG_DEAD, dregno)) != 0)
51250397Sobrien		{
51350397Sobrien		  if (GET_MODE (XEXP (dest_death, 0)) != GET_MODE (dest))
51450397Sobrien		    failed = 1, dest_death = 0;
51550397Sobrien		  else
51650397Sobrien		    remove_note (q, dest_death);
51750397Sobrien		}
51850397Sobrien	    }
51950397Sobrien
52050397Sobrien	  if (! failed)
52150397Sobrien	    {
52250397Sobrien	      /* These counters need to be updated if and only if we are
52350397Sobrien		 going to move the REG_DEAD note.  */
52450397Sobrien	      if (sregno >= FIRST_PSEUDO_REGISTER)
52550397Sobrien		{
52650397Sobrien		  if (REG_LIVE_LENGTH (sregno) >= 0)
52750397Sobrien		    {
52850397Sobrien		      REG_LIVE_LENGTH (sregno) -= s_length;
52950397Sobrien		      /* REG_LIVE_LENGTH is only an approximation after
53050397Sobrien			 combine if sched is not run, so make sure that we
53150397Sobrien			 still have a reasonable value.  */
53250397Sobrien		      if (REG_LIVE_LENGTH (sregno) < 2)
53350397Sobrien			REG_LIVE_LENGTH (sregno) = 2;
53450397Sobrien		    }
53550397Sobrien
53650397Sobrien		  REG_N_CALLS_CROSSED (sregno) -= s_n_calls;
53750397Sobrien		}
53850397Sobrien
53950397Sobrien	      /* Move death note of SRC from P to INSN.  */
54050397Sobrien	      remove_note (p, note);
54150397Sobrien	      XEXP (note, 1) = REG_NOTES (insn);
54250397Sobrien	      REG_NOTES (insn) = note;
54350397Sobrien	    }
54450397Sobrien
54590075Sobrien	  /* DEST is also dead if INSN has a REG_UNUSED note for DEST.  */
54690075Sobrien	  if (! dest_death
54790075Sobrien	      && (dest_death = find_regno_note (insn, REG_UNUSED, dregno)))
54890075Sobrien	    {
54990075Sobrien	      PUT_REG_NOTE_KIND (dest_death, REG_DEAD);
55090075Sobrien	      remove_note (insn, dest_death);
55190075Sobrien	    }
55290075Sobrien
55350397Sobrien	  /* Put death note of DEST on P if we saw it die.  */
55450397Sobrien	  if (dest_death)
55550397Sobrien	    {
55650397Sobrien	      XEXP (dest_death, 1) = REG_NOTES (p);
55750397Sobrien	      REG_NOTES (p) = dest_death;
55850397Sobrien
55950397Sobrien	      if (dregno >= FIRST_PSEUDO_REGISTER)
56050397Sobrien		{
56150397Sobrien		  /* If and only if we are moving the death note for DREGNO,
56250397Sobrien		     then we need to update its counters.  */
56350397Sobrien		  if (REG_LIVE_LENGTH (dregno) >= 0)
56450397Sobrien		    REG_LIVE_LENGTH (dregno) += d_length;
56550397Sobrien		  REG_N_CALLS_CROSSED (dregno) += d_n_calls;
56650397Sobrien		}
56750397Sobrien	    }
56850397Sobrien
56950397Sobrien	  return ! failed;
57050397Sobrien	}
57150397Sobrien
57250397Sobrien      /* If SRC is a hard register which is set or killed in some other
57350397Sobrien	 way, we can't do this optimization.  */
57450397Sobrien      else if (sregno < FIRST_PSEUDO_REGISTER
57550397Sobrien	       && dead_or_set_p (p, src))
57650397Sobrien	break;
57750397Sobrien    }
57850397Sobrien  return 0;
57950397Sobrien}
58050397Sobrien
58150397Sobrien/* INSN is a copy of SRC to DEST, in which SRC dies.  See if we now have
58250397Sobrien   a sequence of insns that modify DEST followed by an insn that sets
58350397Sobrien   SRC to DEST in which DEST dies, with no prior modification of DEST.
58450397Sobrien   (There is no need to check if the insns in between actually modify
58550397Sobrien   DEST.  We should not have cases where DEST is not modified, but
58650397Sobrien   the optimization is safe if no such modification is detected.)
58750397Sobrien   In that case, we can replace all uses of DEST, starting with INSN and
58850397Sobrien   ending with the set of SRC to DEST, with SRC.  We do not do this
58950397Sobrien   optimization if a CALL_INSN is crossed unless SRC already crosses a
59050397Sobrien   call or if DEST dies before the copy back to SRC.
59150397Sobrien
59250397Sobrien   It is assumed that DEST and SRC are pseudos; it is too complicated to do
59350397Sobrien   this for hard registers since the substitutions we may make might fail.  */
59450397Sobrien
59550397Sobrienstatic void
596132718Skanoptimize_reg_copy_2 (rtx insn, rtx dest, rtx src)
59750397Sobrien{
59850397Sobrien  rtx p, q;
59950397Sobrien  rtx set;
60050397Sobrien  int sregno = REGNO (src);
60150397Sobrien  int dregno = REGNO (dest);
60250397Sobrien
60350397Sobrien  for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
60450397Sobrien    {
60550397Sobrien      /* ??? We can't scan past the end of a basic block without updating
60690075Sobrien	 the register lifetime info (REG_DEAD/basic_block_live_at_start).  */
60790075Sobrien      if (perhaps_ends_bb_p (p))
60850397Sobrien	break;
60990075Sobrien      else if (! INSN_P (p))
61050397Sobrien	continue;
61150397Sobrien
61250397Sobrien      set = single_set (p);
61350397Sobrien      if (set && SET_SRC (set) == dest && SET_DEST (set) == src
61450397Sobrien	  && find_reg_note (p, REG_DEAD, dest))
61550397Sobrien	{
61650397Sobrien	  /* We can do the optimization.  Scan forward from INSN again,
61750397Sobrien	     replacing regs as we go.  */
61850397Sobrien
61950397Sobrien	  /* Set to stop at next insn.  */
62050397Sobrien	  for (q = insn; q != NEXT_INSN (p); q = NEXT_INSN (q))
62190075Sobrien	    if (INSN_P (q))
62250397Sobrien	      {
62350397Sobrien		if (reg_mentioned_p (dest, PATTERN (q)))
62490075Sobrien		  PATTERN (q) = replace_rtx (PATTERN (q), dest, src);
62550397Sobrien
62650397Sobrien
627169689Skan	      if (CALL_P (q))
62850397Sobrien		{
62950397Sobrien		  REG_N_CALLS_CROSSED (dregno)--;
63050397Sobrien		  REG_N_CALLS_CROSSED (sregno)++;
63150397Sobrien		}
63250397Sobrien	      }
63350397Sobrien
63450397Sobrien	  remove_note (p, find_reg_note (p, REG_DEAD, dest));
63550397Sobrien	  REG_N_DEATHS (dregno)--;
63650397Sobrien	  remove_note (insn, find_reg_note (insn, REG_DEAD, src));
63750397Sobrien	  REG_N_DEATHS (sregno)--;
63850397Sobrien	  return;
63950397Sobrien	}
64050397Sobrien
64150397Sobrien      if (reg_set_p (src, p)
64250397Sobrien	  || find_reg_note (p, REG_DEAD, dest)
643169689Skan	  || (CALL_P (p) && REG_N_CALLS_CROSSED (sregno) == 0))
64450397Sobrien	break;
64550397Sobrien    }
64650397Sobrien}
64750397Sobrien/* INSN is a ZERO_EXTEND or SIGN_EXTEND of SRC to DEST.
64850397Sobrien   Look if SRC dies there, and if it is only set once, by loading
649132718Skan   it from memory.  If so, try to incorporate the zero/sign extension
65050397Sobrien   into the memory read, change SRC to the mode of DEST, and alter
65150397Sobrien   the remaining accesses to use the appropriate SUBREG.  This allows
65250397Sobrien   SRC and DEST to be tied later.  */
65350397Sobrienstatic void
654132718Skanoptimize_reg_copy_3 (rtx insn, rtx dest, rtx src)
65550397Sobrien{
65650397Sobrien  rtx src_reg = XEXP (src, 0);
65750397Sobrien  int src_no = REGNO (src_reg);
65850397Sobrien  int dst_no = REGNO (dest);
659169689Skan  rtx p, set;
66050397Sobrien  enum machine_mode old_mode;
66150397Sobrien
66250397Sobrien  if (src_no < FIRST_PSEUDO_REGISTER
66350397Sobrien      || dst_no < FIRST_PSEUDO_REGISTER
66450397Sobrien      || ! find_reg_note (insn, REG_DEAD, src_reg)
665102780Skan      || REG_N_DEATHS (src_no) != 1
66650397Sobrien      || REG_N_SETS (src_no) != 1)
66750397Sobrien    return;
66890075Sobrien  for (p = PREV_INSN (insn); p && ! reg_set_p (src_reg, p); p = PREV_INSN (p))
66990075Sobrien    /* ??? We can't scan past the end of a basic block without updating
67090075Sobrien       the register lifetime info (REG_DEAD/basic_block_live_at_start).  */
67190075Sobrien    if (perhaps_ends_bb_p (p))
67290075Sobrien      break;
67350397Sobrien
67490075Sobrien  if (! p)
67590075Sobrien    return;
67650397Sobrien
67750397Sobrien  if (! (set = single_set (p))
678169689Skan      || !MEM_P (SET_SRC (set))
67990075Sobrien      /* If there's a REG_EQUIV note, this must be an insn that loads an
68090075Sobrien	 argument.  Prefer keeping the note over doing this optimization.  */
68190075Sobrien      || find_reg_note (p, REG_EQUIV, NULL_RTX)
68250397Sobrien      || SET_DEST (set) != src_reg)
68350397Sobrien    return;
68452284Sobrien
685132718Skan  /* Be conservative: although this optimization is also valid for
68652284Sobrien     volatile memory references, that could cause trouble in later passes.  */
68752284Sobrien  if (MEM_VOLATILE_P (SET_SRC (set)))
68852284Sobrien    return;
68952284Sobrien
69052284Sobrien  /* Do not use a SUBREG to truncate from one mode to another if truncation
69152284Sobrien     is not a nop.  */
69252284Sobrien  if (GET_MODE_BITSIZE (GET_MODE (src_reg)) <= GET_MODE_BITSIZE (GET_MODE (src))
69352284Sobrien      && !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (src)),
69452284Sobrien				 GET_MODE_BITSIZE (GET_MODE (src_reg))))
69552284Sobrien    return;
69652284Sobrien
69750397Sobrien  old_mode = GET_MODE (src_reg);
69850397Sobrien  PUT_MODE (src_reg, GET_MODE (src));
69950397Sobrien  XEXP (src, 0) = SET_SRC (set);
70052284Sobrien
70152284Sobrien  /* Include this change in the group so that it's easily undone if
70252284Sobrien     one of the changes in the group is invalid.  */
70352284Sobrien  validate_change (p, &SET_SRC (set), src, 1);
70452284Sobrien
70552284Sobrien  /* Now walk forward making additional replacements.  We want to be able
70652284Sobrien     to undo all the changes if a later substitution fails.  */
70750397Sobrien  while (p = NEXT_INSN (p), p != insn)
70850397Sobrien    {
70990075Sobrien      if (! INSN_P (p))
71050397Sobrien	continue;
71152284Sobrien
712132718Skan      /* Make a tentative change.  */
713169689Skan      validate_replace_rtx_group (src_reg,
714169689Skan				  gen_lowpart_SUBREG (old_mode, src_reg),
715169689Skan				  p);
71650397Sobrien    }
71752284Sobrien
71852284Sobrien  validate_replace_rtx_group (src, src_reg, insn);
71952284Sobrien
72052284Sobrien  /* Now see if all the changes are valid.  */
72152284Sobrien  if (! apply_change_group ())
72252284Sobrien    {
72352284Sobrien      /* One or more changes were no good.  Back out everything.  */
72452284Sobrien      PUT_MODE (src_reg, old_mode);
72552284Sobrien      XEXP (src, 0) = src_reg;
72652284Sobrien    }
72790075Sobrien  else
72890075Sobrien    {
72990075Sobrien      rtx note = find_reg_note (p, REG_EQUAL, NULL_RTX);
73090075Sobrien      if (note)
73190075Sobrien	remove_note (p, note);
73290075Sobrien    }
73350397Sobrien}
73450397Sobrien
73550397Sobrien
73650397Sobrien/* If we were not able to update the users of src to use dest directly, try
73750397Sobrien   instead moving the value to dest directly before the operation.  */
73850397Sobrien
73950397Sobrienstatic void
740132718Skancopy_src_to_dest (rtx insn, rtx src, rtx dest, int old_max_uid)
74150397Sobrien{
74250397Sobrien  rtx seq;
74350397Sobrien  rtx link;
74450397Sobrien  rtx next;
74550397Sobrien  rtx set;
74650397Sobrien  rtx move_insn;
74750397Sobrien  rtx *p_insn_notes;
74850397Sobrien  rtx *p_move_notes;
74950397Sobrien  int src_regno;
75050397Sobrien  int dest_regno;
75150397Sobrien  int bb;
75250397Sobrien  int insn_uid;
75350397Sobrien  int move_uid;
75450397Sobrien
75550397Sobrien  /* A REG_LIVE_LENGTH of -1 indicates the register is equivalent to a constant
75650397Sobrien     or memory location and is used infrequently; a REG_LIVE_LENGTH of -2 is
75750397Sobrien     parameter when there is no frame pointer that is not allocated a register.
75850397Sobrien     For now, we just reject them, rather than incrementing the live length.  */
75950397Sobrien
760169689Skan  if (REG_P (src)
76150397Sobrien      && REG_LIVE_LENGTH (REGNO (src)) > 0
762169689Skan      && REG_P (dest)
76350397Sobrien      && REG_LIVE_LENGTH (REGNO (dest)) > 0
76450397Sobrien      && (set = single_set (insn)) != NULL_RTX
76550397Sobrien      && !reg_mentioned_p (dest, SET_SRC (set))
76652284Sobrien      && GET_MODE (src) == GET_MODE (dest))
76750397Sobrien    {
76852284Sobrien      int old_num_regs = reg_rtx_no;
76952284Sobrien
77050397Sobrien      /* Generate the src->dest move.  */
77150397Sobrien      start_sequence ();
77250397Sobrien      emit_move_insn (dest, src);
773117395Skan      seq = get_insns ();
77450397Sobrien      end_sequence ();
77552284Sobrien      /* If this sequence uses new registers, we may not use it.  */
77652284Sobrien      if (old_num_regs != reg_rtx_no
77752284Sobrien	  || ! validate_replace_rtx (src, dest, insn))
77852284Sobrien	{
77952284Sobrien	  /* We have to restore reg_rtx_no to its old value, lest
78052284Sobrien	     recompute_reg_usage will try to compute the usage of the
78152284Sobrien	     new regs, yet reg_n_info is not valid for them.  */
78252284Sobrien	  reg_rtx_no = old_num_regs;
78352284Sobrien	  return;
78452284Sobrien	}
78550397Sobrien      emit_insn_before (seq, insn);
78650397Sobrien      move_insn = PREV_INSN (insn);
78750397Sobrien      p_move_notes = &REG_NOTES (move_insn);
78850397Sobrien      p_insn_notes = &REG_NOTES (insn);
78950397Sobrien
790117395Skan      /* Move any notes mentioning src to the move instruction.  */
79150397Sobrien      for (link = REG_NOTES (insn); link != NULL_RTX; link = next)
79250397Sobrien	{
79350397Sobrien	  next = XEXP (link, 1);
79450397Sobrien	  if (XEXP (link, 0) == src)
79550397Sobrien	    {
79650397Sobrien	      *p_move_notes = link;
79750397Sobrien	      p_move_notes = &XEXP (link, 1);
79850397Sobrien	    }
79950397Sobrien	  else
80050397Sobrien	    {
80150397Sobrien	      *p_insn_notes = link;
80250397Sobrien	      p_insn_notes = &XEXP (link, 1);
80350397Sobrien	    }
80450397Sobrien	}
80550397Sobrien
80650397Sobrien      *p_move_notes = NULL_RTX;
80750397Sobrien      *p_insn_notes = NULL_RTX;
80850397Sobrien
809117395Skan      /* Is the insn the head of a basic block?  If so extend it.  */
81050397Sobrien      insn_uid = INSN_UID (insn);
81150397Sobrien      move_uid = INSN_UID (move_insn);
81252284Sobrien      if (insn_uid < old_max_uid)
81350397Sobrien	{
81452284Sobrien	  bb = regmove_bb_head[insn_uid];
81552284Sobrien	  if (bb >= 0)
81652284Sobrien	    {
817132718Skan	      BB_HEAD (BASIC_BLOCK (bb)) = move_insn;
81852284Sobrien	      regmove_bb_head[insn_uid] = -1;
81952284Sobrien	    }
82050397Sobrien	}
82150397Sobrien
82250397Sobrien      /* Update the various register tables.  */
82350397Sobrien      dest_regno = REGNO (dest);
82490075Sobrien      REG_N_SETS (dest_regno) ++;
82550397Sobrien      REG_LIVE_LENGTH (dest_regno)++;
82650397Sobrien      if (REGNO_FIRST_UID (dest_regno) == insn_uid)
82750397Sobrien	REGNO_FIRST_UID (dest_regno) = move_uid;
82850397Sobrien
82950397Sobrien      src_regno = REGNO (src);
83050397Sobrien      if (! find_reg_note (move_insn, REG_DEAD, src))
83150397Sobrien	REG_LIVE_LENGTH (src_regno)++;
83250397Sobrien
83350397Sobrien      if (REGNO_FIRST_UID (src_regno) == insn_uid)
83450397Sobrien	REGNO_FIRST_UID (src_regno) = move_uid;
83550397Sobrien
83650397Sobrien      if (REGNO_LAST_UID (src_regno) == insn_uid)
83750397Sobrien	REGNO_LAST_UID (src_regno) = move_uid;
83850397Sobrien    }
83950397Sobrien}
84050397Sobrien
841169689Skan/* reg_set_in_bb[REGNO] points to basic block iff the register is set
842169689Skan   only once in the given block and has REG_EQUAL note.  */
843169689Skan
844169689Skanbasic_block *reg_set_in_bb;
845169689Skan
846169689Skan/* Size of reg_set_in_bb array.  */
847169689Skanstatic unsigned int max_reg_computed;
848169689Skan
84950397Sobrien
85050397Sobrien/* Return whether REG is set in only one location, and is set to a
85150397Sobrien   constant, but is set in a different basic block from INSN (an
85250397Sobrien   instructions which uses REG).  In this case REG is equivalent to a
85350397Sobrien   constant, and we don't want to break that equivalence, because that
85450397Sobrien   may increase register pressure and make reload harder.  If REG is
85550397Sobrien   set in the same basic block as INSN, we don't worry about it,
85650397Sobrien   because we'll probably need a register anyhow (??? but what if REG
85750397Sobrien   is used in a different basic block as well as this one?).  FIRST is
85850397Sobrien   the first insn in the function.  */
85950397Sobrien
860169689Skanstatic bool
861169689Skanreg_is_remote_constant_p (rtx reg, rtx insn)
86250397Sobrien{
863169689Skan  basic_block bb;
86490075Sobrien  rtx p;
865169689Skan  int max;
86650397Sobrien
867169689Skan  if (!reg_set_in_bb)
86850397Sobrien    {
869169689Skan      max_reg_computed = max = max_reg_num ();
870169689Skan      reg_set_in_bb = xcalloc (max, sizeof (*reg_set_in_bb));
87150397Sobrien
872169689Skan      FOR_EACH_BB (bb)
873169689Skan	for (p = BB_HEAD (bb); p != NEXT_INSN (BB_END (bb));
874169689Skan	     p = NEXT_INSN (p))
87550397Sobrien	{
876169689Skan	  rtx s;
877169689Skan
878169689Skan	  if (!INSN_P (p))
879169689Skan	    continue;
880169689Skan	  s = single_set (p);
881169689Skan	  /* This is the instruction which sets REG.  If there is a
882169689Skan	     REG_EQUAL note, then REG is equivalent to a constant.  */
883169689Skan	  if (s != 0
884169689Skan	      && REG_P (SET_DEST (s))
885169689Skan	      && REG_N_SETS (REGNO (SET_DEST (s))) == 1
886169689Skan	      && find_reg_note (p, REG_EQUAL, NULL_RTX))
887169689Skan	    reg_set_in_bb[REGNO (SET_DEST (s))] = bb;
88850397Sobrien	}
88950397Sobrien    }
890169689Skan  gcc_assert (REGNO (reg) < max_reg_computed);
891169689Skan  if (reg_set_in_bb[REGNO (reg)] == NULL)
892169689Skan    return false;
893169689Skan  if (reg_set_in_bb[REGNO (reg)] != BLOCK_FOR_INSN (insn))
894169689Skan    return true;
895169689Skan  /* Look for the set.  */
896169689Skan  for (p = BB_HEAD (BLOCK_FOR_INSN (insn)); p != insn; p = NEXT_INSN (p))
89750397Sobrien    {
89850397Sobrien      rtx s;
89950397Sobrien
900169689Skan      if (!INSN_P (p))
90150397Sobrien	continue;
90250397Sobrien      s = single_set (p);
90350397Sobrien      if (s != 0
904169689Skan	  && REG_P (SET_DEST (s)) && REGNO (SET_DEST (s)) == REGNO (reg))
90550397Sobrien	{
906169689Skan	  /* The register is set in the same basic block.  */
907169689Skan	  return false;
90850397Sobrien	}
90950397Sobrien    }
910169689Skan  return true;
91150397Sobrien}
91250397Sobrien
91350397Sobrien/* INSN is adding a CONST_INT to a REG.  We search backwards looking for
91450397Sobrien   another add immediate instruction with the same source and dest registers,
91550397Sobrien   and if we find one, we change INSN to an increment, and return 1.  If
91650397Sobrien   no changes are made, we return 0.
91750397Sobrien
91850397Sobrien   This changes
91950397Sobrien     (set (reg100) (plus reg1 offset1))
92050397Sobrien     ...
92150397Sobrien     (set (reg100) (plus reg1 offset2))
92250397Sobrien   to
92350397Sobrien     (set (reg100) (plus reg1 offset1))
92450397Sobrien     ...
92550397Sobrien     (set (reg100) (plus reg100 offset2-offset1))  */
92650397Sobrien
92750397Sobrien/* ??? What does this comment mean?  */
928132718Skan/* cse disrupts preincrement / postdecrement sequences when it finds a
92950397Sobrien   hard register as ultimate source, like the frame pointer.  */
93050397Sobrien
93190075Sobrienstatic int
932169689Skanfixup_match_2 (rtx insn, rtx dst, rtx src, rtx offset)
93350397Sobrien{
93450397Sobrien  rtx p, dst_death = 0;
93550397Sobrien  int length, num_calls = 0;
93650397Sobrien
93750397Sobrien  /* If SRC dies in INSN, we'd have to move the death note.  This is
93850397Sobrien     considered to be very unlikely, so we just skip the optimization
93950397Sobrien     in this case.  */
94050397Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (src)))
94150397Sobrien    return 0;
94250397Sobrien
94350397Sobrien  /* Scan backward to find the first instruction that sets DST.  */
94450397Sobrien
94550397Sobrien  for (length = 0, p = PREV_INSN (insn); p; p = PREV_INSN (p))
94650397Sobrien    {
94750397Sobrien      rtx pset;
94850397Sobrien
94950397Sobrien      /* ??? We can't scan past the end of a basic block without updating
95090075Sobrien	 the register lifetime info (REG_DEAD/basic_block_live_at_start).  */
95190075Sobrien      if (perhaps_ends_bb_p (p))
95250397Sobrien	break;
95390075Sobrien      else if (! INSN_P (p))
954117395Skan	continue;
95550397Sobrien
95650397Sobrien      if (find_regno_note (p, REG_DEAD, REGNO (dst)))
95750397Sobrien	dst_death = p;
95850397Sobrien      if (! dst_death)
95950397Sobrien	length++;
96050397Sobrien
96150397Sobrien      pset = single_set (p);
96250397Sobrien      if (pset && SET_DEST (pset) == dst
96350397Sobrien	  && GET_CODE (SET_SRC (pset)) == PLUS
96450397Sobrien	  && XEXP (SET_SRC (pset), 0) == src
96550397Sobrien	  && GET_CODE (XEXP (SET_SRC (pset), 1)) == CONST_INT)
966117395Skan	{
96750397Sobrien	  HOST_WIDE_INT newconst
96850397Sobrien	    = INTVAL (offset) - INTVAL (XEXP (SET_SRC (pset), 1));
96950397Sobrien	  rtx add = gen_add3_insn (dst, dst, GEN_INT (newconst));
97050397Sobrien
97150397Sobrien	  if (add && validate_change (insn, &PATTERN (insn), add, 0))
97250397Sobrien	    {
97350397Sobrien	      /* Remove the death note for DST from DST_DEATH.  */
97450397Sobrien	      if (dst_death)
97550397Sobrien		{
97650397Sobrien		  remove_death (REGNO (dst), dst_death);
97750397Sobrien		  REG_LIVE_LENGTH (REGNO (dst)) += length;
97850397Sobrien		  REG_N_CALLS_CROSSED (REGNO (dst)) += num_calls;
97950397Sobrien		}
98050397Sobrien
981169689Skan	      if (dump_file)
982169689Skan		fprintf (dump_file,
98350397Sobrien			 "Fixed operand of insn %d.\n",
98450397Sobrien			  INSN_UID (insn));
98550397Sobrien
98650397Sobrien#ifdef AUTO_INC_DEC
98750397Sobrien	      for (p = PREV_INSN (insn); p; p = PREV_INSN (p))
98850397Sobrien		{
989169689Skan		  if (LABEL_P (p)
990169689Skan		      || JUMP_P (p))
99150397Sobrien		    break;
99290075Sobrien		  if (! INSN_P (p))
99350397Sobrien		    continue;
99450397Sobrien		  if (reg_overlap_mentioned_p (dst, PATTERN (p)))
99550397Sobrien		    {
99650397Sobrien		      if (try_auto_increment (p, insn, 0, dst, newconst, 0))
99750397Sobrien			return 1;
99850397Sobrien		      break;
99950397Sobrien		    }
100050397Sobrien		}
100150397Sobrien	      for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
100250397Sobrien		{
1003169689Skan		  if (LABEL_P (p)
1004169689Skan		      || JUMP_P (p))
100550397Sobrien		    break;
100690075Sobrien		  if (! INSN_P (p))
100750397Sobrien		    continue;
100850397Sobrien		  if (reg_overlap_mentioned_p (dst, PATTERN (p)))
100950397Sobrien		    {
101050397Sobrien		      try_auto_increment (p, insn, 0, dst, newconst, 1);
101150397Sobrien		      break;
101250397Sobrien		    }
101350397Sobrien		}
101450397Sobrien#endif
101550397Sobrien	      return 1;
101650397Sobrien	    }
1017117395Skan	}
101850397Sobrien
101950397Sobrien      if (reg_set_p (dst, PATTERN (p)))
1020117395Skan	break;
102150397Sobrien
102250397Sobrien      /* If we have passed a call instruction, and the
102350397Sobrien         pseudo-reg SRC is not already live across a call,
102450397Sobrien         then don't perform the optimization.  */
102550397Sobrien      /* reg_set_p is overly conservative for CALL_INSNS, thinks that all
102650397Sobrien	 hard regs are clobbered.  Thus, we only use it for src for
102750397Sobrien	 non-call insns.  */
1028169689Skan      if (CALL_P (p))
1029117395Skan	{
103050397Sobrien	  if (! dst_death)
103150397Sobrien	    num_calls++;
103250397Sobrien
1033117395Skan	  if (REG_N_CALLS_CROSSED (REGNO (src)) == 0)
1034117395Skan	    break;
103550397Sobrien
103650397Sobrien	  if (call_used_regs [REGNO (dst)]
103750397Sobrien	      || find_reg_fusage (p, CLOBBER, dst))
103850397Sobrien	    break;
1039117395Skan	}
104050397Sobrien      else if (reg_set_p (src, PATTERN (p)))
1041117395Skan	break;
104250397Sobrien    }
104350397Sobrien
104450397Sobrien  return 0;
104550397Sobrien}
104650397Sobrien
104790075Sobrien/* Main entry for the register move optimization.
104890075Sobrien   F is the first instruction.
104990075Sobrien   NREGS is one plus the highest pseudo-reg number used in the instruction.
105090075Sobrien   REGMOVE_DUMP_FILE is a stream for output of a trace of actions taken
105190075Sobrien   (or 0 if none should be output).  */
105290075Sobrien
1053169689Skanstatic void
1054169689Skanregmove_optimize (rtx f, int nregs)
105550397Sobrien{
105652284Sobrien  int old_max_uid = get_max_uid ();
105750397Sobrien  rtx insn;
105850397Sobrien  struct match match;
105950397Sobrien  int pass;
106052284Sobrien  int i;
106150397Sobrien  rtx copy_src, copy_dst;
1062117395Skan  basic_block bb;
106350397Sobrien
106490075Sobrien  /* ??? Hack.  Regmove doesn't examine the CFG, and gets mightily
106590075Sobrien     confused by non-call exceptions ending blocks.  */
106690075Sobrien  if (flag_non_call_exceptions)
106790075Sobrien    return;
106890075Sobrien
106952284Sobrien  /* Find out where a potential flags register is live, and so that we
1070132718Skan     can suppress some optimizations in those zones.  */
107152284Sobrien  mark_flags_life_zones (discover_flags_reg ());
107250397Sobrien
1073169689Skan  regno_src_regno = XNEWVEC (int, nregs);
107452284Sobrien  for (i = nregs; --i >= 0; ) regno_src_regno[i] = -1;
107552284Sobrien
1076169689Skan  regmove_bb_head = XNEWVEC (int, old_max_uid + 1);
107752284Sobrien  for (i = old_max_uid; i >= 0; i--) regmove_bb_head[i] = -1;
1078117395Skan  FOR_EACH_BB (bb)
1079132718Skan    regmove_bb_head[INSN_UID (BB_HEAD (bb))] = bb->index;
108050397Sobrien
108150397Sobrien  /* A forward/backward pass.  Replace output operands with input operands.  */
108250397Sobrien
108350397Sobrien  for (pass = 0; pass <= 2; pass++)
108450397Sobrien    {
108550397Sobrien      if (! flag_regmove && pass >= flag_expensive_optimizations)
108690075Sobrien	goto done;
108750397Sobrien
1088169689Skan      if (dump_file)
1089169689Skan	fprintf (dump_file, "Starting %s pass...\n",
109050397Sobrien		 pass ? "backward" : "forward");
109150397Sobrien
109250397Sobrien      for (insn = pass ? get_last_insn () : f; insn;
109350397Sobrien	   insn = pass ? PREV_INSN (insn) : NEXT_INSN (insn))
109450397Sobrien	{
109550397Sobrien	  rtx set;
109652284Sobrien	  int op_no, match_no;
109750397Sobrien
109850397Sobrien	  set = single_set (insn);
109950397Sobrien	  if (! set)
110050397Sobrien	    continue;
110150397Sobrien
110250397Sobrien	  if (flag_expensive_optimizations && ! pass
110350397Sobrien	      && (GET_CODE (SET_SRC (set)) == SIGN_EXTEND
110450397Sobrien		  || GET_CODE (SET_SRC (set)) == ZERO_EXTEND)
1105169689Skan	      && REG_P (XEXP (SET_SRC (set), 0))
1106169689Skan	      && REG_P (SET_DEST (set)))
110750397Sobrien	    optimize_reg_copy_3 (insn, SET_DEST (set), SET_SRC (set));
110850397Sobrien
110950397Sobrien	  if (flag_expensive_optimizations && ! pass
1110169689Skan	      && REG_P (SET_SRC (set))
1111169689Skan	      && REG_P (SET_DEST (set)))
111250397Sobrien	    {
111350397Sobrien	      /* If this is a register-register copy where SRC is not dead,
111450397Sobrien		 see if we can optimize it.  If this optimization succeeds,
111550397Sobrien		 it will become a copy where SRC is dead.  */
111650397Sobrien	      if ((find_reg_note (insn, REG_DEAD, SET_SRC (set))
111750397Sobrien		   || optimize_reg_copy_1 (insn, SET_DEST (set), SET_SRC (set)))
111850397Sobrien		  && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
111950397Sobrien		{
112050397Sobrien		  /* Similarly for a pseudo-pseudo copy when SRC is dead.  */
112150397Sobrien		  if (REGNO (SET_SRC (set)) >= FIRST_PSEUDO_REGISTER)
112250397Sobrien		    optimize_reg_copy_2 (insn, SET_DEST (set), SET_SRC (set));
112350397Sobrien		  if (regno_src_regno[REGNO (SET_DEST (set))] < 0
112450397Sobrien		      && SET_SRC (set) != SET_DEST (set))
112550397Sobrien		    {
112690075Sobrien		      int srcregno = REGNO (SET_SRC (set));
112750397Sobrien		      if (regno_src_regno[srcregno] >= 0)
112850397Sobrien			srcregno = regno_src_regno[srcregno];
112950397Sobrien		      regno_src_regno[REGNO (SET_DEST (set))] = srcregno;
113050397Sobrien		    }
113150397Sobrien		}
113250397Sobrien	    }
1133117395Skan	  if (! flag_regmove)
1134117395Skan	    continue;
113552284Sobrien
113652284Sobrien	  if (! find_matches (insn, &match))
113750397Sobrien	    continue;
113850397Sobrien
113950397Sobrien	  /* Now scan through the operands looking for a source operand
114050397Sobrien	     which is supposed to match the destination operand.
114150397Sobrien	     Then scan forward for an instruction which uses the dest
114250397Sobrien	     operand.
114350397Sobrien	     If it dies there, then replace the dest in both operands with
114450397Sobrien	     the source operand.  */
114550397Sobrien
114690075Sobrien	  for (op_no = 0; op_no < recog_data.n_operands; op_no++)
114750397Sobrien	    {
114850397Sobrien	      rtx src, dst, src_subreg;
114950397Sobrien	      enum reg_class src_class, dst_class;
115050397Sobrien
115152284Sobrien	      match_no = match.with[op_no];
115250397Sobrien
115350397Sobrien	      /* Nothing to do if the two operands aren't supposed to match.  */
115452284Sobrien	      if (match_no < 0)
115550397Sobrien		continue;
115650397Sobrien
115790075Sobrien	      src = recog_data.operand[op_no];
115890075Sobrien	      dst = recog_data.operand[match_no];
115950397Sobrien
1160169689Skan	      if (!REG_P (src))
116150397Sobrien		continue;
116250397Sobrien
116350397Sobrien	      src_subreg = src;
116450397Sobrien	      if (GET_CODE (dst) == SUBREG
116550397Sobrien		  && GET_MODE_SIZE (GET_MODE (dst))
116650397Sobrien		     >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (dst))))
116750397Sobrien		{
116850397Sobrien		  dst = SUBREG_REG (dst);
1169169689Skan		  src_subreg = lowpart_subreg (GET_MODE (dst),
1170169689Skan					       src, GET_MODE (src));
1171169689Skan		  if (!src_subreg)
1172169689Skan		    continue;
117350397Sobrien		}
1174169689Skan	      if (!REG_P (dst)
117550397Sobrien		  || REGNO (dst) < FIRST_PSEUDO_REGISTER)
117650397Sobrien		continue;
117750397Sobrien
117850397Sobrien	      if (REGNO (src) < FIRST_PSEUDO_REGISTER)
117950397Sobrien		{
118052284Sobrien		  if (match.commutative[op_no] < op_no)
118150397Sobrien		    regno_src_regno[REGNO (dst)] = REGNO (src);
118250397Sobrien		  continue;
118350397Sobrien		}
118450397Sobrien
118550397Sobrien	      if (REG_LIVE_LENGTH (REGNO (src)) < 0)
118650397Sobrien		continue;
118750397Sobrien
118852284Sobrien	      /* op_no/src must be a read-only operand, and
118950397Sobrien		 match_operand/dst must be a write-only operand.  */
119052284Sobrien	      if (match.use[op_no] != READ
119152284Sobrien		  || match.use[match_no] != WRITE)
119250397Sobrien		continue;
119350397Sobrien
119452284Sobrien	      if (match.early_clobber[match_no]
119590075Sobrien		  && count_occurrences (PATTERN (insn), src, 0) > 1)
119650397Sobrien		continue;
119750397Sobrien
119850397Sobrien	      /* Make sure match_operand is the destination.  */
119990075Sobrien	      if (recog_data.operand[match_no] != SET_DEST (set))
120050397Sobrien		continue;
120150397Sobrien
120250397Sobrien	      /* If the operands already match, then there is nothing to do.  */
120390075Sobrien	      if (operands_match_p (src, dst))
120450397Sobrien		continue;
120550397Sobrien
120690075Sobrien	      /* But in the commutative case, we might find a better match.  */
120790075Sobrien	      if (match.commutative[op_no] >= 0)
120890075Sobrien		{
120990075Sobrien		  rtx comm = recog_data.operand[match.commutative[op_no]];
121090075Sobrien		  if (operands_match_p (comm, dst)
121190075Sobrien		      && (replacement_quality (comm)
121290075Sobrien			  >= replacement_quality (src)))
121390075Sobrien		    continue;
121490075Sobrien		}
121590075Sobrien
121650397Sobrien	      src_class = reg_preferred_class (REGNO (src));
121750397Sobrien	      dst_class = reg_preferred_class (REGNO (dst));
121852284Sobrien	      if (! regclass_compatible_p (src_class, dst_class))
121950397Sobrien		continue;
122090075Sobrien
122190075Sobrien	      if (GET_MODE (src) != GET_MODE (dst))
122290075Sobrien		continue;
122390075Sobrien
122450397Sobrien	      if (fixup_match_1 (insn, set, src, src_subreg, dst, pass,
1225169689Skan				 op_no, match_no))
122650397Sobrien		break;
122750397Sobrien	    }
122850397Sobrien	}
122950397Sobrien    }
123050397Sobrien
123150397Sobrien  /* A backward pass.  Replace input operands with output operands.  */
123250397Sobrien
1233169689Skan  if (dump_file)
1234169689Skan    fprintf (dump_file, "Starting backward pass...\n");
123550397Sobrien
123650397Sobrien  for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
123750397Sobrien    {
123890075Sobrien      if (INSN_P (insn))
123950397Sobrien	{
124052284Sobrien	  int op_no, match_no;
124150397Sobrien	  int success = 0;
124252284Sobrien
124352284Sobrien	  if (! find_matches (insn, &match))
124450397Sobrien	    continue;
124550397Sobrien
124650397Sobrien	  /* Now scan through the operands looking for a destination operand
124750397Sobrien	     which is supposed to match a source operand.
124850397Sobrien	     Then scan backward for an instruction which sets the source
124950397Sobrien	     operand.  If safe, then replace the source operand with the
125050397Sobrien	     dest operand in both instructions.  */
125150397Sobrien
125250397Sobrien	  copy_src = NULL_RTX;
125350397Sobrien	  copy_dst = NULL_RTX;
125490075Sobrien	  for (op_no = 0; op_no < recog_data.n_operands; op_no++)
125550397Sobrien	    {
125650397Sobrien	      rtx set, p, src, dst;
125750397Sobrien	      rtx src_note, dst_note;
125850397Sobrien	      int num_calls = 0;
125950397Sobrien	      enum reg_class src_class, dst_class;
126050397Sobrien	      int length;
126150397Sobrien
126252284Sobrien	      match_no = match.with[op_no];
126350397Sobrien
126450397Sobrien	      /* Nothing to do if the two operands aren't supposed to match.  */
126552284Sobrien	      if (match_no < 0)
126650397Sobrien		continue;
126750397Sobrien
126890075Sobrien	      dst = recog_data.operand[match_no];
126990075Sobrien	      src = recog_data.operand[op_no];
127050397Sobrien
1271169689Skan	      if (!REG_P (src))
127250397Sobrien		continue;
127350397Sobrien
1274169689Skan	      if (!REG_P (dst)
127550397Sobrien		  || REGNO (dst) < FIRST_PSEUDO_REGISTER
127690075Sobrien		  || REG_LIVE_LENGTH (REGNO (dst)) < 0
1277132718Skan		  || GET_MODE (src) != GET_MODE (dst))
127850397Sobrien		continue;
127950397Sobrien
128050397Sobrien	      /* If the operands already match, then there is nothing to do.  */
128190075Sobrien	      if (operands_match_p (src, dst))
128250397Sobrien		continue;
128350397Sobrien
128490075Sobrien	      if (match.commutative[op_no] >= 0)
128590075Sobrien		{
128690075Sobrien		  rtx comm = recog_data.operand[match.commutative[op_no]];
128790075Sobrien		  if (operands_match_p (comm, dst))
128890075Sobrien		    continue;
128990075Sobrien		}
129090075Sobrien
129150397Sobrien	      set = single_set (insn);
129250397Sobrien	      if (! set)
129350397Sobrien		continue;
129450397Sobrien
129590075Sobrien	      /* Note that single_set ignores parts of a parallel set for
129690075Sobrien		 which one of the destinations is REG_UNUSED.  We can't
129790075Sobrien		 handle that here, since we can wind up rewriting things
129890075Sobrien		 such that a single register is set twice within a single
129990075Sobrien		 parallel.  */
130090075Sobrien	      if (reg_set_p (src, insn))
130190075Sobrien		continue;
130290075Sobrien
130352284Sobrien	      /* match_no/dst must be a write-only operand, and
130450397Sobrien		 operand_operand/src must be a read-only operand.  */
130552284Sobrien	      if (match.use[op_no] != READ
130652284Sobrien		  || match.use[match_no] != WRITE)
130750397Sobrien		continue;
130850397Sobrien
130952284Sobrien	      if (match.early_clobber[match_no]
131090075Sobrien		  && count_occurrences (PATTERN (insn), src, 0) > 1)
131150397Sobrien		continue;
131250397Sobrien
131352284Sobrien	      /* Make sure match_no is the destination.  */
131490075Sobrien	      if (recog_data.operand[match_no] != SET_DEST (set))
131550397Sobrien		continue;
131650397Sobrien
131750397Sobrien	      if (REGNO (src) < FIRST_PSEUDO_REGISTER)
131850397Sobrien		{
131950397Sobrien		  if (GET_CODE (SET_SRC (set)) == PLUS
132050397Sobrien		      && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT
132150397Sobrien		      && XEXP (SET_SRC (set), 0) == src
132250397Sobrien		      && fixup_match_2 (insn, dst, src,
1323169689Skan					XEXP (SET_SRC (set), 1)))
132450397Sobrien		    break;
132550397Sobrien		  continue;
132650397Sobrien		}
132750397Sobrien	      src_class = reg_preferred_class (REGNO (src));
132850397Sobrien	      dst_class = reg_preferred_class (REGNO (dst));
132996263Sobrien
133096263Sobrien	      if (! (src_note = find_reg_note (insn, REG_DEAD, src)))
133196263Sobrien		{
133296263Sobrien		  /* We used to force the copy here like in other cases, but
133396263Sobrien		     it produces worse code, as it eliminates no copy
133496263Sobrien		     instructions and the copy emitted will be produced by
133596263Sobrien		     reload anyway.  On patterns with multiple alternatives,
1336132718Skan		     there may be better solution available.
133796263Sobrien
133896263Sobrien		     In particular this change produced slower code for numeric
133996263Sobrien		     i387 programs.  */
134096263Sobrien
134196263Sobrien		  continue;
134296263Sobrien		}
134396263Sobrien
134452284Sobrien	      if (! regclass_compatible_p (src_class, dst_class))
134550397Sobrien		{
134650397Sobrien		  if (!copy_src)
134750397Sobrien		    {
134850397Sobrien		      copy_src = src;
134950397Sobrien		      copy_dst = dst;
135050397Sobrien		    }
135150397Sobrien		  continue;
135250397Sobrien		}
135350397Sobrien
135450397Sobrien	      /* Can not modify an earlier insn to set dst if this insn
135550397Sobrien		 uses an old value in the source.  */
135650397Sobrien	      if (reg_overlap_mentioned_p (dst, SET_SRC (set)))
135750397Sobrien		{
135850397Sobrien		  if (!copy_src)
135950397Sobrien		    {
136050397Sobrien		      copy_src = src;
136150397Sobrien		      copy_dst = dst;
136250397Sobrien		    }
136350397Sobrien		  continue;
136450397Sobrien		}
136550397Sobrien
136650397Sobrien	      /* If src is set once in a different basic block,
136750397Sobrien		 and is set equal to a constant, then do not use
136850397Sobrien		 it for this optimization, as this would make it
136950397Sobrien		 no longer equivalent to a constant.  */
137050397Sobrien
1371169689Skan	      if (reg_is_remote_constant_p (src, insn))
137250397Sobrien		{
137350397Sobrien		  if (!copy_src)
137450397Sobrien		    {
137550397Sobrien		      copy_src = src;
137650397Sobrien		      copy_dst = dst;
137750397Sobrien		    }
137850397Sobrien		  continue;
137950397Sobrien		}
138050397Sobrien
138150397Sobrien
1382169689Skan	      if (dump_file)
1383169689Skan		fprintf (dump_file,
138450397Sobrien			 "Could fix operand %d of insn %d matching operand %d.\n",
138552284Sobrien			 op_no, INSN_UID (insn), match_no);
138650397Sobrien
138750397Sobrien	      /* Scan backward to find the first instruction that uses
138850397Sobrien		 the input operand.  If the operand is set here, then
138952284Sobrien		 replace it in both instructions with match_no.  */
139050397Sobrien
139150397Sobrien	      for (length = 0, p = PREV_INSN (insn); p; p = PREV_INSN (p))
139250397Sobrien		{
139350397Sobrien		  rtx pset;
139450397Sobrien
139550397Sobrien		  /* ??? We can't scan past the end of a basic block without
139650397Sobrien		     updating the register lifetime info
139790075Sobrien		     (REG_DEAD/basic_block_live_at_start).  */
139890075Sobrien		  if (perhaps_ends_bb_p (p))
139950397Sobrien		    break;
140090075Sobrien		  else if (! INSN_P (p))
140150397Sobrien		    continue;
140250397Sobrien
140350397Sobrien		  length++;
140450397Sobrien
140550397Sobrien		  /* ??? See if all of SRC is set in P.  This test is much
140650397Sobrien		     more conservative than it needs to be.  */
140750397Sobrien		  pset = single_set (p);
140850397Sobrien		  if (pset && SET_DEST (pset) == src)
140950397Sobrien		    {
141050397Sobrien		      /* We use validate_replace_rtx, in case there
141150397Sobrien			 are multiple identical source operands.  All of
141250397Sobrien			 them have to be changed at the same time.  */
141350397Sobrien		      if (validate_replace_rtx (src, dst, insn))
141450397Sobrien			{
141550397Sobrien			  if (validate_change (p, &SET_DEST (pset),
141650397Sobrien					       dst, 0))
141750397Sobrien			    success = 1;
141850397Sobrien			  else
141950397Sobrien			    {
142050397Sobrien			      /* Change all source operands back.
142150397Sobrien				 This modifies the dst as a side-effect.  */
142250397Sobrien			      validate_replace_rtx (dst, src, insn);
142350397Sobrien			      /* Now make sure the dst is right.  */
142450397Sobrien			      validate_change (insn,
142590075Sobrien					       recog_data.operand_loc[match_no],
142650397Sobrien					       dst, 0);
142750397Sobrien			    }
142850397Sobrien			}
142950397Sobrien		      break;
143050397Sobrien		    }
143150397Sobrien
143250397Sobrien		  if (reg_overlap_mentioned_p (src, PATTERN (p))
143350397Sobrien		      || reg_overlap_mentioned_p (dst, PATTERN (p)))
143450397Sobrien		    break;
143550397Sobrien
143650397Sobrien		  /* If we have passed a call instruction, and the
143750397Sobrien		     pseudo-reg DST is not already live across a call,
143850397Sobrien		     then don't perform the optimization.  */
1439169689Skan		  if (CALL_P (p))
144050397Sobrien		    {
144150397Sobrien		      num_calls++;
144250397Sobrien
144350397Sobrien		      if (REG_N_CALLS_CROSSED (REGNO (dst)) == 0)
144450397Sobrien			break;
144550397Sobrien		    }
144650397Sobrien		}
144750397Sobrien
144850397Sobrien	      if (success)
144950397Sobrien		{
145050397Sobrien		  int dstno, srcno;
145150397Sobrien
145250397Sobrien		  /* Remove the death note for SRC from INSN.  */
145350397Sobrien		  remove_note (insn, src_note);
145450397Sobrien		  /* Move the death note for SRC to P if it is used
145550397Sobrien		     there.  */
145650397Sobrien		  if (reg_overlap_mentioned_p (src, PATTERN (p)))
145750397Sobrien		    {
145850397Sobrien		      XEXP (src_note, 1) = REG_NOTES (p);
145950397Sobrien		      REG_NOTES (p) = src_note;
146050397Sobrien		    }
146150397Sobrien		  /* If there is a REG_DEAD note for DST on P, then remove
146250397Sobrien		     it, because DST is now set there.  */
146350397Sobrien		  if ((dst_note = find_reg_note (p, REG_DEAD, dst)))
146450397Sobrien		    remove_note (p, dst_note);
146550397Sobrien
146650397Sobrien		  dstno = REGNO (dst);
146750397Sobrien		  srcno = REGNO (src);
146850397Sobrien
146950397Sobrien		  REG_N_SETS (dstno)++;
147050397Sobrien		  REG_N_SETS (srcno)--;
147150397Sobrien
147250397Sobrien		  REG_N_CALLS_CROSSED (dstno) += num_calls;
147350397Sobrien		  REG_N_CALLS_CROSSED (srcno) -= num_calls;
147450397Sobrien
147550397Sobrien		  REG_LIVE_LENGTH (dstno) += length;
147650397Sobrien		  if (REG_LIVE_LENGTH (srcno) >= 0)
147750397Sobrien		    {
147850397Sobrien		      REG_LIVE_LENGTH (srcno) -= length;
147950397Sobrien		      /* REG_LIVE_LENGTH is only an approximation after
148050397Sobrien			 combine if sched is not run, so make sure that we
148150397Sobrien			 still have a reasonable value.  */
148250397Sobrien		      if (REG_LIVE_LENGTH (srcno) < 2)
148350397Sobrien			REG_LIVE_LENGTH (srcno) = 2;
148450397Sobrien		    }
148550397Sobrien
1486169689Skan		  if (dump_file)
1487169689Skan		    fprintf (dump_file,
148850397Sobrien			     "Fixed operand %d of insn %d matching operand %d.\n",
148952284Sobrien			     op_no, INSN_UID (insn), match_no);
149050397Sobrien
149150397Sobrien		  break;
149250397Sobrien		}
149350397Sobrien	    }
149450397Sobrien
149550397Sobrien	  /* If we weren't able to replace any of the alternatives, try an
1496132718Skan	     alternative approach of copying the source to the destination.  */
149750397Sobrien	  if (!success && copy_src != NULL_RTX)
149890075Sobrien	    copy_src_to_dest (insn, copy_src, copy_dst, old_max_uid);
149950397Sobrien
150050397Sobrien	}
150150397Sobrien    }
150252284Sobrien
150352284Sobrien  /* In fixup_match_1, some insns may have been inserted after basic block
150452284Sobrien     ends.  Fix that here.  */
1505117395Skan  FOR_EACH_BB (bb)
150652284Sobrien    {
1507132718Skan      rtx end = BB_END (bb);
150852284Sobrien      rtx new = end;
150952284Sobrien      rtx next = NEXT_INSN (new);
151052284Sobrien      while (next != 0 && INSN_UID (next) >= old_max_uid
1511132718Skan	     && (bb->next_bb == EXIT_BLOCK_PTR || BB_HEAD (bb->next_bb) != next))
151252284Sobrien	new = next, next = NEXT_INSN (new);
1513132718Skan      BB_END (bb) = new;
151452284Sobrien    }
151590075Sobrien
151690075Sobrien done:
151790075Sobrien  /* Clean up.  */
151890075Sobrien  free (regno_src_regno);
151990075Sobrien  free (regmove_bb_head);
1520169689Skan  if (reg_set_in_bb)
1521169689Skan    {
1522169689Skan      free (reg_set_in_bb);
1523169689Skan      reg_set_in_bb = NULL;
1524169689Skan    }
152550397Sobrien}
152650397Sobrien
152752284Sobrien/* Returns nonzero if INSN's pattern has matching constraints for any operand.
152852284Sobrien   Returns 0 if INSN can't be recognized, or if the alternative can't be
152952284Sobrien   determined.
153050397Sobrien
153150397Sobrien   Initialize the info in MATCHP based on the constraints.  */
153250397Sobrien
153350397Sobrienstatic int
1534132718Skanfind_matches (rtx insn, struct match *matchp)
153550397Sobrien{
153650397Sobrien  int likely_spilled[MAX_RECOG_OPERANDS];
153752284Sobrien  int op_no;
153850397Sobrien  int any_matches = 0;
153950397Sobrien
154052284Sobrien  extract_insn (insn);
154152284Sobrien  if (! constrain_operands (0))
154252284Sobrien    return 0;
154350397Sobrien
154450397Sobrien  /* Must initialize this before main loop, because the code for
154550397Sobrien     the commutative case may set matches for operands other than
154650397Sobrien     the current one.  */
154790075Sobrien  for (op_no = recog_data.n_operands; --op_no >= 0; )
154852284Sobrien    matchp->with[op_no] = matchp->commutative[op_no] = -1;
154950397Sobrien
155090075Sobrien  for (op_no = 0; op_no < recog_data.n_operands; op_no++)
155150397Sobrien    {
155252284Sobrien      const char *p;
155352284Sobrien      char c;
155450397Sobrien      int i = 0;
155550397Sobrien
155690075Sobrien      p = recog_data.constraints[op_no];
155750397Sobrien
155852284Sobrien      likely_spilled[op_no] = 0;
155952284Sobrien      matchp->use[op_no] = READ;
156052284Sobrien      matchp->early_clobber[op_no] = 0;
156150397Sobrien      if (*p == '=')
156252284Sobrien	matchp->use[op_no] = WRITE;
156350397Sobrien      else if (*p == '+')
156452284Sobrien	matchp->use[op_no] = READWRITE;
156550397Sobrien
156650397Sobrien      for (;*p && i < which_alternative; p++)
156750397Sobrien	if (*p == ',')
156850397Sobrien	  i++;
156950397Sobrien
1570132718Skan      while ((c = *p) != '\0' && c != ',')
1571132718Skan	{
1572132718Skan	  switch (c)
157390075Sobrien	    {
1574132718Skan	    case '=':
1575132718Skan	      break;
1576132718Skan	    case '+':
1577132718Skan	      break;
1578132718Skan	    case '&':
1579132718Skan	      matchp->early_clobber[op_no] = 1;
1580132718Skan	      break;
1581132718Skan	    case '%':
1582132718Skan	      matchp->commutative[op_no] = op_no + 1;
1583132718Skan	      matchp->commutative[op_no + 1] = op_no;
1584132718Skan	      break;
158590075Sobrien
1586132718Skan	    case '0': case '1': case '2': case '3': case '4':
1587132718Skan	    case '5': case '6': case '7': case '8': case '9':
1588132718Skan	      {
1589132718Skan		char *end;
1590132718Skan		unsigned long match_ul = strtoul (p, &end, 10);
1591132718Skan		int match = match_ul;
159290075Sobrien
1593132718Skan		p = end;
159490075Sobrien
1595132718Skan		if (match < op_no && likely_spilled[match])
1596132718Skan		  continue;
1597132718Skan		matchp->with[op_no] = match;
1598132718Skan		any_matches = 1;
1599132718Skan		if (matchp->commutative[op_no] >= 0)
1600132718Skan		  matchp->with[matchp->commutative[op_no]] = match;
1601132718Skan	      }
1602132718Skan	    continue;
1603132718Skan
160450397Sobrien	  case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'h':
160550397Sobrien	  case 'j': case 'k': case 'l': case 'p': case 'q': case 't': case 'u':
160650397Sobrien	  case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B':
160750397Sobrien	  case 'C': case 'D': case 'W': case 'Y': case 'Z':
1608132718Skan	    if (CLASS_LIKELY_SPILLED_P (REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p) ))
160952284Sobrien	      likely_spilled[op_no] = 1;
161050397Sobrien	    break;
161150397Sobrien	  }
1612132718Skan	  p += CONSTRAINT_LEN (c, p);
1613132718Skan	}
161450397Sobrien    }
161552284Sobrien  return any_matches;
161650397Sobrien}
161750397Sobrien
161890075Sobrien/* Try to replace all occurrences of DST_REG with SRC in LOC, that is
161990075Sobrien   assumed to be in INSN.  */
162090075Sobrien
162190075Sobrienstatic void
1622132718Skanreplace_in_call_usage (rtx *loc, unsigned int dst_reg, rtx src, rtx insn)
162390075Sobrien{
162490075Sobrien  rtx x = *loc;
162590075Sobrien  enum rtx_code code;
162690075Sobrien  const char *fmt;
162790075Sobrien  int i, j;
162890075Sobrien
162990075Sobrien  if (! x)
163090075Sobrien    return;
163190075Sobrien
163290075Sobrien  code = GET_CODE (x);
163390075Sobrien  if (code == REG)
163490075Sobrien    {
163590075Sobrien      if (REGNO (x) != dst_reg)
163690075Sobrien	return;
163790075Sobrien
163890075Sobrien      validate_change (insn, loc, src, 1);
163990075Sobrien
164090075Sobrien      return;
164190075Sobrien    }
164290075Sobrien
164390075Sobrien  /* Process each of our operands recursively.  */
164490075Sobrien  fmt = GET_RTX_FORMAT (code);
164590075Sobrien  for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
164690075Sobrien    if (*fmt == 'e')
164790075Sobrien      replace_in_call_usage (&XEXP (x, i), dst_reg, src, insn);
164890075Sobrien    else if (*fmt == 'E')
164990075Sobrien      for (j = 0; j < XVECLEN (x, i); j++)
165090075Sobrien	replace_in_call_usage (& XVECEXP (x, i, j), dst_reg, src, insn);
165190075Sobrien}
165290075Sobrien
165350397Sobrien/* Try to replace output operand DST in SET, with input operand SRC.  SET is
165490075Sobrien   the only set in INSN.  INSN has just been recognized and constrained.
165550397Sobrien   SRC is operand number OPERAND_NUMBER in INSN.
165650397Sobrien   DST is operand number MATCH_NUMBER in INSN.
165750397Sobrien   If BACKWARD is nonzero, we have been called in a backward pass.
165850397Sobrien   Return nonzero for success.  */
165990075Sobrien
166050397Sobrienstatic int
1661132718Skanfixup_match_1 (rtx insn, rtx set, rtx src, rtx src_subreg, rtx dst,
1662169689Skan	       int backward, int operand_number, int match_number)
166350397Sobrien{
166450397Sobrien  rtx p;
166550397Sobrien  rtx post_inc = 0, post_inc_set = 0, search_end = 0;
166650397Sobrien  int success = 0;
166750397Sobrien  int num_calls = 0, s_num_calls = 0;
166850397Sobrien  enum rtx_code code = NOTE;
1669132718Skan  HOST_WIDE_INT insn_const = 0, newconst = 0;
167050397Sobrien  rtx overlap = 0; /* need to move insn ? */
167190075Sobrien  rtx src_note = find_reg_note (insn, REG_DEAD, src), dst_note = NULL_RTX;
167290075Sobrien  int length, s_length;
167350397Sobrien
167450397Sobrien  if (! src_note)
167550397Sobrien    {
167650397Sobrien      /* Look for (set (regX) (op regA constX))
167750397Sobrien		  (set (regY) (op regA constY))
167850397Sobrien	 and change that to
167950397Sobrien		  (set (regA) (op regA constX)).
168050397Sobrien		  (set (regY) (op regA constY-constX)).
168150397Sobrien	 This works for add and shift operations, if
168250397Sobrien	 regA is dead after or set by the second insn.  */
168350397Sobrien
168450397Sobrien      code = GET_CODE (SET_SRC (set));
168550397Sobrien      if ((code == PLUS || code == LSHIFTRT
168650397Sobrien	   || code == ASHIFT || code == ASHIFTRT)
168750397Sobrien	  && XEXP (SET_SRC (set), 0) == src
168850397Sobrien	  && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
168950397Sobrien	insn_const = INTVAL (XEXP (SET_SRC (set), 1));
169052750Sobrien      else if (! stable_and_no_regs_but_for_p (SET_SRC (set), src, dst))
169150397Sobrien	return 0;
169250397Sobrien      else
169350397Sobrien	/* We might find a src_note while scanning.  */
169450397Sobrien	code = NOTE;
169550397Sobrien    }
169650397Sobrien
1697169689Skan  if (dump_file)
1698169689Skan    fprintf (dump_file,
169950397Sobrien	     "Could fix operand %d of insn %d matching operand %d.\n",
170050397Sobrien	     operand_number, INSN_UID (insn), match_number);
170150397Sobrien
170250397Sobrien  /* If SRC is equivalent to a constant set in a different basic block,
170350397Sobrien     then do not use it for this optimization.  We want the equivalence
170450397Sobrien     so that if we have to reload this register, we can reload the
170550397Sobrien     constant, rather than extending the lifespan of the register.  */
1706169689Skan  if (reg_is_remote_constant_p (src, insn))
170750397Sobrien    return 0;
170850397Sobrien
170950397Sobrien  /* Scan forward to find the next instruction that
171050397Sobrien     uses the output operand.  If the operand dies here,
171150397Sobrien     then replace it in both instructions with
171250397Sobrien     operand_number.  */
171350397Sobrien
171450397Sobrien  for (length = s_length = 0, p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
171550397Sobrien    {
1716169689Skan      if (CALL_P (p))
171790075Sobrien	replace_in_call_usage (& CALL_INSN_FUNCTION_USAGE (p),
171890075Sobrien			       REGNO (dst), src, p);
171950397Sobrien
172050397Sobrien      /* ??? We can't scan past the end of a basic block without updating
172190075Sobrien	 the register lifetime info (REG_DEAD/basic_block_live_at_start).  */
172290075Sobrien      if (perhaps_ends_bb_p (p))
172350397Sobrien	break;
172490075Sobrien      else if (! INSN_P (p))
172550397Sobrien	continue;
172650397Sobrien
172750397Sobrien      length++;
172850397Sobrien      if (src_note)
172950397Sobrien	s_length++;
173050397Sobrien
173150397Sobrien      if (reg_set_p (src, p) || reg_set_p (dst, p)
173250397Sobrien	  || (GET_CODE (PATTERN (p)) == USE
173350397Sobrien	      && reg_overlap_mentioned_p (src, XEXP (PATTERN (p), 0))))
173450397Sobrien	break;
173550397Sobrien
173650397Sobrien      /* See if all of DST dies in P.  This test is
173750397Sobrien	 slightly more conservative than it needs to be.  */
173850397Sobrien      if ((dst_note = find_regno_note (p, REG_DEAD, REGNO (dst)))
173950397Sobrien	  && (GET_MODE (XEXP (dst_note, 0)) == GET_MODE (dst)))
174050397Sobrien	{
174190075Sobrien	  /* If we would be moving INSN, check that we won't move it
174290075Sobrien	     into the shadow of a live a live flags register.  */
174390075Sobrien	  /* ??? We only try to move it in front of P, although
174490075Sobrien		 we could move it anywhere between OVERLAP and P.  */
174590075Sobrien	  if (overlap && GET_MODE (PREV_INSN (p)) != VOIDmode)
174690075Sobrien	    break;
174790075Sobrien
174850397Sobrien	  if (! src_note)
174950397Sobrien	    {
175050397Sobrien	      rtx q;
175190075Sobrien	      rtx set2 = NULL_RTX;
175250397Sobrien
175350397Sobrien	      /* If an optimization is done, the value of SRC while P
175450397Sobrien		 is executed will be changed.  Check that this is OK.  */
175550397Sobrien	      if (reg_overlap_mentioned_p (src, PATTERN (p)))
175650397Sobrien		break;
175750397Sobrien	      for (q = p; q; q = NEXT_INSN (q))
175850397Sobrien		{
175950397Sobrien		  /* ??? We can't scan past the end of a basic block without
176050397Sobrien		     updating the register lifetime info
176190075Sobrien		     (REG_DEAD/basic_block_live_at_start).  */
176290075Sobrien		  if (perhaps_ends_bb_p (q))
176350397Sobrien		    {
176450397Sobrien		      q = 0;
176550397Sobrien		      break;
176650397Sobrien		    }
176790075Sobrien		  else if (! INSN_P (q))
176850397Sobrien		    continue;
176990075Sobrien		  else if (reg_overlap_mentioned_p (src, PATTERN (q))
177090075Sobrien			   || reg_set_p (src, q))
177150397Sobrien		    break;
177250397Sobrien		}
177350397Sobrien	      if (q)
177450397Sobrien		set2 = single_set (q);
177550397Sobrien	      if (! q || ! set2 || GET_CODE (SET_SRC (set2)) != code
177650397Sobrien		  || XEXP (SET_SRC (set2), 0) != src
177750397Sobrien		  || GET_CODE (XEXP (SET_SRC (set2), 1)) != CONST_INT
177850397Sobrien		  || (SET_DEST (set2) != src
177950397Sobrien		      && ! find_reg_note (q, REG_DEAD, src)))
178050397Sobrien		{
178150397Sobrien		  /* If this is a PLUS, we can still save a register by doing
178250397Sobrien		     src += insn_const;
178350397Sobrien		     P;
178450397Sobrien		     src -= insn_const; .
178550397Sobrien		     This also gives opportunities for subsequent
178650397Sobrien		     optimizations in the backward pass, so do it there.  */
178750397Sobrien		  if (code == PLUS && backward
178852284Sobrien		      /* Don't do this if we can likely tie DST to SET_DEST
178952284Sobrien			 of P later; we can't do this tying here if we got a
179052284Sobrien			 hard register.  */
179152284Sobrien		      && ! (dst_note && ! REG_N_CALLS_CROSSED (REGNO (dst))
179252284Sobrien			    && single_set (p)
1793169689Skan			    && REG_P (SET_DEST (single_set (p)))
179452284Sobrien			    && (REGNO (SET_DEST (single_set (p)))
179552284Sobrien				< FIRST_PSEUDO_REGISTER))
179652284Sobrien		      /* We may only emit an insn directly after P if we
179752284Sobrien			 are not in the shadow of a live flags register.  */
179852284Sobrien		      && GET_MODE (p) == VOIDmode)
179950397Sobrien		    {
180050397Sobrien		      search_end = q;
180150397Sobrien		      q = insn;
180250397Sobrien		      set2 = set;
180350397Sobrien		      newconst = -insn_const;
180450397Sobrien		      code = MINUS;
180550397Sobrien		    }
180650397Sobrien		  else
180750397Sobrien		    break;
180850397Sobrien		}
180950397Sobrien	      else
181050397Sobrien		{
181150397Sobrien		  newconst = INTVAL (XEXP (SET_SRC (set2), 1)) - insn_const;
181250397Sobrien		  /* Reject out of range shifts.  */
181350397Sobrien		  if (code != PLUS
181450397Sobrien		      && (newconst < 0
181590075Sobrien			  || ((unsigned HOST_WIDE_INT) newconst
181690075Sobrien			      >= (GET_MODE_BITSIZE (GET_MODE
181790075Sobrien						    (SET_SRC (set2)))))))
181850397Sobrien		    break;
181950397Sobrien		  if (code == PLUS)
182050397Sobrien		    {
182150397Sobrien		      post_inc = q;
182250397Sobrien		      if (SET_DEST (set2) != src)
182350397Sobrien			post_inc_set = set2;
182450397Sobrien		    }
182550397Sobrien		}
182650397Sobrien	      /* We use 1 as last argument to validate_change so that all
182750397Sobrien		 changes are accepted or rejected together by apply_change_group
182850397Sobrien		 when it is called by validate_replace_rtx .  */
182950397Sobrien	      validate_change (q, &XEXP (SET_SRC (set2), 1),
183050397Sobrien			       GEN_INT (newconst), 1);
183150397Sobrien	    }
183290075Sobrien	  validate_change (insn, recog_data.operand_loc[match_number], src, 1);
183350397Sobrien	  if (validate_replace_rtx (dst, src_subreg, p))
183450397Sobrien	    success = 1;
183550397Sobrien	  break;
183650397Sobrien	}
183750397Sobrien
183850397Sobrien      if (reg_overlap_mentioned_p (dst, PATTERN (p)))
183950397Sobrien	break;
184050397Sobrien      if (! src_note && reg_overlap_mentioned_p (src, PATTERN (p)))
184150397Sobrien	{
184290075Sobrien	  /* INSN was already checked to be movable wrt. the registers that it
184390075Sobrien	     sets / uses when we found no REG_DEAD note for src on it, but it
184490075Sobrien	     still might clobber the flags register.  We'll have to check that
184590075Sobrien	     we won't insert it into the shadow of a live flags register when
184690075Sobrien	     we finally know where we are to move it.  */
184750397Sobrien	  overlap = p;
184850397Sobrien	  src_note = find_reg_note (p, REG_DEAD, src);
184950397Sobrien	}
185050397Sobrien
185150397Sobrien      /* If we have passed a call instruction, and the pseudo-reg SRC is not
185250397Sobrien	 already live across a call, then don't perform the optimization.  */
1853169689Skan      if (CALL_P (p))
185450397Sobrien	{
185550397Sobrien	  if (REG_N_CALLS_CROSSED (REGNO (src)) == 0)
185650397Sobrien	    break;
185750397Sobrien
185850397Sobrien	  num_calls++;
185950397Sobrien
186050397Sobrien	  if (src_note)
186150397Sobrien	    s_num_calls++;
186250397Sobrien
186350397Sobrien	}
186450397Sobrien    }
186550397Sobrien
186650397Sobrien  if (! success)
186750397Sobrien    return 0;
186850397Sobrien
186950397Sobrien  /* Remove the death note for DST from P.  */
187050397Sobrien  remove_note (p, dst_note);
187150397Sobrien  if (code == MINUS)
187250397Sobrien    {
187350397Sobrien      post_inc = emit_insn_after (copy_rtx (PATTERN (insn)), p);
187452284Sobrien      if ((HAVE_PRE_INCREMENT || HAVE_PRE_DECREMENT)
187552284Sobrien	  && search_end
187650397Sobrien	  && try_auto_increment (search_end, post_inc, 0, src, newconst, 1))
187750397Sobrien	post_inc = 0;
187850397Sobrien      validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (insn_const), 0);
187950397Sobrien      REG_N_SETS (REGNO (src))++;
188050397Sobrien      REG_LIVE_LENGTH (REGNO (src))++;
188150397Sobrien    }
188250397Sobrien  if (overlap)
188350397Sobrien    {
188450397Sobrien      /* The lifetime of src and dest overlap,
188550397Sobrien	 but we can change this by moving insn.  */
188650397Sobrien      rtx pat = PATTERN (insn);
188750397Sobrien      if (src_note)
188850397Sobrien	remove_note (overlap, src_note);
188952284Sobrien      if ((HAVE_POST_INCREMENT || HAVE_POST_DECREMENT)
189052284Sobrien	  && code == PLUS
189150397Sobrien	  && try_auto_increment (overlap, insn, 0, src, insn_const, 0))
189250397Sobrien	insn = overlap;
189350397Sobrien      else
189450397Sobrien	{
189550397Sobrien	  rtx notes = REG_NOTES (insn);
189650397Sobrien
189750397Sobrien	  emit_insn_after_with_line_notes (pat, PREV_INSN (p), insn);
189890075Sobrien	  delete_insn (insn);
189950397Sobrien	  /* emit_insn_after_with_line_notes has no
190050397Sobrien	     return value, so search for the new insn.  */
190190075Sobrien	  insn = p;
190290075Sobrien	  while (! INSN_P (insn) || PATTERN (insn) != pat)
190350397Sobrien	    insn = PREV_INSN (insn);
190450397Sobrien
190550397Sobrien	  REG_NOTES (insn) = notes;
190650397Sobrien	}
190750397Sobrien    }
190850397Sobrien  /* Sometimes we'd generate src = const; src += n;
190950397Sobrien     if so, replace the instruction that set src
191050397Sobrien     in the first place.  */
191150397Sobrien
191250397Sobrien  if (! overlap && (code == PLUS || code == MINUS))
191350397Sobrien    {
191450397Sobrien      rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
191590075Sobrien      rtx q, set2 = NULL_RTX;
191650397Sobrien      int num_calls2 = 0, s_length2 = 0;
191750397Sobrien
191850397Sobrien      if (note && CONSTANT_P (XEXP (note, 0)))
191950397Sobrien	{
192090075Sobrien	  for (q = PREV_INSN (insn); q; q = PREV_INSN (q))
192150397Sobrien	    {
192250397Sobrien	      /* ??? We can't scan past the end of a basic block without
192350397Sobrien		 updating the register lifetime info
192490075Sobrien		 (REG_DEAD/basic_block_live_at_start).  */
192590075Sobrien	      if (perhaps_ends_bb_p (q))
192650397Sobrien		{
192750397Sobrien		  q = 0;
192850397Sobrien		  break;
192950397Sobrien		}
193090075Sobrien	      else if (! INSN_P (q))
193190075Sobrien		continue;
193250397Sobrien
193350397Sobrien	      s_length2++;
193450397Sobrien	      if (reg_set_p (src, q))
193550397Sobrien		{
193650397Sobrien		  set2 = single_set (q);
193750397Sobrien		  break;
193850397Sobrien		}
193950397Sobrien	      if (reg_overlap_mentioned_p (src, PATTERN (q)))
194050397Sobrien		{
194150397Sobrien		  q = 0;
194250397Sobrien		  break;
194350397Sobrien		}
1944169689Skan	      if (CALL_P (p))
194550397Sobrien		num_calls2++;
194650397Sobrien	    }
194750397Sobrien	  if (q && set2 && SET_DEST (set2) == src && CONSTANT_P (SET_SRC (set2))
194850397Sobrien	      && validate_change (insn, &SET_SRC (set), XEXP (note, 0), 0))
194950397Sobrien	    {
195090075Sobrien	      delete_insn (q);
195150397Sobrien	      REG_N_SETS (REGNO (src))--;
195250397Sobrien	      REG_N_CALLS_CROSSED (REGNO (src)) -= num_calls2;
195350397Sobrien	      REG_LIVE_LENGTH (REGNO (src)) -= s_length2;
195450397Sobrien	      insn_const = 0;
195550397Sobrien	    }
195650397Sobrien	}
195750397Sobrien    }
195850397Sobrien
195952284Sobrien  if ((HAVE_PRE_INCREMENT || HAVE_PRE_DECREMENT)
196052284Sobrien	   && (code == PLUS || code == MINUS) && insn_const
196150397Sobrien	   && try_auto_increment (p, insn, 0, src, insn_const, 1))
196250397Sobrien    insn = p;
196352284Sobrien  else if ((HAVE_POST_INCREMENT || HAVE_POST_DECREMENT)
196452284Sobrien	   && post_inc
196550397Sobrien	   && try_auto_increment (p, post_inc, post_inc_set, src, newconst, 0))
196650397Sobrien    post_inc = 0;
196750397Sobrien  /* If post_inc still prevails, try to find an
196850397Sobrien     insn where it can be used as a pre-in/decrement.
196950397Sobrien     If code is MINUS, this was already tried.  */
197050397Sobrien  if (post_inc && code == PLUS
197150397Sobrien  /* Check that newconst is likely to be usable
197250397Sobrien     in a pre-in/decrement before starting the search.  */
197352284Sobrien      && ((HAVE_PRE_INCREMENT && newconst > 0 && newconst <= MOVE_MAX)
197452284Sobrien	  || (HAVE_PRE_DECREMENT && newconst < 0 && newconst >= -MOVE_MAX))
197552284Sobrien      && exact_log2 (newconst))
197650397Sobrien    {
197750397Sobrien      rtx q, inc_dest;
197850397Sobrien
197950397Sobrien      inc_dest = post_inc_set ? SET_DEST (post_inc_set) : src;
198050397Sobrien      for (q = post_inc; (q = NEXT_INSN (q)); )
198150397Sobrien	{
198250397Sobrien	  /* ??? We can't scan past the end of a basic block without updating
198390075Sobrien	     the register lifetime info
198490075Sobrien	     (REG_DEAD/basic_block_live_at_start).  */
198590075Sobrien	  if (perhaps_ends_bb_p (q))
198650397Sobrien	    break;
198790075Sobrien	  else if (! INSN_P (q))
198850397Sobrien	    continue;
198990075Sobrien	  else if (src != inc_dest
199090075Sobrien		   && (reg_overlap_mentioned_p (src, PATTERN (q))
199190075Sobrien		       || reg_set_p (src, q)))
199250397Sobrien	    break;
199390075Sobrien	  else if (reg_set_p (inc_dest, q))
199450397Sobrien	    break;
199590075Sobrien	  else if (reg_overlap_mentioned_p (inc_dest, PATTERN (q)))
199650397Sobrien	    {
199750397Sobrien	      try_auto_increment (q, post_inc,
199850397Sobrien				  post_inc_set, inc_dest, newconst, 1);
199950397Sobrien	      break;
200050397Sobrien	    }
200150397Sobrien	}
200250397Sobrien    }
200390075Sobrien
200450397Sobrien  /* Move the death note for DST to INSN if it is used
200550397Sobrien     there.  */
200650397Sobrien  if (reg_overlap_mentioned_p (dst, PATTERN (insn)))
200750397Sobrien    {
200850397Sobrien      XEXP (dst_note, 1) = REG_NOTES (insn);
200950397Sobrien      REG_NOTES (insn) = dst_note;
201050397Sobrien    }
201150397Sobrien
201250397Sobrien  if (src_note)
201350397Sobrien    {
201450397Sobrien      /* Move the death note for SRC from INSN to P.  */
201550397Sobrien      if (! overlap)
201650397Sobrien	remove_note (insn, src_note);
201750397Sobrien      XEXP (src_note, 1) = REG_NOTES (p);
201850397Sobrien      REG_NOTES (p) = src_note;
201950397Sobrien
202050397Sobrien      REG_N_CALLS_CROSSED (REGNO (src)) += s_num_calls;
202150397Sobrien    }
202250397Sobrien
202350397Sobrien  REG_N_SETS (REGNO (src))++;
202450397Sobrien  REG_N_SETS (REGNO (dst))--;
202550397Sobrien
202650397Sobrien  REG_N_CALLS_CROSSED (REGNO (dst)) -= num_calls;
202750397Sobrien
202850397Sobrien  REG_LIVE_LENGTH (REGNO (src)) += s_length;
202950397Sobrien  if (REG_LIVE_LENGTH (REGNO (dst)) >= 0)
203050397Sobrien    {
203150397Sobrien      REG_LIVE_LENGTH (REGNO (dst)) -= length;
203250397Sobrien      /* REG_LIVE_LENGTH is only an approximation after
203350397Sobrien	 combine if sched is not run, so make sure that we
203450397Sobrien	 still have a reasonable value.  */
203550397Sobrien      if (REG_LIVE_LENGTH (REGNO (dst)) < 2)
203650397Sobrien	REG_LIVE_LENGTH (REGNO (dst)) = 2;
203750397Sobrien    }
2038169689Skan  if (dump_file)
2039169689Skan    fprintf (dump_file,
204050397Sobrien	     "Fixed operand %d of insn %d matching operand %d.\n",
204150397Sobrien	     operand_number, INSN_UID (insn), match_number);
204250397Sobrien  return 1;
204350397Sobrien}
204450397Sobrien
204550397Sobrien
2046132718Skan/* Return nonzero if X is stable and mentions no registers but for
204752750Sobrien   mentioning SRC or mentioning / changing DST .  If in doubt, presume
204852750Sobrien   it is unstable.
204952750Sobrien   The rationale is that we want to check if we can move an insn easily
2050169689Skan   while just paying attention to SRC and DST.  */
205150397Sobrienstatic int
2052132718Skanstable_and_no_regs_but_for_p (rtx x, rtx src, rtx dst)
205350397Sobrien{
205450397Sobrien  RTX_CODE code = GET_CODE (x);
205550397Sobrien  switch (GET_RTX_CLASS (code))
205650397Sobrien    {
2057169689Skan    case RTX_UNARY:
2058169689Skan    case RTX_BIN_ARITH:
2059169689Skan    case RTX_COMM_ARITH:
2060169689Skan    case RTX_COMPARE:
2061169689Skan    case RTX_COMM_COMPARE:
2062169689Skan    case RTX_TERNARY:
2063169689Skan    case RTX_BITFIELD_OPS:
206450397Sobrien      {
206550397Sobrien	int i;
206690075Sobrien	const char *fmt = GET_RTX_FORMAT (code);
206750397Sobrien	for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
206852750Sobrien	  if (fmt[i] == 'e'
206952750Sobrien	      && ! stable_and_no_regs_but_for_p (XEXP (x, i), src, dst))
207050397Sobrien	      return 0;
207150397Sobrien	return 1;
207250397Sobrien      }
2073169689Skan    case RTX_OBJ:
207452750Sobrien      if (code == REG)
207552750Sobrien	return x == src || x == dst;
207652750Sobrien      /* If this is a MEM, look inside - there might be a register hidden in
207752750Sobrien	 the address of an unchanging MEM.  */
207852750Sobrien      if (code == MEM
207952750Sobrien	  && ! stable_and_no_regs_but_for_p (XEXP (x, 0), src, dst))
208052750Sobrien	return 0;
2081132718Skan      /* Fall through.  */
208250397Sobrien    default:
208350397Sobrien      return ! rtx_unstable_p (x);
208450397Sobrien    }
208550397Sobrien}
208690075Sobrien
208790075Sobrien/* Track stack adjustments and stack memory references.  Attempt to
208890075Sobrien   reduce the number of stack adjustments by back-propagating across
208990075Sobrien   the memory references.
209050397Sobrien
209190075Sobrien   This is intended primarily for use with targets that do not define
209290075Sobrien   ACCUMULATE_OUTGOING_ARGS.  It is of significantly more value to
209390075Sobrien   targets that define PREFERRED_STACK_BOUNDARY more aligned than
209490075Sobrien   STACK_BOUNDARY (e.g. x86), or if not all registers can be pushed
209590075Sobrien   (e.g. x86 fp regs) which would ordinarily have to be implemented
209690075Sobrien   as a sub/mov pair due to restrictions in calls.c.
209750397Sobrien
209890075Sobrien   Propagation stops when any of the insns that need adjusting are
209990075Sobrien   (a) no longer valid because we've exceeded their range, (b) a
210090075Sobrien   non-trivial push instruction, or (c) a call instruction.
210190075Sobrien
210290075Sobrien   Restriction B is based on the assumption that push instructions
210390075Sobrien   are smaller or faster.  If a port really wants to remove all
210490075Sobrien   pushes, it should have defined ACCUMULATE_OUTGOING_ARGS.  The
210590075Sobrien   one exception that is made is for an add immediately followed
210690075Sobrien   by a push.  */
210790075Sobrien
210890075Sobrien/* This structure records stack memory references between stack adjusting
210990075Sobrien   instructions.  */
211090075Sobrien
211190075Sobrienstruct csa_memlist
211250397Sobrien{
211390075Sobrien  HOST_WIDE_INT sp_offset;
211490075Sobrien  rtx insn, *mem;
211590075Sobrien  struct csa_memlist *next;
211690075Sobrien};
211790075Sobrien
2118132718Skanstatic int stack_memref_p (rtx);
2119132718Skanstatic rtx single_set_for_csa (rtx);
2120132718Skanstatic void free_csa_memlist (struct csa_memlist *);
2121132718Skanstatic struct csa_memlist *record_one_stack_memref (rtx, rtx *,
2122132718Skan						    struct csa_memlist *);
2123132718Skanstatic int try_apply_stack_adjustment (rtx, struct csa_memlist *,
2124132718Skan				       HOST_WIDE_INT, HOST_WIDE_INT);
2125132718Skanstatic void combine_stack_adjustments_for_block (basic_block);
2126132718Skanstatic int record_stack_memrefs (rtx *, void *);
212790075Sobrien
212890075Sobrien
212990075Sobrien/* Main entry point for stack adjustment combination.  */
213090075Sobrien
2131169689Skanstatic void
2132132718Skancombine_stack_adjustments (void)
213390075Sobrien{
2134117395Skan  basic_block bb;
213590075Sobrien
2136117395Skan  FOR_EACH_BB (bb)
2137117395Skan    combine_stack_adjustments_for_block (bb);
213890075Sobrien}
213990075Sobrien
214090075Sobrien/* Recognize a MEM of the form (sp) or (plus sp const).  */
214190075Sobrien
214290075Sobrienstatic int
2143132718Skanstack_memref_p (rtx x)
214490075Sobrien{
2145169689Skan  if (!MEM_P (x))
214690075Sobrien    return 0;
214790075Sobrien  x = XEXP (x, 0);
214890075Sobrien
214990075Sobrien  if (x == stack_pointer_rtx)
215090075Sobrien    return 1;
215190075Sobrien  if (GET_CODE (x) == PLUS
215290075Sobrien      && XEXP (x, 0) == stack_pointer_rtx
215390075Sobrien      && GET_CODE (XEXP (x, 1)) == CONST_INT)
215490075Sobrien    return 1;
215590075Sobrien
215690075Sobrien  return 0;
215790075Sobrien}
215890075Sobrien
215990075Sobrien/* Recognize either normal single_set or the hack in i386.md for
216090075Sobrien   tying fp and sp adjustments.  */
216190075Sobrien
216290075Sobrienstatic rtx
2163132718Skansingle_set_for_csa (rtx insn)
216490075Sobrien{
216590075Sobrien  int i;
216690075Sobrien  rtx tmp = single_set (insn);
216790075Sobrien  if (tmp)
216890075Sobrien    return tmp;
216990075Sobrien
2170169689Skan  if (!NONJUMP_INSN_P (insn)
217190075Sobrien      || GET_CODE (PATTERN (insn)) != PARALLEL)
217290075Sobrien    return NULL_RTX;
217390075Sobrien
217490075Sobrien  tmp = PATTERN (insn);
217590075Sobrien  if (GET_CODE (XVECEXP (tmp, 0, 0)) != SET)
217690075Sobrien    return NULL_RTX;
217790075Sobrien
217890075Sobrien  for (i = 1; i < XVECLEN (tmp, 0); ++i)
217990075Sobrien    {
218090075Sobrien      rtx this = XVECEXP (tmp, 0, i);
218190075Sobrien
218290075Sobrien      /* The special case is allowing a no-op set.  */
218390075Sobrien      if (GET_CODE (this) == SET
218490075Sobrien	  && SET_SRC (this) == SET_DEST (this))
218590075Sobrien	;
218690075Sobrien      else if (GET_CODE (this) != CLOBBER
218790075Sobrien	       && GET_CODE (this) != USE)
218890075Sobrien	return NULL_RTX;
218990075Sobrien    }
219090075Sobrien
219190075Sobrien  return XVECEXP (tmp, 0, 0);
219290075Sobrien}
219390075Sobrien
219490075Sobrien/* Free the list of csa_memlist nodes.  */
219590075Sobrien
219690075Sobrienstatic void
2197132718Skanfree_csa_memlist (struct csa_memlist *memlist)
219890075Sobrien{
219990075Sobrien  struct csa_memlist *next;
220090075Sobrien  for (; memlist ; memlist = next)
220190075Sobrien    {
220290075Sobrien      next = memlist->next;
220390075Sobrien      free (memlist);
220490075Sobrien    }
220590075Sobrien}
220690075Sobrien
220790075Sobrien/* Create a new csa_memlist node from the given memory reference.
220890075Sobrien   It is already known that the memory is stack_memref_p.  */
220990075Sobrien
221090075Sobrienstatic struct csa_memlist *
2211132718Skanrecord_one_stack_memref (rtx insn, rtx *mem, struct csa_memlist *next_memlist)
221290075Sobrien{
221390075Sobrien  struct csa_memlist *ml;
221490075Sobrien
2215169689Skan  ml = XNEW (struct csa_memlist);
221690075Sobrien
221790075Sobrien  if (XEXP (*mem, 0) == stack_pointer_rtx)
221890075Sobrien    ml->sp_offset = 0;
221990075Sobrien  else
222090075Sobrien    ml->sp_offset = INTVAL (XEXP (XEXP (*mem, 0), 1));
222190075Sobrien
222290075Sobrien  ml->insn = insn;
222390075Sobrien  ml->mem = mem;
222490075Sobrien  ml->next = next_memlist;
222590075Sobrien
222690075Sobrien  return ml;
222790075Sobrien}
222890075Sobrien
222990075Sobrien/* Attempt to apply ADJUST to the stack adjusting insn INSN, as well
223090075Sobrien   as each of the memories in MEMLIST.  Return true on success.  */
223190075Sobrien
223290075Sobrienstatic int
2233132718Skantry_apply_stack_adjustment (rtx insn, struct csa_memlist *memlist, HOST_WIDE_INT new_adjust,
2234132718Skan			    HOST_WIDE_INT delta)
223590075Sobrien{
223690075Sobrien  struct csa_memlist *ml;
223790075Sobrien  rtx set;
223890075Sobrien
223990075Sobrien  set = single_set_for_csa (insn);
224090075Sobrien  validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (new_adjust), 1);
224190075Sobrien
224290075Sobrien  for (ml = memlist; ml ; ml = ml->next)
224390075Sobrien    validate_change
224490075Sobrien      (ml->insn, ml->mem,
224590075Sobrien       replace_equiv_address_nv (*ml->mem,
224690075Sobrien				 plus_constant (stack_pointer_rtx,
224790075Sobrien						ml->sp_offset - delta)), 1);
224890075Sobrien
224990075Sobrien  if (apply_change_group ())
225090075Sobrien    {
225190075Sobrien      /* Succeeded.  Update our knowledge of the memory references.  */
225290075Sobrien      for (ml = memlist; ml ; ml = ml->next)
225390075Sobrien	ml->sp_offset -= delta;
225490075Sobrien
225590075Sobrien      return 1;
225690075Sobrien    }
225790075Sobrien  else
225890075Sobrien    return 0;
225990075Sobrien}
226090075Sobrien
226190075Sobrien/* Called via for_each_rtx and used to record all stack memory references in
226290075Sobrien   the insn and discard all other stack pointer references.  */
226390075Sobrienstruct record_stack_memrefs_data
226490075Sobrien{
226590075Sobrien  rtx insn;
226690075Sobrien  struct csa_memlist *memlist;
226790075Sobrien};
226890075Sobrien
226990075Sobrienstatic int
2270132718Skanrecord_stack_memrefs (rtx *xp, void *data)
227190075Sobrien{
227290075Sobrien  rtx x = *xp;
227390075Sobrien  struct record_stack_memrefs_data *d =
227490075Sobrien    (struct record_stack_memrefs_data *) data;
227590075Sobrien  if (!x)
227690075Sobrien    return 0;
227790075Sobrien  switch (GET_CODE (x))
227890075Sobrien    {
227990075Sobrien    case MEM:
228090075Sobrien      if (!reg_mentioned_p (stack_pointer_rtx, x))
228190075Sobrien	return -1;
228290075Sobrien      /* We are not able to handle correctly all possible memrefs containing
228390075Sobrien         stack pointer, so this check is necessary.  */
228490075Sobrien      if (stack_memref_p (x))
228550397Sobrien	{
228690075Sobrien	  d->memlist = record_one_stack_memref (d->insn, xp, d->memlist);
228790075Sobrien	  return -1;
228850397Sobrien	}
228990075Sobrien      return 1;
229090075Sobrien    case REG:
229190075Sobrien      /* ??? We want be able to handle non-memory stack pointer
2292132718Skan	 references later.  For now just discard all insns referring to
229390075Sobrien	 stack pointer outside mem expressions.  We would probably
229490075Sobrien	 want to teach validate_replace to simplify expressions first.
229590075Sobrien
229690075Sobrien	 We can't just compare with STACK_POINTER_RTX because the
229790075Sobrien	 reference to the stack pointer might be in some other mode.
2298132718Skan	 In particular, an explicit clobber in an asm statement will
2299132718Skan	 result in a QImode clobber.  */
230090075Sobrien      if (REGNO (x) == STACK_POINTER_REGNUM)
230190075Sobrien	return 1;
230290075Sobrien      break;
230390075Sobrien    default:
230490075Sobrien      break;
230590075Sobrien    }
230650397Sobrien  return 0;
230750397Sobrien}
230890075Sobrien
230990075Sobrien/* Subroutine of combine_stack_adjustments, called for each basic block.  */
231090075Sobrien
231190075Sobrienstatic void
2312132718Skancombine_stack_adjustments_for_block (basic_block bb)
231390075Sobrien{
231490075Sobrien  HOST_WIDE_INT last_sp_adjust = 0;
231590075Sobrien  rtx last_sp_set = NULL_RTX;
231690075Sobrien  struct csa_memlist *memlist = NULL;
231796263Sobrien  rtx insn, next, set;
231890075Sobrien  struct record_stack_memrefs_data data;
231996263Sobrien  bool end_of_block = false;
232090075Sobrien
2321132718Skan  for (insn = BB_HEAD (bb); !end_of_block ; insn = next)
232290075Sobrien    {
2323132718Skan      end_of_block = insn == BB_END (bb);
232490075Sobrien      next = NEXT_INSN (insn);
232590075Sobrien
232690075Sobrien      if (! INSN_P (insn))
232796263Sobrien	continue;
232890075Sobrien
232990075Sobrien      set = single_set_for_csa (insn);
233090075Sobrien      if (set)
233190075Sobrien	{
233290075Sobrien	  rtx dest = SET_DEST (set);
233390075Sobrien	  rtx src = SET_SRC (set);
233490075Sobrien
233590075Sobrien	  /* Find constant additions to the stack pointer.  */
233690075Sobrien	  if (dest == stack_pointer_rtx
233790075Sobrien	      && GET_CODE (src) == PLUS
233890075Sobrien	      && XEXP (src, 0) == stack_pointer_rtx
233990075Sobrien	      && GET_CODE (XEXP (src, 1)) == CONST_INT)
234090075Sobrien	    {
234190075Sobrien	      HOST_WIDE_INT this_adjust = INTVAL (XEXP (src, 1));
234290075Sobrien
234390075Sobrien	      /* If we've not seen an adjustment previously, record
234490075Sobrien		 it now and continue.  */
234590075Sobrien	      if (! last_sp_set)
234690075Sobrien		{
234790075Sobrien		  last_sp_set = insn;
234890075Sobrien		  last_sp_adjust = this_adjust;
234996263Sobrien		  continue;
235090075Sobrien		}
235190075Sobrien
235290075Sobrien	      /* If not all recorded memrefs can be adjusted, or the
235390075Sobrien		 adjustment is now too large for a constant addition,
235490075Sobrien		 we cannot merge the two stack adjustments.
235590075Sobrien
2356132718Skan		 Also we need to be careful to not move stack pointer
235790075Sobrien		 such that we create stack accesses outside the allocated
235890075Sobrien		 area.  We can combine an allocation into the first insn,
235990075Sobrien		 or a deallocation into the second insn.  We can not
236090075Sobrien		 combine an allocation followed by a deallocation.
236190075Sobrien
236290075Sobrien		 The only somewhat frequent occurrence of the later is when
236390075Sobrien		 a function allocates a stack frame but does not use it.
236490075Sobrien		 For this case, we would need to analyze rtl stream to be
236590075Sobrien		 sure that allocated area is really unused.  This means not
236690075Sobrien		 only checking the memory references, but also all registers
236790075Sobrien		 or global memory references possibly containing a stack
236890075Sobrien		 frame address.
236990075Sobrien
237090075Sobrien		 Perhaps the best way to address this problem is to teach
237190075Sobrien		 gcc not to allocate stack for objects never used.  */
237290075Sobrien
237390075Sobrien	      /* Combine an allocation into the first instruction.  */
237490075Sobrien	      if (STACK_GROWS_DOWNWARD ? this_adjust <= 0 : this_adjust >= 0)
237590075Sobrien		{
237690075Sobrien		  if (try_apply_stack_adjustment (last_sp_set, memlist,
237790075Sobrien						  last_sp_adjust + this_adjust,
237890075Sobrien						  this_adjust))
237990075Sobrien		    {
238090075Sobrien		      /* It worked!  */
238196263Sobrien		      delete_insn (insn);
238290075Sobrien		      last_sp_adjust += this_adjust;
238396263Sobrien		      continue;
238490075Sobrien		    }
238590075Sobrien		}
238690075Sobrien
238790075Sobrien	      /* Otherwise we have a deallocation.  Do not combine with
238890075Sobrien		 a previous allocation.  Combine into the second insn.  */
238990075Sobrien	      else if (STACK_GROWS_DOWNWARD
239090075Sobrien		       ? last_sp_adjust >= 0 : last_sp_adjust <= 0)
239190075Sobrien		{
239290075Sobrien		  if (try_apply_stack_adjustment (insn, memlist,
239390075Sobrien						  last_sp_adjust + this_adjust,
239490075Sobrien						  -last_sp_adjust))
239590075Sobrien		    {
239690075Sobrien		      /* It worked!  */
239790075Sobrien		      delete_insn (last_sp_set);
239890075Sobrien		      last_sp_set = insn;
239990075Sobrien		      last_sp_adjust += this_adjust;
240090075Sobrien		      free_csa_memlist (memlist);
240190075Sobrien		      memlist = NULL;
240296263Sobrien		      continue;
240390075Sobrien		    }
240490075Sobrien		}
240590075Sobrien
240696263Sobrien	      /* Combination failed.  Restart processing from here.  If
240796263Sobrien		 deallocation+allocation conspired to cancel, we can
240896263Sobrien		 delete the old deallocation insn.  */
240996263Sobrien	      if (last_sp_set && last_sp_adjust == 0)
241096263Sobrien		delete_insn (insn);
241190075Sobrien	      free_csa_memlist (memlist);
241290075Sobrien	      memlist = NULL;
241390075Sobrien	      last_sp_set = insn;
241490075Sobrien	      last_sp_adjust = this_adjust;
241596263Sobrien	      continue;
241690075Sobrien	    }
241790075Sobrien
241890075Sobrien	  /* Find a predecrement of exactly the previous adjustment and
241990075Sobrien	     turn it into a direct store.  Obviously we can't do this if
242090075Sobrien	     there were any intervening uses of the stack pointer.  */
242190075Sobrien	  if (memlist == NULL
2422169689Skan	      && MEM_P (dest)
242390075Sobrien	      && ((GET_CODE (XEXP (dest, 0)) == PRE_DEC
242490075Sobrien		   && (last_sp_adjust
242590075Sobrien		       == (HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (dest))))
242690075Sobrien		  || (GET_CODE (XEXP (dest, 0)) == PRE_MODIFY
242790075Sobrien		      && GET_CODE (XEXP (XEXP (dest, 0), 1)) == PLUS
242890075Sobrien		      && XEXP (XEXP (XEXP (dest, 0), 1), 0) == stack_pointer_rtx
242990075Sobrien		      && (GET_CODE (XEXP (XEXP (XEXP (dest, 0), 1), 1))
243090075Sobrien		          == CONST_INT)
243190075Sobrien		      && (INTVAL (XEXP (XEXP (XEXP (dest, 0), 1), 1))
243290075Sobrien		          == -last_sp_adjust)))
243390075Sobrien	      && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx
243490075Sobrien	      && ! reg_mentioned_p (stack_pointer_rtx, src)
243590075Sobrien	      && memory_address_p (GET_MODE (dest), stack_pointer_rtx)
243690075Sobrien	      && validate_change (insn, &SET_DEST (set),
243790075Sobrien				  replace_equiv_address (dest,
243890075Sobrien							 stack_pointer_rtx),
243990075Sobrien				  0))
244090075Sobrien	    {
244190075Sobrien	      delete_insn (last_sp_set);
244290075Sobrien	      free_csa_memlist (memlist);
244390075Sobrien	      memlist = NULL;
244490075Sobrien	      last_sp_set = NULL_RTX;
244590075Sobrien	      last_sp_adjust = 0;
244696263Sobrien	      continue;
244790075Sobrien	    }
244890075Sobrien	}
244990075Sobrien
245090075Sobrien      data.insn = insn;
245190075Sobrien      data.memlist = memlist;
2452169689Skan      if (!CALL_P (insn) && last_sp_set
245390075Sobrien	  && !for_each_rtx (&PATTERN (insn), record_stack_memrefs, &data))
245490075Sobrien	{
245590075Sobrien	   memlist = data.memlist;
245696263Sobrien	   continue;
245790075Sobrien	}
245890075Sobrien      memlist = data.memlist;
245990075Sobrien
246090075Sobrien      /* Otherwise, we were not able to process the instruction.
246190075Sobrien	 Do not continue collecting data across such a one.  */
246290075Sobrien      if (last_sp_set
2463169689Skan	  && (CALL_P (insn)
246490075Sobrien	      || reg_mentioned_p (stack_pointer_rtx, PATTERN (insn))))
246590075Sobrien	{
246696263Sobrien	  if (last_sp_set && last_sp_adjust == 0)
246796263Sobrien	    delete_insn (last_sp_set);
246890075Sobrien	  free_csa_memlist (memlist);
246990075Sobrien	  memlist = NULL;
247090075Sobrien	  last_sp_set = NULL_RTX;
247190075Sobrien	  last_sp_adjust = 0;
247290075Sobrien	}
247390075Sobrien    }
247490075Sobrien
247596263Sobrien  if (last_sp_set && last_sp_adjust == 0)
247696263Sobrien    delete_insn (last_sp_set);
2477169689Skan
2478169689Skan  if (memlist)
2479169689Skan    free_csa_memlist (memlist);
248090075Sobrien}
2481169689Skan
2482169689Skanstatic bool
2483169689Skangate_handle_regmove (void)
2484169689Skan{
2485169689Skan  return (optimize > 0 && flag_regmove);
2486169689Skan}
2487169689Skan
2488169689Skan
2489169689Skan/* Register allocation pre-pass, to reduce number of moves necessary
2490169689Skan   for two-address machines.  */
2491169689Skanstatic unsigned int
2492169689Skanrest_of_handle_regmove (void)
2493169689Skan{
2494169689Skan  regmove_optimize (get_insns (), max_reg_num ());
2495169689Skan  cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
2496169689Skan  return 0;
2497169689Skan}
2498169689Skan
2499169689Skanstruct tree_opt_pass pass_regmove =
2500169689Skan{
2501169689Skan  "regmove",                            /* name */
2502169689Skan  gate_handle_regmove,                  /* gate */
2503169689Skan  rest_of_handle_regmove,               /* execute */
2504169689Skan  NULL,                                 /* sub */
2505169689Skan  NULL,                                 /* next */
2506169689Skan  0,                                    /* static_pass_number */
2507169689Skan  TV_REGMOVE,                           /* tv_id */
2508169689Skan  0,                                    /* properties_required */
2509169689Skan  0,                                    /* properties_provided */
2510169689Skan  0,                                    /* properties_destroyed */
2511169689Skan  0,                                    /* todo_flags_start */
2512169689Skan  TODO_dump_func |
2513169689Skan  TODO_ggc_collect,                     /* todo_flags_finish */
2514169689Skan  'N'                                   /* letter */
2515169689Skan};
2516169689Skan
2517169689Skan
2518169689Skanstatic bool
2519169689Skangate_handle_stack_adjustments (void)
2520169689Skan{
2521169689Skan  return (optimize > 0);
2522169689Skan}
2523169689Skan
2524169689Skanstatic unsigned int
2525169689Skanrest_of_handle_stack_adjustments (void)
2526169689Skan{
2527169689Skan  life_analysis (PROP_POSTRELOAD);
2528169689Skan  cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE
2529169689Skan               | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
2530169689Skan
2531169689Skan  /* This is kind of a heuristic.  We need to run combine_stack_adjustments
2532169689Skan     even for machines with possibly nonzero RETURN_POPS_ARGS
2533169689Skan     and ACCUMULATE_OUTGOING_ARGS.  We expect that only ports having
2534169689Skan     push instructions will have popping returns.  */
2535169689Skan#ifndef PUSH_ROUNDING
2536169689Skan  if (!ACCUMULATE_OUTGOING_ARGS)
2537169689Skan#endif
2538169689Skan    combine_stack_adjustments ();
2539169689Skan  return 0;
2540169689Skan}
2541169689Skan
2542169689Skanstruct tree_opt_pass pass_stack_adjustments =
2543169689Skan{
2544169689Skan  "csa",                                /* name */
2545169689Skan  gate_handle_stack_adjustments,        /* gate */
2546169689Skan  rest_of_handle_stack_adjustments,     /* execute */
2547169689Skan  NULL,                                 /* sub */
2548169689Skan  NULL,                                 /* next */
2549169689Skan  0,                                    /* static_pass_number */
2550169689Skan  0,                                    /* tv_id */
2551169689Skan  0,                                    /* properties_required */
2552169689Skan  0,                                    /* properties_provided */
2553169689Skan  0,                                    /* properties_destroyed */
2554169689Skan  0,                                    /* todo_flags_start */
2555169689Skan  TODO_dump_func |
2556169689Skan  TODO_ggc_collect,                     /* todo_flags_finish */
2557169689Skan  0                                     /* letter */
2558169689Skan};
2559169689Skan
2560