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 non-null if we actually
115 generated a tail call (something that might be denied by the ABI
116 rules governing the call; see calls.c). */
119 expand_gimple_tailcall (basic_block bb
, tree stmt
)
121 rtx last
= get_last_insn ();
126 expand_expr_stmt (stmt
);
128 for (last
= NEXT_INSN (last
); last
; last
= NEXT_INSN (last
))
129 if (CALL_P (last
) && SIBLING_CALL_P (last
))
135 /* ??? Wouldn't it be better to just reset any pending stack adjust?
136 Any instructions emitted here are about to be deleted. */
137 do_pending_stack_adjust ();
139 /* Remove any non-eh, non-abnormal edges that don't go to exit. */
140 /* ??? I.e. the fallthrough edge. HOWEVER! If there were to be
141 EH or abnormal edges, we shouldn't have created a tail call in
142 the first place. So it seems to me we should just be removing
143 all edges here, or redirecting the existing fallthru edge to
151 edge next
= e
->succ_next
;
153 if (!(e
->flags
& (EDGE_ABNORMAL
| EDGE_EH
)))
155 if (e
->dest
!= EXIT_BLOCK_PTR
)
157 e
->dest
->count
-= e
->count
;
158 e
->dest
->frequency
-= EDGE_FREQUENCY (e
);
159 if (e
->dest
->count
< 0)
161 if (e
->dest
->frequency
< 0)
162 e
->dest
->frequency
= 0;
165 probability
+= e
->probability
;
172 /* This is somewhat ugly: the call_expr expander often emits instructions
173 after the sibcall (to perform the function return). These confuse the
174 find_sub_basic_blocks code, so we need to get rid of these. */
175 last
= NEXT_INSN (last
);
176 if (!BARRIER_P (last
))
178 while (NEXT_INSN (last
))
180 /* For instance an sqrt builtin expander expands if with
181 sibcall in the then and label for `else`. */
182 if (LABEL_P (NEXT_INSN (last
)))
184 delete_insn (NEXT_INSN (last
));
187 e
= make_edge (bb
, EXIT_BLOCK_PTR
, EDGE_ABNORMAL
| EDGE_SIBCALL
);
188 e
->probability
+= probability
;
191 update_bb_for_insn (bb
);
193 if (NEXT_INSN (last
))
195 bb
= create_basic_block (NEXT_INSN (last
), get_last_insn (), bb
);
198 if (BARRIER_P (last
))
199 BB_END (bb
) = PREV_INSN (last
);
205 /* Expand basic block BB from GIMPLE trees to RTL. */
208 expand_gimple_basic_block (basic_block bb
, FILE * dump_file
)
210 block_stmt_iterator bsi
= bsi_start (bb
);
217 tree_register_cfg_hooks ();
218 dump_bb (bb
, dump_file
, 0);
219 rtl_register_cfg_hooks ();
222 if (!bsi_end_p (bsi
))
223 stmt
= bsi_stmt (bsi
);
225 if (stmt
&& TREE_CODE (stmt
) == LABEL_EXPR
)
227 last
= get_last_insn ();
229 expand_expr_stmt (stmt
);
231 /* Java emits line number notes in the top of labels.
232 ??? Make this go away once line number notes are obsoleted. */
233 BB_HEAD (bb
) = NEXT_INSN (last
);
234 if (NOTE_P (BB_HEAD (bb
)))
235 BB_HEAD (bb
) = NEXT_INSN (BB_HEAD (bb
));
237 note
= emit_note_after (NOTE_INSN_BASIC_BLOCK
, BB_HEAD (bb
));
240 note
= BB_HEAD (bb
) = emit_note (NOTE_INSN_BASIC_BLOCK
);
242 NOTE_BASIC_BLOCK (note
) = bb
;
247 edge next
= e
->succ_next
;
249 /* Clear EDGE_EXECUTABLE. This flag is never used in the backend. */
250 e
->flags
&= ~EDGE_EXECUTABLE
;
252 /* At the moment not all abnormal edges match the RTL representation.
253 It is safe to remove them here as find_sub_basic_blocks will
254 rediscover them. In the future we should get this fixed properly. */
255 if (e
->flags
& EDGE_ABNORMAL
)
261 for (; !bsi_end_p (bsi
); bsi_next (&bsi
))
263 tree stmt
= bsi_stmt (bsi
);
264 basic_block new_bb
= NULL
;
269 /* Expand this statement, then evaluate the resulting RTL and
270 fixup the CFG accordingly. */
271 if (TREE_CODE (stmt
) == COND_EXPR
)
272 new_bb
= expand_gimple_cond_expr (bb
, stmt
);
275 tree call
= get_call_expr_in (stmt
);
276 if (call
&& CALL_EXPR_TAILCALL (call
))
277 new_bb
= expand_gimple_tailcall (bb
, stmt
);
279 expand_expr_stmt (stmt
);
286 do_pending_stack_adjust ();
288 /* Find the the block tail. The last insn is the block is the insn
289 before a barrier and/or table jump insn. */
290 last
= get_last_insn ();
291 if (BARRIER_P (last
))
292 last
= PREV_INSN (last
);
293 if (JUMP_TABLE_DATA_P (last
))
294 last
= PREV_INSN (PREV_INSN (last
));
298 dump_bb (bb
, dump_file
, 0);
299 update_bb_for_insn (bb
);
305 /* Create a basic block for initialization code. */
308 construct_init_block (void)
310 basic_block init_block
, first_block
;
313 for (e
= ENTRY_BLOCK_PTR
->succ
; e
; e
= e
->succ_next
)
314 if (e
->dest
== ENTRY_BLOCK_PTR
->next_bb
)
317 init_block
= create_basic_block (NEXT_INSN (get_insns ()),
320 init_block
->frequency
= ENTRY_BLOCK_PTR
->frequency
;
321 init_block
->count
= ENTRY_BLOCK_PTR
->count
;
324 first_block
= e
->dest
;
325 redirect_edge_succ (e
, init_block
);
326 e
= make_edge (init_block
, first_block
, EDGE_FALLTHRU
);
329 e
= make_edge (init_block
, EXIT_BLOCK_PTR
, EDGE_FALLTHRU
);
330 e
->probability
= REG_BR_PROB_BASE
;
331 e
->count
= ENTRY_BLOCK_PTR
->count
;
333 update_bb_for_insn (init_block
);
338 /* Create a block containing landing pads and similar stuff. */
341 construct_exit_block (void)
343 rtx head
= get_last_insn ();
345 basic_block exit_block
;
348 /* Make sure the locus is set to the end of the function, so that
349 epilogue line numbers and warnings are set properly. */
350 #ifdef USE_MAPPED_LOCATION
351 if (cfun
->function_end_locus
!= UNKNOWN_LOCATION
)
353 if (cfun
->function_end_locus
.file
)
355 input_location
= cfun
->function_end_locus
;
357 /* The following insns belong to the top scope. */
358 record_block_change (DECL_INITIAL (current_function_decl
));
360 /* Generate rtl for function exit. */
361 expand_function_end ();
363 end
= get_last_insn ();
366 while (NEXT_INSN (head
) && NOTE_P (NEXT_INSN (head
)))
367 head
= NEXT_INSN (head
);
368 exit_block
= create_basic_block (NEXT_INSN (head
), end
,
369 EXIT_BLOCK_PTR
->prev_bb
);
370 exit_block
->frequency
= EXIT_BLOCK_PTR
->frequency
;
371 exit_block
->count
= EXIT_BLOCK_PTR
->count
;
372 for (e
= EXIT_BLOCK_PTR
->pred
; e
; e
= next
)
375 if (!(e
->flags
& EDGE_ABNORMAL
))
376 redirect_edge_succ (e
, exit_block
);
378 e
= make_edge (exit_block
, EXIT_BLOCK_PTR
, EDGE_FALLTHRU
);
379 e
->probability
= REG_BR_PROB_BASE
;
380 e
->count
= EXIT_BLOCK_PTR
->count
;
381 for (e2
= EXIT_BLOCK_PTR
->pred
; e2
; e2
= e2
->pred_next
)
384 e
->count
-= e2
->count
;
385 exit_block
->count
-= e2
->count
;
386 exit_block
->frequency
-= EDGE_FREQUENCY (e2
);
390 if (exit_block
->count
< 0)
391 exit_block
->count
= 0;
392 if (exit_block
->frequency
< 0)
393 exit_block
->frequency
= 0;
394 update_bb_for_insn (exit_block
);
397 /* Translate the intermediate representation contained in the CFG
398 from GIMPLE trees to RTL.
400 We do conversion per basic block and preserve/update the tree CFG.
401 This implies we have to do some magic as the CFG can simultaneously
402 consist of basic blocks containing RTL and GIMPLE trees. This can
403 confuse the CFG hooks, so be careful to not manipulate CFG during
407 tree_expand_cfg (void)
409 basic_block bb
, init_block
;
414 fprintf (dump_file
, "\n;; Function %s",
415 (*lang_hooks
.decl_printable_name
) (current_function_decl
, 2));
416 fprintf (dump_file
, " (%s)\n",
417 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl
)));
420 /* Prepare the rtl middle end to start recording block changes. */
421 reset_block_changes ();
423 /* Expand the variables recorded during gimple lowering. This must
424 occur before the call to expand_function_start to ensure that
425 all used variables are expanded before we expand anything on the
426 PENDING_SIZES list. */
429 /* Set up parameters and prepare for return, for the function. */
430 expand_function_start (current_function_decl
);
432 /* If this function is `main', emit a call to `__main'
433 to run global initializers, etc. */
434 if (DECL_NAME (current_function_decl
)
435 && MAIN_NAME_P (DECL_NAME (current_function_decl
))
436 && DECL_FILE_SCOPE_P (current_function_decl
))
437 expand_main_function ();
439 /* Write the flowgraph to a dot file. */
440 rtl_register_cfg_hooks ();
442 init_block
= construct_init_block ();
444 FOR_BB_BETWEEN (bb
, init_block
->next_bb
, EXIT_BLOCK_PTR
, next_bb
)
445 bb
= expand_gimple_basic_block (bb
, dump_file
);
447 construct_exit_block ();
449 /* Convert from NOTE_INSN_EH_REGION style notes, and do other
450 sorts of eh initialization. Delay this until after the
451 initial rtl dump so that we can see the original nesting. */
452 convert_from_eh_region_ranges ();
454 rebuild_jump_labels (get_insns ());
455 find_exception_handler_labels ();
457 blocks
= sbitmap_alloc (last_basic_block
);
458 sbitmap_ones (blocks
);
459 find_many_sub_basic_blocks (blocks
);
460 purge_all_dead_edges (0);
461 sbitmap_free (blocks
);
464 #ifdef ENABLE_CHECKING
469 struct tree_opt_pass pass_expand
=
473 tree_expand_cfg
, /* execute */
476 0, /* static_pass_number */
477 TV_EXPAND
, /* tv_id */
478 /* ??? If TER is enabled, we actually receive GENERIC. */
479 PROP_gimple_leh
| PROP_cfg
, /* properties_required */
480 PROP_rtl
, /* properties_provided */
481 PROP_gimple_leh
, /* properties_destroyed */
482 0, /* todo_flags_start */
483 0 /* todo_flags_finish */