1*404b540aSrobert /* Top level of GCC compilers (cc1, cc1plus, etc.)
2*404b540aSrobert Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3*404b540aSrobert 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
4*404b540aSrobert
5*404b540aSrobert This file is part of GCC.
6*404b540aSrobert
7*404b540aSrobert GCC is free software; you can redistribute it and/or modify it under
8*404b540aSrobert the terms of the GNU General Public License as published by the Free
9*404b540aSrobert Software Foundation; either version 2, or (at your option) any later
10*404b540aSrobert version.
11*404b540aSrobert
12*404b540aSrobert GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*404b540aSrobert WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*404b540aSrobert FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15*404b540aSrobert for more details.
16*404b540aSrobert
17*404b540aSrobert You should have received a copy of the GNU General Public License
18*404b540aSrobert along with GCC; see the file COPYING. If not, write to the Free
19*404b540aSrobert Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20*404b540aSrobert 02110-1301, USA. */
21*404b540aSrobert
22*404b540aSrobert /* This is the top level of cc1/c++.
23*404b540aSrobert It parses command args, opens files, invokes the various passes
24*404b540aSrobert in the proper order, and counts the time used by each.
25*404b540aSrobert Error messages and low-level interface to malloc also handled here. */
26*404b540aSrobert
27*404b540aSrobert #include "config.h"
28*404b540aSrobert #undef FLOAT /* This is for hpux. They should change hpux. */
29*404b540aSrobert #undef FFS /* Some systems define this in param.h. */
30*404b540aSrobert #include "system.h"
31*404b540aSrobert #include "coretypes.h"
32*404b540aSrobert #include "tm.h"
33*404b540aSrobert #include <signal.h>
34*404b540aSrobert
35*404b540aSrobert #ifdef HAVE_SYS_RESOURCE_H
36*404b540aSrobert # include <sys/resource.h>
37*404b540aSrobert #endif
38*404b540aSrobert
39*404b540aSrobert #ifdef HAVE_SYS_TIMES_H
40*404b540aSrobert # include <sys/times.h>
41*404b540aSrobert #endif
42*404b540aSrobert
43*404b540aSrobert #include "line-map.h"
44*404b540aSrobert #include "input.h"
45*404b540aSrobert #include "tree.h"
46*404b540aSrobert #include "rtl.h"
47*404b540aSrobert #include "tm_p.h"
48*404b540aSrobert #include "flags.h"
49*404b540aSrobert #include "insn-attr.h"
50*404b540aSrobert #include "insn-config.h"
51*404b540aSrobert #include "insn-flags.h"
52*404b540aSrobert #include "hard-reg-set.h"
53*404b540aSrobert #include "recog.h"
54*404b540aSrobert #include "output.h"
55*404b540aSrobert #include "except.h"
56*404b540aSrobert #include "function.h"
57*404b540aSrobert #include "toplev.h"
58*404b540aSrobert #include "expr.h"
59*404b540aSrobert #include "basic-block.h"
60*404b540aSrobert #include "intl.h"
61*404b540aSrobert #include "ggc.h"
62*404b540aSrobert #include "graph.h"
63*404b540aSrobert #include "regs.h"
64*404b540aSrobert #include "timevar.h"
65*404b540aSrobert #include "diagnostic.h"
66*404b540aSrobert #include "params.h"
67*404b540aSrobert #include "reload.h"
68*404b540aSrobert #include "dwarf2asm.h"
69*404b540aSrobert #include "integrate.h"
70*404b540aSrobert #include "real.h"
71*404b540aSrobert #include "debug.h"
72*404b540aSrobert #include "target.h"
73*404b540aSrobert #include "langhooks.h"
74*404b540aSrobert #include "cfglayout.h"
75*404b540aSrobert #include "cfgloop.h"
76*404b540aSrobert #include "hosthooks.h"
77*404b540aSrobert #include "cgraph.h"
78*404b540aSrobert #include "opts.h"
79*404b540aSrobert #include "coverage.h"
80*404b540aSrobert #include "value-prof.h"
81*404b540aSrobert #include "tree-inline.h"
82*404b540aSrobert #include "tree-flow.h"
83*404b540aSrobert #include "tree-pass.h"
84*404b540aSrobert #include "tree-dump.h"
85*404b540aSrobert
86*404b540aSrobert #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
87*404b540aSrobert #include "dwarf2out.h"
88*404b540aSrobert #endif
89*404b540aSrobert
90*404b540aSrobert #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
91*404b540aSrobert #include "dbxout.h"
92*404b540aSrobert #endif
93*404b540aSrobert
94*404b540aSrobert #ifdef SDB_DEBUGGING_INFO
95*404b540aSrobert #include "sdbout.h"
96*404b540aSrobert #endif
97*404b540aSrobert
98*404b540aSrobert #ifdef XCOFF_DEBUGGING_INFO
99*404b540aSrobert #include "xcoffout.h" /* Needed for external data
100*404b540aSrobert declarations for e.g. AIX 4.x. */
101*404b540aSrobert #endif
102*404b540aSrobert
103*404b540aSrobert /* Global variables used to communicate with passes. */
104*404b540aSrobert int dump_flags;
105*404b540aSrobert bool in_gimple_form;
106*404b540aSrobert
107*404b540aSrobert
108*404b540aSrobert /* This is called from various places for FUNCTION_DECL, VAR_DECL,
109*404b540aSrobert and TYPE_DECL nodes.
110*404b540aSrobert
111*404b540aSrobert This does nothing for local (non-static) variables, unless the
112*404b540aSrobert variable is a register variable with DECL_ASSEMBLER_NAME set. In
113*404b540aSrobert that case, or if the variable is not an automatic, it sets up the
114*404b540aSrobert RTL and outputs any assembler code (label definition, storage
115*404b540aSrobert allocation and initialization).
116*404b540aSrobert
117*404b540aSrobert DECL is the declaration. TOP_LEVEL is nonzero
118*404b540aSrobert if this declaration is not within a function. */
119*404b540aSrobert
120*404b540aSrobert void
rest_of_decl_compilation(tree decl,int top_level,int at_end)121*404b540aSrobert rest_of_decl_compilation (tree decl,
122*404b540aSrobert int top_level,
123*404b540aSrobert int at_end)
124*404b540aSrobert {
125*404b540aSrobert /* We deferred calling assemble_alias so that we could collect
126*404b540aSrobert other attributes such as visibility. Emit the alias now. */
127*404b540aSrobert {
128*404b540aSrobert tree alias;
129*404b540aSrobert alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
130*404b540aSrobert if (alias)
131*404b540aSrobert {
132*404b540aSrobert alias = TREE_VALUE (TREE_VALUE (alias));
133*404b540aSrobert alias = get_identifier (TREE_STRING_POINTER (alias));
134*404b540aSrobert assemble_alias (decl, alias);
135*404b540aSrobert }
136*404b540aSrobert }
137*404b540aSrobert
138*404b540aSrobert /* Can't defer this, because it needs to happen before any
139*404b540aSrobert later function definitions are processed. */
140*404b540aSrobert if (DECL_ASSEMBLER_NAME_SET_P (decl) && DECL_REGISTER (decl))
141*404b540aSrobert make_decl_rtl (decl);
142*404b540aSrobert
143*404b540aSrobert /* Forward declarations for nested functions are not "external",
144*404b540aSrobert but we need to treat them as if they were. */
145*404b540aSrobert if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
146*404b540aSrobert || TREE_CODE (decl) == FUNCTION_DECL)
147*404b540aSrobert {
148*404b540aSrobert timevar_push (TV_VARCONST);
149*404b540aSrobert
150*404b540aSrobert /* Don't output anything when a tentative file-scope definition
151*404b540aSrobert is seen. But at end of compilation, do output code for them.
152*404b540aSrobert
153*404b540aSrobert We do output all variables when unit-at-a-time is active and rely on
154*404b540aSrobert callgraph code to defer them except for forward declarations
155*404b540aSrobert (see gcc.c-torture/compile/920624-1.c) */
156*404b540aSrobert if ((at_end
157*404b540aSrobert || !DECL_DEFER_OUTPUT (decl)
158*404b540aSrobert || DECL_INITIAL (decl))
159*404b540aSrobert && !DECL_EXTERNAL (decl))
160*404b540aSrobert {
161*404b540aSrobert if (TREE_CODE (decl) != FUNCTION_DECL)
162*404b540aSrobert cgraph_varpool_finalize_decl (decl);
163*404b540aSrobert else
164*404b540aSrobert assemble_variable (decl, top_level, at_end, 0);
165*404b540aSrobert }
166*404b540aSrobert
167*404b540aSrobert #ifdef ASM_FINISH_DECLARE_OBJECT
168*404b540aSrobert if (decl == last_assemble_variable_decl)
169*404b540aSrobert {
170*404b540aSrobert ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
171*404b540aSrobert top_level, at_end);
172*404b540aSrobert }
173*404b540aSrobert #endif
174*404b540aSrobert
175*404b540aSrobert timevar_pop (TV_VARCONST);
176*404b540aSrobert }
177*404b540aSrobert else if (TREE_CODE (decl) == TYPE_DECL
178*404b540aSrobert /* Like in rest_of_type_compilation, avoid confusing the debug
179*404b540aSrobert information machinery when there are errors. */
180*404b540aSrobert && !(sorrycount || errorcount))
181*404b540aSrobert {
182*404b540aSrobert timevar_push (TV_SYMOUT);
183*404b540aSrobert debug_hooks->type_decl (decl, !top_level);
184*404b540aSrobert timevar_pop (TV_SYMOUT);
185*404b540aSrobert }
186*404b540aSrobert
187*404b540aSrobert /* Let cgraph know about the existence of variables. */
188*404b540aSrobert if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
189*404b540aSrobert cgraph_varpool_node (decl);
190*404b540aSrobert }
191*404b540aSrobert
192*404b540aSrobert /* Called after finishing a record, union or enumeral type. */
193*404b540aSrobert
194*404b540aSrobert void
rest_of_type_compilation(tree type,int toplev)195*404b540aSrobert rest_of_type_compilation (tree type, int toplev)
196*404b540aSrobert {
197*404b540aSrobert /* Avoid confusing the debug information machinery when there are
198*404b540aSrobert errors. */
199*404b540aSrobert if (errorcount != 0 || sorrycount != 0)
200*404b540aSrobert return;
201*404b540aSrobert
202*404b540aSrobert timevar_push (TV_SYMOUT);
203*404b540aSrobert debug_hooks->type_decl (TYPE_STUB_DECL (type), !toplev);
204*404b540aSrobert timevar_pop (TV_SYMOUT);
205*404b540aSrobert }
206*404b540aSrobert
207*404b540aSrobert
208*404b540aSrobert
209*404b540aSrobert void
finish_optimization_passes(void)210*404b540aSrobert finish_optimization_passes (void)
211*404b540aSrobert {
212*404b540aSrobert enum tree_dump_index i;
213*404b540aSrobert struct dump_file_info *dfi;
214*404b540aSrobert char *name;
215*404b540aSrobert
216*404b540aSrobert timevar_push (TV_DUMP);
217*404b540aSrobert if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
218*404b540aSrobert {
219*404b540aSrobert dump_file = dump_begin (pass_profile.static_pass_number, NULL);
220*404b540aSrobert end_branch_prob ();
221*404b540aSrobert if (dump_file)
222*404b540aSrobert dump_end (pass_profile.static_pass_number, dump_file);
223*404b540aSrobert }
224*404b540aSrobert
225*404b540aSrobert if (optimize > 0)
226*404b540aSrobert {
227*404b540aSrobert dump_file = dump_begin (pass_combine.static_pass_number, NULL);
228*404b540aSrobert if (dump_file)
229*404b540aSrobert {
230*404b540aSrobert dump_combine_total_stats (dump_file);
231*404b540aSrobert dump_end (pass_combine.static_pass_number, dump_file);
232*404b540aSrobert }
233*404b540aSrobert }
234*404b540aSrobert
235*404b540aSrobert /* Do whatever is necessary to finish printing the graphs. */
236*404b540aSrobert if (graph_dump_format != no_graph)
237*404b540aSrobert for (i = TDI_end; (dfi = get_dump_file_info (i)) != NULL; ++i)
238*404b540aSrobert if (dump_initialized_p (i)
239*404b540aSrobert && (dfi->flags & TDF_GRAPH) != 0
240*404b540aSrobert && (name = get_dump_file_name (i)) != NULL)
241*404b540aSrobert {
242*404b540aSrobert finish_graph_dump_file (name);
243*404b540aSrobert free (name);
244*404b540aSrobert }
245*404b540aSrobert
246*404b540aSrobert timevar_pop (TV_DUMP);
247*404b540aSrobert }
248*404b540aSrobert
249*404b540aSrobert static bool
gate_rest_of_compilation(void)250*404b540aSrobert gate_rest_of_compilation (void)
251*404b540aSrobert {
252*404b540aSrobert /* Early return if there were errors. We can run afoul of our
253*404b540aSrobert consistency checks, and there's not really much point in fixing them. */
254*404b540aSrobert return !(rtl_dump_and_exit || flag_syntax_only || errorcount || sorrycount);
255*404b540aSrobert }
256*404b540aSrobert
257*404b540aSrobert struct tree_opt_pass pass_rest_of_compilation =
258*404b540aSrobert {
259*404b540aSrobert NULL, /* name */
260*404b540aSrobert gate_rest_of_compilation, /* gate */
261*404b540aSrobert NULL, /* execute */
262*404b540aSrobert NULL, /* sub */
263*404b540aSrobert NULL, /* next */
264*404b540aSrobert 0, /* static_pass_number */
265*404b540aSrobert TV_REST_OF_COMPILATION, /* tv_id */
266*404b540aSrobert PROP_rtl, /* properties_required */
267*404b540aSrobert 0, /* properties_provided */
268*404b540aSrobert 0, /* properties_destroyed */
269*404b540aSrobert 0, /* todo_flags_start */
270*404b540aSrobert TODO_ggc_collect, /* todo_flags_finish */
271*404b540aSrobert 0 /* letter */
272*404b540aSrobert };
273*404b540aSrobert
274*404b540aSrobert static bool
gate_postreload(void)275*404b540aSrobert gate_postreload (void)
276*404b540aSrobert {
277*404b540aSrobert return reload_completed;
278*404b540aSrobert }
279*404b540aSrobert
280*404b540aSrobert struct tree_opt_pass pass_postreload =
281*404b540aSrobert {
282*404b540aSrobert NULL, /* name */
283*404b540aSrobert gate_postreload, /* gate */
284*404b540aSrobert NULL, /* execute */
285*404b540aSrobert NULL, /* sub */
286*404b540aSrobert NULL, /* next */
287*404b540aSrobert 0, /* static_pass_number */
288*404b540aSrobert 0, /* tv_id */
289*404b540aSrobert PROP_rtl, /* properties_required */
290*404b540aSrobert 0, /* properties_provided */
291*404b540aSrobert 0, /* properties_destroyed */
292*404b540aSrobert 0, /* todo_flags_start */
293*404b540aSrobert TODO_ggc_collect, /* todo_flags_finish */
294*404b540aSrobert 0 /* letter */
295*404b540aSrobert };
296*404b540aSrobert
297*404b540aSrobert
298*404b540aSrobert
299*404b540aSrobert /* The root of the compilation pass tree, once constructed. */
300*404b540aSrobert struct tree_opt_pass *all_passes, *all_ipa_passes, *all_lowering_passes;
301*404b540aSrobert
302*404b540aSrobert /* Iterate over the pass tree allocating dump file numbers. We want
303*404b540aSrobert to do this depth first, and independent of whether the pass is
304*404b540aSrobert enabled or not. */
305*404b540aSrobert
306*404b540aSrobert static void
register_one_dump_file(struct tree_opt_pass * pass,bool ipa,int properties)307*404b540aSrobert register_one_dump_file (struct tree_opt_pass *pass, bool ipa, int properties)
308*404b540aSrobert {
309*404b540aSrobert char *dot_name, *flag_name, *glob_name;
310*404b540aSrobert const char *prefix;
311*404b540aSrobert char num[10];
312*404b540aSrobert int flags;
313*404b540aSrobert
314*404b540aSrobert /* See below in next_pass_1. */
315*404b540aSrobert num[0] = '\0';
316*404b540aSrobert if (pass->static_pass_number != -1)
317*404b540aSrobert sprintf (num, "%d", ((int) pass->static_pass_number < 0
318*404b540aSrobert ? 1 : pass->static_pass_number));
319*404b540aSrobert
320*404b540aSrobert dot_name = concat (".", pass->name, num, NULL);
321*404b540aSrobert if (ipa)
322*404b540aSrobert prefix = "ipa-", flags = TDF_IPA;
323*404b540aSrobert else if (properties & PROP_trees)
324*404b540aSrobert prefix = "tree-", flags = TDF_TREE;
325*404b540aSrobert else
326*404b540aSrobert prefix = "rtl-", flags = TDF_RTL;
327*404b540aSrobert
328*404b540aSrobert flag_name = concat (prefix, pass->name, num, NULL);
329*404b540aSrobert glob_name = concat (prefix, pass->name, NULL);
330*404b540aSrobert pass->static_pass_number = dump_register (dot_name, flag_name, glob_name,
331*404b540aSrobert flags, pass->letter);
332*404b540aSrobert }
333*404b540aSrobert
334*404b540aSrobert /* Recursive worker function for register_dump_files. */
335*404b540aSrobert
336*404b540aSrobert static int
register_dump_files_1(struct tree_opt_pass * pass,bool ipa,int properties)337*404b540aSrobert register_dump_files_1 (struct tree_opt_pass *pass, bool ipa, int properties)
338*404b540aSrobert {
339*404b540aSrobert do
340*404b540aSrobert {
341*404b540aSrobert int new_properties = (properties | pass->properties_provided)
342*404b540aSrobert & ~pass->properties_destroyed;
343*404b540aSrobert
344*404b540aSrobert if (pass->name)
345*404b540aSrobert register_one_dump_file (pass, ipa, new_properties);
346*404b540aSrobert
347*404b540aSrobert if (pass->sub)
348*404b540aSrobert new_properties = register_dump_files_1 (pass->sub, false,
349*404b540aSrobert new_properties);
350*404b540aSrobert
351*404b540aSrobert /* If we have a gate, combine the properties that we could have with
352*404b540aSrobert and without the pass being examined. */
353*404b540aSrobert if (pass->gate)
354*404b540aSrobert properties &= new_properties;
355*404b540aSrobert else
356*404b540aSrobert properties = new_properties;
357*404b540aSrobert
358*404b540aSrobert pass = pass->next;
359*404b540aSrobert }
360*404b540aSrobert while (pass);
361*404b540aSrobert
362*404b540aSrobert return properties;
363*404b540aSrobert }
364*404b540aSrobert
365*404b540aSrobert /* Register the dump files for the pipeline starting at PASS. IPA is
366*404b540aSrobert true if the pass is inter-procedural, and PROPERTIES reflects the
367*404b540aSrobert properties that are guaranteed to be available at the beginning of
368*404b540aSrobert the pipeline. */
369*404b540aSrobert
370*404b540aSrobert static void
register_dump_files(struct tree_opt_pass * pass,bool ipa,int properties)371*404b540aSrobert register_dump_files (struct tree_opt_pass *pass, bool ipa, int properties)
372*404b540aSrobert {
373*404b540aSrobert pass->properties_required |= properties;
374*404b540aSrobert pass->todo_flags_start |= TODO_set_props;
375*404b540aSrobert register_dump_files_1 (pass, ipa, properties);
376*404b540aSrobert }
377*404b540aSrobert
378*404b540aSrobert /* Add a pass to the pass list. Duplicate the pass if it's already
379*404b540aSrobert in the list. */
380*404b540aSrobert
381*404b540aSrobert static struct tree_opt_pass **
next_pass_1(struct tree_opt_pass ** list,struct tree_opt_pass * pass)382*404b540aSrobert next_pass_1 (struct tree_opt_pass **list, struct tree_opt_pass *pass)
383*404b540aSrobert {
384*404b540aSrobert /* A nonzero static_pass_number indicates that the
385*404b540aSrobert pass is already in the list. */
386*404b540aSrobert if (pass->static_pass_number)
387*404b540aSrobert {
388*404b540aSrobert struct tree_opt_pass *new;
389*404b540aSrobert
390*404b540aSrobert new = xmalloc (sizeof (*new));
391*404b540aSrobert memcpy (new, pass, sizeof (*new));
392*404b540aSrobert
393*404b540aSrobert /* Indicate to register_dump_files that this pass has duplicates,
394*404b540aSrobert and so it should rename the dump file. The first instance will
395*404b540aSrobert be -1, and be number of duplicates = -static_pass_number - 1.
396*404b540aSrobert Subsequent instances will be > 0 and just the duplicate number. */
397*404b540aSrobert if (pass->name)
398*404b540aSrobert {
399*404b540aSrobert pass->static_pass_number -= 1;
400*404b540aSrobert new->static_pass_number = -pass->static_pass_number;
401*404b540aSrobert }
402*404b540aSrobert
403*404b540aSrobert *list = new;
404*404b540aSrobert }
405*404b540aSrobert else
406*404b540aSrobert {
407*404b540aSrobert pass->static_pass_number = -1;
408*404b540aSrobert *list = pass;
409*404b540aSrobert }
410*404b540aSrobert
411*404b540aSrobert return &(*list)->next;
412*404b540aSrobert
413*404b540aSrobert }
414*404b540aSrobert
415*404b540aSrobert /* Construct the pass tree. The sequencing of passes is driven by
416*404b540aSrobert the cgraph routines:
417*404b540aSrobert
418*404b540aSrobert cgraph_finalize_compilation_unit ()
419*404b540aSrobert for each node N in the cgraph
420*404b540aSrobert cgraph_analyze_function (N)
421*404b540aSrobert cgraph_lower_function (N) -> all_lowering_passes
422*404b540aSrobert
423*404b540aSrobert If we are optimizing, cgraph_optimize is then invoked:
424*404b540aSrobert
425*404b540aSrobert cgraph_optimize ()
426*404b540aSrobert ipa_passes () -> all_ipa_passes
427*404b540aSrobert cgraph_expand_all_functions ()
428*404b540aSrobert for each node N in the cgraph
429*404b540aSrobert cgraph_expand_function (N)
430*404b540aSrobert cgraph_lower_function (N) -> Now a NOP.
431*404b540aSrobert lang_hooks.callgraph.expand_function (DECL (N))
432*404b540aSrobert tree_rest_of_compilation (DECL (N)) -> all_passes
433*404b540aSrobert */
434*404b540aSrobert
435*404b540aSrobert void
init_optimization_passes(void)436*404b540aSrobert init_optimization_passes (void)
437*404b540aSrobert {
438*404b540aSrobert struct tree_opt_pass **p;
439*404b540aSrobert
440*404b540aSrobert #define NEXT_PASS(PASS) (p = next_pass_1 (p, &PASS))
441*404b540aSrobert /* Interprocedural optimization passes. */
442*404b540aSrobert p = &all_ipa_passes;
443*404b540aSrobert NEXT_PASS (pass_early_ipa_inline);
444*404b540aSrobert NEXT_PASS (pass_early_local_passes);
445*404b540aSrobert NEXT_PASS (pass_ipa_cp);
446*404b540aSrobert NEXT_PASS (pass_ipa_inline);
447*404b540aSrobert NEXT_PASS (pass_ipa_reference);
448*404b540aSrobert NEXT_PASS (pass_ipa_pure_const);
449*404b540aSrobert NEXT_PASS (pass_ipa_type_escape);
450*404b540aSrobert NEXT_PASS (pass_ipa_pta);
451*404b540aSrobert *p = NULL;
452*404b540aSrobert
453*404b540aSrobert /* All passes needed to lower the function into shape optimizers can
454*404b540aSrobert operate on. */
455*404b540aSrobert p = &all_lowering_passes;
456*404b540aSrobert NEXT_PASS (pass_remove_useless_stmts);
457*404b540aSrobert NEXT_PASS (pass_mudflap_1);
458*404b540aSrobert NEXT_PASS (pass_lower_omp);
459*404b540aSrobert NEXT_PASS (pass_lower_cf);
460*404b540aSrobert NEXT_PASS (pass_lower_eh);
461*404b540aSrobert NEXT_PASS (pass_build_cfg);
462*404b540aSrobert NEXT_PASS (pass_lower_complex_O0);
463*404b540aSrobert NEXT_PASS (pass_lower_vector);
464*404b540aSrobert NEXT_PASS (pass_warn_function_return);
465*404b540aSrobert NEXT_PASS (pass_early_tree_profile);
466*404b540aSrobert *p = NULL;
467*404b540aSrobert
468*404b540aSrobert p = &pass_early_local_passes.sub;
469*404b540aSrobert NEXT_PASS (pass_tree_profile);
470*404b540aSrobert NEXT_PASS (pass_cleanup_cfg);
471*404b540aSrobert NEXT_PASS (pass_rebuild_cgraph_edges);
472*404b540aSrobert *p = NULL;
473*404b540aSrobert
474*404b540aSrobert p = &all_passes;
475*404b540aSrobert NEXT_PASS (pass_fixup_cfg);
476*404b540aSrobert NEXT_PASS (pass_init_datastructures);
477*404b540aSrobert NEXT_PASS (pass_expand_omp);
478*404b540aSrobert NEXT_PASS (pass_all_optimizations);
479*404b540aSrobert NEXT_PASS (pass_warn_function_noreturn);
480*404b540aSrobert NEXT_PASS (pass_mudflap_2);
481*404b540aSrobert NEXT_PASS (pass_free_datastructures);
482*404b540aSrobert NEXT_PASS (pass_free_cfg_annotations);
483*404b540aSrobert NEXT_PASS (pass_expand);
484*404b540aSrobert NEXT_PASS (pass_rest_of_compilation);
485*404b540aSrobert NEXT_PASS (pass_clean_state);
486*404b540aSrobert *p = NULL;
487*404b540aSrobert
488*404b540aSrobert p = &pass_all_optimizations.sub;
489*404b540aSrobert NEXT_PASS (pass_referenced_vars);
490*404b540aSrobert NEXT_PASS (pass_reset_cc_flags);
491*404b540aSrobert NEXT_PASS (pass_create_structure_vars);
492*404b540aSrobert NEXT_PASS (pass_build_ssa);
493*404b540aSrobert NEXT_PASS (pass_may_alias);
494*404b540aSrobert NEXT_PASS (pass_return_slot);
495*404b540aSrobert NEXT_PASS (pass_rename_ssa_copies);
496*404b540aSrobert NEXT_PASS (pass_early_warn_uninitialized);
497*404b540aSrobert
498*404b540aSrobert /* Initial scalar cleanups. */
499*404b540aSrobert NEXT_PASS (pass_ccp);
500*404b540aSrobert NEXT_PASS (pass_fre);
501*404b540aSrobert NEXT_PASS (pass_dce);
502*404b540aSrobert NEXT_PASS (pass_forwprop);
503*404b540aSrobert NEXT_PASS (pass_copy_prop);
504*404b540aSrobert NEXT_PASS (pass_merge_phi);
505*404b540aSrobert NEXT_PASS (pass_vrp);
506*404b540aSrobert NEXT_PASS (pass_dce);
507*404b540aSrobert NEXT_PASS (pass_dominator);
508*404b540aSrobert
509*404b540aSrobert /* The only const/copy propagation opportunities left after
510*404b540aSrobert DOM should be due to degenerate PHI nodes. So rather than
511*404b540aSrobert run the full propagators, run a specialized pass which
512*404b540aSrobert only examines PHIs to discover const/copy propagation
513*404b540aSrobert opportunities. */
514*404b540aSrobert NEXT_PASS (pass_phi_only_cprop);
515*404b540aSrobert
516*404b540aSrobert NEXT_PASS (pass_phiopt);
517*404b540aSrobert NEXT_PASS (pass_may_alias);
518*404b540aSrobert NEXT_PASS (pass_tail_recursion);
519*404b540aSrobert NEXT_PASS (pass_profile);
520*404b540aSrobert NEXT_PASS (pass_ch);
521*404b540aSrobert NEXT_PASS (pass_stdarg);
522*404b540aSrobert NEXT_PASS (pass_lower_complex);
523*404b540aSrobert NEXT_PASS (pass_sra);
524*404b540aSrobert /* FIXME: SRA may generate arbitrary gimple code, exposing new
525*404b540aSrobert aliased and call-clobbered variables. As mentioned below,
526*404b540aSrobert pass_may_alias should be a TODO item. */
527*404b540aSrobert NEXT_PASS (pass_may_alias);
528*404b540aSrobert NEXT_PASS (pass_rename_ssa_copies);
529*404b540aSrobert NEXT_PASS (pass_dominator);
530*404b540aSrobert
531*404b540aSrobert /* The only const/copy propagation opportunities left after
532*404b540aSrobert DOM should be due to degenerate PHI nodes. So rather than
533*404b540aSrobert run the full propagators, run a specialized pass which
534*404b540aSrobert only examines PHIs to discover const/copy propagation
535*404b540aSrobert opportunities. */
536*404b540aSrobert NEXT_PASS (pass_phi_only_cprop);
537*404b540aSrobert
538*404b540aSrobert NEXT_PASS (pass_reassoc);
539*404b540aSrobert NEXT_PASS (pass_dce);
540*404b540aSrobert NEXT_PASS (pass_dse);
541*404b540aSrobert NEXT_PASS (pass_may_alias);
542*404b540aSrobert NEXT_PASS (pass_forwprop);
543*404b540aSrobert NEXT_PASS (pass_phiopt);
544*404b540aSrobert NEXT_PASS (pass_object_sizes);
545*404b540aSrobert NEXT_PASS (pass_store_ccp);
546*404b540aSrobert NEXT_PASS (pass_store_copy_prop);
547*404b540aSrobert NEXT_PASS (pass_fold_builtins);
548*404b540aSrobert /* FIXME: May alias should a TODO but for 4.0.0,
549*404b540aSrobert we add may_alias right after fold builtins
550*404b540aSrobert which can create arbitrary GIMPLE. */
551*404b540aSrobert NEXT_PASS (pass_may_alias);
552*404b540aSrobert NEXT_PASS (pass_split_crit_edges);
553*404b540aSrobert NEXT_PASS (pass_pre);
554*404b540aSrobert NEXT_PASS (pass_may_alias);
555*404b540aSrobert NEXT_PASS (pass_sink_code);
556*404b540aSrobert NEXT_PASS (pass_tree_loop);
557*404b540aSrobert NEXT_PASS (pass_cse_reciprocals);
558*404b540aSrobert NEXT_PASS (pass_reassoc);
559*404b540aSrobert NEXT_PASS (pass_vrp);
560*404b540aSrobert NEXT_PASS (pass_dominator);
561*404b540aSrobert
562*404b540aSrobert /* The only const/copy propagation opportunities left after
563*404b540aSrobert DOM should be due to degenerate PHI nodes. So rather than
564*404b540aSrobert run the full propagators, run a specialized pass which
565*404b540aSrobert only examines PHIs to discover const/copy propagation
566*404b540aSrobert opportunities. */
567*404b540aSrobert NEXT_PASS (pass_phi_only_cprop);
568*404b540aSrobert
569*404b540aSrobert NEXT_PASS (pass_cd_dce);
570*404b540aSrobert
571*404b540aSrobert /* FIXME: If DCE is not run before checking for uninitialized uses,
572*404b540aSrobert we may get false warnings (e.g., testsuite/gcc.dg/uninit-5.c).
573*404b540aSrobert However, this also causes us to misdiagnose cases that should be
574*404b540aSrobert real warnings (e.g., testsuite/gcc.dg/pr18501.c).
575*404b540aSrobert
576*404b540aSrobert To fix the false positives in uninit-5.c, we would have to
577*404b540aSrobert account for the predicates protecting the set and the use of each
578*404b540aSrobert variable. Using a representation like Gated Single Assignment
579*404b540aSrobert may help. */
580*404b540aSrobert NEXT_PASS (pass_late_warn_uninitialized);
581*404b540aSrobert NEXT_PASS (pass_dse);
582*404b540aSrobert NEXT_PASS (pass_forwprop);
583*404b540aSrobert NEXT_PASS (pass_phiopt);
584*404b540aSrobert NEXT_PASS (pass_tail_calls);
585*404b540aSrobert NEXT_PASS (pass_rename_ssa_copies);
586*404b540aSrobert NEXT_PASS (pass_uncprop);
587*404b540aSrobert NEXT_PASS (pass_del_ssa);
588*404b540aSrobert NEXT_PASS (pass_nrv);
589*404b540aSrobert NEXT_PASS (pass_mark_used_blocks);
590*404b540aSrobert NEXT_PASS (pass_cleanup_cfg_post_optimizing);
591*404b540aSrobert *p = NULL;
592*404b540aSrobert
593*404b540aSrobert p = &pass_tree_loop.sub;
594*404b540aSrobert NEXT_PASS (pass_tree_loop_init);
595*404b540aSrobert NEXT_PASS (pass_copy_prop);
596*404b540aSrobert NEXT_PASS (pass_lim);
597*404b540aSrobert NEXT_PASS (pass_tree_unswitch);
598*404b540aSrobert NEXT_PASS (pass_scev_cprop);
599*404b540aSrobert NEXT_PASS (pass_empty_loop);
600*404b540aSrobert NEXT_PASS (pass_record_bounds);
601*404b540aSrobert NEXT_PASS (pass_linear_transform);
602*404b540aSrobert NEXT_PASS (pass_iv_canon);
603*404b540aSrobert NEXT_PASS (pass_if_conversion);
604*404b540aSrobert NEXT_PASS (pass_vectorize);
605*404b540aSrobert /* NEXT_PASS (pass_may_alias) cannot be done again because the
606*404b540aSrobert vectorizer creates alias relations that are not supported by
607*404b540aSrobert pass_may_alias. */
608*404b540aSrobert NEXT_PASS (pass_complete_unroll);
609*404b540aSrobert NEXT_PASS (pass_loop_prefetch);
610*404b540aSrobert NEXT_PASS (pass_iv_optimize);
611*404b540aSrobert NEXT_PASS (pass_tree_loop_done);
612*404b540aSrobert *p = NULL;
613*404b540aSrobert
614*404b540aSrobert p = &pass_vectorize.sub;
615*404b540aSrobert NEXT_PASS (pass_lower_vector_ssa);
616*404b540aSrobert NEXT_PASS (pass_dce_loop);
617*404b540aSrobert *p = NULL;
618*404b540aSrobert
619*404b540aSrobert p = &pass_loop2.sub;
620*404b540aSrobert NEXT_PASS (pass_rtl_loop_init);
621*404b540aSrobert NEXT_PASS (pass_rtl_move_loop_invariants);
622*404b540aSrobert NEXT_PASS (pass_rtl_unswitch);
623*404b540aSrobert NEXT_PASS (pass_rtl_unroll_and_peel_loops);
624*404b540aSrobert NEXT_PASS (pass_rtl_doloop);
625*404b540aSrobert NEXT_PASS (pass_rtl_loop_done);
626*404b540aSrobert *p = NULL;
627*404b540aSrobert
628*404b540aSrobert p = &pass_rest_of_compilation.sub;
629*404b540aSrobert NEXT_PASS (pass_init_function);
630*404b540aSrobert NEXT_PASS (pass_jump);
631*404b540aSrobert NEXT_PASS (pass_insn_locators_initialize);
632*404b540aSrobert NEXT_PASS (pass_rtl_eh);
633*404b540aSrobert NEXT_PASS (pass_initial_value_sets);
634*404b540aSrobert NEXT_PASS (pass_unshare_all_rtl);
635*404b540aSrobert NEXT_PASS (pass_instantiate_virtual_regs);
636*404b540aSrobert NEXT_PASS (pass_jump2);
637*404b540aSrobert NEXT_PASS (pass_cse);
638*404b540aSrobert NEXT_PASS (pass_gcse);
639*404b540aSrobert NEXT_PASS (pass_jump_bypass);
640*404b540aSrobert NEXT_PASS (pass_rtl_ifcvt);
641*404b540aSrobert NEXT_PASS (pass_tracer);
642*404b540aSrobert /* Perform loop optimizations. It might be better to do them a bit
643*404b540aSrobert sooner, but we want the profile feedback to work more
644*404b540aSrobert efficiently. */
645*404b540aSrobert NEXT_PASS (pass_loop2);
646*404b540aSrobert NEXT_PASS (pass_web);
647*404b540aSrobert NEXT_PASS (pass_cse2);
648*404b540aSrobert NEXT_PASS (pass_life);
649*404b540aSrobert NEXT_PASS (pass_combine);
650*404b540aSrobert NEXT_PASS (pass_if_after_combine);
651*404b540aSrobert NEXT_PASS (pass_partition_blocks);
652*404b540aSrobert NEXT_PASS (pass_regmove);
653*404b540aSrobert NEXT_PASS (pass_split_all_insns);
654*404b540aSrobert NEXT_PASS (pass_mode_switching);
655*404b540aSrobert NEXT_PASS (pass_see);
656*404b540aSrobert NEXT_PASS (pass_recompute_reg_usage);
657*404b540aSrobert NEXT_PASS (pass_sms);
658*404b540aSrobert NEXT_PASS (pass_sched);
659*404b540aSrobert NEXT_PASS (pass_local_alloc);
660*404b540aSrobert NEXT_PASS (pass_global_alloc);
661*404b540aSrobert NEXT_PASS (pass_postreload);
662*404b540aSrobert *p = NULL;
663*404b540aSrobert
664*404b540aSrobert p = &pass_postreload.sub;
665*404b540aSrobert NEXT_PASS (pass_postreload_cse);
666*404b540aSrobert NEXT_PASS (pass_gcse2);
667*404b540aSrobert NEXT_PASS (pass_flow2);
668*404b540aSrobert NEXT_PASS (pass_rtl_seqabstr);
669*404b540aSrobert NEXT_PASS (pass_stack_adjustments);
670*404b540aSrobert NEXT_PASS (pass_peephole2);
671*404b540aSrobert NEXT_PASS (pass_if_after_reload);
672*404b540aSrobert NEXT_PASS (pass_regrename);
673*404b540aSrobert NEXT_PASS (pass_reorder_blocks);
674*404b540aSrobert NEXT_PASS (pass_branch_target_load_optimize);
675*404b540aSrobert NEXT_PASS (pass_leaf_regs);
676*404b540aSrobert NEXT_PASS (pass_sched2);
677*404b540aSrobert NEXT_PASS (pass_split_before_regstack);
678*404b540aSrobert NEXT_PASS (pass_stack_regs);
679*404b540aSrobert NEXT_PASS (pass_compute_alignments);
680*404b540aSrobert NEXT_PASS (pass_duplicate_computed_gotos);
681*404b540aSrobert NEXT_PASS (pass_variable_tracking);
682*404b540aSrobert NEXT_PASS (pass_free_cfg);
683*404b540aSrobert NEXT_PASS (pass_machine_reorg);
684*404b540aSrobert NEXT_PASS (pass_purge_lineno_notes);
685*404b540aSrobert NEXT_PASS (pass_cleanup_barriers);
686*404b540aSrobert NEXT_PASS (pass_delay_slots);
687*404b540aSrobert NEXT_PASS (pass_split_for_shorten_branches);
688*404b540aSrobert NEXT_PASS (pass_convert_to_eh_region_ranges);
689*404b540aSrobert NEXT_PASS (pass_shorten_branches);
690*404b540aSrobert NEXT_PASS (pass_set_nothrow_function_flags);
691*404b540aSrobert NEXT_PASS (pass_final);
692*404b540aSrobert *p = NULL;
693*404b540aSrobert
694*404b540aSrobert #undef NEXT_PASS
695*404b540aSrobert
696*404b540aSrobert /* Register the passes with the tree dump code. */
697*404b540aSrobert register_dump_files (all_ipa_passes, true,
698*404b540aSrobert PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
699*404b540aSrobert | PROP_cfg);
700*404b540aSrobert register_dump_files (all_lowering_passes, false, PROP_gimple_any);
701*404b540aSrobert register_dump_files (all_passes, false,
702*404b540aSrobert PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
703*404b540aSrobert | PROP_cfg);
704*404b540aSrobert }
705*404b540aSrobert
706*404b540aSrobert static unsigned int last_verified;
707*404b540aSrobert static unsigned int curr_properties;
708*404b540aSrobert
709*404b540aSrobert static void
execute_todo(unsigned int flags)710*404b540aSrobert execute_todo (unsigned int flags)
711*404b540aSrobert {
712*404b540aSrobert #if defined ENABLE_CHECKING
713*404b540aSrobert if (need_ssa_update_p ())
714*404b540aSrobert gcc_assert (flags & TODO_update_ssa_any);
715*404b540aSrobert #endif
716*404b540aSrobert
717*404b540aSrobert if (curr_properties & PROP_ssa)
718*404b540aSrobert flags |= TODO_verify_ssa;
719*404b540aSrobert flags &= ~last_verified;
720*404b540aSrobert if (!flags)
721*404b540aSrobert return;
722*404b540aSrobert
723*404b540aSrobert /* Always recalculate SMT usage before doing anything else. */
724*404b540aSrobert if (flags & TODO_update_smt_usage)
725*404b540aSrobert recalculate_used_alone ();
726*404b540aSrobert
727*404b540aSrobert /* Always cleanup the CFG before trying to update SSA . */
728*404b540aSrobert if (flags & TODO_cleanup_cfg)
729*404b540aSrobert {
730*404b540aSrobert /* CFG Cleanup can cause a constant to prop into an ARRAY_REF. */
731*404b540aSrobert updating_used_alone = true;
732*404b540aSrobert
733*404b540aSrobert if (current_loops)
734*404b540aSrobert cleanup_tree_cfg_loop ();
735*404b540aSrobert else
736*404b540aSrobert cleanup_tree_cfg ();
737*404b540aSrobert
738*404b540aSrobert /* Update the used alone after cleanup cfg. */
739*404b540aSrobert recalculate_used_alone ();
740*404b540aSrobert
741*404b540aSrobert /* When cleanup_tree_cfg merges consecutive blocks, it may
742*404b540aSrobert perform some simplistic propagation when removing single
743*404b540aSrobert valued PHI nodes. This propagation may, in turn, cause the
744*404b540aSrobert SSA form to become out-of-date (see PR 22037). So, even
745*404b540aSrobert if the parent pass had not scheduled an SSA update, we may
746*404b540aSrobert still need to do one. */
747*404b540aSrobert if (!(flags & TODO_update_ssa_any) && need_ssa_update_p ())
748*404b540aSrobert flags |= TODO_update_ssa;
749*404b540aSrobert }
750*404b540aSrobert
751*404b540aSrobert if (flags & TODO_update_ssa_any)
752*404b540aSrobert {
753*404b540aSrobert unsigned update_flags = flags & TODO_update_ssa_any;
754*404b540aSrobert update_ssa (update_flags);
755*404b540aSrobert last_verified &= ~TODO_verify_ssa;
756*404b540aSrobert }
757*404b540aSrobert
758*404b540aSrobert if (flags & TODO_remove_unused_locals)
759*404b540aSrobert remove_unused_locals ();
760*404b540aSrobert
761*404b540aSrobert if ((flags & TODO_dump_func)
762*404b540aSrobert && dump_file && current_function_decl)
763*404b540aSrobert {
764*404b540aSrobert if (curr_properties & PROP_trees)
765*404b540aSrobert dump_function_to_file (current_function_decl,
766*404b540aSrobert dump_file, dump_flags);
767*404b540aSrobert else
768*404b540aSrobert {
769*404b540aSrobert if (dump_flags & TDF_SLIM)
770*404b540aSrobert print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags);
771*404b540aSrobert else if ((curr_properties & PROP_cfg) && (dump_flags & TDF_BLOCKS))
772*404b540aSrobert print_rtl_with_bb (dump_file, get_insns ());
773*404b540aSrobert else
774*404b540aSrobert print_rtl (dump_file, get_insns ());
775*404b540aSrobert
776*404b540aSrobert if (curr_properties & PROP_cfg
777*404b540aSrobert && graph_dump_format != no_graph
778*404b540aSrobert && (dump_flags & TDF_GRAPH))
779*404b540aSrobert print_rtl_graph_with_bb (dump_file_name, get_insns ());
780*404b540aSrobert }
781*404b540aSrobert
782*404b540aSrobert /* Flush the file. If verification fails, we won't be able to
783*404b540aSrobert close the file before aborting. */
784*404b540aSrobert fflush (dump_file);
785*404b540aSrobert }
786*404b540aSrobert if ((flags & TODO_dump_cgraph)
787*404b540aSrobert && dump_file && !current_function_decl)
788*404b540aSrobert {
789*404b540aSrobert dump_cgraph (dump_file);
790*404b540aSrobert /* Flush the file. If verification fails, we won't be able to
791*404b540aSrobert close the file before aborting. */
792*404b540aSrobert fflush (dump_file);
793*404b540aSrobert }
794*404b540aSrobert
795*404b540aSrobert if (flags & TODO_ggc_collect)
796*404b540aSrobert {
797*404b540aSrobert ggc_collect ();
798*404b540aSrobert }
799*404b540aSrobert
800*404b540aSrobert #if defined ENABLE_CHECKING
801*404b540aSrobert if (flags & TODO_verify_ssa)
802*404b540aSrobert verify_ssa (true);
803*404b540aSrobert if (flags & TODO_verify_flow)
804*404b540aSrobert verify_flow_info ();
805*404b540aSrobert if (flags & TODO_verify_stmts)
806*404b540aSrobert verify_stmts ();
807*404b540aSrobert if (flags & TODO_verify_loops)
808*404b540aSrobert verify_loop_closed_ssa ();
809*404b540aSrobert #endif
810*404b540aSrobert
811*404b540aSrobert last_verified = flags & TODO_verify_all;
812*404b540aSrobert }
813*404b540aSrobert
814*404b540aSrobert /* Verify invariants that should hold between passes. This is a place
815*404b540aSrobert to put simple sanity checks. */
816*404b540aSrobert
817*404b540aSrobert static void
verify_interpass_invariants(void)818*404b540aSrobert verify_interpass_invariants (void)
819*404b540aSrobert {
820*404b540aSrobert #ifdef ENABLE_CHECKING
821*404b540aSrobert gcc_assert (!fold_deferring_overflow_warnings_p ());
822*404b540aSrobert #endif
823*404b540aSrobert }
824*404b540aSrobert
825*404b540aSrobert static bool
execute_one_pass(struct tree_opt_pass * pass)826*404b540aSrobert execute_one_pass (struct tree_opt_pass *pass)
827*404b540aSrobert {
828*404b540aSrobert bool initializing_dump;
829*404b540aSrobert unsigned int todo_after = 0;
830*404b540aSrobert
831*404b540aSrobert /* See if we're supposed to run this pass. */
832*404b540aSrobert if (pass->gate && !pass->gate ())
833*404b540aSrobert return false;
834*404b540aSrobert
835*404b540aSrobert if (pass->todo_flags_start & TODO_set_props)
836*404b540aSrobert curr_properties = pass->properties_required;
837*404b540aSrobert
838*404b540aSrobert /* Note that the folders should only create gimple expressions.
839*404b540aSrobert This is a hack until the new folder is ready. */
840*404b540aSrobert in_gimple_form = (curr_properties & PROP_trees) != 0;
841*404b540aSrobert
842*404b540aSrobert /* Run pre-pass verification. */
843*404b540aSrobert execute_todo (pass->todo_flags_start);
844*404b540aSrobert
845*404b540aSrobert gcc_assert ((curr_properties & pass->properties_required)
846*404b540aSrobert == pass->properties_required);
847*404b540aSrobert
848*404b540aSrobert if (pass->properties_destroyed & PROP_smt_usage)
849*404b540aSrobert updating_used_alone = true;
850*404b540aSrobert
851*404b540aSrobert /* If a dump file name is present, open it if enabled. */
852*404b540aSrobert if (pass->static_pass_number != -1)
853*404b540aSrobert {
854*404b540aSrobert initializing_dump = !dump_initialized_p (pass->static_pass_number);
855*404b540aSrobert dump_file_name = get_dump_file_name (pass->static_pass_number);
856*404b540aSrobert dump_file = dump_begin (pass->static_pass_number, &dump_flags);
857*404b540aSrobert if (dump_file && current_function_decl)
858*404b540aSrobert {
859*404b540aSrobert const char *dname, *aname;
860*404b540aSrobert dname = lang_hooks.decl_printable_name (current_function_decl, 2);
861*404b540aSrobert aname = (IDENTIFIER_POINTER
862*404b540aSrobert (DECL_ASSEMBLER_NAME (current_function_decl)));
863*404b540aSrobert fprintf (dump_file, "\n;; Function %s (%s)%s\n\n", dname, aname,
864*404b540aSrobert cfun->function_frequency == FUNCTION_FREQUENCY_HOT
865*404b540aSrobert ? " (hot)"
866*404b540aSrobert : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED
867*404b540aSrobert ? " (unlikely executed)"
868*404b540aSrobert : "");
869*404b540aSrobert }
870*404b540aSrobert }
871*404b540aSrobert else
872*404b540aSrobert initializing_dump = false;
873*404b540aSrobert
874*404b540aSrobert /* If a timevar is present, start it. */
875*404b540aSrobert if (pass->tv_id)
876*404b540aSrobert timevar_push (pass->tv_id);
877*404b540aSrobert
878*404b540aSrobert /* Do it! */
879*404b540aSrobert if (pass->execute)
880*404b540aSrobert {
881*404b540aSrobert todo_after = pass->execute ();
882*404b540aSrobert last_verified = 0;
883*404b540aSrobert }
884*404b540aSrobert
885*404b540aSrobert /* Stop timevar. */
886*404b540aSrobert if (pass->tv_id)
887*404b540aSrobert timevar_pop (pass->tv_id);
888*404b540aSrobert
889*404b540aSrobert curr_properties = (curr_properties | pass->properties_provided)
890*404b540aSrobert & ~pass->properties_destroyed;
891*404b540aSrobert
892*404b540aSrobert if (initializing_dump
893*404b540aSrobert && dump_file
894*404b540aSrobert && graph_dump_format != no_graph
895*404b540aSrobert && (curr_properties & (PROP_cfg | PROP_rtl)) == (PROP_cfg | PROP_rtl))
896*404b540aSrobert {
897*404b540aSrobert get_dump_file_info (pass->static_pass_number)->flags |= TDF_GRAPH;
898*404b540aSrobert dump_flags |= TDF_GRAPH;
899*404b540aSrobert clean_graph_dump_file (dump_file_name);
900*404b540aSrobert }
901*404b540aSrobert
902*404b540aSrobert /* Run post-pass cleanup and verification. */
903*404b540aSrobert execute_todo (todo_after | pass->todo_flags_finish);
904*404b540aSrobert verify_interpass_invariants ();
905*404b540aSrobert
906*404b540aSrobert /* Flush and close dump file. */
907*404b540aSrobert if (dump_file_name)
908*404b540aSrobert {
909*404b540aSrobert free ((char *) dump_file_name);
910*404b540aSrobert dump_file_name = NULL;
911*404b540aSrobert }
912*404b540aSrobert if (dump_file)
913*404b540aSrobert {
914*404b540aSrobert dump_end (pass->static_pass_number, dump_file);
915*404b540aSrobert dump_file = NULL;
916*404b540aSrobert }
917*404b540aSrobert
918*404b540aSrobert if (pass->properties_destroyed & PROP_smt_usage)
919*404b540aSrobert updating_used_alone = false;
920*404b540aSrobert
921*404b540aSrobert /* Reset in_gimple_form to not break non-unit-at-a-time mode. */
922*404b540aSrobert in_gimple_form = false;
923*404b540aSrobert
924*404b540aSrobert return true;
925*404b540aSrobert }
926*404b540aSrobert
927*404b540aSrobert void
execute_pass_list(struct tree_opt_pass * pass)928*404b540aSrobert execute_pass_list (struct tree_opt_pass *pass)
929*404b540aSrobert {
930*404b540aSrobert do
931*404b540aSrobert {
932*404b540aSrobert if (execute_one_pass (pass) && pass->sub)
933*404b540aSrobert execute_pass_list (pass->sub);
934*404b540aSrobert pass = pass->next;
935*404b540aSrobert }
936*404b540aSrobert while (pass);
937*404b540aSrobert }
938*404b540aSrobert
939*404b540aSrobert /* Same as execute_pass_list but assume that subpasses of IPA passes
940*404b540aSrobert are local passes. */
941*404b540aSrobert void
execute_ipa_pass_list(struct tree_opt_pass * pass)942*404b540aSrobert execute_ipa_pass_list (struct tree_opt_pass *pass)
943*404b540aSrobert {
944*404b540aSrobert do
945*404b540aSrobert {
946*404b540aSrobert if (execute_one_pass (pass) && pass->sub)
947*404b540aSrobert {
948*404b540aSrobert struct cgraph_node *node;
949*404b540aSrobert for (node = cgraph_nodes; node; node = node->next)
950*404b540aSrobert if (node->analyzed)
951*404b540aSrobert {
952*404b540aSrobert push_cfun (DECL_STRUCT_FUNCTION (node->decl));
953*404b540aSrobert current_function_decl = node->decl;
954*404b540aSrobert execute_pass_list (pass->sub);
955*404b540aSrobert free_dominance_info (CDI_DOMINATORS);
956*404b540aSrobert free_dominance_info (CDI_POST_DOMINATORS);
957*404b540aSrobert current_function_decl = NULL;
958*404b540aSrobert pop_cfun ();
959*404b540aSrobert ggc_collect ();
960*404b540aSrobert }
961*404b540aSrobert }
962*404b540aSrobert pass = pass->next;
963*404b540aSrobert }
964*404b540aSrobert while (pass);
965*404b540aSrobert }
966