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)
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. */
}
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);
}
}
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;
}
}
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
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;
}
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. */
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)))
{
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;
}
didn't see a function declaration before the call. */
return false;
+ case OBJ_TYPE_REF:
+ /* FIXME. */
+ return false;
+
default:;
}
}
}
-/* 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))
{
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. */
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);
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
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;
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;
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);
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);
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)
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 ();
}
}
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. */
/* 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]);
}
-/* 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
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;
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,
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;
}
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;