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