1*e4b17023SJohn Marino /* Web construction code for GNU compiler. 2*e4b17023SJohn Marino Contributed by Jan Hubicka. 3*e4b17023SJohn Marino Copyright (C) 2001, 2002, 2004, 2006, 2007, 2008, 2010 4*e4b17023SJohn Marino Free Software Foundation, Inc. 5*e4b17023SJohn Marino 6*e4b17023SJohn Marino This file is part of GCC. 7*e4b17023SJohn Marino 8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under 9*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free 10*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later 11*e4b17023SJohn Marino version. 12*e4b17023SJohn Marino 13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or 15*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16*e4b17023SJohn Marino for more details. 17*e4b17023SJohn Marino 18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License 19*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see 20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */ 21*e4b17023SJohn Marino 22*e4b17023SJohn Marino /* Simple optimization pass that splits independent uses of each pseudo, 23*e4b17023SJohn Marino increasing effectiveness of other optimizations. The optimization can 24*e4b17023SJohn Marino serve as an example of use for the dataflow module. 25*e4b17023SJohn Marino 26*e4b17023SJohn Marino We don't split registers with REG_USERVAR set unless -fmessy-debugging 27*e4b17023SJohn Marino is specified, because debugging information about such split variables 28*e4b17023SJohn Marino is almost unusable. 29*e4b17023SJohn Marino 30*e4b17023SJohn Marino TODO 31*e4b17023SJohn Marino - We may use profile information and ignore infrequent use for the 32*e4b17023SJohn Marino purpose of web unifying, inserting the compensation code later to 33*e4b17023SJohn Marino implement full induction variable expansion for loops (currently 34*e4b17023SJohn Marino we expand only if the induction variable is dead afterward, which 35*e4b17023SJohn Marino is often the case). */ 36*e4b17023SJohn Marino 37*e4b17023SJohn Marino #include "config.h" 38*e4b17023SJohn Marino #include "system.h" 39*e4b17023SJohn Marino #include "coretypes.h" 40*e4b17023SJohn Marino #include "tm.h" 41*e4b17023SJohn Marino #include "diagnostic-core.h" 42*e4b17023SJohn Marino 43*e4b17023SJohn Marino #include "rtl.h" 44*e4b17023SJohn Marino #include "hard-reg-set.h" 45*e4b17023SJohn Marino #include "flags.h" 46*e4b17023SJohn Marino #include "obstack.h" 47*e4b17023SJohn Marino #include "basic-block.h" 48*e4b17023SJohn Marino #include "output.h" 49*e4b17023SJohn Marino #include "df.h" 50*e4b17023SJohn Marino #include "function.h" 51*e4b17023SJohn Marino #include "insn-config.h" 52*e4b17023SJohn Marino #include "recog.h" 53*e4b17023SJohn Marino #include "timevar.h" 54*e4b17023SJohn Marino #include "tree-pass.h" 55*e4b17023SJohn Marino 56*e4b17023SJohn Marino 57*e4b17023SJohn Marino /* Find the root of unionfind tree (the representative of set). */ 58*e4b17023SJohn Marino 59*e4b17023SJohn Marino struct web_entry * 60*e4b17023SJohn Marino unionfind_root (struct web_entry *element) 61*e4b17023SJohn Marino { 62*e4b17023SJohn Marino struct web_entry *element1 = element, *element2; 63*e4b17023SJohn Marino 64*e4b17023SJohn Marino while (element->pred) 65*e4b17023SJohn Marino element = element->pred; 66*e4b17023SJohn Marino while (element1->pred) 67*e4b17023SJohn Marino { 68*e4b17023SJohn Marino element2 = element1->pred; 69*e4b17023SJohn Marino element1->pred = element; 70*e4b17023SJohn Marino element1 = element2; 71*e4b17023SJohn Marino } 72*e4b17023SJohn Marino return element; 73*e4b17023SJohn Marino } 74*e4b17023SJohn Marino 75*e4b17023SJohn Marino /* Union sets. 76*e4b17023SJohn Marino Return true if FIRST and SECOND points to the same web entry structure and 77*e4b17023SJohn Marino nothing is done. Otherwise, return false. */ 78*e4b17023SJohn Marino 79*e4b17023SJohn Marino bool 80*e4b17023SJohn Marino unionfind_union (struct web_entry *first, struct web_entry *second) 81*e4b17023SJohn Marino { 82*e4b17023SJohn Marino first = unionfind_root (first); 83*e4b17023SJohn Marino second = unionfind_root (second); 84*e4b17023SJohn Marino if (first == second) 85*e4b17023SJohn Marino return true; 86*e4b17023SJohn Marino second->pred = first; 87*e4b17023SJohn Marino return false; 88*e4b17023SJohn Marino } 89*e4b17023SJohn Marino 90*e4b17023SJohn Marino /* For INSN, union all defs and uses that are linked by match_dup. 91*e4b17023SJohn Marino FUN is the function that does the union. */ 92*e4b17023SJohn Marino 93*e4b17023SJohn Marino static void 94*e4b17023SJohn Marino union_match_dups (rtx insn, struct web_entry *def_entry, 95*e4b17023SJohn Marino struct web_entry *use_entry, 96*e4b17023SJohn Marino bool (*fun) (struct web_entry *, struct web_entry *)) 97*e4b17023SJohn Marino { 98*e4b17023SJohn Marino struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); 99*e4b17023SJohn Marino df_ref *use_link = DF_INSN_INFO_USES (insn_info); 100*e4b17023SJohn Marino df_ref *def_link = DF_INSN_INFO_DEFS (insn_info); 101*e4b17023SJohn Marino int i; 102*e4b17023SJohn Marino 103*e4b17023SJohn Marino extract_insn (insn); 104*e4b17023SJohn Marino 105*e4b17023SJohn Marino for (i = 0; i < recog_data.n_dups; i++) 106*e4b17023SJohn Marino { 107*e4b17023SJohn Marino int op = recog_data.dup_num[i]; 108*e4b17023SJohn Marino enum op_type type = recog_data.operand_type[op]; 109*e4b17023SJohn Marino df_ref *ref, *dupref; 110*e4b17023SJohn Marino struct web_entry *entry; 111*e4b17023SJohn Marino 112*e4b17023SJohn Marino for (dupref = use_link; *dupref; dupref++) 113*e4b17023SJohn Marino if (DF_REF_LOC (*dupref) == recog_data.dup_loc[i]) 114*e4b17023SJohn Marino break; 115*e4b17023SJohn Marino 116*e4b17023SJohn Marino if (*dupref == NULL 117*e4b17023SJohn Marino || DF_REF_REGNO (*dupref) < FIRST_PSEUDO_REGISTER) 118*e4b17023SJohn Marino continue; 119*e4b17023SJohn Marino 120*e4b17023SJohn Marino ref = type == OP_IN ? use_link : def_link; 121*e4b17023SJohn Marino entry = type == OP_IN ? use_entry : def_entry; 122*e4b17023SJohn Marino for (; *ref; ref++) 123*e4b17023SJohn Marino if (DF_REF_LOC (*ref) == recog_data.operand_loc[op]) 124*e4b17023SJohn Marino break; 125*e4b17023SJohn Marino 126*e4b17023SJohn Marino (*fun) (use_entry + DF_REF_ID (*dupref), entry + DF_REF_ID (*ref)); 127*e4b17023SJohn Marino } 128*e4b17023SJohn Marino } 129*e4b17023SJohn Marino 130*e4b17023SJohn Marino /* For each use, all possible defs reaching it must come in the same 131*e4b17023SJohn Marino register, union them. 132*e4b17023SJohn Marino FUN is the function that does the union. 133*e4b17023SJohn Marino 134*e4b17023SJohn Marino In USED, we keep the DF_REF_ID of the first uninitialized uses of a 135*e4b17023SJohn Marino register, so that all uninitialized uses of the register can be 136*e4b17023SJohn Marino combined into a single web. We actually offset it by 2, because 137*e4b17023SJohn Marino the values 0 and 1 are reserved for use by entry_register. */ 138*e4b17023SJohn Marino 139*e4b17023SJohn Marino void 140*e4b17023SJohn Marino union_defs (df_ref use, struct web_entry *def_entry, 141*e4b17023SJohn Marino unsigned int *used, struct web_entry *use_entry, 142*e4b17023SJohn Marino bool (*fun) (struct web_entry *, struct web_entry *)) 143*e4b17023SJohn Marino { 144*e4b17023SJohn Marino struct df_insn_info *insn_info = DF_REF_INSN_INFO (use); 145*e4b17023SJohn Marino struct df_link *link = DF_REF_CHAIN (use); 146*e4b17023SJohn Marino df_ref *eq_use_link; 147*e4b17023SJohn Marino df_ref *def_link; 148*e4b17023SJohn Marino rtx set; 149*e4b17023SJohn Marino 150*e4b17023SJohn Marino if (insn_info) 151*e4b17023SJohn Marino { 152*e4b17023SJohn Marino rtx insn = insn_info->insn; 153*e4b17023SJohn Marino eq_use_link = DF_INSN_INFO_EQ_USES (insn_info); 154*e4b17023SJohn Marino def_link = DF_INSN_INFO_DEFS (insn_info); 155*e4b17023SJohn Marino set = single_set (insn); 156*e4b17023SJohn Marino } 157*e4b17023SJohn Marino else 158*e4b17023SJohn Marino { 159*e4b17023SJohn Marino /* An artificial use. It links up with nothing. */ 160*e4b17023SJohn Marino eq_use_link = NULL; 161*e4b17023SJohn Marino def_link = NULL; 162*e4b17023SJohn Marino set = NULL; 163*e4b17023SJohn Marino } 164*e4b17023SJohn Marino 165*e4b17023SJohn Marino /* Union all occurrences of the same register in reg notes. */ 166*e4b17023SJohn Marino 167*e4b17023SJohn Marino if (eq_use_link) 168*e4b17023SJohn Marino while (*eq_use_link) 169*e4b17023SJohn Marino { 170*e4b17023SJohn Marino if (use != *eq_use_link 171*e4b17023SJohn Marino && DF_REF_REAL_REG (use) == DF_REF_REAL_REG (*eq_use_link)) 172*e4b17023SJohn Marino (*fun) (use_entry + DF_REF_ID (use), 173*e4b17023SJohn Marino use_entry + DF_REF_ID (*eq_use_link)); 174*e4b17023SJohn Marino eq_use_link++; 175*e4b17023SJohn Marino } 176*e4b17023SJohn Marino 177*e4b17023SJohn Marino /* Recognize trivial noop moves and attempt to keep them as noop. */ 178*e4b17023SJohn Marino 179*e4b17023SJohn Marino if (set 180*e4b17023SJohn Marino && SET_SRC (set) == DF_REF_REG (use) 181*e4b17023SJohn Marino && SET_SRC (set) == SET_DEST (set)) 182*e4b17023SJohn Marino { 183*e4b17023SJohn Marino if (def_link) 184*e4b17023SJohn Marino while (*def_link) 185*e4b17023SJohn Marino { 186*e4b17023SJohn Marino if (DF_REF_REAL_REG (use) == DF_REF_REAL_REG (*def_link)) 187*e4b17023SJohn Marino (*fun) (use_entry + DF_REF_ID (use), 188*e4b17023SJohn Marino def_entry + DF_REF_ID (*def_link)); 189*e4b17023SJohn Marino def_link++; 190*e4b17023SJohn Marino } 191*e4b17023SJohn Marino } 192*e4b17023SJohn Marino 193*e4b17023SJohn Marino /* UD chains of uninitialized REGs are empty. Keeping all uses of 194*e4b17023SJohn Marino the same uninitialized REG in a single web is not necessary for 195*e4b17023SJohn Marino correctness, since the uses are undefined, but it's wasteful to 196*e4b17023SJohn Marino allocate one register or slot for each reference. Furthermore, 197*e4b17023SJohn Marino creating new pseudos for uninitialized references in debug insns 198*e4b17023SJohn Marino (see PR 42631) causes -fcompare-debug failures. We record the 199*e4b17023SJohn Marino number of the first uninitialized reference we found, and merge 200*e4b17023SJohn Marino with it any other uninitialized references to the same 201*e4b17023SJohn Marino register. */ 202*e4b17023SJohn Marino if (!link) 203*e4b17023SJohn Marino { 204*e4b17023SJohn Marino int regno = REGNO (DF_REF_REAL_REG (use)); 205*e4b17023SJohn Marino if (used[regno]) 206*e4b17023SJohn Marino (*fun) (use_entry + DF_REF_ID (use), use_entry + used[regno] - 2); 207*e4b17023SJohn Marino else 208*e4b17023SJohn Marino used[regno] = DF_REF_ID (use) + 2; 209*e4b17023SJohn Marino } 210*e4b17023SJohn Marino 211*e4b17023SJohn Marino while (link) 212*e4b17023SJohn Marino { 213*e4b17023SJohn Marino (*fun) (use_entry + DF_REF_ID (use), 214*e4b17023SJohn Marino def_entry + DF_REF_ID (link->ref)); 215*e4b17023SJohn Marino link = link->next; 216*e4b17023SJohn Marino } 217*e4b17023SJohn Marino 218*e4b17023SJohn Marino /* A READ_WRITE use requires the corresponding def to be in the same 219*e4b17023SJohn Marino register. Find it and union. */ 220*e4b17023SJohn Marino if (DF_REF_FLAGS (use) & DF_REF_READ_WRITE) 221*e4b17023SJohn Marino { 222*e4b17023SJohn Marino df_ref *link; 223*e4b17023SJohn Marino 224*e4b17023SJohn Marino if (insn_info) 225*e4b17023SJohn Marino link = DF_INSN_INFO_DEFS (insn_info); 226*e4b17023SJohn Marino else 227*e4b17023SJohn Marino link = NULL; 228*e4b17023SJohn Marino 229*e4b17023SJohn Marino if (link) 230*e4b17023SJohn Marino while (*link) 231*e4b17023SJohn Marino { 232*e4b17023SJohn Marino if (DF_REF_REAL_REG (*link) == DF_REF_REAL_REG (use)) 233*e4b17023SJohn Marino (*fun) (use_entry + DF_REF_ID (use), 234*e4b17023SJohn Marino def_entry + DF_REF_ID (*link)); 235*e4b17023SJohn Marino link++; 236*e4b17023SJohn Marino } 237*e4b17023SJohn Marino } 238*e4b17023SJohn Marino } 239*e4b17023SJohn Marino 240*e4b17023SJohn Marino /* Find the corresponding register for the given entry. */ 241*e4b17023SJohn Marino 242*e4b17023SJohn Marino static rtx 243*e4b17023SJohn Marino entry_register (struct web_entry *entry, df_ref ref, unsigned int *used) 244*e4b17023SJohn Marino { 245*e4b17023SJohn Marino struct web_entry *root; 246*e4b17023SJohn Marino rtx reg, newreg; 247*e4b17023SJohn Marino 248*e4b17023SJohn Marino /* Find the corresponding web and see if it has been visited. */ 249*e4b17023SJohn Marino root = unionfind_root (entry); 250*e4b17023SJohn Marino if (root->reg) 251*e4b17023SJohn Marino return root->reg; 252*e4b17023SJohn Marino 253*e4b17023SJohn Marino /* We are seeing this web for the first time, do the assignment. */ 254*e4b17023SJohn Marino reg = DF_REF_REAL_REG (ref); 255*e4b17023SJohn Marino 256*e4b17023SJohn Marino /* In case the original register is already assigned, generate new 257*e4b17023SJohn Marino one. Since we use USED to merge uninitialized refs into a single 258*e4b17023SJohn Marino web, we might found an element to be nonzero without our having 259*e4b17023SJohn Marino used it. Test for 1, because union_defs saves it for our use, 260*e4b17023SJohn Marino and there won't be any use for the other values when we get to 261*e4b17023SJohn Marino this point. */ 262*e4b17023SJohn Marino if (used[REGNO (reg)] != 1) 263*e4b17023SJohn Marino newreg = reg, used[REGNO (reg)] = 1; 264*e4b17023SJohn Marino else 265*e4b17023SJohn Marino { 266*e4b17023SJohn Marino newreg = gen_reg_rtx (GET_MODE (reg)); 267*e4b17023SJohn Marino REG_USERVAR_P (newreg) = REG_USERVAR_P (reg); 268*e4b17023SJohn Marino REG_POINTER (newreg) = REG_POINTER (reg); 269*e4b17023SJohn Marino REG_ATTRS (newreg) = REG_ATTRS (reg); 270*e4b17023SJohn Marino if (dump_file) 271*e4b17023SJohn Marino fprintf (dump_file, "Web oldreg=%i newreg=%i\n", REGNO (reg), 272*e4b17023SJohn Marino REGNO (newreg)); 273*e4b17023SJohn Marino } 274*e4b17023SJohn Marino 275*e4b17023SJohn Marino root->reg = newreg; 276*e4b17023SJohn Marino return newreg; 277*e4b17023SJohn Marino } 278*e4b17023SJohn Marino 279*e4b17023SJohn Marino /* Replace the reference by REG. */ 280*e4b17023SJohn Marino 281*e4b17023SJohn Marino static void 282*e4b17023SJohn Marino replace_ref (df_ref ref, rtx reg) 283*e4b17023SJohn Marino { 284*e4b17023SJohn Marino rtx oldreg = DF_REF_REAL_REG (ref); 285*e4b17023SJohn Marino rtx *loc = DF_REF_REAL_LOC (ref); 286*e4b17023SJohn Marino unsigned int uid = DF_REF_INSN_UID (ref); 287*e4b17023SJohn Marino 288*e4b17023SJohn Marino if (oldreg == reg) 289*e4b17023SJohn Marino return; 290*e4b17023SJohn Marino if (dump_file) 291*e4b17023SJohn Marino fprintf (dump_file, "Updating insn %i (%i->%i)\n", 292*e4b17023SJohn Marino uid, REGNO (oldreg), REGNO (reg)); 293*e4b17023SJohn Marino *loc = reg; 294*e4b17023SJohn Marino df_insn_rescan (DF_REF_INSN (ref)); 295*e4b17023SJohn Marino } 296*e4b17023SJohn Marino 297*e4b17023SJohn Marino 298*e4b17023SJohn Marino static bool 299*e4b17023SJohn Marino gate_handle_web (void) 300*e4b17023SJohn Marino { 301*e4b17023SJohn Marino return (optimize > 0 && flag_web); 302*e4b17023SJohn Marino } 303*e4b17023SJohn Marino 304*e4b17023SJohn Marino /* Main entry point. */ 305*e4b17023SJohn Marino 306*e4b17023SJohn Marino static unsigned int 307*e4b17023SJohn Marino web_main (void) 308*e4b17023SJohn Marino { 309*e4b17023SJohn Marino struct web_entry *def_entry; 310*e4b17023SJohn Marino struct web_entry *use_entry; 311*e4b17023SJohn Marino unsigned int max = max_reg_num (); 312*e4b17023SJohn Marino unsigned int *used; 313*e4b17023SJohn Marino basic_block bb; 314*e4b17023SJohn Marino unsigned int uses_num = 0; 315*e4b17023SJohn Marino rtx insn; 316*e4b17023SJohn Marino 317*e4b17023SJohn Marino df_set_flags (DF_NO_HARD_REGS + DF_EQ_NOTES); 318*e4b17023SJohn Marino df_chain_add_problem (DF_UD_CHAIN); 319*e4b17023SJohn Marino df_analyze (); 320*e4b17023SJohn Marino df_set_flags (DF_DEFER_INSN_RESCAN); 321*e4b17023SJohn Marino 322*e4b17023SJohn Marino /* Assign ids to the uses. */ 323*e4b17023SJohn Marino FOR_ALL_BB (bb) 324*e4b17023SJohn Marino FOR_BB_INSNS (bb, insn) 325*e4b17023SJohn Marino { 326*e4b17023SJohn Marino unsigned int uid = INSN_UID (insn); 327*e4b17023SJohn Marino if (NONDEBUG_INSN_P (insn)) 328*e4b17023SJohn Marino { 329*e4b17023SJohn Marino df_ref *use_rec; 330*e4b17023SJohn Marino for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) 331*e4b17023SJohn Marino { 332*e4b17023SJohn Marino df_ref use = *use_rec; 333*e4b17023SJohn Marino if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) 334*e4b17023SJohn Marino DF_REF_ID (use) = uses_num++; 335*e4b17023SJohn Marino } 336*e4b17023SJohn Marino for (use_rec = DF_INSN_UID_EQ_USES (uid); *use_rec; use_rec++) 337*e4b17023SJohn Marino { 338*e4b17023SJohn Marino df_ref use = *use_rec; 339*e4b17023SJohn Marino if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) 340*e4b17023SJohn Marino DF_REF_ID (use) = uses_num++; 341*e4b17023SJohn Marino } 342*e4b17023SJohn Marino } 343*e4b17023SJohn Marino } 344*e4b17023SJohn Marino 345*e4b17023SJohn Marino /* Record the number of uses and defs at the beginning of the optimization. */ 346*e4b17023SJohn Marino def_entry = XCNEWVEC (struct web_entry, DF_DEFS_TABLE_SIZE()); 347*e4b17023SJohn Marino used = XCNEWVEC (unsigned, max); 348*e4b17023SJohn Marino use_entry = XCNEWVEC (struct web_entry, uses_num); 349*e4b17023SJohn Marino 350*e4b17023SJohn Marino /* Produce the web. */ 351*e4b17023SJohn Marino FOR_ALL_BB (bb) 352*e4b17023SJohn Marino FOR_BB_INSNS (bb, insn) 353*e4b17023SJohn Marino { 354*e4b17023SJohn Marino unsigned int uid = INSN_UID (insn); 355*e4b17023SJohn Marino if (NONDEBUG_INSN_P (insn)) 356*e4b17023SJohn Marino { 357*e4b17023SJohn Marino df_ref *use_rec; 358*e4b17023SJohn Marino union_match_dups (insn, def_entry, use_entry, unionfind_union); 359*e4b17023SJohn Marino for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) 360*e4b17023SJohn Marino { 361*e4b17023SJohn Marino df_ref use = *use_rec; 362*e4b17023SJohn Marino if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) 363*e4b17023SJohn Marino union_defs (use, def_entry, used, use_entry, unionfind_union); 364*e4b17023SJohn Marino } 365*e4b17023SJohn Marino for (use_rec = DF_INSN_UID_EQ_USES (uid); *use_rec; use_rec++) 366*e4b17023SJohn Marino { 367*e4b17023SJohn Marino df_ref use = *use_rec; 368*e4b17023SJohn Marino if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) 369*e4b17023SJohn Marino union_defs (use, def_entry, used, use_entry, unionfind_union); 370*e4b17023SJohn Marino } 371*e4b17023SJohn Marino } 372*e4b17023SJohn Marino } 373*e4b17023SJohn Marino 374*e4b17023SJohn Marino /* Update the instruction stream, allocating new registers for split pseudos 375*e4b17023SJohn Marino in progress. */ 376*e4b17023SJohn Marino FOR_ALL_BB (bb) 377*e4b17023SJohn Marino FOR_BB_INSNS (bb, insn) 378*e4b17023SJohn Marino { 379*e4b17023SJohn Marino unsigned int uid = INSN_UID (insn); 380*e4b17023SJohn Marino 381*e4b17023SJohn Marino if (NONDEBUG_INSN_P (insn) 382*e4b17023SJohn Marino /* Ignore naked clobber. For example, reg 134 in the second insn 383*e4b17023SJohn Marino of the following sequence will not be replaced. 384*e4b17023SJohn Marino 385*e4b17023SJohn Marino (insn (clobber (reg:SI 134))) 386*e4b17023SJohn Marino 387*e4b17023SJohn Marino (insn (set (reg:SI 0 r0) (reg:SI 134))) 388*e4b17023SJohn Marino 389*e4b17023SJohn Marino Thus the later passes can optimize them away. */ 390*e4b17023SJohn Marino && GET_CODE (PATTERN (insn)) != CLOBBER) 391*e4b17023SJohn Marino { 392*e4b17023SJohn Marino df_ref *use_rec; 393*e4b17023SJohn Marino df_ref *def_rec; 394*e4b17023SJohn Marino for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) 395*e4b17023SJohn Marino { 396*e4b17023SJohn Marino df_ref use = *use_rec; 397*e4b17023SJohn Marino if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) 398*e4b17023SJohn Marino replace_ref (use, entry_register (use_entry + DF_REF_ID (use), use, used)); 399*e4b17023SJohn Marino } 400*e4b17023SJohn Marino for (use_rec = DF_INSN_UID_EQ_USES (uid); *use_rec; use_rec++) 401*e4b17023SJohn Marino { 402*e4b17023SJohn Marino df_ref use = *use_rec; 403*e4b17023SJohn Marino if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) 404*e4b17023SJohn Marino replace_ref (use, entry_register (use_entry + DF_REF_ID (use), use, used)); 405*e4b17023SJohn Marino } 406*e4b17023SJohn Marino for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) 407*e4b17023SJohn Marino { 408*e4b17023SJohn Marino df_ref def = *def_rec; 409*e4b17023SJohn Marino if (DF_REF_REGNO (def) >= FIRST_PSEUDO_REGISTER) 410*e4b17023SJohn Marino replace_ref (def, entry_register (def_entry + DF_REF_ID (def), def, used)); 411*e4b17023SJohn Marino } 412*e4b17023SJohn Marino } 413*e4b17023SJohn Marino } 414*e4b17023SJohn Marino 415*e4b17023SJohn Marino free (def_entry); 416*e4b17023SJohn Marino free (use_entry); 417*e4b17023SJohn Marino free (used); 418*e4b17023SJohn Marino return 0; 419*e4b17023SJohn Marino } 420*e4b17023SJohn Marino 421*e4b17023SJohn Marino struct rtl_opt_pass pass_web = 422*e4b17023SJohn Marino { 423*e4b17023SJohn Marino { 424*e4b17023SJohn Marino RTL_PASS, 425*e4b17023SJohn Marino "web", /* name */ 426*e4b17023SJohn Marino gate_handle_web, /* gate */ 427*e4b17023SJohn Marino web_main, /* execute */ 428*e4b17023SJohn Marino NULL, /* sub */ 429*e4b17023SJohn Marino NULL, /* next */ 430*e4b17023SJohn Marino 0, /* static_pass_number */ 431*e4b17023SJohn Marino TV_WEB, /* tv_id */ 432*e4b17023SJohn Marino 0, /* properties_required */ 433*e4b17023SJohn Marino 0, /* properties_provided */ 434*e4b17023SJohn Marino 0, /* properties_destroyed */ 435*e4b17023SJohn Marino 0, /* todo_flags_start */ 436*e4b17023SJohn Marino TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */ 437*e4b17023SJohn Marino } 438*e4b17023SJohn Marino }; 439