Current state of work.
[official-gcc.git] / gcc / cfgexpand.c
blobbb8e3c8d54c3cf98ad77c7aee217127abb2f5386
1 /* A pass for lowering trees to RTL.
2 Copyright (C) 2004 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "rtl.h"
27 #include "tm_p.h"
28 #include "basic-block.h"
29 #include "function.h"
30 #include "expr.h"
31 #include "langhooks.h"
32 #include "tree-flow.h"
33 #include "timevar.h"
34 #include "tree-dump.h"
35 #include "tree-pass.h"
36 #include "except.h"
37 #include "flags.h"
39 /* Expand basic block BB from GIMPLE trees to RTL. */
41 static basic_block
42 expand_block (basic_block bb, FILE * dump_file)
44 block_stmt_iterator bsi = bsi_start (bb);
45 tree stmt = NULL;
46 rtx note, last;
47 edge e;
48 unsigned ix;
50 if (dump_file)
52 tree_register_cfg_hooks ();
53 dump_bb (bb, dump_file, 0);
54 rtl_register_cfg_hooks ();
57 if (!bsi_end_p (bsi))
58 stmt = bsi_stmt (bsi);
60 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
62 last = get_last_insn ();
64 expand_expr_stmt (stmt);
66 /* Java emits line number notes in the top of labels.
67 ??? Make this go away once line number notes are obsoleted. */
68 BB_HEAD (bb) = NEXT_INSN (last);
69 if (NOTE_P (BB_HEAD (bb)))
70 BB_HEAD (bb) = NEXT_INSN (BB_HEAD (bb));
71 bsi_next (&bsi);
72 note = emit_note_after (NOTE_INSN_BASIC_BLOCK, BB_HEAD (bb));
74 else
75 note = BB_HEAD (bb) = emit_note (NOTE_INSN_BASIC_BLOCK);
77 NOTE_BASIC_BLOCK (note) = bb;
79 FOR_EACH_EDGE (e, bb->succ, ix)
81 /* Clear EDGE_EXECUTABLE. This flag is never used in the backend. */
82 e->flags &= ~EDGE_EXECUTABLE;
84 /* At the moment not all abnormal edges match the RTL representation.
85 It is safe to remove them here as find_sub_basic_blocks will
86 rediscover them. In the future we should get this fixed properly. */
87 if (e->flags & EDGE_ABNORMAL)
88 remove_edge (e);
91 for (; !bsi_end_p (bsi); bsi_next (&bsi))
93 tree stmt = bsi_stmt (bsi);
95 last = get_last_insn ();
97 if (!stmt)
98 continue;
100 /* Expand this statement, then evaluate the resulting RTL and
101 fixup the CFG accordingly. */
102 switch (TREE_CODE (stmt))
104 case COND_EXPR:
106 basic_block new_bb, dest;
107 edge new_edge;
108 edge true_edge;
109 edge false_edge;
110 tree pred = COND_EXPR_COND (stmt);
111 tree then_exp = COND_EXPR_THEN (stmt);
112 tree else_exp = COND_EXPR_ELSE (stmt);
113 rtx last = get_last_insn ();
115 extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
116 if (EXPR_LOCUS (stmt))
118 emit_line_note (*(EXPR_LOCUS (stmt)));
119 record_block_change (TREE_BLOCK (stmt));
122 /* These flags have no purpose in RTL land. */
123 true_edge->flags &= ~EDGE_TRUE_VALUE;
124 false_edge->flags &= ~EDGE_FALSE_VALUE;
126 /* We can either have a pure conditional jump with one fallthru
127 edge or two-way jump that needs to be decomposed into two
128 basic blocks. */
129 if (TREE_CODE (then_exp) == GOTO_EXPR
130 && TREE_CODE (else_exp) == NOP_EXPR)
132 jumpif (pred, label_rtx (GOTO_DESTINATION (then_exp)));
133 break;
135 if (TREE_CODE (else_exp) == GOTO_EXPR
136 && TREE_CODE (then_exp) == NOP_EXPR)
138 jumpifnot (pred, label_rtx (GOTO_DESTINATION (else_exp)));
139 break;
141 if (TREE_CODE (then_exp) != GOTO_EXPR
142 || TREE_CODE (else_exp) != GOTO_EXPR)
143 abort ();
145 jumpif (pred, label_rtx (GOTO_DESTINATION (then_exp)));
146 last = get_last_insn ();
147 expand_expr (else_exp, const0_rtx, VOIDmode, 0);
149 BB_END (bb) = last;
150 if (BARRIER_P (BB_END (bb)))
151 BB_END (bb) = PREV_INSN (BB_END (bb));
152 update_bb_for_insn (bb);
154 new_bb = create_basic_block (NEXT_INSN (last), get_last_insn (), bb);
155 dest = false_edge->dest;
156 redirect_edge_succ (false_edge, new_bb);
157 false_edge->flags |= EDGE_FALLTHRU;
158 new_bb->count = false_edge->count;
159 new_bb->frequency = EDGE_FREQUENCY (false_edge);
160 new_edge = make_edge (new_bb, dest, 0);
161 new_edge->probability = REG_BR_PROB_BASE;
162 new_edge->count = new_bb->count;
163 if (BARRIER_P (BB_END (new_bb)))
164 BB_END (new_bb) = PREV_INSN (BB_END (new_bb));
165 update_bb_for_insn (new_bb);
167 if (dump_file)
169 dump_bb (bb, dump_file, 0);
170 dump_bb (new_bb, dump_file, 0);
172 return new_bb;
175 /* Update after expansion of sibling call. */
176 case CALL_EXPR:
177 case MODIFY_EXPR:
178 case RETURN_EXPR:
179 expand_expr_stmt (stmt);
180 for (last = NEXT_INSN (last); last; last = NEXT_INSN (last))
182 if (CALL_P (last) && SIBLING_CALL_P (last))
184 edge e;
185 int probability = 0;
186 gcov_type count = 0;
188 do_pending_stack_adjust ();
190 FOR_EACH_EDGE (e, bb->succ, ix)
192 if (!(e->flags & (EDGE_ABNORMAL | EDGE_EH)))
194 if (e->dest != EXIT_BLOCK_PTR)
196 e->dest->count -= e->count;
197 e->dest->frequency -= EDGE_FREQUENCY (e);
198 if (e->dest->count < 0)
199 e->dest->count = 0;
200 if (e->dest->frequency < 0)
201 e->dest->frequency = 0;
203 count += e->count;
204 probability += e->probability;
205 remove_edge (e);
209 /* This is somewhat ugly: the call_expr expander often emits instructions
210 after the sibcall (to perform the function return). These confuse the
211 find_sub_basic_blocks code, so we need to get rid of these. */
212 last = NEXT_INSN (last);
213 if (!BARRIER_P (last))
214 abort ();
215 while (NEXT_INSN (last))
217 /* For instance an sqrt builtin expander expands if with
218 sibcall in the then and label for `else`. */
219 if (LABEL_P (NEXT_INSN (last)))
220 break;
221 delete_insn (NEXT_INSN (last));
223 e = make_edge (bb, EXIT_BLOCK_PTR,
224 EDGE_ABNORMAL | EDGE_SIBCALL);
225 e->probability += probability;
226 e->count += count;
227 BB_END (bb) = last;
228 update_bb_for_insn (bb);
229 if (NEXT_INSN (last))
230 bb = create_basic_block (NEXT_INSN (last), get_last_insn (), bb);
231 else
232 return bb;
235 break;
237 default:
238 expand_expr_stmt (stmt);
239 break;
243 do_pending_stack_adjust ();
245 /* Find the the block tail. The last insn is the block is the insn
246 before a barrier and/or table jump insn. */
247 last = get_last_insn ();
248 if (BARRIER_P (last))
249 last = PREV_INSN (last);
250 if (JUMP_TABLE_DATA_P (last))
251 last = PREV_INSN (PREV_INSN (last));
252 BB_END (bb) = last;
254 if (dump_file)
255 dump_bb (bb, dump_file, 0);
256 update_bb_for_insn (bb);
257 return bb;
261 /* Create a basic block for initialization code. */
263 static basic_block
264 construct_init_block (void)
266 basic_block init_block, first_block;
267 edge e;
268 unsigned ix;
270 expand_start_bindings_and_block (0, NULL_TREE);
272 FOR_EACH_EDGE (e, ENTRY_BLOCK_PTR->succ, ix)
273 if (e->dest == ENTRY_BLOCK_PTR->next_bb)
274 break;
276 init_block = create_basic_block (NEXT_INSN (get_insns ()),
277 get_last_insn (),
278 ENTRY_BLOCK_PTR);
279 init_block->frequency = ENTRY_BLOCK_PTR->frequency;
280 init_block->count = ENTRY_BLOCK_PTR->count;
281 if (e)
283 first_block = e->dest;
284 redirect_edge_succ (e, init_block);
285 e = make_edge (init_block, first_block, EDGE_FALLTHRU);
287 else
288 e = make_edge (init_block, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
289 e->probability = REG_BR_PROB_BASE;
290 e->count = ENTRY_BLOCK_PTR->count;
292 update_bb_for_insn (init_block);
293 return init_block;
297 /* Create a block containing landing pads and similar stuff. */
299 static void
300 construct_exit_block (void)
302 rtx head = get_last_insn ();
303 rtx end;
304 basic_block exit_block;
305 edge e, e2;
306 unsigned ix;
308 /* Make sure the locus is set to the end of the function, so that
309 epilogue line numbers and warnings are set properly. */
310 #ifdef USE_MAPPED_LOCATION
311 if (cfun->function_end_locus != UNKNOWN_LOCATION)
312 #else
313 if (cfun->function_end_locus.file)
314 #endif
315 input_location = cfun->function_end_locus;
317 /* The following insns belong to the top scope. */
318 record_block_change (DECL_INITIAL (current_function_decl));
320 expand_end_bindings (NULL_TREE, 1, 0);
322 /* Generate rtl for function exit. */
323 expand_function_end ();
325 end = get_last_insn ();
326 if (head == end)
327 return;
328 while (NEXT_INSN (head) && NOTE_P (NEXT_INSN (head)))
329 head = NEXT_INSN (head);
330 exit_block = create_basic_block (NEXT_INSN (head), end, EXIT_BLOCK_PTR->prev_bb);
331 exit_block->frequency = EXIT_BLOCK_PTR->frequency;
332 exit_block->count = EXIT_BLOCK_PTR->count;
334 FOR_EACH_EDGE (e, EXIT_BLOCK_PTR->pred, ix)
336 if (!(e->flags & EDGE_ABNORMAL))
337 redirect_edge_succ (e, exit_block);
339 e = make_edge (exit_block, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
340 e->probability = REG_BR_PROB_BASE;
341 e->count = EXIT_BLOCK_PTR->count;
343 FOR_EACH_EDGE (e2, EXIT_BLOCK_PTR->pred, ix)
344 if (e2 != e)
346 e->count -= e2->count;
347 exit_block->count -= e2->count;
348 exit_block->frequency -= EDGE_FREQUENCY (e2);
350 if (e->count < 0)
351 e->count = 0;
352 if (exit_block->count < 0)
353 exit_block->count = 0;
354 if (exit_block->frequency < 0)
355 exit_block->frequency = 0;
356 update_bb_for_insn (exit_block);
359 /* Translate the intermediate representation contained in the CFG
360 from GIMPLE trees to RTL.
362 We do conversion per basic block and preserve/update the tree CFG.
363 This implies we have to do some magic as the CFG can simultaneously
364 consist of basic blocks containing RTL and GIMPLE trees. This can
365 confuse the CFG hooks, so be careful to not manipulate CFG during
366 the expansion. */
368 static void
369 tree_expand_cfg (void)
371 basic_block bb, init_block;
372 sbitmap blocks;
374 if (dump_file)
376 fprintf (dump_file, "\n;; Function %s",
377 (*lang_hooks.decl_printable_name) (current_function_decl, 2));
378 fprintf (dump_file, " (%s)\n",
379 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
382 /* Prepare the rtl middle end to start recording block changes. */
383 reset_block_changes ();
385 /* Expand the variables recorded during gimple lowering. This must
386 occur before the call to expand_function_start to ensure that
387 all used variables are expanded before we expand anything on the
388 PENDING_SIZES list. */
389 expand_used_vars ();
391 /* Set up parameters and prepare for return, for the function. */
392 expand_function_start (current_function_decl);
394 /* If this function is `main', emit a call to `__main'
395 to run global initializers, etc. */
396 if (DECL_NAME (current_function_decl)
397 && MAIN_NAME_P (DECL_NAME (current_function_decl))
398 && DECL_FILE_SCOPE_P (current_function_decl))
399 expand_main_function ();
401 /* Write the flowgraph to a dot file. */
402 rtl_register_cfg_hooks ();
404 init_block = construct_init_block ();
406 FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR, next_bb)
407 bb = expand_block (bb, dump_file);
409 construct_exit_block ();
411 /* Convert from NOTE_INSN_EH_REGION style notes, and do other
412 sorts of eh initialization. Delay this until after the
413 initial rtl dump so that we can see the original nesting. */
414 convert_from_eh_region_ranges ();
416 rebuild_jump_labels (get_insns ());
417 find_exception_handler_labels ();
419 blocks = sbitmap_alloc (last_basic_block);
420 sbitmap_ones (blocks);
421 find_many_sub_basic_blocks (blocks);
422 purge_all_dead_edges (0);
423 sbitmap_free (blocks);
425 compact_blocks ();
426 #ifdef ENABLE_CHECKING
427 verify_flow_info();
428 #endif
431 struct tree_opt_pass pass_expand =
433 "expand", /* name */
434 NULL, /* gate */
435 tree_expand_cfg, /* execute */
436 NULL, /* sub */
437 NULL, /* next */
438 0, /* static_pass_number */
439 TV_EXPAND, /* tv_id */
440 /* ??? If TER is enabled, we actually receive GENERIC. */
441 PROP_gimple_leh | PROP_cfg, /* properties_required */
442 PROP_rtl, /* properties_provided */
443 PROP_gimple_leh, /* properties_destroyed */
444 0, /* todo_flags_start */
445 0 /* todo_flags_finish */