xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/web.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg /* Web construction code for GNU compiler.
21debfc3dSmrg    Contributed by Jan Hubicka.
3*8feb0f0bSmrg    Copyright (C) 2001-2020 Free Software Foundation, Inc.
41debfc3dSmrg 
51debfc3dSmrg This file is part of GCC.
61debfc3dSmrg 
71debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
81debfc3dSmrg the terms of the GNU General Public License as published by the Free
91debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
101debfc3dSmrg version.
111debfc3dSmrg 
121debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
131debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
141debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
151debfc3dSmrg for more details.
161debfc3dSmrg 
171debfc3dSmrg You should have received a copy of the GNU General Public License
181debfc3dSmrg along with GCC; see the file COPYING3.  If not see
191debfc3dSmrg <http://www.gnu.org/licenses/>.  */
201debfc3dSmrg 
211debfc3dSmrg /* Simple optimization pass that splits independent uses of each pseudo,
221debfc3dSmrg    increasing effectiveness of other optimizations.  The optimization can
231debfc3dSmrg    serve as an example of use for the dataflow module.
241debfc3dSmrg 
251debfc3dSmrg    TODO
261debfc3dSmrg     - We may use profile information and ignore infrequent use for the
271debfc3dSmrg       purpose of web unifying, inserting the compensation code later to
281debfc3dSmrg       implement full induction variable expansion for loops (currently
291debfc3dSmrg       we expand only if the induction variable is dead afterward, which
301debfc3dSmrg       is often the case).  */
311debfc3dSmrg 
321debfc3dSmrg #include "config.h"
331debfc3dSmrg #include "system.h"
341debfc3dSmrg #include "coretypes.h"
351debfc3dSmrg #include "backend.h"
361debfc3dSmrg #include "rtl.h"
371debfc3dSmrg #include "df.h"
381debfc3dSmrg #include "insn-config.h"
391debfc3dSmrg #include "recog.h"
401debfc3dSmrg 
411debfc3dSmrg #include "tree-pass.h"
421debfc3dSmrg 
431debfc3dSmrg 
441debfc3dSmrg /* Find the root of unionfind tree (the representative of set).  */
451debfc3dSmrg 
461debfc3dSmrg web_entry_base *
unionfind_root()471debfc3dSmrg web_entry_base::unionfind_root ()
481debfc3dSmrg {
491debfc3dSmrg   web_entry_base *element = this, *element1 = this, *element2;
501debfc3dSmrg 
511debfc3dSmrg   while (element->pred ())
521debfc3dSmrg     element = element->pred ();
531debfc3dSmrg   while (element1->pred ())
541debfc3dSmrg     {
551debfc3dSmrg       element2 = element1->pred ();
561debfc3dSmrg       element1->set_pred (element);
571debfc3dSmrg       element1 = element2;
581debfc3dSmrg     }
591debfc3dSmrg   return element;
601debfc3dSmrg }
611debfc3dSmrg 
621debfc3dSmrg /* Union sets.
631debfc3dSmrg    Return true if FIRST and SECOND points to the same web entry structure and
641debfc3dSmrg    nothing is done.  Otherwise, return false.  */
651debfc3dSmrg 
661debfc3dSmrg bool
unionfind_union(web_entry_base * first,web_entry_base * second)671debfc3dSmrg unionfind_union (web_entry_base *first, web_entry_base *second)
681debfc3dSmrg {
691debfc3dSmrg   first = first->unionfind_root ();
701debfc3dSmrg   second = second->unionfind_root ();
711debfc3dSmrg   if (first == second)
721debfc3dSmrg     return true;
731debfc3dSmrg   second->set_pred (first);
741debfc3dSmrg   return false;
751debfc3dSmrg }
761debfc3dSmrg 
77*8feb0f0bSmrg struct web_entry : public web_entry_base
781debfc3dSmrg {
791debfc3dSmrg  private:
801debfc3dSmrg   rtx reg_pvt;
811debfc3dSmrg 
821debfc3dSmrg  public:
regweb_entry831debfc3dSmrg   rtx reg () { return reg_pvt; }
set_regweb_entry841debfc3dSmrg   void set_reg (rtx r) { reg_pvt = r; }
851debfc3dSmrg };
861debfc3dSmrg 
871debfc3dSmrg /* For INSN, union all defs and uses that are linked by match_dup.
881debfc3dSmrg    FUN is the function that does the union.  */
891debfc3dSmrg 
901debfc3dSmrg static void
union_match_dups(rtx_insn * insn,web_entry * def_entry,web_entry * use_entry,bool (* fun)(web_entry_base *,web_entry_base *))911debfc3dSmrg union_match_dups (rtx_insn *insn, web_entry *def_entry, web_entry *use_entry,
921debfc3dSmrg 		  bool (*fun) (web_entry_base *, web_entry_base *))
931debfc3dSmrg {
941debfc3dSmrg   struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
951debfc3dSmrg   df_ref use_link = DF_INSN_INFO_USES (insn_info);
961debfc3dSmrg   df_ref def_link = DF_INSN_INFO_DEFS (insn_info);
971debfc3dSmrg   struct web_entry *dup_entry;
981debfc3dSmrg   int i;
991debfc3dSmrg 
1001debfc3dSmrg   extract_insn (insn);
1011debfc3dSmrg 
1021debfc3dSmrg   for (i = 0; i < recog_data.n_dups; i++)
1031debfc3dSmrg     {
1041debfc3dSmrg       int op = recog_data.dup_num[i];
1051debfc3dSmrg       enum op_type type = recog_data.operand_type[op];
1061debfc3dSmrg       df_ref ref, dupref;
1071debfc3dSmrg       struct web_entry *entry;
1081debfc3dSmrg 
1091debfc3dSmrg       dup_entry = use_entry;
1101debfc3dSmrg       for (dupref = use_link; dupref; dupref = DF_REF_NEXT_LOC (dupref))
1111debfc3dSmrg 	if (DF_REF_LOC (dupref) == recog_data.dup_loc[i])
1121debfc3dSmrg 	  break;
1131debfc3dSmrg 
1141debfc3dSmrg       if (dupref == NULL && type == OP_INOUT)
1151debfc3dSmrg 	{
1161debfc3dSmrg 	  dup_entry = def_entry;
1171debfc3dSmrg 	  for (dupref = def_link; dupref; dupref = DF_REF_NEXT_LOC (dupref))
1181debfc3dSmrg 	    if (DF_REF_LOC (dupref) == recog_data.dup_loc[i])
1191debfc3dSmrg 	      break;
1201debfc3dSmrg 	}
1211debfc3dSmrg       /* ??? *DUPREF can still be zero, because when an operand matches
1221debfc3dSmrg 	 a memory, DF_REF_LOC (use_link[n]) points to the register part
1231debfc3dSmrg 	 of the address, whereas recog_data.dup_loc[m] points to the
1241debfc3dSmrg 	 entire memory ref, thus we fail to find the duplicate entry,
1251debfc3dSmrg          even though it is there.
1261debfc3dSmrg          Example: i686-pc-linux-gnu gcc.c-torture/compile/950607-1.c
1271debfc3dSmrg 		  -O3 -fomit-frame-pointer -funroll-loops  */
1281debfc3dSmrg       if (dupref == NULL
1291debfc3dSmrg 	  || DF_REF_REGNO (dupref) < FIRST_PSEUDO_REGISTER)
1301debfc3dSmrg 	continue;
1311debfc3dSmrg 
1321debfc3dSmrg       ref = type == OP_IN ? use_link : def_link;
1331debfc3dSmrg       entry = type == OP_IN ? use_entry : def_entry;
1341debfc3dSmrg       for (; ref; ref = DF_REF_NEXT_LOC (ref))
1351debfc3dSmrg 	{
1361debfc3dSmrg 	  rtx *l = DF_REF_LOC (ref);
1371debfc3dSmrg 	  if (l == recog_data.operand_loc[op])
1381debfc3dSmrg 	    break;
1391debfc3dSmrg 	  if (l && DF_REF_REAL_LOC (ref) == recog_data.operand_loc[op])
1401debfc3dSmrg 	    break;
1411debfc3dSmrg 	}
1421debfc3dSmrg 
1431debfc3dSmrg       if (!ref && type == OP_INOUT)
1441debfc3dSmrg 	{
1451debfc3dSmrg 	  entry = use_entry;
1461debfc3dSmrg 	  for (ref = use_link; ref; ref = DF_REF_NEXT_LOC (ref))
1471debfc3dSmrg 	    {
1481debfc3dSmrg 	      rtx *l = DF_REF_LOC (ref);
1491debfc3dSmrg 	      if (l == recog_data.operand_loc[op])
1501debfc3dSmrg 		break;
1511debfc3dSmrg 	      if (l && DF_REF_REAL_LOC (ref) == recog_data.operand_loc[op])
1521debfc3dSmrg 		break;
1531debfc3dSmrg 	    }
1541debfc3dSmrg 	}
1551debfc3dSmrg 
1561debfc3dSmrg       gcc_assert (ref);
1571debfc3dSmrg       (*fun) (dup_entry + DF_REF_ID (dupref), entry + DF_REF_ID (ref));
1581debfc3dSmrg     }
1591debfc3dSmrg }
1601debfc3dSmrg 
1611debfc3dSmrg /* For each use, all possible defs reaching it must come in the same
1621debfc3dSmrg    register, union them.
1631debfc3dSmrg    FUN is the function that does the union.
1641debfc3dSmrg 
1651debfc3dSmrg    In USED, we keep the DF_REF_ID of the first uninitialized uses of a
1661debfc3dSmrg    register, so that all uninitialized uses of the register can be
1671debfc3dSmrg    combined into a single web.  We actually offset it by 2, because
1681debfc3dSmrg    the values 0 and 1 are reserved for use by entry_register.  */
1691debfc3dSmrg 
1701debfc3dSmrg void
union_defs(df_ref use,web_entry * def_entry,unsigned int * used,web_entry * use_entry,bool (* fun)(web_entry_base *,web_entry_base *))1711debfc3dSmrg union_defs (df_ref use, web_entry *def_entry,
1721debfc3dSmrg 	    unsigned int *used, web_entry *use_entry,
1731debfc3dSmrg  	    bool (*fun) (web_entry_base *, web_entry_base *))
1741debfc3dSmrg {
1751debfc3dSmrg   struct df_insn_info *insn_info = DF_REF_INSN_INFO (use);
1761debfc3dSmrg   struct df_link *link = DF_REF_CHAIN (use);
1771debfc3dSmrg   rtx set;
1781debfc3dSmrg 
1791debfc3dSmrg   if (insn_info)
1801debfc3dSmrg     {
1811debfc3dSmrg       df_ref eq_use;
1821debfc3dSmrg 
1831debfc3dSmrg       set = single_set (insn_info->insn);
1841debfc3dSmrg       FOR_EACH_INSN_INFO_EQ_USE (eq_use, insn_info)
1851debfc3dSmrg 	if (use != eq_use
1861debfc3dSmrg 	    && DF_REF_REAL_REG (use) == DF_REF_REAL_REG (eq_use))
1871debfc3dSmrg 	  (*fun) (use_entry + DF_REF_ID (use), use_entry + DF_REF_ID (eq_use));
1881debfc3dSmrg     }
1891debfc3dSmrg   else
1901debfc3dSmrg     set = NULL;
1911debfc3dSmrg 
1921debfc3dSmrg   /* Union all occurrences of the same register in reg notes.  */
1931debfc3dSmrg 
1941debfc3dSmrg   /* Recognize trivial noop moves and attempt to keep them as noop.  */
1951debfc3dSmrg 
1961debfc3dSmrg   if (set
1971debfc3dSmrg       && SET_SRC (set) == DF_REF_REG (use)
1981debfc3dSmrg       && SET_SRC (set) == SET_DEST (set))
1991debfc3dSmrg     {
2001debfc3dSmrg       df_ref def;
2011debfc3dSmrg 
2021debfc3dSmrg       FOR_EACH_INSN_INFO_DEF (def, insn_info)
2031debfc3dSmrg 	if (DF_REF_REAL_REG (use) == DF_REF_REAL_REG (def))
2041debfc3dSmrg 	  (*fun) (use_entry + DF_REF_ID (use), def_entry + DF_REF_ID (def));
2051debfc3dSmrg     }
2061debfc3dSmrg 
2071debfc3dSmrg   /* UD chains of uninitialized REGs are empty.  Keeping all uses of
2081debfc3dSmrg      the same uninitialized REG in a single web is not necessary for
2091debfc3dSmrg      correctness, since the uses are undefined, but it's wasteful to
2101debfc3dSmrg      allocate one register or slot for each reference.  Furthermore,
2111debfc3dSmrg      creating new pseudos for uninitialized references in debug insns
2121debfc3dSmrg      (see PR 42631) causes -fcompare-debug failures.  We record the
2131debfc3dSmrg      number of the first uninitialized reference we found, and merge
2141debfc3dSmrg      with it any other uninitialized references to the same
2151debfc3dSmrg      register.  */
2161debfc3dSmrg   if (!link)
2171debfc3dSmrg     {
2181debfc3dSmrg       int regno = REGNO (DF_REF_REAL_REG (use));
2191debfc3dSmrg       if (used[regno])
2201debfc3dSmrg 	(*fun) (use_entry + DF_REF_ID (use), use_entry + used[regno] - 2);
2211debfc3dSmrg       else
2221debfc3dSmrg 	used[regno] = DF_REF_ID (use) + 2;
2231debfc3dSmrg     }
2241debfc3dSmrg 
2251debfc3dSmrg   while (link)
2261debfc3dSmrg     {
2271debfc3dSmrg       (*fun) (use_entry + DF_REF_ID (use),
2281debfc3dSmrg 	      def_entry + DF_REF_ID (link->ref));
2291debfc3dSmrg       link = link->next;
2301debfc3dSmrg     }
2311debfc3dSmrg 
2321debfc3dSmrg   /* A READ_WRITE use requires the corresponding def to be in the same
2331debfc3dSmrg      register.  Find it and union.  */
2341debfc3dSmrg   if (DF_REF_FLAGS (use) & DF_REF_READ_WRITE)
2351debfc3dSmrg     if (insn_info)
2361debfc3dSmrg       {
2371debfc3dSmrg 	df_ref def;
2381debfc3dSmrg 
2391debfc3dSmrg 	FOR_EACH_INSN_INFO_DEF (def, insn_info)
2401debfc3dSmrg 	  if (DF_REF_REAL_REG (use) == DF_REF_REAL_REG (def))
2411debfc3dSmrg 	    (*fun) (use_entry + DF_REF_ID (use), def_entry + DF_REF_ID (def));
2421debfc3dSmrg       }
2431debfc3dSmrg }
2441debfc3dSmrg 
2451debfc3dSmrg /* Find the corresponding register for the given entry.  */
2461debfc3dSmrg 
2471debfc3dSmrg static rtx
entry_register(web_entry * entry,df_ref ref,unsigned int * used)2481debfc3dSmrg entry_register (web_entry *entry, df_ref ref, unsigned int *used)
2491debfc3dSmrg {
2501debfc3dSmrg   web_entry *root;
2511debfc3dSmrg   rtx reg, newreg;
2521debfc3dSmrg 
2531debfc3dSmrg   /* Find the corresponding web and see if it has been visited.  */
2541debfc3dSmrg   root = (web_entry *)entry->unionfind_root ();
2551debfc3dSmrg   if (root->reg ())
2561debfc3dSmrg     return root->reg ();
2571debfc3dSmrg 
2581debfc3dSmrg   /* We are seeing this web for the first time, do the assignment.  */
2591debfc3dSmrg   reg = DF_REF_REAL_REG (ref);
2601debfc3dSmrg 
2611debfc3dSmrg   /* In case the original register is already assigned, generate new
2621debfc3dSmrg      one.  Since we use USED to merge uninitialized refs into a single
2631debfc3dSmrg      web, we might found an element to be nonzero without our having
2641debfc3dSmrg      used it.  Test for 1, because union_defs saves it for our use,
2651debfc3dSmrg      and there won't be any use for the other values when we get to
2661debfc3dSmrg      this point.  */
2671debfc3dSmrg   if (used[REGNO (reg)] != 1)
2681debfc3dSmrg     newreg = reg, used[REGNO (reg)] = 1;
2691debfc3dSmrg   else
2701debfc3dSmrg     {
2711debfc3dSmrg       newreg = gen_reg_rtx (GET_MODE (reg));
2721debfc3dSmrg       REG_USERVAR_P (newreg) = REG_USERVAR_P (reg);
2731debfc3dSmrg       REG_POINTER (newreg) = REG_POINTER (reg);
2741debfc3dSmrg       REG_ATTRS (newreg) = REG_ATTRS (reg);
2751debfc3dSmrg       if (dump_file)
2761debfc3dSmrg 	fprintf (dump_file, "Web oldreg=%i newreg=%i\n", REGNO (reg),
2771debfc3dSmrg 		 REGNO (newreg));
2781debfc3dSmrg     }
2791debfc3dSmrg 
2801debfc3dSmrg   root->set_reg (newreg);
2811debfc3dSmrg   return newreg;
2821debfc3dSmrg }
2831debfc3dSmrg 
2841debfc3dSmrg /* Replace the reference by REG.  */
2851debfc3dSmrg 
2861debfc3dSmrg static void
replace_ref(df_ref ref,rtx reg)2871debfc3dSmrg replace_ref (df_ref ref, rtx reg)
2881debfc3dSmrg {
2891debfc3dSmrg   rtx oldreg = DF_REF_REAL_REG (ref);
2901debfc3dSmrg   rtx *loc = DF_REF_REAL_LOC (ref);
2911debfc3dSmrg   unsigned int uid = DF_REF_INSN_UID (ref);
2921debfc3dSmrg 
2931debfc3dSmrg   if (oldreg == reg)
2941debfc3dSmrg     return;
2951debfc3dSmrg   if (dump_file)
2961debfc3dSmrg     fprintf (dump_file, "Updating insn %i (%i->%i)\n",
2971debfc3dSmrg 	     uid, REGNO (oldreg), REGNO (reg));
2981debfc3dSmrg   *loc = reg;
2991debfc3dSmrg   df_insn_rescan (DF_REF_INSN (ref));
3001debfc3dSmrg }
3011debfc3dSmrg 
3021debfc3dSmrg 
3031debfc3dSmrg namespace {
3041debfc3dSmrg 
3051debfc3dSmrg const pass_data pass_data_web =
3061debfc3dSmrg {
3071debfc3dSmrg   RTL_PASS, /* type */
3081debfc3dSmrg   "web", /* name */
3091debfc3dSmrg   OPTGROUP_NONE, /* optinfo_flags */
3101debfc3dSmrg   TV_WEB, /* tv_id */
3111debfc3dSmrg   0, /* properties_required */
3121debfc3dSmrg   0, /* properties_provided */
3131debfc3dSmrg   0, /* properties_destroyed */
3141debfc3dSmrg   0, /* todo_flags_start */
3151debfc3dSmrg   TODO_df_finish, /* todo_flags_finish */
3161debfc3dSmrg };
3171debfc3dSmrg 
3181debfc3dSmrg class pass_web : public rtl_opt_pass
3191debfc3dSmrg {
3201debfc3dSmrg public:
pass_web(gcc::context * ctxt)3211debfc3dSmrg   pass_web (gcc::context *ctxt)
3221debfc3dSmrg     : rtl_opt_pass (pass_data_web, ctxt)
3231debfc3dSmrg   {}
3241debfc3dSmrg 
3251debfc3dSmrg   /* opt_pass methods: */
gate(function *)3261debfc3dSmrg   virtual bool gate (function *) { return (optimize > 0 && flag_web); }
3271debfc3dSmrg   virtual unsigned int execute (function *);
3281debfc3dSmrg 
3291debfc3dSmrg }; // class pass_web
3301debfc3dSmrg 
3311debfc3dSmrg unsigned int
execute(function * fun)3321debfc3dSmrg pass_web::execute (function *fun)
3331debfc3dSmrg {
3341debfc3dSmrg   web_entry *def_entry;
3351debfc3dSmrg   web_entry *use_entry;
3361debfc3dSmrg   unsigned int max = max_reg_num ();
3371debfc3dSmrg   unsigned int *used;
3381debfc3dSmrg   basic_block bb;
3391debfc3dSmrg   unsigned int uses_num = 0;
3401debfc3dSmrg   rtx_insn *insn;
3411debfc3dSmrg 
3421debfc3dSmrg   df_set_flags (DF_NO_HARD_REGS + DF_EQ_NOTES);
3431debfc3dSmrg   df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
3441debfc3dSmrg   df_chain_add_problem (DF_UD_CHAIN);
3451debfc3dSmrg   df_analyze ();
3461debfc3dSmrg   df_set_flags (DF_DEFER_INSN_RESCAN);
3471debfc3dSmrg 
3481debfc3dSmrg   /* Assign ids to the uses.  */
3491debfc3dSmrg   FOR_ALL_BB_FN (bb, fun)
3501debfc3dSmrg     FOR_BB_INSNS (bb, insn)
3511debfc3dSmrg     {
3521debfc3dSmrg       if (NONDEBUG_INSN_P (insn))
3531debfc3dSmrg 	{
3541debfc3dSmrg 	  struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
3551debfc3dSmrg 	  df_ref use;
3561debfc3dSmrg 	  FOR_EACH_INSN_INFO_USE (use, insn_info)
3571debfc3dSmrg 	    if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER)
3581debfc3dSmrg 	      DF_REF_ID (use) = uses_num++;
3591debfc3dSmrg 	  FOR_EACH_INSN_INFO_EQ_USE (use, insn_info)
3601debfc3dSmrg 	    if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER)
3611debfc3dSmrg 	      DF_REF_ID (use) = uses_num++;
3621debfc3dSmrg 	}
3631debfc3dSmrg     }
3641debfc3dSmrg 
3651debfc3dSmrg   /* Record the number of uses and defs at the beginning of the optimization.  */
3661debfc3dSmrg   def_entry = XCNEWVEC (web_entry, DF_DEFS_TABLE_SIZE ());
3671debfc3dSmrg   used = XCNEWVEC (unsigned, max);
3681debfc3dSmrg   use_entry = XCNEWVEC (web_entry, uses_num);
3691debfc3dSmrg 
3701debfc3dSmrg   /* Produce the web.  */
3711debfc3dSmrg   FOR_ALL_BB_FN (bb, fun)
3721debfc3dSmrg     FOR_BB_INSNS (bb, insn)
3731debfc3dSmrg       if (NONDEBUG_INSN_P (insn))
3741debfc3dSmrg 	{
3751debfc3dSmrg 	  struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
3761debfc3dSmrg 	  df_ref use;
3771debfc3dSmrg 	  union_match_dups (insn, def_entry, use_entry, unionfind_union);
3781debfc3dSmrg 	  FOR_EACH_INSN_INFO_USE (use, insn_info)
3791debfc3dSmrg 	    if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER)
3801debfc3dSmrg 	      union_defs (use, def_entry, used, use_entry, unionfind_union);
3811debfc3dSmrg 	  FOR_EACH_INSN_INFO_EQ_USE (use, insn_info)
3821debfc3dSmrg 	    if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER)
3831debfc3dSmrg 	      union_defs (use, def_entry, used, use_entry, unionfind_union);
3841debfc3dSmrg 	}
3851debfc3dSmrg 
3861debfc3dSmrg   /* Update the instruction stream, allocating new registers for split pseudos
3871debfc3dSmrg      in progress.  */
3881debfc3dSmrg   FOR_ALL_BB_FN (bb, fun)
3891debfc3dSmrg     FOR_BB_INSNS (bb, insn)
3901debfc3dSmrg       if (NONDEBUG_INSN_P (insn)
3911debfc3dSmrg 	  /* Ignore naked clobber.  For example, reg 134 in the second insn
3921debfc3dSmrg 	     of the following sequence will not be replaced.
3931debfc3dSmrg 
3941debfc3dSmrg 	       (insn (clobber (reg:SI 134)))
3951debfc3dSmrg 
3961debfc3dSmrg 	       (insn (set (reg:SI 0 r0) (reg:SI 134)))
3971debfc3dSmrg 
3981debfc3dSmrg 	     Thus the later passes can optimize them away.  */
3991debfc3dSmrg 	  && GET_CODE (PATTERN (insn)) != CLOBBER)
4001debfc3dSmrg 	{
4011debfc3dSmrg 	  struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
4021debfc3dSmrg 	  df_ref def, use;
4031debfc3dSmrg 	  FOR_EACH_INSN_INFO_USE (use, insn_info)
4041debfc3dSmrg 	    if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER)
4051debfc3dSmrg 	      replace_ref (use, entry_register (use_entry + DF_REF_ID (use),
4061debfc3dSmrg 						use, used));
4071debfc3dSmrg 	  FOR_EACH_INSN_INFO_EQ_USE (use, insn_info)
4081debfc3dSmrg 	    if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER)
4091debfc3dSmrg 	      replace_ref (use, entry_register (use_entry + DF_REF_ID (use),
4101debfc3dSmrg 						use, used));
4111debfc3dSmrg 	  FOR_EACH_INSN_INFO_DEF (def, insn_info)
4121debfc3dSmrg 	    if (DF_REF_REGNO (def) >= FIRST_PSEUDO_REGISTER)
4131debfc3dSmrg 	      replace_ref (def, entry_register (def_entry + DF_REF_ID (def),
4141debfc3dSmrg 						def, used));
4151debfc3dSmrg 	}
4161debfc3dSmrg 
4171debfc3dSmrg   free (def_entry);
4181debfc3dSmrg   free (use_entry);
4191debfc3dSmrg   free (used);
4201debfc3dSmrg   return 0;
4211debfc3dSmrg }
4221debfc3dSmrg 
4231debfc3dSmrg } // anon namespace
4241debfc3dSmrg 
4251debfc3dSmrg rtl_opt_pass *
make_pass_web(gcc::context * ctxt)4261debfc3dSmrg make_pass_web (gcc::context *ctxt)
4271debfc3dSmrg {
4281debfc3dSmrg   return new pass_web (ctxt);
4291debfc3dSmrg }
430