xref: /openbsd-src/gnu/gcc/gcc/passes.c (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
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