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)
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. */
23 #include "coretypes.h"
28 #include "basic-block.h"
31 #include "langhooks.h"
32 #include "tree-flow.h"
34 #include "tree-dump.h"
35 #include "tree-pass.h"
40 /* A subroutine of expand_gimple_basic_block. Expand one COND_EXPR.
41 Returns a new basic block if we've terminated the current basic
42 block and created a new one. */
45 expand_gimple_cond_expr (basic_block bb, tree stmt)
47 basic_block new_bb, dest;
51 tree pred = COND_EXPR_COND (stmt);
52 tree then_exp = COND_EXPR_THEN (stmt);
53 tree else_exp = COND_EXPR_ELSE (stmt);
56 extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
57 if (EXPR_LOCUS (stmt))
59 emit_line_note (*(EXPR_LOCUS (stmt)));
60 record_block_change (TREE_BLOCK (stmt));
63 /* These flags have no purpose in RTL land. */
64 true_edge->flags &= ~EDGE_TRUE_VALUE;
65 false_edge->flags &= ~EDGE_FALSE_VALUE;
67 /* We can either have a pure conditional jump with one fallthru edge or
68 two-way jump that needs to be decomposed into two basic blocks. */
69 if (TREE_CODE (then_exp) == GOTO_EXPR && IS_EMPTY_STMT (else_exp))
71 jumpif (pred, label_rtx (GOTO_DESTINATION (then_exp)));
74 if (TREE_CODE (else_exp) == GOTO_EXPR && IS_EMPTY_STMT (then_exp))
76 jumpifnot (pred, label_rtx (GOTO_DESTINATION (else_exp)));
79 if (TREE_CODE (then_exp) != GOTO_EXPR || TREE_CODE (else_exp) != GOTO_EXPR)
82 jumpif (pred, label_rtx (GOTO_DESTINATION (then_exp)));
83 last = get_last_insn ();
84 expand_expr (else_exp, const0_rtx, VOIDmode, 0);
87 if (BARRIER_P (BB_END (bb)))
88 BB_END (bb) = PREV_INSN (BB_END (bb));
89 update_bb_for_insn (bb);
91 new_bb = create_basic_block (NEXT_INSN (last), get_last_insn (), bb);
92 dest = false_edge->dest;
93 redirect_edge_succ (false_edge, new_bb);
94 false_edge->flags |= EDGE_FALLTHRU;
95 new_bb->count = false_edge->count;
96 new_bb->frequency = EDGE_FREQUENCY (false_edge);
97 new_edge = make_edge (new_bb, dest, 0);
98 new_edge->probability = REG_BR_PROB_BASE;
99 new_edge->count = new_bb->count;
100 if (BARRIER_P (BB_END (new_bb)))
101 BB_END (new_bb) = PREV_INSN (BB_END (new_bb));
102 update_bb_for_insn (new_bb);
106 dump_bb (bb, dump_file, 0);
107 dump_bb (new_bb, dump_file, 0);
113 /* A subroutine of expand_gimple_basic_block. Expand one CALL_EXPR
114 that has CALL_EXPR_TAILCALL set. Returns a new basic block if we've
115 terminated the current basic block and created a new one. */
118 expand_gimple_tailcall (basic_block bb, tree stmt)
120 rtx last = get_last_insn ();
122 expand_expr_stmt (stmt);
124 for (last = NEXT_INSN (last); last; last = NEXT_INSN (last))
126 if (CALL_P (last) && SIBLING_CALL_P (last))
132 do_pending_stack_adjust ();
136 edge next = e->succ_next;
138 if (!(e->flags & (EDGE_ABNORMAL | EDGE_EH)))
140 if (e->dest != EXIT_BLOCK_PTR)
142 e->dest->count -= e->count;
143 e->dest->frequency -= EDGE_FREQUENCY (e);
144 if (e->dest->count < 0)
146 if (e->dest->frequency < 0)
147 e->dest->frequency = 0;
150 probability += e->probability;
157 /* This is somewhat ugly: the call_expr expander often emits
158 instructions after the sibcall (to perform the function
159 return). These confuse the find_sub_basic_blocks code,
160 so we need to get rid of these. */
161 last = NEXT_INSN (last);
162 if (!BARRIER_P (last))
164 while (NEXT_INSN (last))
166 /* For instance an sqrt builtin expander expands if with
167 sibcall in the then and label for `else`. */
168 if (LABEL_P (NEXT_INSN (last)))
170 delete_insn (NEXT_INSN (last));
172 e = make_edge (bb, EXIT_BLOCK_PTR, EDGE_ABNORMAL | EDGE_SIBCALL);
173 e->probability += probability;
176 update_bb_for_insn (bb);
177 if (NEXT_INSN (last))
178 bb = create_basic_block (NEXT_INSN (last), get_last_insn (), bb);
187 /* Expand basic block BB from GIMPLE trees to RTL. */
190 expand_gimple_basic_block (basic_block bb, FILE * dump_file)
192 block_stmt_iterator bsi = bsi_start (bb);
199 tree_register_cfg_hooks ();
200 dump_bb (bb, dump_file, 0);
201 rtl_register_cfg_hooks ();
204 if (!bsi_end_p (bsi))
205 stmt = bsi_stmt (bsi);
207 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
209 last = get_last_insn ();
211 expand_expr_stmt (stmt);
213 /* Java emits line number notes in the top of labels.
214 ??? Make this go away once line number notes are obsoleted. */
215 BB_HEAD (bb) = NEXT_INSN (last);
216 if (NOTE_P (BB_HEAD (bb)))
217 BB_HEAD (bb) = NEXT_INSN (BB_HEAD (bb));
219 note = emit_note_after (NOTE_INSN_BASIC_BLOCK, BB_HEAD (bb));
222 note = BB_HEAD (bb) = emit_note (NOTE_INSN_BASIC_BLOCK);
224 NOTE_BASIC_BLOCK (note) = bb;
229 edge next = e->succ_next;
231 /* Clear EDGE_EXECUTABLE. This flag is never used in the backend. */
232 e->flags &= ~EDGE_EXECUTABLE;
234 /* At the moment not all abnormal edges match the RTL representation.
235 It is safe to remove them here as find_sub_basic_blocks will
236 rediscover them. In the future we should get this fixed properly. */
237 if (e->flags & EDGE_ABNORMAL)
243 for (; !bsi_end_p (bsi); bsi_next (&bsi))
245 tree stmt = bsi_stmt (bsi);
246 basic_block new_bb = NULL;
251 /* Expand this statement, then evaluate the resulting RTL and
252 fixup the CFG accordingly. */
253 if (TREE_CODE (stmt) == COND_EXPR)
254 new_bb = expand_gimple_cond_expr (bb, stmt);
257 tree call = get_call_expr_in (stmt);
258 if (call && CALL_EXPR_TAILCALL (call))
259 new_bb = expand_gimple_tailcall (bb, stmt);
261 expand_expr_stmt (stmt);
268 do_pending_stack_adjust ();
270 /* Find the the block tail. The last insn is the block is the insn
271 before a barrier and/or table jump insn. */
272 last = get_last_insn ();
273 if (BARRIER_P (last))
274 last = PREV_INSN (last);
275 if (JUMP_TABLE_DATA_P (last))
276 last = PREV_INSN (PREV_INSN (last));
280 dump_bb (bb, dump_file, 0);
281 update_bb_for_insn (bb);
287 /* Create a basic block for initialization code. */
290 construct_init_block (void)
292 basic_block init_block, first_block;
295 expand_start_bindings_and_block (0, NULL_TREE);
297 for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
298 if (e->dest == ENTRY_BLOCK_PTR->next_bb)
301 init_block = create_basic_block (NEXT_INSN (get_insns ()),
304 init_block->frequency = ENTRY_BLOCK_PTR->frequency;
305 init_block->count = ENTRY_BLOCK_PTR->count;
308 first_block = e->dest;
309 redirect_edge_succ (e, init_block);
310 e = make_edge (init_block, first_block, EDGE_FALLTHRU);
313 e = make_edge (init_block, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
314 e->probability = REG_BR_PROB_BASE;
315 e->count = ENTRY_BLOCK_PTR->count;
317 update_bb_for_insn (init_block);
322 /* Create a block containing landing pads and similar stuff. */
325 construct_exit_block (void)
327 rtx head = get_last_insn ();
329 basic_block exit_block;
332 /* Make sure the locus is set to the end of the function, so that
333 epilogue line numbers and warnings are set properly. */
334 #ifdef USE_MAPPED_LOCATION
335 if (cfun->function_end_locus != UNKNOWN_LOCATION)
337 if (cfun->function_end_locus.file)
339 input_location = cfun->function_end_locus;
341 /* The following insns belong to the top scope. */
342 record_block_change (DECL_INITIAL (current_function_decl));
344 expand_end_bindings (NULL_TREE, 1, 0);
346 /* Generate rtl for function exit. */
347 expand_function_end ();
349 end = get_last_insn ();
352 while (NEXT_INSN (head) && NOTE_P (NEXT_INSN (head)))
353 head = NEXT_INSN (head);
354 exit_block = create_basic_block (NEXT_INSN (head), end,
355 EXIT_BLOCK_PTR->prev_bb);
356 exit_block->frequency = EXIT_BLOCK_PTR->frequency;
357 exit_block->count = EXIT_BLOCK_PTR->count;
358 for (e = EXIT_BLOCK_PTR->pred; e; e = next)
361 if (!(e->flags & EDGE_ABNORMAL))
362 redirect_edge_succ (e, exit_block);
364 e = make_edge (exit_block, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
365 e->probability = REG_BR_PROB_BASE;
366 e->count = EXIT_BLOCK_PTR->count;
367 for (e2 = EXIT_BLOCK_PTR->pred; e2; e2 = e2->pred_next)
370 e->count -= e2->count;
371 exit_block->count -= e2->count;
372 exit_block->frequency -= EDGE_FREQUENCY (e2);
376 if (exit_block->count < 0)
377 exit_block->count = 0;
378 if (exit_block->frequency < 0)
379 exit_block->frequency = 0;
380 update_bb_for_insn (exit_block);
383 /* Translate the intermediate representation contained in the CFG
384 from GIMPLE trees to RTL.
386 We do conversion per basic block and preserve/update the tree CFG.
387 This implies we have to do some magic as the CFG can simultaneously
388 consist of basic blocks containing RTL and GIMPLE trees. This can
389 confuse the CFG hooks, so be careful to not manipulate CFG during
393 tree_expand_cfg (void)
395 basic_block bb, init_block;
400 fprintf (dump_file, "\n;; Function %s",
401 (*lang_hooks.decl_printable_name) (current_function_decl, 2));
402 fprintf (dump_file, " (%s)\n",
403 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
406 /* Prepare the rtl middle end to start recording block changes. */
407 reset_block_changes ();
409 /* Expand the variables recorded during gimple lowering. This must
410 occur before the call to expand_function_start to ensure that
411 all used variables are expanded before we expand anything on the
412 PENDING_SIZES list. */
415 /* Set up parameters and prepare for return, for the function. */
416 expand_function_start (current_function_decl);
418 /* If this function is `main', emit a call to `__main'
419 to run global initializers, etc. */
420 if (DECL_NAME (current_function_decl)
421 && MAIN_NAME_P (DECL_NAME (current_function_decl))
422 && DECL_FILE_SCOPE_P (current_function_decl))
423 expand_main_function ();
425 /* Write the flowgraph to a dot file. */
426 rtl_register_cfg_hooks ();
428 init_block = construct_init_block ();
430 FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR, next_bb)
431 bb = expand_gimple_basic_block (bb, dump_file);
433 construct_exit_block ();
435 /* Convert from NOTE_INSN_EH_REGION style notes, and do other
436 sorts of eh initialization. Delay this until after the
437 initial rtl dump so that we can see the original nesting. */
438 convert_from_eh_region_ranges ();
440 rebuild_jump_labels (get_insns ());
441 find_exception_handler_labels ();
443 blocks = sbitmap_alloc (last_basic_block);
444 sbitmap_ones (blocks);
445 find_many_sub_basic_blocks (blocks);
446 purge_all_dead_edges (0);
447 sbitmap_free (blocks);
450 #ifdef ENABLE_CHECKING
455 struct tree_opt_pass pass_expand =
459 tree_expand_cfg, /* execute */
462 0, /* static_pass_number */
463 TV_EXPAND, /* tv_id */
464 /* ??? If TER is enabled, we actually receive GENERIC. */
465 PROP_gimple_leh | PROP_cfg, /* properties_required */
466 PROP_rtl, /* properties_provided */
467 PROP_gimple_leh, /* properties_destroyed */
468 0, /* todo_flags_start */
469 0 /* todo_flags_finish */