00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024 #include "system.h"
00025 #include "coretypes.h"
00026 #include "tm.h"
00027 #include "rtl.h"
00028 #include "obstack.h"
00029 #include "hard-reg-set.h"
00030 #include "basic-block.h"
00031 #include "insn-config.h"
00032 #include "recog.h"
00033 #include "toplev.h"
00034 #include "tm_p.h"
00035 #include "timevar.h"
00036
00037
00038 struct depth_first_search_dsS {
00039
00040 basic_block *stack;
00041
00042
00043
00044 unsigned int sp;
00045
00046
00047 sbitmap visited_blocks;
00048 };
00049 typedef struct depth_first_search_dsS *depth_first_search_ds;
00050
00051 static void flow_dfs_compute_reverse_init (depth_first_search_ds);
00052 static void flow_dfs_compute_reverse_add_bb (depth_first_search_ds,
00053 basic_block);
00054 static basic_block flow_dfs_compute_reverse_execute (depth_first_search_ds,
00055 basic_block);
00056 static void flow_dfs_compute_reverse_finish (depth_first_search_ds);
00057 static bool flow_active_insn_p (rtx);
00058
00059
00060
00061
00062 static bool
00063 flow_active_insn_p (rtx insn)
00064 {
00065 if (active_insn_p (insn))
00066 return true;
00067
00068
00069
00070
00071
00072
00073 if (GET_CODE (PATTERN (insn)) == CLOBBER
00074 && REG_P (XEXP (PATTERN (insn), 0))
00075 && REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))
00076 return true;
00077
00078 return false;
00079 }
00080
00081
00082
00083
00084 bool
00085 forwarder_block_p (basic_block bb)
00086 {
00087 rtx insn;
00088
00089 if (bb == EXIT_BLOCK_PTR || bb == ENTRY_BLOCK_PTR
00090 || !single_succ_p (bb))
00091 return false;
00092
00093 for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
00094 if (INSN_P (insn) && flow_active_insn_p (insn))
00095 return false;
00096
00097 return (!INSN_P (insn)
00098 || (JUMP_P (insn) && simplejump_p (insn))
00099 || !flow_active_insn_p (insn));
00100 }
00101
00102
00103
00104 bool
00105 can_fallthru (basic_block src, basic_block target)
00106 {
00107 rtx insn = BB_END (src);
00108 rtx insn2;
00109 edge e;
00110 edge_iterator ei;
00111
00112 if (target == EXIT_BLOCK_PTR)
00113 return true;
00114 if (src->next_bb != target)
00115 return 0;
00116 FOR_EACH_EDGE (e, ei, src->succs)
00117 if (e->dest == EXIT_BLOCK_PTR
00118 && e->flags & EDGE_FALLTHRU)
00119 return 0;
00120
00121 insn2 = BB_HEAD (target);
00122 if (insn2 && !active_insn_p (insn2))
00123 insn2 = next_active_insn (insn2);
00124
00125
00126 return next_active_insn (insn) == insn2;
00127 }
00128
00129
00130
00131
00132 bool
00133 could_fall_through (basic_block src, basic_block target)
00134 {
00135 edge e;
00136 edge_iterator ei;
00137
00138 if (target == EXIT_BLOCK_PTR)
00139 return true;
00140 FOR_EACH_EDGE (e, ei, src->succs)
00141 if (e->dest == EXIT_BLOCK_PTR
00142 && e->flags & EDGE_FALLTHRU)
00143 return 0;
00144 return true;
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 bool
00158 mark_dfs_back_edges (void)
00159 {
00160 edge_iterator *stack;
00161 int *pre;
00162 int *post;
00163 int sp;
00164 int prenum = 1;
00165 int postnum = 1;
00166 sbitmap visited;
00167 bool found = false;
00168
00169
00170 pre = XCNEWVEC (int, last_basic_block);
00171 post = XCNEWVEC (int, last_basic_block);
00172
00173
00174 stack = XNEWVEC (edge_iterator, n_basic_blocks + 1);
00175 sp = 0;
00176
00177
00178 visited = sbitmap_alloc (last_basic_block);
00179
00180
00181 sbitmap_zero (visited);
00182
00183
00184 stack[sp++] = ei_start (ENTRY_BLOCK_PTR->succs);
00185
00186 while (sp)
00187 {
00188 edge_iterator ei;
00189 basic_block src;
00190 basic_block dest;
00191
00192
00193 ei = stack[sp - 1];
00194 src = ei_edge (ei)->src;
00195 dest = ei_edge (ei)->dest;
00196 ei_edge (ei)->flags &= ~EDGE_DFS_BACK;
00197
00198
00199 if (dest != EXIT_BLOCK_PTR && ! TEST_BIT (visited, dest->index))
00200 {
00201
00202 SET_BIT (visited, dest->index);
00203
00204 pre[dest->index] = prenum++;
00205 if (EDGE_COUNT (dest->succs) > 0)
00206 {
00207
00208
00209 stack[sp++] = ei_start (dest->succs);
00210 }
00211 else
00212 post[dest->index] = postnum++;
00213 }
00214 else
00215 {
00216 if (dest != EXIT_BLOCK_PTR && src != ENTRY_BLOCK_PTR
00217 && pre[src->index] >= pre[dest->index]
00218 && post[dest->index] == 0)
00219 ei_edge (ei)->flags |= EDGE_DFS_BACK, found = true;
00220
00221 if (ei_one_before_end_p (ei) && src != ENTRY_BLOCK_PTR)
00222 post[src->index] = postnum++;
00223
00224 if (!ei_one_before_end_p (ei))
00225 ei_next (&stack[sp - 1]);
00226 else
00227 sp--;
00228 }
00229 }
00230
00231 free (pre);
00232 free (post);
00233 free (stack);
00234 sbitmap_free (visited);
00235
00236 return found;
00237 }
00238
00239
00240
00241 void
00242 set_edge_can_fallthru_flag (void)
00243 {
00244 basic_block bb;
00245
00246 FOR_EACH_BB (bb)
00247 {
00248 edge e;
00249 edge_iterator ei;
00250
00251 FOR_EACH_EDGE (e, ei, bb->succs)
00252 {
00253 e->flags &= ~EDGE_CAN_FALLTHRU;
00254
00255
00256 if (e->flags & EDGE_FALLTHRU)
00257 e->flags |= EDGE_CAN_FALLTHRU;
00258 }
00259
00260
00261
00262 if (EDGE_COUNT (bb->succs) != 2)
00263 continue;
00264 if (!any_condjump_p (BB_END (bb)))
00265 continue;
00266 if (!invert_jump (BB_END (bb), JUMP_LABEL (BB_END (bb)), 0))
00267 continue;
00268 invert_jump (BB_END (bb), JUMP_LABEL (BB_END (bb)), 0);
00269 EDGE_SUCC (bb, 0)->flags |= EDGE_CAN_FALLTHRU;
00270 EDGE_SUCC (bb, 1)->flags |= EDGE_CAN_FALLTHRU;
00271 }
00272 }
00273
00274
00275
00276
00277
00278 void
00279 find_unreachable_blocks (void)
00280 {
00281 edge e;
00282 edge_iterator ei;
00283 basic_block *tos, *worklist, bb;
00284
00285 tos = worklist = XNEWVEC (basic_block, n_basic_blocks);
00286
00287
00288
00289 FOR_EACH_BB (bb)
00290 bb->flags &= ~BB_REACHABLE;
00291
00292
00293
00294
00295
00296 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
00297 {
00298 *tos++ = e->dest;
00299
00300
00301 e->dest->flags |= BB_REACHABLE;
00302 }
00303
00304
00305
00306 while (tos != worklist)
00307 {
00308 basic_block b = *--tos;
00309
00310 FOR_EACH_EDGE (e, ei, b->succs)
00311 {
00312 basic_block dest = e->dest;
00313
00314 if (!(dest->flags & BB_REACHABLE))
00315 {
00316 *tos++ = dest;
00317 dest->flags |= BB_REACHABLE;
00318 }
00319 }
00320 }
00321
00322 free (worklist);
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 struct edge_list *
00339 create_edge_list (void)
00340 {
00341 struct edge_list *elist;
00342 edge e;
00343 int num_edges;
00344 int block_count;
00345 basic_block bb;
00346 edge_iterator ei;
00347
00348 block_count = n_basic_blocks;
00349
00350 num_edges = 0;
00351
00352
00353
00354 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
00355 {
00356 num_edges += EDGE_COUNT (bb->succs);
00357 }
00358
00359 elist = XNEW (struct edge_list);
00360 elist->num_blocks = block_count;
00361 elist->num_edges = num_edges;
00362 elist->index_to_edge = XNEWVEC (edge, num_edges);
00363
00364 num_edges = 0;
00365
00366
00367 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
00368 FOR_EACH_EDGE (e, ei, bb->succs)
00369 elist->index_to_edge[num_edges++] = e;
00370
00371 return elist;
00372 }
00373
00374
00375
00376 void
00377 free_edge_list (struct edge_list *elist)
00378 {
00379 if (elist)
00380 {
00381 free (elist->index_to_edge);
00382 free (elist);
00383 }
00384 }
00385
00386
00387
00388 void
00389 print_edge_list (FILE *f, struct edge_list *elist)
00390 {
00391 int x;
00392
00393 fprintf (f, "Compressed edge list, %d BBs + entry & exit, and %d edges\n",
00394 elist->num_blocks, elist->num_edges);
00395
00396 for (x = 0; x < elist->num_edges; x++)
00397 {
00398 fprintf (f, " %-4d - edge(", x);
00399 if (INDEX_EDGE_PRED_BB (elist, x) == ENTRY_BLOCK_PTR)
00400 fprintf (f, "entry,");
00401 else
00402 fprintf (f, "%d,", INDEX_EDGE_PRED_BB (elist, x)->index);
00403
00404 if (INDEX_EDGE_SUCC_BB (elist, x) == EXIT_BLOCK_PTR)
00405 fprintf (f, "exit)\n");
00406 else
00407 fprintf (f, "%d)\n", INDEX_EDGE_SUCC_BB (elist, x)->index);
00408 }
00409 }
00410
00411
00412
00413
00414
00415 void
00416 verify_edge_list (FILE *f, struct edge_list *elist)
00417 {
00418 int pred, succ, index;
00419 edge e;
00420 basic_block bb, p, s;
00421 edge_iterator ei;
00422
00423 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
00424 {
00425 FOR_EACH_EDGE (e, ei, bb->succs)
00426 {
00427 pred = e->src->index;
00428 succ = e->dest->index;
00429 index = EDGE_INDEX (elist, e->src, e->dest);
00430 if (index == EDGE_INDEX_NO_EDGE)
00431 {
00432 fprintf (f, "*p* No index for edge from %d to %d\n", pred, succ);
00433 continue;
00434 }
00435
00436 if (INDEX_EDGE_PRED_BB (elist, index)->index != pred)
00437 fprintf (f, "*p* Pred for index %d should be %d not %d\n",
00438 index, pred, INDEX_EDGE_PRED_BB (elist, index)->index);
00439 if (INDEX_EDGE_SUCC_BB (elist, index)->index != succ)
00440 fprintf (f, "*p* Succ for index %d should be %d not %d\n",
00441 index, succ, INDEX_EDGE_SUCC_BB (elist, index)->index);
00442 }
00443 }
00444
00445
00446
00447
00448 FOR_BB_BETWEEN (p, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
00449 FOR_BB_BETWEEN (s, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb)
00450 {
00451 int found_edge = 0;
00452
00453 FOR_EACH_EDGE (e, ei, p->succs)
00454 if (e->dest == s)
00455 {
00456 found_edge = 1;
00457 break;
00458 }
00459
00460 FOR_EACH_EDGE (e, ei, s->preds)
00461 if (e->src == p)
00462 {
00463 found_edge = 1;
00464 break;
00465 }
00466
00467 if (EDGE_INDEX (elist, p, s)
00468 == EDGE_INDEX_NO_EDGE && found_edge != 0)
00469 fprintf (f, "*** Edge (%d, %d) appears to not have an index\n",
00470 p->index, s->index);
00471 if (EDGE_INDEX (elist, p, s)
00472 != EDGE_INDEX_NO_EDGE && found_edge == 0)
00473 fprintf (f, "*** Edge (%d, %d) has index %d, but there is no edge\n",
00474 p->index, s->index, EDGE_INDEX (elist, p, s));
00475 }
00476 }
00477
00478
00479
00480
00481 edge
00482 find_edge (basic_block pred, basic_block succ)
00483 {
00484 edge e;
00485 edge_iterator ei;
00486
00487 if (EDGE_COUNT (pred->succs) <= EDGE_COUNT (succ->preds))
00488 {
00489 FOR_EACH_EDGE (e, ei, pred->succs)
00490 if (e->dest == succ)
00491 return e;
00492 }
00493 else
00494 {
00495 FOR_EACH_EDGE (e, ei, succ->preds)
00496 if (e->src == pred)
00497 return e;
00498 }
00499
00500 return NULL;
00501 }
00502
00503
00504
00505
00506 int
00507 find_edge_index (struct edge_list *edge_list, basic_block pred, basic_block succ)
00508 {
00509 int x;
00510
00511 for (x = 0; x < NUM_EDGES (edge_list); x++)
00512 if (INDEX_EDGE_PRED_BB (edge_list, x) == pred
00513 && INDEX_EDGE_SUCC_BB (edge_list, x) == succ)
00514 return x;
00515
00516 return (EDGE_INDEX_NO_EDGE);
00517 }
00518
00519
00520
00521 void
00522 flow_nodes_print (const char *str, const sbitmap nodes, FILE *file)
00523 {
00524 unsigned int node = 0;
00525 sbitmap_iterator sbi;
00526
00527 if (! nodes)
00528 return;
00529
00530 fprintf (file, "%s { ", str);
00531 EXECUTE_IF_SET_IN_SBITMAP (nodes, 0, node, sbi)
00532 fprintf (file, "%d ", node);
00533 fputs ("}\n", file);
00534 }
00535
00536
00537
00538 void
00539 flow_edge_list_print (const char *str, const edge *edge_list, int num_edges, FILE *file)
00540 {
00541 int i;
00542
00543 if (! edge_list)
00544 return;
00545
00546 fprintf (file, "%s { ", str);
00547 for (i = 0; i < num_edges; i++)
00548 fprintf (file, "%d->%d ", edge_list[i]->src->index,
00549 edge_list[i]->dest->index);
00550
00551 fputs ("}\n", file);
00552 }
00553
00554
00555
00556
00557
00558
00559 static void
00560 remove_fake_predecessors (basic_block bb)
00561 {
00562 edge e;
00563 edge_iterator ei;
00564
00565 for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
00566 {
00567 if ((e->flags & EDGE_FAKE) == EDGE_FAKE)
00568 remove_edge (e);
00569 else
00570 ei_next (&ei);
00571 }
00572 }
00573
00574
00575
00576
00577
00578 void
00579 remove_fake_edges (void)
00580 {
00581 basic_block bb;
00582
00583 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb)
00584 remove_fake_predecessors (bb);
00585 }
00586
00587
00588
00589 void
00590 remove_fake_exit_edges (void)
00591 {
00592 remove_fake_predecessors (EXIT_BLOCK_PTR);
00593 }
00594
00595
00596
00597
00598
00599
00600 void
00601 add_noreturn_fake_exit_edges (void)
00602 {
00603 basic_block bb;
00604
00605 FOR_EACH_BB (bb)
00606 if (EDGE_COUNT (bb->succs) == 0)
00607 make_single_succ_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
00608 }
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 void
00622 connect_infinite_loops_to_exit (void)
00623 {
00624 basic_block unvisited_block = EXIT_BLOCK_PTR;
00625 struct depth_first_search_dsS dfs_ds;
00626
00627
00628
00629 flow_dfs_compute_reverse_init (&dfs_ds);
00630 flow_dfs_compute_reverse_add_bb (&dfs_ds, EXIT_BLOCK_PTR);
00631
00632
00633 while (1)
00634 {
00635 unvisited_block = flow_dfs_compute_reverse_execute (&dfs_ds,
00636 unvisited_block);
00637 if (!unvisited_block)
00638 break;
00639
00640 make_edge (unvisited_block, EXIT_BLOCK_PTR, EDGE_FAKE);
00641 flow_dfs_compute_reverse_add_bb (&dfs_ds, unvisited_block);
00642 }
00643
00644 flow_dfs_compute_reverse_finish (&dfs_ds);
00645 return;
00646 }
00647
00648
00649
00650
00651 int
00652 post_order_compute (int *post_order, bool include_entry_exit)
00653 {
00654 edge_iterator *stack;
00655 int sp;
00656 int post_order_num = 0;
00657 sbitmap visited;
00658
00659 if (include_entry_exit)
00660 post_order[post_order_num++] = EXIT_BLOCK;
00661
00662
00663 stack = XNEWVEC (edge_iterator, n_basic_blocks + 1);
00664 sp = 0;
00665
00666
00667 visited = sbitmap_alloc (last_basic_block);
00668
00669
00670 sbitmap_zero (visited);
00671
00672
00673 stack[sp++] = ei_start (ENTRY_BLOCK_PTR->succs);
00674
00675 while (sp)
00676 {
00677 edge_iterator ei;
00678 basic_block src;
00679 basic_block dest;
00680
00681
00682 ei = stack[sp - 1];
00683 src = ei_edge (ei)->src;
00684 dest = ei_edge (ei)->dest;
00685
00686
00687 if (dest != EXIT_BLOCK_PTR && ! TEST_BIT (visited, dest->index))
00688 {
00689
00690 SET_BIT (visited, dest->index);
00691
00692 if (EDGE_COUNT (dest->succs) > 0)
00693
00694
00695 stack[sp++] = ei_start (dest->succs);
00696 else
00697 post_order[post_order_num++] = dest->index;
00698 }
00699 else
00700 {
00701 if (ei_one_before_end_p (ei) && src != ENTRY_BLOCK_PTR)
00702 post_order[post_order_num++] = src->index;
00703
00704 if (!ei_one_before_end_p (ei))
00705 ei_next (&stack[sp - 1]);
00706 else
00707 sp--;
00708 }
00709 }
00710
00711 if (include_entry_exit)
00712 post_order[post_order_num++] = ENTRY_BLOCK;
00713
00714 free (stack);
00715 sbitmap_free (visited);
00716 return post_order_num;
00717 }
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 int
00731 pre_and_rev_post_order_compute (int *pre_order, int *rev_post_order,
00732 bool include_entry_exit)
00733 {
00734 edge_iterator *stack;
00735 int sp;
00736 int pre_order_num = 0;
00737 int rev_post_order_num = n_basic_blocks - 1;
00738 sbitmap visited;
00739
00740
00741 stack = XNEWVEC (edge_iterator, n_basic_blocks + 1);
00742 sp = 0;
00743
00744 if (include_entry_exit)
00745 {
00746 if (pre_order)
00747 pre_order[pre_order_num] = ENTRY_BLOCK;
00748 pre_order_num++;
00749 if (rev_post_order)
00750 rev_post_order[rev_post_order_num--] = ENTRY_BLOCK;
00751 }
00752 else
00753 rev_post_order_num -= NUM_FIXED_BLOCKS;
00754
00755
00756 visited = sbitmap_alloc (last_basic_block);
00757
00758
00759 sbitmap_zero (visited);
00760
00761
00762 stack[sp++] = ei_start (ENTRY_BLOCK_PTR->succs);
00763
00764 while (sp)
00765 {
00766 edge_iterator ei;
00767 basic_block src;
00768 basic_block dest;
00769
00770
00771 ei = stack[sp - 1];
00772 src = ei_edge (ei)->src;
00773 dest = ei_edge (ei)->dest;
00774
00775
00776 if (dest != EXIT_BLOCK_PTR && ! TEST_BIT (visited, dest->index))
00777 {
00778
00779 SET_BIT (visited, dest->index);
00780
00781 if (pre_order)
00782 pre_order[pre_order_num] = dest->index;
00783
00784 pre_order_num++;
00785
00786 if (EDGE_COUNT (dest->succs) > 0)
00787
00788
00789 stack[sp++] = ei_start (dest->succs);
00790 else if (rev_post_order)
00791
00792
00793 rev_post_order[rev_post_order_num--] = dest->index;
00794 }
00795 else
00796 {
00797 if (ei_one_before_end_p (ei) && src != ENTRY_BLOCK_PTR
00798 && rev_post_order)
00799
00800
00801 rev_post_order[rev_post_order_num--] = src->index;
00802
00803 if (!ei_one_before_end_p (ei))
00804 ei_next (&stack[sp - 1]);
00805 else
00806 sp--;
00807 }
00808 }
00809
00810 free (stack);
00811 sbitmap_free (visited);
00812
00813 if (include_entry_exit)
00814 {
00815 if (pre_order)
00816 pre_order[pre_order_num] = EXIT_BLOCK;
00817 pre_order_num++;
00818 if (rev_post_order)
00819 rev_post_order[rev_post_order_num--] = EXIT_BLOCK;
00820
00821 gcc_assert (pre_order_num == n_basic_blocks);
00822 }
00823 else
00824
00825
00826 gcc_assert (pre_order_num == n_basic_blocks - NUM_FIXED_BLOCKS);
00827
00828 return pre_order_num;
00829 }
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861 static void
00862 flow_dfs_compute_reverse_init (depth_first_search_ds data)
00863 {
00864
00865 data->stack = XNEWVEC (basic_block, n_basic_blocks);
00866 data->sp = 0;
00867
00868
00869 data->visited_blocks = sbitmap_alloc (last_basic_block);
00870
00871
00872 sbitmap_zero (data->visited_blocks);
00873
00874 return;
00875 }
00876
00877
00878
00879
00880
00881 static void
00882 flow_dfs_compute_reverse_add_bb (depth_first_search_ds data, basic_block bb)
00883 {
00884 data->stack[data->sp++] = bb;
00885 SET_BIT (data->visited_blocks, bb->index);
00886 }
00887
00888
00889
00890
00891
00892
00893 static basic_block
00894 flow_dfs_compute_reverse_execute (depth_first_search_ds data,
00895 basic_block last_unvisited)
00896 {
00897 basic_block bb;
00898 edge e;
00899 edge_iterator ei;
00900
00901 while (data->sp > 0)
00902 {
00903 bb = data->stack[--data->sp];
00904
00905
00906 FOR_EACH_EDGE (e, ei, bb->preds)
00907 if (!TEST_BIT (data->visited_blocks, e->src->index))
00908 flow_dfs_compute_reverse_add_bb (data, e->src);
00909 }
00910
00911
00912 FOR_BB_BETWEEN (bb, last_unvisited, NULL, prev_bb)
00913 if (!TEST_BIT (data->visited_blocks, bb->index))
00914 return bb;
00915
00916 return NULL;
00917 }
00918
00919
00920
00921
00922 static void
00923 flow_dfs_compute_reverse_finish (depth_first_search_ds data)
00924 {
00925 free (data->stack);
00926 sbitmap_free (data->visited_blocks);
00927 }
00928
00929
00930
00931
00932 int
00933 dfs_enumerate_from (basic_block bb, int reverse,
00934 bool (*predicate) (basic_block, void *),
00935 basic_block *rslt, int rslt_max, void *data)
00936 {
00937 basic_block *st, lbb;
00938 int sp = 0, tv = 0;
00939 unsigned size;
00940
00941
00942
00943
00944
00945
00946 static sbitmap visited;
00947 static unsigned v_size;
00948
00949 #define MARK_VISITED(BB) (SET_BIT (visited, (BB)->index))
00950 #define UNMARK_VISITED(BB) (RESET_BIT (visited, (BB)->index))
00951 #define VISITED_P(BB) (TEST_BIT (visited, (BB)->index))
00952
00953
00954 size = last_basic_block;
00955 if (size < 10)
00956 size = 10;
00957
00958 if (!visited)
00959 {
00960
00961 visited = sbitmap_alloc (size);
00962 sbitmap_zero (visited);
00963 v_size = size;
00964 }
00965 else if (v_size < size)
00966 {
00967
00968 if (2 * v_size > size)
00969 size = 2 * v_size;
00970
00971 visited = sbitmap_resize (visited, size, 0);
00972 v_size = size;
00973 }
00974
00975 st = XCNEWVEC (basic_block, rslt_max);
00976 rslt[tv++] = st[sp++] = bb;
00977 MARK_VISITED (bb);
00978 while (sp)
00979 {
00980 edge e;
00981 edge_iterator ei;
00982 lbb = st[--sp];
00983 if (reverse)
00984 {
00985 FOR_EACH_EDGE (e, ei, lbb->preds)
00986 if (!VISITED_P (e->src) && predicate (e->src, data))
00987 {
00988 gcc_assert (tv != rslt_max);
00989 rslt[tv++] = st[sp++] = e->src;
00990 MARK_VISITED (e->src);
00991 }
00992 }
00993 else
00994 {
00995 FOR_EACH_EDGE (e, ei, lbb->succs)
00996 if (!VISITED_P (e->dest) && predicate (e->dest, data))
00997 {
00998 gcc_assert (tv != rslt_max);
00999 rslt[tv++] = st[sp++] = e->dest;
01000 MARK_VISITED (e->dest);
01001 }
01002 }
01003 }
01004 free (st);
01005 for (sp = 0; sp < tv; sp++)
01006 UNMARK_VISITED (rslt[sp]);
01007 return tv;
01008 #undef MARK_VISITED
01009 #undef UNMARK_VISITED
01010 #undef VISITED_P
01011 }
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037 static void
01038 compute_dominance_frontiers_1 (bitmap *frontiers)
01039 {
01040 edge p;
01041 edge_iterator ei;
01042 basic_block b;
01043 FOR_EACH_BB (b)
01044 {
01045 if (EDGE_COUNT (b->preds) >= 2)
01046 {
01047 FOR_EACH_EDGE (p, ei, b->preds)
01048 {
01049 basic_block runner = p->src;
01050 basic_block domsb;
01051 if (runner == ENTRY_BLOCK_PTR)
01052 continue;
01053
01054 domsb = get_immediate_dominator (CDI_DOMINATORS, b);
01055 while (runner != domsb)
01056 {
01057 if (bitmap_bit_p (frontiers[runner->index], b->index))
01058 break;
01059 bitmap_set_bit (frontiers[runner->index],
01060 b->index);
01061 runner = get_immediate_dominator (CDI_DOMINATORS,
01062 runner);
01063 }
01064 }
01065 }
01066 }
01067 }
01068
01069
01070 void
01071 compute_dominance_frontiers (bitmap *frontiers)
01072 {
01073 timevar_push (TV_DOM_FRONTIERS);
01074
01075 compute_dominance_frontiers_1 (frontiers);
01076
01077 timevar_pop (TV_DOM_FRONTIERS);
01078 }
01079