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