1 1.1 mrg /* Code for RTL register eliminations. 2 1.1 mrg Copyright (C) 2010-2022 Free Software Foundation, Inc. 3 1.1 mrg Contributed by Vladimir Makarov <vmakarov (at) redhat.com>. 4 1.1 mrg 5 1.1 mrg This file is part of GCC. 6 1.1 mrg 7 1.1 mrg GCC is free software; you can redistribute it and/or modify it under 8 1.1 mrg the terms of the GNU General Public License as published by the Free 9 1.1 mrg Software Foundation; either version 3, or (at your option) any later 10 1.1 mrg version. 11 1.1 mrg 12 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 1.1 mrg for more details. 16 1.1 mrg 17 1.1 mrg You should have received a copy of the GNU General Public License 18 1.1 mrg along with GCC; see the file COPYING3. If not see 19 1.1 mrg <http://www.gnu.org/licenses/>. */ 20 1.1 mrg 21 1.1 mrg /* Eliminable registers (like a soft argument or frame pointer) are 22 1.1 mrg widely used in RTL. These eliminable registers should be replaced 23 1.1 mrg by real hard registers (like the stack pointer or hard frame 24 1.1 mrg pointer) plus some offset. The offsets usually change whenever the 25 1.1 mrg stack is expanded. We know the final offsets only at the very end 26 1.1 mrg of LRA. 27 1.1 mrg 28 1.1 mrg Within LRA, we usually keep the RTL in such a state that the 29 1.1 mrg eliminable registers can be replaced by just the corresponding hard 30 1.1 mrg register (without any offset). To achieve this we should add the 31 1.1 mrg initial elimination offset at the beginning of LRA and update the 32 1.1 mrg offsets whenever the stack is expanded. We need to do this before 33 1.1 mrg every constraint pass because the choice of offset often affects 34 1.1 mrg whether a particular address or memory constraint is satisfied. 35 1.1 mrg 36 1.1 mrg We keep RTL code at most time in such state that the virtual 37 1.1 mrg registers can be changed by just the corresponding hard registers 38 1.1 mrg (with zero offsets) and we have the right RTL code. To achieve this 39 1.1 mrg we should add initial offset at the beginning of LRA work and update 40 1.1 mrg offsets after each stack expanding. But actually we update virtual 41 1.1 mrg registers to the same virtual registers + corresponding offsets 42 1.1 mrg before every constraint pass because it affects constraint 43 1.1 mrg satisfaction (e.g. an address displacement became too big for some 44 1.1 mrg target). 45 1.1 mrg 46 1.1 mrg The final change of eliminable registers to the corresponding hard 47 1.1 mrg registers are done at the very end of LRA when there were no change 48 1.1 mrg in offsets anymore: 49 1.1 mrg 50 1.1 mrg fp + 42 => sp + 42 51 1.1 mrg 52 1.1 mrg */ 53 1.1 mrg 54 1.1 mrg #include "config.h" 55 1.1 mrg #include "system.h" 56 1.1 mrg #include "coretypes.h" 57 1.1 mrg #include "backend.h" 58 1.1 mrg #include "target.h" 59 1.1 mrg #include "rtl.h" 60 1.1 mrg #include "tree.h" 61 1.1 mrg #include "df.h" 62 1.1 mrg #include "memmodel.h" 63 1.1 mrg #include "tm_p.h" 64 1.1 mrg #include "optabs.h" 65 1.1 mrg #include "regs.h" 66 1.1 mrg #include "ira.h" 67 1.1 mrg #include "recog.h" 68 1.1 mrg #include "output.h" 69 1.1 mrg #include "rtl-error.h" 70 1.1 mrg #include "lra-int.h" 71 1.1 mrg 72 1.1 mrg /* This structure is used to record information about hard register 73 1.1 mrg eliminations. */ 74 1.1 mrg class lra_elim_table 75 1.1 mrg { 76 1.1 mrg public: 77 1.1 mrg /* Hard register number to be eliminated. */ 78 1.1 mrg int from; 79 1.1 mrg /* Hard register number used as replacement. */ 80 1.1 mrg int to; 81 1.1 mrg /* Difference between values of the two hard registers above on 82 1.1 mrg previous iteration. */ 83 1.1 mrg poly_int64 previous_offset; 84 1.1 mrg /* Difference between the values on the current iteration. */ 85 1.1 mrg poly_int64 offset; 86 1.1 mrg /* Nonzero if this elimination can be done. */ 87 1.1 mrg bool can_eliminate; 88 1.1 mrg /* CAN_ELIMINATE since the last check. */ 89 1.1 mrg bool prev_can_eliminate; 90 1.1 mrg /* REG rtx for the register to be eliminated. We cannot simply 91 1.1 mrg compare the number since we might then spuriously replace a hard 92 1.1 mrg register corresponding to a pseudo assigned to the reg to be 93 1.1 mrg eliminated. */ 94 1.1 mrg rtx from_rtx; 95 1.1 mrg /* REG rtx for the replacement. */ 96 1.1 mrg rtx to_rtx; 97 1.1 mrg }; 98 1.1 mrg 99 1.1 mrg /* The elimination table. Each array entry describes one possible way 100 1.1 mrg of eliminating a register in favor of another. If there is more 101 1.1 mrg than one way of eliminating a particular register, the most 102 1.1 mrg preferred should be specified first. */ 103 1.1 mrg static class lra_elim_table *reg_eliminate = 0; 104 1.1 mrg 105 1.1 mrg /* This is an intermediate structure to initialize the table. It has 106 1.1 mrg exactly the members provided by ELIMINABLE_REGS. */ 107 1.1 mrg static const struct elim_table_1 108 1.1 mrg { 109 1.1 mrg const int from; 110 1.1 mrg const int to; 111 1.1 mrg } reg_eliminate_1[] = 112 1.1 mrg 113 1.1 mrg ELIMINABLE_REGS; 114 1.1 mrg 115 1.1 mrg #define NUM_ELIMINABLE_REGS ARRAY_SIZE (reg_eliminate_1) 116 1.1 mrg 117 1.1 mrg /* Print info about elimination table to file F. */ 118 1.1 mrg static void 119 1.1 mrg print_elim_table (FILE *f) 120 1.1 mrg { 121 1.1 mrg class lra_elim_table *ep; 122 1.1 mrg 123 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 124 1.1 mrg { 125 1.1 mrg fprintf (f, "%s eliminate %d to %d (offset=", 126 1.1 mrg ep->can_eliminate ? "Can" : "Can't", ep->from, ep->to); 127 1.1 mrg print_dec (ep->offset, f); 128 1.1 mrg fprintf (f, ", prev_offset="); 129 1.1 mrg print_dec (ep->previous_offset, f); 130 1.1 mrg fprintf (f, ")\n"); 131 1.1 mrg } 132 1.1 mrg } 133 1.1 mrg 134 1.1 mrg /* Print info about elimination table to stderr. */ 135 1.1 mrg void 136 1.1 mrg lra_debug_elim_table (void) 137 1.1 mrg { 138 1.1 mrg print_elim_table (stderr); 139 1.1 mrg } 140 1.1 mrg 141 1.1 mrg /* Setup possibility of elimination in elimination table element EP to 142 1.1 mrg VALUE. Setup FRAME_POINTER_NEEDED if elimination from frame 143 1.1 mrg pointer to stack pointer is not possible anymore. */ 144 1.1 mrg static void 145 1.1 mrg setup_can_eliminate (class lra_elim_table *ep, bool value) 146 1.1 mrg { 147 1.1 mrg ep->can_eliminate = ep->prev_can_eliminate = value; 148 1.1 mrg if (! value 149 1.1 mrg && ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM) 150 1.1 mrg frame_pointer_needed = 1; 151 1.1 mrg if (!frame_pointer_needed) 152 1.1 mrg REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = 0; 153 1.1 mrg } 154 1.1 mrg 155 1.1 mrg /* Map: eliminable "from" register -> its current elimination, 156 1.1 mrg or NULL if none. The elimination table may contain more than 157 1.1 mrg one elimination for the same hard register, but this map specifies 158 1.1 mrg the one that we are currently using. */ 159 1.1 mrg static class lra_elim_table *elimination_map[FIRST_PSEUDO_REGISTER]; 160 1.1 mrg 161 1.1 mrg /* When an eliminable hard register becomes not eliminable, we use the 162 1.1 mrg following special structure to restore original offsets for the 163 1.1 mrg register. */ 164 1.1 mrg static class lra_elim_table self_elim_table; 165 1.1 mrg 166 1.1 mrg /* Offsets should be used to restore original offsets for eliminable 167 1.1 mrg hard register which just became not eliminable. Zero, 168 1.1 mrg otherwise. */ 169 1.1 mrg static poly_int64_pod self_elim_offsets[FIRST_PSEUDO_REGISTER]; 170 1.1 mrg 171 1.1 mrg /* Map: hard regno -> RTL presentation. RTL presentations of all 172 1.1 mrg potentially eliminable hard registers are stored in the map. */ 173 1.1 mrg static rtx eliminable_reg_rtx[FIRST_PSEUDO_REGISTER]; 174 1.1 mrg 175 1.1 mrg /* Set up ELIMINATION_MAP of the currently used eliminations. */ 176 1.1 mrg static void 177 1.1 mrg setup_elimination_map (void) 178 1.1 mrg { 179 1.1 mrg int i; 180 1.1 mrg class lra_elim_table *ep; 181 1.1 mrg 182 1.1 mrg for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 183 1.1 mrg elimination_map[i] = NULL; 184 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 185 1.1 mrg if (ep->can_eliminate && elimination_map[ep->from] == NULL) 186 1.1 mrg elimination_map[ep->from] = ep; 187 1.1 mrg } 188 1.1 mrg 189 1.1 mrg 190 1.1 mrg 192 1.1 mrg /* Compute the sum of X and Y, making canonicalizations assumed in an 193 1.1 mrg address, namely: sum constant integers, surround the sum of two 194 1.1 mrg constants with a CONST, put the constant as the second operand, and 195 1.1 mrg group the constant on the outermost sum. 196 1.1 mrg 197 1.1 mrg This routine assumes both inputs are already in canonical form. */ 198 1.1 mrg static rtx 199 1.1 mrg form_sum (rtx x, rtx y) 200 1.1 mrg { 201 1.1 mrg machine_mode mode = GET_MODE (x); 202 1.1 mrg poly_int64 offset; 203 1.1 mrg 204 1.1 mrg if (mode == VOIDmode) 205 1.1 mrg mode = GET_MODE (y); 206 1.1 mrg 207 1.1 mrg if (mode == VOIDmode) 208 1.1 mrg mode = Pmode; 209 1.1 mrg 210 1.1 mrg if (poly_int_rtx_p (x, &offset)) 211 1.1 mrg return plus_constant (mode, y, offset); 212 1.1 mrg else if (poly_int_rtx_p (y, &offset)) 213 1.1 mrg return plus_constant (mode, x, offset); 214 1.1 mrg else if (CONSTANT_P (x)) 215 1.1 mrg std::swap (x, y); 216 1.1 mrg 217 1.1 mrg if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1))) 218 1.1 mrg return form_sum (XEXP (x, 0), form_sum (XEXP (x, 1), y)); 219 1.1 mrg 220 1.1 mrg /* Note that if the operands of Y are specified in the opposite 221 1.1 mrg order in the recursive calls below, infinite recursion will 222 1.1 mrg occur. */ 223 1.1 mrg if (GET_CODE (y) == PLUS && CONSTANT_P (XEXP (y, 1))) 224 1.1 mrg return form_sum (form_sum (x, XEXP (y, 0)), XEXP (y, 1)); 225 1.1 mrg 226 1.1 mrg /* If both constant, encapsulate sum. Otherwise, just form sum. A 227 1.1 mrg constant will have been placed second. */ 228 1.1 mrg if (CONSTANT_P (x) && CONSTANT_P (y)) 229 1.1 mrg { 230 1.1 mrg if (GET_CODE (x) == CONST) 231 1.1 mrg x = XEXP (x, 0); 232 1.1 mrg if (GET_CODE (y) == CONST) 233 1.1 mrg y = XEXP (y, 0); 234 1.1 mrg 235 1.1 mrg return gen_rtx_CONST (VOIDmode, gen_rtx_PLUS (mode, x, y)); 236 1.1 mrg } 237 1.1 mrg 238 1.1 mrg return gen_rtx_PLUS (mode, x, y); 239 1.1 mrg } 240 1.1 mrg 241 1.1 mrg /* Return the current substitution hard register of the elimination of 242 1.1 mrg HARD_REGNO. If HARD_REGNO is not eliminable, return itself. */ 243 1.1 mrg int 244 1.1 mrg lra_get_elimination_hard_regno (int hard_regno) 245 1.1 mrg { 246 1.1 mrg class lra_elim_table *ep; 247 1.1 mrg 248 1.1 mrg if (hard_regno < 0 || hard_regno >= FIRST_PSEUDO_REGISTER) 249 1.1 mrg return hard_regno; 250 1.1 mrg if ((ep = elimination_map[hard_regno]) == NULL) 251 1.1 mrg return hard_regno; 252 1.1 mrg return ep->to; 253 1.1 mrg } 254 1.1 mrg 255 1.1 mrg /* Return elimination which will be used for hard reg REG, NULL 256 1.1 mrg otherwise. */ 257 1.1 mrg static class lra_elim_table * 258 1.1 mrg get_elimination (rtx reg) 259 1.1 mrg { 260 1.1 mrg int hard_regno; 261 1.1 mrg class lra_elim_table *ep; 262 1.1 mrg 263 1.1 mrg lra_assert (REG_P (reg)); 264 1.1 mrg if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER) 265 1.1 mrg return NULL; 266 1.1 mrg if ((ep = elimination_map[hard_regno]) != NULL) 267 1.1 mrg return ep->from_rtx != reg ? NULL : ep; 268 1.1 mrg poly_int64 offset = self_elim_offsets[hard_regno]; 269 1.1 mrg if (known_eq (offset, 0)) 270 1.1 mrg return NULL; 271 1.1 mrg /* This is an iteration to restore offsets just after HARD_REGNO 272 1.1 mrg stopped to be eliminable. */ 273 1.1 mrg self_elim_table.from = self_elim_table.to = hard_regno; 274 1.1 mrg self_elim_table.from_rtx 275 1.1 mrg = self_elim_table.to_rtx 276 1.1 mrg = eliminable_reg_rtx[hard_regno]; 277 1.1 mrg lra_assert (self_elim_table.from_rtx != NULL); 278 1.1 mrg self_elim_table.offset = offset; 279 1.1 mrg return &self_elim_table; 280 1.1 mrg } 281 1.1 mrg 282 1.1 mrg /* Transform (subreg (plus reg const)) to (plus (subreg reg) const) 283 1.1 mrg when it is possible. Return X or the transformation result if the 284 1.1 mrg transformation is done. */ 285 1.1 mrg static rtx 286 1.1 mrg move_plus_up (rtx x) 287 1.1 mrg { 288 1.1 mrg rtx subreg_reg; 289 1.1 mrg machine_mode x_mode, subreg_reg_mode; 290 1.1 mrg 291 1.1 mrg if (GET_CODE (x) != SUBREG || !subreg_lowpart_p (x)) 292 1.1 mrg return x; 293 1.1 mrg subreg_reg = SUBREG_REG (x); 294 1.1 mrg x_mode = GET_MODE (x); 295 1.1 mrg subreg_reg_mode = GET_MODE (subreg_reg); 296 1.1 mrg if (!paradoxical_subreg_p (x) 297 1.1 mrg && GET_CODE (subreg_reg) == PLUS 298 1.1 mrg && CONSTANT_P (XEXP (subreg_reg, 1)) 299 1.1 mrg && GET_MODE_CLASS (x_mode) == MODE_INT 300 1.1 mrg && GET_MODE_CLASS (subreg_reg_mode) == MODE_INT) 301 1.1 mrg { 302 1.1 mrg rtx cst = simplify_subreg (x_mode, XEXP (subreg_reg, 1), subreg_reg_mode, 303 1.1 mrg subreg_lowpart_offset (x_mode, 304 1.1 mrg subreg_reg_mode)); 305 1.1 mrg if (cst && CONSTANT_P (cst)) 306 1.1 mrg return gen_rtx_PLUS (x_mode, lowpart_subreg (x_mode, 307 1.1 mrg XEXP (subreg_reg, 0), 308 1.1 mrg subreg_reg_mode), cst); 309 1.1 mrg } 310 1.1 mrg return x; 311 1.1 mrg } 312 1.1 mrg 313 1.1 mrg /* Scan X and replace any eliminable registers (such as fp) with a 314 1.1 mrg replacement (such as sp) if SUBST_P, plus an offset. The offset is 315 1.1 mrg a change in the offset between the eliminable register and its 316 1.1 mrg substitution if UPDATE_P, or the full offset if FULL_P, or 317 1.1 mrg otherwise zero. If FULL_P, we also use the SP offsets for 318 1.1 mrg elimination to SP. If UPDATE_P, use UPDATE_SP_OFFSET for updating 319 1.1 mrg offsets of register elimnable to SP. If UPDATE_SP_OFFSET is 320 1.1 mrg non-zero, don't use difference of the offset and the previous 321 1.1 mrg offset. 322 1.1 mrg 323 1.1 mrg MEM_MODE is the mode of an enclosing MEM. We need this to know how 324 1.1 mrg much to adjust a register for, e.g., PRE_DEC. Also, if we are 325 1.1 mrg inside a MEM, we are allowed to replace a sum of a hard register 326 1.1 mrg and the constant zero with the hard register, which we cannot do 327 1.1 mrg outside a MEM. In addition, we need to record the fact that a 328 1.1 mrg hard register is referenced outside a MEM. 329 1.1 mrg 330 1.1 mrg If we make full substitution to SP for non-null INSN, add the insn 331 1.1 mrg sp offset. */ 332 1.1 mrg rtx 333 1.1 mrg lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, 334 1.1 mrg bool subst_p, bool update_p, 335 1.1 mrg poly_int64 update_sp_offset, bool full_p) 336 1.1 mrg { 337 1.1 mrg enum rtx_code code = GET_CODE (x); 338 1.1 mrg class lra_elim_table *ep; 339 1.1 mrg rtx new_rtx; 340 1.1 mrg int i, j; 341 1.1 mrg const char *fmt; 342 1.1 mrg int copied = 0; 343 1.1 mrg 344 1.1 mrg lra_assert (!update_p || !full_p); 345 1.1 mrg lra_assert (known_eq (update_sp_offset, 0) 346 1.1 mrg || (!subst_p && update_p && !full_p)); 347 1.1 mrg if (! current_function_decl) 348 1.1 mrg return x; 349 1.1 mrg 350 1.1 mrg switch (code) 351 1.1 mrg { 352 1.1 mrg CASE_CONST_ANY: 353 1.1 mrg case CONST: 354 1.1 mrg case SYMBOL_REF: 355 1.1 mrg case CODE_LABEL: 356 1.1 mrg case PC: 357 1.1 mrg case ASM_INPUT: 358 1.1 mrg case ADDR_VEC: 359 1.1 mrg case ADDR_DIFF_VEC: 360 1.1 mrg case RETURN: 361 1.1 mrg return x; 362 1.1 mrg 363 1.1 mrg case REG: 364 1.1 mrg /* First handle the case where we encounter a bare hard register 365 1.1 mrg that is eliminable. Replace it with a PLUS. */ 366 1.1 mrg if ((ep = get_elimination (x)) != NULL) 367 1.1 mrg { 368 1.1 mrg rtx to = subst_p ? ep->to_rtx : ep->from_rtx; 369 1.1 mrg 370 1.1 mrg if (maybe_ne (update_sp_offset, 0)) 371 1.1 mrg { 372 1.1 mrg if (ep->to_rtx == stack_pointer_rtx) 373 1.1 mrg return plus_constant (Pmode, to, update_sp_offset); 374 1.1 mrg return to; 375 1.1 mrg } 376 1.1 mrg else if (update_p) 377 1.1 mrg return plus_constant (Pmode, to, ep->offset - ep->previous_offset); 378 1.1 mrg else if (full_p) 379 1.1 mrg return plus_constant (Pmode, to, 380 1.1 mrg ep->offset 381 1.1 mrg - (insn != NULL_RTX 382 1.1 mrg && ep->to_rtx == stack_pointer_rtx 383 1.1 mrg ? lra_get_insn_recog_data (insn)->sp_offset 384 1.1 mrg : 0)); 385 1.1 mrg else 386 1.1 mrg return to; 387 1.1 mrg } 388 1.1 mrg return x; 389 1.1 mrg 390 1.1 mrg case PLUS: 391 1.1 mrg /* If this is the sum of an eliminable register and a constant, rework 392 1.1 mrg the sum. */ 393 1.1 mrg if (REG_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1))) 394 1.1 mrg { 395 1.1 mrg if ((ep = get_elimination (XEXP (x, 0))) != NULL) 396 1.1 mrg { 397 1.1 mrg poly_int64 offset, curr_offset; 398 1.1 mrg rtx to = subst_p ? ep->to_rtx : ep->from_rtx; 399 1.1 mrg 400 1.1 mrg if (! update_p && ! full_p) 401 1.1 mrg return simplify_gen_binary (PLUS, Pmode, to, XEXP (x, 1)); 402 1.1 mrg 403 1.1 mrg if (maybe_ne (update_sp_offset, 0)) 404 1.1 mrg offset = ep->to_rtx == stack_pointer_rtx ? update_sp_offset : 0; 405 1.1 mrg else 406 1.1 mrg offset = (update_p 407 1.1 mrg ? ep->offset - ep->previous_offset : ep->offset); 408 1.1 mrg if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx) 409 1.1 mrg offset -= lra_get_insn_recog_data (insn)->sp_offset; 410 1.1 mrg if (poly_int_rtx_p (XEXP (x, 1), &curr_offset) 411 1.1 mrg && known_eq (curr_offset, -offset)) 412 1.1 mrg return to; 413 1.1 mrg else 414 1.1 mrg return gen_rtx_PLUS (Pmode, to, 415 1.1 mrg plus_constant (Pmode, 416 1.1 mrg XEXP (x, 1), offset)); 417 1.1 mrg } 418 1.1 mrg 419 1.1 mrg /* If the hard register is not eliminable, we are done since 420 1.1 mrg the other operand is a constant. */ 421 1.1 mrg return x; 422 1.1 mrg } 423 1.1 mrg 424 1.1 mrg /* If this is part of an address, we want to bring any constant 425 1.1 mrg to the outermost PLUS. We will do this by doing hard 426 1.1 mrg register replacement in our operands and seeing if a constant 427 1.1 mrg shows up in one of them. 428 1.1 mrg 429 1.1 mrg Note that there is no risk of modifying the structure of the 430 1.1 mrg insn, since we only get called for its operands, thus we are 431 1.1 mrg either modifying the address inside a MEM, or something like 432 1.1 mrg an address operand of a load-address insn. */ 433 1.1 mrg 434 1.1 mrg { 435 1.1 mrg rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode, 436 1.1 mrg subst_p, update_p, 437 1.1 mrg update_sp_offset, full_p); 438 1.1 mrg rtx new1 = lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode, 439 1.1 mrg subst_p, update_p, 440 1.1 mrg update_sp_offset, full_p); 441 1.1 mrg 442 1.1 mrg new0 = move_plus_up (new0); 443 1.1 mrg new1 = move_plus_up (new1); 444 1.1 mrg if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1)) 445 1.1 mrg return form_sum (new0, new1); 446 1.1 mrg } 447 1.1 mrg return x; 448 1.1 mrg 449 1.1 mrg case MULT: 450 1.1 mrg /* If this is the product of an eliminable hard register and a 451 1.1 mrg constant, apply the distribute law and move the constant out 452 1.1 mrg so that we have (plus (mult ..) ..). This is needed in order 453 1.1 mrg to keep load-address insns valid. This case is pathological. 454 1.1 mrg We ignore the possibility of overflow here. */ 455 1.1 mrg if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)) 456 1.1 mrg && (ep = get_elimination (XEXP (x, 0))) != NULL) 457 1.1 mrg { 458 1.1 mrg rtx to = subst_p ? ep->to_rtx : ep->from_rtx; 459 1.1 mrg 460 1.1 mrg if (maybe_ne (update_sp_offset, 0)) 461 1.1 mrg { 462 1.1 mrg if (ep->to_rtx == stack_pointer_rtx) 463 1.1 mrg return plus_constant (Pmode, 464 1.1 mrg gen_rtx_MULT (Pmode, to, XEXP (x, 1)), 465 1.1 mrg update_sp_offset * INTVAL (XEXP (x, 1))); 466 1.1 mrg return gen_rtx_MULT (Pmode, to, XEXP (x, 1)); 467 1.1 mrg } 468 1.1 mrg else if (update_p) 469 1.1 mrg return plus_constant (Pmode, 470 1.1 mrg gen_rtx_MULT (Pmode, to, XEXP (x, 1)), 471 1.1 mrg (ep->offset - ep->previous_offset) 472 1.1 mrg * INTVAL (XEXP (x, 1))); 473 1.1 mrg else if (full_p) 474 1.1 mrg { 475 1.1 mrg poly_int64 offset = ep->offset; 476 1.1 mrg 477 1.1 mrg if (insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx) 478 1.1 mrg offset -= lra_get_insn_recog_data (insn)->sp_offset; 479 1.1 mrg return 480 1.1 mrg plus_constant (Pmode, 481 1.1 mrg gen_rtx_MULT (Pmode, to, XEXP (x, 1)), 482 1.1 mrg offset * INTVAL (XEXP (x, 1))); 483 1.1 mrg } 484 1.1 mrg else 485 1.1 mrg return gen_rtx_MULT (Pmode, to, XEXP (x, 1)); 486 1.1 mrg } 487 1.1 mrg 488 1.1 mrg /* fall through */ 489 1.1 mrg 490 1.1 mrg case CALL: 491 1.1 mrg case COMPARE: 492 1.1 mrg /* See comments before PLUS about handling MINUS. */ 493 1.1 mrg case MINUS: 494 1.1 mrg case DIV: case UDIV: 495 1.1 mrg case MOD: case UMOD: 496 1.1 mrg case AND: case IOR: case XOR: 497 1.1 mrg case ROTATERT: case ROTATE: 498 1.1 mrg case ASHIFTRT: case LSHIFTRT: case ASHIFT: 499 1.1 mrg case NE: case EQ: 500 1.1 mrg case GE: case GT: case GEU: case GTU: 501 1.1 mrg case LE: case LT: case LEU: case LTU: 502 1.1 mrg { 503 1.1 mrg rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode, 504 1.1 mrg subst_p, update_p, 505 1.1 mrg update_sp_offset, full_p); 506 1.1 mrg rtx new1 = XEXP (x, 1) 507 1.1 mrg ? lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode, 508 1.1 mrg subst_p, update_p, 509 1.1 mrg update_sp_offset, full_p) : 0; 510 1.1 mrg 511 1.1 mrg if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1)) 512 1.1 mrg return gen_rtx_fmt_ee (code, GET_MODE (x), new0, new1); 513 1.1 mrg } 514 1.1 mrg return x; 515 1.1 mrg 516 1.1 mrg case EXPR_LIST: 517 1.1 mrg /* If we have something in XEXP (x, 0), the usual case, 518 1.1 mrg eliminate it. */ 519 1.1 mrg if (XEXP (x, 0)) 520 1.1 mrg { 521 1.1 mrg new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode, 522 1.1 mrg subst_p, update_p, 523 1.1 mrg update_sp_offset, full_p); 524 1.1 mrg if (new_rtx != XEXP (x, 0)) 525 1.1 mrg { 526 1.1 mrg /* If this is a REG_DEAD note, it is not valid anymore. 527 1.1 mrg Using the eliminated version could result in creating a 528 1.1 mrg REG_DEAD note for the stack or frame pointer. */ 529 1.1 mrg if (REG_NOTE_KIND (x) == REG_DEAD) 530 1.1 mrg return (XEXP (x, 1) 531 1.1 mrg ? lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode, 532 1.1 mrg subst_p, update_p, 533 1.1 mrg update_sp_offset, full_p) 534 1.1 mrg : NULL_RTX); 535 1.1 mrg 536 1.1 mrg x = alloc_reg_note (REG_NOTE_KIND (x), new_rtx, XEXP (x, 1)); 537 1.1 mrg } 538 1.1 mrg } 539 1.1 mrg 540 1.1 mrg /* fall through */ 541 1.1 mrg 542 1.1 mrg case INSN_LIST: 543 1.1 mrg case INT_LIST: 544 1.1 mrg /* Now do eliminations in the rest of the chain. If this was 545 1.1 mrg an EXPR_LIST, this might result in allocating more memory than is 546 1.1 mrg strictly needed, but it simplifies the code. */ 547 1.1 mrg if (XEXP (x, 1)) 548 1.1 mrg { 549 1.1 mrg new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode, 550 1.1 mrg subst_p, update_p, 551 1.1 mrg update_sp_offset, full_p); 552 1.1 mrg if (new_rtx != XEXP (x, 1)) 553 1.1 mrg return 554 1.1 mrg gen_rtx_fmt_ee (GET_CODE (x), GET_MODE (x), 555 1.1 mrg XEXP (x, 0), new_rtx); 556 1.1 mrg } 557 1.1 mrg return x; 558 1.1 mrg 559 1.1 mrg case PRE_INC: 560 1.1 mrg case POST_INC: 561 1.1 mrg case PRE_DEC: 562 1.1 mrg case POST_DEC: 563 1.1 mrg /* We do not support elimination of a register that is modified. 564 1.1 mrg elimination_effects has already make sure that this does not 565 1.1 mrg happen. */ 566 1.1 mrg return x; 567 1.1 mrg 568 1.1 mrg case PRE_MODIFY: 569 1.1 mrg case POST_MODIFY: 570 1.1 mrg /* We do not support elimination of a hard register that is 571 1.1 mrg modified. LRA has already make sure that this does not 572 1.1 mrg happen. The only remaining case we need to consider here is 573 1.1 mrg that the increment value may be an eliminable register. */ 574 1.1 mrg if (GET_CODE (XEXP (x, 1)) == PLUS 575 1.1 mrg && XEXP (XEXP (x, 1), 0) == XEXP (x, 0)) 576 1.1 mrg { 577 1.1 mrg rtx new_rtx = lra_eliminate_regs_1 (insn, XEXP (XEXP (x, 1), 1), 578 1.1 mrg mem_mode, subst_p, update_p, 579 1.1 mrg update_sp_offset, full_p); 580 1.1 mrg 581 1.1 mrg if (new_rtx != XEXP (XEXP (x, 1), 1)) 582 1.1 mrg return gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (x, 0), 583 1.1 mrg gen_rtx_PLUS (GET_MODE (x), 584 1.1 mrg XEXP (x, 0), new_rtx)); 585 1.1 mrg } 586 1.1 mrg return x; 587 1.1 mrg 588 1.1 mrg case STRICT_LOW_PART: 589 1.1 mrg case NEG: case NOT: 590 1.1 mrg case SIGN_EXTEND: case ZERO_EXTEND: 591 1.1 mrg case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: 592 1.1 mrg case FLOAT: case FIX: 593 1.1 mrg case UNSIGNED_FIX: case UNSIGNED_FLOAT: 594 1.1 mrg case ABS: 595 1.1 mrg case SQRT: 596 1.1 mrg case FFS: 597 1.1 mrg case CLZ: 598 1.1 mrg case CTZ: 599 1.1 mrg case POPCOUNT: 600 1.1 mrg case PARITY: 601 1.1 mrg case BSWAP: 602 1.1 mrg new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode, 603 1.1 mrg subst_p, update_p, 604 1.1 mrg update_sp_offset, full_p); 605 1.1 mrg if (new_rtx != XEXP (x, 0)) 606 1.1 mrg return gen_rtx_fmt_e (code, GET_MODE (x), new_rtx); 607 1.1 mrg return x; 608 1.1 mrg 609 1.1 mrg case SUBREG: 610 1.1 mrg new_rtx = lra_eliminate_regs_1 (insn, SUBREG_REG (x), mem_mode, 611 1.1 mrg subst_p, update_p, 612 1.1 mrg update_sp_offset, full_p); 613 1.1 mrg 614 1.1 mrg if (new_rtx != SUBREG_REG (x)) 615 1.1 mrg { 616 1.1 mrg if (MEM_P (new_rtx) && !paradoxical_subreg_p (x)) 617 1.1 mrg { 618 1.1 mrg SUBREG_REG (x) = new_rtx; 619 1.1 mrg alter_subreg (&x, false); 620 1.1 mrg return x; 621 1.1 mrg } 622 1.1 mrg else if (! subst_p) 623 1.1 mrg { 624 1.1 mrg /* LRA can transform subregs itself. So don't call 625 1.1 mrg simplify_gen_subreg until LRA transformations are 626 1.1 mrg finished. Function simplify_gen_subreg can do 627 1.1 mrg non-trivial transformations (like truncation) which 628 1.1 mrg might make LRA work to fail. */ 629 1.1 mrg SUBREG_REG (x) = new_rtx; 630 1.1 mrg return x; 631 1.1 mrg } 632 1.1 mrg else 633 1.1 mrg return simplify_gen_subreg (GET_MODE (x), new_rtx, 634 1.1 mrg GET_MODE (new_rtx), SUBREG_BYTE (x)); 635 1.1 mrg } 636 1.1 mrg 637 1.1 mrg return x; 638 1.1 mrg 639 1.1 mrg case MEM: 640 1.1 mrg /* Our only special processing is to pass the mode of the MEM to our 641 1.1 mrg recursive call and copy the flags. While we are here, handle this 642 1.1 mrg case more efficiently. */ 643 1.1 mrg return 644 1.1 mrg replace_equiv_address_nv 645 1.1 mrg (x, 646 1.1 mrg lra_eliminate_regs_1 (insn, XEXP (x, 0), GET_MODE (x), 647 1.1 mrg subst_p, update_p, update_sp_offset, full_p)); 648 1.1 mrg 649 1.1 mrg case USE: 650 1.1 mrg /* Handle insn_list USE that a call to a pure function may generate. */ 651 1.1 mrg new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), VOIDmode, 652 1.1 mrg subst_p, update_p, update_sp_offset, full_p); 653 1.1 mrg if (new_rtx != XEXP (x, 0)) 654 1.1 mrg return gen_rtx_USE (GET_MODE (x), new_rtx); 655 1.1 mrg return x; 656 1.1 mrg 657 1.1 mrg case CLOBBER: 658 1.1 mrg case SET: 659 1.1 mrg gcc_unreachable (); 660 1.1 mrg 661 1.1 mrg default: 662 1.1 mrg break; 663 1.1 mrg } 664 1.1 mrg 665 1.1 mrg /* Process each of our operands recursively. If any have changed, make a 666 1.1 mrg copy of the rtx. */ 667 1.1 mrg fmt = GET_RTX_FORMAT (code); 668 1.1 mrg for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++) 669 1.1 mrg { 670 1.1 mrg if (*fmt == 'e') 671 1.1 mrg { 672 1.1 mrg new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, i), mem_mode, 673 1.1 mrg subst_p, update_p, 674 1.1 mrg update_sp_offset, full_p); 675 1.1 mrg if (new_rtx != XEXP (x, i) && ! copied) 676 1.1 mrg { 677 1.1 mrg x = shallow_copy_rtx (x); 678 1.1 mrg copied = 1; 679 1.1 mrg } 680 1.1 mrg XEXP (x, i) = new_rtx; 681 1.1 mrg } 682 1.1 mrg else if (*fmt == 'E') 683 1.1 mrg { 684 1.1 mrg int copied_vec = 0; 685 1.1 mrg for (j = 0; j < XVECLEN (x, i); j++) 686 1.1 mrg { 687 1.1 mrg new_rtx = lra_eliminate_regs_1 (insn, XVECEXP (x, i, j), mem_mode, 688 1.1 mrg subst_p, update_p, 689 1.1 mrg update_sp_offset, full_p); 690 1.1 mrg if (new_rtx != XVECEXP (x, i, j) && ! copied_vec) 691 1.1 mrg { 692 1.1 mrg rtvec new_v = gen_rtvec_v (XVECLEN (x, i), 693 1.1 mrg XVEC (x, i)->elem); 694 1.1 mrg if (! copied) 695 1.1 mrg { 696 1.1 mrg x = shallow_copy_rtx (x); 697 1.1 mrg copied = 1; 698 1.1 mrg } 699 1.1 mrg XVEC (x, i) = new_v; 700 1.1 mrg copied_vec = 1; 701 1.1 mrg } 702 1.1 mrg XVECEXP (x, i, j) = new_rtx; 703 1.1 mrg } 704 1.1 mrg } 705 1.1 mrg } 706 1.1 mrg 707 1.1 mrg return x; 708 1.1 mrg } 709 1.1 mrg 710 1.1 mrg /* This function is used externally in subsequent passes of GCC. It 711 1.1 mrg always does a full elimination of X. */ 712 1.1 mrg rtx 713 1.1 mrg lra_eliminate_regs (rtx x, machine_mode mem_mode, 714 1.1 mrg rtx insn ATTRIBUTE_UNUSED) 715 1.1 mrg { 716 1.1 mrg return lra_eliminate_regs_1 (NULL, x, mem_mode, true, false, 0, true); 717 1.1 mrg } 718 1.1 mrg 719 1.1 mrg /* Stack pointer offset before the current insn relative to one at the 720 1.1 mrg func start. RTL insns can change SP explicitly. We keep the 721 1.1 mrg changes from one insn to another through this variable. */ 722 1.1 mrg static poly_int64 curr_sp_change; 723 1.1 mrg 724 1.1 mrg /* Scan rtx X for references to elimination source or target registers 725 1.1 mrg in contexts that would prevent the elimination from happening. 726 1.1 mrg Update the table of eliminables to reflect the changed state. 727 1.1 mrg MEM_MODE is the mode of an enclosing MEM rtx, or VOIDmode if not 728 1.1 mrg within a MEM. */ 729 1.1 mrg static void 730 1.1 mrg mark_not_eliminable (rtx x, machine_mode mem_mode) 731 1.1 mrg { 732 1.1 mrg enum rtx_code code = GET_CODE (x); 733 1.1 mrg class lra_elim_table *ep; 734 1.1 mrg int i, j; 735 1.1 mrg const char *fmt; 736 1.1 mrg poly_int64 offset = 0; 737 1.1 mrg 738 1.1 mrg switch (code) 739 1.1 mrg { 740 1.1 mrg case PRE_INC: 741 1.1 mrg case POST_INC: 742 1.1 mrg case PRE_DEC: 743 1.1 mrg case POST_DEC: 744 1.1 mrg case POST_MODIFY: 745 1.1 mrg case PRE_MODIFY: 746 1.1 mrg if (XEXP (x, 0) == stack_pointer_rtx 747 1.1 mrg && ((code != PRE_MODIFY && code != POST_MODIFY) 748 1.1 mrg || (GET_CODE (XEXP (x, 1)) == PLUS 749 1.1 mrg && XEXP (x, 0) == XEXP (XEXP (x, 1), 0) 750 1.1 mrg && poly_int_rtx_p (XEXP (XEXP (x, 1), 1), &offset)))) 751 1.1 mrg { 752 1.1 mrg poly_int64 size = GET_MODE_SIZE (mem_mode); 753 1.1 mrg 754 1.1 mrg #ifdef PUSH_ROUNDING 755 1.1 mrg /* If more bytes than MEM_MODE are pushed, account for 756 1.1 mrg them. */ 757 1.1 mrg size = PUSH_ROUNDING (size); 758 1.1 mrg #endif 759 1.1 mrg if (code == PRE_DEC || code == POST_DEC) 760 1.1 mrg curr_sp_change -= size; 761 1.1 mrg else if (code == PRE_INC || code == POST_INC) 762 1.1 mrg curr_sp_change += size; 763 1.1 mrg else if (code == PRE_MODIFY || code == POST_MODIFY) 764 1.1 mrg curr_sp_change += offset; 765 1.1 mrg } 766 1.1 mrg else if (REG_P (XEXP (x, 0)) 767 1.1 mrg && REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER) 768 1.1 mrg { 769 1.1 mrg /* If we modify the source of an elimination rule, disable 770 1.1 mrg it. Do the same if it is the destination and not the 771 1.1 mrg hard frame register. */ 772 1.1 mrg for (ep = reg_eliminate; 773 1.1 mrg ep < ®_eliminate[NUM_ELIMINABLE_REGS]; 774 1.1 mrg ep++) 775 1.1 mrg if (ep->from_rtx == XEXP (x, 0) 776 1.1 mrg || (ep->to_rtx == XEXP (x, 0) 777 1.1 mrg && ep->to_rtx != hard_frame_pointer_rtx)) 778 1.1 mrg setup_can_eliminate (ep, false); 779 1.1 mrg } 780 1.1 mrg return; 781 1.1 mrg 782 1.1 mrg case USE: 783 1.1 mrg if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER) 784 1.1 mrg /* If using a hard register that is the source of an eliminate 785 1.1 mrg we still think can be performed, note it cannot be 786 1.1 mrg performed since we don't know how this hard register is 787 1.1 mrg used. */ 788 1.1 mrg for (ep = reg_eliminate; 789 1.1 mrg ep < ®_eliminate[NUM_ELIMINABLE_REGS]; 790 1.1 mrg ep++) 791 1.1 mrg if (ep->from_rtx == XEXP (x, 0) 792 1.1 mrg && ep->to_rtx != hard_frame_pointer_rtx) 793 1.1 mrg setup_can_eliminate (ep, false); 794 1.1 mrg return; 795 1.1 mrg 796 1.1 mrg case CLOBBER: 797 1.1 mrg if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER) 798 1.1 mrg /* If clobbering a hard register that is the replacement 799 1.1 mrg register for an elimination we still think can be 800 1.1 mrg performed, note that it cannot be performed. Otherwise, we 801 1.1 mrg need not be concerned about it. */ 802 1.1 mrg for (ep = reg_eliminate; 803 1.1 mrg ep < ®_eliminate[NUM_ELIMINABLE_REGS]; 804 1.1 mrg ep++) 805 1.1 mrg if (ep->to_rtx == XEXP (x, 0) 806 1.1 mrg && ep->to_rtx != hard_frame_pointer_rtx) 807 1.1 mrg setup_can_eliminate (ep, false); 808 1.1 mrg return; 809 1.1 mrg 810 1.1 mrg case SET: 811 1.1 mrg if (SET_DEST (x) == stack_pointer_rtx 812 1.1 mrg && GET_CODE (SET_SRC (x)) == PLUS 813 1.1 mrg && XEXP (SET_SRC (x), 0) == SET_DEST (x) 814 1.1 mrg && poly_int_rtx_p (XEXP (SET_SRC (x), 1), &offset)) 815 1.1 mrg { 816 1.1 mrg curr_sp_change += offset; 817 1.1 mrg return; 818 1.1 mrg } 819 1.1 mrg if (! REG_P (SET_DEST (x)) 820 1.1 mrg || REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER) 821 1.1 mrg mark_not_eliminable (SET_DEST (x), mem_mode); 822 1.1 mrg else 823 1.1 mrg { 824 1.1 mrg /* See if this is setting the replacement hard register for 825 1.1 mrg an elimination. 826 1.1 mrg 827 1.1 mrg If DEST is the hard frame pointer, we do nothing because 828 1.1 mrg we assume that all assignments to the frame pointer are 829 1.1 mrg for non-local gotos and are being done at a time when 830 1.1 mrg they are valid and do not disturb anything else. Some 831 1.1 mrg machines want to eliminate a fake argument pointer (or 832 1.1 mrg even a fake frame pointer) with either the real frame 833 1.1 mrg pointer or the stack pointer. Assignments to the hard 834 1.1 mrg frame pointer must not prevent this elimination. */ 835 1.1 mrg for (ep = reg_eliminate; 836 1.1 mrg ep < ®_eliminate[NUM_ELIMINABLE_REGS]; 837 1.1 mrg ep++) 838 1.1 mrg if (ep->to_rtx == SET_DEST (x) 839 1.1 mrg && SET_DEST (x) != hard_frame_pointer_rtx) 840 1.1 mrg setup_can_eliminate (ep, false); 841 1.1 mrg } 842 1.1 mrg 843 1.1 mrg mark_not_eliminable (SET_SRC (x), mem_mode); 844 1.1 mrg return; 845 1.1 mrg 846 1.1 mrg case MEM: 847 1.1 mrg /* Our only special processing is to pass the mode of the MEM to 848 1.1 mrg our recursive call. */ 849 1.1 mrg mark_not_eliminable (XEXP (x, 0), GET_MODE (x)); 850 1.1 mrg return; 851 1.1 mrg 852 1.1 mrg default: 853 1.1 mrg break; 854 1.1 mrg } 855 1.1 mrg 856 1.1 mrg fmt = GET_RTX_FORMAT (code); 857 1.1 mrg for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++) 858 1.1 mrg { 859 1.1 mrg if (*fmt == 'e') 860 1.1 mrg mark_not_eliminable (XEXP (x, i), mem_mode); 861 1.1 mrg else if (*fmt == 'E') 862 1.1 mrg for (j = 0; j < XVECLEN (x, i); j++) 863 1.1 mrg mark_not_eliminable (XVECEXP (x, i, j), mem_mode); 864 1.1 mrg } 865 1.1 mrg } 866 1.1 mrg 867 1.1 mrg 868 1.1 mrg 870 1.1 mrg /* Scan INSN and eliminate all eliminable hard registers in it. 871 1.1 mrg 872 1.1 mrg If REPLACE_P is true, do the replacement destructively. Also 873 1.1 mrg delete the insn as dead it if it is setting an eliminable register. 874 1.1 mrg 875 1.1 mrg If REPLACE_P is false, just update the offsets while keeping the 876 1.1 mrg base register the same. If FIRST_P, use the sp offset for 877 1.1 mrg elimination to sp. Otherwise, use UPDATE_SP_OFFSET for this. If 878 1.1 mrg UPDATE_SP_OFFSET is non-zero, don't use difference of the offset 879 1.1 mrg and the previous offset. Attach the note about used elimination 880 1.1 mrg for insns setting frame pointer to update elimination easy (without 881 1.1 mrg parsing already generated elimination insns to find offset 882 1.1 mrg previously used) in future. */ 883 1.1 mrg 884 1.1 mrg void 885 1.1 mrg eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p, 886 1.1 mrg poly_int64 update_sp_offset) 887 1.1 mrg { 888 1.1 mrg int icode = recog_memoized (insn); 889 1.1 mrg rtx set, old_set = single_set (insn); 890 1.1 mrg bool validate_p; 891 1.1 mrg int i; 892 1.1 mrg rtx substed_operand[MAX_RECOG_OPERANDS]; 893 1.1 mrg rtx orig_operand[MAX_RECOG_OPERANDS]; 894 1.1 mrg class lra_elim_table *ep; 895 1.1 mrg rtx plus_src, plus_cst_src; 896 1.1 mrg lra_insn_recog_data_t id; 897 1.1 mrg struct lra_static_insn_data *static_id; 898 1.1 mrg 899 1.1 mrg if (icode < 0 && asm_noperands (PATTERN (insn)) < 0 && ! DEBUG_INSN_P (insn)) 900 1.1 mrg { 901 1.1 mrg lra_assert (GET_CODE (PATTERN (insn)) == USE 902 1.1 mrg || GET_CODE (PATTERN (insn)) == CLOBBER 903 1.1 mrg || GET_CODE (PATTERN (insn)) == ASM_INPUT); 904 1.1 mrg return; 905 1.1 mrg } 906 1.1 mrg 907 1.1 mrg /* We allow one special case which happens to work on all machines we 908 1.1 mrg currently support: a single set with the source or a REG_EQUAL 909 1.1 mrg note being a PLUS of an eliminable register and a constant. */ 910 1.1 mrg plus_src = plus_cst_src = 0; 911 1.1 mrg poly_int64 offset = 0; 912 1.1 mrg if (old_set && REG_P (SET_DEST (old_set))) 913 1.1 mrg { 914 1.1 mrg if (GET_CODE (SET_SRC (old_set)) == PLUS) 915 1.1 mrg plus_src = SET_SRC (old_set); 916 1.1 mrg /* First see if the source is of the form (plus (...) CST). */ 917 1.1 mrg if (plus_src && poly_int_rtx_p (XEXP (plus_src, 1), &offset)) 918 1.1 mrg plus_cst_src = plus_src; 919 1.1 mrg /* Check that the first operand of the PLUS is a hard reg or 920 1.1 mrg the lowpart subreg of one. */ 921 1.1 mrg if (plus_cst_src) 922 1.1 mrg { 923 1.1 mrg rtx reg = XEXP (plus_cst_src, 0); 924 1.1 mrg 925 1.1 mrg if (GET_CODE (reg) == SUBREG && subreg_lowpart_p (reg)) 926 1.1 mrg reg = SUBREG_REG (reg); 927 1.1 mrg 928 1.1 mrg if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER) 929 1.1 mrg plus_cst_src = 0; 930 1.1 mrg } 931 1.1 mrg } 932 1.1 mrg if (plus_cst_src) 933 1.1 mrg { 934 1.1 mrg rtx reg = XEXP (plus_cst_src, 0); 935 1.1 mrg 936 1.1 mrg if (GET_CODE (reg) == SUBREG) 937 1.1 mrg reg = SUBREG_REG (reg); 938 1.1 mrg 939 1.1 mrg if (REG_P (reg) && (ep = get_elimination (reg)) != NULL) 940 1.1 mrg { 941 1.1 mrg rtx to_rtx = replace_p ? ep->to_rtx : ep->from_rtx; 942 1.1 mrg 943 1.1 mrg if (! replace_p) 944 1.1 mrg { 945 1.1 mrg if (known_eq (update_sp_offset, 0)) 946 1.1 mrg offset += (ep->offset - ep->previous_offset); 947 1.1 mrg if (ep->to_rtx == stack_pointer_rtx) 948 1.1 mrg { 949 1.1 mrg if (first_p) 950 1.1 mrg offset -= lra_get_insn_recog_data (insn)->sp_offset; 951 1.1 mrg else 952 1.1 mrg offset += update_sp_offset; 953 1.1 mrg } 954 1.1 mrg offset = trunc_int_for_mode (offset, GET_MODE (plus_cst_src)); 955 1.1 mrg } 956 1.1 mrg 957 1.1 mrg if (GET_CODE (XEXP (plus_cst_src, 0)) == SUBREG) 958 1.1 mrg to_rtx = gen_lowpart (GET_MODE (XEXP (plus_cst_src, 0)), to_rtx); 959 1.1 mrg /* If we have a nonzero offset, and the source is already a 960 1.1 mrg simple REG, the following transformation would increase 961 1.1 mrg the cost of the insn by replacing a simple REG with (plus 962 1.1 mrg (reg sp) CST). So try only when we already had a PLUS 963 1.1 mrg before. */ 964 1.1 mrg if (known_eq (offset, 0) || plus_src) 965 1.1 mrg { 966 1.1 mrg rtx new_src = plus_constant (GET_MODE (to_rtx), to_rtx, offset); 967 1.1 mrg 968 1.1 mrg old_set = single_set (insn); 969 1.1 mrg 970 1.1 mrg /* First see if this insn remains valid when we make the 971 1.1 mrg change. If not, try to replace the whole pattern 972 1.1 mrg with a simple set (this may help if the original insn 973 1.1 mrg was a PARALLEL that was only recognized as single_set 974 1.1 mrg due to REG_UNUSED notes). If this isn't valid 975 1.1 mrg either, keep the INSN_CODE the same and let the 976 1.1 mrg constraint pass fix it up. */ 977 1.1 mrg if (! validate_change (insn, &SET_SRC (old_set), new_src, 0)) 978 1.1 mrg { 979 1.1 mrg rtx new_pat = gen_rtx_SET (SET_DEST (old_set), new_src); 980 1.1 mrg 981 1.1 mrg if (! validate_change (insn, &PATTERN (insn), new_pat, 0)) 982 1.1 mrg SET_SRC (old_set) = new_src; 983 1.1 mrg } 984 1.1 mrg lra_update_insn_recog_data (insn); 985 1.1 mrg /* This can't have an effect on elimination offsets, so skip 986 1.1 mrg right to the end. */ 987 1.1 mrg return; 988 1.1 mrg } 989 1.1 mrg } 990 1.1 mrg } 991 1.1 mrg 992 1.1 mrg /* Eliminate all eliminable registers occurring in operands that 993 1.1 mrg can be handled by the constraint pass. */ 994 1.1 mrg id = lra_get_insn_recog_data (insn); 995 1.1 mrg static_id = id->insn_static_data; 996 1.1 mrg validate_p = false; 997 1.1 mrg for (i = 0; i < static_id->n_operands; i++) 998 1.1 mrg { 999 1.1 mrg orig_operand[i] = *id->operand_loc[i]; 1000 1.1 mrg substed_operand[i] = *id->operand_loc[i]; 1001 1.1 mrg 1002 1.1 mrg /* For an asm statement, every operand is eliminable. */ 1003 1.1 mrg if (icode < 0 || insn_data[icode].operand[i].eliminable) 1004 1.1 mrg { 1005 1.1 mrg /* Check for setting a hard register that we know about. */ 1006 1.1 mrg if (static_id->operand[i].type != OP_IN 1007 1.1 mrg && REG_P (orig_operand[i])) 1008 1.1 mrg { 1009 1.1 mrg /* If we are assigning to a hard register that can be 1010 1.1 mrg eliminated, it must be as part of a PARALLEL, since 1011 1.1 mrg the code above handles single SETs. This reg cannot 1012 1.1 mrg be longer eliminated -- it is forced by 1013 1.1 mrg mark_not_eliminable. */ 1014 1.1 mrg for (ep = reg_eliminate; 1015 1.1 mrg ep < ®_eliminate[NUM_ELIMINABLE_REGS]; 1016 1.1 mrg ep++) 1017 1.1 mrg lra_assert (ep->from_rtx != orig_operand[i] 1018 1.1 mrg || ! ep->can_eliminate); 1019 1.1 mrg } 1020 1.1 mrg 1021 1.1 mrg /* Companion to the above plus substitution, we can allow 1022 1.1 mrg invariants as the source of a plain move. */ 1023 1.1 mrg substed_operand[i] 1024 1.1 mrg = lra_eliminate_regs_1 (insn, *id->operand_loc[i], VOIDmode, 1025 1.1 mrg replace_p, ! replace_p && ! first_p, 1026 1.1 mrg update_sp_offset, first_p); 1027 1.1 mrg if (substed_operand[i] != orig_operand[i]) 1028 1.1 mrg validate_p = true; 1029 1.1 mrg } 1030 1.1 mrg } 1031 1.1 mrg 1032 1.1 mrg if (! validate_p) 1033 1.1 mrg return; 1034 1.1 mrg 1035 1.1 mrg /* Substitute the operands; the new values are in the substed_operand 1036 1.1 mrg array. */ 1037 1.1 mrg for (i = 0; i < static_id->n_operands; i++) 1038 1.1 mrg *id->operand_loc[i] = substed_operand[i]; 1039 1.1 mrg for (i = 0; i < static_id->n_dups; i++) 1040 1.1 mrg *id->dup_loc[i] = substed_operand[(int) static_id->dup_num[i]]; 1041 1.1 mrg 1042 1.1 mrg /* Transform plus (plus (hard reg, const), pseudo) to plus (plus (pseudo, 1043 1.1 mrg const), hard reg) in order to keep insn containing eliminated register 1044 1.1 mrg after all reloads calculating its offset. This permits to keep register 1045 1.1 mrg pressure under control and helps to avoid LRA cycling in patalogical 1046 1.1 mrg cases. */ 1047 1.1 mrg if (! replace_p && (set = single_set (insn)) != NULL 1048 1.1 mrg && GET_CODE (SET_SRC (set)) == PLUS 1049 1.1 mrg && GET_CODE (XEXP (SET_SRC (set), 0)) == PLUS) 1050 1.1 mrg { 1051 1.1 mrg rtx reg1, reg2, op1, op2; 1052 1.1 mrg 1053 1.1 mrg reg1 = op1 = XEXP (XEXP (SET_SRC (set), 0), 0); 1054 1.1 mrg reg2 = op2 = XEXP (SET_SRC (set), 1); 1055 1.1 mrg if (GET_CODE (reg1) == SUBREG) 1056 1.1 mrg reg1 = SUBREG_REG (reg1); 1057 1.1 mrg if (GET_CODE (reg2) == SUBREG) 1058 1.1 mrg reg2 = SUBREG_REG (reg2); 1059 1.1 mrg if (REG_P (reg1) && REG_P (reg2) 1060 1.1 mrg && REGNO (reg1) < FIRST_PSEUDO_REGISTER 1061 1.1 mrg && REGNO (reg2) >= FIRST_PSEUDO_REGISTER 1062 1.1 mrg && GET_MODE (reg1) == Pmode 1063 1.1 mrg && !have_addptr3_insn (lra_pmode_pseudo, reg1, 1064 1.1 mrg XEXP (XEXP (SET_SRC (set), 0), 1))) 1065 1.1 mrg { 1066 1.1 mrg XEXP (XEXP (SET_SRC (set), 0), 0) = op2; 1067 1.1 mrg XEXP (SET_SRC (set), 1) = op1; 1068 1.1 mrg } 1069 1.1 mrg } 1070 1.1 mrg 1071 1.1 mrg /* If we had a move insn but now we don't, re-recognize it. 1072 1.1 mrg This will cause spurious re-recognition if the old move had a 1073 1.1 mrg PARALLEL since the new one still will, but we can't call 1074 1.1 mrg single_set without having put new body into the insn and the 1075 1.1 mrg re-recognition won't hurt in this rare case. */ 1076 1.1 mrg lra_update_insn_recog_data (insn); 1077 1.1 mrg } 1078 1.1 mrg 1079 1.1 mrg /* Spill pseudos which are assigned to hard registers in SET. Add 1080 1.1 mrg affected insns for processing in the subsequent constraint 1081 1.1 mrg pass. */ 1082 1.1 mrg static void 1083 1.1 mrg spill_pseudos (HARD_REG_SET set) 1084 1.1 mrg { 1085 1.1 mrg int i; 1086 1.1 mrg bitmap_head to_process; 1087 1.1 mrg rtx_insn *insn; 1088 1.1 mrg 1089 1.1 mrg if (hard_reg_set_empty_p (set)) 1090 1.1 mrg return; 1091 1.1 mrg if (lra_dump_file != NULL) 1092 1.1 mrg { 1093 1.1 mrg fprintf (lra_dump_file, " Spilling non-eliminable hard regs:"); 1094 1.1 mrg for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 1095 1.1 mrg if (TEST_HARD_REG_BIT (set, i)) 1096 1.1 mrg fprintf (lra_dump_file, " %d", i); 1097 1.1 mrg fprintf (lra_dump_file, "\n"); 1098 1.1 mrg } 1099 1.1 mrg bitmap_initialize (&to_process, ®_obstack); 1100 1.1 mrg for (i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++) 1101 1.1 mrg if (lra_reg_info[i].nrefs != 0 && reg_renumber[i] >= 0 1102 1.1 mrg && overlaps_hard_reg_set_p (set, 1103 1.1 mrg PSEUDO_REGNO_MODE (i), reg_renumber[i])) 1104 1.1 mrg { 1105 1.1 mrg if (lra_dump_file != NULL) 1106 1.1 mrg fprintf (lra_dump_file, " Spilling r%d(%d)\n", 1107 1.1 mrg i, reg_renumber[i]); 1108 1.1 mrg reg_renumber[i] = -1; 1109 1.1 mrg bitmap_ior_into (&to_process, &lra_reg_info[i].insn_bitmap); 1110 1.1 mrg } 1111 1.1 mrg lra_no_alloc_regs |= set; 1112 1.1 mrg for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn)) 1113 1.1 mrg if (bitmap_bit_p (&to_process, INSN_UID (insn))) 1114 1.1 mrg { 1115 1.1 mrg lra_push_insn (insn); 1116 1.1 mrg lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT); 1117 1.1 mrg } 1118 1.1 mrg bitmap_clear (&to_process); 1119 1.1 mrg } 1120 1.1 mrg 1121 1.1 mrg /* Update all offsets and possibility for elimination on eliminable 1122 1.1 mrg registers. Spill pseudos assigned to registers which are 1123 1.1 mrg uneliminable, update LRA_NO_ALLOC_REGS and ELIMINABLE_REG_SET. Add 1124 1.1 mrg insns to INSNS_WITH_CHANGED_OFFSETS containing eliminable hard 1125 1.1 mrg registers whose offsets should be changed. Return true if any 1126 1.1 mrg elimination offset changed. */ 1127 1.1 mrg static bool 1128 1.1 mrg update_reg_eliminate (bitmap insns_with_changed_offsets) 1129 1.1 mrg { 1130 1.1 mrg bool prev, result; 1131 1.1 mrg class lra_elim_table *ep, *ep1; 1132 1.1 mrg HARD_REG_SET temp_hard_reg_set; 1133 1.1 mrg 1134 1.1 mrg targetm.compute_frame_layout (); 1135 1.1 mrg 1136 1.1 mrg /* Clear self elimination offsets. */ 1137 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 1138 1.1 mrg self_elim_offsets[ep->from] = 0; 1139 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 1140 1.1 mrg { 1141 1.1 mrg /* If it is a currently used elimination: update the previous 1142 1.1 mrg offset. */ 1143 1.1 mrg if (elimination_map[ep->from] == ep) 1144 1.1 mrg ep->previous_offset = ep->offset; 1145 1.1 mrg 1146 1.1 mrg prev = ep->prev_can_eliminate; 1147 1.1 mrg setup_can_eliminate (ep, targetm.can_eliminate (ep->from, ep->to)); 1148 1.1 mrg if (ep->can_eliminate && ! prev) 1149 1.1 mrg { 1150 1.1 mrg /* It is possible that not eliminable register becomes 1151 1.1 mrg eliminable because we took other reasons into account to 1152 1.1 mrg set up eliminable regs in the initial set up. Just 1153 1.1 mrg ignore new eliminable registers. */ 1154 1.1 mrg setup_can_eliminate (ep, false); 1155 1.1 mrg continue; 1156 1.1 mrg } 1157 1.1 mrg if (ep->can_eliminate != prev && elimination_map[ep->from] == ep) 1158 1.1 mrg { 1159 1.1 mrg /* We cannot use this elimination anymore -- find another 1160 1.1 mrg one. */ 1161 1.1 mrg if (lra_dump_file != NULL) 1162 1.1 mrg fprintf (lra_dump_file, 1163 1.1 mrg " Elimination %d to %d is not possible anymore\n", 1164 1.1 mrg ep->from, ep->to); 1165 1.1 mrg /* If after processing RTL we decides that SP can be used as 1166 1.1 mrg a result of elimination, it cannot be changed. */ 1167 1.1 mrg gcc_assert ((ep->to_rtx != stack_pointer_rtx) 1168 1.1 mrg || (ep->from < FIRST_PSEUDO_REGISTER 1169 1.1 mrg && fixed_regs [ep->from])); 1170 1.1 mrg /* Mark that is not eliminable anymore. */ 1171 1.1 mrg elimination_map[ep->from] = NULL; 1172 1.1 mrg for (ep1 = ep + 1; ep1 < ®_eliminate[NUM_ELIMINABLE_REGS]; ep1++) 1173 1.1 mrg if (ep1->can_eliminate && ep1->from == ep->from) 1174 1.1 mrg break; 1175 1.1 mrg if (ep1 < ®_eliminate[NUM_ELIMINABLE_REGS]) 1176 1.1 mrg { 1177 1.1 mrg if (lra_dump_file != NULL) 1178 1.1 mrg fprintf (lra_dump_file, " Using elimination %d to %d now\n", 1179 1.1 mrg ep1->from, ep1->to); 1180 1.1 mrg lra_assert (known_eq (ep1->previous_offset, 0)); 1181 1.1 mrg ep1->previous_offset = ep->offset; 1182 1.1 mrg } 1183 1.1 mrg else 1184 1.1 mrg { 1185 1.1 mrg /* There is no elimination anymore just use the hard 1186 1.1 mrg register `from' itself. Setup self elimination 1187 1.1 mrg offset to restore the original offset values. */ 1188 1.1 mrg if (lra_dump_file != NULL) 1189 1.1 mrg fprintf (lra_dump_file, " %d is not eliminable at all\n", 1190 1.1 mrg ep->from); 1191 1.1 mrg self_elim_offsets[ep->from] = -ep->offset; 1192 1.1 mrg if (maybe_ne (ep->offset, 0)) 1193 1.1 mrg bitmap_ior_into (insns_with_changed_offsets, 1194 1.1 mrg &lra_reg_info[ep->from].insn_bitmap); 1195 1.1 mrg } 1196 1.1 mrg } 1197 1.1 mrg 1198 1.1 mrg INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, ep->offset); 1199 1.1 mrg } 1200 1.1 mrg setup_elimination_map (); 1201 1.1 mrg result = false; 1202 1.1 mrg CLEAR_HARD_REG_SET (temp_hard_reg_set); 1203 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 1204 1.1 mrg if (elimination_map[ep->from] == NULL) 1205 1.1 mrg add_to_hard_reg_set (&temp_hard_reg_set, Pmode, ep->from); 1206 1.1 mrg else if (elimination_map[ep->from] == ep) 1207 1.1 mrg { 1208 1.1 mrg /* Prevent the hard register into which we eliminate from 1209 1.1 mrg the usage for pseudos. */ 1210 1.1 mrg if (ep->from != ep->to) 1211 1.1 mrg add_to_hard_reg_set (&temp_hard_reg_set, Pmode, ep->to); 1212 1.1 mrg if (maybe_ne (ep->previous_offset, ep->offset)) 1213 1.1 mrg { 1214 1.1 mrg bitmap_ior_into (insns_with_changed_offsets, 1215 1.1 mrg &lra_reg_info[ep->from].insn_bitmap); 1216 1.1 mrg 1217 1.1 mrg /* Update offset when the eliminate offset have been 1218 1.1 mrg changed. */ 1219 1.1 mrg lra_update_reg_val_offset (lra_reg_info[ep->from].val, 1220 1.1 mrg ep->offset - ep->previous_offset); 1221 1.1 mrg result = true; 1222 1.1 mrg } 1223 1.1 mrg } 1224 1.1 mrg lra_no_alloc_regs |= temp_hard_reg_set; 1225 1.1 mrg eliminable_regset &= ~temp_hard_reg_set; 1226 1.1 mrg spill_pseudos (temp_hard_reg_set); 1227 1.1 mrg return result; 1228 1.1 mrg } 1229 1.1 mrg 1230 1.1 mrg /* Initialize the table of hard registers to eliminate. 1231 1.1 mrg Pre-condition: global flag frame_pointer_needed has been set before 1232 1.1 mrg calling this function. */ 1233 1.1 mrg static void 1234 1.1 mrg init_elim_table (void) 1235 1.1 mrg { 1236 1.1 mrg class lra_elim_table *ep; 1237 1.1 mrg bool value_p; 1238 1.1 mrg const struct elim_table_1 *ep1; 1239 1.1 mrg 1240 1.1 mrg if (!reg_eliminate) 1241 1.1 mrg reg_eliminate = XCNEWVEC (class lra_elim_table, NUM_ELIMINABLE_REGS); 1242 1.1 mrg 1243 1.1 mrg memset (self_elim_offsets, 0, sizeof (self_elim_offsets)); 1244 1.1 mrg /* Initiate member values which will be never changed. */ 1245 1.1 mrg self_elim_table.can_eliminate = self_elim_table.prev_can_eliminate = true; 1246 1.1 mrg self_elim_table.previous_offset = 0; 1247 1.1 mrg 1248 1.1 mrg for (ep = reg_eliminate, ep1 = reg_eliminate_1; 1249 1.1 mrg ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++, ep1++) 1250 1.1 mrg { 1251 1.1 mrg ep->offset = ep->previous_offset = 0; 1252 1.1 mrg ep->from = ep1->from; 1253 1.1 mrg ep->to = ep1->to; 1254 1.1 mrg value_p = (targetm.can_eliminate (ep->from, ep->to) 1255 1.1 mrg && ! (ep->to == STACK_POINTER_REGNUM 1256 1.1 mrg && frame_pointer_needed 1257 1.1 mrg && (! SUPPORTS_STACK_ALIGNMENT 1258 1.1 mrg || ! stack_realign_fp))); 1259 1.1 mrg setup_can_eliminate (ep, value_p); 1260 1.1 mrg } 1261 1.1 mrg 1262 1.1 mrg /* Build the FROM and TO REG rtx's. Note that code in gen_rtx_REG 1263 1.1 mrg will cause, e.g., gen_rtx_REG (Pmode, STACK_POINTER_REGNUM) to 1264 1.1 mrg equal stack_pointer_rtx. We depend on this. Threfore we switch 1265 1.1 mrg off that we are in LRA temporarily. */ 1266 1.1 mrg lra_in_progress = 0; 1267 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 1268 1.1 mrg { 1269 1.1 mrg ep->from_rtx = gen_rtx_REG (Pmode, ep->from); 1270 1.1 mrg ep->to_rtx = gen_rtx_REG (Pmode, ep->to); 1271 1.1 mrg eliminable_reg_rtx[ep->from] = ep->from_rtx; 1272 1.1 mrg } 1273 1.1 mrg lra_in_progress = 1; 1274 1.1 mrg } 1275 1.1 mrg 1276 1.1 mrg /* Function for initialization of elimination once per function. It 1277 1.1 mrg sets up sp offset for each insn. */ 1278 1.1 mrg static void 1279 1.1 mrg init_elimination (void) 1280 1.1 mrg { 1281 1.1 mrg bool stop_to_sp_elimination_p; 1282 1.1 mrg basic_block bb; 1283 1.1 mrg rtx_insn *insn; 1284 1.1 mrg class lra_elim_table *ep; 1285 1.1 mrg 1286 1.1 mrg init_elim_table (); 1287 1.1 mrg FOR_EACH_BB_FN (bb, cfun) 1288 1.1 mrg { 1289 1.1 mrg curr_sp_change = 0; 1290 1.1 mrg stop_to_sp_elimination_p = false; 1291 1.1 mrg FOR_BB_INSNS (bb, insn) 1292 1.1 mrg if (INSN_P (insn)) 1293 1.1 mrg { 1294 1.1 mrg lra_get_insn_recog_data (insn)->sp_offset = curr_sp_change; 1295 1.1 mrg if (NONDEBUG_INSN_P (insn)) 1296 1.1 mrg { 1297 1.1 mrg mark_not_eliminable (PATTERN (insn), VOIDmode); 1298 1.1 mrg if (maybe_ne (curr_sp_change, 0) 1299 1.1 mrg && find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX)) 1300 1.1 mrg stop_to_sp_elimination_p = true; 1301 1.1 mrg } 1302 1.1 mrg } 1303 1.1 mrg if (! frame_pointer_needed 1304 1.1 mrg && (maybe_ne (curr_sp_change, 0) || stop_to_sp_elimination_p) 1305 1.1 mrg && bb->succs && bb->succs->length () != 0) 1306 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 1307 1.1 mrg if (ep->to == STACK_POINTER_REGNUM) 1308 1.1 mrg setup_can_eliminate (ep, false); 1309 1.1 mrg } 1310 1.1 mrg setup_elimination_map (); 1311 1.1 mrg } 1312 1.1 mrg 1313 1.1 mrg /* Eliminate hard reg given by its location LOC. */ 1314 1.1 mrg void 1315 1.1 mrg lra_eliminate_reg_if_possible (rtx *loc) 1316 1.1 mrg { 1317 1.1 mrg int regno; 1318 1.1 mrg class lra_elim_table *ep; 1319 1.1 mrg 1320 1.1 mrg lra_assert (REG_P (*loc)); 1321 1.1 mrg if ((regno = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER 1322 1.1 mrg || ! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno)) 1323 1.1 mrg return; 1324 1.1 mrg if ((ep = get_elimination (*loc)) != NULL) 1325 1.1 mrg *loc = ep->to_rtx; 1326 1.1 mrg } 1327 1.1 mrg 1328 1.1 mrg /* Do (final if FINAL_P or first if FIRST_P) elimination in INSN. Add 1329 1.1 mrg the insn for subsequent processing in the constraint pass, update 1330 1.1 mrg the insn info. */ 1331 1.1 mrg static void 1332 1.1 mrg process_insn_for_elimination (rtx_insn *insn, bool final_p, bool first_p) 1333 1.1 mrg { 1334 1.1 mrg eliminate_regs_in_insn (insn, final_p, first_p, 0); 1335 1.1 mrg if (! final_p) 1336 1.1 mrg { 1337 1.1 mrg /* Check that insn changed its code. This is a case when a move 1338 1.1 mrg insn becomes an add insn and we do not want to process the 1339 1.1 mrg insn as a move anymore. */ 1340 1.1 mrg int icode = recog (PATTERN (insn), insn, 0); 1341 1.1 mrg 1342 1.1 mrg if (icode >= 0 && icode != INSN_CODE (insn)) 1343 1.1 mrg { 1344 1.1 mrg if (INSN_CODE (insn) >= 0) 1345 1.1 mrg /* Insn code is changed. It may change its operand type 1346 1.1 mrg from IN to INOUT. Inform the subsequent assignment 1347 1.1 mrg subpass about this situation. */ 1348 1.1 mrg check_and_force_assignment_correctness_p = true; 1349 1.1 mrg INSN_CODE (insn) = icode; 1350 1.1 mrg lra_update_insn_recog_data (insn); 1351 1.1 mrg } 1352 1.1 mrg lra_update_insn_regno_info (insn); 1353 1.1 mrg lra_push_insn (insn); 1354 1.1 mrg lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT); 1355 1.1 mrg } 1356 1.1 mrg } 1357 1.1 mrg 1358 1.1 mrg /* Entry function to do final elimination if FINAL_P or to update 1359 1.1 mrg elimination register offsets (FIRST_P if we are doing it the first 1360 1.1 mrg time). */ 1361 1.1 mrg void 1362 1.1 mrg lra_eliminate (bool final_p, bool first_p) 1363 1.1 mrg { 1364 1.1 mrg unsigned int uid; 1365 1.1 mrg bitmap_head insns_with_changed_offsets; 1366 1.1 mrg bitmap_iterator bi; 1367 1.1 mrg class lra_elim_table *ep; 1368 1.1 mrg 1369 1.1 mrg gcc_assert (! final_p || ! first_p); 1370 1.1 mrg 1371 1.1 mrg timevar_push (TV_LRA_ELIMINATE); 1372 1.1 mrg 1373 1.1 mrg if (first_p) 1374 1.1 mrg init_elimination (); 1375 1.1 mrg 1376 1.1 mrg bitmap_initialize (&insns_with_changed_offsets, ®_obstack); 1377 1.1 mrg if (final_p) 1378 1.1 mrg { 1379 1.1 mrg if (flag_checking) 1380 1.1 mrg { 1381 1.1 mrg update_reg_eliminate (&insns_with_changed_offsets); 1382 1.1 mrg gcc_assert (bitmap_empty_p (&insns_with_changed_offsets)); 1383 1.1 mrg } 1384 1.1 mrg /* We change eliminable hard registers in insns so we should do 1385 1.1 mrg this for all insns containing any eliminable hard 1386 1.1 mrg register. */ 1387 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 1388 1.1 mrg if (elimination_map[ep->from] != NULL) 1389 1.1 mrg bitmap_ior_into (&insns_with_changed_offsets, 1390 1.1 mrg &lra_reg_info[ep->from].insn_bitmap); 1391 1.1 mrg } 1392 1.1 mrg else if (! update_reg_eliminate (&insns_with_changed_offsets)) 1393 1.1 mrg goto lra_eliminate_done; 1394 1.1 mrg if (lra_dump_file != NULL) 1395 1.1 mrg { 1396 1.1 mrg fprintf (lra_dump_file, "New elimination table:\n"); 1397 1.1 mrg print_elim_table (lra_dump_file); 1398 1.1 mrg } 1399 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (&insns_with_changed_offsets, 0, uid, bi) 1400 1.1 mrg /* A dead insn can be deleted in process_insn_for_elimination. */ 1401 1.1 mrg if (lra_insn_recog_data[uid] != NULL) 1402 1.1 mrg process_insn_for_elimination (lra_insn_recog_data[uid]->insn, 1403 1.1 mrg final_p, first_p); 1404 1.1 mrg bitmap_clear (&insns_with_changed_offsets); 1405 1.1 mrg 1406 1.1 mrg lra_eliminate_done: 1407 timevar_pop (TV_LRA_ELIMINATE); 1408 } 1409