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 /* Expand variables in the unexpanded_var_list. */
43 expand_used_vars (void)
47 cfun
->unexpanded_var_list
= nreverse (cfun
->unexpanded_var_list
);
49 for (cell
= cfun
->unexpanded_var_list
; cell
; cell
= TREE_CHAIN (cell
))
50 expand_var (TREE_VALUE (cell
));
52 cfun
->unexpanded_var_list
= NULL_TREE
;
56 /* A subroutine of expand_gimple_basic_block. Expand one COND_EXPR.
57 Returns a new basic block if we've terminated the current basic
58 block and created a new one. */
61 expand_gimple_cond_expr (basic_block bb
, tree stmt
)
63 basic_block new_bb
, dest
;
67 tree pred
= COND_EXPR_COND (stmt
);
68 tree then_exp
= COND_EXPR_THEN (stmt
);
69 tree else_exp
= COND_EXPR_ELSE (stmt
);
72 extract_true_false_edges_from_block (bb
, &true_edge
, &false_edge
);
73 if (EXPR_LOCUS (stmt
))
75 emit_line_note (*(EXPR_LOCUS (stmt
)));
76 record_block_change (TREE_BLOCK (stmt
));
79 /* These flags have no purpose in RTL land. */
80 true_edge
->flags
&= ~EDGE_TRUE_VALUE
;
81 false_edge
->flags
&= ~EDGE_FALSE_VALUE
;
83 /* We can either have a pure conditional jump with one fallthru edge or
84 two-way jump that needs to be decomposed into two basic blocks. */
85 if (TREE_CODE (then_exp
) == GOTO_EXPR
&& IS_EMPTY_STMT (else_exp
))
87 jumpif (pred
, label_rtx (GOTO_DESTINATION (then_exp
)));
90 if (TREE_CODE (else_exp
) == GOTO_EXPR
&& IS_EMPTY_STMT (then_exp
))
92 jumpifnot (pred
, label_rtx (GOTO_DESTINATION (else_exp
)));
95 if (TREE_CODE (then_exp
) != GOTO_EXPR
|| TREE_CODE (else_exp
) != GOTO_EXPR
)
98 jumpif (pred
, label_rtx (GOTO_DESTINATION (then_exp
)));
99 last
= get_last_insn ();
100 expand_expr (else_exp
, const0_rtx
, VOIDmode
, 0);
103 if (BARRIER_P (BB_END (bb
)))
104 BB_END (bb
) = PREV_INSN (BB_END (bb
));
105 update_bb_for_insn (bb
);
107 new_bb
= create_basic_block (NEXT_INSN (last
), get_last_insn (), bb
);
108 dest
= false_edge
->dest
;
109 redirect_edge_succ (false_edge
, new_bb
);
110 false_edge
->flags
|= EDGE_FALLTHRU
;
111 new_bb
->count
= false_edge
->count
;
112 new_bb
->frequency
= EDGE_FREQUENCY (false_edge
);
113 new_edge
= make_edge (new_bb
, dest
, 0);
114 new_edge
->probability
= REG_BR_PROB_BASE
;
115 new_edge
->count
= new_bb
->count
;
116 if (BARRIER_P (BB_END (new_bb
)))
117 BB_END (new_bb
) = PREV_INSN (BB_END (new_bb
));
118 update_bb_for_insn (new_bb
);
122 dump_bb (bb
, dump_file
, 0);
123 dump_bb (new_bb
, dump_file
, 0);
129 /* A subroutine of expand_gimple_basic_block. Expand one CALL_EXPR
130 that has CALL_EXPR_TAILCALL set. Returns non-null if we actually
131 generated a tail call (something that might be denied by the ABI
132 rules governing the call; see calls.c). */
135 expand_gimple_tailcall (basic_block bb
, tree stmt
)
137 rtx last
= get_last_insn ();
142 expand_expr_stmt (stmt
);
144 for (last
= NEXT_INSN (last
); last
; last
= NEXT_INSN (last
))
145 if (CALL_P (last
) && SIBLING_CALL_P (last
))
151 /* ??? Wouldn't it be better to just reset any pending stack adjust?
152 Any instructions emitted here are about to be deleted. */
153 do_pending_stack_adjust ();
155 /* Remove any non-eh, non-abnormal edges that don't go to exit. */
156 /* ??? I.e. the fallthrough edge. HOWEVER! If there were to be
157 EH or abnormal edges, we shouldn't have created a tail call in
158 the first place. So it seems to me we should just be removing
159 all edges here, or redirecting the existing fallthru edge to
167 edge next
= e
->succ_next
;
169 if (!(e
->flags
& (EDGE_ABNORMAL
| EDGE_EH
)))
171 if (e
->dest
!= EXIT_BLOCK_PTR
)
173 e
->dest
->count
-= e
->count
;
174 e
->dest
->frequency
-= EDGE_FREQUENCY (e
);
175 if (e
->dest
->count
< 0)
177 if (e
->dest
->frequency
< 0)
178 e
->dest
->frequency
= 0;
181 probability
+= e
->probability
;
188 /* This is somewhat ugly: the call_expr expander often emits instructions
189 after the sibcall (to perform the function return). These confuse the
190 find_sub_basic_blocks code, so we need to get rid of these. */
191 last
= NEXT_INSN (last
);
192 if (!BARRIER_P (last
))
194 while (NEXT_INSN (last
))
196 /* For instance an sqrt builtin expander expands if with
197 sibcall in the then and label for `else`. */
198 if (LABEL_P (NEXT_INSN (last
)))
200 delete_insn (NEXT_INSN (last
));
203 e
= make_edge (bb
, EXIT_BLOCK_PTR
, EDGE_ABNORMAL
| EDGE_SIBCALL
);
204 e
->probability
+= probability
;
207 update_bb_for_insn (bb
);
209 if (NEXT_INSN (last
))
211 bb
= create_basic_block (NEXT_INSN (last
), get_last_insn (), bb
);
214 if (BARRIER_P (last
))
215 BB_END (bb
) = PREV_INSN (last
);
221 /* Expand basic block BB from GIMPLE trees to RTL. */
224 expand_gimple_basic_block (basic_block bb
, FILE * dump_file
)
226 block_stmt_iterator bsi
= bsi_start (bb
);
233 tree_register_cfg_hooks ();
234 dump_bb (bb
, dump_file
, 0);
235 rtl_register_cfg_hooks ();
238 if (!bsi_end_p (bsi
))
239 stmt
= bsi_stmt (bsi
);
241 if (stmt
&& TREE_CODE (stmt
) == LABEL_EXPR
)
243 last
= get_last_insn ();
245 expand_expr_stmt (stmt
);
247 /* Java emits line number notes in the top of labels.
248 ??? Make this go away once line number notes are obsoleted. */
249 BB_HEAD (bb
) = NEXT_INSN (last
);
250 if (NOTE_P (BB_HEAD (bb
)))
251 BB_HEAD (bb
) = NEXT_INSN (BB_HEAD (bb
));
253 note
= emit_note_after (NOTE_INSN_BASIC_BLOCK
, BB_HEAD (bb
));
256 note
= BB_HEAD (bb
) = emit_note (NOTE_INSN_BASIC_BLOCK
);
258 NOTE_BASIC_BLOCK (note
) = bb
;
263 edge next
= e
->succ_next
;
265 /* Clear EDGE_EXECUTABLE. This flag is never used in the backend. */
266 e
->flags
&= ~EDGE_EXECUTABLE
;
268 /* At the moment not all abnormal edges match the RTL representation.
269 It is safe to remove them here as find_sub_basic_blocks will
270 rediscover them. In the future we should get this fixed properly. */
271 if (e
->flags
& EDGE_ABNORMAL
)
277 for (; !bsi_end_p (bsi
); bsi_next (&bsi
))
279 tree stmt
= bsi_stmt (bsi
);
280 basic_block new_bb
= NULL
;
285 /* Expand this statement, then evaluate the resulting RTL and
286 fixup the CFG accordingly. */
287 if (TREE_CODE (stmt
) == COND_EXPR
)
288 new_bb
= expand_gimple_cond_expr (bb
, stmt
);
291 tree call
= get_call_expr_in (stmt
);
292 if (call
&& CALL_EXPR_TAILCALL (call
))
293 new_bb
= expand_gimple_tailcall (bb
, stmt
);
295 expand_expr_stmt (stmt
);
302 do_pending_stack_adjust ();
304 /* Find the the block tail. The last insn is the block is the insn
305 before a barrier and/or table jump insn. */
306 last
= get_last_insn ();
307 if (BARRIER_P (last
))
308 last
= PREV_INSN (last
);
309 if (JUMP_TABLE_DATA_P (last
))
310 last
= PREV_INSN (PREV_INSN (last
));
314 dump_bb (bb
, dump_file
, 0);
315 update_bb_for_insn (bb
);
321 /* Create a basic block for initialization code. */
324 construct_init_block (void)
326 basic_block init_block
, first_block
;
329 for (e
= ENTRY_BLOCK_PTR
->succ
; e
; e
= e
->succ_next
)
330 if (e
->dest
== ENTRY_BLOCK_PTR
->next_bb
)
333 init_block
= create_basic_block (NEXT_INSN (get_insns ()),
336 init_block
->frequency
= ENTRY_BLOCK_PTR
->frequency
;
337 init_block
->count
= ENTRY_BLOCK_PTR
->count
;
340 first_block
= e
->dest
;
341 redirect_edge_succ (e
, init_block
);
342 e
= make_edge (init_block
, first_block
, EDGE_FALLTHRU
);
345 e
= make_edge (init_block
, EXIT_BLOCK_PTR
, EDGE_FALLTHRU
);
346 e
->probability
= REG_BR_PROB_BASE
;
347 e
->count
= ENTRY_BLOCK_PTR
->count
;
349 update_bb_for_insn (init_block
);
354 /* Create a block containing landing pads and similar stuff. */
357 construct_exit_block (void)
359 rtx head
= get_last_insn ();
361 basic_block exit_block
;
364 /* Make sure the locus is set to the end of the function, so that
365 epilogue line numbers and warnings are set properly. */
366 #ifdef USE_MAPPED_LOCATION
367 if (cfun
->function_end_locus
!= UNKNOWN_LOCATION
)
369 if (cfun
->function_end_locus
.file
)
371 input_location
= cfun
->function_end_locus
;
373 /* The following insns belong to the top scope. */
374 record_block_change (DECL_INITIAL (current_function_decl
));
376 /* Generate rtl for function exit. */
377 expand_function_end ();
379 end
= get_last_insn ();
382 while (NEXT_INSN (head
) && NOTE_P (NEXT_INSN (head
)))
383 head
= NEXT_INSN (head
);
384 exit_block
= create_basic_block (NEXT_INSN (head
), end
,
385 EXIT_BLOCK_PTR
->prev_bb
);
386 exit_block
->frequency
= EXIT_BLOCK_PTR
->frequency
;
387 exit_block
->count
= EXIT_BLOCK_PTR
->count
;
388 for (e
= EXIT_BLOCK_PTR
->pred
; e
; e
= next
)
391 if (!(e
->flags
& EDGE_ABNORMAL
))
392 redirect_edge_succ (e
, exit_block
);
394 e
= make_edge (exit_block
, EXIT_BLOCK_PTR
, EDGE_FALLTHRU
);
395 e
->probability
= REG_BR_PROB_BASE
;
396 e
->count
= EXIT_BLOCK_PTR
->count
;
397 for (e2
= EXIT_BLOCK_PTR
->pred
; e2
; e2
= e2
->pred_next
)
400 e
->count
-= e2
->count
;
401 exit_block
->count
-= e2
->count
;
402 exit_block
->frequency
-= EDGE_FREQUENCY (e2
);
406 if (exit_block
->count
< 0)
407 exit_block
->count
= 0;
408 if (exit_block
->frequency
< 0)
409 exit_block
->frequency
= 0;
410 update_bb_for_insn (exit_block
);
413 /* Translate the intermediate representation contained in the CFG
414 from GIMPLE trees to RTL.
416 We do conversion per basic block and preserve/update the tree CFG.
417 This implies we have to do some magic as the CFG can simultaneously
418 consist of basic blocks containing RTL and GIMPLE trees. This can
419 confuse the CFG hooks, so be careful to not manipulate CFG during
423 tree_expand_cfg (void)
425 basic_block bb
, init_block
;
430 fprintf (dump_file
, "\n;; Function %s",
431 (*lang_hooks
.decl_printable_name
) (current_function_decl
, 2));
432 fprintf (dump_file
, " (%s)\n",
433 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl
)));
436 profile_status
= PROFILE_ABSENT
;
438 /* Some backends want to know that we are expanding to RTL. */
439 currently_expanding_to_rtl
= 1;
441 /* Prepare the rtl middle end to start recording block changes. */
442 reset_block_changes ();
444 /* Expand the variables recorded during gimple lowering. */
447 /* Set up parameters and prepare for return, for the function. */
448 expand_function_start (current_function_decl
);
450 /* If this function is `main', emit a call to `__main'
451 to run global initializers, etc. */
452 if (DECL_NAME (current_function_decl
)
453 && MAIN_NAME_P (DECL_NAME (current_function_decl
))
454 && DECL_FILE_SCOPE_P (current_function_decl
))
455 expand_main_function ();
457 /* Register rtl specific functions for cfg. */
458 rtl_register_cfg_hooks ();
460 init_block
= construct_init_block ();
462 FOR_BB_BETWEEN (bb
, init_block
->next_bb
, EXIT_BLOCK_PTR
, next_bb
)
463 bb
= expand_gimple_basic_block (bb
, dump_file
);
465 construct_exit_block ();
467 /* We're done expanding trees to RTL. */
468 currently_expanding_to_rtl
= 0;
470 /* Convert from NOTE_INSN_EH_REGION style notes, and do other
471 sorts of eh initialization. Delay this until after the
472 initial rtl dump so that we can see the original nesting. */
473 convert_from_eh_region_ranges ();
475 rebuild_jump_labels (get_insns ());
476 find_exception_handler_labels ();
478 blocks
= sbitmap_alloc (last_basic_block
);
479 sbitmap_ones (blocks
);
480 find_many_sub_basic_blocks (blocks
);
481 purge_all_dead_edges (0);
482 sbitmap_free (blocks
);
485 #ifdef ENABLE_CHECKING
490 struct tree_opt_pass pass_expand
=
494 tree_expand_cfg
, /* execute */
497 0, /* static_pass_number */
498 TV_EXPAND
, /* tv_id */
499 /* ??? If TER is enabled, we actually receive GENERIC. */
500 PROP_gimple_leh
| PROP_cfg
, /* properties_required */
501 PROP_rtl
, /* properties_provided */
502 PROP_gimple_leh
, /* properties_destroyed */
503 0, /* todo_flags_start */
504 0 /* todo_flags_finish */