1139804Simp/* LRA (local register allocator) driver and LRA utilities. 2185435Sbz Copyright (C) 2010-2015 Free Software Foundation, Inc. 3185435Sbz Contributed by Vladimir Makarov <vmakarov@redhat.com>. 4191673Sjamie 5185435SbzThis file is part of GCC. 6190466Sjamie 7185404SbzGCC is free software; you can redistribute it and/or modify it under 8185404Sbzthe terms of the GNU General Public License as published by the Free 9185404SbzSoftware Foundation; either version 3, or (at your option) any later 10185404Sbzversion. 11185404Sbz 12185404SbzGCC is distributed in the hope that it will be useful, but WITHOUT ANY 13185404SbzWARRANTY; without even the implied warranty of MERCHANTABILITY or 14185404SbzFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15185404Sbzfor more details. 16185404Sbz 17185404SbzYou should have received a copy of the GNU General Public License 18185404Sbzalong with GCC; see the file COPYING3. If not see 19185404Sbz<http://www.gnu.org/licenses/>. */ 20185404Sbz 21185404Sbz 22185404Sbz/* The Local Register Allocator (LRA) is a replacement of former 23185404Sbz reload pass. It is focused to simplify code solving the reload 24185404Sbz pass tasks, to make the code maintenance easier, and to implement new 25185404Sbz perspective optimizations. 26185404Sbz 2746197Sphk The major LRA design solutions are: 2846155Sphk o division small manageable, separated sub-tasks 29116182Sobrien o reflection of all transformations and decisions in RTL as more 30116182Sobrien as possible 31116182Sobrien o insn constraints as a primary source of the info (minimizing 32193066Sjamie number of target-depended macros/hooks) 33185435Sbz 34185435Sbz In brief LRA works by iterative insn process with the final goal is 35185435Sbz to satisfy all insn and address constraints: 36131177Spjd o New reload insns (in brief reloads) and reload pseudos might be 3746155Sphk generated; 3846155Sphk o Some pseudos might be spilled to assign hard registers to 3946155Sphk new reload pseudos; 4046155Sphk o Recalculating spilled pseudo values (rematerialization); 4146155Sphk o Changing spilled pseudos to stack memory or their equivalences; 4246155Sphk o Allocation stack memory changes the address displacement and 4346155Sphk new iteration is needed. 44192895Sjamie 45164032Srwatson Here is block diagram of LRA passes: 4646155Sphk 47124882Srwatson ------------------------ 48177785Skib --------------- | Undo inheritance for | --------------- 4946155Sphk | Memory-memory | | spilled pseudos, | | New (and old) | 5087275Srwatson | move coalesce |<---| splits for pseudos got |<-- | pseudos | 5187275Srwatson --------------- | the same hard regs, | | assignment | 52220137Strasz Start | | and optional reloads | --------------- 53221362Strasz | | ------------------------ ^ 54168401Spjd V | ---------------- | 55193066Sjamie ----------- V | Update virtual | | 56113275Smike| Remove |----> ------------>| register | | 57147185Spjd| scratches | ^ | displacements | | 58113275Smike ----------- | ---------------- | 5946155Sphk | | | 60113275Smike | V New | 6157163Srwatson | ------------ pseudos ------------------- 62113275Smike | |Constraints:| or insns | Inheritance/split | 63196019Srwatson | | RTL |--------->| transformations | 6446155Sphk | | transfor- | | in EBB scope | 65196019Srwatson | substi- | mations | ------------------- 66196019Srwatson | tutions ------------ 6746155Sphk | | No change 68196019Srwatson ---------------- V 69185435Sbz | Spilled pseudo | ------------------- 70185435Sbz | to memory |<----| Rematerialization | 71185435Sbz | substitution | ------------------- 72185435Sbz ---------------- 73185435Sbz | No susbtitions 74185435Sbz V 7546155Sphk ------------------------- 76163606Srwatson | Hard regs substitution, | 77163606Srwatson | devirtalization, and |------> Finish 78195944Sjamie | restoring scratches got | 79195944Sjamie | memory | 8046155Sphk ------------------------- 81227293Sed 8246155Sphk To speed up the process: 83202468Sbz o We process only insns affected by changes on previous 84202468Sbz iterations; 85202468Sbz o We don't use DFA-infrastructure because it results in much slower 86202468Sbz compiler speed than a special IR described below does; 87202468Sbz o We use a special insn representation for quick access to insn 88202468Sbz info which is always *synchronized* with the current RTL; 89202468Sbz o Insn IR is minimized by memory. It is divided on three parts: 90202468Sbz o one specific for each insn in RTL (only operand locations); 91202468Sbz o one common for all insns in RTL with the same insn code 92202468Sbz (different operand attributes from machine descriptions); 93202468Sbz o one oriented for maintenance of live info (list of pseudos). 94202468Sbz o Pseudo data: 95202468Sbz o all insns where the pseudo is referenced; 96202468Sbz o live info (conflicting hard regs, live ranges, # of 97202468Sbz references etc); 98192895Sjamie o data used for assigning (preferred hard regs, costs etc). 99192895Sjamie 100192895Sjamie This file contains LRA driver, LRA utility functions and data, and 101192895Sjamie code for dealing with scratches. */ 102192895Sjamie 103192895Sjamie#include "config.h" 104192895Sjamie#include "system.h" 105192895Sjamie#include "coretypes.h" 106231267Smm#include "tm.h" 107194762Sjamie#include "hard-reg-set.h" 108195944Sjamie#include "rtl.h" 109201145Santoine#include "tm_p.h" 110196176Sbz#include "regs.h" 111202468Sbz#include "insn-config.h" 112196176Sbz#include "insn-codes.h" 113202468Sbz#include "recog.h" 114196176Sbz#include "output.h" 115192895Sjamie#include "addresses.h" 116192895Sjamie#include "flags.h" 117192895Sjamie#include "hashtab.h" 11857163Srwatson#include "hash-set.h" 119221362Strasz#include "vec.h" 120168401Spjd#include "machmode.h" 121191673Sjamie#include "input.h" 122191673Sjamie#include "function.h" 123221362Strasz#include "symtab.h" 124179881Sdelphij#include "wide-int.h" 125113275Smike#include "inchash.h" 126191673Sjamie#include "tree.h" 127190466Sjamie#include "optabs.h" 128191673Sjamie#include "statistics.h" 129192895Sjamie#include "double-int.h" 130192895Sjamie#include "real.h" 131221362Strasz#include "fixed-value.h" 132221362Strasz#include "alias.h" 133232598Strasz#include "expmed.h" 134221362Strasz#include "dojump.h" 135221362Strasz#include "explow.h" 136185435Sbz#include "calls.h" 137190466Sjamie#include "emit-rtl.h" 138192895Sjamie#include "varasm.h" 139185435Sbz#include "stmt.h" 140185435Sbz#include "expr.h" 141190466Sjamie#include "predict.h" 142192895Sjamie#include "dominance.h" 143185435Sbz#include "cfg.h" 144113275Smike#include "cfgrtl.h" 145191673Sjamie#include "cfgbuild.h" 146191673Sjamie#include "basic-block.h" 147191673Sjamie#include "except.h" 148191673Sjamie#include "tree-pass.h" 149191673Sjamie#include "timevar.h" 150191673Sjamie#include "target.h" 151113275Smike#include "ira.h" 152192895Sjamie#include "lra-int.h" 153216861Sbz#include "df.h" 154216861Sbz 155216861Sbz/* Dump bitmap SET with TITLE and BB INDEX. */ 156192895Sjamievoid 157192895Sjamielra_dump_bitmap_with_title (const char *title, bitmap set, int index) 158192895Sjamie{ 159202468Sbz unsigned int i; 160202468Sbz int count; 161202468Sbz bitmap_iterator bi; 162202468Sbz static const int max_nums_on_line = 10; 163202468Sbz 164202468Sbz if (bitmap_empty_p (set)) 165192895Sjamie return; 166216861Sbz fprintf (lra_dump_file, " %s %d:", title, index); 167192895Sjamie fprintf (lra_dump_file, "\n"); 168192895Sjamie count = max_nums_on_line + 1; 169192895Sjamie EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi) 170202468Sbz { 171202468Sbz if (count > max_nums_on_line) 172202468Sbz { 173202468Sbz fprintf (lra_dump_file, "\n "); 174202468Sbz count = 0; 175202468Sbz } 176195870Sjamie fprintf (lra_dump_file, " %4u", i); 177216861Sbz count++; 178195870Sjamie } 179195870Sjamie fprintf (lra_dump_file, "\n"); 180195870Sjamie} 181195870Sjamie 182195870Sjamie/* Hard registers currently not available for allocation. It can 183195870Sjamie changed after some hard registers become not eliminable. */ 184195870SjamieHARD_REG_SET lra_no_alloc_regs; 185195870Sjamie 186195870Sjamiestatic int get_new_reg_value (void); 187195870Sjamiestatic void expand_reg_info (void); 188192895Sjamiestatic void invalidate_insn_recog_data (int); 189195870Sjamiestatic int get_insn_freq (rtx_insn *); 190192895Sjamiestatic void invalidate_insn_data_regno_info (lra_insn_recog_data_t, 191192895Sjamie rtx_insn *, int); 192195870Sjamie 193192895Sjamie/* Expand all regno related info needed for LRA. */ 194192895Sjamiestatic void 195216861Sbzexpand_reg_data (int old) 196192895Sjamie{ 197192895Sjamie resize_reg_info (); 198192895Sjamie expand_reg_info (); 199192895Sjamie ira_expand_reg_equiv (); 200192895Sjamie for (int i = (int) max_reg_num () - 1; i >= old; i--) 201192895Sjamie lra_change_class (i, ALL_REGS, " Set", true); 202192895Sjamie} 203192895Sjamie 204192895Sjamie/* Create and return a new reg of ORIGINAL mode. If ORIGINAL is NULL 205232059Smm or of VOIDmode, use MD_MODE for the new reg. Initialize its 206232059Smm register class to RCLASS. Print message about assigning class 207232186Smm RCLASS containing new register name TITLE unless it is NULL. Use 208232278Smm attributes of ORIGINAL if it is a register. The created register 209254741Sdelphij will have unique held value. */ 210277985Sjamiertx 211192895Sjamielra_create_new_reg_with_unique_value (machine_mode md_mode, rtx original, 212216861Sbz enum reg_class rclass, const char *title) 213192895Sjamie{ 214192895Sjamie machine_mode mode; 215192895Sjamie rtx new_reg; 216192895Sjamie 217192895Sjamie if (original == NULL_RTX || (mode = GET_MODE (original)) == VOIDmode) 218192895Sjamie mode = md_mode; 219192895Sjamie lra_assert (mode != VOIDmode); 220192895Sjamie new_reg = gen_reg_rtx (mode); 221192895Sjamie if (original == NULL_RTX || ! REG_P (original)) 222232059Smm { 223232059Smm if (lra_dump_file != NULL) 224232186Smm fprintf (lra_dump_file, " Creating newreg=%i", REGNO (new_reg)); 225232278Smm } 226254741Sdelphij else 227277985Sjamie { 228192895Sjamie if (ORIGINAL_REGNO (original) >= FIRST_PSEUDO_REGISTER) 229216861Sbz ORIGINAL_REGNO (new_reg) = ORIGINAL_REGNO (original); 230192895Sjamie REG_USERVAR_P (new_reg) = REG_USERVAR_P (original); 231196002Sjamie REG_POINTER (new_reg) = REG_POINTER (original); 232196002Sjamie REG_ATTRS (new_reg) = REG_ATTRS (original); 233232059Smm if (lra_dump_file != NULL) 234192895Sjamie fprintf (lra_dump_file, " Creating newreg=%i from oldreg=%i", 235196002Sjamie REGNO (new_reg), REGNO (original)); 236231267Smm } 237192895Sjamie if (lra_dump_file != NULL) 238193865Sjamie { 239192895Sjamie if (title != NULL) 240192895Sjamie fprintf (lra_dump_file, ", assigning class %s to%s%s r%d", 241280632Sian reg_class_names[rclass], *title == '\0' ? "" : " ", 242280632Sian title, REGNO (new_reg)); 243280632Sian fprintf (lra_dump_file, "\n"); 244280632Sian } 245280632Sian expand_reg_data (max_reg_num ()); 246280632Sian setup_reg_classes (REGNO (new_reg), rclass, NO_REGS, rclass); 247280632Sian return new_reg; 248280632Sian} 249280632Sian 250280632Sian/* Analogous to the previous function but also inherits value of 251280632Sian ORIGINAL. */ 252280632Sianrtx 253280632Sianlra_create_new_reg (machine_mode md_mode, rtx original, 254192895Sjamie enum reg_class rclass, const char *title) 255185435Sbz{ 256185435Sbz rtx new_reg; 257185435Sbz 258185435Sbz new_reg 259185435Sbz = lra_create_new_reg_with_unique_value (md_mode, original, rclass, title); 260185435Sbz if (original != NULL_RTX && REG_P (original)) 261185435Sbz lra_assign_reg_val (REGNO (original), REGNO (new_reg)); 262185435Sbz return new_reg; 263185435Sbz} 264185435Sbz 265185435Sbz/* Set up for REGNO unique hold value. */ 266185435Sbzvoid 267185435Sbzlra_set_regno_unique_value (int regno) 268185435Sbz{ 269185435Sbz lra_reg_info[regno].val = get_new_reg_value (); 270185435Sbz} 271185435Sbz 272185435Sbz/* Invalidate INSN related info used by LRA. The info should never be 273185435Sbz used after that. */ 274185435Sbzvoid 275185435Sbzlra_invalidate_insn_data (rtx_insn *insn) 276185435Sbz{ 277185435Sbz lra_invalidate_insn_regno_info (insn); 278185435Sbz invalidate_insn_recog_data (INSN_UID (insn)); 279185435Sbz} 280185435Sbz 281185435Sbz/* Mark INSN deleted and invalidate the insn related info used by 282185435Sbz LRA. */ 283185435Sbzvoid 284185435Sbzlra_set_insn_deleted (rtx_insn *insn) 285185435Sbz{ 286185435Sbz lra_invalidate_insn_data (insn); 287185435Sbz SET_INSN_DELETED (insn); 288185435Sbz} 289185435Sbz 290185435Sbz/* Delete an unneeded INSN and any previous insns who sole purpose is 291185435Sbz loading data that is dead in INSN. */ 292190466Sjamievoid 293185435Sbzlra_delete_dead_insn (rtx_insn *insn) 294185435Sbz{ 295185435Sbz rtx_insn *prev = prev_real_insn (insn); 296185435Sbz rtx prev_dest; 297185435Sbz 298185435Sbz /* If the previous insn sets a register that dies in our insn, 299185435Sbz delete it too. */ 300185435Sbz if (prev && GET_CODE (PATTERN (prev)) == SET 301185435Sbz && (prev_dest = SET_DEST (PATTERN (prev)), REG_P (prev_dest)) 302191673Sjamie && reg_mentioned_p (prev_dest, PATTERN (insn)) 303191673Sjamie && find_regno_note (insn, REG_DEAD, REGNO (prev_dest)) 304191673Sjamie && ! side_effects_p (SET_SRC (PATTERN (prev)))) 305191673Sjamie lra_delete_dead_insn (prev); 306191673Sjamie 307191673Sjamie lra_set_insn_deleted (insn); 308225617Skmacy} 309185435Sbz 310191673Sjamie/* Emit insn x = y + z. Return NULL if we failed to do it. 311191673Sjamie Otherwise, return the insn. We don't use gen_add3_insn as it might 312192895Sjamie clobber CC. */ 313185435Sbzstatic rtx 314191673Sjamieemit_add3_insn (rtx x, rtx y, rtx z) 315191673Sjamie{ 316191673Sjamie rtx_insn *last; 317185435Sbz 318191673Sjamie last = get_last_insn (); 319191673Sjamie 320191673Sjamie if (have_addptr3_insn (x, y, z)) 321191673Sjamie { 322185435Sbz rtx insn = gen_addptr3_insn (x, y, z); 323192895Sjamie 324192895Sjamie /* If the target provides an "addptr" pattern it hopefully does 325191673Sjamie for a reason. So falling back to the normal add would be 326191673Sjamie a bug. */ 327191673Sjamie lra_assert (insn != NULL_RTX); 328192895Sjamie emit_insn (insn); 329192895Sjamie return insn; 330192895Sjamie } 331258929Speter 332191673Sjamie rtx_insn *insn = emit_insn (gen_rtx_SET (VOIDmode, x, 333191673Sjamie gen_rtx_PLUS (GET_MODE (y), y, z))); 334191673Sjamie if (recog_memoized (insn) < 0) 335191673Sjamie { 336185435Sbz delete_insns_since (last); 337191673Sjamie insn = NULL; 338191673Sjamie } 339185435Sbz return insn; 340191673Sjamie} 341185435Sbz 342191673Sjamie/* Emit insn x = x + y. Return the insn. We use gen_add2_insn as the 343191673Sjamie last resort. */ 344191673Sjamiestatic rtx 345191673Sjamieemit_add2_insn (rtx x, rtx y) 346191673Sjamie{ 347192895Sjamie rtx insn; 348192895Sjamie 349192895Sjamie insn = emit_add3_insn (x, x, y); 350192895Sjamie if (insn == NULL_RTX) 351192895Sjamie { 352192895Sjamie insn = gen_add2_insn (x, y); 353192895Sjamie if (insn != NULL_RTX) 354192895Sjamie emit_insn (insn); 355192895Sjamie } 356192895Sjamie return insn; 357192895Sjamie} 358192895Sjamie 359193865Sjamie/* Target checks operands through operand predicates to recognize an 360193865Sjamie insn. We should have a special precaution to generate add insns 361193865Sjamie which are frequent results of elimination. 362193865Sjamie 363193865Sjamie Emit insns for x = y + z. X can be used to store intermediate 364193865Sjamie values and should be not in Y and Z when we use X to store an 365193865Sjamie intermediate value. Y + Z should form [base] [+ index[ * scale]] [ 366193865Sjamie + disp] where base and index are registers, disp and scale are 367193865Sjamie constants. Y should contain base if it is present, Z should 368192895Sjamie contain disp if any. index[*scale] can be part of Y or Z. */ 369192895Sjamievoid 370185435Sbzlra_emit_add (rtx x, rtx y, rtx z) 371193865Sjamie{ 372192895Sjamie int old; 373192895Sjamie rtx_insn *last; 374192895Sjamie rtx a1, a2, base, index, disp, scale, index_scale; 375192895Sjamie bool ok_p; 376192895Sjamie 377192895Sjamie rtx add3_insn = emit_add3_insn (x, y, z); 378192895Sjamie old = max_reg_num (); 379192895Sjamie if (add3_insn != NULL) 380192895Sjamie ; 381192895Sjamie else 382192895Sjamie { 383192895Sjamie disp = a2 = NULL_RTX; 384192895Sjamie if (GET_CODE (y) == PLUS) 385192895Sjamie { 386192895Sjamie a1 = XEXP (y, 0); 387192895Sjamie a2 = XEXP (y, 1); 388192895Sjamie disp = z; 389192895Sjamie } 390192895Sjamie else 391192895Sjamie { 392192895Sjamie a1 = y; 393192895Sjamie if (CONSTANT_P (z)) 394192895Sjamie disp = z; 395192895Sjamie else 396192895Sjamie a2 = z; 397192895Sjamie } 398192895Sjamie index_scale = scale = NULL_RTX; 399192895Sjamie if (GET_CODE (a1) == MULT) 400192895Sjamie { 401192895Sjamie index_scale = a1; 402192895Sjamie index = XEXP (a1, 0); 403192895Sjamie scale = XEXP (a1, 1); 404192895Sjamie base = a2; 405192895Sjamie } 406192895Sjamie else if (a2 != NULL_RTX && GET_CODE (a2) == MULT) 407192895Sjamie { 408192895Sjamie index_scale = a2; 409192895Sjamie index = XEXP (a2, 0); 410192895Sjamie scale = XEXP (a2, 1); 411192895Sjamie base = a1; 412192895Sjamie } 413192895Sjamie else 414192895Sjamie { 415191673Sjamie base = a1; 416192895Sjamie index = a2; 417192895Sjamie } 418191673Sjamie if (! (REG_P (base) || GET_CODE (base) == SUBREG) 419191673Sjamie || (index != NULL_RTX 420192895Sjamie && ! (REG_P (index) || GET_CODE (index) == SUBREG)) 421192895Sjamie || (disp != NULL_RTX && ! CONSTANT_P (disp)) 422192895Sjamie || (scale != NULL_RTX && ! CONSTANT_P (scale))) 423191673Sjamie { 424192895Sjamie /* Probably we have no 3 op add. Last chance is to use 2-op 425192895Sjamie add insn. To succeed, don't move Z to X as an address 426191673Sjamie segment always comes in Y. Otherwise, we might fail when 427192895Sjamie adding the address segment to register. */ 428192895Sjamie lra_assert (x != y && x != z); 429192895Sjamie emit_move_insn (x, y); 430191673Sjamie rtx insn = emit_add2_insn (x, z); 431192895Sjamie lra_assert (insn != NULL_RTX); 432191673Sjamie } 433191673Sjamie else 434191673Sjamie { 435192895Sjamie if (index_scale == NULL_RTX) 436191673Sjamie index_scale = index; 437192895Sjamie if (disp == NULL_RTX) 438191673Sjamie { 439191673Sjamie /* Generate x = index_scale; x = x + base. */ 440192895Sjamie lra_assert (index_scale != NULL_RTX && base != NULL_RTX); 441192895Sjamie emit_move_insn (x, index_scale); 442192895Sjamie rtx insn = emit_add2_insn (x, base); 443192895Sjamie lra_assert (insn != NULL_RTX); 444192895Sjamie } 445192895Sjamie else if (scale == NULL_RTX) 446192895Sjamie { 447192895Sjamie /* Try x = base + disp. */ 448192895Sjamie lra_assert (base != NULL_RTX); 449192895Sjamie last = get_last_insn (); 450192895Sjamie rtx_insn *move_insn = 451192895Sjamie emit_move_insn (x, gen_rtx_PLUS (GET_MODE (base), base, disp)); 452192895Sjamie if (recog_memoized (move_insn) < 0) 453192895Sjamie { 454192895Sjamie delete_insns_since (last); 455192895Sjamie /* Generate x = disp; x = x + base. */ 456192895Sjamie emit_move_insn (x, disp); 457192895Sjamie rtx add2_insn = emit_add2_insn (x, base); 458192895Sjamie lra_assert (add2_insn != NULL_RTX); 459192895Sjamie } 460192895Sjamie /* Generate x = x + index. */ 461192895Sjamie if (index != NULL_RTX) 462192895Sjamie { 463192895Sjamie rtx insn = emit_add2_insn (x, index); 464192895Sjamie lra_assert (insn != NULL_RTX); 465192895Sjamie } 466192895Sjamie } 467192895Sjamie else 468192895Sjamie { 469191673Sjamie /* Try x = index_scale; x = x + disp; x = x + base. */ 470191673Sjamie last = get_last_insn (); 471191673Sjamie rtx_insn *move_insn = emit_move_insn (x, index_scale); 472191673Sjamie ok_p = false; 473192895Sjamie if (recog_memoized (move_insn) >= 0) 474192895Sjamie { 475191673Sjamie rtx insn = emit_add2_insn (x, disp); 476192895Sjamie if (insn != NULL_RTX) 477192895Sjamie { 478192895Sjamie insn = emit_add2_insn (x, base); 479192895Sjamie if (insn != NULL_RTX) 480192895Sjamie ok_p = true; 481192895Sjamie } 482192895Sjamie } 483192895Sjamie if (! ok_p) 484192895Sjamie { 485191673Sjamie delete_insns_since (last); 486191673Sjamie /* Generate x = disp; x = x + base; x = x + index_scale. */ 487191673Sjamie emit_move_insn (x, disp); 488191673Sjamie rtx insn = emit_add2_insn (x, base); 489192895Sjamie lra_assert (insn != NULL_RTX); 490192895Sjamie insn = emit_add2_insn (x, index_scale); 491185435Sbz lra_assert (insn != NULL_RTX); 492185435Sbz } 493192895Sjamie } 494192895Sjamie } 495192895Sjamie } 496192895Sjamie /* Functions emit_... can create pseudos -- so expand the pseudo 497192895Sjamie data. */ 498192895Sjamie if (old != max_reg_num ()) 499192895Sjamie expand_reg_data (old); 500192895Sjamie} 501192895Sjamie 502192895Sjamie/* The number of emitted reload insns so far. */ 503192895Sjamieint lra_curr_reload_num; 504185435Sbz 505192895Sjamie/* Emit x := y, processing special case when y = u + v or y = u + v * 506192895Sjamie scale + w through emit_add (Y can be an address which is base + 507191673Sjamie index reg * scale + displacement in general case). X may be used 508191673Sjamie as intermediate result therefore it should be not in Y. */ 509191673Sjamievoid 510185435Sbzlra_emit_move (rtx x, rtx y) 511185435Sbz{ 512192895Sjamie int old; 513191673Sjamie 514191673Sjamie if (GET_CODE (y) != PLUS) 515191673Sjamie { 516191673Sjamie if (rtx_equal_p (x, y)) 517191673Sjamie return; 518191673Sjamie old = max_reg_num (); 519191673Sjamie emit_move_insn (x, y); 520191673Sjamie if (REG_P (x)) 521225617Skmacy lra_reg_info[ORIGINAL_REGNO (x)].last_reload = ++lra_curr_reload_num; 522185435Sbz /* Function emit_move can create pseudos -- so expand the pseudo 523191673Sjamie data. */ 524191673Sjamie if (old != max_reg_num ()) 525191673Sjamie expand_reg_data (old); 526191673Sjamie return; 527191673Sjamie } 528191673Sjamie lra_emit_add (x, XEXP (y, 0), XEXP (y, 1)); 529191673Sjamie} 530191673Sjamie 531191673Sjamie/* Update insn operands which are duplication of operands whose 532191673Sjamie numbers are in array of NOPS (with end marker -1). The insn is 533191673Sjamie represented by its LRA internal representation ID. */ 534191673Sjamievoid 535191673Sjamielra_update_dups (lra_insn_recog_data_t id, signed char *nops) 536191673Sjamie{ 537191673Sjamie int i, j, nop; 538191673Sjamie struct lra_static_insn_data *static_id = id->insn_static_data; 539191673Sjamie 540191673Sjamie for (i = 0; i < static_id->n_dups; i++) 541191673Sjamie for (j = 0; (nop = nops[j]) >= 0; j++) 542185435Sbz if (static_id->dup_num[i] == nop) 543190466Sjamie *id->dup_loc[i] = *id->operand_loc[nop]; 544185435Sbz} 545185435Sbz 546185435Sbz 547185435Sbz 548191673Sjamie/* This page contains code dealing with info about registers in the 549191673Sjamie insns. */ 550196135Sbz 551191673Sjamie/* Pools for insn reg info. */ 552196835Sjamiestatic alloc_pool insn_reg_pool; 553280632Sian 554192895Sjamie/* Initiate pool for insn reg info. */ 555196135Sbzstatic void 556191673Sjamieinit_insn_regs (void) 557192895Sjamie{ 558193066Sjamie insn_reg_pool 559192895Sjamie = create_alloc_pool ("insn regs", sizeof (struct lra_insn_reg), 100); 560192895Sjamie} 561231267Smm 562195870Sjamie/* Create LRA insn related info about a reference to REGNO in INSN with 563280632Sian TYPE (in/out/inout), biggest reference mode MODE, flag that it is 564230129Smm reference through subreg (SUBREG_P), flag that is early clobbered 565191673Sjamie in the insn (EARLY_CLOBBER), and reference to the next insn reg 566192895Sjamie info (NEXT). */ 567191673Sjamiestatic struct lra_insn_reg * 568191673Sjamienew_insn_reg (rtx_insn *insn, int regno, enum op_type type, 569195974Sjamie machine_mode mode, 570191673Sjamie bool subreg_p, bool early_clobber, struct lra_insn_reg *next) 571191673Sjamie{ 572195974Sjamie struct lra_insn_reg *ir; 573191673Sjamie 574224290Smckusick ir = (struct lra_insn_reg *) pool_alloc (insn_reg_pool); 575224290Smckusick ir->type = type; 576191673Sjamie ir->biggest_mode = mode; 577185435Sbz if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (lra_reg_info[regno].biggest_mode) 578191673Sjamie && NONDEBUG_INSN_P (insn)) 579191673Sjamie lra_reg_info[regno].biggest_mode = mode; 580191673Sjamie ir->subreg_p = subreg_p; 581191673Sjamie ir->early_clobber = early_clobber; 582191673Sjamie ir->regno = regno; 583192895Sjamie ir->next = next; 584194762Sjamie return ir; 585192895Sjamie} 586191673Sjamie 587191673Sjamie/* Free insn reg info IR. */ 588191673Sjamiestatic void 589185435Sbzfree_insn_reg (struct lra_insn_reg *ir) 590191673Sjamie{ 591191673Sjamie pool_free (insn_reg_pool, ir); 592191673Sjamie} 593191673Sjamie 594185435Sbz/* Free insn reg info list IR. */ 595191673Sjamiestatic void 596191673Sjamiefree_insn_regs (struct lra_insn_reg *ir) 597191673Sjamie{ 598185435Sbz struct lra_insn_reg *next_ir; 599191673Sjamie 600191673Sjamie for (; ir != NULL; ir = next_ir) 601191673Sjamie { 602185435Sbz next_ir = ir->next; 603185435Sbz free_insn_reg (ir); 604185435Sbz } 605185435Sbz} 606185435Sbz 607185435Sbz/* Finish pool for insn reg info. */ 608230407Smmstatic void 609191673Sjamiefinish_insn_regs (void) 610191673Sjamie{ 611191673Sjamie free_alloc_pool (insn_reg_pool); 612191673Sjamie} 613191673Sjamie 614191673Sjamie 615191673Sjamie 616191673Sjamie/* This page contains code dealing LRA insn info (or in other words 617191673Sjamie LRA internal insn representation). */ 618191673Sjamie 619191673Sjamie/* Map INSN_CODE -> the static insn data. This info is valid during 620191673Sjamie all translation unit. */ 621191673Sjamiestruct lra_static_insn_data *insn_code_data[LAST_INSN_CODE]; 622191673Sjamie 623191673Sjamie/* Debug insns are represented as a special insn with one input 624194762Sjamie operand which is RTL expression in var_location. */ 625194762Sjamie 626194762Sjamie/* The following data are used as static insn operand data for all 627194762Sjamie debug insns. If structure lra_operand_data is changed, the 628194762Sjamie initializer should be changed too. */ 629194762Sjamiestatic struct lra_operand_data debug_operand_data = 630194762Sjamie { 631194762Sjamie NULL, /* alternative */ 632194762Sjamie VOIDmode, /* We are not interesting in the operand mode. */ 633192895Sjamie OP_IN, 634212436Sjamie 0, 0, 0, 0 635212436Sjamie }; 636212436Sjamie 637192895Sjamie/* The following data are used as static insn data for all debug 638212436Sjamie insns. If structure lra_static_insn_data is changed, the 639212436Sjamie initializer should be changed too. */ 640212436Sjamiestatic struct lra_static_insn_data debug_insn_static_data = 641212436Sjamie { 642212436Sjamie &debug_operand_data, 643192895Sjamie 0, /* Duplication operands #. */ 644231267Smm -1, /* Commutative operand #. */ 645231267Smm 1, /* Operands #. There is only one operand which is debug RTL 646231267Smm expression. */ 647231267Smm 0, /* Duplications #. */ 648231267Smm 0, /* Alternatives #. We are not interesting in alternatives 649231267Smm because we does not proceed debug_insns for reloads. */ 650231267Smm NULL, /* Hard registers referenced in machine description. */ 651231267Smm NULL /* Descriptions of operands in alternatives. */ 652191673Sjamie }; 653192895Sjamie 654192895Sjamie/* Called once per compiler work to initialize some LRA data related 655192895Sjamie to insns. */ 656192895Sjamiestatic void 657192895Sjamieinit_insn_code_data_once (void) 658192895Sjamie{ 659192895Sjamie memset (insn_code_data, 0, sizeof (insn_code_data)); 660191673Sjamie} 661195870Sjamie 662195870Sjamie/* Called once per compiler work to finalize some LRA data related to 663195870Sjamie insns. */ 664195870Sjamiestatic void 665195870Sjamiefinish_insn_code_data_once (void) 666195870Sjamie{ 667195870Sjamie int i; 668195870Sjamie 669195870Sjamie for (i = 0; i < LAST_INSN_CODE; i++) 670195870Sjamie { 671195870Sjamie if (insn_code_data[i] != NULL) 672195870Sjamie free (insn_code_data[i]); 673195870Sjamie } 674195870Sjamie} 675195870Sjamie 676195870Sjamie/* Return static insn data, allocate and setup if necessary. Although 677195870Sjamie dup_num is static data (it depends only on icode), to set it up we 678195870Sjamie need to extract insn first. So recog_data should be valid for 679195870Sjamie normal insn (ICODE >= 0) before the call. */ 680195870Sjamiestatic struct lra_static_insn_data * 681195870Sjamieget_static_insn_data (int icode, int nop, int ndup, int nalt) 682195870Sjamie{ 683195870Sjamie struct lra_static_insn_data *data; 684195870Sjamie size_t n_bytes; 685195870Sjamie 686195870Sjamie lra_assert (icode < LAST_INSN_CODE); 687195870Sjamie if (icode >= 0 && (data = insn_code_data[icode]) != NULL) 688195870Sjamie return data; 689211085Sjamie lra_assert (nop >= 0 && ndup >= 0 && nalt >= 0); 690211085Sjamie n_bytes = sizeof (struct lra_static_insn_data) 691211085Sjamie + sizeof (struct lra_operand_data) * nop 692211085Sjamie + sizeof (int) * ndup; 693211085Sjamie data = XNEWVAR (struct lra_static_insn_data, n_bytes); 694211085Sjamie data->operand_alternative = NULL; 695194251Sjamie data->n_operands = nop; 696194251Sjamie data->n_dups = ndup; 697194251Sjamie data->n_alternatives = nalt; 698194251Sjamie data->operand = ((struct lra_operand_data *) 699194251Sjamie ((char *) data + sizeof (struct lra_static_insn_data))); 700194251Sjamie data->dup_num = ((int *) ((char *) data->operand 701194251Sjamie + sizeof (struct lra_operand_data) * nop)); 702195974Sjamie if (icode >= 0) 703195974Sjamie { 704195974Sjamie int i; 705195974Sjamie 706195974Sjamie insn_code_data[icode] = data; 707195974Sjamie for (i = 0; i < nop; i++) 708195974Sjamie { 709195974Sjamie data->operand[i].constraint 710195974Sjamie = insn_data[icode].operand[i].constraint; 711195974Sjamie data->operand[i].mode = insn_data[icode].operand[i].mode; 712195974Sjamie data->operand[i].strict_low = insn_data[icode].operand[i].strict_low; 713195974Sjamie data->operand[i].is_operator 714195974Sjamie = insn_data[icode].operand[i].is_operator; 715195974Sjamie data->operand[i].type 716191673Sjamie = (data->operand[i].constraint[0] == '=' ? OP_OUT 717192895Sjamie : data->operand[i].constraint[0] == '+' ? OP_INOUT 718192895Sjamie : OP_IN); 719192895Sjamie data->operand[i].is_address = false; 720192895Sjamie } 721192895Sjamie for (i = 0; i < ndup; i++) 722192895Sjamie data->dup_num[i] = recog_data.dup_num[i]; 723192895Sjamie } 724192895Sjamie return data; 725191673Sjamie} 726191673Sjamie 727191673Sjamie/* The current length of the following array. */ 728191673Sjamieint lra_insn_recog_data_len; 729191673Sjamie 730191673Sjamie/* Map INSN_UID -> the insn recog data (NULL if unknown). */ 731191673Sjamielra_insn_recog_data_t *lra_insn_recog_data; 732191673Sjamie 733191673Sjamie/* Initialize LRA data about insns. */ 734191673Sjamiestatic void 735191673Sjamieinit_insn_recog_data (void) 736191673Sjamie{ 737191673Sjamie lra_insn_recog_data_len = 0; 738191673Sjamie lra_insn_recog_data = NULL; 739191673Sjamie init_insn_regs (); 740191673Sjamie} 741191673Sjamie 742191673Sjamie/* Expand, if necessary, LRA data about insns. */ 743191673Sjamiestatic void 744191673Sjamiecheck_and_expand_insn_recog_data (int index) 745191673Sjamie{ 746191673Sjamie int i, old; 747193066Sjamie 748193066Sjamie if (lra_insn_recog_data_len > index) 749191673Sjamie return; 750191673Sjamie old = lra_insn_recog_data_len; 751191673Sjamie lra_insn_recog_data_len = index * 3 / 2 + 1; 752191673Sjamie lra_insn_recog_data = XRESIZEVEC (lra_insn_recog_data_t, 753191673Sjamie lra_insn_recog_data, 754191673Sjamie lra_insn_recog_data_len); 755191673Sjamie for (i = old; i < lra_insn_recog_data_len; i++) 756191673Sjamie lra_insn_recog_data[i] = NULL; 757191673Sjamie} 758191673Sjamie 759193066Sjamie/* Finish LRA DATA about insn. */ 760193066Sjamiestatic void 761193066Sjamiefree_insn_recog_data (lra_insn_recog_data_t data) 762193066Sjamie{ 763193066Sjamie if (data->operand_loc != NULL) 764193066Sjamie free (data->operand_loc); 765193066Sjamie if (data->dup_loc != NULL) 766193066Sjamie free (data->dup_loc); 767193066Sjamie if (data->arg_hard_regs != NULL) 768193066Sjamie free (data->arg_hard_regs); 769193066Sjamie if (data->icode < 0 && NONDEBUG_INSN_P (data->insn)) 770193066Sjamie { 771193066Sjamie if (data->insn_static_data->operand_alternative != NULL) 772193066Sjamie free (const_cast <operand_alternative *> 773193066Sjamie (data->insn_static_data->operand_alternative)); 774193066Sjamie free_insn_regs (data->insn_static_data->hard_regs); 775193066Sjamie free (data->insn_static_data); 776193066Sjamie } 777193066Sjamie free_insn_regs (data->regs); 778193066Sjamie data->regs = NULL; 779193066Sjamie free (data); 780193066Sjamie} 781193066Sjamie 782193066Sjamie/* Finish LRA data about all insns. */ 783193066Sjamiestatic void 784193066Sjamiefinish_insn_recog_data (void) 785193066Sjamie{ 786193066Sjamie int i; 787193066Sjamie lra_insn_recog_data_t data; 788193066Sjamie 789193066Sjamie for (i = 0; i < lra_insn_recog_data_len; i++) 790193066Sjamie if ((data = lra_insn_recog_data[i]) != NULL) 791193066Sjamie free_insn_recog_data (data); 792193066Sjamie finish_insn_regs (); 793193066Sjamie free (lra_insn_recog_data); 794193066Sjamie} 795205014Snwhitehorn 796217896Sdchagin/* Setup info about operands in alternatives of LRA DATA of insn. */ 797193066Sjamiestatic void 798193066Sjamiesetup_operand_alternative (lra_insn_recog_data_t data, 799193066Sjamie const operand_alternative *op_alt) 800193066Sjamie{ 801193066Sjamie int i, j, nop, nalt; 802193066Sjamie int icode = data->icode; 803193066Sjamie struct lra_static_insn_data *static_data = data->insn_static_data; 804193066Sjamie 805193066Sjamie static_data->commutative = -1; 806193066Sjamie nop = static_data->n_operands; 807193066Sjamie nalt = static_data->n_alternatives; 808193066Sjamie static_data->operand_alternative = op_alt; 809193066Sjamie for (i = 0; i < nop; i++) 810193066Sjamie { 811193066Sjamie static_data->operand[i].early_clobber = false; 812193066Sjamie static_data->operand[i].is_address = false; 813193066Sjamie if (static_data->operand[i].constraint[0] == '%') 814185435Sbz { 815191673Sjamie /* We currently only support one commutative pair of operands. */ 816191673Sjamie if (static_data->commutative < 0) 817277279Sjamie static_data->commutative = i; 818191673Sjamie else 819191673Sjamie lra_assert (icode < 0); /* Asm */ 820191673Sjamie /* The last operand should not be marked commutative. */ 821191673Sjamie lra_assert (i != nop - 1); 822191673Sjamie } 823192895Sjamie } 824195870Sjamie for (j = 0; j < nalt; j++) 825195870Sjamie for (i = 0; i < nop; i++, op_alt++) 826195870Sjamie { 827195870Sjamie static_data->operand[i].early_clobber |= op_alt->earlyclobber; 828195870Sjamie static_data->operand[i].is_address |= op_alt->is_address; 829192895Sjamie } 830192895Sjamie} 831185435Sbz 832192895Sjamie/* Recursively process X and collect info about registers, which are 833192895Sjamie not the insn operands, in X with TYPE (in/out/inout) and flag that 834185435Sbz it is early clobbered in the insn (EARLY_CLOBBER) and add the info 835195974Sjamie to LIST. X is a part of insn given by DATA. Return the result 836192895Sjamie list. */ 837192895Sjamiestatic struct lra_insn_reg * 838192895Sjamiecollect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data, 839192895Sjamie struct lra_insn_reg *list, 840192895Sjamie enum op_type type, bool early_clobber) 841202116Sbz{ 842202116Sbz int i, j, regno, last; 843202116Sbz bool subreg_p; 844192895Sjamie machine_mode mode; 845192895Sjamie struct lra_insn_reg *curr; 846192895Sjamie rtx op = *x; 847192895Sjamie enum rtx_code code = GET_CODE (op); 848192895Sjamie const char *fmt = GET_RTX_FORMAT (code); 849192895Sjamie 850192895Sjamie for (i = 0; i < data->insn_static_data->n_operands; i++) 851192895Sjamie if (x == data->operand_loc[i]) 852192895Sjamie /* It is an operand loc. Stop here. */ 853192895Sjamie return list; 854192895Sjamie for (i = 0; i < data->insn_static_data->n_dups; i++) 855192895Sjamie if (x == data->dup_loc[i]) 856192895Sjamie /* It is a dup loc. Stop here. */ 857192895Sjamie return list; 858192895Sjamie mode = GET_MODE (op); 859192895Sjamie subreg_p = false; 860192895Sjamie if (code == SUBREG) 861192895Sjamie { 862192895Sjamie op = SUBREG_REG (op); 863192895Sjamie code = GET_CODE (op); 864192895Sjamie if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (op))) 865192895Sjamie { 866192895Sjamie mode = GET_MODE (op); 867192895Sjamie if (GET_MODE_SIZE (mode) > REGMODE_NATURAL_SIZE (mode)) 868185435Sbz subreg_p = true; 869191673Sjamie } 870191673Sjamie } 871185435Sbz if (REG_P (op)) 872185435Sbz { 873191673Sjamie if ((regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER) 874191673Sjamie return list; 875277279Sjamie /* Process all regs even unallocatable ones as we need info 876191673Sjamie about all regs for rematerialization pass. */ 877191673Sjamie for (last = regno + hard_regno_nregs[regno][mode]; 878191673Sjamie regno < last; 879191673Sjamie regno++) 880191673Sjamie { 881192895Sjamie for (curr = list; curr != NULL; curr = curr->next) 882195870Sjamie if (curr->regno == regno && curr->subreg_p == subreg_p 883195870Sjamie && curr->biggest_mode == mode) 884195870Sjamie { 885195870Sjamie if (curr->type != type) 886195870Sjamie curr->type = OP_INOUT; 887192895Sjamie if (curr->early_clobber != early_clobber) 888192895Sjamie curr->early_clobber = true; 889185435Sbz break; 890192895Sjamie } 891192895Sjamie if (curr == NULL) 892185435Sbz { 893195974Sjamie /* This is a new hard regno or the info can not be 894192895Sjamie integrated into the found structure. */ 895192895Sjamie#ifdef STACK_REGS 896192895Sjamie early_clobber 897192895Sjamie = (early_clobber 898192895Sjamie /* This clobber is to inform popping floating 899192895Sjamie point stack only. */ 900192895Sjamie && ! (FIRST_STACK_REG <= regno 901192895Sjamie && regno <= LAST_STACK_REG)); 902192895Sjamie#endif 903192895Sjamie list = new_insn_reg (data->insn, regno, type, mode, subreg_p, 904192895Sjamie early_clobber, list); 905192895Sjamie } 906192895Sjamie } 907192895Sjamie return list; 908192895Sjamie } 909192895Sjamie switch (code) 910185435Sbz { 911191673Sjamie case SET: 912185435Sbz list = collect_non_operand_hard_regs (&SET_DEST (op), data, 913185435Sbz list, OP_OUT, false); 914195945Sjamie list = collect_non_operand_hard_regs (&SET_SRC (op), data, 915195945Sjamie list, OP_IN, false); 916195945Sjamie break; 917195945Sjamie case CLOBBER: 918195945Sjamie /* We treat clobber of non-operand hard registers as early 919195945Sjamie clobber (the behavior is expected from asm). */ 920195945Sjamie list = collect_non_operand_hard_regs (&XEXP (op, 0), data, 921195945Sjamie list, OP_OUT, true); 922195945Sjamie break; 923230143Smm case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC: 924191673Sjamie list = collect_non_operand_hard_regs (&XEXP (op, 0), data, 925191673Sjamie list, OP_INOUT, false); 926191673Sjamie break; 927191673Sjamie case PRE_MODIFY: case POST_MODIFY: 928191673Sjamie list = collect_non_operand_hard_regs (&XEXP (op, 0), data, 929191673Sjamie list, OP_INOUT, false); 930191673Sjamie list = collect_non_operand_hard_regs (&XEXP (op, 1), data, 931191673Sjamie list, OP_IN, false); 932191673Sjamie break; 933191673Sjamie default: 934191673Sjamie fmt = GET_RTX_FORMAT (code); 935191673Sjamie for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 936191673Sjamie { 937191673Sjamie if (fmt[i] == 'e') 938191673Sjamie list = collect_non_operand_hard_regs (&XEXP (op, i), data, 939191673Sjamie list, OP_IN, false); 940191673Sjamie else if (fmt[i] == 'E') 941241896Skib for (j = XVECLEN (op, i) - 1; j >= 0; j--) 942230129Smm list = collect_non_operand_hard_regs (&XVECEXP (op, i, j), data, 943230129Smm list, OP_IN, false); 944230129Smm } 945230129Smm } 946230129Smm return list; 947230129Smm} 948230407Smm 949230407Smm/* Set up and return info about INSN. Set up the info if it is not set up 950230407Smm yet. */ 951230407Smmlra_insn_recog_data_t 952230407Smmlra_set_insn_recog_data (rtx_insn *insn) 953230407Smm{ 954230129Smm lra_insn_recog_data_t data; 955230129Smm int i, n, icode; 956230129Smm rtx **locs; 957230129Smm unsigned int uid = INSN_UID (insn); 958230407Smm struct lra_static_insn_data *insn_static_data; 959230129Smm 960230129Smm check_and_expand_insn_recog_data (uid); 961230129Smm if (DEBUG_INSN_P (insn)) 962230129Smm icode = -1; 963230129Smm else 964230129Smm { 965230129Smm icode = INSN_CODE (insn); 966230129Smm if (icode < 0) 967230129Smm /* It might be a new simple insn which is not recognized yet. */ 968230129Smm INSN_CODE (insn) = icode = recog_memoized (insn); 969192895Sjamie } 970192895Sjamie data = XNEW (struct lra_insn_recog_data); 971192895Sjamie lra_insn_recog_data[uid] = data; 972192895Sjamie data->insn = insn; 973192895Sjamie data->used_insn_alternative = -1; 974192895Sjamie data->icode = icode; 975191673Sjamie data->regs = NULL; 976191673Sjamie if (DEBUG_INSN_P (insn)) 977185435Sbz { 978280632Sian data->insn_static_data = &debug_insn_static_data; 979280632Sian data->dup_loc = NULL; 980280632Sian data->arg_hard_regs = NULL; 981280632Sian data->preferred_alternatives = ALL_ALTERNATIVES; 982280632Sian data->operand_loc = XNEWVEC (rtx *, 1); 983280632Sian data->operand_loc[0] = &INSN_VAR_LOCATION_LOC (insn); 984280632Sian return data; 985280632Sian } 986280632Sian if (icode < 0) 987280632Sian { 988280632Sian int nop, nalt; 989280632Sian machine_mode operand_mode[MAX_RECOG_OPERANDS]; 990280632Sian const char *constraints[MAX_RECOG_OPERANDS]; 991280632Sian 992280632Sian nop = asm_noperands (PATTERN (insn)); 993280632Sian data->operand_loc = data->dup_loc = NULL; 994280632Sian nalt = 1; 995280632Sian if (nop < 0) 996280632Sian { 997280632Sian /* It is a special insn like USE or CLOBBER. We should 998280632Sian recognize any regular insn otherwise LRA can do nothing 999280632Sian with this insn. */ 1000280632Sian gcc_assert (GET_CODE (PATTERN (insn)) == USE 1001280632Sian || GET_CODE (PATTERN (insn)) == CLOBBER 1002280632Sian || GET_CODE (PATTERN (insn)) == ASM_INPUT); 1003280632Sian data->insn_static_data = insn_static_data 1004280632Sian = get_static_insn_data (-1, 0, 0, nalt); 1005280632Sian } 1006280632Sian else 1007280632Sian { 1008280632Sian /* expand_asm_operands makes sure there aren't too many 1009280632Sian operands. */ 1010280632Sian lra_assert (nop <= MAX_RECOG_OPERANDS); 1011280632Sian if (nop != 0) 1012280632Sian data->operand_loc = XNEWVEC (rtx *, nop); 1013280632Sian /* Now get the operand values and constraints out of the 1014280632Sian insn. */ 1015280632Sian decode_asm_operands (PATTERN (insn), NULL, 1016280632Sian data->operand_loc, 1017280632Sian constraints, operand_mode, NULL); 1018191673Sjamie if (nop > 0) 1019191673Sjamie { 1020191673Sjamie const char *p = recog_data.constraints[0]; 1021191673Sjamie 1022191673Sjamie for (p = constraints[0]; *p; p++) 1023191673Sjamie nalt += *p == ','; 1024191673Sjamie } 1025191673Sjamie data->insn_static_data = insn_static_data 1026191673Sjamie = get_static_insn_data (-1, nop, 0, nalt); 1027185435Sbz for (i = 0; i < nop; i++) 1028191673Sjamie { 1029191673Sjamie insn_static_data->operand[i].mode = operand_mode[i]; 1030191673Sjamie insn_static_data->operand[i].constraint = constraints[i]; 1031191673Sjamie insn_static_data->operand[i].strict_low = false; 1032191673Sjamie insn_static_data->operand[i].is_operator = false; 1033191673Sjamie insn_static_data->operand[i].is_address = false; 1034191673Sjamie } 1035191673Sjamie } 1036191673Sjamie for (i = 0; i < insn_static_data->n_operands; i++) 1037185435Sbz insn_static_data->operand[i].type 1038191673Sjamie = (insn_static_data->operand[i].constraint[0] == '=' ? OP_OUT 1039191673Sjamie : insn_static_data->operand[i].constraint[0] == '+' ? OP_INOUT 1040185435Sbz : OP_IN); 1041191673Sjamie data->preferred_alternatives = ALL_ALTERNATIVES; 1042191673Sjamie if (nop > 0) 1043191673Sjamie { 1044191673Sjamie operand_alternative *op_alt = XCNEWVEC (operand_alternative, 1045191673Sjamie nalt * nop); 1046191673Sjamie preprocess_constraints (nop, nalt, constraints, op_alt); 1047191673Sjamie setup_operand_alternative (data, op_alt); 1048196835Sjamie } 1049196835Sjamie } 1050196835Sjamie else 1051196835Sjamie { 1052196835Sjamie insn_extract (insn); 1053196835Sjamie data->insn_static_data = insn_static_data 1054196835Sjamie = get_static_insn_data (icode, insn_data[icode].n_operands, 1055191673Sjamie insn_data[icode].n_dups, 1056192895Sjamie insn_data[icode].n_alternatives); 1057192895Sjamie n = insn_static_data->n_operands; 1058192895Sjamie if (n == 0) 1059192895Sjamie locs = NULL; 1060192895Sjamie else 1061192895Sjamie { 1062192895Sjamie locs = XNEWVEC (rtx *, n); 1063191673Sjamie memcpy (locs, recog_data.operand_loc, n * sizeof (rtx *)); 1064191673Sjamie } 1065191673Sjamie data->operand_loc = locs; 1066191673Sjamie n = insn_static_data->n_dups; 1067191673Sjamie if (n == 0) 1068191673Sjamie locs = NULL; 1069191673Sjamie else 1070192895Sjamie { 1071191673Sjamie locs = XNEWVEC (rtx *, n); 1072191673Sjamie memcpy (locs, recog_data.dup_loc, n * sizeof (rtx *)); 1073191673Sjamie } 1074191673Sjamie data->dup_loc = locs; 1075191673Sjamie data->preferred_alternatives = get_preferred_alternatives (insn); 1076191673Sjamie const operand_alternative *op_alt = preprocess_insn_constraints (icode); 1077191673Sjamie if (!insn_static_data->operand_alternative) 1078191673Sjamie setup_operand_alternative (data, op_alt); 1079192895Sjamie else if (op_alt != insn_static_data->operand_alternative) 1080192895Sjamie insn_static_data->operand_alternative = op_alt; 1081192895Sjamie } 1082192895Sjamie if (GET_CODE (PATTERN (insn)) == CLOBBER || GET_CODE (PATTERN (insn)) == USE) 1083191673Sjamie insn_static_data->hard_regs = NULL; 1084191673Sjamie else 1085191673Sjamie insn_static_data->hard_regs 1086191673Sjamie = collect_non_operand_hard_regs (&PATTERN (insn), data, 1087191673Sjamie NULL, OP_IN, false); 1088191673Sjamie data->arg_hard_regs = NULL; 1089191673Sjamie if (CALL_P (insn)) 1090191673Sjamie { 1091191673Sjamie bool use_p; 1092191673Sjamie rtx link; 1093191673Sjamie int n_hard_regs, regno, arg_hard_regs[FIRST_PSEUDO_REGISTER]; 1094191673Sjamie 1095191673Sjamie n_hard_regs = 0; 1096191673Sjamie /* Finding implicit hard register usage. We believe it will be 1097191673Sjamie not changed whatever transformations are used. Call insns 1098191673Sjamie are such example. */ 1099191673Sjamie for (link = CALL_INSN_FUNCTION_USAGE (insn); 1100192895Sjamie link != NULL_RTX; 1101191673Sjamie link = XEXP (link, 1)) 1102191673Sjamie if (((use_p = GET_CODE (XEXP (link, 0)) == USE) 1103191673Sjamie || GET_CODE (XEXP (link, 0)) == CLOBBER) 1104191673Sjamie && REG_P (XEXP (XEXP (link, 0), 0))) 1105191673Sjamie { 1106191673Sjamie regno = REGNO (XEXP (XEXP (link, 0), 0)); 1107191673Sjamie lra_assert (regno < FIRST_PSEUDO_REGISTER); 1108191673Sjamie /* It is an argument register. */ 1109191673Sjamie for (i = (hard_regno_nregs 1110191673Sjamie [regno][GET_MODE (XEXP (XEXP (link, 0), 0))]) - 1; 1111191673Sjamie i >= 0; 1112191673Sjamie i--) 1113191673Sjamie arg_hard_regs[n_hard_regs++] 1114191673Sjamie = regno + i + (use_p ? 0 : FIRST_PSEUDO_REGISTER); 1115191673Sjamie } 1116191673Sjamie if (n_hard_regs != 0) 1117191673Sjamie { 1118191673Sjamie arg_hard_regs[n_hard_regs++] = -1; 1119191673Sjamie data->arg_hard_regs = XNEWVEC (int, n_hard_regs); 1120191673Sjamie memcpy (data->arg_hard_regs, arg_hard_regs, 1121196835Sjamie sizeof (int) * n_hard_regs); 1122196835Sjamie } 1123196835Sjamie } 1124196835Sjamie /* Some output operand can be recognized only from the context not 1125192895Sjamie from the constraints which are empty in this case. Call insn may 1126192895Sjamie contain a hard register in set destination with empty constraint 1127192895Sjamie and extract_insn treats them as an input. */ 1128192895Sjamie for (i = 0; i < insn_static_data->n_operands; i++) 1129192895Sjamie { 1130196835Sjamie int j; 1131192895Sjamie rtx pat, set; 1132196835Sjamie struct lra_operand_data *operand = &insn_static_data->operand[i]; 1133196835Sjamie 1134192895Sjamie /* ??? Should we treat 'X' the same way. It looks to me that 1135192895Sjamie 'X' means anything and empty constraint means we do not 1136192895Sjamie care. */ 1137192895Sjamie if (operand->type != OP_IN || *operand->constraint != '\0' 1138192895Sjamie || operand->is_operator) 1139192895Sjamie continue; 1140192895Sjamie pat = PATTERN (insn); 1141192895Sjamie if (GET_CODE (pat) == SET) 1142192895Sjamie { 1143192895Sjamie if (data->operand_loc[i] != &SET_DEST (pat)) 1144192895Sjamie continue; 1145192895Sjamie } 1146192895Sjamie else if (GET_CODE (pat) == PARALLEL) 1147192895Sjamie { 1148192895Sjamie for (j = XVECLEN (pat, 0) - 1; j >= 0; j--) 1149192895Sjamie { 1150196835Sjamie set = XVECEXP (PATTERN (insn), 0, j); 1151192895Sjamie if (GET_CODE (set) == SET 1152191673Sjamie && &SET_DEST (set) == data->operand_loc[i]) 1153192895Sjamie break; 1154192895Sjamie } 1155192895Sjamie if (j < 0) 1156191673Sjamie continue; 1157192895Sjamie } 1158191673Sjamie else 1159192895Sjamie continue; 1160191673Sjamie operand->type = OP_OUT; 1161191673Sjamie } 1162191673Sjamie return data; 1163191673Sjamie} 1164191673Sjamie 1165191673Sjamie/* Return info about insn give by UID. The info should be already set 1166191673Sjamie up. */ 1167191673Sjamiestatic lra_insn_recog_data_t 1168191673Sjamieget_insn_recog_data_by_uid (int uid) 1169191673Sjamie{ 1170191673Sjamie lra_insn_recog_data_t data; 1171191673Sjamie 1172191673Sjamie data = lra_insn_recog_data[uid]; 1173191673Sjamie lra_assert (data != NULL); 1174191673Sjamie return data; 1175191673Sjamie} 1176191673Sjamie 1177191673Sjamie/* Invalidate all info about insn given by its UID. */ 1178191673Sjamiestatic void 1179192895Sjamieinvalidate_insn_recog_data (int uid) 1180191673Sjamie{ 1181191673Sjamie lra_insn_recog_data_t data; 1182191673Sjamie 1183191673Sjamie data = lra_insn_recog_data[uid]; 1184191673Sjamie lra_assert (data != NULL); 1185191673Sjamie free_insn_recog_data (data); 1186191673Sjamie lra_insn_recog_data[uid] = NULL; 1187191673Sjamie} 1188191673Sjamie 1189191673Sjamie/* Update all the insn info about INSN. It is usually called when 1190191673Sjamie something in the insn was changed. Return the updated info. */ 1191191673Sjamielra_insn_recog_data_t 1192191673Sjamielra_update_insn_recog_data (rtx_insn *insn) 1193191673Sjamie{ 1194191673Sjamie lra_insn_recog_data_t data; 1195191673Sjamie int n; 1196191673Sjamie unsigned int uid = INSN_UID (insn); 1197191673Sjamie struct lra_static_insn_data *insn_static_data; 1198191673Sjamie HOST_WIDE_INT sp_offset = 0; 1199191673Sjamie 1200191673Sjamie check_and_expand_insn_recog_data (uid); 1201191673Sjamie if ((data = lra_insn_recog_data[uid]) != NULL 1202191673Sjamie && data->icode != INSN_CODE (insn)) 1203191673Sjamie { 1204191673Sjamie sp_offset = data->sp_offset; 1205191673Sjamie invalidate_insn_data_regno_info (data, insn, get_insn_freq (insn)); 1206191673Sjamie invalidate_insn_recog_data (uid); 1207191673Sjamie data = NULL; 1208191673Sjamie } 1209191673Sjamie if (data == NULL) 1210191673Sjamie { 1211191673Sjamie data = lra_get_insn_recog_data (insn); 1212191673Sjamie /* Initiate or restore SP offset. */ 1213191673Sjamie data->sp_offset = sp_offset; 1214191673Sjamie return data; 1215191673Sjamie } 1216191673Sjamie insn_static_data = data->insn_static_data; 1217191673Sjamie data->used_insn_alternative = -1; 1218191673Sjamie if (DEBUG_INSN_P (insn)) 1219191673Sjamie return data; 1220191673Sjamie if (data->icode < 0) 1221191673Sjamie { 1222185435Sbz int nop; 1223191673Sjamie machine_mode operand_mode[MAX_RECOG_OPERANDS]; 1224191673Sjamie const char *constraints[MAX_RECOG_OPERANDS]; 1225194762Sjamie 1226194762Sjamie nop = asm_noperands (PATTERN (insn)); 1227194762Sjamie if (nop >= 0) 1228194762Sjamie { 1229194762Sjamie lra_assert (nop == data->insn_static_data->n_operands); 1230194762Sjamie /* Now get the operand values and constraints out of the 1231191673Sjamie insn. */ 1232192895Sjamie decode_asm_operands (PATTERN (insn), NULL, 1233192895Sjamie data->operand_loc, 1234192895Sjamie constraints, operand_mode, NULL); 1235192895Sjamie#ifdef ENABLE_CHECKING 1236192895Sjamie { 1237192895Sjamie int i; 1238192895Sjamie 1239192895Sjamie for (i = 0; i < nop; i++) 1240192895Sjamie lra_assert 1241192895Sjamie (insn_static_data->operand[i].mode == operand_mode[i] 1242191673Sjamie && insn_static_data->operand[i].constraint == constraints[i] 1243191673Sjamie && ! insn_static_data->operand[i].is_operator); 1244191673Sjamie } 1245191673Sjamie#endif 1246191673Sjamie } 1247191673Sjamie#ifdef ENABLE_CHECKING 1248191673Sjamie { 1249191673Sjamie int i; 1250191673Sjamie 1251191673Sjamie for (i = 0; i < insn_static_data->n_operands; i++) 1252191673Sjamie lra_assert 1253191673Sjamie (insn_static_data->operand[i].type 1254191673Sjamie == (insn_static_data->operand[i].constraint[0] == '=' ? OP_OUT 1255191673Sjamie : insn_static_data->operand[i].constraint[0] == '+' ? OP_INOUT 1256191673Sjamie : OP_IN)); 1257191673Sjamie } 1258191673Sjamie#endif 1259191673Sjamie } 1260191673Sjamie else 1261192895Sjamie { 1262192895Sjamie insn_extract (insn); 1263192895Sjamie n = insn_static_data->n_operands; 1264191673Sjamie if (n != 0) 1265191673Sjamie memcpy (data->operand_loc, recog_data.operand_loc, n * sizeof (rtx *)); 1266191673Sjamie n = insn_static_data->n_dups; 1267191673Sjamie if (n != 0) 1268191673Sjamie memcpy (data->dup_loc, recog_data.dup_loc, n * sizeof (rtx *)); 1269191673Sjamie lra_assert (check_bool_attrs (insn)); 1270191673Sjamie } 1271191673Sjamie return data; 1272191673Sjamie} 1273191673Sjamie 1274191673Sjamie/* Set up that INSN is using alternative ALT now. */ 1275191673Sjamievoid 1276191673Sjamielra_set_used_insn_alternative (rtx_insn *insn, int alt) 1277191673Sjamie{ 1278191673Sjamie lra_insn_recog_data_t data; 1279191673Sjamie 1280191673Sjamie data = lra_get_insn_recog_data (insn); 1281191673Sjamie data->used_insn_alternative = alt; 1282192895Sjamie} 1283192895Sjamie 1284194762Sjamie/* Set up that insn with UID is using alternative ALT now. The insn 1285185435Sbz info should be already set up. */ 1286192895Sjamievoid 1287191673Sjamielra_set_used_insn_alternative_by_uid (int uid, int alt) 1288192895Sjamie{ 1289192895Sjamie lra_insn_recog_data_t data; 1290191673Sjamie 1291191673Sjamie check_and_expand_insn_recog_data (uid); 1292191673Sjamie data = lra_insn_recog_data[uid]; 1293191673Sjamie lra_assert (data != NULL); 1294192895Sjamie data->used_insn_alternative = alt; 1295191673Sjamie} 1296191673Sjamie 1297195944Sjamie 1298195944Sjamie 1299195945Sjamie/* This page contains code dealing with common register info and 1300195945Sjamie pseudo copies. */ 1301195945Sjamie 1302195945Sjamie/* The size of the following array. */ 1303195945Sjamiestatic int reg_info_size; 1304192895Sjamie/* Common info about each register. */ 1305195974Sjamiestruct lra_reg *lra_reg_info; 1306195974Sjamie 1307195974Sjamie/* Last register value. */ 1308195974Sjamiestatic int last_reg_value; 1309195974Sjamie 1310195974Sjamie/* Return new register value. */ 1311195974Sjamiestatic int 1312195974Sjamieget_new_reg_value (void) 1313195974Sjamie{ 1314195974Sjamie return ++last_reg_value; 1315195974Sjamie} 1316195974Sjamie 1317195974Sjamie/* Pools for copies. */ 1318195974Sjamiestatic alloc_pool copy_pool; 1319192895Sjamie 1320192895Sjamie/* Vec referring to pseudo copies. */ 1321195974Sjamiestatic vec<lra_copy_t> copy_vec; 1322195974Sjamie 1323195974Sjamie/* Initialize I-th element of lra_reg_info. */ 1324195974Sjamiestatic inline void 1325195974Sjamieinitialize_lra_reg_info_element (int i) 1326195974Sjamie{ 1327195974Sjamie bitmap_initialize (&lra_reg_info[i].insn_bitmap, ®_obstack); 1328195974Sjamie#ifdef STACK_REGS 1329195974Sjamie lra_reg_info[i].no_stack_p = false; 1330195974Sjamie#endif 1331195974Sjamie CLEAR_HARD_REG_SET (lra_reg_info[i].conflict_hard_regs); 1332195974Sjamie CLEAR_HARD_REG_SET (lra_reg_info[i].actual_call_used_reg_set); 1333195974Sjamie lra_reg_info[i].preferred_hard_regno1 = -1; 1334195974Sjamie lra_reg_info[i].preferred_hard_regno2 = -1; 1335192895Sjamie lra_reg_info[i].preferred_hard_regno_profit1 = 0; 1336195945Sjamie lra_reg_info[i].preferred_hard_regno_profit2 = 0; 1337195945Sjamie lra_reg_info[i].biggest_mode = VOIDmode; 1338202468Sbz lra_reg_info[i].live_ranges = NULL; 1339202468Sbz lra_reg_info[i].nrefs = lra_reg_info[i].freq = 0; 1340202468Sbz lra_reg_info[i].last_reload = 0; 1341192895Sjamie lra_reg_info[i].restore_regno = -1; 1342192895Sjamie lra_reg_info[i].val = get_new_reg_value (); 1343196002Sjamie lra_reg_info[i].offset = 0; 1344232059Smm lra_reg_info[i].copies = NULL; 1345191673Sjamie} 1346280632Sian 1347280632Sian/* Initialize common reg info and copies. */ 1348280632Sianstatic void 1349280632Sianinit_reg_info (void) 1350280632Sian{ 1351280632Sian int i; 1352192895Sjamie 1353192895Sjamie last_reg_value = 0; 1354191673Sjamie reg_info_size = max_reg_num () * 3 / 2 + 1; 1355194251Sjamie lra_reg_info = XNEWVEC (struct lra_reg, reg_info_size); 1356194251Sjamie for (i = 0; i < reg_info_size; i++) 1357194251Sjamie initialize_lra_reg_info_element (i); 1358194251Sjamie copy_pool 1359194251Sjamie = create_alloc_pool ("lra copies", sizeof (struct lra_copy), 100); 1360185435Sbz copy_vec.create (100); 1361191673Sjamie} 1362191673Sjamie 1363185435Sbz 1364192895Sjamie/* Finish common reg info and copies. */ 1365191673Sjamiestatic void 1366191673Sjamiefinish_reg_info (void) 1367191673Sjamie{ 1368191673Sjamie int i; 1369185435Sbz 1370191673Sjamie for (i = 0; i < reg_info_size; i++) 1371185435Sbz bitmap_clear (&lra_reg_info[i].insn_bitmap); 1372191673Sjamie free (lra_reg_info); 1373191673Sjamie reg_info_size = 0; 1374191673Sjamie free_alloc_pool (copy_pool); 1375185435Sbz copy_vec.release (); 1376191673Sjamie} 1377191673Sjamie 1378195974Sjamie/* Expand common reg info if it is necessary. */ 1379195974Sjamiestatic void 1380195974Sjamieexpand_reg_info (void) 1381195974Sjamie{ 1382195974Sjamie int i, old = reg_info_size; 1383195945Sjamie 1384195945Sjamie if (reg_info_size > max_reg_num ()) 1385195945Sjamie return; 1386195945Sjamie reg_info_size = max_reg_num () * 3 / 2 + 1; 1387195945Sjamie lra_reg_info = XRESIZEVEC (struct lra_reg, lra_reg_info, reg_info_size); 1388195945Sjamie for (i = old; i < reg_info_size; i++) 1389195945Sjamie initialize_lra_reg_info_element (i); 1390195945Sjamie} 1391195945Sjamie 1392195974Sjamie/* Free all copies. */ 1393195974Sjamievoid 1394195974Sjamielra_free_copies (void) 1395195974Sjamie{ 1396195974Sjamie lra_copy_t cp; 1397195974Sjamie 1398195974Sjamie while (copy_vec.length () != 0) 1399195974Sjamie { 1400195974Sjamie cp = copy_vec.pop (); 1401195974Sjamie lra_reg_info[cp->regno1].copies = lra_reg_info[cp->regno2].copies = NULL; 1402195974Sjamie pool_free (copy_pool, cp); 1403195974Sjamie } 1404195974Sjamie} 1405195974Sjamie 1406195974Sjamie/* Create copy of two pseudos REGNO1 and REGNO2. The copy execution 1407195974Sjamie frequency is FREQ. */ 1408191673Sjamievoid 1409185435Sbzlra_create_copy (int regno1, int regno2, int freq) 1410191673Sjamie{ 1411192895Sjamie bool regno1_dest_p; 1412192895Sjamie lra_copy_t cp; 1413192895Sjamie 1414192895Sjamie lra_assert (regno1 != regno2); 1415192895Sjamie regno1_dest_p = true; 1416192895Sjamie if (regno1 > regno2) 1417194762Sjamie { 1418194762Sjamie int temp = regno2; 1419194762Sjamie 1420194762Sjamie regno1_dest_p = false; 1421194762Sjamie regno2 = regno1; 1422194762Sjamie regno1 = temp; 1423192895Sjamie } 1424192895Sjamie cp = (lra_copy_t) pool_alloc (copy_pool); 1425192895Sjamie copy_vec.safe_push (cp); 1426192895Sjamie cp->regno1_dest_p = regno1_dest_p; 1427192895Sjamie cp->freq = freq; 1428192895Sjamie cp->regno1 = regno1; 1429231267Smm cp->regno2 = regno2; 1430231267Smm cp->regno1_next = lra_reg_info[regno1].copies; 1431231267Smm lra_reg_info[regno1].copies = cp; 1432231267Smm cp->regno2_next = lra_reg_info[regno2].copies; 1433232059Smm lra_reg_info[regno2].copies = cp; 1434231267Smm if (lra_dump_file != NULL) 1435231267Smm fprintf (lra_dump_file, " Creating copy r%d%sr%d@%d\n", 1436231267Smm regno1, regno1_dest_p ? "<-" : "->", regno2, freq); 1437231267Smm} 1438232059Smm 1439231267Smm/* Return N-th (0, 1, ...) copy. If there is no copy, return 1440231267Smm NULL. */ 1441231267Smmlra_copy_t 1442231267Smmlra_get_copy (int n) 1443231267Smm{ 1444232059Smm if (n >= (int) copy_vec.length ()) 1445231267Smm return NULL; 1446231267Smm return copy_vec[n]; 1447231267Smm} 1448185435Sbz 1449195974Sjamie 1450192895Sjamie 1451195974Sjamie/* This page contains code dealing with info about registers in 1452195974Sjamie insns. */ 1453195974Sjamie 1454195974Sjamie/* Process X of insn UID recursively and add info (operand type is 1455195974Sjamie given by TYPE, flag of that it is early clobber is EARLY_CLOBBER) 1456195974Sjamie about registers in X to the insn DATA. */ 1457195974Sjamiestatic void 1458195974Sjamieadd_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid, 1459195974Sjamie enum op_type type, bool early_clobber) 1460195974Sjamie{ 1461195974Sjamie int i, j, regno; 1462195974Sjamie bool subreg_p; 1463195974Sjamie machine_mode mode; 1464195974Sjamie const char *fmt; 1465195974Sjamie enum rtx_code code; 1466195974Sjamie struct lra_insn_reg *curr; 1467195974Sjamie 1468195974Sjamie code = GET_CODE (x); 1469195974Sjamie mode = GET_MODE (x); 1470195974Sjamie subreg_p = false; 1471195974Sjamie if (GET_CODE (x) == SUBREG) 1472195974Sjamie { 1473195974Sjamie x = SUBREG_REG (x); 1474195974Sjamie code = GET_CODE (x); 1475192895Sjamie if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x))) 1476192895Sjamie { 1477192895Sjamie mode = GET_MODE (x); 1478192895Sjamie if (GET_MODE_SIZE (mode) > REGMODE_NATURAL_SIZE (mode)) 1479192895Sjamie subreg_p = true; 1480192895Sjamie } 1481192895Sjamie } 1482195974Sjamie if (REG_P (x)) 1483195974Sjamie { 1484195974Sjamie regno = REGNO (x); 1485195974Sjamie /* Process all regs even unallocatable ones as we need info about 1486195974Sjamie all regs for rematerialization pass. */ 1487195974Sjamie expand_reg_info (); 1488195974Sjamie if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, uid)) 1489195945Sjamie { 1490195974Sjamie data->regs = new_insn_reg (data->insn, regno, type, mode, subreg_p, 1491195974Sjamie early_clobber, data->regs); 1492195974Sjamie return; 1493195945Sjamie } 1494195974Sjamie else 1495195974Sjamie { 1496195945Sjamie for (curr = data->regs; curr != NULL; curr = curr->next) 1497195974Sjamie if (curr->regno == regno) 1498195945Sjamie { 1499195974Sjamie if (curr->subreg_p != subreg_p || curr->biggest_mode != mode) 1500192895Sjamie /* The info can not be integrated into the found 1501195974Sjamie structure. */ 1502195974Sjamie data->regs = new_insn_reg (data->insn, regno, type, mode, 1503195974Sjamie subreg_p, early_clobber, 1504195974Sjamie data->regs); 1505195974Sjamie else 1506195974Sjamie { 1507195974Sjamie if (curr->type != type) 1508195974Sjamie curr->type = OP_INOUT; 1509195974Sjamie if (curr->early_clobber != early_clobber) 1510195974Sjamie curr->early_clobber = true; 1511195974Sjamie } 1512195974Sjamie return; 1513195974Sjamie } 1514195974Sjamie gcc_unreachable (); 1515192895Sjamie } 1516192895Sjamie } 1517192895Sjamie 1518192895Sjamie switch (code) 1519185435Sbz { 1520191673Sjamie case SET: 1521195974Sjamie add_regs_to_insn_regno_info (data, SET_DEST (x), uid, OP_OUT, false); 1522192895Sjamie add_regs_to_insn_regno_info (data, SET_SRC (x), uid, OP_IN, false); 1523195974Sjamie break; 1524195974Sjamie case CLOBBER: 1525195974Sjamie /* We treat clobber of non-operand hard registers as early 1526195974Sjamie clobber (the behavior is expected from asm). */ 1527195974Sjamie add_regs_to_insn_regno_info (data, XEXP (x, 0), uid, OP_OUT, true); 1528195974Sjamie break; 1529195974Sjamie case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC: 1530195974Sjamie add_regs_to_insn_regno_info (data, XEXP (x, 0), uid, OP_INOUT, false); 1531195974Sjamie break; 1532195974Sjamie case PRE_MODIFY: case POST_MODIFY: 1533195974Sjamie add_regs_to_insn_regno_info (data, XEXP (x, 0), uid, OP_INOUT, false); 1534195974Sjamie add_regs_to_insn_regno_info (data, XEXP (x, 1), uid, OP_IN, false); 1535195974Sjamie break; 1536195974Sjamie default: 1537195974Sjamie if ((code != PARALLEL && code != EXPR_LIST) || type != OP_OUT) 1538195974Sjamie /* Some targets place small structures in registers for return 1539195974Sjamie values of functions, and those registers are wrapped in 1540195974Sjamie PARALLEL that we may see as the destination of a SET. Here 1541195974Sjamie is an example: 1542195974Sjamie 1543195974Sjamie (call_insn 13 12 14 2 (set (parallel:BLK [ 1544195974Sjamie (expr_list:REG_DEP_TRUE (reg:DI 0 ax) 1545195974Sjamie (const_int 0 [0])) 1546192895Sjamie (expr_list:REG_DEP_TRUE (reg:DI 1 dx) 1547192895Sjamie (const_int 8 [0x8])) 1548192895Sjamie ]) 1549192895Sjamie (call (mem:QI (symbol_ref:DI (... */ 1550192895Sjamie type = OP_IN; 1551192895Sjamie fmt = GET_RTX_FORMAT (code); 1552192895Sjamie for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 1553195974Sjamie { 1554195974Sjamie if (fmt[i] == 'e') 1555195945Sjamie add_regs_to_insn_regno_info (data, XEXP (x, i), uid, type, false); 1556195974Sjamie else if (fmt[i] == 'E') 1557195974Sjamie { 1558195974Sjamie for (j = XVECLEN (x, i) - 1; j >= 0; j--) 1559195945Sjamie add_regs_to_insn_regno_info (data, XVECEXP (x, i, j), uid, 1560195974Sjamie type, false); 1561195974Sjamie } 1562195945Sjamie } 1563195974Sjamie } 1564195945Sjamie} 1565195974Sjamie 1566192895Sjamie/* Return execution frequency of INSN. */ 1567195974Sjamiestatic int 1568195974Sjamieget_insn_freq (rtx_insn *insn) 1569195974Sjamie{ 1570195974Sjamie basic_block bb = BLOCK_FOR_INSN (insn); 1571195974Sjamie 1572195974Sjamie gcc_checking_assert (bb != NULL); 1573195974Sjamie return REG_FREQ_FROM_BB (bb); 1574195974Sjamie} 1575195974Sjamie 1576195974Sjamie/* Invalidate all reg info of INSN with DATA and execution frequency 1577195974Sjamie FREQ. Update common info about the invalidated registers. */ 1578195974Sjamiestatic void 1579195974Sjamieinvalidate_insn_data_regno_info (lra_insn_recog_data_t data, rtx_insn *insn, 1580195974Sjamie int freq) 1581192895Sjamie{ 1582192895Sjamie int uid; 1583191673Sjamie bool debug_p; 1584192895Sjamie unsigned int i; 1585191673Sjamie struct lra_insn_reg *ir, *next_ir; 1586192895Sjamie 1587192895Sjamie uid = INSN_UID (insn); 1588191673Sjamie debug_p = DEBUG_INSN_P (insn); 1589191673Sjamie for (ir = data->regs; ir != NULL; ir = next_ir) 1590191673Sjamie { 1591196835Sjamie i = ir->regno; 1592196835Sjamie next_ir = ir->next; 1593191673Sjamie free_insn_reg (ir); 1594196835Sjamie bitmap_clear_bit (&lra_reg_info[i].insn_bitmap, uid); 1595196835Sjamie if (i >= FIRST_PSEUDO_REGISTER && ! debug_p) 1596192895Sjamie { 1597191673Sjamie lra_reg_info[i].nrefs--; 1598191673Sjamie lra_reg_info[i].freq -= freq; 1599192895Sjamie lra_assert (lra_reg_info[i].nrefs >= 0 && lra_reg_info[i].freq >= 0); 1600192895Sjamie } 1601191673Sjamie } 1602192895Sjamie data->regs = NULL; 1603192895Sjamie} 1604192895Sjamie 1605192895Sjamie/* Invalidate all reg info of INSN. Update common info about the 1606192895Sjamie invalidated registers. */ 1607192895Sjamievoid 1608192895Sjamielra_invalidate_insn_regno_info (rtx_insn *insn) 1609192895Sjamie{ 1610192895Sjamie invalidate_insn_data_regno_info (lra_get_insn_recog_data (insn), insn, 1611192895Sjamie get_insn_freq (insn)); 1612192895Sjamie} 1613192895Sjamie 1614192895Sjamie/* Update common reg info from reg info of insn given by its DATA and 1615191673Sjamie execution frequency FREQ. */ 1616192895Sjamiestatic void 1617192895Sjamiesetup_insn_reg_info (lra_insn_recog_data_t data, int freq) 1618192895Sjamie{ 1619192895Sjamie unsigned int i; 1620185435Sbz struct lra_insn_reg *ir; 1621191673Sjamie 1622191673Sjamie for (ir = data->regs; ir != NULL; ir = ir->next) 1623192895Sjamie if ((i = ir->regno) >= FIRST_PSEUDO_REGISTER) 1624195974Sjamie { 1625195974Sjamie lra_reg_info[i].nrefs++; 1626195974Sjamie lra_reg_info[i].freq += freq; 1627195974Sjamie } 1628195974Sjamie} 1629195974Sjamie 1630192895Sjamie/* Set up insn reg info of INSN. Update common reg info from reg info 1631195945Sjamie of INSN. */ 1632195945Sjamievoid 1633195945Sjamielra_update_insn_regno_info (rtx_insn *insn) 1634195945Sjamie{ 1635195945Sjamie int i, uid, freq; 1636195945Sjamie lra_insn_recog_data_t data; 1637192895Sjamie struct lra_static_insn_data *static_data; 1638192895Sjamie enum rtx_code code; 1639192895Sjamie rtx link; 1640192895Sjamie 1641192895Sjamie if (! INSN_P (insn)) 1642185435Sbz return; 1643191673Sjamie data = lra_get_insn_recog_data (insn); 1644191673Sjamie static_data = data->insn_static_data; 1645192895Sjamie freq = get_insn_freq (insn); 1646195974Sjamie invalidate_insn_data_regno_info (data, insn, freq); 1647195974Sjamie uid = INSN_UID (insn); 1648195974Sjamie for (i = static_data->n_operands - 1; i >= 0; i--) 1649195974Sjamie add_regs_to_insn_regno_info (data, *data->operand_loc[i], uid, 1650195974Sjamie static_data->operand[i].type, 1651195974Sjamie static_data->operand[i].early_clobber); 1652192895Sjamie if ((code = GET_CODE (PATTERN (insn))) == CLOBBER || code == USE) 1653195945Sjamie add_regs_to_insn_regno_info (data, XEXP (PATTERN (insn), 0), uid, 1654195945Sjamie code == USE ? OP_IN : OP_OUT, false); 1655195945Sjamie if (CALL_P (insn)) 1656195945Sjamie /* On some targets call insns can refer to pseudos in memory in 1657195945Sjamie CALL_INSN_FUNCTION_USAGE list. Process them in order to 1658195945Sjamie consider their occurrences in calls for different 1659192895Sjamie transformations (e.g. inheritance) with given pseudos. */ 1660192895Sjamie for (link = CALL_INSN_FUNCTION_USAGE (insn); 1661192895Sjamie link != NULL_RTX; 1662192895Sjamie link = XEXP (link, 1)) 1663192895Sjamie if (((code = GET_CODE (XEXP (link, 0))) == USE || code == CLOBBER) 1664191673Sjamie && MEM_P (XEXP (XEXP (link, 0), 0))) 1665191673Sjamie add_regs_to_insn_regno_info (data, XEXP (XEXP (link, 0), 0), uid, 1666192895Sjamie code == USE ? OP_IN : OP_OUT, false); 1667191673Sjamie if (NONDEBUG_INSN_P (insn)) 1668192895Sjamie setup_insn_reg_info (data, freq); 1669192895Sjamie} 1670192895Sjamie 1671192895Sjamie/* Return reg info of insn given by it UID. */ 1672192895Sjamiestruct lra_insn_reg * 1673194762Sjamielra_get_insn_regs (int uid) 1674194762Sjamie{ 1675194762Sjamie lra_insn_recog_data_t data; 1676194762Sjamie 1677194762Sjamie data = get_insn_recog_data_by_uid (uid); 1678194762Sjamie return data->regs; 1679194762Sjamie} 1680194762Sjamie 1681192895Sjamie 1682192895Sjamie 1683192895Sjamie/* This page contains code dealing with stack of the insns which 1684192895Sjamie should be processed by the next constraint pass. */ 1685192895Sjamie 1686192895Sjamie/* Bitmap used to put an insn on the stack only in one exemplar. */ 1687192895Sjamiestatic sbitmap lra_constraint_insn_stack_bitmap; 1688231267Smm 1689231267Smm/* The stack itself. */ 1690231267Smmvec<rtx_insn *> lra_constraint_insn_stack; 1691231267Smm 1692232059Smm/* Put INSN on the stack. If ALWAYS_UPDATE is true, always update the reg 1693231267Smm info for INSN, otherwise only update it if INSN is not already on the 1694192895Sjamie stack. */ 1695192895Sjamiestatic inline void 1696192895Sjamielra_push_insn_1 (rtx_insn *insn, bool always_update) 1697192895Sjamie{ 1698192895Sjamie unsigned int uid = INSN_UID (insn); 1699192895Sjamie if (always_update) 1700192895Sjamie lra_update_insn_regno_info (insn); 1701192895Sjamie if (uid >= SBITMAP_SIZE (lra_constraint_insn_stack_bitmap)) 1702192895Sjamie lra_constraint_insn_stack_bitmap = 1703192895Sjamie sbitmap_resize (lra_constraint_insn_stack_bitmap, 3 * uid / 2, 0); 1704192895Sjamie if (bitmap_bit_p (lra_constraint_insn_stack_bitmap, uid)) 1705192895Sjamie return; 1706192895Sjamie bitmap_set_bit (lra_constraint_insn_stack_bitmap, uid); 1707191673Sjamie if (! always_update) 1708192895Sjamie lra_update_insn_regno_info (insn); 1709230129Smm lra_constraint_insn_stack.safe_push (insn); 1710230129Smm} 1711192895Sjamie 1712192895Sjamie/* Put INSN on the stack. */ 1713192895Sjamievoid 1714192895Sjamielra_push_insn (rtx_insn *insn) 1715191673Sjamie{ 1716191673Sjamie lra_push_insn_1 (insn, false); 1717193066Sjamie} 1718193066Sjamie 1719193066Sjamie/* Put INSN on the stack and update its reg info. */ 1720193066Sjamievoid 1721193066Sjamielra_push_insn_and_update_insn_regno_info (rtx_insn *insn) 1722193066Sjamie{ 1723193066Sjamie lra_push_insn_1 (insn, true); 1724193066Sjamie} 1725194118Sjamie 1726194118Sjamie/* Put insn with UID on the stack. */ 1727194118Sjamievoid 1728194118Sjamielra_push_insn_by_uid (unsigned int uid) 1729194118Sjamie{ 1730194118Sjamie lra_push_insn (lra_insn_recog_data[uid]->insn); 1731193066Sjamie} 1732193066Sjamie 1733193066Sjamie/* Take the last-inserted insns off the stack and return it. */ 1734193066Sjamiertx_insn * 1735193066Sjamielra_pop_insn (void) 1736194118Sjamie{ 1737193066Sjamie rtx_insn *insn = lra_constraint_insn_stack.pop (); 1738194118Sjamie bitmap_clear_bit (lra_constraint_insn_stack_bitmap, INSN_UID (insn)); 1739194118Sjamie return insn; 1740193066Sjamie} 1741194118Sjamie 1742193066Sjamie/* Return the current size of the insn stack. */ 1743193066Sjamieunsigned int 1744193066Sjamielra_insn_stack_length (void) 1745193066Sjamie{ 1746193066Sjamie return lra_constraint_insn_stack.length (); 1747193066Sjamie} 1748193066Sjamie 1749194118Sjamie/* Push insns FROM to TO (excluding it) going in reverse order. */ 1750194118Sjamiestatic void 1751194118Sjamiepush_insns (rtx_insn *from, rtx_insn *to) 1752193066Sjamie{ 1753194118Sjamie rtx_insn *insn; 1754194118Sjamie 1755194118Sjamie if (from == NULL_RTX) 1756193066Sjamie return; 1757194118Sjamie for (insn = from; insn != to; insn = PREV_INSN (insn)) 1758194118Sjamie if (INSN_P (insn)) 1759194118Sjamie lra_push_insn (insn); 1760193066Sjamie} 1761193066Sjamie 1762193066Sjamie/* Set up sp offset for insn in range [FROM, LAST]. The offset is 1763193066Sjamie taken from the next BB insn after LAST or zero if there in such 1764193066Sjamie insn. */ 1765192895Sjamiestatic void 1766192895Sjamiesetup_sp_offset (rtx_insn *from, rtx_insn *last) 1767192895Sjamie{ 1768192895Sjamie rtx_insn *before = next_nonnote_insn_bb (last); 1769192895Sjamie HOST_WIDE_INT offset = (before == NULL_RTX || ! INSN_P (before) 1770192895Sjamie ? 0 : lra_get_insn_recog_data (before)->sp_offset); 1771191673Sjamie 1772191673Sjamie for (rtx_insn *insn = from; insn != NEXT_INSN (last); insn = NEXT_INSN (insn)) 1773191673Sjamie lra_get_insn_recog_data (insn)->sp_offset = offset; 1774191673Sjamie} 1775191673Sjamie 1776191673Sjamie/* Emit insns BEFORE before INSN and insns AFTER after INSN. Put the 1777191673Sjamie insns onto the stack. Print about emitting the insns with 1778191673Sjamie TITLE. */ 1779191673Sjamievoid 1780191673Sjamielra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after, 1781191673Sjamie const char *title) 1782191673Sjamie{ 1783191673Sjamie rtx_insn *last; 1784191673Sjamie 1785191673Sjamie if (before == NULL_RTX && after == NULL_RTX) 1786191673Sjamie return; 1787191673Sjamie if (lra_dump_file != NULL) 1788185435Sbz { 1789221362Strasz dump_insn_slim (lra_dump_file, insn); 1790284665Strasz if (before != NULL_RTX) 1791221362Strasz { 1792221362Strasz fprintf (lra_dump_file," %s before:\n", title); 1793221362Strasz dump_rtl_slim (lra_dump_file, before, NULL, -1, 0); 1794192895Sjamie } 1795192895Sjamie if (after != NULL_RTX) 1796192895Sjamie { 1797192895Sjamie fprintf (lra_dump_file, " %s after:\n", title); 1798192895Sjamie dump_rtl_slim (lra_dump_file, after, NULL, -1, 0); 1799192895Sjamie } 1800192895Sjamie fprintf (lra_dump_file, "\n"); 1801192895Sjamie } 1802192895Sjamie if (before != NULL_RTX) 1803192895Sjamie { 1804195945Sjamie if (cfun->can_throw_non_call_exceptions) 1805195945Sjamie copy_reg_eh_region_note_forward (insn, before, NULL); 1806195945Sjamie emit_insn_before (before, insn); 1807195945Sjamie push_insns (PREV_INSN (insn), PREV_INSN (before)); 1808195945Sjamie setup_sp_offset (before, PREV_INSN (insn)); 1809195945Sjamie } 1810192895Sjamie if (after != NULL_RTX) 1811192895Sjamie { 1812192895Sjamie if (cfun->can_throw_non_call_exceptions) 1813192895Sjamie copy_reg_eh_region_note_forward (insn, after, NULL); 1814192895Sjamie for (last = after; NEXT_INSN (last) != NULL_RTX; last = NEXT_INSN (last)) 1815192895Sjamie ; 1816192895Sjamie emit_insn_after (after, insn); 1817192895Sjamie push_insns (last, insn); 1818192895Sjamie setup_sp_offset (after, last); 1819192895Sjamie } 1820192895Sjamie if (cfun->can_throw_non_call_exceptions) 1821192895Sjamie { 1822192895Sjamie rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); 1823192895Sjamie if (note && !insn_could_throw_p (insn)) 1824192895Sjamie remove_note (insn, note); 1825192895Sjamie } 1826192895Sjamie} 1827195945Sjamie 1828195945Sjamie 1829195945Sjamie/* Replace all references to register OLD_REGNO in *LOC with pseudo 1830195945Sjamie register NEW_REG. Try to simplify subreg of constant if SUBREG_P. 1831195945Sjamie Return true if any change was made. */ 1832195945Sjamiebool 1833192895Sjamielra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg, bool subreg_p) 1834192895Sjamie{ 1835192895Sjamie rtx x = *loc; 1836192895Sjamie bool result = false; 1837192895Sjamie enum rtx_code code; 1838192895Sjamie const char *fmt; 1839192895Sjamie int i, j; 1840192895Sjamie 1841192895Sjamie if (x == NULL_RTX) 1842192895Sjamie return false; 1843192895Sjamie 1844191673Sjamie code = GET_CODE (x); 1845191673Sjamie if (code == SUBREG && subreg_p) 1846191673Sjamie { 1847191673Sjamie rtx subst, inner = SUBREG_REG (x); 1848191673Sjamie /* Transform subreg of constant while we still have inner mode 1849191673Sjamie of the subreg. The subreg internal should not be an insn 1850191673Sjamie operand. */ 1851191673Sjamie if (REG_P (inner) && (int) REGNO (inner) == old_regno 1852191673Sjamie && CONSTANT_P (new_reg) 1853191673Sjamie && (subst = simplify_subreg (GET_MODE (x), new_reg, GET_MODE (inner), 1854191673Sjamie SUBREG_BYTE (x))) != NULL_RTX) 1855191673Sjamie { 1856191673Sjamie *loc = subst; 1857191673Sjamie return true; 1858191673Sjamie } 1859191673Sjamie 1860191673Sjamie } 1861191673Sjamie else if (code == REG && (int) REGNO (x) == old_regno) 1862191673Sjamie { 1863191673Sjamie machine_mode mode = GET_MODE (x); 1864191673Sjamie machine_mode inner_mode = GET_MODE (new_reg); 1865191673Sjamie 1866191673Sjamie if (mode != inner_mode 1867191673Sjamie && ! (CONST_INT_P (new_reg) && SCALAR_INT_MODE_P (mode))) 1868191673Sjamie { 1869191673Sjamie if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (inner_mode) 1870191673Sjamie || ! SCALAR_INT_MODE_P (inner_mode)) 1871191673Sjamie new_reg = gen_rtx_SUBREG (mode, new_reg, 0); 1872191673Sjamie else 1873235803Strasz new_reg = gen_lowpart_SUBREG (mode, new_reg); 1874284665Strasz } 1875271622Strasz *loc = new_reg; 1876271622Strasz return true; 1877235803Strasz } 1878271622Strasz 1879271622Strasz /* Scan all the operand sub-expressions. */ 1880235803Strasz fmt = GET_RTX_FORMAT (code); 1881235803Strasz for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 1882235803Strasz { 1883235803Strasz if (fmt[i] == 'e') 1884235803Strasz { 1885191673Sjamie if (lra_substitute_pseudo (&XEXP (x, i), old_regno, 1886191673Sjamie new_reg, subreg_p)) 1887191673Sjamie result = true; 1888191673Sjamie } 1889191673Sjamie else if (fmt[i] == 'E') 1890191673Sjamie { 1891191673Sjamie for (j = XVECLEN (x, i) - 1; j >= 0; j--) 1892191673Sjamie if (lra_substitute_pseudo (&XVECEXP (x, i, j), old_regno, 1893191673Sjamie new_reg, subreg_p)) 1894191673Sjamie result = true; 1895191673Sjamie } 1896191673Sjamie } 1897191673Sjamie return result; 1898191673Sjamie} 1899191673Sjamie 1900191673Sjamie/* Call lra_substitute_pseudo within an insn. Try to simplify subreg 1901191673Sjamie of constant if SUBREG_P. This won't update the insn ptr, just the 1902191673Sjamie contents of the insn. */ 1903191673Sjamiebool 1904191673Sjamielra_substitute_pseudo_within_insn (rtx_insn *insn, int old_regno, 1905232598Strasz rtx new_reg, bool subreg_p) 1906191673Sjamie{ 1907191673Sjamie rtx loc = insn; 1908192895Sjamie return lra_substitute_pseudo (&loc, old_regno, new_reg, subreg_p); 1909192895Sjamie} 1910192895Sjamie 1911192895Sjamie 1912192895Sjamie 1913191673Sjamie/* This page contains code dealing with scratches (changing them onto 1914191673Sjamie pseudos and restoring them from the pseudos). 1915191673Sjamie 1916241896Skib We change scratches into pseudos at the beginning of LRA to 1917191673Sjamie simplify dealing with them (conflicts, hard register assignments). 1918191673Sjamie 1919191673Sjamie If the pseudo denoting scratch was spilled it means that we do need 1920191673Sjamie a hard register for it. Such pseudos are transformed back to 1921191673Sjamie scratches at the end of LRA. */ 1922191673Sjamie 1923191673Sjamie/* Description of location of a former scratch operand. */ 1924191673Sjamiestruct sloc 1925191673Sjamie{ 1926191673Sjamie rtx_insn *insn; /* Insn where the scratch was. */ 1927191673Sjamie int nop; /* Number of the operand which was a scratch. */ 1928191673Sjamie}; 1929191673Sjamie 1930191673Sjamietypedef struct sloc *sloc_t; 1931191673Sjamie 1932191673Sjamie/* Locations of the former scratches. */ 1933191673Sjamiestatic vec<sloc_t> scratches; 1934191673Sjamie 1935191673Sjamie/* Bitmap of scratch regnos. */ 1936191673Sjamiestatic bitmap_head scratch_bitmap; 1937191673Sjamie 1938191673Sjamie/* Bitmap of scratch operands. */ 1939191673Sjamiestatic bitmap_head scratch_operand_bitmap; 1940191673Sjamie 1941191673Sjamie/* Return true if pseudo REGNO is made of SCRATCH. */ 1942230407Smmbool 1943230407Smmlra_former_scratch_p (int regno) 1944191673Sjamie{ 1945191673Sjamie return bitmap_bit_p (&scratch_bitmap, regno); 1946191673Sjamie} 1947191673Sjamie 1948191673Sjamie/* Return true if the operand NOP of INSN is a former scratch. */ 194982710Sdillonbool 1950191673Sjamielra_former_scratch_operand_p (rtx_insn *insn, int nop) 1951191673Sjamie{ 1952191673Sjamie return bitmap_bit_p (&scratch_operand_bitmap, 1953191673Sjamie INSN_UID (insn) * MAX_RECOG_OPERANDS + nop) != 0; 1954114168Smike} 195582710Sdillon 195646155Sphk/* Register operand NOP in INSN as a former scratch. It will be 1957225617Skmacy changed to scratch back, if it is necessary, at the LRA end. */ 195846155Sphkvoid 1959191673Sjamielra_register_new_scratch_op (rtx_insn *insn, int nop) 1960185435Sbz{ 1961185435Sbz lra_insn_recog_data_t id = lra_get_insn_recog_data (insn); 1962191673Sjamie rtx op = *id->operand_loc[nop]; 1963191673Sjamie sloc_t loc = XNEW (struct sloc); 1964191673Sjamie lra_assert (REG_P (op)); 1965191673Sjamie loc->insn = insn; 1966191673Sjamie loc->nop = nop; 1967185435Sbz scratches.safe_push (loc); 1968185435Sbz bitmap_set_bit (&scratch_bitmap, REGNO (op)); 1969191673Sjamie bitmap_set_bit (&scratch_operand_bitmap, 1970191673Sjamie INSN_UID (insn) * MAX_RECOG_OPERANDS + nop); 1971191673Sjamie add_reg_note (insn, REG_UNUSED, op); 1972191673Sjamie} 1973191673Sjamie 1974191673Sjamie/* Change scratches onto pseudos and save their location. */ 1975191673Sjamiestatic void 1976185435Sbzremove_scratches (void) 1977191673Sjamie{ 1978191673Sjamie int i; 1979191673Sjamie bool insn_changed_p; 1980192895Sjamie basic_block bb; 1981191673Sjamie rtx_insn *insn; 1982191673Sjamie rtx reg; 1983191673Sjamie lra_insn_recog_data_t id; 1984192895Sjamie struct lra_static_insn_data *static_id; 1985185435Sbz 1986191673Sjamie scratches.create (get_max_uid ()); 1987191673Sjamie bitmap_initialize (&scratch_bitmap, ®_obstack); 1988185435Sbz bitmap_initialize (&scratch_operand_bitmap, ®_obstack); 1989191673Sjamie FOR_EACH_BB_FN (bb, cfun) 1990191673Sjamie FOR_BB_INSNS (bb, insn) 1991191673Sjamie if (INSN_P (insn)) 1992191673Sjamie { 1993191673Sjamie id = lra_get_insn_recog_data (insn); 1994192895Sjamie static_id = id->insn_static_data; 1995185435Sbz insn_changed_p = false; 1996191673Sjamie for (i = 0; i < static_id->n_operands; i++) 1997191673Sjamie if (GET_CODE (*id->operand_loc[i]) == SCRATCH 1998191673Sjamie && GET_MODE (*id->operand_loc[i]) != VOIDmode) 1999191673Sjamie { 2000191673Sjamie insn_changed_p = true; 2001191673Sjamie *id->operand_loc[i] = reg 2002191673Sjamie = lra_create_new_reg (static_id->operand[i].mode, 2003192895Sjamie *id->operand_loc[i], ALL_REGS, NULL); 2004191673Sjamie lra_register_new_scratch_op (insn, i); 2005191673Sjamie if (lra_dump_file != NULL) 2006191673Sjamie fprintf (lra_dump_file, 2007191673Sjamie "Removing SCRATCH in insn #%u (nop %d)\n", 2008191673Sjamie INSN_UID (insn), i); 2009191673Sjamie } 2010191673Sjamie if (insn_changed_p) 2011191673Sjamie /* Because we might use DF right after caller-saves sub-pass 2012191673Sjamie we need to keep DF info up to date. */ 2013191673Sjamie df_insn_rescan (insn); 2014191673Sjamie } 2015191673Sjamie} 2016191673Sjamie 2017191673Sjamie/* Changes pseudos created by function remove_scratches onto scratches. */ 2018185435Sbzstatic void 2019191673Sjamierestore_scratches (void) 2020191673Sjamie{ 2021191673Sjamie int regno; 2022192895Sjamie unsigned i; 2023191673Sjamie sloc_t loc; 2024191673Sjamie rtx_insn *last = NULL; 2025191673Sjamie lra_insn_recog_data_t id = NULL; 2026191673Sjamie 2027191673Sjamie for (i = 0; scratches.iterate (i, &loc); i++) 2028191673Sjamie { 2029191673Sjamie if (last != loc->insn) 2030191673Sjamie { 2031191673Sjamie last = loc->insn; 2032191673Sjamie id = lra_get_insn_recog_data (last); 2033191673Sjamie } 2034191673Sjamie if (REG_P (*id->operand_loc[loc->nop]) 2035191673Sjamie && ((regno = REGNO (*id->operand_loc[loc->nop])) 2036191673Sjamie >= FIRST_PSEUDO_REGISTER) 2037191673Sjamie && lra_get_regno_hard_regno (regno) < 0) 2038191673Sjamie { 203946155Sphk /* It should be only case when scratch register with chosen 2040191673Sjamie constraint 'X' did not get memory or hard register. */ 2041191673Sjamie lra_assert (lra_former_scratch_p (regno)); 2042191673Sjamie *id->operand_loc[loc->nop] 2043191673Sjamie = gen_rtx_SCRATCH (GET_MODE (*id->operand_loc[loc->nop])); 2044191673Sjamie lra_update_dup (id, loc->nop); 2045191673Sjamie if (lra_dump_file != NULL) 2046192895Sjamie fprintf (lra_dump_file, "Restoring SCRATCH in insn #%u(nop %d)\n", 2047191673Sjamie INSN_UID (loc->insn), loc->nop); 2048191673Sjamie } 2049191673Sjamie } 2050191673Sjamie for (i = 0; scratches.iterate (i, &loc); i++) 2051191673Sjamie free (loc); 2052191673Sjamie scratches.release (); 2053191673Sjamie bitmap_clear (&scratch_bitmap); 2054191673Sjamie bitmap_clear (&scratch_operand_bitmap); 2055191673Sjamie} 2056191673Sjamie 2057191673Sjamie 2058191673Sjamie 2059191673Sjamie#ifdef ENABLE_CHECKING 2060191673Sjamie 2061191673Sjamie/* Function checks RTL for correctness. If FINAL_P is true, it is 2062185435Sbz done at the end of LRA and the check is more rigorous. */ 2063191673Sjamiestatic void 2064191673Sjamiecheck_rtl (bool final_p) 2065191673Sjamie{ 2066191673Sjamie basic_block bb; 2067191673Sjamie rtx_insn *insn; 2068191673Sjamie 2069191673Sjamie lra_assert (! final_p || reload_completed); 2070191673Sjamie FOR_EACH_BB_FN (bb, cfun) 2071191673Sjamie FOR_BB_INSNS (bb, insn) 2072191673Sjamie if (NONDEBUG_INSN_P (insn) 2073191673Sjamie && GET_CODE (PATTERN (insn)) != USE 2074191673Sjamie && GET_CODE (PATTERN (insn)) != CLOBBER 2075192895Sjamie && GET_CODE (PATTERN (insn)) != ASM_INPUT) 2076192895Sjamie { 2077191673Sjamie if (final_p) 2078191673Sjamie { 2079192895Sjamie#ifdef ENABLED_CHECKING 2080192895Sjamie extract_constrain_insn (insn); 2081192895Sjamie#endif 2082192895Sjamie continue; 2083191673Sjamie } 2084191673Sjamie /* LRA code is based on assumption that all addresses can be 2085191673Sjamie correctly decomposed. LRA can generate reloads for 2086192895Sjamie decomposable addresses. The decomposition code checks the 2087191673Sjamie correctness of the addresses. So we don't need to check 2088191673Sjamie the addresses here. Don't call insn_invalid_p here, it can 2089191673Sjamie change the code at this stage. */ 2090191673Sjamie if (recog_memoized (insn) < 0 && asm_noperands (PATTERN (insn)) < 0) 2091191673Sjamie fatal_insn_not_found (insn); 2092191673Sjamie } 2093191673Sjamie} 2094191673Sjamie#endif /* #ifdef ENABLE_CHECKING */ 2095191673Sjamie 2096191673Sjamie/* Determine if the current function has an exception receiver block 2097191673Sjamie that reaches the exit block via non-exceptional edges */ 2098191673Sjamiestatic bool 2099191673Sjamiehas_nonexceptional_receiver (void) 2100191673Sjamie{ 2101191673Sjamie edge e; 2102191673Sjamie edge_iterator ei; 2103191673Sjamie basic_block *tos, *worklist, bb; 2104191673Sjamie 2105194762Sjamie /* If we're not optimizing, then just err on the safe side. */ 2106194762Sjamie if (!optimize) 2107194762Sjamie return true; 2108194762Sjamie 2109194762Sjamie /* First determine which blocks can reach exit via normal paths. */ 2110194762Sjamie tos = worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun) + 1); 2111194762Sjamie 2112194762Sjamie FOR_EACH_BB_FN (bb, cfun) 2113194118Sjamie bb->flags &= ~BB_REACHABLE; 2114191673Sjamie 2115191673Sjamie /* Place the exit block on our worklist. */ 2116194118Sjamie EXIT_BLOCK_PTR_FOR_FN (cfun)->flags |= BB_REACHABLE; 2117193066Sjamie *tos++ = EXIT_BLOCK_PTR_FOR_FN (cfun); 2118193066Sjamie 2119194118Sjamie /* Iterate: find everything reachable from what we've already seen. */ 2120193066Sjamie while (tos != worklist) 2121193066Sjamie { 2122205014Snwhitehorn bb = *--tos; 2123217896Sdchagin 2124193066Sjamie FOR_EACH_EDGE (e, ei, bb->preds) 2125193066Sjamie if (e->flags & EDGE_ABNORMAL) 2126193066Sjamie { 2127193066Sjamie free (worklist); 2128193066Sjamie return true; 2129193066Sjamie } 2130193066Sjamie else 2131193066Sjamie { 2132193066Sjamie basic_block src = e->src; 2133192895Sjamie 2134192895Sjamie if (!(src->flags & BB_REACHABLE)) 2135191673Sjamie { 2136191673Sjamie src->flags |= BB_REACHABLE; 2137231267Smm *tos++ = src; 2138231267Smm } 2139231267Smm } 2140231267Smm } 2141192895Sjamie free (worklist); 2142192895Sjamie /* No exceptional block reached exit unexceptionally. */ 2143192895Sjamie return false; 2144192895Sjamie} 2145192895Sjamie 2146192895Sjamie#ifdef AUTO_INC_DEC 2147192895Sjamie 2148192895Sjamie/* Process recursively X of INSN and add REG_INC notes if necessary. */ 2149192895Sjamiestatic void 2150192895Sjamieadd_auto_inc_notes (rtx_insn *insn, rtx x) 2151192895Sjamie{ 2152192895Sjamie enum rtx_code code = GET_CODE (x); 2153192895Sjamie const char *fmt; 2154195870Sjamie int i, j; 2155195870Sjamie 2156195870Sjamie if (code == MEM && auto_inc_p (XEXP (x, 0))) 2157195870Sjamie { 2158195870Sjamie add_reg_note (insn, REG_INC, XEXP (XEXP (x, 0), 0)); 2159195870Sjamie return; 2160195870Sjamie } 2161195870Sjamie 2162195870Sjamie /* Scan all X sub-expressions. */ 2163195870Sjamie fmt = GET_RTX_FORMAT (code); 2164195870Sjamie for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 2165195870Sjamie { 2166195870Sjamie if (fmt[i] == 'e') 2167192895Sjamie add_auto_inc_notes (insn, XEXP (x, i)); 2168192895Sjamie else if (fmt[i] == 'E') 2169192895Sjamie for (j = XVECLEN (x, i) - 1; j >= 0; j--) 2170192895Sjamie add_auto_inc_notes (insn, XVECEXP (x, i, j)); 2171192895Sjamie } 2172192895Sjamie} 2173192895Sjamie 2174192895Sjamie#endif 2175192895Sjamie 2176192895Sjamie/* Remove all REG_DEAD and REG_UNUSED notes and regenerate REG_INC. 2177192895Sjamie We change pseudos by hard registers without notification of DF and 2178192895Sjamie that can make the notes obsolete. DF-infrastructure does not deal 2179192895Sjamie with REG_INC notes -- so we should regenerate them here. */ 2180191673Sjamiestatic void 2181191673Sjamieupdate_inc_notes (void) 2182191673Sjamie{ 2183191673Sjamie rtx *pnote; 2184191673Sjamie basic_block bb; 2185191673Sjamie rtx_insn *insn; 2186191673Sjamie 2187191673Sjamie FOR_EACH_BB_FN (bb, cfun) 2188280632Sian FOR_BB_INSNS (bb, insn) 2189280632Sian if (NONDEBUG_INSN_P (insn)) 2190280632Sian { 2191280632Sian pnote = ®_NOTES (insn); 2192280632Sian while (*pnote != 0) 2193280632Sian { 2194280632Sian if (REG_NOTE_KIND (*pnote) == REG_DEAD 2195191673Sjamie || REG_NOTE_KIND (*pnote) == REG_UNUSED 2196191673Sjamie || REG_NOTE_KIND (*pnote) == REG_INC) 2197191673Sjamie *pnote = XEXP (*pnote, 1); 2198191673Sjamie else 2199191673Sjamie pnote = &XEXP (*pnote, 1); 220046155Sphk } 2201191673Sjamie#ifdef AUTO_INC_DEC 2202191673Sjamie add_auto_inc_notes (insn, PATTERN (insn)); 220384828Sjhb#endif 2204191673Sjamie } 2205191673Sjamie} 2206191673Sjamie 2207191673Sjamie/* Set to 1 while in lra. */ 2208191673Sjamieint lra_in_progress; 2209191673Sjamie 2210191673Sjamie/* Start of pseudo regnos before the LRA. */ 2211185435Sbzint lra_new_regno_start; 2212191673Sjamie 2213191673Sjamie/* Start of reload pseudo regnos before the new spill pass. */ 2214191673Sjamieint lra_constraint_new_regno_start; 2215191673Sjamie 2216191673Sjamie/* Avoid spilling pseudos with regno more than the following value if 2217191673Sjamie it is possible. */ 2218191673Sjamieint lra_bad_spill_regno_start; 2219191673Sjamie 2220191673Sjamie/* Inheritance pseudo regnos before the new spill pass. */ 2221191673Sjamiebitmap_head lra_inheritance_pseudos; 2222191673Sjamie 2223191673Sjamie/* Split regnos before the new spill pass. */ 2224191673Sjamiebitmap_head lra_split_regs; 2225191673Sjamie 2226191673Sjamie/* Reload pseudo regnos before the new assignmnet pass which still can 2227191673Sjamie be spilled after the assinment pass as memory is also accepted in 2228191673Sjamie insns for the reload pseudos. */ 2229191673Sjamiebitmap_head lra_optional_reload_pseudos; 2230191673Sjamie 2231191673Sjamie/* Pseudo regnos used for subreg reloads before the new assignment 2232191673Sjamie pass. Such pseudos still can be spilled after the assinment 2233185435Sbz pass. */ 2234191673Sjamiebitmap_head lra_subreg_reload_pseudos; 2235191673Sjamie 2236191673Sjamie/* File used for output of LRA debug information. */ 2237191673SjamieFILE *lra_dump_file; 2238191673Sjamie 2239191673Sjamie/* True if we should try spill into registers of different classes 2240191673Sjamie instead of memory. */ 2241191673Sjamiebool lra_reg_spill_p; 2242191673Sjamie 2243191673Sjamie/* Set up value LRA_REG_SPILL_P. */ 2244191673Sjamiestatic void 2245191673Sjamiesetup_reg_spill_flag (void) 2246191673Sjamie{ 2247191673Sjamie int cl, mode; 2248191673Sjamie 2249191673Sjamie if (targetm.spill_class != NULL) 2250191673Sjamie for (cl = 0; cl < (int) LIM_REG_CLASSES; cl++) 2251191673Sjamie for (mode = 0; mode < MAX_MACHINE_MODE; mode++) 2252191673Sjamie if (targetm.spill_class ((enum reg_class) cl, 2253191673Sjamie (machine_mode) mode) != NO_REGS) 2254191673Sjamie { 2255191673Sjamie lra_reg_spill_p = true; 2256185435Sbz return; 2257191673Sjamie } 2258191673Sjamie lra_reg_spill_p = false; 2259191673Sjamie} 2260113275Smike 2261192895Sjamie/* True if the current function is too big to use regular algorithms 2262191673Sjamie in LRA. In other words, we should use simpler and faster algorithms 2263191673Sjamie in LRA. It also means we should not worry about generation code 2264191673Sjamie for caller saves. The value is set up in IRA. */ 2265191673Sjamiebool lra_simple_p; 2266191673Sjamie 2267191673Sjamie/* Major LRA entry function. F is a file should be used to dump LRA 2268225617Skmacy debug info. */ 2269191673Sjamievoid 2270192895Sjamielra (FILE *f) 2271192895Sjamie{ 2272185435Sbz int i; 2273191673Sjamie bool live_p, scratch_p, inserted_p; 2274185435Sbz 2275191673Sjamie lra_dump_file = f; 2276185435Sbz 2277185435Sbz timevar_push (TV_LRA); 2278192895Sjamie 2279191673Sjamie /* Make sure that the last insn is a note. Some subsequent passes 2280185435Sbz need it. */ 2281191673Sjamie emit_note (NOTE_INSN_DELETED); 2282185435Sbz 2283185435Sbz COPY_HARD_REG_SET (lra_no_alloc_regs, ira_no_alloc_regs); 2284192895Sjamie 2285192895Sjamie init_reg_info (); 2286192895Sjamie expand_reg_info (); 2287192895Sjamie 2288192895Sjamie init_insn_recog_data (); 2289192895Sjamie 2290192895Sjamie#ifdef ENABLE_CHECKING 2291192895Sjamie /* Some quick check on RTL generated by previous passes. */ 2292192895Sjamie check_rtl (false); 2293192895Sjamie#endif 2294192895Sjamie 2295192895Sjamie lra_in_progress = 1; 2296192895Sjamie 2297192895Sjamie lra_live_range_iter = lra_coalesce_iter = lra_constraint_iter = 0; 2298192895Sjamie lra_assignment_iter = lra_assignment_iter_after_spill = 0; 2299192895Sjamie lra_inheritance_iter = lra_undo_inheritance_iter = 0; 2300192895Sjamie lra_rematerialization_iter = 0; 2301192895Sjamie 2302192895Sjamie setup_reg_spill_flag (); 2303192895Sjamie 2304192895Sjamie /* Function remove_scratches can creates new pseudos for clobbers -- 2305192895Sjamie so set up lra_constraint_new_regno_start before its call to 2306192895Sjamie permit changing reg classes for pseudos created by this 2307192895Sjamie simplification. */ 2308192895Sjamie lra_constraint_new_regno_start = lra_new_regno_start = max_reg_num (); 2309192895Sjamie lra_bad_spill_regno_start = INT_MAX; 2310192895Sjamie remove_scratches (); 2311192895Sjamie scratch_p = lra_constraint_new_regno_start != max_reg_num (); 2312192895Sjamie 2313192895Sjamie /* A function that has a non-local label that can reach the exit 2314192895Sjamie block via non-exceptional paths must save all call-saved 2315192895Sjamie registers. */ 2316192895Sjamie if (cfun->has_nonlocal_label && has_nonexceptional_receiver ()) 2317192895Sjamie crtl->saves_all_registers = 1; 2318192895Sjamie 2319192895Sjamie if (crtl->saves_all_registers) 2320192895Sjamie for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 2321192895Sjamie if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i)) 2322192895Sjamie df_set_regs_ever_live (i, true); 2323192895Sjamie 2324192895Sjamie /* We don't DF from now and avoid its using because it is to 2325191673Sjamie expensive when a lot of RTL changes are made. */ 2326191673Sjamie df_set_flags (DF_NO_INSN_RESCAN); 2327191673Sjamie lra_constraint_insn_stack.create (get_max_uid ()); 2328191673Sjamie lra_constraint_insn_stack_bitmap = sbitmap_alloc (get_max_uid ()); 2329191673Sjamie bitmap_clear (lra_constraint_insn_stack_bitmap); 2330191673Sjamie lra_live_ranges_init (); 2331179881Sdelphij lra_constraints_init (); 2332113275Smike lra_curr_reload_num = 0; 2333192895Sjamie push_insns (get_last_insn (), NULL); 2334192895Sjamie /* It is needed for the 1st coalescing. */ 2335192895Sjamie bitmap_initialize (&lra_inheritance_pseudos, ®_obstack); 2336192895Sjamie bitmap_initialize (&lra_split_regs, ®_obstack); 2337192895Sjamie bitmap_initialize (&lra_optional_reload_pseudos, ®_obstack); 2338192895Sjamie bitmap_initialize (&lra_subreg_reload_pseudos, ®_obstack); 2339192895Sjamie live_p = false; 2340191673Sjamie if (get_frame_size () != 0 && crtl->stack_alignment_needed) 2341191673Sjamie /* If we have a stack frame, we must align it now. The stack size 2342192895Sjamie may be a part of the offset computation for register 2343191673Sjamie elimination. */ 2344191673Sjamie assign_stack_local (BLKmode, 0, crtl->stack_alignment_needed); 2345113275Smike lra_init_equiv (); 2346191673Sjamie for (;;) 2347191673Sjamie { 2348191673Sjamie for (;;) 2349191673Sjamie { 2350191673Sjamie /* We should try to assign hard registers to scratches even 2351191673Sjamie if there were no RTL transformations in 2352191673Sjamie lra_constraints. */ 2353191673Sjamie if (! lra_constraints (lra_constraint_iter == 0) 2354191673Sjamie && (lra_constraint_iter > 1 2355225617Skmacy || (! scratch_p && ! caller_save_needed))) 2356191673Sjamie break; 2357191673Sjamie /* Constraint transformations may result in that eliminable 2358191673Sjamie hard regs become uneliminable and pseudos which use them 2359192895Sjamie should be spilled. It is better to do it before pseudo 2360191673Sjamie assignments. 2361113275Smike 2362113275Smike For example, rs6000 can make 2363190466Sjamie RS6000_PIC_OFFSET_TABLE_REGNUM uneliminable if we started 2364113275Smike to use a constant pool. */ 2365114168Smike lra_eliminate (false, false); 2366114168Smike /* Do inheritance only for regular algorithms. */ 2367114168Smike if (! lra_simple_p) 2368113275Smike { 2369113275Smike if (flag_ipa_ra) 2370225617Skmacy { 2371113275Smike if (live_p) 2372113275Smike lra_clear_live_ranges (); 2373191673Sjamie /* As a side-effect of lra_create_live_ranges, we calculate 2374167309Spjd actual_call_used_reg_set, which is needed during 2375164032Srwatson lra_inheritance. */ 2376126023Snectar lra_create_live_ranges (true, true); 2377126023Snectar live_p = true; 2378126023Snectar } 2379168401Spjd lra_inheritance (); 2380192895Sjamie } 2381113275Smike if (live_p) 2382168401Spjd lra_clear_live_ranges (); 2383113275Smike /* We need live ranges for lra_assign -- so build them. But 2384113275Smike don't remove dead insns or change global live info as we 2385185435Sbz can undo inheritance transformations after inheritance 2386185435Sbz pseudo assigning. */ 2387185435Sbz lra_create_live_ranges (true, false); 2388191673Sjamie live_p = true; 2389185435Sbz /* If we don't spill non-reload and non-inheritance pseudos, 2390191673Sjamie there is no sense to run memory-memory move coalescing. 2391185435Sbz If inheritance pseudos were spilled, the memory-memory 2392185435Sbz moves involving them will be removed by pass undoing 2393185435Sbz inheritance. */ 2394185435Sbz if (lra_simple_p) 2395191673Sjamie lra_assign (); 2396191673Sjamie else 2397191673Sjamie { 2398191673Sjamie bool spill_p = !lra_assign (); 2399191673Sjamie 2400191673Sjamie if (lra_undo_inheritance ()) 2401191673Sjamie live_p = false; 2402192895Sjamie if (spill_p) 2403191673Sjamie { 2404191673Sjamie if (! live_p) 2405241896Skib { 2406191673Sjamie lra_create_live_ranges (true, true); 2407191673Sjamie live_p = true; 2408191673Sjamie } 2409191673Sjamie if (lra_coalesce ()) 2410191673Sjamie live_p = false; 2411191673Sjamie } 2412191673Sjamie if (! live_p) 2413191673Sjamie lra_clear_live_ranges (); 2414191673Sjamie } 2415113275Smike } 2416191673Sjamie /* Don't clear optional reloads bitmap until all constraints are 2417113275Smike satisfied as we need to differ them from regular reloads. */ 2418191673Sjamie bitmap_clear (&lra_optional_reload_pseudos); 2419191673Sjamie bitmap_clear (&lra_subreg_reload_pseudos); 2420191673Sjamie bitmap_clear (&lra_inheritance_pseudos); 2421191673Sjamie bitmap_clear (&lra_split_regs); 2422191673Sjamie if (! live_p) 2423191673Sjamie { 2424191673Sjamie /* We need full live info for spilling pseudos into 2425168401Spjd registers instead of memory. */ 2426113275Smike lra_create_live_ranges (lra_reg_spill_p, true); 2427185435Sbz live_p = true; 2428185435Sbz } 2429185435Sbz /* We should check necessity for spilling here as the above live 2430192895Sjamie range pass can remove spilled pseudos. */ 2431191673Sjamie if (! lra_need_for_spills_p ()) 2432185435Sbz break; 2433185435Sbz /* Now we know what pseudos should be spilled. Try to 2434191673Sjamie rematerialize them first. */ 2435185435Sbz if (lra_remat ()) 2436175202Sattilio { 2437113275Smike /* We need full live info -- see the comment above. */ 2438113275Smike lra_create_live_ranges (lra_reg_spill_p, true); 2439113275Smike live_p = true; 2440172930Srwatson if (! lra_need_for_spills_p ()) 2441113275Smike break; 2442113275Smike } 2443175294Sattilio lra_spill (); 2444191673Sjamie /* Assignment of stack slots changes elimination offsets for 2445241896Skib some eliminations. So update the offsets here. */ 2446113275Smike lra_eliminate (false, false); 244784828Sjhb lra_constraint_new_regno_start = max_reg_num (); 244884828Sjhb if (lra_bad_spill_regno_start == INT_MAX 244984828Sjhb && lra_inheritance_iter > LRA_MAX_INHERITANCE_PASSES 2450113275Smike && lra_rematerialization_iter > LRA_MAX_REMATERIALIZATION_PASSES) 245184828Sjhb /* After switching off inheritance and rematerialization 2452113630Sjhb passes, avoid spilling reload pseudos will be created to 245384828Sjhb prevent LRA cycling in some complicated cases. */ 245484828Sjhb lra_bad_spill_regno_start = lra_constraint_new_regno_start; 2455220137Strasz lra_assignment_iter_after_spill = 0; 2456220137Strasz } 2457220137Strasz restore_scratches (); 245884828Sjhb lra_eliminate (true, false); 2459192895Sjamie lra_final_code_change (); 246046155Sphk lra_in_progress = 0; 2461191673Sjamie if (live_p) 2462175294Sattilio lra_clear_live_ranges (); 2463191673Sjamie lra_live_ranges_finish (); 2464191673Sjamie lra_constraints_finish (); 2465192895Sjamie finish_reg_info (); 2466191673Sjamie sbitmap_free (lra_constraint_insn_stack_bitmap); 246746155Sphk lra_constraint_insn_stack.release (); 246846155Sphk finish_insn_recog_data (); 246946155Sphk regstat_free_n_sets_and_refs (); 2470192895Sjamie regstat_free_ri (); 2471113275Smike reload_completed = 1; 2472113275Smike update_inc_notes (); 2473113275Smike 2474168399Spjd inserted_p = fixup_abnormal_edges (); 2475113275Smike 2476113275Smike /* We've possibly turned single trapping insn into multiple ones. */ 2477113275Smike if (cfun->can_throw_non_call_exceptions) 2478113275Smike { 2479168401Spjd sbitmap blocks; 2480191673Sjamie blocks = sbitmap_alloc (last_basic_block_for_fn (cfun)); 2481113275Smike bitmap_ones (blocks); 2482113275Smike find_many_sub_basic_blocks (blocks); 2483191673Sjamie sbitmap_free (blocks); 2484191673Sjamie } 2485191673Sjamie 2486113275Smike if (inserted_p) 2487113275Smike commit_edge_insertions (); 2488113275Smike 2489113275Smike /* Replacing pseudos with their memory equivalents might have 2490113275Smike created shared rtx. Subsequent passes would get confused 2491191673Sjamie by this, so unshare everything here. */ 2492192895Sjamie unshare_all_rtl_again (get_insns ()); 2493191673Sjamie 2494191673Sjamie#ifdef ENABLE_CHECKING 2495192895Sjamie check_rtl (true); 2496191673Sjamie#endif 2497192895Sjamie 2498192895Sjamie timevar_pop (TV_LRA); 2499192895Sjamie} 2500192895Sjamie 2501192895Sjamie/* Called once per compiler to initialize LRA data once. */ 2502192895Sjamievoid 2503192895Sjamielra_init_once (void) 2504192895Sjamie{ 2505192895Sjamie init_insn_code_data_once (); 2506192895Sjamie} 2507192895Sjamie 2508192895Sjamie/* Called once per compiler to finish LRA data which are initialize 2509192895Sjamie once. */ 2510192895Sjamievoid 2511192895Sjamielra_finish_once (void) 2512192895Sjamie{ 2513192895Sjamie finish_insn_code_data_once (); 2514192895Sjamie} 2515192895Sjamie