OSDN Git Service

* tree-sra.c (try_instantiate_multiple_fields): Needlessly
[pf3gnuchains/gcc-fork.git] / gcc / tree-optimize.c
1 /* Top-level control of tree optimizations.
2    Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3    Contributed by Diego Novillo <dnovillo@redhat.com>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "tm_p.h"
29 #include "hard-reg-set.h"
30 #include "basic-block.h"
31 #include "output.h"
32 #include "expr.h"
33 #include "diagnostic.h"
34 #include "basic-block.h"
35 #include "flags.h"
36 #include "tree-flow.h"
37 #include "tree-dump.h"
38 #include "timevar.h"
39 #include "function.h"
40 #include "langhooks.h"
41 #include "toplev.h"
42 #include "flags.h"
43 #include "cgraph.h"
44 #include "tree-inline.h"
45 #include "tree-mudflap.h"
46 #include "tree-pass.h"
47 #include "ggc.h"
48 #include "cgraph.h"
49 #include "graph.h"
50 #include "cfgloop.h"
51 #include "except.h"
52
53
54 /* Gate: execute, or not, all of the non-trivial optimizations.  */
55
56 static bool
57 gate_all_optimizations (void)
58 {
59   return (optimize >= 1
60           /* Don't bother doing anything if the program has errors. 
61              We have to pass down the queue if we already went into SSA */
62           && (!(errorcount || sorrycount) || gimple_in_ssa_p (cfun)));
63 }
64
65 struct tree_opt_pass pass_all_optimizations =
66 {
67   NULL,                                 /* name */
68   gate_all_optimizations,               /* gate */
69   NULL,                                 /* execute */
70   NULL,                                 /* sub */
71   NULL,                                 /* next */
72   0,                                    /* static_pass_number */
73   0,                                    /* tv_id */
74   0,                                    /* properties_required */
75   0,                                    /* properties_provided */
76   0,                                    /* properties_destroyed */
77   0,                                    /* todo_flags_start */
78   0,                                    /* todo_flags_finish */
79   0                                     /* letter */
80 };
81
82 /* Gate: execute, or not, all of the non-trivial optimizations.  */
83
84 static bool
85 gate_all_early_local_passes (void)
86 {
87           /* Don't bother doing anything if the program has errors.  */
88   return (!errorcount && !sorrycount);
89 }
90
91 struct tree_opt_pass pass_early_local_passes =
92 {
93   "early_local_cleanups",               /* name */
94   gate_all_early_local_passes,          /* gate */
95   NULL,                                 /* execute */
96   NULL,                                 /* sub */
97   NULL,                                 /* next */
98   0,                                    /* static_pass_number */
99   0,                                    /* tv_id */
100   0,                                    /* properties_required */
101   0,                                    /* properties_provided */
102   0,                                    /* properties_destroyed */
103   0,                                    /* todo_flags_start */
104   TODO_remove_functions,                /* todo_flags_finish */
105   0                                     /* letter */
106 };
107
108 static unsigned int
109 execute_early_local_optimizations (void)
110 {
111   if (flag_unit_at_a_time)
112     cgraph_state = CGRAPH_STATE_IPA_SSA;
113   return 0;
114 }
115
116 /* Gate: execute, or not, all of the non-trivial optimizations.  */
117
118 static bool
119 gate_all_early_optimizations (void)
120 {
121   return (optimize >= 1
122           /* Don't bother doing anything if the program has errors.  */
123           && !(errorcount || sorrycount));
124 }
125
126 struct tree_opt_pass pass_all_early_optimizations =
127 {
128   "early_optimizations",                /* name */
129   gate_all_early_optimizations,         /* gate */
130   execute_early_local_optimizations,    /* execute */
131   NULL,                                 /* sub */
132   NULL,                                 /* next */
133   0,                                    /* static_pass_number */
134   0,                                    /* tv_id */
135   0,                                    /* properties_required */
136   0,                                    /* properties_provided */
137   0,                                    /* properties_destroyed */
138   0,                                    /* todo_flags_start */
139   0,                                    /* todo_flags_finish */
140   0                                     /* letter */
141 };
142
143 /* Pass: cleanup the CFG just before expanding trees to RTL.
144    This is just a round of label cleanups and case node grouping
145    because after the tree optimizers have run such cleanups may
146    be necessary.  */
147
148 static unsigned int
149 execute_cleanup_cfg_pre_ipa (void)
150 {
151   cleanup_tree_cfg ();
152   return 0;
153 }
154
155 struct tree_opt_pass pass_cleanup_cfg =
156 {
157   "cleanup_cfg",                        /* name */
158   NULL,                                 /* gate */
159   execute_cleanup_cfg_pre_ipa,          /* execute */
160   NULL,                                 /* sub */
161   NULL,                                 /* next */
162   0,                                    /* static_pass_number */
163   0,                                    /* tv_id */
164   PROP_cfg,                             /* properties_required */
165   0,                                    /* properties_provided */
166   0,                                    /* properties_destroyed */
167   0,                                    /* todo_flags_start */
168   TODO_dump_func,                                       /* todo_flags_finish */
169   0                                     /* letter */
170 };
171
172
173 /* Pass: cleanup the CFG just before expanding trees to RTL.
174    This is just a round of label cleanups and case node grouping
175    because after the tree optimizers have run such cleanups may
176    be necessary.  */
177
178 static unsigned int
179 execute_cleanup_cfg_post_optimizing (void)
180 {
181   fold_cond_expr_cond ();
182   cleanup_tree_cfg ();
183   cleanup_dead_labels ();
184   group_case_labels ();
185   return 0;
186 }
187
188 struct tree_opt_pass pass_cleanup_cfg_post_optimizing =
189 {
190   "final_cleanup",                      /* name */
191   NULL,                                 /* gate */
192   execute_cleanup_cfg_post_optimizing,  /* execute */
193   NULL,                                 /* sub */
194   NULL,                                 /* next */
195   0,                                    /* static_pass_number */
196   0,                                    /* tv_id */
197   PROP_cfg,                             /* properties_required */
198   0,                                    /* properties_provided */
199   0,                                    /* properties_destroyed */
200   0,                                    /* todo_flags_start */
201   TODO_dump_func,                                       /* todo_flags_finish */
202   0                                     /* letter */
203 };
204
205 /* Pass: do the actions required to finish with tree-ssa optimization
206    passes.  */
207
208 static unsigned int
209 execute_free_datastructures (void)
210 {
211   /* ??? This isn't the right place for this.  Worse, it got computed
212      more or less at random in various passes.  */
213   free_dominance_info (CDI_DOMINATORS);
214   free_dominance_info (CDI_POST_DOMINATORS);
215
216   /* Remove the ssa structures.  Do it here since this includes statement
217      annotations that need to be intact during disband_implicit_edges.  */
218   if (cfun->gimple_df)
219     delete_tree_ssa ();
220   return 0;
221 }
222
223 struct tree_opt_pass pass_free_datastructures =
224 {
225   NULL,                                 /* name */
226   NULL,                                 /* gate */
227   execute_free_datastructures,                  /* execute */
228   NULL,                                 /* sub */
229   NULL,                                 /* next */
230   0,                                    /* static_pass_number */
231   0,                                    /* tv_id */
232   PROP_cfg,                             /* properties_required */
233   0,                                    /* properties_provided */
234   0,                                    /* properties_destroyed */
235   0,                                    /* todo_flags_start */
236   0,                                    /* todo_flags_finish */
237   0                                     /* letter */
238 };
239 /* Pass: free cfg annotations.  */
240
241 static unsigned int
242 execute_free_cfg_annotations (void)
243 {
244   /* Emit gotos for implicit jumps.  */
245   disband_implicit_edges ();
246
247   /* And get rid of annotations we no longer need.  */
248   delete_tree_cfg_annotations ();
249
250   return 0;
251 }
252
253 struct tree_opt_pass pass_free_cfg_annotations =
254 {
255   NULL,                                 /* name */
256   NULL,                                 /* gate */
257   execute_free_cfg_annotations,         /* execute */
258   NULL,                                 /* sub */
259   NULL,                                 /* next */
260   0,                                    /* static_pass_number */
261   0,                                    /* tv_id */
262   PROP_cfg,                             /* properties_required */
263   0,                                    /* properties_provided */
264   0,                                    /* properties_destroyed */
265   0,                                    /* todo_flags_start */
266   0,                                    /* todo_flags_finish */
267   0                                     /* letter */
268 };
269
270 /* Pass: fixup_cfg.  IPA passes, compilation of earlier functions or inlining
271    might have changed some properties, such as marked functions nothrow.
272    Remove redundant edges and basic blocks, and create new ones if necessary.
273
274    This pass can't be executed as stand alone pass from pass manager, because
275    in between inlining and this fixup the verify_flow_info would fail.  */
276
277 unsigned int
278 execute_fixup_cfg (void)
279 {
280   basic_block bb;
281   block_stmt_iterator bsi;
282   int todo = gimple_in_ssa_p (cfun) ? TODO_verify_ssa : 0;
283
284   cfun->after_inlining = true;
285
286   if (cfun->eh)
287     FOR_EACH_BB (bb)
288       {
289         for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
290           {
291             tree stmt = bsi_stmt (bsi);
292             tree call = get_call_expr_in (stmt);
293             tree decl = call ? get_callee_fndecl (call) : NULL;
294
295             if (decl && call_expr_flags (call) & (ECF_CONST | ECF_PURE)
296                 && TREE_SIDE_EFFECTS (call))
297               {
298                 if (gimple_in_ssa_p (cfun))
299                   {
300                     todo |= TODO_update_ssa | TODO_cleanup_cfg;
301                     update_stmt (stmt);
302                   }
303                 TREE_SIDE_EFFECTS (call) = 0;
304               }
305             if (decl && TREE_NOTHROW (decl))
306               TREE_NOTHROW (call) = 1;
307             if (!tree_could_throw_p (stmt) && lookup_stmt_eh_region (stmt))
308               remove_stmt_from_eh_region (stmt);
309           }
310         if (tree_purge_dead_eh_edges (bb))
311           todo |= TODO_cleanup_cfg;
312       }
313
314   /* Dump a textual representation of the flowgraph.  */
315   if (dump_file)
316     dump_tree_cfg (dump_file, dump_flags);
317
318   return todo;
319 }
320
321 /* Do the actions required to initialize internal data structures used
322    in tree-ssa optimization passes.  */
323
324 static unsigned int
325 execute_init_datastructures (void)
326 {
327   /* Allocate hash tables, arrays and other structures.  */
328   init_tree_ssa ();
329   return 0;
330 }
331
332 /* Gate: initialize or not the SSA datastructures.  */
333
334 static bool
335 gate_init_datastructures (void)
336 {
337   return (optimize >= 1);
338 }
339
340 struct tree_opt_pass pass_init_datastructures =
341 {
342   NULL,                                 /* name */
343   gate_init_datastructures,             /* gate */
344   execute_init_datastructures,          /* execute */
345   NULL,                                 /* sub */
346   NULL,                                 /* next */
347   0,                                    /* static_pass_number */
348   0,                                    /* tv_id */
349   PROP_cfg,                             /* properties_required */
350   0,                                    /* properties_provided */
351   0,                                    /* properties_destroyed */
352   0,                                    /* todo_flags_start */
353   0,                                    /* todo_flags_finish */
354   0                                     /* letter */
355 };
356
357 void
358 tree_lowering_passes (tree fn)
359 {
360   tree saved_current_function_decl = current_function_decl;
361
362   current_function_decl = fn;
363   push_cfun (DECL_STRUCT_FUNCTION (fn));
364   tree_register_cfg_hooks ();
365   bitmap_obstack_initialize (NULL);
366   execute_pass_list (all_lowering_passes);
367   if (optimize && cgraph_global_info_ready)
368     execute_pass_list (pass_early_local_passes.sub);
369   free_dominance_info (CDI_POST_DOMINATORS);
370   free_dominance_info (CDI_DOMINATORS);
371   compact_blocks ();
372   current_function_decl = saved_current_function_decl;
373   bitmap_obstack_release (NULL);
374   pop_cfun ();
375 }
376 \f
377 /* For functions-as-trees languages, this performs all optimization and
378    compilation for FNDECL.  */
379
380 void
381 tree_rest_of_compilation (tree fndecl)
382 {
383   location_t saved_loc;
384   struct cgraph_node *node;
385
386   timevar_push (TV_EXPAND);
387
388   gcc_assert (!flag_unit_at_a_time || cgraph_global_info_ready);
389
390   node = cgraph_node (fndecl);
391
392   /* Initialize the default bitmap obstack.  */
393   bitmap_obstack_initialize (NULL);
394
395   /* Initialize the RTL code for the function.  */
396   current_function_decl = fndecl;
397   cfun = DECL_STRUCT_FUNCTION (fndecl);
398   saved_loc = input_location;
399   input_location = DECL_SOURCE_LOCATION (fndecl);
400   init_function_start (fndecl);
401
402   /* Even though we're inside a function body, we still don't want to
403      call expand_expr to calculate the size of a variable-sized array.
404      We haven't necessarily assigned RTL to all variables yet, so it's
405      not safe to try to expand expressions involving them.  */
406   cfun->x_dont_save_pending_sizes_p = 1;
407   
408   tree_register_cfg_hooks ();
409
410   bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
411   /* Perform all tree transforms and optimizations.  */
412   execute_pass_list (all_passes);
413   
414   bitmap_obstack_release (&reg_obstack);
415
416   /* Release the default bitmap obstack.  */
417   bitmap_obstack_release (NULL);
418   
419   DECL_SAVED_TREE (fndecl) = NULL;
420   cfun = 0;
421
422   /* If requested, warn about function definitions where the function will
423      return a value (usually of some struct or union type) which itself will
424      take up a lot of stack space.  */
425   if (warn_larger_than && !DECL_EXTERNAL (fndecl) && TREE_TYPE (fndecl))
426     {
427       tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
428
429       if (ret_type && TYPE_SIZE_UNIT (ret_type)
430           && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
431           && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
432                                    larger_than_size))
433         {
434           unsigned int size_as_int
435             = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
436
437           if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
438             warning (0, "size of return value of %q+D is %u bytes",
439                      fndecl, size_as_int);
440           else
441             warning (0, "size of return value of %q+D is larger than %wd bytes",
442                      fndecl, larger_than_size);
443         }
444     }
445
446   if (!flag_inline_trees)
447     {
448       DECL_SAVED_TREE (fndecl) = NULL;
449       if (DECL_STRUCT_FUNCTION (fndecl) == 0
450           && !cgraph_node (fndecl)->origin)
451         {
452           /* Stop pointing to the local nodes about to be freed.
453              But DECL_INITIAL must remain nonzero so we know this
454              was an actual function definition.
455              For a nested function, this is done in c_pop_function_context.
456              If rest_of_compilation set this to 0, leave it 0.  */
457           if (DECL_INITIAL (fndecl) != 0)
458             DECL_INITIAL (fndecl) = error_mark_node;
459         }
460     }
461
462   input_location = saved_loc;
463
464   ggc_collect ();
465   timevar_pop (TV_EXPAND);
466 }