00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "config.h"
00027 #include "system.h"
00028 #include "coretypes.h"
00029 #include "tm.h"
00030 #include "tree.h"
00031 #include "rtl.h"
00032 #include "tm_p.h"
00033 #include "hard-reg-set.h"
00034 #include "basic-block.h"
00035 #include "output.h"
00036 #include "errors.h"
00037 #include "flags.h"
00038 #include "function.h"
00039 #include "expr.h"
00040 #include "ggc.h"
00041 #include "langhooks.h"
00042 #include "diagnostic.h"
00043 #include "tree-flow.h"
00044 #include "timevar.h"
00045 #include "tree-dump.h"
00046 #include "tree-pass.h"
00047 #include "toplev.h"
00048 #include "except.h"
00049 #include "cfgloop.h"
00050 #include "cfglayout.h"
00051 #include "hashtab.h"
00052
00053
00054
00055
00056
00057
00058
00059 static const int initial_cfg_capacity = 20;
00060
00061
00062
00063 static GTY(()) varray_type label_to_block_map;
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 struct edge_to_cases_elt
00079 {
00080
00081 edge e;
00082
00083
00084
00085
00086
00087 tree case_labels;
00088 };
00089
00090 static htab_t edge_to_cases;
00091
00092
00093 struct cfg_stats_d
00094 {
00095 long num_merged_labels;
00096 };
00097
00098 static struct cfg_stats_d cfg_stats;
00099
00100
00101 static bool found_computed_goto;
00102
00103
00104 static basic_block create_bb (void *, void *, basic_block);
00105 static void create_block_annotation (basic_block);
00106 static void free_blocks_annotations (void);
00107 static void clear_blocks_annotations (void);
00108 static void make_blocks (tree);
00109 static void factor_computed_gotos (void);
00110
00111
00112 static void make_edges (void);
00113 static void make_ctrl_stmt_edges (basic_block);
00114 static void make_exit_edges (basic_block);
00115 static void make_cond_expr_edges (basic_block);
00116 static void make_switch_expr_edges (basic_block);
00117 static void make_goto_expr_edges (basic_block);
00118 static edge tree_redirect_edge_and_branch (edge, basic_block);
00119 static edge tree_try_redirect_by_replacing_jump (edge, basic_block);
00120 static void split_critical_edges (void);
00121 static bool remove_fallthru_edge (VEC(edge) *);
00122
00123
00124 static inline bool stmt_starts_bb_p (tree, tree);
00125 static int tree_verify_flow_info (void);
00126 static void tree_make_forwarder_block (edge);
00127 static bool tree_forwarder_block_p (basic_block, bool);
00128 static void tree_cfg2vcg (FILE *);
00129
00130
00131 static void tree_merge_blocks (basic_block, basic_block);
00132 static bool tree_can_merge_blocks_p (basic_block, basic_block);
00133 static void remove_bb (basic_block);
00134 static bool cleanup_control_flow (void);
00135 static bool cleanup_control_expr_graph (basic_block, block_stmt_iterator);
00136 static edge find_taken_edge_cond_expr (basic_block, tree);
00137 static edge find_taken_edge_switch_expr (basic_block, tree);
00138 static tree find_case_label_for_value (tree, tree);
00139 static bool phi_alternatives_equal (basic_block, edge, edge);
00140 static bool cleanup_forwarder_blocks (void);
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 static void
00151 build_tree_cfg (tree *tp)
00152 {
00153
00154 tree_register_cfg_hooks ();
00155
00156
00157 alloc_rbi_pool ();
00158
00159
00160 init_flow ();
00161 profile_status = PROFILE_ABSENT;
00162 n_basic_blocks = 0;
00163 last_basic_block = 0;
00164 VARRAY_BB_INIT (basic_block_info, initial_cfg_capacity, "basic_block_info");
00165 memset ((void *) &cfg_stats, 0, sizeof (cfg_stats));
00166
00167
00168 VARRAY_BB_INIT (label_to_block_map, initial_cfg_capacity,
00169 "label to block map");
00170
00171 ENTRY_BLOCK_PTR->next_bb = EXIT_BLOCK_PTR;
00172 EXIT_BLOCK_PTR->prev_bb = ENTRY_BLOCK_PTR;
00173
00174 found_computed_goto = 0;
00175 make_blocks (*tp);
00176
00177
00178
00179
00180
00181
00182 if (found_computed_goto)
00183 factor_computed_gotos ();
00184
00185
00186 if (n_basic_blocks == 0)
00187 create_empty_bb (ENTRY_BLOCK_PTR);
00188
00189 create_block_annotation (ENTRY_BLOCK_PTR);
00190 create_block_annotation (EXIT_BLOCK_PTR);
00191
00192
00193 VARRAY_GROW (basic_block_info, n_basic_blocks);
00194
00195
00196 cleanup_dead_labels ();
00197
00198
00199
00200
00201 group_case_labels ();
00202
00203
00204 make_edges ();
00205
00206
00207
00208
00209 {
00210 int local_dump_flags;
00211 FILE *dump_file = dump_begin (TDI_vcg, &local_dump_flags);
00212 if (dump_file)
00213 {
00214 tree_cfg2vcg (dump_file);
00215 dump_end (TDI_vcg, dump_file);
00216 }
00217 }
00218
00219
00220 if (dump_file)
00221 dump_tree_cfg (dump_file, dump_flags);
00222 }
00223
00224 static void
00225 execute_build_cfg (void)
00226 {
00227 build_tree_cfg (&DECL_SAVED_TREE (current_function_decl));
00228 }
00229
00230 struct tree_opt_pass pass_build_cfg =
00231 {
00232 "cfg",
00233 NULL,
00234 execute_build_cfg,
00235 NULL,
00236 NULL,
00237 0,
00238 TV_TREE_CFG,
00239 PROP_gimple_leh,
00240 PROP_cfg,
00241 0,
00242 0,
00243 TODO_verify_stmts,
00244 0
00245 };
00246
00247
00248
00249
00250
00251
00252 static void
00253 factor_computed_gotos (void)
00254 {
00255 basic_block bb;
00256 tree factored_label_decl = NULL;
00257 tree var = NULL;
00258 tree factored_computed_goto_label = NULL;
00259 tree factored_computed_goto = NULL;
00260
00261
00262
00263
00264
00265 FOR_EACH_BB (bb)
00266 {
00267 block_stmt_iterator bsi = bsi_last (bb);
00268 tree last;
00269
00270 if (bsi_end_p (bsi))
00271 continue;
00272 last = bsi_stmt (bsi);
00273
00274
00275
00276 if (last == factored_computed_goto)
00277 continue;
00278
00279
00280 if (computed_goto_p (last))
00281 {
00282 tree assignment;
00283
00284
00285
00286
00287 if (! factored_computed_goto)
00288 {
00289 basic_block new_bb = create_empty_bb (bb);
00290 block_stmt_iterator new_bsi = bsi_start (new_bb);
00291
00292
00293
00294
00295
00296 var = create_tmp_var (ptr_type_node, "gotovar");
00297
00298
00299
00300 factored_label_decl = create_artificial_label ();
00301 factored_computed_goto_label
00302 = build1 (LABEL_EXPR, void_type_node, factored_label_decl);
00303 bsi_insert_after (&new_bsi, factored_computed_goto_label,
00304 BSI_NEW_STMT);
00305
00306
00307 factored_computed_goto = build1 (GOTO_EXPR, void_type_node, var);
00308 bsi_insert_after (&new_bsi, factored_computed_goto,
00309 BSI_NEW_STMT);
00310 }
00311
00312
00313 assignment = build (MODIFY_EXPR, ptr_type_node,
00314 var, GOTO_DESTINATION (last));
00315 bsi_insert_before (&bsi, assignment, BSI_SAME_STMT);
00316
00317
00318 GOTO_DESTINATION (last) = factored_label_decl;
00319 }
00320 }
00321 }
00322
00323
00324
00325
00326 static void
00327 create_block_annotation (basic_block bb)
00328 {
00329
00330 gcc_assert (!bb->tree_annotations);
00331 bb->tree_annotations = ggc_alloc_cleared (sizeof (struct bb_ann_d));
00332 }
00333
00334
00335
00336
00337 static void free_blocks_annotations (void)
00338 {
00339 clear_blocks_annotations ();
00340 }
00341
00342
00343
00344
00345 static void
00346 clear_blocks_annotations (void)
00347 {
00348 basic_block bb;
00349
00350 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
00351 bb->tree_annotations = NULL;
00352 }
00353
00354
00355
00356
00357 static void
00358 make_blocks (tree stmt_list)
00359 {
00360 tree_stmt_iterator i = tsi_start (stmt_list);
00361 tree stmt = NULL;
00362 bool start_new_block = true;
00363 bool first_stmt_of_list = true;
00364 basic_block bb = ENTRY_BLOCK_PTR;
00365
00366 while (!tsi_end_p (i))
00367 {
00368 tree prev_stmt;
00369
00370 prev_stmt = stmt;
00371 stmt = tsi_stmt (i);
00372
00373
00374
00375
00376 if (start_new_block || stmt_starts_bb_p (stmt, prev_stmt))
00377 {
00378 if (!first_stmt_of_list)
00379 stmt_list = tsi_split_statement_list_before (&i);
00380 bb = create_basic_block (stmt_list, NULL, bb);
00381 start_new_block = false;
00382 }
00383
00384
00385
00386 set_bb_for_stmt (stmt, bb);
00387
00388 if (computed_goto_p (stmt))
00389 found_computed_goto = true;
00390
00391
00392
00393 if (stmt_ends_bb_p (stmt))
00394 start_new_block = true;
00395
00396 tsi_next (&i);
00397 first_stmt_of_list = false;
00398 }
00399 }
00400
00401
00402
00403
00404 static basic_block
00405 create_bb (void *h, void *e, basic_block after)
00406 {
00407 basic_block bb;
00408
00409 gcc_assert (!e);
00410
00411
00412
00413
00414 bb = alloc_block ();
00415
00416 bb->index = last_basic_block;
00417 bb->flags = BB_NEW;
00418 bb->stmt_list = h ? h : alloc_stmt_list ();
00419
00420
00421 link_block (bb, after);
00422
00423
00424 if ((size_t) last_basic_block == VARRAY_SIZE (basic_block_info))
00425 {
00426 size_t new_size = last_basic_block + (last_basic_block + 3) / 4;
00427 VARRAY_GROW (basic_block_info, new_size);
00428 }
00429
00430
00431 BASIC_BLOCK (last_basic_block) = bb;
00432
00433 create_block_annotation (bb);
00434
00435 n_basic_blocks++;
00436 last_basic_block++;
00437
00438 initialize_bb_rbi (bb);
00439 return bb;
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449 static void
00450 fold_cond_expr_cond (void)
00451 {
00452 basic_block bb;
00453
00454 FOR_EACH_BB (bb)
00455 {
00456 tree stmt = last_stmt (bb);
00457
00458 if (stmt
00459 && TREE_CODE (stmt) == COND_EXPR)
00460 {
00461 tree cond = fold (COND_EXPR_COND (stmt));
00462 if (integer_zerop (cond))
00463 COND_EXPR_COND (stmt) = integer_zero_node;
00464 else if (integer_onep (cond))
00465 COND_EXPR_COND (stmt) = integer_one_node;
00466 }
00467 }
00468 }
00469
00470
00471
00472 static void
00473 make_edges (void)
00474 {
00475 basic_block bb;
00476
00477
00478
00479 make_edge (ENTRY_BLOCK_PTR, BASIC_BLOCK (0), EDGE_FALLTHRU);
00480
00481
00482 FOR_EACH_BB (bb)
00483 {
00484 tree first = first_stmt (bb);
00485 tree last = last_stmt (bb);
00486
00487 if (first)
00488 {
00489
00490 if (is_ctrl_stmt (last))
00491 make_ctrl_stmt_edges (bb);
00492
00493
00494 if (is_ctrl_altering_stmt (last))
00495 make_exit_edges (bb);
00496 }
00497
00498
00499
00500 if (EDGE_COUNT (bb->succs) == 0)
00501 make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
00502 }
00503
00504
00505
00506 remove_fake_exit_edges ();
00507
00508
00509 fold_cond_expr_cond ();
00510
00511
00512 cleanup_tree_cfg ();
00513 }
00514
00515
00516
00517
00518 static void
00519 make_ctrl_stmt_edges (basic_block bb)
00520 {
00521 tree last = last_stmt (bb);
00522
00523 gcc_assert (last);
00524 switch (TREE_CODE (last))
00525 {
00526 case GOTO_EXPR:
00527 make_goto_expr_edges (bb);
00528 break;
00529
00530 case RETURN_EXPR:
00531 make_edge (bb, EXIT_BLOCK_PTR, 0);
00532 break;
00533
00534 case COND_EXPR:
00535 make_cond_expr_edges (bb);
00536 break;
00537
00538 case SWITCH_EXPR:
00539 make_switch_expr_edges (bb);
00540 break;
00541
00542 case RESX_EXPR:
00543 make_eh_edges (last);
00544
00545 if (EDGE_COUNT (bb->succs) == 0)
00546 make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
00547 break;
00548
00549 default:
00550 gcc_unreachable ();
00551 }
00552 }
00553
00554
00555
00556
00557
00558
00559 static void
00560 make_exit_edges (basic_block bb)
00561 {
00562 tree last = last_stmt (bb), op;
00563
00564 gcc_assert (last);
00565 switch (TREE_CODE (last))
00566 {
00567 case CALL_EXPR:
00568
00569
00570
00571 if (TREE_SIDE_EFFECTS (last)
00572 && current_function_has_nonlocal_label)
00573 make_goto_expr_edges (bb);
00574
00575
00576
00577 make_eh_edges (last);
00578
00579
00580
00581
00582
00583
00584
00585
00586 if (call_expr_flags (last) & ECF_NORETURN)
00587 {
00588 make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
00589 return;
00590 }
00591
00592
00593 make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
00594 break;
00595
00596 case MODIFY_EXPR:
00597
00598
00599
00600 op = get_call_expr_in (last);
00601 if (op && TREE_SIDE_EFFECTS (op)
00602 && current_function_has_nonlocal_label)
00603 make_goto_expr_edges (bb);
00604
00605 make_eh_edges (last);
00606 make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
00607 break;
00608
00609 default:
00610 gcc_unreachable ();
00611 }
00612 }
00613
00614
00615
00616
00617
00618 static void
00619 make_cond_expr_edges (basic_block bb)
00620 {
00621 tree entry = last_stmt (bb);
00622 basic_block then_bb, else_bb;
00623 tree then_label, else_label;
00624
00625 gcc_assert (entry);
00626 gcc_assert (TREE_CODE (entry) == COND_EXPR);
00627
00628
00629 then_label = GOTO_DESTINATION (COND_EXPR_THEN (entry));
00630 else_label = GOTO_DESTINATION (COND_EXPR_ELSE (entry));
00631 then_bb = label_to_block (then_label);
00632 else_bb = label_to_block (else_label);
00633
00634 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
00635 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
00636 }
00637
00638
00639
00640 static hashval_t
00641 edge_to_cases_hash (const void *p)
00642 {
00643 edge e = ((struct edge_to_cases_elt *)p)->e;
00644
00645
00646 return htab_hash_pointer (e);
00647 }
00648
00649
00650
00651
00652 static int
00653 edge_to_cases_eq (const void *p1, const void *p2)
00654 {
00655 edge e1 = ((struct edge_to_cases_elt *)p1)->e;
00656 edge e2 = ((struct edge_to_cases_elt *)p2)->e;
00657
00658 return e1 == e2;
00659 }
00660
00661
00662
00663
00664
00665
00666
00667
00668 static void
00669 edge_to_cases_cleanup (void *p)
00670 {
00671 struct edge_to_cases_elt *elt = p;
00672 tree t, next;
00673
00674 for (t = elt->case_labels; t; t = next)
00675 {
00676 next = TREE_CHAIN (t);
00677 TREE_CHAIN (t) = NULL;
00678 }
00679 free (p);
00680 }
00681
00682
00683
00684 static void
00685 start_recording_case_labels (void)
00686 {
00687 gcc_assert (edge_to_cases == NULL);
00688
00689 edge_to_cases = htab_create (37,
00690 edge_to_cases_hash,
00691 edge_to_cases_eq,
00692 edge_to_cases_cleanup);
00693 }
00694
00695
00696
00697 static bool
00698 recording_case_labels_p (void)
00699 {
00700 return (edge_to_cases != NULL);
00701 }
00702
00703
00704
00705 static void
00706 end_recording_case_labels (void)
00707 {
00708 htab_delete (edge_to_cases);
00709 edge_to_cases = NULL;
00710 }
00711
00712
00713
00714 static void
00715 record_switch_edge (edge e, tree case_label)
00716 {
00717 struct edge_to_cases_elt *elt;
00718 void **slot;
00719
00720
00721
00722 elt = xmalloc (sizeof (struct edge_to_cases_elt));
00723 elt->e = e;
00724 elt->case_labels = case_label;
00725
00726 slot = htab_find_slot (edge_to_cases, elt, INSERT);
00727
00728 if (*slot == NULL)
00729 {
00730
00731 *slot = (void *)elt;
00732 }
00733 else
00734 {
00735
00736
00737 free (elt);
00738
00739
00740 elt = (struct edge_to_cases_elt *) *slot;
00741
00742
00743 TREE_CHAIN (case_label) = elt->case_labels;
00744 elt->case_labels = case_label;
00745 }
00746 }
00747
00748
00749
00750
00751
00752
00753 static tree
00754 get_cases_for_edge (edge e, tree t)
00755 {
00756 struct edge_to_cases_elt elt, *elt_p;
00757 void **slot;
00758 size_t i, n;
00759 tree vec;
00760
00761
00762
00763 if (!recording_case_labels_p ())
00764 return NULL;
00765
00766 restart:
00767 elt.e = e;
00768 elt.case_labels = NULL;
00769 slot = htab_find_slot (edge_to_cases, &elt, NO_INSERT);
00770
00771 if (slot)
00772 {
00773 elt_p = (struct edge_to_cases_elt *)*slot;
00774 return elt_p->case_labels;
00775 }
00776
00777
00778
00779
00780
00781 vec = SWITCH_LABELS (t);
00782 n = TREE_VEC_LENGTH (vec);
00783 for (i = 0; i < n; i++)
00784 {
00785 tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
00786 basic_block label_bb = label_to_block (lab);
00787 record_switch_edge (find_edge (e->src, label_bb), TREE_VEC_ELT (vec, i));
00788 }
00789 goto restart;
00790 }
00791
00792
00793
00794
00795
00796 static void
00797 make_switch_expr_edges (basic_block bb)
00798 {
00799 tree entry = last_stmt (bb);
00800 size_t i, n;
00801 tree vec;
00802
00803 vec = SWITCH_LABELS (entry);
00804 n = TREE_VEC_LENGTH (vec);
00805
00806 for (i = 0; i < n; ++i)
00807 {
00808 tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
00809 basic_block label_bb = label_to_block (lab);
00810 make_edge (bb, label_bb, 0);
00811 }
00812 }
00813
00814
00815
00816
00817 basic_block
00818 label_to_block (tree dest)
00819 {
00820 int uid = LABEL_DECL_UID (dest);
00821
00822
00823
00824
00825 if ((errorcount || sorrycount) && uid < 0)
00826 {
00827 block_stmt_iterator bsi = bsi_start (BASIC_BLOCK (0));
00828 tree stmt;
00829
00830 stmt = build1 (LABEL_EXPR, void_type_node, dest);
00831 bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
00832 uid = LABEL_DECL_UID (dest);
00833 }
00834 return VARRAY_BB (label_to_block_map, uid);
00835 }
00836
00837
00838
00839
00840 static void
00841 make_goto_expr_edges (basic_block bb)
00842 {
00843 tree goto_t, dest;
00844 basic_block target_bb;
00845 int for_call;
00846 block_stmt_iterator last = bsi_last (bb);
00847
00848 goto_t = bsi_stmt (last);
00849
00850
00851
00852
00853 if (TREE_CODE (goto_t) != GOTO_EXPR)
00854 {
00855 dest = error_mark_node;
00856 for_call = 1;
00857 }
00858 else
00859 {
00860 dest = GOTO_DESTINATION (goto_t);
00861 for_call = 0;
00862
00863
00864 if (simple_goto_p (goto_t))
00865 {
00866 edge e = make_edge (bb, label_to_block (dest), EDGE_FALLTHRU);
00867 #ifdef USE_MAPPED_LOCATION
00868 e->goto_locus = EXPR_LOCATION (goto_t);
00869 #else
00870 e->goto_locus = EXPR_LOCUS (goto_t);
00871 #endif
00872 bsi_remove (&last);
00873 return;
00874 }
00875
00876
00877 if (TREE_CODE (dest) == LABEL_DECL)
00878 return;
00879
00880
00881 }
00882
00883
00884
00885
00886 FOR_EACH_BB (target_bb)
00887 {
00888 block_stmt_iterator bsi;
00889
00890 for (bsi = bsi_start (target_bb); !bsi_end_p (bsi); bsi_next (&bsi))
00891 {
00892 tree target = bsi_stmt (bsi);
00893
00894 if (TREE_CODE (target) != LABEL_EXPR)
00895 break;
00896
00897 if (
00898
00899
00900 (FORCED_LABEL (LABEL_EXPR_LABEL (target)) && for_call == 0)
00901
00902
00903
00904 || (DECL_NONLOCAL (LABEL_EXPR_LABEL (target)) && for_call == 1))
00905 {
00906 make_edge (bb, target_bb, EDGE_ABNORMAL);
00907 break;
00908 }
00909 }
00910 }
00911
00912
00913 if (!for_call && EDGE_COUNT (bb->succs) == 0)
00914 make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
00915 }
00916
00917
00918
00919
00920
00921
00922
00923
00924 bool
00925 cleanup_tree_cfg (void)
00926 {
00927 bool retval = false;
00928
00929 timevar_push (TV_TREE_CLEANUP_CFG);
00930
00931 retval = cleanup_control_flow ();
00932 retval |= delete_unreachable_blocks ();
00933
00934
00935
00936
00937
00938 if (optimize > 0)
00939 {
00940
00941
00942
00943
00944 start_recording_case_labels ();
00945 retval |= cleanup_forwarder_blocks ();
00946 end_recording_case_labels ();
00947 }
00948
00949 #ifdef ENABLE_CHECKING
00950 if (retval)
00951 {
00952 gcc_assert (!cleanup_control_flow ());
00953 gcc_assert (!delete_unreachable_blocks ());
00954 if (optimize > 0)
00955 gcc_assert (!cleanup_forwarder_blocks ());
00956 }
00957 #endif
00958
00959
00960
00961 retval |= merge_seq_blocks ();
00962
00963 compact_blocks ();
00964
00965 #ifdef ENABLE_CHECKING
00966 verify_flow_info ();
00967 #endif
00968 timevar_pop (TV_TREE_CLEANUP_CFG);
00969 return retval;
00970 }
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981 static tree *label_for_bb;
00982
00983
00984 static void
00985 update_eh_label (struct eh_region *region)
00986 {
00987 tree old_label = get_eh_region_tree_label (region);
00988 if (old_label)
00989 {
00990 tree new_label;
00991 basic_block bb = label_to_block (old_label);
00992
00993
00994
00995
00996 if (! bb)
00997 return;
00998
00999 new_label = label_for_bb[bb->index];
01000 set_eh_region_tree_label (region, new_label);
01001 }
01002 }
01003
01004
01005 static tree
01006 main_block_label (tree label)
01007 {
01008 basic_block bb = label_to_block (label);
01009
01010
01011 if (!label_for_bb[bb->index])
01012 label_for_bb[bb->index] = label;
01013 return label_for_bb[bb->index];
01014 }
01015
01016
01017
01018
01019
01020
01021 void
01022 cleanup_dead_labels (void)
01023 {
01024 basic_block bb;
01025 label_for_bb = xcalloc (last_basic_block, sizeof (tree));
01026
01027
01028
01029 FOR_EACH_BB (bb)
01030 {
01031 block_stmt_iterator i;
01032
01033 for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
01034 {
01035 tree label, stmt = bsi_stmt (i);
01036
01037 if (TREE_CODE (stmt) != LABEL_EXPR)
01038 break;
01039
01040 label = LABEL_EXPR_LABEL (stmt);
01041
01042
01043
01044 if (! label_for_bb[bb->index])
01045 {
01046 label_for_bb[bb->index] = label;
01047 continue;
01048 }
01049
01050
01051
01052
01053 if (! DECL_ARTIFICIAL (label)
01054 && DECL_ARTIFICIAL (label_for_bb[bb->index]))
01055 {
01056 label_for_bb[bb->index] = label;
01057 break;
01058 }
01059 }
01060 }
01061
01062
01063
01064 FOR_EACH_BB (bb)
01065 {
01066 tree stmt = last_stmt (bb);
01067 if (!stmt)
01068 continue;
01069
01070 switch (TREE_CODE (stmt))
01071 {
01072 case COND_EXPR:
01073 {
01074 tree true_branch, false_branch;
01075
01076 true_branch = COND_EXPR_THEN (stmt);
01077 false_branch = COND_EXPR_ELSE (stmt);
01078
01079 GOTO_DESTINATION (true_branch)
01080 = main_block_label (GOTO_DESTINATION (true_branch));
01081 GOTO_DESTINATION (false_branch)
01082 = main_block_label (GOTO_DESTINATION (false_branch));
01083
01084 break;
01085 }
01086
01087 case SWITCH_EXPR:
01088 {
01089 size_t i;
01090 tree vec = SWITCH_LABELS (stmt);
01091 size_t n = TREE_VEC_LENGTH (vec);
01092
01093
01094 for (i = 0; i < n; ++i)
01095 {
01096 tree elt = TREE_VEC_ELT (vec, i);
01097 tree label = main_block_label (CASE_LABEL (elt));
01098 CASE_LABEL (elt) = label;
01099 }
01100 break;
01101 }
01102
01103
01104
01105 case GOTO_EXPR:
01106 if (! computed_goto_p (stmt))
01107 {
01108 GOTO_DESTINATION (stmt)
01109 = main_block_label (GOTO_DESTINATION (stmt));
01110 break;
01111 }
01112
01113 default:
01114 break;
01115 }
01116 }
01117
01118 for_each_eh_region (update_eh_label);
01119
01120
01121
01122 FOR_EACH_BB (bb)
01123 {
01124 block_stmt_iterator i;
01125 tree label_for_this_bb = label_for_bb[bb->index];
01126
01127 if (! label_for_this_bb)
01128 continue;
01129
01130 for (i = bsi_start (bb); !bsi_end_p (i); )
01131 {
01132 tree label, stmt = bsi_stmt (i);
01133
01134 if (TREE_CODE (stmt) != LABEL_EXPR)
01135 break;
01136
01137 label = LABEL_EXPR_LABEL (stmt);
01138
01139 if (label == label_for_this_bb
01140 || ! DECL_ARTIFICIAL (label)
01141 || DECL_NONLOCAL (label))
01142 bsi_next (&i);
01143 else
01144 bsi_remove (&i);
01145 }
01146 }
01147
01148 free (label_for_bb);
01149 }
01150
01151
01152
01153
01154
01155
01156 void
01157 group_case_labels (void)
01158 {
01159 basic_block bb;
01160
01161 FOR_EACH_BB (bb)
01162 {
01163 tree stmt = last_stmt (bb);
01164 if (stmt && TREE_CODE (stmt) == SWITCH_EXPR)
01165 {
01166 tree labels = SWITCH_LABELS (stmt);
01167 int old_size = TREE_VEC_LENGTH (labels);
01168 int i, j, new_size = old_size;
01169 tree default_case = TREE_VEC_ELT (labels, old_size - 1);
01170 tree default_label;
01171
01172
01173
01174 default_label = CASE_LABEL (default_case);
01175
01176
01177
01178
01179 i = 0;
01180 while (i < old_size - 1)
01181 {
01182 tree base_case, base_label, base_high, type;
01183 base_case = TREE_VEC_ELT (labels, i);
01184
01185 gcc_assert (base_case);
01186 base_label = CASE_LABEL (base_case);
01187
01188
01189
01190 if (base_label == default_label)
01191 {
01192 TREE_VEC_ELT (labels, i) = NULL_TREE;
01193 i++;
01194 new_size--;
01195 continue;
01196 }
01197
01198 type = TREE_TYPE (CASE_LOW (base_case));
01199 base_high = CASE_HIGH (base_case) ?
01200 CASE_HIGH (base_case) : CASE_LOW (base_case);
01201 i++;
01202
01203
01204
01205 while (i < old_size - 1)
01206 {
01207 tree merge_case = TREE_VEC_ELT (labels, i);
01208 tree merge_label = CASE_LABEL (merge_case);
01209 tree t = int_const_binop (PLUS_EXPR, base_high,
01210 integer_one_node, 1);
01211
01212
01213
01214 if (merge_label == base_label
01215 && tree_int_cst_equal (CASE_LOW (merge_case), t))
01216 {
01217 base_high = CASE_HIGH (merge_case) ?
01218 CASE_HIGH (merge_case) : CASE_LOW (merge_case);
01219 CASE_HIGH (base_case) = base_high;
01220 TREE_VEC_ELT (labels, i) = NULL_TREE;
01221 new_size--;
01222 i++;
01223 }
01224 else
01225 break;
01226 }
01227 }
01228
01229
01230
01231 for (i = 0, j = 0; i < new_size; i++)
01232 {
01233 while (! TREE_VEC_ELT (labels, j))
01234 j++;
01235 TREE_VEC_ELT (labels, i) = TREE_VEC_ELT (labels, j++);
01236 }
01237 TREE_VEC_LENGTH (labels) = new_size;
01238 }
01239 }
01240 }
01241
01242
01243
01244 static bool
01245 tree_can_merge_blocks_p (basic_block a, basic_block b)
01246 {
01247 tree stmt;
01248 block_stmt_iterator bsi;
01249
01250 if (EDGE_COUNT (a->succs) != 1)
01251 return false;
01252
01253 if (EDGE_SUCC (a, 0)->flags & EDGE_ABNORMAL)
01254 return false;
01255
01256 if (EDGE_SUCC (a, 0)->dest != b)
01257 return false;
01258
01259 if (EDGE_COUNT (b->preds) > 1)
01260 return false;
01261
01262 if (b == EXIT_BLOCK_PTR)
01263 return false;
01264
01265
01266
01267 stmt = last_stmt (a);
01268 if (stmt && stmt_ends_bb_p (stmt))
01269 return false;
01270
01271
01272 if (stmt && TREE_CODE (stmt) == LABEL_EXPR
01273 && DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
01274 return false;
01275
01276
01277
01278 if (phi_nodes (b))
01279 return false;
01280
01281
01282 for (bsi = bsi_start (b); !bsi_end_p (bsi); bsi_next (&bsi))
01283 {
01284 stmt = bsi_stmt (bsi);
01285 if (TREE_CODE (stmt) != LABEL_EXPR)
01286 break;
01287 if (!DECL_ARTIFICIAL (LABEL_EXPR_LABEL (stmt)))
01288 return false;
01289 }
01290
01291 return true;
01292 }
01293
01294
01295
01296
01297 static void
01298 tree_merge_blocks (basic_block a, basic_block b)
01299 {
01300 block_stmt_iterator bsi;
01301 tree_stmt_iterator last;
01302
01303 if (dump_file)
01304 fprintf (dump_file, "Merging blocks %d and %d\n", a->index, b->index);
01305
01306
01307 move_block_after (b, a);
01308
01309 gcc_assert (EDGE_SUCC (a, 0)->flags & EDGE_FALLTHRU);
01310 gcc_assert (!last_stmt (a) || !stmt_ends_bb_p (last_stmt (a)));
01311
01312
01313 for (bsi = bsi_start (b); !bsi_end_p (bsi);)
01314 {
01315 if (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR)
01316 bsi_remove (&bsi);
01317 else
01318 {
01319 set_bb_for_stmt (bsi_stmt (bsi), a);
01320 bsi_next (&bsi);
01321 }
01322 }
01323
01324
01325 last = tsi_last (a->stmt_list);
01326 tsi_link_after (&last, b->stmt_list, TSI_NEW_STMT);
01327 b->stmt_list = NULL;
01328 }
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348 struct rus_data
01349 {
01350 tree *last_goto;
01351 bool repeat;
01352 bool may_throw;
01353 bool may_branch;
01354 bool has_label;
01355 };
01356
01357 static void remove_useless_stmts_1 (tree *, struct rus_data *);
01358
01359 static bool
01360 remove_useless_stmts_warn_notreached (tree stmt)
01361 {
01362 if (EXPR_HAS_LOCATION (stmt))
01363 {
01364 location_t loc = EXPR_LOCATION (stmt);
01365 if (LOCATION_LINE (loc) > 0)
01366 {
01367 warning ("%Hwill never be executed", &loc);
01368 return true;
01369 }
01370 }
01371
01372 switch (TREE_CODE (stmt))
01373 {
01374 case STATEMENT_LIST:
01375 {
01376 tree_stmt_iterator i;
01377 for (i = tsi_start (stmt); !tsi_end_p (i); tsi_next (&i))
01378 if (remove_useless_stmts_warn_notreached (tsi_stmt (i)))
01379 return true;
01380 }
01381 break;
01382
01383 case COND_EXPR:
01384 if (remove_useless_stmts_warn_notreached (COND_EXPR_COND (stmt)))
01385 return true;
01386 if (remove_useless_stmts_warn_notreached (COND_EXPR_THEN (stmt)))
01387 return true;
01388 if (remove_useless_stmts_warn_notreached (COND_EXPR_ELSE (stmt)))
01389 return true;
01390 break;
01391
01392 case TRY_FINALLY_EXPR:
01393 case TRY_CATCH_EXPR:
01394 if (remove_useless_stmts_warn_notreached (TREE_OPERAND (stmt, 0)))
01395 return true;
01396 if (remove_useless_stmts_warn_notreached (TREE_OPERAND (stmt, 1)))
01397 return true;
01398 break;
01399
01400 case CATCH_EXPR:
01401 return remove_useless_stmts_warn_notreached (CATCH_BODY (stmt));
01402 case EH_FILTER_EXPR:
01403 return remove_useless_stmts_warn_notreached (EH_FILTER_FAILURE (stmt));
01404 case BIND_EXPR:
01405 return remove_useless_stmts_warn_notreached (BIND_EXPR_BLOCK (stmt));
01406
01407 default:
01408
01409 break;
01410 }
01411
01412 return false;
01413 }
01414
01415 static void
01416 remove_useless_stmts_cond (tree *stmt_p, struct rus_data *data)
01417 {
01418 tree then_clause, else_clause, cond;
01419 bool save_has_label, then_has_label, else_has_label;
01420
01421 save_has_label = data->has_label;
01422 data->has_label = false;
01423 data->last_goto = NULL;
01424
01425 remove_useless_stmts_1 (&COND_EXPR_THEN (*stmt_p), data);
01426
01427 then_has_label = data->has_label;
01428 data->has_label = false;
01429 data->last_goto = NULL;
01430
01431 remove_useless_stmts_1 (&COND_EXPR_ELSE (*stmt_p), data);
01432
01433 else_has_label = data->has_label;
01434 data->has_label = save_has_label | then_has_label | else_has_label;
01435
01436 then_clause = COND_EXPR_THEN (*stmt_p);
01437 else_clause = COND_EXPR_ELSE (*stmt_p);
01438 cond = fold (COND_EXPR_COND (*stmt_p));
01439
01440
01441 if (!TREE_SIDE_EFFECTS (then_clause) && !TREE_SIDE_EFFECTS (else_clause))
01442 {
01443 *stmt_p = build_empty_stmt ();
01444 data->repeat = true;
01445 }
01446
01447
01448
01449 else if (integer_nonzerop (cond) && !else_has_label)
01450 {
01451 if (warn_notreached)
01452 remove_useless_stmts_warn_notreached (else_clause);
01453 *stmt_p = then_clause;
01454 data->repeat = true;
01455 }
01456 else if (integer_zerop (cond) && !then_has_label)
01457 {
01458 if (warn_notreached)
01459 remove_useless_stmts_warn_notreached (then_clause);
01460 *stmt_p = else_clause;
01461 data->repeat = true;
01462 }
01463
01464
01465 else
01466 {
01467 tree then_stmt = expr_only (then_clause);
01468 tree else_stmt = expr_only (else_clause);
01469
01470
01471 if (then_stmt && else_stmt
01472 && TREE_CODE (then_stmt) == GOTO_EXPR
01473 && TREE_CODE (else_stmt) == GOTO_EXPR
01474 && (GOTO_DESTINATION (then_stmt) == GOTO_DESTINATION (else_stmt)))
01475 {
01476 *stmt_p = then_stmt;
01477 data->repeat = true;
01478 }
01479
01480
01481
01482
01483 else if (TREE_CODE (cond) == VAR_DECL || TREE_CODE (cond) == PARM_DECL)
01484 {
01485 if (else_stmt
01486 && TREE_CODE (else_stmt) == MODIFY_EXPR
01487 && TREE_OPERAND (else_stmt, 0) == cond
01488 && integer_zerop (TREE_OPERAND (else_stmt, 1)))
01489 COND_EXPR_ELSE (*stmt_p) = alloc_stmt_list ();
01490 }
01491 else if ((TREE_CODE (cond) == EQ_EXPR || TREE_CODE (cond) == NE_EXPR)
01492 && (TREE_CODE (TREE_OPERAND (cond, 0)) == VAR_DECL
01493 || TREE_CODE (TREE_OPERAND (cond, 0)) == PARM_DECL)
01494 && TREE_CONSTANT (TREE_OPERAND (cond, 1)))
01495 {
01496 tree stmt = (TREE_CODE (cond) == EQ_EXPR
01497 ? then_stmt : else_stmt);
01498 tree *location = (TREE_CODE (cond) == EQ_EXPR
01499 ? &COND_EXPR_THEN (*stmt_p)
01500 : &COND_EXPR_ELSE (*stmt_p));
01501
01502 if (stmt
01503 && TREE_CODE (stmt) == MODIFY_EXPR
01504 && TREE_OPERAND (stmt, 0) == TREE_OPERAND (cond, 0)
01505 && TREE_OPERAND (stmt, 1) == TREE_OPERAND (cond, 1))
01506 *location = alloc_stmt_list ();
01507 }
01508 }
01509
01510
01511
01512 data->last_goto = NULL;
01513 }
01514
01515
01516 static void
01517 remove_useless_stmts_tf (tree *stmt_p, struct rus_data *data)
01518 {
01519 bool save_may_branch, save_may_throw;
01520 bool this_may_branch, this_may_throw;
01521
01522
01523 save_may_branch = data->may_branch;
01524 save_may_throw = data->may_throw;
01525 data->may_branch = false;
01526 data->may_throw = false;
01527 data->last_goto = NULL;
01528
01529 remove_useless_stmts_1 (&TREE_OPERAND (*stmt_p, 0), data);
01530
01531 this_may_branch = data->may_branch;
01532 this_may_throw = data->may_throw;
01533 data->may_branch |= save_may_branch;
01534 data->may_throw |= save_may_throw;
01535 data->last_goto = NULL;
01536
01537 remove_useless_stmts_1 (&TREE_OPERAND (*stmt_p, 1), data);
01538
01539
01540
01541 if (!TREE_SIDE_EFFECTS (TREE_OPERAND (*stmt_p, 0)))
01542 {
01543 *stmt_p = TREE_OPERAND (*stmt_p, 1);
01544 data->repeat = true;
01545 }
01546
01547
01548
01549 else if (!TREE_SIDE_EFFECTS (TREE_OPERAND (*stmt_p, 1)))
01550 {
01551 *stmt_p = TREE_OPERAND (*stmt_p, 0);
01552 data->repeat = true;
01553 }
01554
01555
01556
01557 else if (!this_may_branch && !this_may_throw)
01558 {
01559 tree stmt = *stmt_p;
01560 *stmt_p = TREE_OPERAND (stmt, 0);
01561 append_to_statement_list (TREE_OPERAND (stmt, 1), stmt_p);
01562 data->repeat = true;
01563 }
01564 }
01565
01566
01567 static void
01568 remove_useless_stmts_tc (tree *stmt_p, struct rus_data *data)
01569 {
01570 bool save_may_throw, this_may_throw;
01571 tree_stmt_iterator i;
01572 tree stmt;
01573
01574
01575 save_may_throw = data->may_throw;
01576 data->may_throw = false;
01577 data->last_goto = NULL;
01578
01579 remove_useless_stmts_1 (&TREE_OPERAND (*stmt_p, 0), data);
01580
01581 this_may_throw = data->may_throw;
01582 data->may_throw = save_may_throw;
01583
01584
01585 if (!this_may_throw)
01586 {
01587 if (warn_notreached)
01588 remove_useless_stmts_warn_notreached (TREE_OPERAND (*stmt_p, 1));
01589 *stmt_p = TREE_OPERAND (*stmt_p, 0);
01590 data->repeat = true;
01591 return;
01592 }
01593
01594
01595
01596
01597 this_may_throw = true;
01598 i = tsi_start (TREE_OPERAND (*stmt_p, 1));
01599 stmt = tsi_stmt (i);
01600 data->last_goto = NULL;
01601
01602 switch (TREE_CODE (stmt))
01603 {
01604 case CATCH_EXPR:
01605 for (; !tsi_end_p (i); tsi_next (&i))
01606 {
01607 stmt = tsi_stmt (i);
01608
01609
01610 if (CATCH_TYPES (stmt) == NULL)
01611 this_may_throw = false;
01612 data->last_goto = NULL;
01613 remove_useless_stmts_1 (&CATCH_BODY (stmt), data);
01614 }
01615 break;
01616
01617 case EH_FILTER_EXPR:
01618 if (EH_FILTER_MUST_NOT_THROW (stmt))
01619 this_may_throw = false;
01620 else if (EH_FILTER_TYPES (stmt) == NULL)
01621 this_may_throw = false;
01622 remove_useless_stmts_1 (&EH_FILTER_FAILURE (stmt), data);
01623 break;
01624
01625 default:
01626
01627 remove_useless_stmts_1 (&TREE_OPERAND (*stmt_p, 1), data);
01628
01629
01630
01631 if (!TREE_SIDE_EFFECTS (TREE_OPERAND (*stmt_p, 1)))
01632 {
01633 *stmt_p = TREE_OPERAND (*stmt_p, 0);
01634 data->repeat = true;
01635 }
01636 break;
01637 }
01638 data->may_throw |= this_may_throw;
01639 }
01640
01641
01642 static void
01643 remove_useless_stmts_bind (tree *stmt_p, struct rus_data *data)
01644 {
01645 tree block;
01646
01647
01648 remove_useless_stmts_1 (&BIND_EXPR_BODY (*stmt_p), data);
01649
01650
01651
01652
01653
01654
01655
01656 block = BIND_EXPR_BLOCK (*stmt_p);
01657 if (BIND_EXPR_VARS (*stmt_p) == NULL_TREE
01658 && *stmt_p != DECL_SAVED_TREE (current_function_decl)
01659 && (! block
01660 || ! BLOCK_ABSTRACT_ORIGIN (block)
01661 || (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block))
01662 != FUNCTION_DECL)))
01663 {
01664 *stmt_p = BIND_EXPR_BODY (*stmt_p);
01665 data->repeat = true;
01666 }
01667 }
01668
01669
01670 static void
01671 remove_useless_stmts_goto (tree *stmt_p, struct rus_data *data)
01672 {
01673 tree dest = GOTO_DESTINATION (*stmt_p);
01674
01675 data->may_branch = true;
01676 data->last_goto = NULL;
01677
01678
01679 if (TREE_CODE (dest) == LABEL_DECL)
01680 data->last_goto = stmt_p;
01681 }
01682
01683
01684 static void
01685 remove_useless_stmts_label (tree *stmt_p, struct rus_data *data)
01686 {
01687 tree label = LABEL_EXPR_LABEL (*stmt_p);
01688
01689 data->has_label = true;
01690
01691
01692 if (DECL_NONLOCAL (label))
01693 data->last_goto = NULL;
01694
01695 else if (data->last_goto && GOTO_DESTINATION (*data->last_goto) == label)
01696 {
01697 *data->last_goto = build_empty_stmt ();
01698 data->repeat = true;
01699 }
01700
01701
01702 }
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713 static void
01714 update_call_expr_flags (tree call)
01715 {
01716 tree decl = get_callee_fndecl (call);
01717 if (!decl)
01718 return;
01719 if (call_expr_flags (call) & (ECF_CONST | ECF_PURE))
01720 {
01721 TREE_SIDE_EFFECTS (call) = 0;
01722 #ifdef KEY
01723 if (gspin_invoked (call))
01724 gs_set_flag_value (call, GS_TREE_SIDE_EFFECTS, 0);
01725 #endif
01726 }
01727
01728 if (TREE_NOTHROW (decl))
01729 {
01730 TREE_NOTHROW (call) = 1;
01731 #ifdef KEY
01732 if (gspin_invoked (call))
01733 gs_set_flag_value (call, GS_TREE_NOTHROW, 1);
01734 #endif
01735 }
01736 }
01737
01738
01739
01740
01741 void
01742 notice_special_calls (tree t)
01743 {
01744 int flags = call_expr_flags (t);
01745
01746 if (flags & ECF_MAY_BE_ALLOCA)
01747 current_function_calls_alloca = true;
01748 if (flags & ECF_RETURNS_TWICE)
01749 current_function_calls_setjmp = true;
01750 }
01751
01752
01753
01754
01755
01756 void
01757 clear_special_calls (void)
01758 {
01759 current_function_calls_alloca = false;
01760 current_function_calls_setjmp = false;
01761 }
01762
01763
01764 static void
01765 remove_useless_stmts_1 (tree *tp, struct rus_data *data)
01766 {
01767 tree t = *tp, op;
01768
01769 switch (TREE_CODE (t))
01770 {
01771 case COND_EXPR:
01772 remove_useless_stmts_cond (tp, data);
01773 break;
01774
01775 case TRY_FINALLY_EXPR:
01776 remove_useless_stmts_tf (tp, data);
01777 break;
01778
01779 case TRY_CATCH_EXPR:
01780 remove_useless_stmts_tc (tp, data);
01781 break;
01782
01783 case BIND_EXPR:
01784 remove_useless_stmts_bind (tp, data);
01785 break;
01786
01787 case GOTO_EXPR:
01788 remove_useless_stmts_goto (tp, data);
01789 break;
01790
01791 case LABEL_EXPR:
01792 remove_useless_stmts_label (tp, data);
01793 break;
01794
01795 case RETURN_EXPR:
01796 fold_stmt (tp);
01797 data->last_goto = NULL;
01798 data->may_branch = true;
01799 break;
01800
01801 case CALL_EXPR:
01802 fold_stmt (tp);
01803 data->last_goto = NULL;
01804 notice_special_calls (t);
01805 update_call_expr_flags (t);
01806 if (tree_could_throw_p (t))
01807 data->may_throw = true;
01808 break;
01809
01810 case MODIFY_EXPR:
01811 data->last_goto = NULL;
01812 fold_stmt (tp);
01813 op = get_call_expr_in (t);
01814 if (op)
01815 {
01816 update_call_expr_flags (op);
01817 notice_special_calls (op);
01818 }
01819 if (tree_could_throw_p (t))
01820 data->may_throw = true;
01821 break;
01822
01823 case STATEMENT_LIST:
01824 {
01825 tree_stmt_iterator i = tsi_start (t);
01826 while (!tsi_end_p (i))
01827 {
01828 t = tsi_stmt (i);
01829 if (IS_EMPTY_STMT (t))
01830 {
01831 tsi_delink (&i);
01832 continue;
01833 }
01834
01835 remove_useless_stmts_1 (tsi_stmt_ptr (i), data);
01836
01837 t = tsi_stmt (i);
01838 if (TREE_CODE (t) == STATEMENT_LIST)
01839 {
01840 tsi_link_before (&i, t, TSI_SAME_STMT);
01841 tsi_delink (&i);
01842 }
01843 else
01844 tsi_next (&i);
01845 }
01846 }
01847 break;
01848 case ASM_EXPR:
01849 fold_stmt (tp);
01850 data->last_goto = NULL;
01851 break;
01852
01853 default:
01854 data->last_goto = NULL;
01855 break;
01856 }
01857 }
01858
01859 static void
01860 remove_useless_stmts (void)
01861 {
01862 struct rus_data data;
01863
01864 clear_special_calls ();
01865
01866 do
01867 {
01868 memset (&data, 0, sizeof (data));
01869 remove_useless_stmts_1 (&DECL_SAVED_TREE (current_function_decl), &data);
01870 }
01871 while (data.repeat);
01872 }
01873
01874
01875 struct tree_opt_pass pass_remove_useless_stmts =
01876 {
01877 "useless",
01878 NULL,
01879 remove_useless_stmts,
01880 NULL,
01881 NULL,
01882 0,
01883 0,
01884 PROP_gimple_any,
01885 0,
01886 0,
01887 0,
01888 TODO_dump_func,
01889 0
01890 };
01891
01892
01893
01894
01895 static void
01896 cfg_remove_useless_stmts_bb (basic_block bb)
01897 {
01898 block_stmt_iterator bsi;
01899 tree stmt = NULL_TREE;
01900 tree cond, var = NULL_TREE, val = NULL_TREE;
01901 struct var_ann_d *ann;
01902
01903
01904
01905 if (EDGE_COUNT (bb->preds) != 1
01906 || !(EDGE_PRED (bb, 0)->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
01907 return;
01908
01909 cond = COND_EXPR_COND (last_stmt (EDGE_PRED (bb, 0)->src));
01910
01911 if (TREE_CODE (cond) == VAR_DECL || TREE_CODE (cond) == PARM_DECL)
01912 {
01913 var = cond;
01914 val = (EDGE_PRED (bb, 0)->flags & EDGE_FALSE_VALUE
01915 ? boolean_false_node : boolean_true_node);
01916 }
01917 else if (TREE_CODE (cond) == TRUTH_NOT_EXPR
01918 && (TREE_CODE (TREE_OPERAND (cond, 0)) == VAR_DECL
01919 || TREE_CODE (TREE_OPERAND (cond, 0)) == PARM_DECL))
01920 {
01921 var = TREE_OPERAND (cond, 0);
01922 val = (EDGE_PRED (bb, 0)->flags & EDGE_FALSE_VALUE
01923 ? boolean_true_node : boolean_false_node);
01924 }
01925 else
01926 {
01927 if (EDGE_PRED (bb, 0)->flags & EDGE_FALSE_VALUE)
01928 cond = invert_truthvalue (cond);
01929 if (TREE_CODE (cond) == EQ_EXPR
01930 && (TREE_CODE (TREE_OPERAND (cond, 0)) == VAR_DECL
01931 || TREE_CODE (TREE_OPERAND (cond, 0)) == PARM_DECL)
01932 && (TREE_CODE (TREE_OPERAND (cond, 1)) == VAR_DECL
01933 || TREE_CODE (TREE_OPERAND (cond, 1)) == PARM_DECL
01934 || TREE_CONSTANT (TREE_OPERAND (cond, 1))))
01935 {
01936 var = TREE_OPERAND (cond, 0);
01937 val = TREE_OPERAND (cond, 1);
01938 }
01939 else
01940 return;
01941 }
01942
01943
01944 ann = var_ann (var);
01945 if (!ann
01946 || ann->may_aliases
01947 || TREE_ADDRESSABLE (var))
01948 return;
01949
01950 if (! TREE_CONSTANT (val))
01951 {
01952 ann = var_ann (val);
01953 if (!ann
01954 || ann->may_aliases
01955 || TREE_ADDRESSABLE (val))
01956 return;
01957 }
01958
01959
01960
01961 if (FLOAT_TYPE_P (TREE_TYPE (var)))
01962 return;
01963
01964 for (bsi = bsi_start (bb); !bsi_end_p (bsi);)
01965 {
01966 stmt = bsi_stmt (bsi);
01967
01968
01969
01970
01971 if (TREE_CODE (stmt) == MODIFY_EXPR
01972 && TREE_OPERAND (stmt, 0) == var
01973 && operand_equal_p (val, TREE_OPERAND (stmt, 1), 0))
01974 {
01975 bsi_remove (&bsi);
01976 continue;
01977 }
01978
01979
01980
01981
01982
01983 if (TREE_CODE (stmt) == ASM_EXPR
01984 || (TREE_CODE (stmt) == MODIFY_EXPR
01985 && (TREE_OPERAND (stmt, 0) == var
01986 || TREE_OPERAND (stmt, 0) == val)))
01987 return;
01988
01989 bsi_next (&bsi);
01990 }
01991 }
01992
01993
01994
01995
01996 void
01997 cfg_remove_useless_stmts (void)
01998 {
01999 basic_block bb;
02000
02001 #ifdef ENABLE_CHECKING
02002 verify_flow_info ();
02003 #endif
02004
02005 FOR_EACH_BB (bb)
02006 {
02007 cfg_remove_useless_stmts_bb (bb);
02008 }
02009 }
02010
02011
02012
02013
02014 static void
02015 remove_phi_nodes_and_edges_for_unreachable_block (basic_block bb)
02016 {
02017 tree phi;
02018
02019
02020
02021 phi = phi_nodes (bb);
02022 while (phi)
02023 {
02024 tree next = PHI_CHAIN (phi);
02025 remove_phi_node (phi, NULL_TREE, bb);
02026 phi = next;
02027 }
02028
02029
02030 while (EDGE_COUNT (bb->succs) > 0)
02031 remove_edge (EDGE_SUCC (bb, 0));
02032 }
02033
02034
02035
02036
02037 static void
02038 remove_bb (basic_block bb)
02039 {
02040 block_stmt_iterator i;
02041 source_locus loc = 0;
02042
02043 if (dump_file)
02044 {
02045 fprintf (dump_file, "Removing basic block %d\n", bb->index);
02046 if (dump_flags & TDF_DETAILS)
02047 {
02048 dump_bb (bb, dump_file, 0);
02049 fprintf (dump_file, "\n");
02050 }
02051 }
02052
02053
02054 for (i = bsi_start (bb); !bsi_end_p (i);)
02055 {
02056 tree stmt = bsi_stmt (i);
02057 if (TREE_CODE (stmt) == LABEL_EXPR
02058 && (FORCED_LABEL (LABEL_EXPR_LABEL (stmt))
02059 || DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt))))
02060 {
02061 basic_block new_bb;
02062 block_stmt_iterator new_bsi;
02063
02064
02065
02066
02067 if (DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
02068 {
02069 DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)) = 0;
02070 FORCED_LABEL (LABEL_EXPR_LABEL (stmt)) = 1;
02071 }
02072
02073 new_bb = bb->prev_bb;
02074 new_bsi = bsi_start (new_bb);
02075 bsi_remove (&i);
02076 bsi_insert_before (&new_bsi, stmt, BSI_NEW_STMT);
02077 }
02078 else
02079 {
02080 release_defs (stmt);
02081
02082 set_bb_for_stmt (stmt, NULL);
02083 bsi_remove (&i);
02084 }
02085
02086
02087
02088
02089
02090 if (TREE_CODE (stmt) != GOTO_EXPR && EXPR_HAS_LOCATION (stmt) && !loc)
02091 {
02092 source_locus t;
02093
02094 #ifdef USE_MAPPED_LOCATION
02095 t = EXPR_LOCATION (stmt);
02096 #else
02097 t = EXPR_LOCUS (stmt);
02098 #endif
02099 if (t && LOCATION_LINE (*t) > 0)
02100 loc = t;
02101 }
02102 }
02103
02104
02105
02106
02107
02108 if (warn_notreached && loc)
02109 #ifdef USE_MAPPED_LOCATION
02110 warning ("%Hwill never be executed", &loc);
02111 #else
02112 warning ("%Hwill never be executed", loc);
02113 #endif
02114
02115 remove_phi_nodes_and_edges_for_unreachable_block (bb);
02116 }
02117
02118
02119
02120
02121
02122
02123
02124 VEC(tree) *modified_noreturn_calls;
02125
02126
02127
02128 static bool
02129 cleanup_control_flow (void)
02130 {
02131 basic_block bb;
02132 block_stmt_iterator bsi;
02133 bool retval = false;
02134 tree stmt;
02135
02136
02137 while (VEC_length (tree, modified_noreturn_calls))
02138 {
02139 stmt = VEC_pop (tree, modified_noreturn_calls);
02140 bb = bb_for_stmt (stmt);
02141 if (bb != NULL && last_stmt (bb) != stmt && noreturn_call_p (stmt))
02142 split_block (bb, stmt);
02143 }
02144
02145 FOR_EACH_BB (bb)
02146 {
02147 bsi = bsi_last (bb);
02148
02149 if (bsi_end_p (bsi))
02150 continue;
02151
02152 stmt = bsi_stmt (bsi);
02153 if (TREE_CODE (stmt) == COND_EXPR
02154 || TREE_CODE (stmt) == SWITCH_EXPR)
02155 retval |= cleanup_control_expr_graph (bb, bsi);
02156
02157
02158
02159 if (noreturn_call_p (stmt) && remove_fallthru_edge (bb->succs))
02160 {
02161 free_dominance_info (CDI_DOMINATORS);
02162 retval = true;
02163 }
02164 }
02165 return retval;
02166 }
02167
02168
02169
02170
02171
02172 static bool
02173 cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi)
02174 {
02175 edge taken_edge;
02176 bool retval = false;
02177 tree expr = bsi_stmt (bsi), val;
02178
02179 if (EDGE_COUNT (bb->succs) > 1)
02180 {
02181 edge e;
02182 edge_iterator ei;
02183
02184 switch (TREE_CODE (expr))
02185 {
02186 case COND_EXPR:
02187 val = COND_EXPR_COND (expr);
02188 break;
02189
02190 case SWITCH_EXPR:
02191 val = SWITCH_COND (expr);
02192 if (TREE_CODE (val) != INTEGER_CST)
02193 return false;
02194 break;
02195
02196 default:
02197 gcc_unreachable ();
02198 }
02199
02200 taken_edge = find_taken_edge (bb, val);
02201 if (!taken_edge)
02202 return false;
02203
02204
02205 for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
02206 {
02207 if (e != taken_edge)
02208 {
02209 taken_edge->probability += e->probability;
02210 taken_edge->count += e->count;
02211 remove_edge (e);
02212 retval = true;
02213 }
02214 else
02215 ei_next (&ei);
02216 }
02217 if (taken_edge->probability > REG_BR_PROB_BASE)
02218 taken_edge->probability = REG_BR_PROB_BASE;
02219 }
02220 else
02221 taken_edge = EDGE_SUCC (bb, 0);
02222
02223 bsi_remove (&bsi);
02224 taken_edge->flags = EDGE_FALLTHRU;
02225
02226
02227 free_dominance_info (CDI_DOMINATORS);
02228
02229 return retval;
02230 }
02231
02232
02233
02234 static bool
02235 remove_fallthru_edge (VEC(edge) *ev)
02236 {
02237 edge_iterator ei;
02238 edge e;
02239
02240 FOR_EACH_EDGE (e, ei, ev)
02241 if ((e->flags & EDGE_FALLTHRU) != 0)
02242 {
02243 remove_edge (e);
02244 return true;
02245 }
02246 return false;
02247 }
02248
02249
02250
02251
02252
02253 edge
02254 find_taken_edge (basic_block bb, tree val)
02255 {
02256 tree stmt;
02257
02258 stmt = last_stmt (bb);
02259
02260 gcc_assert (stmt);
02261 gcc_assert (is_ctrl_stmt (stmt));
02262 gcc_assert (val);
02263
02264 if (TREE_CODE (val) != INTEGER_CST)
02265 return NULL;
02266
02267 if (TREE_CODE (stmt) == COND_EXPR)
02268 return find_taken_edge_cond_expr (bb, val);
02269
02270 if (TREE_CODE (stmt) == SWITCH_EXPR)
02271 return find_taken_edge_switch_expr (bb, val);
02272
02273 gcc_unreachable ();
02274 }
02275
02276
02277
02278
02279
02280
02281 static edge
02282 find_taken_edge_cond_expr (basic_block bb, tree val)
02283 {
02284 edge true_edge, false_edge;
02285
02286 extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
02287
02288 gcc_assert (TREE_CODE (val) == INTEGER_CST);
02289 return (zero_p (val) ? false_edge : true_edge);
02290 }
02291
02292
02293
02294
02295
02296 static edge
02297 find_taken_edge_switch_expr (basic_block bb, tree val)
02298 {
02299 tree switch_expr, taken_case;
02300 basic_block dest_bb;
02301 edge e;
02302
02303 switch_expr = last_stmt (bb);
02304 taken_case = find_case_label_for_value (switch_expr, val);
02305 dest_bb = label_to_block (CASE_LABEL (taken_case));
02306
02307 e = find_edge (bb, dest_bb);
02308 gcc_assert (e);
02309 return e;
02310 }
02311
02312
02313
02314
02315
02316
02317 static tree
02318 find_case_label_for_value (tree switch_expr, tree val)
02319 {
02320 tree vec = SWITCH_LABELS (switch_expr);
02321 size_t low, high, n = TREE_VEC_LENGTH (vec);
02322 tree default_case = TREE_VEC_ELT (vec, n - 1);
02323
02324 for (low = -1, high = n - 1; high - low > 1; )
02325 {
02326 size_t i = (high + low) / 2;
02327 tree t = TREE_VEC_ELT (vec, i);
02328 int cmp;
02329
02330
02331 cmp = tree_int_cst_compare (CASE_LOW (t), val);
02332
02333 if (cmp > 0)
02334 high = i;
02335 else
02336 low = i;
02337
02338 if (CASE_HIGH (t) == NULL)
02339 {
02340
02341 if (cmp == 0)
02342 return t;
02343 }
02344 else
02345 {
02346
02347 if (cmp <= 0 && tree_int_cst_compare (CASE_HIGH (t), val) >= 0)
02348 return t;
02349 }
02350 }
02351
02352 return default_case;
02353 }
02354
02355
02356
02357
02358
02359
02360 static bool
02361 phi_alternatives_equal (basic_block dest, edge e1, edge e2)
02362 {
02363 int n1 = e1->dest_idx;
02364 int n2 = e2->dest_idx;
02365 tree phi;
02366
02367 for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
02368 {
02369 tree val1 = PHI_ARG_DEF (phi, n1);
02370 tree val2 = PHI_ARG_DEF (phi, n2);
02371
02372 gcc_assert (val1 != NULL_TREE);
02373 gcc_assert (val2 != NULL_TREE);
02374
02375 if (!operand_equal_for_phi_arg_p (val1, val2))
02376 return false;
02377 }
02378
02379 return true;
02380 }
02381
02382
02383
02384
02385
02386
02387
02388
02389 void
02390 tree_dump_bb (basic_block bb, FILE *outf, int indent)
02391 {
02392 dump_generic_bb (outf, bb, indent, TDF_VOPS);
02393 }
02394
02395
02396
02397
02398 void
02399 debug_tree_bb (basic_block bb)
02400 {
02401 dump_bb (bb, stderr, 0);
02402 }
02403
02404
02405
02406
02407 basic_block
02408 debug_tree_bb_n (int n)
02409 {
02410 debug_tree_bb (BASIC_BLOCK (n));
02411 return BASIC_BLOCK (n);
02412 }
02413
02414
02415
02416
02417
02418
02419
02420 void
02421 debug_tree_cfg (int flags)
02422 {
02423 dump_tree_cfg (stderr, flags);
02424 }
02425
02426
02427
02428
02429
02430
02431
02432 void
02433 dump_tree_cfg (FILE *file, int flags)
02434 {
02435 if (flags & TDF_DETAILS)
02436 {
02437 const char *funcname
02438 = lang_hooks.decl_printable_name (current_function_decl, 2);
02439
02440 fputc ('\n', file);
02441 fprintf (file, ";; Function %s\n\n", funcname);
02442 fprintf (file, ";; \n%d basic blocks, %d edges, last basic block %d.\n\n",
02443 n_basic_blocks, n_edges, last_basic_block);
02444
02445 brief_dump_cfg (file);
02446 fprintf (file, "\n");
02447 }
02448
02449 if (flags & TDF_STATS)
02450 dump_cfg_stats (file);
02451
02452 dump_function_to_file (current_function_decl, file, flags | TDF_BLOCKS);
02453 }
02454
02455
02456
02457
02458 void
02459 dump_cfg_stats (FILE *file)
02460 {
02461 static long max_num_merged_labels = 0;
02462 unsigned long size, total = 0;
02463 int n_edges;
02464 basic_block bb;
02465 const char * const fmt_str = "%-30s%-13s%12s\n";
02466 const char * const fmt_str_1 = "%-30s%13d%11lu%c\n";
02467 const char * const fmt_str_3 = "%-43s%11lu%c\n";
02468 const char *funcname
02469 = lang_hooks.decl_printable_name (current_function_decl, 2);
02470
02471
02472 fprintf (file, "\nCFG Statistics for %s\n\n", funcname);
02473
02474 fprintf (file, "---------------------------------------------------------\n");
02475 fprintf (file, fmt_str, "", " Number of ", "Memory");
02476 fprintf (file, fmt_str, "", " instances ", "used ");
02477 fprintf (file, "---------------------------------------------------------\n");
02478
02479 size = n_basic_blocks * sizeof (struct basic_block_def);
02480 total += size;
02481 fprintf (file, fmt_str_1, "Basic blocks", n_basic_blocks,
02482 SCALE (size), LABEL (size));
02483
02484 n_edges = 0;
02485 FOR_EACH_BB (bb)
02486 n_edges += EDGE_COUNT (bb->succs);
02487 size = n_edges * sizeof (struct edge_def);
02488 total += size;
02489 fprintf (file, fmt_str_1, "Edges", n_edges, SCALE (size), LABEL (size));
02490
02491 size = n_basic_blocks * sizeof (struct bb_ann_d);
02492 total += size;
02493 fprintf (file, fmt_str_1, "Basic block annotations", n_basic_blocks,
02494 SCALE (size), LABEL (size));
02495
02496 fprintf (file, "---------------------------------------------------------\n");
02497 fprintf (file, fmt_str_3, "Total memory used by CFG data", SCALE (total),
02498 LABEL (total));
02499 fprintf (file, "---------------------------------------------------------\n");
02500 fprintf (file, "\n");
02501
02502 if (cfg_stats.num_merged_labels > max_num_merged_labels)
02503 max_num_merged_labels = cfg_stats.num_merged_labels;
02504
02505 fprintf (file, "Coalesced label blocks: %ld (Max so far: %ld)\n",
02506 cfg_stats.num_merged_labels, max_num_merged_labels);
02507
02508 fprintf (file, "\n");
02509 }
02510
02511
02512
02513
02514
02515 void
02516 debug_cfg_stats (void)
02517 {
02518 dump_cfg_stats (stderr);
02519 }
02520
02521
02522
02523
02524 static void
02525 tree_cfg2vcg (FILE *file)
02526 {
02527 edge e;
02528 edge_iterator ei;
02529 basic_block bb;
02530 const char *funcname
02531 = lang_hooks.decl_printable_name (current_function_decl, 2);
02532
02533
02534 fprintf (file, "graph: { title: \"%s\"\n", funcname);
02535 fprintf (file, "node: { title: \"ENTRY\" label: \"ENTRY\" }\n");
02536 fprintf (file, "node: { title: \"EXIT\" label: \"EXIT\" }\n");
02537
02538
02539 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
02540 {
02541 fprintf (file, "edge: { sourcename: \"ENTRY\" targetname: \"%d\"",
02542 e->dest->index);
02543
02544 if (e->flags & EDGE_FAKE)
02545 fprintf (file, " linestyle: dotted priority: 10");
02546 else
02547 fprintf (file, " linestyle: solid priority: 100");
02548
02549 fprintf (file, " }\n");
02550 }
02551 fputc ('\n', file);
02552
02553 FOR_EACH_BB (bb)
02554 {
02555 enum tree_code head_code, end_code;
02556 const char *head_name, *end_name;
02557 int head_line = 0;
02558 int end_line = 0;
02559 tree first = first_stmt (bb);
02560 tree last = last_stmt (bb);
02561
02562 if (first)
02563 {
02564 head_code = TREE_CODE (first);
02565 head_name = tree_code_name[head_code];
02566 head_line = get_lineno (first);
02567 }
02568 else
02569 head_name = "no-statement";
02570
02571 if (last)
02572 {
02573 end_code = TREE_CODE (last);
02574 end_name = tree_code_name[end_code];
02575 end_line = get_lineno (last);
02576 }
02577 else
02578 end_name = "no-statement";
02579
02580 fprintf (file, "node: { title: \"%d\" label: \"#%d\\n%s (%d)\\n%s (%d)\"}\n",
02581 bb->index, bb->index, head_name, head_line, end_name,
02582 end_line);
02583
02584 FOR_EACH_EDGE (e, ei, bb->succs)
02585 {
02586 if (e->dest == EXIT_BLOCK_PTR)
02587 fprintf (file, "edge: { sourcename: \"%d\" targetname: \"EXIT\"", bb->index);
02588 else
02589 fprintf (file, "edge: { sourcename: \"%d\" targetname: \"%d\"", bb->index, e->dest->index);
02590
02591 if (e->flags & EDGE_FAKE)
02592 fprintf (file, " priority: 10 linestyle: dotted");
02593 else
02594 fprintf (file, " priority: 100 linestyle: solid");
02595
02596 fprintf (file, " }\n");
02597 }
02598
02599 if (bb->next_bb != EXIT_BLOCK_PTR)
02600 fputc ('\n', file);
02601 }
02602
02603 fputs ("}\n\n", file);
02604 }
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614 bool
02615 is_ctrl_stmt (tree t)
02616 {
02617 return (TREE_CODE (t) == COND_EXPR
02618 || TREE_CODE (t) == SWITCH_EXPR
02619 || TREE_CODE (t) == GOTO_EXPR
02620 || TREE_CODE (t) == RETURN_EXPR
02621 || TREE_CODE (t) == RESX_EXPR);
02622 }
02623
02624
02625
02626
02627
02628 bool
02629 is_ctrl_altering_stmt (tree t)
02630 {
02631 tree call;
02632
02633 gcc_assert (t);
02634 call = get_call_expr_in (t);
02635 if (call)
02636 {
02637
02638
02639 if (TREE_SIDE_EFFECTS (call) && current_function_has_nonlocal_label)
02640 return true;
02641
02642
02643 if (call_expr_flags (call) & ECF_NORETURN)
02644 return true;
02645 }
02646
02647
02648 return tree_can_throw_internal (t);
02649 }
02650
02651
02652
02653
02654 bool
02655 computed_goto_p (tree t)
02656 {
02657 return (TREE_CODE (t) == GOTO_EXPR
02658 && TREE_CODE (GOTO_DESTINATION (t)) != LABEL_DECL);
02659 }
02660
02661
02662
02663
02664 bool
02665 simple_goto_p (tree expr)
02666 {
02667 return (TREE_CODE (expr) == GOTO_EXPR
02668 && TREE_CODE (GOTO_DESTINATION (expr)) == LABEL_DECL);
02669 }
02670
02671
02672
02673
02674
02675
02676
02677
02678 static inline bool
02679 stmt_starts_bb_p (tree t, tree prev_t)
02680 {
02681 enum tree_code code;
02682
02683 if (t == NULL_TREE)
02684 return false;
02685
02686
02687
02688
02689
02690 code = TREE_CODE (t);
02691 if (code == LABEL_EXPR)
02692 {
02693
02694 if (code == LABEL_EXPR
02695 && (DECL_NONLOCAL (LABEL_EXPR_LABEL (t))
02696 || FORCED_LABEL (LABEL_EXPR_LABEL (t))))
02697 return true;
02698
02699 if (prev_t && TREE_CODE (prev_t) == code)
02700 {
02701 if (DECL_NONLOCAL (LABEL_EXPR_LABEL (prev_t)))
02702 return true;
02703
02704 cfg_stats.num_merged_labels++;
02705 return false;
02706 }
02707 else
02708 return true;
02709 }
02710
02711 return false;
02712 }
02713
02714
02715
02716
02717 bool
02718 stmt_ends_bb_p (tree t)
02719 {
02720 return is_ctrl_stmt (t) || is_ctrl_altering_stmt (t);
02721 }
02722
02723
02724
02725
02726 void
02727 disband_implicit_edges (void)
02728 {
02729 basic_block bb;
02730 block_stmt_iterator last;
02731 edge e;
02732 edge_iterator ei;
02733 tree stmt, label;
02734
02735 FOR_EACH_BB (bb)
02736 {
02737 last = bsi_last (bb);
02738 stmt = last_stmt (bb);
02739
02740 if (stmt && TREE_CODE (stmt) == COND_EXPR)
02741 {
02742
02743
02744
02745
02746 e = find_edge (bb, bb->next_bb);
02747 if (e)
02748 {
02749 if (e->flags & EDGE_TRUE_VALUE)
02750 COND_EXPR_THEN (stmt) = build_empty_stmt ();
02751 else if (e->flags & EDGE_FALSE_VALUE)
02752 COND_EXPR_ELSE (stmt) = build_empty_stmt ();
02753 else
02754 gcc_unreachable ();
02755 e->flags |= EDGE_FALLTHRU;
02756 }
02757
02758 continue;
02759 }
02760
02761 if (stmt && TREE_CODE (stmt) == RETURN_EXPR)
02762 {
02763
02764
02765 gcc_assert (EDGE_COUNT (bb->succs) == 1);
02766 gcc_assert (EDGE_SUCC (bb, 0)->dest == EXIT_BLOCK_PTR);
02767
02768 if (bb->next_bb == EXIT_BLOCK_PTR
02769 && !TREE_OPERAND (stmt, 0))
02770 {
02771 bsi_remove (&last);
02772 EDGE_SUCC (bb, 0)->flags |= EDGE_FALLTHRU;
02773 }
02774 continue;
02775 }
02776
02777
02778
02779 if (stmt && is_ctrl_stmt (stmt))
02780 continue;
02781
02782
02783 FOR_EACH_EDGE (e, ei, bb->succs)
02784 if (e->flags & EDGE_FALLTHRU)
02785 break;
02786
02787 if (!e || e->dest == bb->next_bb)
02788 continue;
02789
02790 gcc_assert (e->dest != EXIT_BLOCK_PTR);
02791 label = tree_block_label (e->dest);
02792
02793 stmt = build1 (GOTO_EXPR, void_type_node, label);
02794 #ifdef USE_MAPPED_LOCATION
02795 SET_EXPR_LOCATION (stmt, e->goto_locus);
02796 #else
02797 SET_EXPR_LOCUS (stmt, e->goto_locus);
02798 #endif
02799 bsi_insert_after (&last, stmt, BSI_NEW_STMT);
02800 e->flags &= ~EDGE_FALLTHRU;
02801 }
02802 }
02803
02804
02805
02806 void
02807 delete_tree_cfg_annotations (void)
02808 {
02809 basic_block bb;
02810 if (n_basic_blocks > 0)
02811 free_blocks_annotations ();
02812
02813 label_to_block_map = NULL;
02814 free_rbi_pool ();
02815 FOR_EACH_BB (bb)
02816 bb->rbi = NULL;
02817 }
02818
02819
02820
02821
02822 tree
02823 first_stmt (basic_block bb)
02824 {
02825 block_stmt_iterator i = bsi_start (bb);
02826 return !bsi_end_p (i) ? bsi_stmt (i) : NULL_TREE;
02827 }
02828
02829
02830
02831
02832 tree
02833 last_stmt (basic_block bb)
02834 {
02835 block_stmt_iterator b = bsi_last (bb);
02836 return !bsi_end_p (b) ? bsi_stmt (b) : NULL_TREE;
02837 }
02838
02839
02840
02841
02842 tree *
02843 last_stmt_ptr (basic_block bb)
02844 {
02845 block_stmt_iterator last = bsi_last (bb);
02846 return !bsi_end_p (last) ? bsi_stmt_ptr (last) : NULL;
02847 }
02848
02849
02850
02851
02852
02853
02854 tree
02855 last_and_only_stmt (basic_block bb)
02856 {
02857 block_stmt_iterator i = bsi_last (bb);
02858 tree last, prev;
02859
02860 if (bsi_end_p (i))
02861 return NULL_TREE;
02862
02863 last = bsi_stmt (i);
02864 bsi_prev (&i);
02865 if (bsi_end_p (i))
02866 return last;
02867
02868
02869
02870
02871
02872
02873
02874
02875 prev = bsi_stmt (i);
02876 if (TREE_CODE (prev) == LABEL_EXPR)
02877 return last;
02878 else
02879 return NULL_TREE;
02880 }
02881
02882
02883
02884
02885 void
02886 set_bb_for_stmt (tree t, basic_block bb)
02887 {
02888 if (TREE_CODE (t) == PHI_NODE)
02889 PHI_BB (t) = bb;
02890 else if (TREE_CODE (t) == STATEMENT_LIST)
02891 {
02892 tree_stmt_iterator i;
02893 for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
02894 set_bb_for_stmt (tsi_stmt (i), bb);
02895 }
02896 else
02897 {
02898 stmt_ann_t ann = get_stmt_ann (t);
02899 ann->bb = bb;
02900
02901
02902
02903 if (TREE_CODE (t) == LABEL_EXPR)
02904 {
02905 int uid;
02906
02907 t = LABEL_EXPR_LABEL (t);
02908 uid = LABEL_DECL_UID (t);
02909 if (uid == -1)
02910 {
02911 LABEL_DECL_UID (t) = uid = cfun->last_label_uid++;
02912 if (VARRAY_SIZE (label_to_block_map) <= (unsigned) uid)
02913 VARRAY_GROW (label_to_block_map, 3 * uid / 2);
02914 }
02915 else
02916
02917
02918 gcc_assert (!bb || !VARRAY_BB (label_to_block_map, uid));
02919 VARRAY_BB (label_to_block_map, uid) = bb;
02920 }
02921 }
02922 }
02923
02924
02925
02926 extern block_stmt_iterator
02927 bsi_for_stmt (tree stmt)
02928 {
02929 block_stmt_iterator bsi;
02930
02931 for (bsi = bsi_start (bb_for_stmt (stmt)); !bsi_end_p (bsi); bsi_next (&bsi))
02932 if (bsi_stmt (bsi) == stmt)
02933 return bsi;
02934
02935 gcc_unreachable ();
02936 }
02937
02938
02939
02940
02941
02942 void
02943 bsi_insert_before (block_stmt_iterator *i, tree t, enum bsi_iterator_update m)
02944 {
02945 set_bb_for_stmt (t, i->bb);
02946 tsi_link_before (&i->tsi, t, m);
02947 modify_stmt (t);
02948 }
02949
02950
02951
02952
02953
02954
02955 void
02956 bsi_insert_after (block_stmt_iterator *i, tree t, enum bsi_iterator_update m)
02957 {
02958 set_bb_for_stmt (t, i->bb);
02959 tsi_link_after (&i->tsi, t, m);
02960 modify_stmt (t);
02961 }
02962
02963
02964
02965
02966
02967 void
02968 bsi_remove (block_stmt_iterator *i)
02969 {
02970 tree t = bsi_stmt (*i);
02971 set_bb_for_stmt (t, NULL);
02972 tsi_delink (&i->tsi);
02973 }
02974
02975
02976
02977
02978 void
02979 bsi_move_after (block_stmt_iterator *from, block_stmt_iterator *to)
02980 {
02981 tree stmt = bsi_stmt (*from);
02982 bsi_remove (from);
02983 bsi_insert_after (to, stmt, BSI_SAME_STMT);
02984 }
02985
02986
02987
02988
02989 void
02990 bsi_move_before (block_stmt_iterator *from, block_stmt_iterator *to)
02991 {
02992 tree stmt = bsi_stmt (*from);
02993 bsi_remove (from);
02994 bsi_insert_before (to, stmt, BSI_SAME_STMT);
02995 }
02996
02997
02998
02999
03000 void
03001 bsi_move_to_bb_end (block_stmt_iterator *from, basic_block bb)
03002 {
03003 block_stmt_iterator last = bsi_last (bb);
03004
03005
03006 if (!bsi_end_p (last) && is_ctrl_stmt (bsi_stmt (last)))
03007 bsi_move_before (from, &last);
03008 else
03009 bsi_move_after (from, &last);
03010 }
03011
03012
03013
03014
03015
03016
03017 void
03018 bsi_replace (const block_stmt_iterator *bsi, tree stmt, bool preserve_eh_info)
03019 {
03020 int eh_region;
03021 tree orig_stmt = bsi_stmt (*bsi);
03022
03023 SET_EXPR_LOCUS (stmt, EXPR_LOCUS (orig_stmt));
03024 set_bb_for_stmt (stmt, bsi->bb);
03025
03026
03027
03028 if (preserve_eh_info)
03029 {
03030 eh_region = lookup_stmt_eh_region (orig_stmt);
03031 if (eh_region >= 0)
03032 add_stmt_to_eh_region (stmt, eh_region);
03033 }
03034
03035 *bsi_stmt_ptr (*bsi) = stmt;
03036 modify_stmt (stmt);
03037 }
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050 static bool
03051 tree_find_edge_insert_loc (edge e, block_stmt_iterator *bsi,
03052 basic_block *new_bb)
03053 {
03054 basic_block dest, src;
03055 tree tmp;
03056
03057 dest = e->dest;
03058 restart:
03059
03060
03061
03062
03063
03064
03065
03066
03067 if (EDGE_COUNT (dest->preds) == 1
03068 && ! phi_nodes (dest)
03069 && dest != EXIT_BLOCK_PTR)
03070 {
03071 *bsi = bsi_start (dest);
03072 if (bsi_end_p (*bsi))
03073 return true;
03074
03075
03076 tmp = bsi_stmt (*bsi);
03077 while (TREE_CODE (tmp) == LABEL_EXPR)
03078 {
03079 bsi_next (bsi);
03080 if (bsi_end_p (*bsi))
03081 break;
03082 tmp = bsi_stmt (*bsi);
03083 }
03084
03085 if (bsi_end_p (*bsi))
03086 {
03087 *bsi = bsi_last (dest);
03088 return true;
03089 }
03090 else
03091 return false;
03092 }
03093
03094
03095
03096
03097 src = e->src;
03098 if ((e->flags & EDGE_ABNORMAL) == 0
03099 && EDGE_COUNT (src->succs) == 1
03100 && src != ENTRY_BLOCK_PTR)
03101 {
03102 *bsi = bsi_last (src);
03103 if (bsi_end_p (*bsi))
03104 return true;
03105
03106 tmp = bsi_stmt (*bsi);
03107 if (!stmt_ends_bb_p (tmp))
03108 return true;
03109
03110
03111
03112 if (TREE_CODE (tmp) == RETURN_EXPR)
03113 {
03114 tree op = TREE_OPERAND (tmp, 0);
03115 if (!is_gimple_val (op))
03116 {
03117 gcc_assert (TREE_CODE (op) == MODIFY_EXPR);
03118 bsi_insert_before (bsi, op, BSI_NEW_STMT);
03119 TREE_OPERAND (tmp, 0) = TREE_OPERAND (op, 0);
03120 }
03121 bsi_prev (bsi);
03122 return true;
03123 }
03124 }
03125
03126
03127 dest = split_edge (e);
03128 if (new_bb)
03129 *new_bb = dest;
03130 e = EDGE_PRED (dest, 0);
03131 goto restart;
03132 }
03133
03134
03135
03136
03137
03138 void
03139 bsi_commit_edge_inserts (void)
03140 {
03141 basic_block bb;
03142 edge e;
03143 edge_iterator ei;
03144
03145 bsi_commit_one_edge_insert (EDGE_SUCC (ENTRY_BLOCK_PTR, 0), NULL);
03146
03147 FOR_EACH_BB (bb)
03148 FOR_EACH_EDGE (e, ei, bb->succs)
03149 bsi_commit_one_edge_insert (e, NULL);
03150 }
03151
03152
03153
03154
03155
03156 void
03157 bsi_commit_one_edge_insert (edge e, basic_block *new_bb)
03158 {
03159 if (new_bb)
03160 *new_bb = NULL;
03161 if (PENDING_STMT (e))
03162 {
03163 block_stmt_iterator bsi;
03164 tree stmt = PENDING_STMT (e);
03165
03166 PENDING_STMT (e) = NULL_TREE;
03167
03168 if (tree_find_edge_insert_loc (e, &bsi, new_bb))
03169 bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
03170 else
03171 bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
03172 }
03173 }
03174
03175
03176
03177
03178
03179 void
03180 bsi_insert_on_edge (edge e, tree stmt)
03181 {
03182 append_to_statement_list (stmt, &PENDING_STMT (e));
03183 }
03184
03185
03186
03187
03188 basic_block
03189 bsi_insert_on_edge_immediate (edge e, tree stmt)
03190 {
03191 block_stmt_iterator bsi;
03192 basic_block new_bb = NULL;
03193
03194 gcc_assert (!PENDING_STMT (e));
03195
03196 if (tree_find_edge_insert_loc (e, &bsi, &new_bb))
03197 bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
03198 else
03199 bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
03200
03201 return new_bb;
03202 }
03203
03204
03205
03206
03207
03208
03209
03210 static void
03211 reinstall_phi_args (edge new_edge, edge old_edge)
03212 {
03213 tree var, phi;
03214
03215 if (!PENDING_STMT (old_edge))
03216 return;
03217
03218 for (var = PENDING_STMT (old_edge), phi = phi_nodes (new_edge->dest);
03219 var && phi;
03220 var = TREE_CHAIN (var), phi = PHI_CHAIN (phi))
03221 {
03222 tree result = TREE_PURPOSE (var);
03223 tree arg = TREE_VALUE (var);
03224
03225 gcc_assert (result == PHI_RESULT (phi));
03226
03227 add_phi_arg (phi, arg, new_edge);
03228 }
03229
03230 PENDING_STMT (old_edge) = NULL;
03231 }
03232
03233
03234
03235
03236 static basic_block
03237 tree_split_edge (edge edge_in)
03238 {
03239 basic_block new_bb, after_bb, dest, src;
03240 edge new_edge, e;
03241
03242
03243 gcc_assert (!(edge_in->flags & EDGE_ABNORMAL));
03244
03245 src = edge_in->src;
03246 dest = edge_in->dest;
03247
03248
03249
03250
03251 if (dest->prev_bb && find_edge (dest->prev_bb, dest))
03252 after_bb = edge_in->src;
03253 else
03254 after_bb = dest->prev_bb;
03255
03256 new_bb = create_empty_bb (after_bb);
03257 new_bb->frequency = EDGE_FREQUENCY (edge_in);
03258 new_bb->count = edge_in->count;
03259 new_edge = make_edge (new_bb, dest, EDGE_FALLTHRU);
03260 new_edge->probability = REG_BR_PROB_BASE;
03261 new_edge->count = edge_in->count;
03262
03263 e = redirect_edge_and_branch (edge_in, new_bb);
03264 gcc_assert (e);
03265 reinstall_phi_args (new_edge, e);
03266
03267 return new_bb;
03268 }
03269
03270
03271
03272
03273 static bool
03274 has_label_p (basic_block bb, tree label)
03275 {
03276 block_stmt_iterator bsi;
03277
03278 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
03279 {
03280 tree stmt = bsi_stmt (bsi);
03281
03282 if (TREE_CODE (stmt) != LABEL_EXPR)
03283 return false;
03284 if (LABEL_EXPR_LABEL (stmt) == label)
03285 return true;
03286 }
03287 return false;
03288 }
03289
03290
03291
03292
03293
03294
03295 static tree
03296 verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
03297 {
03298 tree t = *tp, x;
03299 bool in_phi = (data != NULL);
03300
03301 if (TYPE_P (t))
03302 *walk_subtrees = 0;
03303
03304
03305
03306
03307 #define CHECK_OP(N, MSG) \
03308 do { if (!CONSTANT_CLASS_P (TREE_OPERAND (t, N)) \
03309 && !is_gimple_val (TREE_OPERAND (t, N))) \
03310 { error (MSG); return TREE_OPERAND (t, N); }} while (0)
03311
03312 switch (TREE_CODE (t))
03313 {
03314 case SSA_NAME:
03315 if (SSA_NAME_IN_FREE_LIST (t))
03316 {
03317 error ("SSA name in freelist but still referenced");
03318 return *tp;
03319 }
03320 break;
03321
03322 case MODIFY_EXPR:
03323 x = TREE_OPERAND (t, 0);
03324 if (TREE_CODE (x) == BIT_FIELD_REF
03325 && is_gimple_reg (TREE_OPERAND (x, 0)))
03326 {
03327 error ("GIMPLE register modified with BIT_FIELD_REF");
03328 return t;
03329 }
03330 break;
03331
03332 case ADDR_EXPR:
03333
03334
03335
03336
03337
03338
03339
03340 if (in_phi)
03341 break;
03342
03343
03344
03345
03346 for (x = TREE_OPERAND (t, 0);
03347 handled_component_p (x);
03348 x = TREE_OPERAND (x, 0))
03349 ;
03350
03351 if (TREE_CODE (x) != VAR_DECL && TREE_CODE (x) != PARM_DECL)
03352 return NULL;
03353 if (!TREE_ADDRESSABLE (x))
03354 {
03355 error ("address taken, but ADDRESSABLE bit not set");
03356 return x;
03357 }
03358 break;
03359
03360 case COND_EXPR:
03361 x = COND_EXPR_COND (t);
03362 if (TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE)
03363 {
03364 error ("non-boolean used in condition");
03365 return x;
03366 }
03367 break;
03368
03369 case NOP_EXPR:
03370 case CONVERT_EXPR:
03371 case FIX_TRUNC_EXPR:
03372 case FIX_CEIL_EXPR:
03373 case FIX_FLOOR_EXPR:
03374 case FIX_ROUND_EXPR:
03375 case FLOAT_EXPR:
03376 case NEGATE_EXPR:
03377 case ABS_EXPR:
03378 case BIT_NOT_EXPR:
03379 case NON_LVALUE_EXPR:
03380 case TRUTH_NOT_EXPR:
03381 CHECK_OP (0, "Invalid operand to unary operator");
03382 break;
03383
03384 case REALPART_EXPR:
03385 case IMAGPART_EXPR:
03386 case COMPONENT_REF:
03387 case ARRAY_REF:
03388 case ARRAY_RANGE_REF:
03389 case BIT_FIELD_REF:
03390 case VIEW_CONVERT_EXPR:
03391
03392
03393
03394
03395 while (handled_component_p (t))
03396 {
03397 if (TREE_CODE (t) == COMPONENT_REF && TREE_OPERAND (t, 2))
03398 CHECK_OP (2, "Invalid COMPONENT_REF offset operator");
03399 else if (TREE_CODE (t) == ARRAY_REF
03400 || TREE_CODE (t) == ARRAY_RANGE_REF)
03401 {
03402 CHECK_OP (1, "Invalid array index.");
03403 if (TREE_OPERAND (t, 2))
03404 CHECK_OP (2, "Invalid array lower bound.");
03405 if (TREE_OPERAND (t, 3))
03406 CHECK_OP (3, "Invalid array stride.");
03407 }
03408 else if (TREE_CODE (t) == BIT_FIELD_REF)
03409 {
03410 CHECK_OP (1, "Invalid operand to BIT_FIELD_REF");
03411 CHECK_OP (2, "Invalid operand to BIT_FIELD_REF");
03412 }
03413
03414 t = TREE_OPERAND (t, 0);
03415 }
03416
03417 if (!CONSTANT_CLASS_P (t) && !is_gimple_lvalue (t))
03418 {
03419 error ("Invalid reference prefix.");
03420 return t;
03421 }
03422 *walk_subtrees = 0;
03423 break;
03424
03425 case LT_EXPR:
03426 case LE_EXPR:
03427 case GT_EXPR:
03428 case GE_EXPR:
03429 case EQ_EXPR:
03430 case NE_EXPR:
03431 case UNORDERED_EXPR:
03432 case ORDERED_EXPR:
03433 case UNLT_EXPR:
03434 case UNLE_EXPR:
03435 case UNGT_EXPR:
03436 case UNGE_EXPR:
03437 case UNEQ_EXPR:
03438 case LTGT_EXPR:
03439 case PLUS_EXPR:
03440 case MINUS_EXPR:
03441 case MULT_EXPR:
03442 case TRUNC_DIV_EXPR:
03443 case CEIL_DIV_EXPR:
03444 case FLOOR_DIV_EXPR:
03445 case ROUND_DIV_EXPR:
03446 case TRUNC_MOD_EXPR:
03447 case CEIL_MOD_EXPR:
03448 case FLOOR_MOD_EXPR:
03449 case ROUND_MOD_EXPR:
03450 case RDIV_EXPR:
03451 case EXACT_DIV_EXPR:
03452 case MIN_EXPR:
03453 case MAX_EXPR:
03454 case LSHIFT_EXPR:
03455 case RSHIFT_EXPR:
03456 case LROTATE_EXPR:
03457 case RROTATE_EXPR:
03458 case BIT_IOR_EXPR:
03459 case BIT_XOR_EXPR:
03460 case BIT_AND_EXPR:
03461 CHECK_OP (0, "Invalid operand to binary operator");
03462 CHECK_OP (1, "Invalid operand to binary operator");
03463 break;
03464
03465 default:
03466 break;
03467 }
03468 return NULL;
03469
03470 #undef CHECK_OP
03471 }
03472
03473
03474
03475
03476
03477 static bool
03478 verify_stmt (tree stmt, bool last_in_block)
03479 {
03480 tree addr;
03481
03482 if (!is_gimple_stmt (stmt))
03483 {
03484 error ("Is not a valid GIMPLE statement.");
03485 goto fail;
03486 }
03487
03488 addr = walk_tree (&stmt, verify_expr, NULL, NULL);
03489 if (addr)
03490 {
03491 debug_generic_stmt (addr);
03492 return true;
03493 }
03494
03495
03496
03497
03498
03499
03500 if (lookup_stmt_eh_region (stmt) >= 0)
03501 {
03502 if (!tree_could_throw_p (stmt))
03503 {
03504 error ("Statement marked for throw, but doesn%'t.");
03505 goto fail;
03506 }
03507 if (!last_in_block && tree_can_throw_internal (stmt))
03508 {
03509 error ("Statement marked for throw in middle of block.");
03510 goto fail;
03511 }
03512 }
03513
03514 return false;
03515
03516 fail:
03517 debug_generic_stmt (stmt);
03518 return true;
03519 }
03520
03521
03522
03523
03524 static bool
03525 tree_node_can_be_shared (tree t)
03526 {
03527 if (IS_TYPE_OR_DECL_P (t)
03528
03529
03530 || CONSTANT_CLASS_P (t)
03531 || is_gimple_min_invariant (t)
03532 || TREE_CODE (t) == SSA_NAME
03533 || t == error_mark_node)
03534 return true;
03535
03536 if (TREE_CODE (t) == CASE_LABEL_EXPR)
03537 return true;
03538
03539 while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
03540
03541
03542 && (CONSTANT_CLASS_P (TREE_OPERAND (t, 1))
03543 || is_gimple_min_invariant (TREE_OPERAND (t, 1))))
03544 || (TREE_CODE (t) == COMPONENT_REF
03545 || TREE_CODE (t) == REALPART_EXPR
03546 || TREE_CODE (t) == IMAGPART_EXPR))
03547 t = TREE_OPERAND (t, 0);
03548
03549 if (DECL_P (t))
03550 return true;
03551
03552 return false;
03553 }
03554
03555
03556
03557
03558 static tree
03559 verify_node_sharing (tree * tp, int *walk_subtrees, void *data)
03560 {
03561 htab_t htab = (htab_t) data;
03562 void **slot;
03563
03564 if (tree_node_can_be_shared (*tp))
03565 {
03566 *walk_subtrees = false;
03567 return NULL;
03568 }
03569
03570 slot = htab_find_slot (htab, *tp, INSERT);
03571 if (*slot)
03572 return *slot;
03573 *slot = *tp;
03574
03575 return NULL;
03576 }
03577
03578
03579
03580
03581 void
03582 verify_stmts (void)
03583 {
03584 basic_block bb;
03585 block_stmt_iterator bsi;
03586 bool err = false;
03587 htab_t htab;
03588 tree addr;
03589
03590 timevar_push (TV_TREE_STMT_VERIFY);
03591 htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
03592
03593 FOR_EACH_BB (bb)
03594 {
03595 tree phi;
03596 int i;
03597
03598 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
03599 {
03600 int phi_num_args = PHI_NUM_ARGS (phi);
03601
03602 for (i = 0; i < phi_num_args; i++)
03603 {
03604 tree t = PHI_ARG_DEF (phi, i);
03605 tree addr;
03606
03607
03608
03609 if (TREE_CODE (t) != SSA_NAME
03610 && TREE_CODE (t) != FUNCTION_DECL
03611 && !is_gimple_val (t))
03612 {
03613 error ("PHI def is not a GIMPLE value");
03614 debug_generic_stmt (phi);
03615 debug_generic_stmt (t);
03616 err |= true;
03617 }
03618
03619 addr = walk_tree (&t, verify_expr, (void *) 1, NULL);
03620 if (addr)
03621 {
03622 debug_generic_stmt (addr);
03623 err |= true;
03624 }
03625
03626 addr = walk_tree (&t, verify_node_sharing, htab, NULL);
03627 if (addr)
03628 {
03629 error ("Incorrect sharing of tree nodes");
03630 debug_generic_stmt (phi);
03631 debug_generic_stmt (addr);
03632 err |= true;
03633 }
03634 }
03635 }
03636
03637 for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
03638 {
03639 tree stmt = bsi_stmt (bsi);
03640 bsi_next (&bsi);
03641 err |= verify_stmt (stmt, bsi_end_p (bsi));
03642 addr = walk_tree (&stmt, verify_node_sharing, htab, NULL);
03643 if (addr)
03644 {
03645 error ("Incorrect sharing of tree nodes");
03646 debug_generic_stmt (stmt);
03647 debug_generic_stmt (addr);
03648 err |= true;
03649 }
03650 }
03651 }
03652
03653 if (err)
03654 internal_error ("verify_stmts failed.");
03655
03656 htab_delete (htab);
03657 timevar_pop (TV_TREE_STMT_VERIFY);
03658 }
03659
03660
03661
03662
03663 static int
03664 tree_verify_flow_info (void)
03665 {
03666 int err = 0;
03667 basic_block bb;
03668 block_stmt_iterator bsi;
03669 tree stmt;
03670 edge e;
03671 edge_iterator ei;
03672
03673 if (ENTRY_BLOCK_PTR->stmt_list)
03674 {
03675 error ("ENTRY_BLOCK has a statement list associated with it\n");
03676 err = 1;
03677 }
03678
03679 if (EXIT_BLOCK_PTR->stmt_list)
03680 {
03681 error ("EXIT_BLOCK has a statement list associated with it\n");
03682 err = 1;
03683 }
03684
03685 FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
03686 if (e->flags & EDGE_FALLTHRU)
03687 {
03688 error ("Fallthru to exit from bb %d\n", e->src->index);
03689 err = 1;
03690 }
03691
03692 FOR_EACH_BB (bb)
03693 {
03694 bool found_ctrl_stmt = false;
03695
03696 stmt = NULL_TREE;
03697
03698
03699 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
03700 {
03701 tree prev_stmt = stmt;
03702
03703 stmt = bsi_stmt (bsi);
03704
03705 if (TREE_CODE (stmt) != LABEL_EXPR)
03706 break;
03707
03708 if (prev_stmt && DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
03709 {
03710 error ("Nonlocal label %s is not first "
03711 "in a sequence of labels in bb %d",
03712 IDENTIFIER_POINTER (DECL_NAME (LABEL_EXPR_LABEL (stmt))),
03713 bb->index);
03714 err = 1;
03715 }
03716
03717 if (label_to_block (LABEL_EXPR_LABEL (stmt)) != bb)
03718 {
03719 error ("Label %s to block does not match in bb %d\n",
03720 IDENTIFIER_POINTER (DECL_NAME (LABEL_EXPR_LABEL (stmt))),
03721 bb->index);
03722 err = 1;
03723 }
03724
03725 if (decl_function_context (LABEL_EXPR_LABEL (stmt))
03726 != current_function_decl)
03727 {
03728 error ("Label %s has incorrect context in bb %d\n",
03729 IDENTIFIER_POINTER (DECL_NAME (LABEL_EXPR_LABEL (stmt))),
03730 bb->index);
03731 err = 1;
03732 }
03733 }
03734
03735
03736 for (; !bsi_end_p (bsi); bsi_next (&bsi))
03737 {
03738 tree stmt = bsi_stmt (bsi);
03739
03740 if (found_ctrl_stmt)
03741 {
03742 error ("Control flow in the middle of basic block %d\n",
03743 bb->index);
03744 err = 1;
03745 }
03746
03747 if (stmt_ends_bb_p (stmt))
03748 found_ctrl_stmt = true;
03749
03750 if (TREE_CODE (stmt) == LABEL_EXPR)
03751 {
03752 error ("Label %s in the middle of basic block %d\n",
03753 IDENTIFIER_POINTER (DECL_NAME (stmt)),
03754 bb->index);
03755 err = 1;
03756 }
03757 }
03758 bsi = bsi_last (bb);
03759 if (bsi_end_p (bsi))
03760 continue;
03761
03762 stmt = bsi_stmt (bsi);
03763
03764 if (is_ctrl_stmt (stmt))
03765 {
03766 FOR_EACH_EDGE (e, ei, bb->succs)
03767 if (e->flags & EDGE_FALLTHRU)
03768 {
03769 error ("Fallthru edge after a control statement in bb %d \n",
03770 bb->index);
03771 err = 1;
03772 }
03773 }
03774
03775 switch (TREE_CODE (stmt))
03776 {
03777 case COND_EXPR:
03778 {
03779 edge true_edge;
03780 edge false_edge;
03781 if (TREE_CODE (COND_EXPR_THEN (stmt)) != GOTO_EXPR
03782 || TREE_CODE (COND_EXPR_ELSE (stmt)) != GOTO_EXPR)
03783 {
03784 error ("Structured COND_EXPR at the end of bb %d\n", bb->index);
03785 err = 1;
03786 }
03787
03788 extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
03789
03790 if (!true_edge || !false_edge
03791 || !(true_edge->flags & EDGE_TRUE_VALUE)
03792 || !(false_edge->flags & EDGE_FALSE_VALUE)
03793 || (true_edge->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL))
03794 || (false_edge->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL))
03795 || EDGE_COUNT (bb->succs) >= 3)
03796 {
03797 error ("Wrong outgoing edge flags at end of bb %d\n",
03798 bb->index);
03799 err = 1;
03800 }
03801
03802 if (!has_label_p (true_edge->dest,
03803 GOTO_DESTINATION (COND_EXPR_THEN (stmt))))
03804 {
03805 error ("%<then%> label does not match edge at end of bb %d\n",
03806 bb->index);
03807 err = 1;
03808 }
03809
03810 if (!has_label_p (false_edge->dest,
03811 GOTO_DESTINATION (COND_EXPR_ELSE (stmt))))
03812 {
03813 error ("%<else%> label does not match edge at end of bb %d\n",
03814 bb->index);
03815 err = 1;
03816 }
03817 }
03818 break;
03819
03820 case GOTO_EXPR:
03821 if (simple_goto_p (stmt))
03822 {
03823 error ("Explicit goto at end of bb %d\n", bb->index);
03824 err = 1;
03825 }
03826 else
03827 {
03828
03829
03830 FOR_EACH_EDGE (e, ei, bb->succs)
03831 if ((e->flags & (EDGE_FALLTHRU | EDGE_TRUE_VALUE
03832 | EDGE_FALSE_VALUE))
03833 || !(e->flags & EDGE_ABNORMAL))
03834 {
03835 error ("Wrong outgoing edge flags at end of bb %d\n",
03836 bb->index);
03837 err = 1;
03838 }
03839 }
03840 break;
03841
03842 case RETURN_EXPR:
03843 if (EDGE_COUNT (bb->succs) != 1
03844 || (EDGE_SUCC (bb, 0)->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL
03845 | EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
03846 {
03847 error ("Wrong outgoing edge flags at end of bb %d\n", bb->index);
03848 err = 1;
03849 }
03850 if (EDGE_SUCC (bb, 0)->dest != EXIT_BLOCK_PTR)
03851 {
03852 error ("Return edge does not point to exit in bb %d\n",
03853 bb->index);
03854 err = 1;
03855 }
03856 break;
03857
03858 case SWITCH_EXPR:
03859 {
03860 tree prev;
03861 edge e;
03862 size_t i, n;
03863 tree vec;
03864
03865 vec = SWITCH_LABELS (stmt);
03866 n = TREE_VEC_LENGTH (vec);
03867
03868
03869 for (i = 0; i < n; ++i)
03870 {
03871 tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
03872 basic_block label_bb = label_to_block (lab);
03873
03874 gcc_assert (!label_bb->aux || label_bb->aux == (void *)1);
03875 label_bb->aux = (void *)1;
03876 }
03877
03878
03879 prev = TREE_VEC_ELT (vec, 0);
03880 for (i = 1; i < n - 1; ++i)
03881 {
03882 tree c = TREE_VEC_ELT (vec, i);
03883 if (! CASE_LOW (c))
03884 {
03885 error ("Found default case not at end of case vector");
03886 err = 1;
03887 continue;
03888 }
03889 if (! tree_int_cst_lt (CASE_LOW (prev), CASE_LOW (c)))
03890 {
03891 error ("Case labels not sorted:\n ");
03892 print_generic_expr (stderr, prev, 0);
03893 fprintf (stderr," is greater than ");
03894 print_generic_expr (stderr, c, 0);
03895 fprintf (stderr," but comes before it.\n");
03896 err = 1;
03897 }
03898 prev = c;
03899 }
03900 if (CASE_LOW (TREE_VEC_ELT (vec, n - 1)))
03901 {
03902 error ("No default case found at end of case vector");
03903 err = 1;
03904 }
03905
03906 FOR_EACH_EDGE (e, ei, bb->succs)
03907 {
03908 if (!e->dest->aux)
03909 {
03910 error ("Extra outgoing edge %d->%d\n",
03911 bb->index, e->dest->index);
03912 err = 1;
03913 }
03914 e->dest->aux = (void *)2;
03915 if ((e->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL
03916 | EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
03917 {
03918 error ("Wrong outgoing edge flags at end of bb %d\n",
03919 bb->index);
03920 err = 1;
03921 }
03922 }
03923
03924
03925 for (i = 0; i < n; ++i)
03926 {
03927 tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
03928 basic_block label_bb = label_to_block (lab);
03929
03930 if (label_bb->aux != (void *)2)
03931 {
03932 error ("Missing edge %i->%i",
03933 bb->index, label_bb->index);
03934 err = 1;
03935 }
03936 }
03937
03938 FOR_EACH_EDGE (e, ei, bb->succs)
03939 e->dest->aux = (void *)0;
03940 }
03941
03942 default: ;
03943 }
03944 }
03945
03946 if (dom_computed[CDI_DOMINATORS] >= DOM_NO_FAST_QUERY)
03947 verify_dominators (CDI_DOMINATORS);
03948
03949 return err;
03950 }
03951
03952
03953
03954
03955
03956 static void
03957 tree_make_forwarder_block (edge fallthru)
03958 {
03959 edge e;
03960 edge_iterator ei;
03961 basic_block dummy, bb;
03962 tree phi, new_phi, var;
03963
03964 dummy = fallthru->src;
03965 bb = fallthru->dest;
03966
03967 if (EDGE_COUNT (bb->preds) == 1)
03968 return;
03969
03970
03971
03972 for (phi = phi_nodes (dummy); phi; phi = PHI_CHAIN (phi))
03973 {
03974 var = PHI_RESULT (phi);
03975 new_phi = create_phi_node (var, bb);
03976 SSA_NAME_DEF_STMT (var) = new_phi;
03977 SET_PHI_RESULT (phi, make_ssa_name (SSA_NAME_VAR (var), phi));
03978 add_phi_arg (new_phi, PHI_RESULT (phi), fallthru);
03979 }
03980
03981
03982 set_phi_nodes (bb, phi_reverse (phi_nodes (bb)));
03983
03984
03985 FOR_EACH_EDGE (e, ei, bb->preds)
03986 {
03987 if (e == fallthru)
03988 continue;
03989
03990 flush_pending_stmts (e);
03991 }
03992 }
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002 static bool
04003 tree_forwarder_block_p (basic_block bb, bool phi_wanted)
04004 {
04005 block_stmt_iterator bsi;
04006
04007
04008 if (EDGE_COUNT (bb->succs) != 1
04009
04010
04011 || (phi_nodes (bb) != NULL_TREE) != phi_wanted
04012
04013 || EDGE_SUCC (bb, 0)->dest == EXIT_BLOCK_PTR
04014
04015 || EDGE_SUCC (bb, 0)->dest == bb
04016
04017 || (EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL))
04018 return false;
04019
04020 #if ENABLE_CHECKING
04021 gcc_assert (bb != ENTRY_BLOCK_PTR);
04022 #endif
04023
04024
04025
04026 for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_next (&bsi))
04027 {
04028 tree stmt = bsi_stmt (bsi);
04029
04030 switch (TREE_CODE (stmt))
04031 {
04032 case LABEL_EXPR:
04033 if (DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
04034 return false;
04035 break;
04036
04037 default:
04038 return false;
04039 }
04040 }
04041
04042 if (find_edge (ENTRY_BLOCK_PTR, bb))
04043 return false;
04044
04045 return true;
04046 }
04047
04048
04049
04050 static inline bool
04051 has_abnormal_incoming_edge_p (basic_block bb)
04052 {
04053 edge e;
04054 edge_iterator ei;
04055
04056 FOR_EACH_EDGE (e, ei, bb->preds)
04057 if (e->flags & EDGE_ABNORMAL)
04058 return true;
04059
04060 return false;
04061 }
04062
04063
04064
04065
04066
04067 static bool
04068 remove_forwarder_block (basic_block bb, basic_block **worklist)
04069 {
04070 edge succ = EDGE_SUCC (bb, 0), e, s;
04071 basic_block dest = succ->dest;
04072 tree label;
04073 tree phi;
04074 edge_iterator ei;
04075 block_stmt_iterator bsi, bsi_to;
04076 bool seen_abnormal_edge = false;
04077
04078
04079
04080
04081 if (dest == bb)
04082 return false;
04083
04084
04085
04086 label = first_stmt (dest);
04087 if (label
04088 && TREE_CODE (label) == LABEL_EXPR
04089 && DECL_NONLOCAL (LABEL_EXPR_LABEL (label)))
04090 return false;
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103 if (has_abnormal_incoming_edge_p (bb))
04104 {
04105 seen_abnormal_edge = true;
04106
04107 if (has_abnormal_incoming_edge_p (dest)
04108 || phi_nodes (dest) != NULL_TREE)
04109 return false;
04110 }
04111
04112
04113
04114
04115 if (phi_nodes (dest))
04116 {
04117 FOR_EACH_EDGE (e, ei, bb->preds)
04118 {
04119 s = find_edge (e->src, dest);
04120 if (!s)
04121 continue;
04122
04123 if (!phi_alternatives_equal (dest, succ, s))
04124 return false;
04125 }
04126 }
04127
04128
04129 for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
04130 {
04131 if (e->flags & EDGE_ABNORMAL)
04132 {
04133
04134
04135 s = redirect_edge_succ_nodup (e, dest);
04136 }
04137 else
04138 s = redirect_edge_and_branch (e, dest);
04139
04140 if (s == e)
04141 {
04142
04143
04144 for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
04145 add_phi_arg (phi, PHI_ARG_DEF (phi, succ->dest_idx), s);
04146 }
04147 else
04148 {
04149
04150
04151
04152
04153 if (tree_forwarder_block_p (s->src, false))
04154 *(*worklist)++ = s->src;
04155 }
04156 }
04157
04158 if (seen_abnormal_edge)
04159 {
04160
04161
04162
04163 bsi_to = bsi_start (dest);
04164 for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
04165 {
04166 label = bsi_stmt (bsi);
04167 gcc_assert (TREE_CODE (label) == LABEL_EXPR);
04168 bsi_remove (&bsi);
04169 bsi_insert_before (&bsi_to, label, BSI_CONTINUE_LINKING);
04170 }
04171 }
04172
04173
04174 if (dom_info_available_p (CDI_DOMINATORS))
04175 {
04176 basic_block dom, dombb, domdest;
04177
04178 dombb = get_immediate_dominator (CDI_DOMINATORS, bb);
04179 domdest = get_immediate_dominator (CDI_DOMINATORS, dest);
04180 if (domdest == bb)
04181 {
04182
04183
04184 dom = dombb;
04185 }
04186 else
04187 dom = nearest_common_dominator (CDI_DOMINATORS, domdest, dombb);
04188
04189 set_immediate_dominator (CDI_DOMINATORS, dest, dom);
04190 }
04191
04192
04193 delete_basic_block (bb);
04194
04195 return true;
04196 }
04197
04198
04199
04200 static bool
04201 cleanup_forwarder_blocks (void)
04202 {
04203 basic_block bb;
04204 bool changed = false;
04205 basic_block *worklist = xmalloc (sizeof (basic_block) * n_basic_blocks);
04206 basic_block *current = worklist;
04207
04208 FOR_EACH_BB (bb)
04209 {
04210 if (tree_forwarder_block_p (bb, false))
04211 *current++ = bb;
04212 }
04213
04214 while (current != worklist)
04215 {
04216 bb = *--current;
04217 changed |= remove_forwarder_block (bb, ¤t);
04218 }
04219
04220 free (worklist);
04221 return changed;
04222 }
04223
04224
04225
04226 static void
04227 remove_forwarder_block_with_phi (basic_block bb)
04228 {
04229 edge succ = EDGE_SUCC (bb, 0);
04230 basic_block dest = succ->dest;
04231 tree label;
04232 basic_block dombb, domdest, dom;
04233
04234
04235
04236
04237 if (dest == bb)
04238 return;
04239
04240
04241
04242 label = first_stmt (dest);
04243 if (label
04244 && TREE_CODE (label) == LABEL_EXPR
04245 && DECL_NONLOCAL (LABEL_EXPR_LABEL (label)))
04246 return;
04247
04248
04249 while (EDGE_COUNT (bb->preds) > 0)
04250 {
04251 edge e = EDGE_PRED (bb, 0), s;
04252 tree phi;
04253
04254 s = find_edge (e->src, dest);
04255 if (s)
04256 {
04257
04258
04259
04260 if (phi_alternatives_equal (dest, s, succ))
04261 {
04262 e = redirect_edge_and_branch (e, dest);
04263 PENDING_STMT (e) = NULL_TREE;
04264 continue;
04265 }
04266
04267
04268
04269
04270 e = EDGE_SUCC (split_edge (e), 0);
04271 }
04272
04273 s = redirect_edge_and_branch (e, dest);
04274
04275
04276 gcc_assert (s == e);
04277
04278
04279
04280 for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
04281 {
04282 tree def = PHI_ARG_DEF (phi, succ->dest_idx);
04283
04284 if (TREE_CODE (def) == SSA_NAME)
04285 {
04286 tree var;
04287
04288
04289
04290
04291 for (var = PENDING_STMT (e); var; var = TREE_CHAIN (var))
04292 {
04293 tree old_arg = TREE_PURPOSE (var);
04294 tree new_arg = TREE_VALUE (var);
04295
04296 if (def == old_arg)
04297 {
04298 def = new_arg;
04299 break;
04300 }
04301 }
04302 }
04303
04304 add_phi_arg (phi, def, s);
04305 }
04306
04307 PENDING_STMT (e) = NULL;
04308 }
04309
04310
04311 dombb = get_immediate_dominator (CDI_DOMINATORS, bb);
04312 domdest = get_immediate_dominator (CDI_DOMINATORS, dest);
04313 if (domdest == bb)
04314 {
04315
04316
04317 dom = dombb;
04318 }
04319 else
04320 dom = nearest_common_dominator (CDI_DOMINATORS, domdest, dombb);
04321
04322 set_immediate_dominator (CDI_DOMINATORS, dest, dom);
04323
04324
04325
04326 delete_basic_block (bb);
04327 }
04328
04329
04330
04331
04332
04333
04334
04335
04336
04337
04338
04339
04340
04341
04342
04343
04344
04345
04346
04347
04348
04349
04350
04351
04352
04353
04354 static void
04355 merge_phi_nodes (void)
04356 {
04357 basic_block *worklist = xmalloc (sizeof (basic_block) * n_basic_blocks);
04358 basic_block *current = worklist;
04359 basic_block bb;
04360
04361 calculate_dominance_info (CDI_DOMINATORS);
04362
04363
04364 FOR_EACH_BB (bb)
04365 {
04366 basic_block dest;
04367
04368
04369 if (!tree_forwarder_block_p (bb, true))
04370 continue;
04371
04372 dest = EDGE_SUCC (bb, 0)->dest;
04373
04374
04375
04376 if (!phi_nodes (dest)
04377
04378
04379 || has_abnormal_incoming_edge_p (bb))
04380 continue;
04381
04382 if (!dominated_by_p (CDI_DOMINATORS, dest, bb))
04383 {
04384
04385
04386
04387 *current++ = bb;
04388 }
04389 }
04390
04391
04392 while (current != worklist)
04393 {
04394 bb = *--current;
04395 remove_forwarder_block_with_phi (bb);
04396 }
04397
04398 free (worklist);
04399 }
04400
04401 static bool
04402 gate_merge_phi (void)
04403 {
04404 return 1;
04405 }
04406
04407 struct tree_opt_pass pass_merge_phi = {
04408 "mergephi",
04409 gate_merge_phi,
04410 merge_phi_nodes,
04411 NULL,
04412 NULL,
04413 0,
04414 TV_TREE_MERGE_PHI,
04415 PROP_cfg | PROP_ssa,
04416 0,
04417 0,
04418 0,
04419 TODO_dump_func | TODO_ggc_collect
04420 | TODO_verify_ssa,
04421 0
04422 };
04423
04424
04425
04426
04427 tree
04428 tree_block_label (basic_block bb)
04429 {
04430 block_stmt_iterator i, s = bsi_start (bb);
04431 bool first = true;
04432 tree label, stmt;
04433
04434 for (i = s; !bsi_end_p (i); first = false, bsi_next (&i))
04435 {
04436 stmt = bsi_stmt (i);
04437 if (TREE_CODE (stmt) != LABEL_EXPR)
04438 break;
04439 label = LABEL_EXPR_LABEL (stmt);
04440 if (!DECL_NONLOCAL (label))
04441 {
04442 if (!first)
04443 bsi_move_before (&i, &s);
04444 return label;
04445 }
04446 }
04447
04448 label = create_artificial_label ();
04449 stmt = build1 (LABEL_EXPR, void_type_node, label);
04450 bsi_insert_before (&s, stmt, BSI_NEW_STMT);
04451 return label;
04452 }
04453
04454
04455
04456
04457
04458
04459
04460
04461 static edge
04462 tree_try_redirect_by_replacing_jump (edge e, basic_block target)
04463 {
04464 basic_block src = e->src;
04465 block_stmt_iterator b;
04466 tree stmt;
04467
04468
04469
04470 if (EDGE_COUNT (src->succs) != 2
04471
04472
04473 || EDGE_SUCC (src, EDGE_SUCC (src, 0) == e)->dest != target)
04474 return NULL;
04475
04476 b = bsi_last (src);
04477 if (bsi_end_p (b))
04478 return NULL;
04479 stmt = bsi_stmt (b);
04480
04481 if (TREE_CODE (stmt) == COND_EXPR
04482 || TREE_CODE (stmt) == SWITCH_EXPR)
04483 {
04484 bsi_remove (&b);
04485 e = ssa_redirect_edge (e, target);
04486 e->flags = EDGE_FALLTHRU;
04487 return e;
04488 }
04489
04490 return NULL;
04491 }
04492
04493
04494
04495
04496
04497 static edge
04498 tree_redirect_edge_and_branch (edge e, basic_block dest)
04499 {
04500 basic_block bb = e->src;
04501 block_stmt_iterator bsi;
04502 edge ret;
04503 tree label, stmt;
04504
04505 if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
04506 return NULL;
04507
04508 if (e->src != ENTRY_BLOCK_PTR
04509 && (ret = tree_try_redirect_by_replacing_jump (e, dest)))
04510 return ret;
04511
04512 if (e->dest == dest)
04513 return NULL;
04514
04515 label = tree_block_label (dest);
04516
04517 bsi = bsi_last (bb);
04518 stmt = bsi_end_p (bsi) ? NULL : bsi_stmt (bsi);
04519
04520 switch (stmt ? TREE_CODE (stmt) : ERROR_MARK)
04521 {
04522 case COND_EXPR:
04523 stmt = (e->flags & EDGE_TRUE_VALUE
04524 ? COND_EXPR_THEN (stmt)
04525 : COND_EXPR_ELSE (stmt));
04526 GOTO_DESTINATION (stmt) = label;
04527 break;
04528
04529 case GOTO_EXPR:
04530
04531
04532 gcc_unreachable ();
04533
04534 case SWITCH_EXPR:
04535 {
04536 tree cases = get_cases_for_edge (e, stmt);
04537
04538
04539
04540 if (cases)
04541 {
04542 edge e2 = find_edge (e->src, dest);
04543 tree last, first;
04544
04545 first = cases;
04546 while (cases)
04547 {
04548 last = cases;
04549 CASE_LABEL (cases) = label;
04550 cases = TREE_CHAIN (cases);
04551 }
04552
04553
04554
04555 if (e2)
04556 {
04557 tree cases2 = get_cases_for_edge (e2, stmt);
04558
04559 TREE_CHAIN (last) = TREE_CHAIN (cases2);
04560 TREE_CHAIN (cases2) = first;
04561 }
04562 }
04563 else
04564 {
04565 tree vec = SWITCH_LABELS (stmt);
04566 size_t i, n = TREE_VEC_LENGTH (vec);
04567
04568 for (i = 0; i < n; i++)
04569 {
04570 tree elt = TREE_VEC_ELT (vec, i);
04571
04572 if (label_to_block (CASE_LABEL (elt)) == e->dest)
04573 CASE_LABEL (elt) = label;
04574 }
04575 }
04576
04577 break;
04578 }
04579
04580 case RETURN_EXPR:
04581 bsi_remove (&bsi);
04582 e->flags |= EDGE_FALLTHRU;
04583 break;
04584
04585 default:
04586
04587
04588 gcc_assert (e->flags & EDGE_FALLTHRU);
04589 break;
04590 }
04591
04592
04593
04594
04595 e = ssa_redirect_edge (e, dest);
04596
04597 return e;
04598 }
04599
04600
04601
04602
04603 static basic_block
04604 tree_redirect_edge_and_branch_force (edge e, basic_block dest)
04605 {
04606 e = tree_redirect_edge_and_branch (e, dest);
04607 gcc_assert (e);
04608
04609 return NULL;
04610 }
04611
04612
04613
04614
04615
04616 static basic_block
04617 tree_split_block (basic_block bb, void *stmt)
04618 {
04619 block_stmt_iterator bsi, bsi_tgt;
04620 tree act;
04621 basic_block new_bb;
04622 edge e;
04623 edge_iterator ei;
04624
04625 new_bb = create_empty_bb (bb);
04626
04627
04628 new_bb->succs = bb->succs;
04629 bb->succs = NULL;
04630 FOR_EACH_EDGE (e, ei, new_bb->succs)
04631 e->src = new_bb;
04632
04633 if (stmt && TREE_CODE ((tree) stmt) == LABEL_EXPR)
04634 stmt = NULL;
04635
04636
04637 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
04638 {
04639 act = bsi_stmt (bsi);
04640 if (TREE_CODE (act) == LABEL_EXPR)
04641 continue;
04642
04643 if (!stmt)
04644 break;
04645
04646 if (stmt == act)
04647 {
04648 bsi_next (&bsi);
04649 break;
04650 }
04651 }
04652
04653 bsi_tgt = bsi_start (new_bb);
04654 while (!bsi_end_p (bsi))
04655 {
04656 act = bsi_stmt (bsi);
04657 bsi_remove (&bsi);
04658 bsi_insert_after (&bsi_tgt, act, BSI_NEW_STMT);
04659 }
04660
04661 return new_bb;
04662 }
04663
04664
04665
04666
04667 static bool
04668 tree_move_block_after (basic_block bb, basic_block after)
04669 {
04670 if (bb->prev_bb == after)
04671 return true;
04672
04673 unlink_block (bb);
04674 link_block (bb, after);
04675
04676 return true;
04677 }
04678
04679
04680
04681
04682 static bool
04683 tree_can_duplicate_bb_p (basic_block bb ATTRIBUTE_UNUSED)
04684 {
04685 return true;
04686 }
04687
04688
04689
04690
04691 static basic_block
04692 tree_duplicate_bb (basic_block bb)
04693 {
04694 basic_block new_bb;
04695 block_stmt_iterator bsi, bsi_tgt;
04696 tree phi, val;
04697 ssa_op_iter op_iter;
04698
04699 new_bb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
04700
04701
04702
04703
04704 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
04705 {
04706 mark_for_rewrite (PHI_RESULT (phi));
04707 create_phi_node (PHI_RESULT (phi), new_bb);
04708 }
04709 set_phi_nodes (new_bb, phi_reverse (phi_nodes (new_bb)));
04710
04711 bsi_tgt = bsi_start (new_bb);
04712 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
04713 {
04714 tree stmt = bsi_stmt (bsi);
04715 tree copy;
04716
04717 if (TREE_CODE (stmt) == LABEL_EXPR)
04718 continue;
04719
04720
04721 get_stmt_operands (stmt);
04722
04723 FOR_EACH_SSA_TREE_OPERAND (val, stmt, op_iter, SSA_OP_ALL_DEFS)
04724 mark_for_rewrite (val);
04725
04726 copy = unshare_expr (stmt);
04727
04728
04729 get_stmt_ann (copy);
04730 copy_virtual_operands (copy, stmt);
04731
04732 bsi_insert_after (&bsi_tgt, copy, BSI_NEW_STMT);
04733 }
04734
04735 return new_bb;
04736 }
04737
04738
04739
04740
04741
04742 void
04743 add_phi_args_after_copy_bb (basic_block bb_copy)
04744 {
04745 basic_block bb, dest;
04746 edge e, e_copy;
04747 edge_iterator ei;
04748 tree phi, phi_copy, phi_next, def;
04749
04750 bb = bb_copy->rbi->original;
04751
04752 FOR_EACH_EDGE (e_copy, ei, bb_copy->succs)
04753 {
04754 if (!phi_nodes (e_copy->dest))
04755 continue;
04756
04757 if (e_copy->dest->rbi->duplicated)
04758 dest = e_copy->dest->rbi->original;
04759 else
04760 dest = e_copy->dest;
04761
04762 e = find_edge (bb, dest);
04763 if (!e)
04764 {
04765
04766
04767
04768 FOR_EACH_EDGE (e, ei, bb->succs)
04769 if (e->dest->rbi->duplicated
04770 && e->dest->rbi->original == dest)
04771 break;
04772
04773 gcc_assert (e != NULL);
04774 }
04775
04776 for (phi = phi_nodes (e->dest), phi_copy = phi_nodes (e_copy->dest);
04777 phi;
04778 phi = phi_next, phi_copy = PHI_CHAIN (phi_copy))
04779 {
04780 phi_next = PHI_CHAIN (phi);
04781
04782 gcc_assert (PHI_RESULT (phi) == PHI_RESULT (phi_copy));
04783 def = PHI_ARG_DEF_FROM_EDGE (phi, e);
04784 add_phi_arg (phi_copy, def, e_copy);
04785 }
04786 }
04787 }
04788
04789
04790
04791
04792
04793 void
04794 add_phi_args_after_copy (basic_block *region_copy, unsigned n_region)
04795 {
04796 unsigned i;
04797
04798 for (i = 0; i < n_region; i++)
04799 region_copy[i]->rbi->duplicated = 1;
04800
04801 for (i = 0; i < n_region; i++)
04802 add_phi_args_after_copy_bb (region_copy[i]);
04803
04804 for (i = 0; i < n_region; i++)
04805 region_copy[i]->rbi->duplicated = 0;
04806 }
04807
04808
04809
04810 struct ssa_name_map_entry
04811 {
04812 tree from_name;
04813 tree to_name;
04814 };
04815
04816
04817
04818 static hashval_t
04819 ssa_name_map_entry_hash (const void *entry)
04820 {
04821 const struct ssa_name_map_entry *en = entry;
04822 return SSA_NAME_VERSION (en->from_name);
04823 }
04824
04825
04826
04827 static int
04828 ssa_name_map_entry_eq (const void *in_table, const void *ssa_name)
04829 {
04830 const struct ssa_name_map_entry *en = in_table;
04831
04832 return en->from_name == ssa_name;
04833 }
04834
04835
04836
04837
04838 void
04839 allocate_ssa_names (bitmap definitions, htab_t *map)
04840 {
04841 tree name;
04842 struct ssa_name_map_entry *entry;
04843 PTR *slot;
04844 unsigned ver;
04845 bitmap_iterator bi;
04846
04847 if (!*map)
04848 *map = htab_create (10, ssa_name_map_entry_hash,
04849 ssa_name_map_entry_eq, free);
04850 EXECUTE_IF_SET_IN_BITMAP (definitions, 0, ver, bi)
04851 {
04852 name = ssa_name (ver);
04853 slot = htab_find_slot_with_hash (*map, name, SSA_NAME_VERSION (name),
04854 INSERT);
04855 if (*slot)
04856 entry = *slot;
04857 else
04858 {
04859 entry = xmalloc (sizeof (struct ssa_name_map_entry));
04860 entry->from_name = name;
04861 *slot = entry;
04862 }
04863 entry->to_name = duplicate_ssa_name (name, SSA_NAME_DEF_STMT (name));
04864 }
04865 }
04866
04867
04868
04869
04870 static void
04871 rewrite_to_new_ssa_names_def (def_operand_p def, tree stmt, htab_t map)
04872 {
04873 tree name = DEF_FROM_PTR (def);
04874 struct ssa_name_map_entry *entry;
04875
04876 gcc_assert (TREE_CODE (name) == SSA_NAME);
04877
04878 entry = htab_find_with_hash (map, name, SSA_NAME_VERSION (name));
04879 if (!entry)
04880 return;
04881
04882 SET_DEF (def, entry->to_name);
04883 SSA_NAME_DEF_STMT (entry->to_name) = stmt;
04884 }
04885
04886
04887
04888 static void
04889 rewrite_to_new_ssa_names_use (use_operand_p use, htab_t map)
04890 {
04891 tree name = USE_FROM_PTR (use);
04892 struct ssa_name_map_entry *entry;
04893
04894 if (TREE_CODE (name) != SSA_NAME)
04895 return;
04896
04897 entry = htab_find_with_hash (map, name, SSA_NAME_VERSION (name));
04898 if (!entry)
04899 return;
04900
04901 SET_USE (use, entry->to_name);
04902 }
04903
04904
04905
04906
04907 void
04908 rewrite_to_new_ssa_names_bb (basic_block bb, htab_t map)
04909 {
04910 unsigned i;
04911 edge e;
04912 edge_iterator ei;
04913 tree phi, stmt;
04914 block_stmt_iterator bsi;
04915 use_optype uses;
04916 vuse_optype vuses;
04917 def_optype defs;
04918 v_may_def_optype v_may_defs;
04919 v_must_def_optype v_must_defs;
04920 stmt_ann_t ann;
04921
04922 FOR_EACH_EDGE (e, ei, bb->preds)
04923 if (e->flags & EDGE_ABNORMAL)
04924 break;
04925
04926 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
04927 {
04928 rewrite_to_new_ssa_names_def (PHI_RESULT_PTR (phi), phi, map);
04929 if (e)
04930 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)) = 1;
04931 }
04932
04933 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
04934 {
04935 stmt = bsi_stmt (bsi);
04936 get_stmt_operands (stmt);
04937 ann = stmt_ann (stmt);
04938
04939 uses = USE_OPS (ann);
04940 for (i = 0; i < NUM_USES (uses); i++)
04941 rewrite_to_new_ssa_names_use (USE_OP_PTR (uses, i), map);
04942
04943 defs = DEF_OPS (ann);
04944 for (i = 0; i < NUM_DEFS (defs); i++)
04945 rewrite_to_new_ssa_names_def (DEF_OP_PTR (defs, i), stmt, map);
04946
04947 vuses = VUSE_OPS (ann);
04948 for (i = 0; i < NUM_VUSES (vuses); i++)
04949 rewrite_to_new_ssa_names_use (VUSE_OP_PTR (vuses, i), map);
04950
04951 v_may_defs = V_MAY_DEF_OPS (ann);
04952 for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
04953 {
04954 rewrite_to_new_ssa_names_use
04955 (V_MAY_DEF_OP_PTR (v_may_defs, i), map);
04956 rewrite_to_new_ssa_names_def
04957 (V_MAY_DEF_RESULT_PTR (v_may_defs, i), stmt, map);
04958 }
04959
04960 v_must_defs = V_MUST_DEF_OPS (ann);
04961 for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
04962 {
04963 rewrite_to_new_ssa_names_def
04964 (V_MUST_DEF_RESULT_PTR (v_must_defs, i), stmt, map);
04965 rewrite_to_new_ssa_names_use
04966 (V_MUST_DEF_KILL_PTR (v_must_defs, i), map);
04967 }
04968 }
04969
04970 FOR_EACH_EDGE (e, ei, bb->succs)
04971 for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
04972 {
04973 rewrite_to_new_ssa_names_use
04974 (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), map);
04975
04976 if (e->flags & EDGE_ABNORMAL)
04977 {
04978 tree op = PHI_ARG_DEF_FROM_EDGE (phi, e);
04979 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op) = 1;
04980 }
04981 }
04982 }
04983
04984
04985
04986
04987 void
04988 rewrite_to_new_ssa_names (basic_block *region, unsigned n_region, htab_t map)
04989 {
04990 unsigned r;
04991
04992 for (r = 0; r < n_region; r++)
04993 rewrite_to_new_ssa_names_bb (region[r], map);
04994 }
04995
04996
04997
04998
04999
05000
05001
05002
05003
05004
05005
05006 bool
05007 tree_duplicate_sese_region (edge entry, edge exit,
05008 basic_block *region, unsigned n_region,
05009 basic_block *region_copy)
05010 {
05011 unsigned i, n_doms, ver;
05012 bool free_region_copy = false, copying_header = false;
05013 struct loop *loop = entry->dest->loop_father;
05014 edge exit_copy;
05015 bitmap definitions;
05016 tree phi;
05017 basic_block *doms;
05018 htab_t ssa_name_map = NULL;
05019 edge redirected;
05020 bitmap_iterator bi;
05021
05022 if (!can_copy_bbs_p (region, n_region))
05023 return false;
05024
05025
05026
05027
05028
05029
05030 for (i = 0; i < n_region; i++)
05031 {
05032
05033
05034 if (region[i]->loop_father != loop)
05035 return false;
05036
05037 if (region[i] != entry->dest
05038 && region[i] == loop->header)
05039 return false;
05040 }
05041
05042 loop->copy = loop;
05043
05044
05045
05046 if (loop->header == entry->dest)
05047 {
05048 copying_header = true;
05049 loop->copy = loop->outer;
05050
05051 if (!dominated_by_p (CDI_DOMINATORS, loop->latch, exit->src))
05052 return false;
05053
05054 for (i = 0; i < n_region; i++)
05055 if (region[i] != exit->src
05056 && dominated_by_p (CDI_DOMINATORS, region[i], exit->src))
05057 return false;
05058 }
05059
05060 if (!region_copy)
05061 {
05062 region_copy = xmalloc (sizeof (basic_block) * n_region);
05063 free_region_copy = true;
05064 }
05065
05066 gcc_assert (!any_marked_for_rewrite_p ());
05067
05068
05069
05070 doms = xmalloc (sizeof (basic_block) * n_basic_blocks);
05071 n_doms = get_dominated_by_region (CDI_DOMINATORS, region, n_region, doms);
05072
05073 copy_bbs (region, n_region, region_copy, &exit, 1, &exit_copy, loop);
05074 definitions = marked_ssa_names ();
05075
05076 if (copying_header)
05077 {
05078 loop->header = exit->dest;
05079 loop->latch = exit->src;
05080 }
05081
05082
05083 redirected = redirect_edge_and_branch (entry, entry->dest->rbi->copy);
05084 gcc_assert (redirected != NULL);
05085 flush_pending_stmts (entry);
05086
05087
05088
05089
05090 set_immediate_dominator (CDI_DOMINATORS, entry->dest, entry->src);
05091 doms[n_doms++] = entry->dest->rbi->original;
05092 iterate_fix_dominators (CDI_DOMINATORS, doms, n_doms);
05093 free (doms);
05094
05095
05096 add_phi_args_after_copy (region_copy, n_region);
05097
05098
05099
05100
05101 EXECUTE_IF_SET_IN_BITMAP (definitions, 0, ver, bi)
05102 {
05103 tree name = ssa_name (ver);
05104
05105 phi = create_phi_node (name, exit->dest);
05106 add_phi_arg (phi, name, exit);
05107 add_phi_arg (phi, name, exit_copy);
05108
05109 SSA_NAME_DEF_STMT (name) = phi;
05110 }
05111
05112
05113
05114
05115
05116 allocate_ssa_names (definitions, &ssa_name_map);
05117 rewrite_to_new_ssa_names (region, n_region, ssa_name_map);
05118 allocate_ssa_names (definitions, &ssa_name_map);
05119 rewrite_to_new_ssa_names (region_copy, n_region, ssa_name_map);
05120 htab_delete (ssa_name_map);
05121
05122 if (free_region_copy)
05123 free (region_copy);
05124
05125 unmark_all_for_rewrite ();
05126 BITMAP_FREE (definitions);
05127
05128 return true;
05129 }
05130
05131
05132
05133 void
05134 dump_function_to_file (tree fn, FILE *file, int flags)
05135 {
05136 tree arg, vars, var;
05137 bool ignore_topmost_bind = false, any_var = false;
05138 basic_block bb;
05139 tree chain;
05140
05141 fprintf (file, "%s (", lang_hooks.decl_printable_name (fn, 2));
05142
05143 arg = DECL_ARGUMENTS (fn);
05144 while (arg)
05145 {
05146 print_generic_expr (file, arg, dump_flags);
05147 if (TREE_CHAIN (arg))
05148 fprintf (file, ", ");
05149 arg = TREE_CHAIN (arg);
05150 }
05151 fprintf (file, ")\n");
05152
05153 if (flags & TDF_RAW)
05154 {
05155 dump_node (fn, TDF_SLIM | flags, file);
05156 return;
05157 }
05158
05159
05160
05161 if (cfun && cfun->unexpanded_var_list)
05162 {
05163 ignore_topmost_bind = true;
05164
05165 fprintf (file, "{\n");
05166 for (vars = cfun->unexpanded_var_list; vars; vars = TREE_CHAIN (vars))
05167 {
05168 var = TREE_VALUE (vars);
05169
05170 print_generic_decl (file, var, flags);
05171 fprintf (file, "\n");
05172
05173 any_var = true;
05174 }
05175 }
05176
05177 if (basic_block_info)
05178 {
05179
05180 check_bb_profile (ENTRY_BLOCK_PTR, file);
05181 if (!ignore_topmost_bind)
05182 fprintf (file, "{\n");
05183
05184 if (any_var && n_basic_blocks)
05185 fprintf (file, "\n");
05186
05187 FOR_EACH_BB (bb)
05188 dump_generic_bb (file, bb, 2, flags);
05189
05190 fprintf (file, "}\n");
05191 check_bb_profile (EXIT_BLOCK_PTR, file);
05192 }
05193 else
05194 {
05195 int indent;
05196
05197
05198 chain = DECL_SAVED_TREE (fn);
05199
05200 if (TREE_CODE (chain) == BIND_EXPR)
05201 {
05202 if (ignore_topmost_bind)
05203 {
05204 chain = BIND_EXPR_BODY (chain);
05205 indent = 2;
05206 }
05207 else
05208 indent = 0;
05209 }
05210 else
05211 {
05212 if (!ignore_topmost_bind)
05213 fprintf (file, "{\n");
05214 indent = 2;
05215 }
05216
05217 if (any_var)
05218 fprintf (file, "\n");
05219
05220 print_generic_stmt_indented (file, chain, flags, indent);
05221 if (ignore_topmost_bind)
05222 fprintf (file, "}\n");
05223 }
05224
05225 fprintf (file, "\n\n");
05226 }
05227
05228
05229
05230 static void print_loop (FILE *, struct loop *, int);
05231 static void print_pred_bbs (FILE *, basic_block bb);
05232 static void print_succ_bbs (FILE *, basic_block bb);
05233
05234
05235
05236
05237 static void
05238 print_pred_bbs (FILE *file, basic_block bb)
05239 {
05240 edge e;
05241 edge_iterator ei;
05242
05243 FOR_EACH_EDGE (e, ei, bb->preds)
05244 fprintf (file, "bb_%d", e->src->index);
05245 }
05246
05247
05248
05249
05250 static void
05251 print_succ_bbs (FILE *file, basic_block bb)
05252 {
05253 edge e;
05254 edge_iterator ei;
05255
05256 FOR_EACH_EDGE (e, ei, bb->succs)
05257 fprintf (file, "bb_%d", e->src->index);
05258 }
05259
05260
05261
05262
05263 static void
05264 print_loop (FILE *file, struct loop *loop, int indent)
05265 {
05266 char *s_indent;
05267 basic_block bb;
05268
05269 if (loop == NULL)
05270 return;
05271
05272 s_indent = (char *) alloca ((size_t) indent + 1);
05273 memset ((void *) s_indent, ' ', (size_t) indent);
05274 s_indent[indent] = '\0';
05275
05276
05277 fprintf (file, "%sloop_%d\n", s_indent, loop->num);
05278
05279
05280 fprintf (file, "%s{\n", s_indent);
05281 FOR_EACH_BB (bb)
05282 if (bb->loop_father == loop)
05283 {
05284
05285 fprintf (file, "%s bb_%d (preds = {", s_indent, bb->index);
05286 print_pred_bbs (file, bb);
05287 fprintf (file, "}, succs = {");
05288 print_succ_bbs (file, bb);
05289 fprintf (file, "})\n");
05290
05291
05292 fprintf (file, "%s {\n", s_indent);
05293 tree_dump_bb (bb, file, indent + 4);
05294 fprintf (file, "%s }\n", s_indent);
05295 }
05296
05297 print_loop (file, loop->inner, indent + 2);
05298 fprintf (file, "%s}\n", s_indent);
05299 print_loop (file, loop->next, indent);
05300 }
05301
05302
05303
05304
05305
05306 void
05307 print_loop_ir (FILE *file)
05308 {
05309 basic_block bb;
05310
05311 bb = BASIC_BLOCK (0);
05312 if (bb && bb->loop_father)
05313 print_loop (file, bb->loop_father, 0);
05314 }
05315
05316
05317
05318
05319 void
05320 debug_loop_ir (void)
05321 {
05322 print_loop_ir (stderr);
05323 }
05324
05325
05326
05327
05328
05329
05330 static bool
05331 tree_block_ends_with_call_p (basic_block bb)
05332 {
05333 block_stmt_iterator bsi = bsi_last (bb);
05334 return get_call_expr_in (bsi_stmt (bsi)) != NULL;
05335 }
05336
05337
05338
05339
05340
05341 static bool
05342 tree_block_ends_with_condjump_p (basic_block bb)
05343 {
05344 tree stmt = tsi_stmt (bsi_last (bb).tsi);
05345 return (TREE_CODE (stmt) == COND_EXPR);
05346 }
05347
05348
05349
05350
05351
05352 static bool
05353 need_fake_edge_p (tree t)
05354 {
05355 tree call;
05356
05357
05358
05359
05360
05361
05362
05363
05364 call = get_call_expr_in (t);
05365 if (call
05366 && !(call_expr_flags (call) & (ECF_NORETURN | ECF_ALWAYS_RETURN)))
05367 return true;
05368
05369 if (TREE_CODE (t) == ASM_EXPR
05370 && (ASM_VOLATILE_P (t) || ASM_INPUT_P (t)))
05371 return true;
05372
05373 return false;
05374 }
05375
05376
05377
05378
05379
05380
05381
05382
05383
05384
05385 static int
05386 tree_flow_call_edges_add (sbitmap blocks)
05387 {
05388 int i;
05389 int blocks_split = 0;
05390 int last_bb = last_basic_block;
05391 bool check_last_block = false;
05392
05393 if (n_basic_blocks == 0)
05394 return 0;
05395
05396 if (! blocks)
05397 check_last_block = true;
05398 else
05399 check_last_block = TEST_BIT (blocks, EXIT_BLOCK_PTR->prev_bb->index);
05400
05401
05402
05403
05404
05405
05406
05407
05408
05409
05410
05411
05412
05413 if (check_last_block)
05414 {
05415 basic_block bb = EXIT_BLOCK_PTR->prev_bb;
05416 block_stmt_iterator bsi = bsi_last (bb);
05417 tree t = NULL_TREE;
05418 if (!bsi_end_p (bsi))
05419 t = bsi_stmt (bsi);
05420
05421 if (need_fake_edge_p (t))
05422 {
05423 edge e;
05424
05425 e = find_edge (bb, EXIT_BLOCK_PTR);
05426 if (e)
05427 {
05428 bsi_insert_on_edge (e, build_empty_stmt ());
05429 bsi_commit_edge_inserts ();
05430 }
05431 }
05432 }
05433
05434
05435
05436
05437 for (i = 0; i < last_bb; i++)
05438 {
05439 basic_block bb = BASIC_BLOCK (i);
05440 block_stmt_iterator bsi;
05441 tree stmt, last_stmt;
05442
05443 if (!bb)
05444 continue;
05445
05446 if (blocks && !TEST_BIT (blocks, i))
05447 continue;
05448
05449 bsi = bsi_last (bb);
05450 if (!bsi_end_p (bsi))
05451 {
05452 last_stmt = bsi_stmt (bsi);
05453 do
05454 {
05455 stmt = bsi_stmt (bsi);
05456 if (need_fake_edge_p (stmt))
05457 {
05458 edge e;
05459
05460
05461
05462
05463
05464 #ifdef ENABLE_CHECKING
05465 if (stmt == last_stmt)
05466 {
05467 e = find_edge (bb, EXIT_BLOCK_PTR);
05468 gcc_assert (e == NULL);
05469 }
05470 #endif
05471
05472
05473
05474 if (stmt != last_stmt)
05475 {
05476 e = split_block (bb, stmt);
05477 if (e)
05478 blocks_split++;
05479 }
05480 make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
05481 }
05482 bsi_prev (&bsi);
05483 }
05484 while (!bsi_end_p (bsi));
05485 }
05486 }
05487
05488 if (blocks_split)
05489 verify_flow_info ();
05490
05491 return blocks_split;
05492 }
05493
05494 bool
05495 tree_purge_dead_eh_edges (basic_block bb)
05496 {
05497 bool changed = false;
05498 edge e;
05499 edge_iterator ei;
05500 tree stmt = last_stmt (bb);
05501
05502 if (stmt && tree_can_throw_internal (stmt))
05503 return false;
05504
05505 for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
05506 {
05507 if (e->flags & EDGE_EH)
05508 {
05509 remove_edge (e);
05510 changed = true;
05511 }
05512 else
05513 ei_next (&ei);
05514 }
05515
05516
05517
05518
05519
05520
05521
05522
05523
05524
05525
05526
05527
05528
05529
05530
05531
05532
05533 if (changed)
05534 free_dominance_info (CDI_DOMINATORS);
05535
05536 return changed;
05537 }
05538
05539 bool
05540 tree_purge_all_dead_eh_edges (bitmap blocks)
05541 {
05542 bool changed = false;
05543 unsigned i;
05544 bitmap_iterator bi;
05545
05546 EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i, bi)
05547 {
05548 changed |= tree_purge_dead_eh_edges (BASIC_BLOCK (i));
05549 }
05550
05551 return changed;
05552 }
05553
05554
05555
05556
05557 static void
05558 tree_execute_on_growing_pred (edge e)
05559 {
05560 basic_block bb = e->dest;
05561
05562 if (phi_nodes (bb))
05563 reserve_phi_args_for_new_edge (bb);
05564 }
05565
05566
05567
05568
05569 static void
05570 tree_execute_on_shrinking_pred (edge e)
05571 {
05572 if (phi_nodes (e->dest))
05573 remove_phi_args (e);
05574 }
05575
05576 struct cfg_hooks tree_cfg_hooks = {
05577 "tree",
05578 tree_verify_flow_info,
05579 tree_dump_bb,
05580 create_bb,
05581 tree_redirect_edge_and_branch,
05582 tree_redirect_edge_and_branch_force,
05583 remove_bb,
05584 tree_split_block,
05585 tree_move_block_after,
05586 tree_can_merge_blocks_p,
05587 tree_merge_blocks,
05588 tree_predict_edge,
05589 tree_predicted_by_p,
05590 tree_can_duplicate_bb_p,
05591 tree_duplicate_bb,
05592 tree_split_edge,
05593 tree_make_forwarder_block,
05594 NULL,
05595 tree_block_ends_with_call_p,
05596 tree_block_ends_with_condjump_p,
05597 tree_flow_call_edges_add,
05598 tree_execute_on_growing_pred,
05599 tree_execute_on_shrinking_pred,
05600 };
05601
05602
05603
05604
05605 static void
05606 split_critical_edges (void)
05607 {
05608 basic_block bb;
05609 edge e;
05610 edge_iterator ei;
05611
05612
05613
05614
05615 start_recording_case_labels ();
05616 FOR_ALL_BB (bb)
05617 {
05618 FOR_EACH_EDGE (e, ei, bb->succs)
05619 if (EDGE_CRITICAL_P (e) && !(e->flags & EDGE_ABNORMAL))
05620 {
05621 split_edge (e);
05622 }
05623 }
05624 end_recording_case_labels ();
05625 }
05626
05627 struct tree_opt_pass pass_split_crit_edges =
05628 {
05629 "crited",
05630 NULL,
05631 split_critical_edges,
05632 NULL,
05633 NULL,
05634 0,
05635 TV_TREE_SPLIT_EDGES,
05636 PROP_cfg,
05637 PROP_no_crit_edges,
05638 0,
05639 0,
05640 TODO_dump_func,
05641 0
05642 };
05643
05644
05645
05646
05647
05648
05649
05650 tree
05651 gimplify_val (block_stmt_iterator *bsi, tree type, tree exp)
05652 {
05653 tree t, new_stmt, orig_stmt;
05654
05655 if (is_gimple_val (exp))
05656 return exp;
05657
05658 t = make_rename_temp (type, NULL);
05659 new_stmt = build (MODIFY_EXPR, type, t, exp);
05660
05661 orig_stmt = bsi_stmt (*bsi);
05662 SET_EXPR_LOCUS (new_stmt, EXPR_LOCUS (orig_stmt));
05663 TREE_BLOCK (new_stmt) = TREE_BLOCK (orig_stmt);
05664
05665 bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
05666
05667 return t;
05668 }
05669
05670
05671
05672
05673 tree
05674 gimplify_build3 (block_stmt_iterator *bsi, enum tree_code code,
05675 tree type, tree a, tree b, tree c)
05676 {
05677 tree ret;
05678
05679 ret = fold (build3 (code, type, a, b, c));
05680 STRIP_NOPS (ret);
05681
05682 return gimplify_val (bsi, type, ret);
05683 }
05684
05685
05686
05687
05688 tree
05689 gimplify_build2 (block_stmt_iterator *bsi, enum tree_code code,
05690 tree type, tree a, tree b)
05691 {
05692 tree ret;
05693
05694 ret = fold (build2 (code, type, a, b));
05695 STRIP_NOPS (ret);
05696
05697 return gimplify_val (bsi, type, ret);
05698 }
05699
05700
05701
05702
05703 tree
05704 gimplify_build1 (block_stmt_iterator *bsi, enum tree_code code, tree type,
05705 tree a)
05706 {
05707 tree ret;
05708
05709 ret = fold (build1 (code, type, a));
05710 STRIP_NOPS (ret);
05711
05712 return gimplify_val (bsi, type, ret);
05713 }
05714
05715
05716
05717
05718
05719 static void
05720 execute_warn_function_return (void)
05721 {
05722 #ifdef USE_MAPPED_LOCATION
05723 source_location location;
05724 #else
05725 location_t *locus;
05726 #endif
05727 tree last;
05728 edge e;
05729 edge_iterator ei;
05730
05731 if (warn_missing_noreturn
05732 && !TREE_THIS_VOLATILE (cfun->decl)
05733 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) == 0
05734 && !lang_hooks.function.missing_noreturn_ok_p (cfun->decl))
05735 warning ("%Jfunction might be possible candidate for "
05736 "attribute %<noreturn%>",
05737 cfun->decl);
05738
05739
05740 if (TREE_THIS_VOLATILE (cfun->decl)
05741 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0)
05742 {
05743 #ifdef USE_MAPPED_LOCATION
05744 location = UNKNOWN_LOCATION;
05745 #else
05746 locus = NULL;
05747 #endif
05748 FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
05749 {
05750 last = last_stmt (e->src);
05751 if (TREE_CODE (last) == RETURN_EXPR
05752 #ifdef USE_MAPPED_LOCATION
05753 && (location = EXPR_LOCATION (last)) != UNKNOWN_LOCATION)
05754 #else
05755 && (locus = EXPR_LOCUS (last)) != NULL)
05756 #endif
05757 break;
05758 }
05759 #ifdef USE_MAPPED_LOCATION
05760 if (location == UNKNOWN_LOCATION)
05761 location = cfun->function_end_locus;
05762 warning ("%H%<noreturn%> function does return", &location);
05763 #else
05764 if (!locus)
05765 locus = &cfun->function_end_locus;
05766 warning ("%H%<noreturn%> function does return", locus);
05767 #endif
05768 }
05769
05770
05771
05772 else if (warn_return_type
05773 && !TREE_NO_WARNING (cfun->decl)
05774 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0
05775 && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (cfun->decl))))
05776 {
05777 FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
05778 {
05779 tree last = last_stmt (e->src);
05780 if (TREE_CODE (last) == RETURN_EXPR
05781 && TREE_OPERAND (last, 0) == NULL
05782 && !TREE_NO_WARNING (last))
05783 {
05784 #ifdef USE_MAPPED_LOCATION
05785 location = EXPR_LOCATION (last);
05786 if (location == UNKNOWN_LOCATION)
05787 location = cfun->function_end_locus;
05788 warning ("%Hcontrol reaches end of non-void function", &location);
05789 #else
05790 locus = EXPR_LOCUS (last);
05791 if (!locus)
05792 locus = &cfun->function_end_locus;
05793 warning ("%Hcontrol reaches end of non-void function", locus);
05794 #endif
05795 TREE_NO_WARNING (cfun->decl) = 1;
05796 break;
05797 }
05798 }
05799 }
05800 }
05801
05802
05803
05804
05805
05806
05807
05808 void
05809 extract_true_false_edges_from_block (basic_block b,
05810 edge *true_edge,
05811 edge *false_edge)
05812 {
05813 edge e = EDGE_SUCC (b, 0);
05814
05815 if (e->flags & EDGE_TRUE_VALUE)
05816 {
05817 *true_edge = e;
05818 *false_edge = EDGE_SUCC (b, 1);
05819 }
05820 else
05821 {
05822 *false_edge = e;
05823 *true_edge = EDGE_SUCC (b, 1);
05824 }
05825 }
05826
05827 struct tree_opt_pass pass_warn_function_return =
05828 {
05829 NULL,
05830 NULL,
05831 execute_warn_function_return,
05832 NULL,
05833 NULL,
05834 0,
05835 0,
05836 PROP_cfg,
05837 0,
05838 0,
05839 0,
05840 0,
05841 0
05842 };
05843
05844 #include "gt-tree-cfg.h"