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