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