fd361c5fc85d65ce9fae611a29e8b247678d77a7
[gcc.git] / gcc / cfghooks.c
1 /* Hooks for cfg representation specific functions.
2 Copyright (C) 2003 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <s.pop@laposte.net>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "basic-block.h"
29 #include "timevar.h"
30 #include "toplev.h"
31
32 /* A pointer to one of the hooks containers. */
33 static struct cfg_hooks *cfg_hooks;
34
35 /* Initialization of functions specific to the rtl IR. */
36 void
37 rtl_register_cfg_hooks (void)
38 {
39 cfg_hooks = &rtl_cfg_hooks;
40 }
41
42 /* Initialization of functions specific to the rtl IR. */
43 void
44 cfg_layout_rtl_register_cfg_hooks (void)
45 {
46 cfg_hooks = &cfg_layout_rtl_cfg_hooks;
47 }
48
49 /* Verify the CFG consistency.
50
51 Currently it does following: checks edge and basic block list correctness
52 and calls into IL dependent checking then. */
53
54 void
55 verify_flow_info (void)
56 {
57 size_t *edge_checksum;
58 int num_bb_notes, err = 0;
59 basic_block bb, last_bb_seen;
60 basic_block *last_visited;
61
62 timevar_push (TV_CFG_VERIFY);
63 last_visited = xcalloc (last_basic_block + 2, sizeof (basic_block));
64 edge_checksum = xcalloc (last_basic_block + 2, sizeof (size_t));
65
66 /* Check bb chain & numbers. */
67 last_bb_seen = ENTRY_BLOCK_PTR;
68 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb)
69 {
70 if (bb != EXIT_BLOCK_PTR
71 && bb != BASIC_BLOCK (bb->index))
72 {
73 error ("bb %d on wrong place", bb->index);
74 err = 1;
75 }
76
77 if (bb->prev_bb != last_bb_seen)
78 {
79 error ("prev_bb of %d should be %d, not %d",
80 bb->index, last_bb_seen->index, bb->prev_bb->index);
81 err = 1;
82 }
83
84 last_bb_seen = bb;
85 }
86
87 /* Now check the basic blocks (boundaries etc.) */
88 FOR_EACH_BB_REVERSE (bb)
89 {
90 int n_fallthru = 0;
91 edge e;
92
93 if (bb->count < 0)
94 {
95 error ("verify_flow_info: Wrong count of block %i %i",
96 bb->index, (int)bb->count);
97 err = 1;
98 }
99 if (bb->frequency < 0)
100 {
101 error ("verify_flow_info: Wrong frequency of block %i %i",
102 bb->index, bb->frequency);
103 err = 1;
104 }
105 for (e = bb->succ; e; e = e->succ_next)
106 {
107 if (last_visited [e->dest->index + 2] == bb)
108 {
109 error ("verify_flow_info: Duplicate edge %i->%i",
110 e->src->index, e->dest->index);
111 err = 1;
112 }
113 if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
114 {
115 error ("verify_flow_info: Wrong probability of edge %i->%i %i",
116 e->src->index, e->dest->index, e->probability);
117 err = 1;
118 }
119 if (e->count < 0)
120 {
121 error ("verify_flow_info: Wrong count of edge %i->%i %i",
122 e->src->index, e->dest->index, (int)e->count);
123 err = 1;
124 }
125
126 last_visited [e->dest->index + 2] = bb;
127
128 if (e->flags & EDGE_FALLTHRU)
129 n_fallthru++;
130
131 if (e->src != bb)
132 {
133 error ("verify_flow_info: Basic block %d succ edge is corrupted",
134 bb->index);
135 fprintf (stderr, "Predecessor: ");
136 dump_edge_info (stderr, e, 0);
137 fprintf (stderr, "\nSuccessor: ");
138 dump_edge_info (stderr, e, 1);
139 fprintf (stderr, "\n");
140 err = 1;
141 }
142
143 edge_checksum[e->dest->index + 2] += (size_t) e;
144 }
145 if (n_fallthru > 1)
146 {
147 error ("Wrong amount of branch edges after unconditional jump %i", bb->index);
148 err = 1;
149 }
150
151 for (e = bb->pred; e; e = e->pred_next)
152 {
153 if (e->dest != bb)
154 {
155 error ("basic block %d pred edge is corrupted", bb->index);
156 fputs ("Predecessor: ", stderr);
157 dump_edge_info (stderr, e, 0);
158 fputs ("\nSuccessor: ", stderr);
159 dump_edge_info (stderr, e, 1);
160 fputc ('\n', stderr);
161 err = 1;
162 }
163 edge_checksum[e->dest->index + 2] -= (size_t) e;
164 }
165 }
166
167 /* Complete edge checksumming for ENTRY and EXIT. */
168 {
169 edge e;
170
171 for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
172 edge_checksum[e->dest->index + 2] += (size_t) e;
173
174 for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
175 edge_checksum[e->dest->index + 2] -= (size_t) e;
176 }
177
178 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
179 if (edge_checksum[bb->index + 2])
180 {
181 error ("basic block %i edge lists are corrupted", bb->index);
182 err = 1;
183 }
184
185 num_bb_notes = 0;
186 last_bb_seen = ENTRY_BLOCK_PTR;
187
188 /* Clean up. */
189 free (last_visited);
190 free (edge_checksum);
191
192 if (cfg_hooks->verify_flow_info)
193 err |= cfg_hooks->verify_flow_info ();
194 if (err)
195 internal_error ("verify_flow_info failed");
196 timevar_pop (TV_CFG_VERIFY);
197 }
198
199 /* Print out one basic block. This function takes care of the purely
200 graph related information. The cfg hook for the active representation
201 should dump representation-specific information. */
202
203 void
204 dump_bb (basic_block bb, FILE *outf, int indent)
205 {
206 edge e;
207 char *s_indent;
208
209 s_indent = (char *) alloca ((size_t) indent + 1);
210 memset ((void *) s_indent, ' ', (size_t) indent);
211 s_indent[indent] = '\0';
212
213 fprintf (outf, ";;%s basic block %d, loop depth %d, count ",
214 s_indent, bb->index, bb->loop_depth);
215 fprintf (outf, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count);
216 putc ('\n', outf);
217
218 fprintf (outf, ";;%s prev block ", s_indent);
219 if (bb->prev_bb)
220 fprintf (outf, "%d, ", bb->prev_bb->index);
221 else
222 fprintf (outf, "(nil), ");
223 fprintf (outf, "next block ");
224 if (bb->next_bb)
225 fprintf (outf, "%d", bb->next_bb->index);
226 else
227 fprintf (outf, "(nil)");
228 putc ('\n', outf);
229
230 fprintf (outf, ";;%s pred: ", s_indent);
231 for (e = bb->pred; e; e = e->pred_next)
232 dump_edge_info (outf, e, 0);
233 putc ('\n', outf);
234
235 fprintf (outf, ";;%s succ: ", s_indent);
236 for (e = bb->succ; e; e = e->succ_next)
237 dump_edge_info (outf, e, 1);
238 putc ('\n', outf);
239
240 if (cfg_hooks->dump_bb)
241 cfg_hooks->dump_bb (bb, outf, indent);
242 }
243
244 /* Redirect edge E to the given basic block DEST and update underlying program
245 representation. Returns edge representing redirected branch (that may not
246 be equivalent to E in the case of duplicate edges being removed) or NULL
247 if edge is not easily redirectable for whatever reason. */
248
249 bool
250 redirect_edge_and_branch (edge e, basic_block dest)
251 {
252 bool ret;
253
254 if (!cfg_hooks->redirect_edge_and_branch)
255 internal_error ("%s does not support redirect_edge_and_branch.",
256 cfg_hooks->name);
257
258 ret = cfg_hooks->redirect_edge_and_branch (e, dest);
259
260 return ret;
261 }
262
263 /* Redirect the edge E to basic block DEST even if it requires creating
264 of a new basic block; then it returns the newly created basic block.
265 Aborts when redirection is impossible. */
266
267 basic_block
268 redirect_edge_and_branch_force (edge e, basic_block dest)
269 {
270 basic_block ret;
271
272 if (!cfg_hooks->redirect_edge_and_branch_force)
273 internal_error ("%s does not support redirect_edge_and_branch_force.",
274 cfg_hooks->name);
275
276 ret = cfg_hooks->redirect_edge_and_branch_force (e, dest);
277
278 return ret;
279 }
280
281 /* Splits basic block BB after the specified instruction I (but at least after
282 the labels). If I is NULL, splits just after labels. The newly created edge
283 is returned. The new basic block is created just after the old one. */
284
285 edge
286 split_block (basic_block bb, void *i)
287 {
288 basic_block new_bb;
289
290 if (!cfg_hooks->split_block)
291 internal_error ("%s does not support split_block.", cfg_hooks->name);
292
293 new_bb = cfg_hooks->split_block (bb, i);
294 if (!new_bb)
295 return NULL;
296
297 new_bb->count = bb->count;
298 new_bb->frequency = bb->frequency;
299 new_bb->loop_depth = bb->loop_depth;
300
301 if (dom_computed[CDI_DOMINATORS] >= DOM_CONS_OK)
302 {
303 redirect_immediate_dominators (CDI_DOMINATORS, bb, new_bb);
304 set_immediate_dominator (CDI_DOMINATORS, new_bb, bb);
305 }
306
307 return make_edge (bb, new_bb, EDGE_FALLTHRU);
308 }
309
310 /* Splits block BB just after labels. The newly created edge is returned. */
311
312 edge
313 split_block_after_labels (basic_block bb)
314 {
315 return split_block (bb, NULL);
316 }
317
318 /* Moves block BB immediatelly after block AFTER. Returns false if the
319 movement was impossible. */
320
321 bool
322 move_block_after (basic_block bb, basic_block after)
323 {
324 bool ret;
325
326 if (!cfg_hooks->move_block_after)
327 internal_error ("%s does not support move_block_after.", cfg_hooks->name);
328
329 ret = cfg_hooks->move_block_after (bb, after);
330
331 return ret;
332 }
333
334 /* Deletes the basic block BB. */
335
336 void
337 delete_basic_block (basic_block bb)
338 {
339 if (!cfg_hooks->delete_basic_block)
340 internal_error ("%s does not support delete_basic_block.", cfg_hooks->name);
341
342 cfg_hooks->delete_basic_block (bb);
343
344 /* Remove the edges into and out of this block. Note that there may
345 indeed be edges in, if we are removing an unreachable loop. */
346 while (bb->pred != NULL)
347 remove_edge (bb->pred);
348 while (bb->succ != NULL)
349 remove_edge (bb->succ);
350
351 bb->pred = NULL;
352 bb->succ = NULL;
353
354 if (dom_computed[CDI_DOMINATORS])
355 delete_from_dominance_info (CDI_DOMINATORS, bb);
356 if (dom_computed[CDI_POST_DOMINATORS])
357 delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
358
359 /* Remove the basic block from the array. */
360 expunge_block (bb);
361 }
362
363 /* Splits edge E and returns the newly created basic block. */
364
365 basic_block
366 split_edge (edge e)
367 {
368 basic_block ret;
369 gcov_type count = e->count;
370 int freq = EDGE_FREQUENCY (e);
371
372 if (!cfg_hooks->split_edge)
373 internal_error ("%s does not support split_edge.", cfg_hooks->name);
374
375 ret = cfg_hooks->split_edge (e);
376 ret->count = count;
377 ret->frequency = freq;
378 ret->succ->probability = REG_BR_PROB_BASE;
379 ret->succ->count = count;
380
381 if (dom_computed[CDI_DOMINATORS])
382 set_immediate_dominator (CDI_DOMINATORS, ret, ret->pred->src);
383
384 if (dom_computed[CDI_DOMINATORS] >= DOM_NO_FAST_QUERY)
385 set_immediate_dominator (CDI_DOMINATORS, ret->succ->dest,
386 recount_dominator (CDI_DOMINATORS,
387 ret->succ->dest));
388
389 return ret;
390 }
391
392 /* Creates a new basic block just after the basic block AFTER.
393 HEAD and END are the first and the last statement belonging
394 to the block. If both are NULL, an empty block is created. */
395
396 basic_block
397 create_basic_block (void *head, void *end, basic_block after)
398 {
399 basic_block ret;
400
401 if (!cfg_hooks->create_basic_block)
402 internal_error ("%s does not support create_basic_block.", cfg_hooks->name);
403
404 ret = cfg_hooks->create_basic_block (head, end, after);
405
406 if (dom_computed[CDI_DOMINATORS])
407 add_to_dominance_info (CDI_DOMINATORS, ret);
408 if (dom_computed[CDI_POST_DOMINATORS])
409 add_to_dominance_info (CDI_POST_DOMINATORS, ret);
410
411 return ret;
412 }
413
414 /* Creates an empty basic block just after basic block AFTER. */
415
416 basic_block
417 create_empty_bb (basic_block after)
418 {
419 return create_basic_block (NULL, NULL, after);
420 }
421
422 /* Checks whether we may merge blocks BB1 and BB2. */
423
424 bool
425 can_merge_blocks_p (basic_block bb1, basic_block bb2)
426 {
427 bool ret;
428
429 if (!cfg_hooks->can_merge_blocks_p)
430 internal_error ("%s does not support can_merge_blocks_p.", cfg_hooks->name);
431
432 ret = cfg_hooks->can_merge_blocks_p (bb1, bb2);
433
434 return ret;
435 }
436
437 /* Merges basic block B into basic block A. */
438
439 void
440 merge_blocks (basic_block a, basic_block b)
441 {
442 edge e;
443
444 if (!cfg_hooks->merge_blocks)
445 internal_error ("%s does not support merge_blocks.", cfg_hooks->name);
446
447 cfg_hooks->merge_blocks (a, b);
448
449 /* Normally there should only be one successor of A and that is B, but
450 partway though the merge of blocks for conditional_execution we'll
451 be merging a TEST block with THEN and ELSE successors. Free the
452 whole lot of them and hope the caller knows what they're doing. */
453 while (a->succ)
454 remove_edge (a->succ);
455
456 /* Adjust the edges out of B for the new owner. */
457 for (e = b->succ; e; e = e->succ_next)
458 e->src = a;
459 a->succ = b->succ;
460 a->flags |= b->flags;
461
462 /* B hasn't quite yet ceased to exist. Attempt to prevent mishap. */
463 b->pred = b->succ = NULL;
464 a->global_live_at_end = b->global_live_at_end;
465
466 if (dom_computed[CDI_DOMINATORS])
467 redirect_immediate_dominators (CDI_DOMINATORS, b, a);
468
469 if (dom_computed[CDI_DOMINATORS])
470 delete_from_dominance_info (CDI_DOMINATORS, b);
471 if (dom_computed[CDI_POST_DOMINATORS])
472 delete_from_dominance_info (CDI_POST_DOMINATORS, b);
473
474 expunge_block (b);
475 }
476
477 /* Split BB into entry part and the rest (the rest is the newly created block).
478 Redirect those edges for that REDIRECT_EDGE_P returns true to the entry
479 part. Returns the edge connecting the entry part to the rest. */
480
481 edge
482 make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge),
483 void (*new_bb_cbk) (basic_block))
484 {
485 edge e, next_e, fallthru;
486 basic_block dummy, jump;
487
488 if (!cfg_hooks->make_forwarder_block)
489 internal_error ("%s does not support make_forwarder_block.",
490 cfg_hooks->name);
491
492 fallthru = split_block_after_labels (bb);
493 dummy = fallthru->src;
494 bb = fallthru->dest;
495
496 /* Redirect back edges we want to keep. */
497 for (e = dummy->pred; e; e = next_e)
498 {
499 next_e = e->pred_next;
500 if (redirect_edge_p (e))
501 continue;
502
503 dummy->frequency -= EDGE_FREQUENCY (e);
504 dummy->count -= e->count;
505 if (dummy->frequency < 0)
506 dummy->frequency = 0;
507 if (dummy->count < 0)
508 dummy->count = 0;
509
510 jump = redirect_edge_and_branch_force (e, bb);
511 if (jump)
512 new_bb_cbk (jump);
513 }
514
515 if (dom_computed[CDI_DOMINATORS] >= DOM_CONS_OK)
516 {
517 basic_block doms_to_fix[2];
518
519 doms_to_fix[0] = dummy;
520 doms_to_fix[1] = bb;
521 iterate_fix_dominators (CDI_DOMINATORS, doms_to_fix, 2);
522 }
523
524 cfg_hooks->make_forwarder_block (fallthru);
525
526 return fallthru;
527 }
528
529 void
530 tidy_fallthru_edge (edge e)
531 {
532 if (cfg_hooks->tidy_fallthru_edge)
533 cfg_hooks->tidy_fallthru_edge (e);
534 }
535
536 /* Fix up edges that now fall through, or rather should now fall through
537 but previously required a jump around now deleted blocks. Simplify
538 the search by only examining blocks numerically adjacent, since this
539 is how find_basic_blocks created them. */
540
541 void
542 tidy_fallthru_edges (void)
543 {
544 basic_block b, c;
545
546 if (!cfg_hooks->tidy_fallthru_edge)
547 return;
548
549 if (ENTRY_BLOCK_PTR->next_bb == EXIT_BLOCK_PTR)
550 return;
551
552 FOR_BB_BETWEEN (b, ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR->prev_bb, next_bb)
553 {
554 edge s;
555
556 c = b->next_bb;
557
558 /* We care about simple conditional or unconditional jumps with
559 a single successor.
560
561 If we had a conditional branch to the next instruction when
562 find_basic_blocks was called, then there will only be one
563 out edge for the block which ended with the conditional
564 branch (since we do not create duplicate edges).
565
566 Furthermore, the edge will be marked as a fallthru because we
567 merge the flags for the duplicate edges. So we do not want to
568 check that the edge is not a FALLTHRU edge. */
569
570 if ((s = b->succ) != NULL
571 && ! (s->flags & EDGE_COMPLEX)
572 && s->succ_next == NULL
573 && s->dest == c)
574 tidy_fallthru_edge (s);
575 }
576 }