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"
38 /* Expand basic block BB from GIMPLE trees to RTL. */
41 expand_block (basic_block bb
, FILE * dump_file
)
43 block_stmt_iterator bsi
= bsi_start (bb
);
50 tree_register_cfg_hooks ();
51 dump_bb (bb
, dump_file
, 0);
52 rtl_register_cfg_hooks ();
56 stmt
= bsi_stmt (bsi
);
58 if (stmt
&& TREE_CODE (stmt
) == LABEL_EXPR
)
60 last
= get_last_insn ();
62 expand_expr_stmt (stmt
);
64 /* Java emits line number notes in the top of labels.
65 ??? Make this go away once line number notes are obsoleted. */
66 BB_HEAD (bb
) = NEXT_INSN (last
);
67 if (GET_CODE (BB_HEAD (bb
)) == NOTE
)
68 BB_HEAD (bb
) = NEXT_INSN (BB_HEAD (bb
));
70 note
= emit_note_after (NOTE_INSN_BASIC_BLOCK
, BB_HEAD (bb
));
73 note
= BB_HEAD (bb
) = emit_note (NOTE_INSN_BASIC_BLOCK
);
75 NOTE_BASIC_BLOCK (note
) = bb
;
80 edge next
= e
->succ_next
;
82 /* Clear EDGE_EXECUTABLE. This flag is never used in the backend. */
83 e
->flags
&= ~EDGE_EXECUTABLE
;
85 /* At the moment not all abnormal edges match the RTL representation.
86 It is safe to remove them here as find_sub_basic_blocks will
87 rediscover them. In the future we should get this fixed properly. */
88 if (e
->flags
& EDGE_ABNORMAL
)
94 for (; !bsi_end_p (bsi
); bsi_next (&bsi
))
96 tree stmt
= bsi_stmt (bsi
);
98 last
= get_last_insn ();
103 /* Expand this statement, then evaluate the resulting RTL and
104 fixup the CFG accordingly. */
105 switch (TREE_CODE (stmt
))
109 basic_block new_bb
, dest
;
113 tree pred
= COND_EXPR_COND (stmt
);
114 tree then_exp
= COND_EXPR_THEN (stmt
);
115 tree else_exp
= COND_EXPR_ELSE (stmt
);
116 rtx last
= get_last_insn ();
118 extract_true_false_edges_from_block (bb
, &true_edge
, &false_edge
);
119 if (EXPR_LOCUS (stmt
))
121 emit_line_note (*(EXPR_LOCUS (stmt
)));
122 record_block_change (TREE_BLOCK (stmt
));
125 /* These flags have no purpose in RTL land. */
126 true_edge
->flags
&= ~EDGE_TRUE_VALUE
;
127 false_edge
->flags
&= ~EDGE_FALSE_VALUE
;
129 /* We can either have a pure conditional jump with one fallthru
130 edge or two-way jump that needs to be decomposed into two
132 if (TREE_CODE (then_exp
) == GOTO_EXPR
133 && TREE_CODE (else_exp
) == NOP_EXPR
)
135 jumpif (pred
, label_rtx (GOTO_DESTINATION (then_exp
)));
138 if (TREE_CODE (else_exp
) == GOTO_EXPR
139 && TREE_CODE (then_exp
) == NOP_EXPR
)
141 jumpifnot (pred
, label_rtx (GOTO_DESTINATION (else_exp
)));
144 if (TREE_CODE (then_exp
) != GOTO_EXPR
145 || TREE_CODE (else_exp
) != GOTO_EXPR
)
148 jumpif (pred
, label_rtx (GOTO_DESTINATION (then_exp
)));
149 last
= get_last_insn ();
150 expand_expr (else_exp
, const0_rtx
, VOIDmode
, 0);
153 if (GET_CODE (BB_END (bb
)) == BARRIER
)
154 BB_END (bb
) = PREV_INSN (BB_END (bb
));
155 update_bb_for_insn (bb
);
157 new_bb
= create_basic_block (NEXT_INSN (last
), get_last_insn (), bb
);
158 dest
= false_edge
->dest
;
159 redirect_edge_succ (false_edge
, new_bb
);
160 false_edge
->flags
|= EDGE_FALLTHRU
;
161 new_bb
->count
= false_edge
->count
;
162 new_bb
->frequency
= EDGE_FREQUENCY (false_edge
);
163 new_edge
= make_edge (new_bb
, dest
, 0);
164 new_edge
->probability
= REG_BR_PROB_BASE
;
165 new_edge
->count
= new_bb
->count
;
166 if (GET_CODE (BB_END (new_bb
)) == BARRIER
)
167 BB_END (new_bb
) = PREV_INSN (BB_END (new_bb
));
168 update_bb_for_insn (new_bb
);
172 dump_bb (bb
, dump_file
, 0);
173 dump_bb (new_bb
, dump_file
, 0);
178 /* Update after expansion of sibling call. */
182 expand_expr_stmt (stmt
);
183 for (last
= NEXT_INSN (last
); last
; last
= NEXT_INSN (last
))
185 if (GET_CODE (last
) == CALL_INSN
&& SIBLING_CALL_P (last
))
191 do_pending_stack_adjust ();
195 edge next
= e
->succ_next
;
197 if (!(e
->flags
& (EDGE_ABNORMAL
| EDGE_EH
)))
199 if (e
->dest
!= EXIT_BLOCK_PTR
)
201 e
->dest
->count
-= e
->count
;
202 e
->dest
->frequency
-= EDGE_FREQUENCY (e
);
203 if (e
->dest
->count
< 0)
205 if (e
->dest
->frequency
< 0)
206 e
->dest
->frequency
= 0;
209 probability
+= e
->probability
;
216 /* This is somewhat ugly: the call_expr expander often emits instructions
217 after the sibcall (to perform the function return). These confuse the
218 find_sub_basic_blocks code, so we need to get rid of these. */
219 last
= NEXT_INSN (last
);
220 if (GET_CODE (last
) != BARRIER
)
222 while (NEXT_INSN (last
))
224 /* For instance an sqrt builtin expander expands if with
225 sibcall in the then and label for `else`. */
226 if (GET_CODE (NEXT_INSN (last
)) == CODE_LABEL
)
228 delete_insn (NEXT_INSN (last
));
230 e
= make_edge (bb
, EXIT_BLOCK_PTR
,
231 EDGE_ABNORMAL
| EDGE_SIBCALL
);
232 e
->probability
+= probability
;
235 update_bb_for_insn (bb
);
236 if (NEXT_INSN (last
))
237 bb
= create_basic_block (NEXT_INSN (last
), get_last_insn (), bb
);
245 expand_expr_stmt (stmt
);
250 do_pending_stack_adjust ();
252 /* Find the the block tail. The last insn is the block is the insn
253 before a barrier and/or table jump insn. */
254 last
= get_last_insn ();
255 if (GET_CODE (last
) == BARRIER
)
256 last
= PREV_INSN (last
);
257 if (JUMP_TABLE_DATA_P (last
))
258 last
= PREV_INSN (PREV_INSN (last
));
262 dump_bb (bb
, dump_file
, 0);
263 update_bb_for_insn (bb
);
268 /* Create a basic block for initialization code. */
271 construct_init_block (void)
273 basic_block init_block
, first_block
;
276 expand_start_bindings_and_block (0, NULL_TREE
);
278 for (e
= ENTRY_BLOCK_PTR
->succ
; e
; e
= e
->succ_next
)
279 if (e
->dest
== ENTRY_BLOCK_PTR
->next_bb
)
282 init_block
= create_basic_block (NEXT_INSN (get_insns ()),
285 init_block
->frequency
= ENTRY_BLOCK_PTR
->frequency
;
286 init_block
->count
= ENTRY_BLOCK_PTR
->count
;
289 first_block
= e
->dest
;
290 redirect_edge_succ (e
, init_block
);
291 e
= make_edge (init_block
, first_block
, EDGE_FALLTHRU
);
294 e
= make_edge (init_block
, EXIT_BLOCK_PTR
, EDGE_FALLTHRU
);
295 e
->probability
= REG_BR_PROB_BASE
;
296 e
->count
= ENTRY_BLOCK_PTR
->count
;
298 update_bb_for_insn (init_block
);
303 /* Create a block containing landing pads and similar stuff. */
306 construct_exit_block (void)
308 rtx head
= get_last_insn ();
310 basic_block exit_block
;
313 /* Make sure the locus is set to the end of the function, so that
314 epilogue line numbers and warnings are set properly. */
315 #ifdef USE_MAPPED_LOCATION
316 if (cfun
->function_end_locus
!= UNKNOWN_LOCATION
)
318 if (cfun
->function_end_locus
.file
)
320 input_location
= cfun
->function_end_locus
;
322 /* The following insns belong to the top scope. */
323 record_block_change (DECL_INITIAL (current_function_decl
));
325 expand_end_bindings (NULL_TREE
, 1, 0);
327 /* Generate rtl for function exit. */
328 expand_function_end ();
330 end
= get_last_insn ();
333 while (NEXT_INSN (head
) && GET_CODE (NEXT_INSN (head
)) == NOTE
)
334 head
= NEXT_INSN (head
);
335 exit_block
= create_basic_block (NEXT_INSN (head
), end
, EXIT_BLOCK_PTR
->prev_bb
);
336 exit_block
->frequency
= EXIT_BLOCK_PTR
->frequency
;
337 exit_block
->count
= EXIT_BLOCK_PTR
->count
;
338 for (e
= EXIT_BLOCK_PTR
->pred
; e
; e
= next
)
341 if (!(e
->flags
& EDGE_ABNORMAL
))
342 redirect_edge_succ (e
, exit_block
);
344 e
= make_edge (exit_block
, EXIT_BLOCK_PTR
, EDGE_FALLTHRU
);
345 e
->probability
= REG_BR_PROB_BASE
;
346 e
->count
= EXIT_BLOCK_PTR
->count
;
347 for (e2
= EXIT_BLOCK_PTR
->pred
; e2
; e2
= e2
->pred_next
)
350 e
->count
-= e2
->count
;
351 exit_block
->count
-= e2
->count
;
352 exit_block
->frequency
-= EDGE_FREQUENCY (e2
);
356 if (exit_block
->count
< 0)
357 exit_block
->count
= 0;
358 if (exit_block
->frequency
< 0)
359 exit_block
->frequency
= 0;
360 update_bb_for_insn (exit_block
);
363 /* Translate the intermediate representation contained in the CFG
364 from GIMPLE trees to RTL.
366 We do conversion per basic block and preserve/update the tree CFG.
367 This implies we have to do some magic as the CFG can simultaneously
368 consist of basic blocks containing RTL and GIMPLE trees. This can
369 confuse the CFG hooks, so be careful to not manipulate CFG during
373 tree_expand_cfg (void)
375 basic_block bb
, init_block
;
380 fprintf (dump_file
, "\n;; Function %s",
381 (*lang_hooks
.decl_printable_name
) (current_function_decl
, 2));
382 fprintf (dump_file
, " (%s)\n",
383 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl
)));
386 /* Prepare the rtl middle end to start recording block changes. */
387 reset_block_changes ();
389 /* Expand the variables recorded during gimple lowering. This must
390 occur before the call to expand_function_start to ensure that
391 all used variables are expanded before we expand anything on the
392 PENDING_SIZES list. */
395 /* Set up parameters and prepare for return, for the function. */
396 expand_function_start (current_function_decl
);
398 /* If this function is `main', emit a call to `__main'
399 to run global initializers, etc. */
400 if (DECL_NAME (current_function_decl
)
401 && MAIN_NAME_P (DECL_NAME (current_function_decl
))
402 && DECL_FILE_SCOPE_P (current_function_decl
))
403 expand_main_function ();
405 /* Write the flowgraph to a dot file. */
406 rtl_register_cfg_hooks ();
408 init_block
= construct_init_block ();
410 FOR_BB_BETWEEN (bb
, init_block
->next_bb
, EXIT_BLOCK_PTR
, next_bb
)
411 bb
= expand_block (bb
, dump_file
);
413 construct_exit_block ();
415 /* Convert from NOTE_INSN_EH_REGION style notes, and do other
416 sorts of eh initialization. Delay this until after the
417 initial rtl dump so that we can see the original nesting. */
418 convert_from_eh_region_ranges ();
420 rebuild_jump_labels (get_insns ());
421 find_exception_handler_labels ();
423 blocks
= sbitmap_alloc (last_basic_block
);
424 sbitmap_ones (blocks
);
425 find_many_sub_basic_blocks (blocks
);
426 purge_all_dead_edges (0);
427 sbitmap_free (blocks
);
430 #ifdef ENABLE_CHECKING
435 struct tree_opt_pass pass_expand
=
439 tree_expand_cfg
, /* execute */
442 0, /* static_pass_number */
443 TV_EXPAND
, /* tv_id */
444 /* ??? If TER is enabled, we actually receive GENERIC. */
445 PROP_gimple_leh
| PROP_cfg
, /* properties_required */
446 PROP_rtl
, /* properties_provided */
447 PROP_gimple_leh
, /* properties_destroyed */
448 0, /* todo_flags_start */
449 0 /* todo_flags_finish */