X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Ftree-cfg.c;h=8da55ff7cd958418654b69517ee6d24fc9e8feff;hp=069d330e74d3fbce244c7dc59aaff224a57f3453;hb=c782188f3ffc0c0dc71ee09baacd80f7a7589ab5;hpb=47aaf6e6cb103ab06e8fd6bb7d326d41d16eefa1 diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 069d330e74d..8da55ff7cd9 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -417,8 +417,7 @@ fold_cond_expr_cond (void) cond = fold (COND_EXPR_COND (stmt)); zerop = integer_zerop (cond); onep = integer_onep (cond); - fold_undefer_overflow_warnings (((zerop || onep) - && !TREE_NO_WARNING (stmt)), + fold_undefer_overflow_warnings (zerop || onep, stmt, WARN_STRICT_OVERFLOW_CONDITIONAL); if (zerop) @@ -525,6 +524,13 @@ make_edges (void) fallthru = false; break; + + case OMP_ATOMIC_LOAD: + case OMP_ATOMIC_STORE: + fallthru = true; + break; + + case OMP_RETURN: /* In the case of an OMP_SECTION, the edge will go somewhere other than the next block. This will be created later. */ @@ -1316,7 +1322,21 @@ tree_merge_blocks (basic_block a, basic_block b) } else { - replace_uses_by (def, use); + /* If we deal with a PHI for virtual operands, we can simply + propagate these without fussing with folding or updating + the stmt. */ + if (!is_gimple_reg (def)) + { + imm_use_iterator iter; + use_operand_p use_p; + tree stmt; + + FOR_EACH_IMM_USE_STMT (stmt, iter, def) + FOR_EACH_IMM_USE_ON_STMT (use_p, iter) + SET_USE (use_p, use); + } + else + replace_uses_by (def, use); remove_phi_node (phi, NULL, true); } } @@ -1423,7 +1443,7 @@ remove_useless_stmts_warn_notreached (tree stmt) location_t loc = EXPR_LOCATION (stmt); if (LOCATION_LINE (loc) > 0) { - warning (0, "%Hwill never be executed", &loc); + warning (OPT_Wunreachable_code, "%Hwill never be executed", &loc); return true; } } @@ -2459,7 +2479,7 @@ is_ctrl_altering_stmt (const_tree t) const_tree call; gcc_assert (t); - call = const_get_call_expr_in (t); + call = get_call_expr_in (CONST_CAST_TREE (t)); if (call) { /* A non-pure/const CALL_EXPR alters flow control if the current @@ -3212,6 +3232,11 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) error ("address taken, but ADDRESSABLE bit not set"); return x; } + + /* Stop recursing and verifying invariant ADDR_EXPRs, they tend + to become arbitrary complicated. */ + if (is_gimple_min_invariant (t)) + *walk_subtrees = 0; break; } @@ -3539,6 +3564,24 @@ verify_gimple_reference (tree expr) return verify_gimple_min_lval (expr); } +/* Returns true if there is one pointer type in TYPE_POINTER_TO (SRC_OBJ) + list of pointer-to types that is trivially convertible to DEST. */ + +static bool +one_pointer_to_useless_type_conversion_p (tree dest, tree src_obj) +{ + tree src; + + if (!TYPE_POINTER_TO (src_obj)) + return true; + + for (src = TYPE_POINTER_TO (src_obj); src; src = TYPE_NEXT_PTR_TO (src)) + if (useless_type_conversion_p (dest, src)) + return true; + + return false; +} + /* Verify the GIMPLE expression EXPR. Returns true if there is an error, otherwise false. */ @@ -3725,7 +3768,6 @@ verify_gimple_expr (tree expr) return true; } if (!POINTER_TYPE_P (TREE_TYPE (op0)) - || TREE_CODE (TREE_TYPE (op1)) != INTEGER_TYPE || !useless_type_conversion_p (type, TREE_TYPE (op0)) || !useless_type_conversion_p (sizetype, TREE_TYPE (op1))) { @@ -3770,22 +3812,20 @@ verify_gimple_expr (tree expr) case ADDR_EXPR: { tree op = TREE_OPERAND (expr, 0); - tree ptr_type; if (!is_gimple_addressable (op)) { error ("invalid operand in unary expression"); return true; } - ptr_type = build_pointer_type (TREE_TYPE (op)); - if (!useless_type_conversion_p (type, ptr_type) + if (!one_pointer_to_useless_type_conversion_p (type, TREE_TYPE (op)) /* FIXME: a longstanding wart, &a == &a[0]. */ && (TREE_CODE (TREE_TYPE (op)) != ARRAY_TYPE - || !useless_type_conversion_p (type, - build_pointer_type (TREE_TYPE (TREE_TYPE (op)))))) + || !one_pointer_to_useless_type_conversion_p (type, + TREE_TYPE (TREE_TYPE (op))))) { error ("type mismatch in address expression"); debug_generic_stmt (TREE_TYPE (expr)); - debug_generic_stmt (ptr_type); + debug_generic_stmt (TYPE_POINTER_TO (TREE_TYPE (op))); return true; } @@ -3851,6 +3891,10 @@ verify_gimple_expr (tree expr) didn't see a function declaration before the call. */ return false; + case OBJ_TYPE_REF: + /* FIXME. */ + return false; + default:; } @@ -4023,12 +4067,14 @@ verify_gimple_stmt (tree stmt) } } -/* Verify the GIMPLE statements inside the statement list STMTS. */ +/* Verify the GIMPLE statements inside the statement list STMTS. + Returns true if there were any errors. */ -void -verify_gimple_1 (tree stmts) +static bool +verify_gimple_2 (tree stmts) { tree_stmt_iterator tsi; + bool err = false; for (tsi = tsi_start (stmts); !tsi_end_p (tsi); tsi_next (&tsi)) { @@ -4037,28 +4083,44 @@ verify_gimple_1 (tree stmts) switch (TREE_CODE (stmt)) { case BIND_EXPR: - verify_gimple_1 (BIND_EXPR_BODY (stmt)); + err |= verify_gimple_2 (BIND_EXPR_BODY (stmt)); break; case TRY_CATCH_EXPR: case TRY_FINALLY_EXPR: - verify_gimple_1 (TREE_OPERAND (stmt, 0)); - verify_gimple_1 (TREE_OPERAND (stmt, 1)); + err |= verify_gimple_2 (TREE_OPERAND (stmt, 0)); + err |= verify_gimple_2 (TREE_OPERAND (stmt, 1)); break; case CATCH_EXPR: - verify_gimple_1 (CATCH_BODY (stmt)); + err |= verify_gimple_2 (CATCH_BODY (stmt)); break; case EH_FILTER_EXPR: - verify_gimple_1 (EH_FILTER_FAILURE (stmt)); + err |= verify_gimple_2 (EH_FILTER_FAILURE (stmt)); break; default: - if (verify_gimple_stmt (stmt)) - debug_generic_expr (stmt); + { + bool err2 = verify_gimple_stmt (stmt); + if (err2) + debug_generic_expr (stmt); + err |= err2; + } } } + + return err; +} + + +/* Verify the GIMPLE statements inside the statement list STMTS. */ + +void +verify_gimple_1 (tree stmts) +{ + if (verify_gimple_2 (stmts)) + internal_error ("verify_gimple failed"); } /* Verify the GIMPLE statements inside the current function. */ @@ -4258,11 +4320,18 @@ verify_stmts (void) tree t = PHI_ARG_DEF (phi, i); tree addr; + if (!t) + { + error ("missing PHI def"); + debug_generic_stmt (phi); + err |= true; + continue; + } /* Addressable variables do have SSA_NAMEs but they are not considered gimple values. */ - if (TREE_CODE (t) != SSA_NAME - && TREE_CODE (t) != FUNCTION_DECL - && !is_gimple_val (t)) + else if (TREE_CODE (t) != SSA_NAME + && TREE_CODE (t) != FUNCTION_DECL + && !is_gimple_val (t)) { error ("PHI def is not a GIMPLE value"); debug_generic_stmt (phi); @@ -5008,6 +5077,52 @@ tree_duplicate_bb (basic_block bb) return new_bb; } +/* Adds phi node arguments for edge E_COPY after basic block duplication. */ + +static void +add_phi_args_after_copy_edge (edge e_copy) +{ + basic_block bb, bb_copy = e_copy->src, dest; + edge e; + edge_iterator ei; + tree phi, phi_copy, phi_next, def; + + if (!phi_nodes (e_copy->dest)) + return; + + bb = bb_copy->flags & BB_DUPLICATED ? get_bb_original (bb_copy) : bb_copy; + + if (e_copy->dest->flags & BB_DUPLICATED) + dest = get_bb_original (e_copy->dest); + else + dest = e_copy->dest; + + e = find_edge (bb, dest); + if (!e) + { + /* During loop unrolling the target of the latch edge is copied. + In this case we are not looking for edge to dest, but to + duplicated block whose original was dest. */ + FOR_EACH_EDGE (e, ei, bb->succs) + { + if ((e->dest->flags & BB_DUPLICATED) + && get_bb_original (e->dest) == dest) + break; + } + + gcc_assert (e != NULL); + } + + for (phi = phi_nodes (e->dest), phi_copy = phi_nodes (e_copy->dest); + phi; + phi = phi_next, phi_copy = PHI_CHAIN (phi_copy)) + { + phi_next = PHI_CHAIN (phi); + def = PHI_ARG_DEF_FROM_EDGE (phi, e); + add_phi_arg (phi_copy, def, e_copy); + } +} + /* Basic block BB_COPY was created by code duplication. Add phi node arguments for edges going out of BB_COPY. The blocks that were @@ -5016,54 +5131,23 @@ tree_duplicate_bb (basic_block bb) void add_phi_args_after_copy_bb (basic_block bb_copy) { - basic_block bb, dest; - edge e, e_copy; edge_iterator ei; - tree phi, phi_copy, phi_next, def; - - bb = get_bb_original (bb_copy); + edge e_copy; FOR_EACH_EDGE (e_copy, ei, bb_copy->succs) { - if (!phi_nodes (e_copy->dest)) - continue; - - if (e_copy->dest->flags & BB_DUPLICATED) - dest = get_bb_original (e_copy->dest); - else - dest = e_copy->dest; - - e = find_edge (bb, dest); - if (!e) - { - /* During loop unrolling the target of the latch edge is copied. - In this case we are not looking for edge to dest, but to - duplicated block whose original was dest. */ - FOR_EACH_EDGE (e, ei, bb->succs) - if ((e->dest->flags & BB_DUPLICATED) - && get_bb_original (e->dest) == dest) - break; - - gcc_assert (e != NULL); - } - - for (phi = phi_nodes (e->dest), phi_copy = phi_nodes (e_copy->dest); - phi; - phi = phi_next, phi_copy = PHI_CHAIN (phi_copy)) - { - phi_next = PHI_CHAIN (phi); - def = PHI_ARG_DEF_FROM_EDGE (phi, e); - add_phi_arg (phi_copy, def, e_copy); - } + add_phi_args_after_copy_edge (e_copy); } } /* Blocks in REGION_COPY array of length N_REGION were created by duplication of basic blocks. Add phi node arguments for edges - going from these blocks. */ + going from these blocks. If E_COPY is not NULL, also add + phi node arguments for its destination.*/ void -add_phi_args_after_copy (basic_block *region_copy, unsigned n_region) +add_phi_args_after_copy (basic_block *region_copy, unsigned n_region, + edge e_copy) { unsigned i; @@ -5072,6 +5156,8 @@ add_phi_args_after_copy (basic_block *region_copy, unsigned n_region) for (i = 0; i < n_region; i++) add_phi_args_after_copy_bb (region_copy[i]); + if (e_copy) + add_phi_args_after_copy_edge (e_copy); for (i = 0; i < n_region; i++) region_copy[i]->flags &= ~BB_DUPLICATED; @@ -5209,10 +5295,180 @@ tree_duplicate_sese_region (edge entry, edge exit, set_immediate_dominator (CDI_DOMINATORS, entry->dest, entry->src); VEC_safe_push (basic_block, heap, doms, get_bb_original (entry->dest)); iterate_fix_dominators (CDI_DOMINATORS, doms, false); - free (doms); + VEC_free (basic_block, heap, doms); /* Add the other PHI node arguments. */ - add_phi_args_after_copy (region_copy, n_region); + add_phi_args_after_copy (region_copy, n_region, NULL); + + /* Update the SSA web. */ + update_ssa (TODO_update_ssa); + + if (free_region_copy) + free (region_copy); + + free_original_copy_tables (); + return true; +} + +/* Duplicates REGION consisting of N_REGION blocks. The new blocks + are stored to REGION_COPY in the same order in that they appear + in REGION, if REGION_COPY is not NULL. ENTRY is the entry to + the region, EXIT an exit from it. The condition guarding EXIT + is moved to ENTRY. Returns true if duplication succeeds, false + otherwise. + + For example, + + some_code; + if (cond) + A; + else + B; + + is transformed to + + if (cond) + { + some_code; + A; + } + else + { + some_code; + B; + } +*/ + +bool +tree_duplicate_sese_tail (edge entry, edge exit, + basic_block *region, unsigned n_region, + basic_block *region_copy) +{ + unsigned i; + bool free_region_copy = false; + struct loop *loop = exit->dest->loop_father; + struct loop *orig_loop = entry->dest->loop_father; + basic_block switch_bb, entry_bb, nentry_bb; + VEC (basic_block, heap) *doms; + int total_freq = 0, exit_freq = 0; + gcov_type total_count = 0, exit_count = 0; + edge exits[2], nexits[2], e; + block_stmt_iterator bsi; + tree cond; + edge sorig, snew; + + gcc_assert (EDGE_COUNT (exit->src->succs) == 2); + exits[0] = exit; + exits[1] = EDGE_SUCC (exit->src, EDGE_SUCC (exit->src, 0) == exit); + + if (!can_copy_bbs_p (region, n_region)) + return false; + + /* Some sanity checking. Note that we do not check for all possible + missuses of the functions. I.e. if you ask to copy something weird + (e.g., in the example, if there is a jump from inside to the middle + of some_code, or come_code defines some of the values used in cond) + it will work, but the resulting code will not be correct. */ + for (i = 0; i < n_region; i++) + { + /* We do not handle subloops, i.e. all the blocks must belong to the + same loop. */ + if (region[i]->loop_father != orig_loop) + return false; + + if (region[i] == orig_loop->latch) + return false; + } + + initialize_original_copy_tables (); + set_loop_copy (orig_loop, loop); + + if (!region_copy) + { + region_copy = XNEWVEC (basic_block, n_region); + free_region_copy = true; + } + + gcc_assert (!need_ssa_update_p ()); + + /* Record blocks outside the region that are dominated by something + inside. */ + doms = get_dominated_by_region (CDI_DOMINATORS, region, n_region); + + if (exit->src->count) + { + total_count = exit->src->count; + exit_count = exit->count; + /* Fix up corner cases, to avoid division by zero or creation of negative + frequencies. */ + if (exit_count > total_count) + exit_count = total_count; + } + else + { + total_freq = exit->src->frequency; + exit_freq = EDGE_FREQUENCY (exit); + /* Fix up corner cases, to avoid division by zero or creation of negative + frequencies. */ + if (total_freq == 0) + total_freq = 1; + if (exit_freq > total_freq) + exit_freq = total_freq; + } + + copy_bbs (region, n_region, region_copy, exits, 2, nexits, orig_loop, + split_edge_bb_loc (exit)); + if (total_count) + { + scale_bbs_frequencies_gcov_type (region, n_region, + total_count - exit_count, + total_count); + scale_bbs_frequencies_gcov_type (region_copy, n_region, exit_count, + total_count); + } + else + { + scale_bbs_frequencies_int (region, n_region, total_freq - exit_freq, + total_freq); + scale_bbs_frequencies_int (region_copy, n_region, exit_freq, total_freq); + } + + /* Create the switch block, and put the exit condition to it. */ + entry_bb = entry->dest; + nentry_bb = get_bb_copy (entry_bb); + if (!last_stmt (entry->src) + || !stmt_ends_bb_p (last_stmt (entry->src))) + switch_bb = entry->src; + else + switch_bb = split_edge (entry); + set_immediate_dominator (CDI_DOMINATORS, nentry_bb, switch_bb); + + bsi = bsi_last (switch_bb); + cond = last_stmt (exit->src); + gcc_assert (TREE_CODE (cond) == COND_EXPR); + bsi_insert_after (&bsi, unshare_expr (cond), BSI_NEW_STMT); + + sorig = single_succ_edge (switch_bb); + sorig->flags = exits[1]->flags; + snew = make_edge (switch_bb, nentry_bb, exits[0]->flags); + + /* Register the new edge from SWITCH_BB in loop exit lists. */ + rescan_loop_exit (snew, true, false); + + /* Add the PHI node arguments. */ + add_phi_args_after_copy (region_copy, n_region, snew); + + /* Get rid of now superfluous conditions and associated edges (and phi node + arguments). */ + e = redirect_edge_and_branch (exits[0], exits[1]->dest); + PENDING_STMT (e) = NULL_TREE; + e = redirect_edge_and_branch (nexits[1], nexits[0]->dest); + PENDING_STMT (e) = NULL_TREE; + + /* Anything that is outside of the region, but was dominated by something + inside needs to update dominance info. */ + iterate_fix_dominators (CDI_DOMINATORS, doms, false); + VEC_free (basic_block, heap, doms); /* Update the SSA web. */ update_ssa (TODO_update_ssa); @@ -5455,10 +5711,12 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb, block_stmt_iterator si; struct move_stmt_d d; unsigned old_len, new_len; - tree phi; + tree phi, next_phi; /* Remove BB from dominance structures. */ delete_from_dominance_info (CDI_DOMINATORS, bb); + if (current_loops) + remove_bb_from_loops (bb); /* Link BB to the new linked list. */ move_block_after (bb, after); @@ -5493,14 +5751,20 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb, bb->index, bb); /* Remap the variables in phi nodes. */ - for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) + for (phi = phi_nodes (bb); phi; phi = next_phi) { use_operand_p use; tree op = PHI_RESULT (phi); ssa_op_iter oi; + next_phi = PHI_CHAIN (phi); if (!is_gimple_reg (op)) - continue; + { + /* Remove the phi nodes for virtual operands (alias analysis will be + run for the new function, anyway). */ + remove_phi_node (phi, NULL, true); + continue; + } SET_PHI_RESULT (phi, replace_ssa_name (op, vars_map, dest_cfun->decl)); FOR_EACH_PHI_ARG (use, phi, oi, SSA_OP_USE) @@ -5568,7 +5832,12 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb, gimple_remove_stmt_histograms (cfun, stmt); } + /* We cannot leave any operands allocated from the operand caches of + the current function. */ + free_stmt_operands (stmt); + push_cfun (dest_cfun); update_stmt (stmt); + pop_cfun (); } } @@ -5657,6 +5926,7 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, edge_iterator ei; htab_t new_label_map; struct pointer_map_t *vars_map; + struct loop *loop = entry_bb->loop_father; /* If ENTRY does not strictly dominate EXIT, this cannot be an SESE region. */ @@ -5785,6 +6055,8 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, /* Back in the original function, the SESE region has disappeared, create a new basic block in its place. */ bb = create_empty_bb (entry_pred[0]); + if (current_loops) + add_bb_to_loop (bb, loop); for (i = 0; i < num_entry_edges; i++) { e = make_edge (entry_pred[i], bb, entry_flag[i]); @@ -5935,12 +6207,6 @@ debug_function (tree fn, int flags) } -/* Pretty print of the loops intermediate representation. */ -static void print_loop (FILE *, struct loop *, int); -static void print_pred_bbs (FILE *, basic_block bb); -static void print_succ_bbs (FILE *, basic_block bb); - - /* Print on FILE the indexes for the predecessors of basic_block BB. */ static void @@ -5966,11 +6232,42 @@ print_succ_bbs (FILE *file, basic_block bb) fprintf (file, "bb_%d ", e->dest->index); } +/* Print to FILE the basic block BB following the VERBOSITY level. */ -/* Pretty print LOOP on FILE, indented INDENT spaces. */ +void +print_loops_bb (FILE *file, basic_block bb, int indent, int verbosity) +{ + char *s_indent = (char *) alloca ((size_t) indent + 1); + memset ((void *) s_indent, ' ', (size_t) indent); + s_indent[indent] = '\0'; + + /* Print basic_block's header. */ + if (verbosity >= 2) + { + fprintf (file, "%s bb_%d (preds = {", s_indent, bb->index); + print_pred_bbs (file, bb); + fprintf (file, "}, succs = {"); + print_succ_bbs (file, bb); + fprintf (file, "})\n"); + } + + /* Print basic_block's body. */ + if (verbosity >= 3) + { + fprintf (file, "%s {\n", s_indent); + tree_dump_bb (bb, file, indent + 4); + fprintf (file, "%s }\n", s_indent); + } +} + +static void print_loop_and_siblings (FILE *, struct loop *, int, int); + +/* Pretty print LOOP on FILE, indented INDENT spaces. Following + VERBOSITY level this outputs the contents of the loop, or just its + structure. */ static void -print_loop (FILE *file, struct loop *loop, int indent) +print_loop (FILE *file, struct loop *loop, int indent, int verbosity) { char *s_indent; basic_block bb; @@ -5982,55 +6279,90 @@ print_loop (FILE *file, struct loop *loop, int indent) memset ((void *) s_indent, ' ', (size_t) indent); s_indent[indent] = '\0'; - /* Print the loop's header. */ - fprintf (file, "%sloop_%d\n", s_indent, loop->num); + /* Print loop's header. */ + fprintf (file, "%sloop_%d (header = %d, latch = %d", s_indent, + loop->num, loop->header->index, loop->latch->index); + fprintf (file, ", niter = "); + print_generic_expr (file, loop->nb_iterations, 0); - /* Print the loop's body. */ - fprintf (file, "%s{\n", s_indent); - FOR_EACH_BB (bb) - if (bb->loop_father == loop) - { - /* Print the basic_block's header. */ - fprintf (file, "%s bb_%d (preds = {", s_indent, bb->index); - print_pred_bbs (file, bb); - fprintf (file, "}, succs = {"); - print_succ_bbs (file, bb); - fprintf (file, "})\n"); - - /* Print the basic_block's body. */ - fprintf (file, "%s {\n", s_indent); - tree_dump_bb (bb, file, indent + 4); - fprintf (file, "%s }\n", s_indent); - } + if (loop->any_upper_bound) + { + fprintf (file, ", upper_bound = "); + dump_double_int (file, loop->nb_iterations_upper_bound, true); + } - print_loop (file, loop->inner, indent + 2); - fprintf (file, "%s}\n", s_indent); - print_loop (file, loop->next, indent); + if (loop->any_estimate) + { + fprintf (file, ", estimate = "); + dump_double_int (file, loop->nb_iterations_estimate, true); + } + fprintf (file, ")\n"); + + /* Print loop's body. */ + if (verbosity >= 1) + { + fprintf (file, "%s{\n", s_indent); + FOR_EACH_BB (bb) + if (bb->loop_father == loop) + print_loops_bb (file, bb, indent, verbosity); + + print_loop_and_siblings (file, loop->inner, indent + 2, verbosity); + fprintf (file, "%s}\n", s_indent); + } } +/* Print the LOOP and its sibling loops on FILE, indented INDENT + spaces. Following VERBOSITY level this outputs the contents of the + loop, or just its structure. */ + +static void +print_loop_and_siblings (FILE *file, struct loop *loop, int indent, int verbosity) +{ + if (loop == NULL) + return; + + print_loop (file, loop, indent, verbosity); + print_loop_and_siblings (file, loop->next, indent, verbosity); +} /* Follow a CFG edge from the entry point of the program, and on entry of a loop, pretty print the loop structure on FILE. */ void -print_loop_ir (FILE *file) +print_loops (FILE *file, int verbosity) { basic_block bb; bb = BASIC_BLOCK (NUM_FIXED_BLOCKS); if (bb && bb->loop_father) - print_loop (file, bb->loop_father, 0); + print_loop_and_siblings (file, bb->loop_father, 0, verbosity); } -/* Debugging loops structure at tree level. */ +/* Debugging loops structure at tree level, at some VERBOSITY level. */ void -debug_loop_ir (void) +debug_loops (int verbosity) { - print_loop_ir (stderr); + print_loops (stderr, verbosity); } +/* Print on stderr the code of LOOP, at some VERBOSITY level. */ + +void +debug_loop (struct loop *loop, int verbosity) +{ + print_loop (stderr, loop, 0, verbosity); +} + +/* Print on stderr the code of loop number NUM, at some VERBOSITY + level. */ + +void +debug_loop_num (unsigned num, int verbosity) +{ + debug_loop (get_loop (num), verbosity); +} /* Return true if BB ends with a call, possibly followed by some instructions that must stay with the call. Return false, @@ -6040,7 +6372,7 @@ static bool tree_block_ends_with_call_p (basic_block bb) { block_stmt_iterator bsi = bsi_last (bb); - return const_get_call_expr_in (bsi_stmt (bsi)) != NULL; + return get_call_expr_in (bsi_stmt (bsi)) != NULL; } @@ -6711,12 +7043,12 @@ execute_warn_function_return (void) location = EXPR_LOCATION (last); if (location == UNKNOWN_LOCATION) location = cfun->function_end_locus; - warning (0, "%Hcontrol reaches end of non-void function", &location); + warning (OPT_Wreturn_type, "%Hcontrol reaches end of non-void function", &location); #else locus = EXPR_LOCUS (last); if (!locus) locus = &cfun->function_end_locus; - warning (0, "%Hcontrol reaches end of non-void function", locus); + warning (OPT_Wreturn_type, "%Hcontrol reaches end of non-void function", locus); #endif TREE_NO_WARNING (cfun->decl) = 1; break;