regmove.c revision 169689
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 = ®_NOTES (move_insn); 78850397Sobrien p_insn_notes = ®_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