]> gcc.gnu.org Git - gcc.git/blame - gcc/cfgexpand.c
reload.c (find_reloads_address): Make return value tri-state.
[gcc.git] / gcc / cfgexpand.c
CommitLineData
242229bb
JH
1/* A pass for lowering trees to RTL.
2 Copyright (C) 2004 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
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"
80c7a9eb
RH
38
39
727a31fa
RH
40/* Expand variables in the unexpanded_var_list. */
41
42static void
43expand_used_vars (void)
44{
45 tree cell;
46
47 cfun->unexpanded_var_list = nreverse (cfun->unexpanded_var_list);
48
49 for (cell = cfun->unexpanded_var_list; cell; cell = TREE_CHAIN (cell))
50 expand_var (TREE_VALUE (cell));
51
52 cfun->unexpanded_var_list = NULL_TREE;
53}
54
55
80c7a9eb
RH
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. */
59
60static basic_block
61expand_gimple_cond_expr (basic_block bb, tree stmt)
62{
63 basic_block new_bb, dest;
64 edge new_edge;
65 edge true_edge;
66 edge false_edge;
67 tree pred = COND_EXPR_COND (stmt);
68 tree then_exp = COND_EXPR_THEN (stmt);
69 tree else_exp = COND_EXPR_ELSE (stmt);
70 rtx last;
71
72 extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
73 if (EXPR_LOCUS (stmt))
74 {
75 emit_line_note (*(EXPR_LOCUS (stmt)));
76 record_block_change (TREE_BLOCK (stmt));
77 }
78
79 /* These flags have no purpose in RTL land. */
80 true_edge->flags &= ~EDGE_TRUE_VALUE;
81 false_edge->flags &= ~EDGE_FALSE_VALUE;
82
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))
86 {
87 jumpif (pred, label_rtx (GOTO_DESTINATION (then_exp)));
88 return NULL;
89 }
90 if (TREE_CODE (else_exp) == GOTO_EXPR && IS_EMPTY_STMT (then_exp))
91 {
92 jumpifnot (pred, label_rtx (GOTO_DESTINATION (else_exp)));
93 return NULL;
94 }
95 if (TREE_CODE (then_exp) != GOTO_EXPR || TREE_CODE (else_exp) != GOTO_EXPR)
96 abort ();
97
98 jumpif (pred, label_rtx (GOTO_DESTINATION (then_exp)));
99 last = get_last_insn ();
100 expand_expr (else_exp, const0_rtx, VOIDmode, 0);
101
102 BB_END (bb) = last;
103 if (BARRIER_P (BB_END (bb)))
104 BB_END (bb) = PREV_INSN (BB_END (bb));
105 update_bb_for_insn (bb);
106
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);
119
120 if (dump_file)
121 {
122 dump_bb (bb, dump_file, 0);
123 dump_bb (new_bb, dump_file, 0);
124 }
125
126 return new_bb;
127}
128
129/* A subroutine of expand_gimple_basic_block. Expand one CALL_EXPR
224e770b
RH
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). */
80c7a9eb
RH
133
134static basic_block
135expand_gimple_tailcall (basic_block bb, tree stmt)
136{
137 rtx last = get_last_insn ();
224e770b
RH
138 edge e;
139 int probability;
140 gcov_type count;
80c7a9eb
RH
141
142 expand_expr_stmt (stmt);
143
144 for (last = NEXT_INSN (last); last; last = NEXT_INSN (last))
224e770b
RH
145 if (CALL_P (last) && SIBLING_CALL_P (last))
146 goto found;
80c7a9eb 147
224e770b 148 return NULL;
80c7a9eb 149
224e770b
RH
150 found:
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 ();
154
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
160 the exit block. */
161
162 e = bb->succ;
163 probability = 0;
164 count = 0;
165 while (e)
166 {
167 edge next = e->succ_next;
168
169 if (!(e->flags & (EDGE_ABNORMAL | EDGE_EH)))
170 {
171 if (e->dest != EXIT_BLOCK_PTR)
80c7a9eb 172 {
224e770b
RH
173 e->dest->count -= e->count;
174 e->dest->frequency -= EDGE_FREQUENCY (e);
175 if (e->dest->count < 0)
176 e->dest->count = 0;
177 if (e->dest->frequency < 0)
178 e->dest->frequency = 0;
80c7a9eb 179 }
224e770b
RH
180 count += e->count;
181 probability += e->probability;
182 remove_edge (e);
80c7a9eb 183 }
224e770b
RH
184
185 e = next;
80c7a9eb
RH
186 }
187
224e770b
RH
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))
193 abort ();
194 while (NEXT_INSN (last))
195 {
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)))
199 break;
200 delete_insn (NEXT_INSN (last));
201 }
202
203 e = make_edge (bb, EXIT_BLOCK_PTR, EDGE_ABNORMAL | EDGE_SIBCALL);
204 e->probability += probability;
205 e->count += count;
206 BB_END (bb) = last;
207 update_bb_for_insn (bb);
208
209 if (NEXT_INSN (last))
210 {
211 bb = create_basic_block (NEXT_INSN (last), get_last_insn (), bb);
212
213 last = BB_END (bb);
214 if (BARRIER_P (last))
215 BB_END (bb) = PREV_INSN (last);
216 }
217
218 return bb;
80c7a9eb
RH
219}
220
242229bb
JH
221/* Expand basic block BB from GIMPLE trees to RTL. */
222
223static basic_block
80c7a9eb 224expand_gimple_basic_block (basic_block bb, FILE * dump_file)
242229bb
JH
225{
226 block_stmt_iterator bsi = bsi_start (bb);
227 tree stmt = NULL;
228 rtx note, last;
229 edge e;
230
231 if (dump_file)
232 {
233 tree_register_cfg_hooks ();
234 dump_bb (bb, dump_file, 0);
235 rtl_register_cfg_hooks ();
236 }
237
238 if (!bsi_end_p (bsi))
239 stmt = bsi_stmt (bsi);
240
241 if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
242 {
243 last = get_last_insn ();
244
4dfa0342 245 expand_expr_stmt (stmt);
242229bb 246
caf93cb0 247 /* Java emits line number notes in the top of labels.
242229bb
JH
248 ??? Make this go away once line number notes are obsoleted. */
249 BB_HEAD (bb) = NEXT_INSN (last);
4b4bf941 250 if (NOTE_P (BB_HEAD (bb)))
242229bb
JH
251 BB_HEAD (bb) = NEXT_INSN (BB_HEAD (bb));
252 bsi_next (&bsi);
253 note = emit_note_after (NOTE_INSN_BASIC_BLOCK, BB_HEAD (bb));
254 }
255 else
256 note = BB_HEAD (bb) = emit_note (NOTE_INSN_BASIC_BLOCK);
257
258 NOTE_BASIC_BLOCK (note) = bb;
259
260 e = bb->succ;
261 while (e)
262 {
263 edge next = e->succ_next;
264
265 /* Clear EDGE_EXECUTABLE. This flag is never used in the backend. */
266 e->flags &= ~EDGE_EXECUTABLE;
267
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)
272 remove_edge (e);
273
274 e = next;
275 }
276
277 for (; !bsi_end_p (bsi); bsi_next (&bsi))
278 {
279 tree stmt = bsi_stmt (bsi);
80c7a9eb 280 basic_block new_bb = NULL;
242229bb
JH
281
282 if (!stmt)
283 continue;
284
285 /* Expand this statement, then evaluate the resulting RTL and
286 fixup the CFG accordingly. */
80c7a9eb
RH
287 if (TREE_CODE (stmt) == COND_EXPR)
288 new_bb = expand_gimple_cond_expr (bb, stmt);
289 else
242229bb 290 {
80c7a9eb
RH
291 tree call = get_call_expr_in (stmt);
292 if (call && CALL_EXPR_TAILCALL (call))
293 new_bb = expand_gimple_tailcall (bb, stmt);
294 else
295 expand_expr_stmt (stmt);
242229bb 296 }
80c7a9eb
RH
297
298 if (new_bb)
299 return new_bb;
242229bb
JH
300 }
301
302 do_pending_stack_adjust ();
303
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 ();
4b4bf941 307 if (BARRIER_P (last))
242229bb
JH
308 last = PREV_INSN (last);
309 if (JUMP_TABLE_DATA_P (last))
310 last = PREV_INSN (PREV_INSN (last));
311 BB_END (bb) = last;
caf93cb0 312
242229bb
JH
313 if (dump_file)
314 dump_bb (bb, dump_file, 0);
315 update_bb_for_insn (bb);
80c7a9eb 316
242229bb
JH
317 return bb;
318}
319
320
321/* Create a basic block for initialization code. */
322
323static basic_block
324construct_init_block (void)
325{
326 basic_block init_block, first_block;
327 edge e;
328
242229bb
JH
329 for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
330 if (e->dest == ENTRY_BLOCK_PTR->next_bb)
331 break;
332
333 init_block = create_basic_block (NEXT_INSN (get_insns ()),
334 get_last_insn (),
335 ENTRY_BLOCK_PTR);
336 init_block->frequency = ENTRY_BLOCK_PTR->frequency;
337 init_block->count = ENTRY_BLOCK_PTR->count;
338 if (e)
339 {
340 first_block = e->dest;
341 redirect_edge_succ (e, init_block);
342 e = make_edge (init_block, first_block, EDGE_FALLTHRU);
343 }
344 else
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;
348
349 update_bb_for_insn (init_block);
350 return init_block;
351}
352
353
354/* Create a block containing landing pads and similar stuff. */
355
356static void
357construct_exit_block (void)
358{
359 rtx head = get_last_insn ();
360 rtx end;
361 basic_block exit_block;
362 edge e, e2, next;
363
caf93cb0 364 /* Make sure the locus is set to the end of the function, so that
242229bb 365 epilogue line numbers and warnings are set properly. */
6773e15f
PB
366#ifdef USE_MAPPED_LOCATION
367 if (cfun->function_end_locus != UNKNOWN_LOCATION)
368#else
242229bb 369 if (cfun->function_end_locus.file)
6773e15f 370#endif
242229bb
JH
371 input_location = cfun->function_end_locus;
372
373 /* The following insns belong to the top scope. */
374 record_block_change (DECL_INITIAL (current_function_decl));
375
242229bb
JH
376 /* Generate rtl for function exit. */
377 expand_function_end ();
378
379 end = get_last_insn ();
380 if (head == end)
381 return;
4b4bf941 382 while (NEXT_INSN (head) && NOTE_P (NEXT_INSN (head)))
242229bb 383 head = NEXT_INSN (head);
80c7a9eb
RH
384 exit_block = create_basic_block (NEXT_INSN (head), end,
385 EXIT_BLOCK_PTR->prev_bb);
242229bb
JH
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)
389 {
390 next = e->pred_next;
391 if (!(e->flags & EDGE_ABNORMAL))
392 redirect_edge_succ (e, exit_block);
393 }
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)
398 if (e2 != e)
399 {
400 e->count -= e2->count;
401 exit_block->count -= e2->count;
402 exit_block->frequency -= EDGE_FREQUENCY (e2);
403 }
404 if (e->count < 0)
405 e->count = 0;
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);
411}
412
242229bb
JH
413/* Translate the intermediate representation contained in the CFG
414 from GIMPLE trees to RTL.
415
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
61ada8ae 419 confuse the CFG hooks, so be careful to not manipulate CFG during
242229bb
JH
420 the expansion. */
421
422static void
423tree_expand_cfg (void)
424{
425 basic_block bb, init_block;
426 sbitmap blocks;
427
428 if (dump_file)
429 {
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)));
434 }
435
878f99d2
JH
436 profile_status = PROFILE_ABSENT;
437
4586b4ca
SB
438 /* Some backends want to know that we are expanding to RTL. */
439 currently_expanding_to_rtl = 1;
440
6429e3be
RH
441 /* Prepare the rtl middle end to start recording block changes. */
442 reset_block_changes ();
443
727a31fa 444 /* Expand the variables recorded during gimple lowering. */
242229bb
JH
445 expand_used_vars ();
446
447 /* Set up parameters and prepare for return, for the function. */
b79c5284 448 expand_function_start (current_function_decl);
242229bb
JH
449
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 ();
456
3fbd86b1 457 /* Register rtl specific functions for cfg. */
242229bb
JH
458 rtl_register_cfg_hooks ();
459
460 init_block = construct_init_block ();
461
462 FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR, next_bb)
80c7a9eb 463 bb = expand_gimple_basic_block (bb, dump_file);
242229bb
JH
464
465 construct_exit_block ();
466
4586b4ca
SB
467 /* We're done expanding trees to RTL. */
468 currently_expanding_to_rtl = 0;
469
242229bb
JH
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 ();
474
475 rebuild_jump_labels (get_insns ());
476 find_exception_handler_labels ();
477
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);
483
484 compact_blocks ();
485#ifdef ENABLE_CHECKING
486 verify_flow_info();
487#endif
488}
489
490struct tree_opt_pass pass_expand =
491{
492 "expand", /* name */
493 NULL, /* gate */
494 tree_expand_cfg, /* execute */
495 NULL, /* sub */
496 NULL, /* next */
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 */
505};
This page took 0.150564 seconds and 5 git commands to generate.