OSDN Git Service

Tree level if-conversion for vectorizer.
[pf3gnuchains/gcc-fork.git] / gcc / tree-optimize.c
1 /* Top-level control of tree optimizations.
2    Copyright 2001, 2002, 2003, 2004 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, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, 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 "tree-alias-common.h"
48 #include "ggc.h"
49 #include "cgraph.h"
50
51
52 /* Global variables used to communicate with passes.  */
53 int dump_flags;
54 bitmap vars_to_rename;
55 bool in_gimple_form;
56
57 /* The root of the compilation pass tree, once constructed.  */
58 static struct tree_opt_pass *all_passes;
59
60 /* Pass: dump the gimplified, inlined, functions.  */
61
62 static struct tree_opt_pass pass_gimple = 
63 {
64   "gimple",                             /* name */
65   NULL,                                 /* gate */
66   NULL,                                 /* execute */
67   NULL,                                 /* sub */
68   NULL,                                 /* next */
69   0,                                    /* static_pass_number */
70   0,                                    /* tv_id */
71   0,                                    /* properties_required */
72   PROP_gimple_any,                      /* properties_provided */
73   0,                                    /* properties_destroyed */
74   0,                                    /* todo_flags_start */
75   TODO_dump_func                        /* todo_flags_finish */
76 };
77
78 /* Gate: execute, or not, all of the non-trivial optimizations.  */
79
80 static bool
81 gate_all_optimizations (void)
82 {
83   return (optimize >= 1
84           /* Don't bother doing anything if the program has errors.  */
85           && !(errorcount || sorrycount));
86 }
87
88 static struct tree_opt_pass pass_all_optimizations =
89 {
90   NULL,                                 /* name */
91   gate_all_optimizations,               /* gate */
92   NULL,                                 /* execute */
93   NULL,                                 /* sub */
94   NULL,                                 /* next */
95   0,                                    /* static_pass_number */
96   0,                                    /* tv_id */
97   0,                                    /* properties_required */
98   0,                                    /* properties_provided */
99   0,                                    /* properties_destroyed */
100   0,                                    /* todo_flags_start */
101   0                                     /* todo_flags_finish */
102 };
103
104 /* Pass: cleanup the CFG just before expanding trees to RTL.
105    This is just a round of label cleanups and case node grouping
106    because after the tree optimizers have run such cleanups may
107    be necessary.  */
108
109 static void 
110 execute_cleanup_cfg_post_optimizing (void)
111 {
112   cleanup_tree_cfg ();
113   cleanup_dead_labels ();
114   group_case_labels ();
115 }
116
117 static struct tree_opt_pass pass_cleanup_cfg_post_optimizing =
118 {
119   NULL,                                 /* name */
120   NULL,                                 /* gate */
121   execute_cleanup_cfg_post_optimizing,  /* execute */
122   NULL,                                 /* sub */
123   NULL,                                 /* next */
124   0,                                    /* static_pass_number */
125   0,                                    /* tv_id */
126   PROP_cfg,                             /* properties_required */
127   0,                                    /* properties_provided */
128   0,                                    /* properties_destroyed */
129   0,                                    /* todo_flags_start */
130   0                                     /* todo_flags_finish */
131 };
132
133 /* Pass: do the actions required to finish with tree-ssa optimization
134    passes.  */
135
136 static void
137 execute_free_datastructures (void)
138 {
139   tree *chain;
140
141   /* ??? This isn't the right place for this.  Worse, it got computed
142      more or less at random in various passes.  */
143   free_dominance_info (CDI_DOMINATORS);
144
145   /* Emit gotos for implicit jumps.  */
146   disband_implicit_edges ();
147
148   /* Remove the ssa structures.  Do it here since this includes statement
149      annotations that need to be intact during disband_implicit_edges.  */
150   delete_tree_ssa ();
151
152   /* Re-chain the statements from the blocks.  */
153   chain = &DECL_SAVED_TREE (current_function_decl);
154   *chain = alloc_stmt_list ();
155
156   /* And get rid of annotations we no longer need.  */
157   delete_tree_cfg_annotations ();
158 }
159
160 static struct tree_opt_pass pass_free_datastructures =
161 {
162   NULL,                                 /* name */
163   NULL,                                 /* gate */
164   execute_free_datastructures,                  /* execute */
165   NULL,                                 /* sub */
166   NULL,                                 /* next */
167   0,                                    /* static_pass_number */
168   0,                                    /* tv_id */
169   PROP_cfg,                             /* properties_required */
170   0,                                    /* properties_provided */
171   0,                                    /* properties_destroyed */
172   0,                                    /* todo_flags_start */
173   0                                     /* todo_flags_finish */
174 };
175
176
177 /* Do the actions required to initialize internal data structures used
178    in tree-ssa optimization passes.  */
179
180 static void
181 execute_init_datastructures (void)
182 {
183   /* Allocate hash tables, arrays and other structures.  */
184   init_tree_ssa ();
185 }
186
187 static struct tree_opt_pass pass_init_datastructures =
188 {
189   NULL,                                 /* name */
190   NULL,                                 /* gate */
191   execute_init_datastructures,          /* execute */
192   NULL,                                 /* sub */
193   NULL,                                 /* next */
194   0,                                    /* static_pass_number */
195   0,                                    /* tv_id */
196   PROP_cfg,                             /* properties_required */
197   0,                                    /* properties_provided */
198   0,                                    /* properties_destroyed */
199   0,                                    /* todo_flags_start */
200   0                                     /* todo_flags_finish */
201 };
202
203 /* Iterate over the pass tree allocating dump file numbers.  We want
204    to do this depth first, and independent of whether the pass is
205    enabled or not.  */
206
207 static void
208 register_one_dump_file (struct tree_opt_pass *pass)
209 {
210   char *dot_name, *flag_name;
211   char num[10];
212
213   if (!pass->name)
214     return;
215
216   /* See below in next_pass_1.  */
217   num[0] = '\0';
218   if (pass->static_pass_number != -1)
219     sprintf (num, "%d", ((int) pass->static_pass_number < 0
220                          ? 1 : pass->static_pass_number));
221
222   dot_name = concat (".", pass->name, num, NULL);
223   flag_name = concat ("tree-", pass->name, num, NULL);
224
225   pass->static_pass_number = dump_register (dot_name, flag_name);
226 }
227
228 static int 
229 register_dump_files (struct tree_opt_pass *pass, int properties)
230 {
231   do
232     {
233       /* Verify that all required properties are present.  */
234       if (pass->properties_required & ~properties)
235         abort ();
236
237       if (pass->properties_destroyed & pass->properties_provided)
238         abort ();
239
240       pass->properties_required = properties;
241       pass->properties_provided = properties =
242         (properties | pass->properties_provided) & ~pass->properties_destroyed;
243
244       if (properties & PROP_trees)
245         register_one_dump_file (pass);
246       if (pass->sub)
247         properties = register_dump_files (pass->sub, properties);
248       pass = pass->next;
249     }
250   while (pass);
251
252   return properties;
253 }
254
255 /* Add a pass to the pass list. Duplicate the pass if it's already
256    in the list.  */
257
258 static struct tree_opt_pass **
259 next_pass_1 (struct tree_opt_pass **list, struct tree_opt_pass *pass)
260 {
261
262   /* A non-zero static_pass_number indicates that the
263      pass is already in the list. */
264   if (pass->static_pass_number)
265     {
266       struct tree_opt_pass *new;
267
268       new = xmalloc (sizeof (*new));
269       memcpy (new, pass, sizeof (*new));
270
271       /* Indicate to register_dump_files that this pass has duplicates,
272          and so it should rename the dump file.  The first instance will
273          be -1, and be number of duplicates = -static_pass_number - 1.
274          Subsequent instances will be > 0 and just the duplicate number.  */
275       if (pass->name)
276         {
277           pass->static_pass_number -= 1;
278           new->static_pass_number = -pass->static_pass_number;
279         }
280       
281       *list = new;
282     }
283   else
284     {
285       pass->static_pass_number = -1;
286       *list = pass;
287     }  
288   
289   return &(*list)->next;
290           
291 }
292
293 /* Construct the pass tree.  */
294
295 void
296 init_tree_optimization_passes (void)
297 {
298   struct tree_opt_pass **p;
299
300 #define NEXT_PASS(PASS)  (p = next_pass_1 (p, &PASS))
301
302   p = &all_passes;
303   NEXT_PASS (pass_gimple);
304   NEXT_PASS (pass_remove_useless_stmts);
305   NEXT_PASS (pass_mudflap_1);
306   NEXT_PASS (pass_lower_cf);
307   NEXT_PASS (pass_lower_eh);
308   NEXT_PASS (pass_build_cfg);
309   NEXT_PASS (pass_pre_expand);
310   NEXT_PASS (pass_tree_profile);
311   NEXT_PASS (pass_init_datastructures);
312   NEXT_PASS (pass_all_optimizations);
313   NEXT_PASS (pass_warn_function_return);
314   NEXT_PASS (pass_mudflap_2);
315   NEXT_PASS (pass_free_datastructures);
316   NEXT_PASS (pass_expand);
317   NEXT_PASS (pass_rest_of_compilation);
318   *p = NULL;
319
320   p = &pass_all_optimizations.sub;
321   NEXT_PASS (pass_referenced_vars);
322   NEXT_PASS (pass_build_pta);
323   NEXT_PASS (pass_build_ssa);
324   NEXT_PASS (pass_may_alias);
325   NEXT_PASS (pass_rename_ssa_copies);
326   NEXT_PASS (pass_early_warn_uninitialized);
327   NEXT_PASS (pass_dce);
328   NEXT_PASS (pass_dominator);
329   NEXT_PASS (pass_redundant_phi);
330   NEXT_PASS (pass_dce);
331   NEXT_PASS (pass_forwprop);
332   NEXT_PASS (pass_phiopt);
333   NEXT_PASS (pass_may_alias);
334   NEXT_PASS (pass_tail_recursion);
335   NEXT_PASS (pass_ch);
336   NEXT_PASS (pass_profile);
337   NEXT_PASS (pass_sra);
338   NEXT_PASS (pass_rename_ssa_copies);
339   NEXT_PASS (pass_dominator);
340   NEXT_PASS (pass_redundant_phi);
341   NEXT_PASS (pass_dce);
342   NEXT_PASS (pass_dse);
343   NEXT_PASS (pass_may_alias);
344   NEXT_PASS (pass_forwprop);
345   NEXT_PASS (pass_phiopt);
346   NEXT_PASS (pass_ccp);
347   NEXT_PASS (pass_redundant_phi);
348   NEXT_PASS (pass_fold_builtins);
349   NEXT_PASS (pass_split_crit_edges);
350   NEXT_PASS (pass_pre);
351   NEXT_PASS (pass_loop);
352   NEXT_PASS (pass_dominator);
353   NEXT_PASS (pass_redundant_phi);
354   NEXT_PASS (pass_cd_dce);
355   NEXT_PASS (pass_dse);
356   NEXT_PASS (pass_forwprop);
357   NEXT_PASS (pass_phiopt);
358   NEXT_PASS (pass_tail_calls);
359   NEXT_PASS (pass_late_warn_uninitialized);
360   NEXT_PASS (pass_del_pta);
361   NEXT_PASS (pass_del_ssa);
362   NEXT_PASS (pass_nrv);
363   NEXT_PASS (pass_remove_useless_vars);
364   NEXT_PASS (pass_cleanup_cfg_post_optimizing);
365   *p = NULL;
366
367   p = &pass_loop.sub;
368   NEXT_PASS (pass_loop_init);
369   NEXT_PASS (pass_lim);
370   NEXT_PASS (pass_iv_canon);
371   NEXT_PASS (pass_if_conversion);
372   NEXT_PASS (pass_vectorize);
373   NEXT_PASS (pass_complete_unroll);
374   NEXT_PASS (pass_loop_done);
375   *p = NULL;
376
377 #undef NEXT_PASS
378
379   /* Register the passes with the tree dump code.  */
380   register_dump_files (all_passes, 0);
381 }
382
383 static void execute_pass_list (struct tree_opt_pass *);
384
385 static unsigned int last_verified;
386
387 static void
388 execute_todo (unsigned int flags)
389 {
390   if (flags & TODO_rename_vars)
391     {
392       rewrite_into_ssa (false);
393       bitmap_clear (vars_to_rename);
394     }
395
396   if ((flags & TODO_dump_func) && dump_file)
397     {
398       dump_function_to_file (current_function_decl,
399                              dump_file, dump_flags);
400
401       /* Flush the file.  If verification fails, we won't be able to
402          close the file before aborting.  */
403       fflush (dump_file);
404     }
405
406   if (flags & TODO_ggc_collect)
407     ggc_collect ();
408
409 #ifdef ENABLE_CHECKING
410   if (flags & TODO_verify_ssa)
411     verify_ssa ();
412   if (flags & TODO_verify_flow)
413     verify_flow_info ();
414   if (flags & TODO_verify_stmts)
415     verify_stmts ();
416 #endif
417 }
418
419 static bool
420 execute_one_pass (struct tree_opt_pass *pass)
421 {
422   unsigned int todo; 
423
424   /* See if we're supposed to run this pass.  */
425   if (pass->gate && !pass->gate ())
426     return false;
427
428   /* Note that the folders should only create gimple expressions.
429      This is a hack until the new folder is ready.  */
430   in_gimple_form = (pass->properties_provided & PROP_trees) != 0;
431
432   /* Run pre-pass verification.  */
433   todo = pass->todo_flags_start & ~last_verified;
434   if (todo)
435     execute_todo (todo);
436
437   /* If a dump file name is present, open it if enabled.  */
438   if (pass->static_pass_number != -1)
439     {
440       dump_file = dump_begin (pass->static_pass_number, &dump_flags);
441       if (dump_file)
442         {
443           const char *dname, *aname;
444           dname = lang_hooks.decl_printable_name (current_function_decl, 2);
445           aname = (IDENTIFIER_POINTER
446                    (DECL_ASSEMBLER_NAME (current_function_decl)));
447           fprintf (dump_file, "\n;; Function %s (%s)\n\n", dname, aname);
448         }
449     }
450
451   /* If a timevar is present, start it.  */
452   if (pass->tv_id)
453     timevar_push (pass->tv_id);
454
455   /* Do it!  */
456   if (pass->execute)
457     pass->execute ();
458
459   /* Run post-pass cleanup and verification.  */
460   todo = pass->todo_flags_finish;
461   last_verified = todo & TODO_verify_all;
462   if (todo)
463     execute_todo (todo);
464
465   /* Close down timevar and dump file.  */
466   if (pass->tv_id)
467     timevar_pop (pass->tv_id);
468   if (dump_file)
469     {
470       dump_end (pass->static_pass_number, dump_file);
471       dump_file = NULL;
472     }
473
474   return true;
475 }
476
477 static void
478 execute_pass_list (struct tree_opt_pass *pass)
479 {
480   do
481     {
482       if (execute_one_pass (pass) && pass->sub)
483         execute_pass_list (pass->sub);
484       pass = pass->next;
485     }
486   while (pass);
487 }
488
489 \f
490 /* For functions-as-trees languages, this performs all optimization and
491    compilation for FNDECL.  */
492
493 void
494 tree_rest_of_compilation (tree fndecl, bool nested_p)
495 {
496   location_t saved_loc;
497   struct cgraph_node *saved_node = NULL, *node;
498
499   timevar_push (TV_EXPAND);
500
501   if (flag_unit_at_a_time && !cgraph_global_info_ready)
502     abort ();
503
504   /* Initialize the RTL code for the function.  */
505   current_function_decl = fndecl;
506   saved_loc = input_location;
507   input_location = DECL_SOURCE_LOCATION (fndecl);
508   init_function_start (fndecl);
509
510   /* Even though we're inside a function body, we still don't want to
511      call expand_expr to calculate the size of a variable-sized array.
512      We haven't necessarily assigned RTL to all variables yet, so it's
513      not safe to try to expand expressions involving them.  */
514   cfun->x_dont_save_pending_sizes_p = 1;
515
516   node = cgraph_node (fndecl);
517
518   /* We might need the body of this function so that we can expand
519      it inline somewhere else.  This means not lowering some constructs
520      such as exception handling.  */
521   if (cgraph_preserve_function_body_p (fndecl))
522     {
523       if (!flag_unit_at_a_time)
524         {
525           struct cgraph_edge *e;
526
527           saved_node = cgraph_clone_node (node);
528           for (e = saved_node->callees; e; e = e->next_callee)
529             if (!e->inline_failed)
530               cgraph_clone_inlined_nodes (e, true);
531         }
532       cfun->saved_static_chain_decl = cfun->static_chain_decl;
533       cfun->saved_tree = save_body (fndecl, &cfun->saved_args,
534                                     &cfun->saved_static_chain_decl);
535     }
536
537   if (flag_inline_trees)
538     {
539       struct cgraph_edge *e;
540       for (e = node->callees; e; e = e->next_callee)
541         if (!e->inline_failed || warn_inline)
542           break;
543       if (e)
544         {
545           timevar_push (TV_INTEGRATION);
546           optimize_inline_calls (fndecl);
547           timevar_pop (TV_INTEGRATION);
548         }
549     }
550
551   if (!vars_to_rename)
552     vars_to_rename = BITMAP_XMALLOC ();
553
554   /* If this is a nested function, protect the local variables in the stack
555      above us from being collected while we're compiling this function.  */
556   if (nested_p)
557     ggc_push_context ();
558
559   /* Perform all tree transforms and optimizations.  */
560   execute_pass_list (all_passes);
561
562   /* Restore original body if still needed.  */
563   if (cfun->saved_tree)
564     {
565       DECL_SAVED_TREE (fndecl) = cfun->saved_tree;
566       DECL_ARGUMENTS (fndecl) = cfun->saved_args;
567       cfun->static_chain_decl = cfun->saved_static_chain_decl;
568
569       /* When not in unit-at-a-time mode, we must preserve out of line copy
570          representing node before inlining.  Restore original outgoing edges
571          using clone we created earlier.  */
572       if (!flag_unit_at_a_time)
573         {
574           struct cgraph_edge *e;
575           while (node->callees)
576             cgraph_remove_edge (node->callees);
577           node->callees = saved_node->callees;
578           saved_node->callees = NULL;
579           for (e = saved_node->callees; e; e = e->next_callee)
580             e->caller = node;
581           cgraph_remove_node (saved_node);
582         }
583     }
584   else
585     DECL_SAVED_TREE (fndecl) = NULL;
586   cfun = 0;
587
588   /* If requested, warn about function definitions where the function will
589      return a value (usually of some struct or union type) which itself will
590      take up a lot of stack space.  */
591   if (warn_larger_than && !DECL_EXTERNAL (fndecl) && TREE_TYPE (fndecl))
592     {
593       tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
594
595       if (ret_type && TYPE_SIZE_UNIT (ret_type)
596           && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
597           && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
598                                    larger_than_size))
599         {
600           unsigned int size_as_int
601             = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
602
603           if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
604             warning ("%Jsize of return value of '%D' is %u bytes",
605                      fndecl, fndecl, size_as_int);
606           else
607             warning ("%Jsize of return value of '%D' is larger than %wd bytes",
608                      fndecl, fndecl, larger_than_size);
609         }
610     }
611
612   if (!nested_p && !flag_inline_trees)
613     {
614       DECL_SAVED_TREE (fndecl) = NULL;
615       if (DECL_STRUCT_FUNCTION (fndecl) == 0
616           && !cgraph_node (fndecl)->origin)
617         {
618           /* Stop pointing to the local nodes about to be freed.
619              But DECL_INITIAL must remain nonzero so we know this
620              was an actual function definition.
621              For a nested function, this is done in c_pop_function_context.
622              If rest_of_compilation set this to 0, leave it 0.  */
623           if (DECL_INITIAL (fndecl) != 0)
624             DECL_INITIAL (fndecl) = error_mark_node;
625         }
626     }
627
628   input_location = saved_loc;
629
630   ggc_collect ();
631
632   /* Undo the GC context switch.  */
633   if (nested_p)
634     ggc_pop_context ();
635   timevar_pop (TV_EXPAND);
636 }