i386.c (legitimize_tls_address): Generate tls_initial_exec_64_sun only when !TARGET_X32.
[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 "output.h"
30 #include "flags.h"
31 #include "tree-flow.h"
32 #include "tree-dump.h"
33 #include "timevar.h"
34 #include "function.h"
35 #include "langhooks.h"
36 #include "diagnostic-core.h"
37 #include "toplev.h"
38 #include "flags.h"
39 #include "cgraph.h"
40 #include "tree-inline.h"
41 #include "tree-pass.h"
42 #include "ggc.h"
43 #include "cgraph.h"
44 #include "graph.h"
45 #include "cfgloop.h"
46 #include "except.h"
47 #include "plugin.h"
48
49
50 /* Pass: cleanup the CFG just before expanding trees to RTL.
51 This is just a round of label cleanups and case node grouping
52 because after the tree optimizers have run such cleanups may
53 be necessary. */
54
55 static unsigned int
56 execute_cleanup_cfg_post_optimizing (void)
57 {
58 unsigned int todo = 0;
59 if (cleanup_tree_cfg ())
60 todo |= TODO_update_ssa;
61 maybe_remove_unreachable_handlers ();
62 cleanup_dead_labels ();
63 group_case_labels ();
64 if ((flag_compare_debug_opt || flag_compare_debug)
65 && flag_dump_final_insns)
66 {
67 FILE *final_output = fopen (flag_dump_final_insns, "a");
68
69 if (!final_output)
70 {
71 error ("could not open final insn dump file %qs: %m",
72 flag_dump_final_insns);
73 flag_dump_final_insns = NULL;
74 }
75 else
76 {
77 int save_unnumbered = flag_dump_unnumbered;
78 int save_noaddr = flag_dump_noaddr;
79
80 flag_dump_noaddr = flag_dump_unnumbered = 1;
81 fprintf (final_output, "\n");
82 dump_enumerated_decls (final_output, dump_flags | TDF_NOUID);
83 flag_dump_noaddr = save_noaddr;
84 flag_dump_unnumbered = save_unnumbered;
85 if (fclose (final_output))
86 {
87 error ("could not close final insn dump file %qs: %m",
88 flag_dump_final_insns);
89 flag_dump_final_insns = NULL;
90 }
91 }
92 }
93 return todo;
94 }
95
96 struct gimple_opt_pass pass_cleanup_cfg_post_optimizing =
97 {
98 {
99 GIMPLE_PASS,
100 "optimized", /* name */
101 NULL, /* gate */
102 execute_cleanup_cfg_post_optimizing, /* execute */
103 NULL, /* sub */
104 NULL, /* next */
105 0, /* static_pass_number */
106 TV_TREE_CLEANUP_CFG, /* tv_id */
107 PROP_cfg, /* properties_required */
108 0, /* properties_provided */
109 0, /* properties_destroyed */
110 0, /* todo_flags_start */
111 TODO_remove_unused_locals /* todo_flags_finish */
112 }
113 };
114
115 /* IPA passes, compilation of earlier functions or inlining
116 might have changed some properties, such as marked functions nothrow,
117 pure, const or noreturn.
118 Remove redundant edges and basic blocks, and create new ones if necessary.
119
120 This pass can't be executed as stand alone pass from pass manager, because
121 in between inlining and this fixup the verify_flow_info would fail. */
122
123 unsigned int
124 execute_fixup_cfg (void)
125 {
126 basic_block bb;
127 gimple_stmt_iterator gsi;
128 int todo = gimple_in_ssa_p (cfun) ? TODO_verify_ssa : 0;
129 gcov_type count_scale;
130 edge e;
131 edge_iterator ei;
132
133 if (ENTRY_BLOCK_PTR->count)
134 count_scale = ((cgraph_get_node (current_function_decl)->count
135 * REG_BR_PROB_BASE + ENTRY_BLOCK_PTR->count / 2)
136 / ENTRY_BLOCK_PTR->count);
137 else
138 count_scale = REG_BR_PROB_BASE;
139
140 ENTRY_BLOCK_PTR->count = cgraph_get_node (current_function_decl)->count;
141 EXIT_BLOCK_PTR->count = (EXIT_BLOCK_PTR->count * count_scale
142 + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
143
144 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
145 e->count = (e->count * count_scale
146 + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
147
148 FOR_EACH_BB (bb)
149 {
150 bb->count = (bb->count * count_scale
151 + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
152 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
153 {
154 gimple stmt = gsi_stmt (gsi);
155 tree decl = is_gimple_call (stmt)
156 ? gimple_call_fndecl (stmt)
157 : NULL;
158 if (decl)
159 {
160 int flags = gimple_call_flags (stmt);
161 if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE))
162 {
163 if (gimple_purge_dead_abnormal_call_edges (bb))
164 todo |= TODO_cleanup_cfg;
165
166 if (gimple_in_ssa_p (cfun))
167 {
168 todo |= TODO_update_ssa | TODO_cleanup_cfg;
169 update_stmt (stmt);
170 }
171 }
172
173 if (flags & ECF_NORETURN
174 && fixup_noreturn_call (stmt))
175 todo |= TODO_cleanup_cfg;
176 }
177
178 if (maybe_clean_eh_stmt (stmt)
179 && gimple_purge_dead_eh_edges (bb))
180 todo |= TODO_cleanup_cfg;
181 }
182
183 FOR_EACH_EDGE (e, ei, bb->succs)
184 e->count = (e->count * count_scale
185 + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE;
186 }
187 if (count_scale != REG_BR_PROB_BASE)
188 compute_function_frequency ();
189
190 /* We just processed all calls. */
191 if (cfun->gimple_df)
192 {
193 VEC_free (gimple, gc, MODIFIED_NORETURN_CALLS (cfun));
194 MODIFIED_NORETURN_CALLS (cfun) = NULL;
195 }
196
197 /* Dump a textual representation of the flowgraph. */
198 if (dump_file)
199 gimple_dump_cfg (dump_file, dump_flags);
200
201 return todo;
202 }
203
204 struct gimple_opt_pass pass_fixup_cfg =
205 {
206 {
207 GIMPLE_PASS,
208 "*free_cfg_annotations", /* name */
209 NULL, /* gate */
210 execute_fixup_cfg, /* execute */
211 NULL, /* sub */
212 NULL, /* next */
213 0, /* static_pass_number */
214 TV_NONE, /* tv_id */
215 PROP_cfg, /* properties_required */
216 0, /* properties_provided */
217 0, /* properties_destroyed */
218 0, /* todo_flags_start */
219 0 /* todo_flags_finish */
220 }
221 };