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