whatis.cc: New file.
[gcc.git] / gcc / tree-optimize.c
1 /* Top-level control of tree optimizations.
2 Copyright 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
4 Contributed by Diego Novillo <dnovillo@redhat.com>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "tm_p.h"
28 #include "basic-block.h"
29 #include "flags.h"
30 #include "tree-flow.h"
31 #include "function.h"
32 #include "langhooks.h"
33 #include "diagnostic-core.h"
34 #include "toplev.h"
35 #include "flags.h"
36 #include "cgraph.h"
37 #include "tree-inline.h"
38 #include "tree-pass.h"
39 #include "ggc.h"
40 #include "cgraph.h"
41 #include "graph.h"
42 #include "cfgloop.h"
43 #include "except.h"
44 #include "plugin.h"
45
46
47 /* Pass: cleanup the CFG just before expanding trees to RTL.
48 This is just a round of label cleanups and case node grouping
49 because after the tree optimizers have run such cleanups may
50 be necessary. */
51
52 static unsigned int
53 execute_cleanup_cfg_post_optimizing (void)
54 {
55 unsigned int todo = 0;
56 if (cleanup_tree_cfg ())
57 todo |= TODO_update_ssa;
58 maybe_remove_unreachable_handlers ();
59 cleanup_dead_labels ();
60 group_case_labels ();
61 if ((flag_compare_debug_opt || flag_compare_debug)
62 && flag_dump_final_insns)
63 {
64 FILE *final_output = fopen (flag_dump_final_insns, "a");
65
66 if (!final_output)
67 {
68 error ("could not open final insn dump file %qs: %m",
69 flag_dump_final_insns);
70 flag_dump_final_insns = NULL;
71 }
72 else
73 {
74 int save_unnumbered = flag_dump_unnumbered;
75 int save_noaddr = flag_dump_noaddr;
76
77 flag_dump_noaddr = flag_dump_unnumbered = 1;
78 fprintf (final_output, "\n");
79 dump_enumerated_decls (final_output, dump_flags | TDF_NOUID);
80 flag_dump_noaddr = save_noaddr;
81 flag_dump_unnumbered = save_unnumbered;
82 if (fclose (final_output))
83 {
84 error ("could not close final insn dump file %qs: %m",
85 flag_dump_final_insns);
86 flag_dump_final_insns = NULL;
87 }
88 }
89 }
90 return todo;
91 }
92
93 struct gimple_opt_pass pass_cleanup_cfg_post_optimizing =
94 {
95 {
96 GIMPLE_PASS,
97 "optimized", /* name */
98 OPTGROUP_NONE, /* optinfo_flags */
99 NULL, /* gate */
100 execute_cleanup_cfg_post_optimizing, /* execute */
101 NULL, /* sub */
102 NULL, /* next */
103 0, /* static_pass_number */
104 TV_TREE_CLEANUP_CFG, /* tv_id */
105 PROP_cfg, /* properties_required */
106 0, /* properties_provided */
107 0, /* properties_destroyed */
108 0, /* todo_flags_start */
109 TODO_remove_unused_locals /* todo_flags_finish */
110 }
111 };
112
113 /* IPA passes, compilation of earlier functions or inlining
114 might have changed some properties, such as marked functions nothrow,
115 pure, const or noreturn.
116 Remove redundant edges and basic blocks, and create new ones if necessary.
117
118 This pass can't be executed as stand alone pass from pass manager, because
119 in between inlining and this fixup the verify_flow_info would fail. */
120
121 unsigned int
122 execute_fixup_cfg (void)
123 {
124 basic_block bb;
125 gimple_stmt_iterator gsi;
126 int todo = gimple_in_ssa_p (cfun) ? TODO_verify_ssa : 0;
127 gcov_type count_scale;
128 edge e;
129 edge_iterator ei;
130
131 if (ENTRY_BLOCK_PTR->count)
132 count_scale = ((cgraph_get_node (current_function_decl)->count
133 * REG_BR_PROB_BASE + ENTRY_BLOCK_PTR->count / 2)
134 / ENTRY_BLOCK_PTR->count);
135 else
136 count_scale = REG_BR_PROB_BASE;
137
138 ENTRY_BLOCK_PTR->count = cgraph_get_node (current_function_decl)->count;
139 EXIT_BLOCK_PTR->count = (EXIT_BLOCK_PTR->count * count_scale
140 + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
141
142 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
143 e->count = (e->count * count_scale
144 + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
145
146 FOR_EACH_BB (bb)
147 {
148 bb->count = (bb->count * count_scale
149 + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
150 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
151 {
152 gimple stmt = gsi_stmt (gsi);
153 tree decl = is_gimple_call (stmt)
154 ? gimple_call_fndecl (stmt)
155 : NULL;
156 if (decl)
157 {
158 int flags = gimple_call_flags (stmt);
159 if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE))
160 {
161 if (gimple_purge_dead_abnormal_call_edges (bb))
162 todo |= TODO_cleanup_cfg;
163
164 if (gimple_in_ssa_p (cfun))
165 {
166 todo |= TODO_update_ssa | TODO_cleanup_cfg;
167 update_stmt (stmt);
168 }
169 }
170
171 if (flags & ECF_NORETURN
172 && fixup_noreturn_call (stmt))
173 todo |= TODO_cleanup_cfg;
174 }
175
176 if (maybe_clean_eh_stmt (stmt)
177 && gimple_purge_dead_eh_edges (bb))
178 todo |= TODO_cleanup_cfg;
179 }
180
181 FOR_EACH_EDGE (e, ei, bb->succs)
182 e->count = (e->count * count_scale
183 + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
184
185 /* If we have a basic block with no successors that does not
186 end with a control statement or a noreturn call end it with
187 a call to __builtin_unreachable. This situation can occur
188 when inlining a noreturn call that does in fact return. */
189 if (EDGE_COUNT (bb->succs) == 0)
190 {
191 gimple stmt = last_stmt (bb);
192 if (!stmt
193 || (!is_ctrl_stmt (stmt)
194 && (!is_gimple_call (stmt)
195 || (gimple_call_flags (stmt) & ECF_NORETURN) == 0)))
196 {
197 stmt = gimple_build_call
198 (builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0);
199 gimple_stmt_iterator gsi = gsi_last_bb (bb);
200 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
201 }
202 }
203 }
204 if (count_scale != REG_BR_PROB_BASE)
205 compute_function_frequency ();
206
207 /* We just processed all calls. */
208 if (cfun->gimple_df)
209 {
210 VEC_free (gimple, gc, MODIFIED_NORETURN_CALLS (cfun));
211 MODIFIED_NORETURN_CALLS (cfun) = NULL;
212 }
213
214 /* Dump a textual representation of the flowgraph. */
215 if (dump_file)
216 gimple_dump_cfg (dump_file, dump_flags);
217
218 return todo;
219 }
220
221 struct gimple_opt_pass pass_fixup_cfg =
222 {
223 {
224 GIMPLE_PASS,
225 "*free_cfg_annotations", /* name */
226 OPTGROUP_NONE, /* optinfo_flags */
227 NULL, /* gate */
228 execute_fixup_cfg, /* execute */
229 NULL, /* sub */
230 NULL, /* next */
231 0, /* static_pass_number */
232 TV_NONE, /* tv_id */
233 PROP_cfg, /* properties_required */
234 0, /* properties_provided */
235 0, /* properties_destroyed */
236 0, /* todo_flags_start */
237 0 /* todo_flags_finish */
238 }
239 };