/* Chain of labels defined inside this binding contour.
For contours that have stack levels or cleanups. */
struct label_chain *label_chain;
- /* Number of function calls seen, as of start of this block. */
- int n_function_calls;
/* Nonzero if this is associated with an EH region. */
int exception_region;
/* The saved target_temp_slot_level from our outer block.
always compute a value for each expr-stmt in case it is the last one. */
int x_expr_stmts_for_value;
- /* Filename and line number of last line-number note,
- whether we actually emitted it or not. */
- const char *x_emit_filename;
- int x_emit_lineno;
+ /* Location of last line-number note, whether we actually
+ emitted it or not. */
+ location_t x_emit_locus;
struct goto_fixup *x_goto_fixup_chain;
};
#define last_expr_type (cfun->stmt->x_last_expr_type)
#define last_expr_value (cfun->stmt->x_last_expr_value)
#define expr_stmts_for_value (cfun->stmt->x_expr_stmts_for_value)
-#define emit_filename (cfun->stmt->x_emit_filename)
-#define emit_lineno (cfun->stmt->x_emit_lineno)
+#define emit_locus (cfun->stmt->x_emit_locus)
#define goto_fixup_chain (cfun->stmt->x_goto_fixup_chain)
/* Nonzero if we are using EH to handle cleanups. */
static enum br_predictor return_prediction PARAMS ((rtx));
static void expand_value_return PARAMS ((rtx));
static int tail_recursion_args PARAMS ((tree, tree));
-static void expand_cleanups PARAMS ((tree, tree, int, int));
+static void expand_cleanups PARAMS ((tree, int, int));
static void check_seenlabel PARAMS ((void));
static void do_jump_if_equal PARAMS ((rtx, rtx, rtx, int));
static int estimate_case_costs PARAMS ((case_node_ptr));
update it. */
if (cfun->stmt)
{
- emit_filename = file;
- emit_lineno = line;
+ emit_locus.file = file;
+ emit_locus.line = line;
}
}
return DECL_RTL (label);
}
+/* As above, but also put it on the forced-reference list of the
+ function that contains it. */
+rtx
+force_label_rtx (label)
+ tree label;
+{
+ rtx ref = label_rtx (label);
+ tree function = decl_function_context (label);
+ struct function *p;
+
+ if (!function)
+ abort ();
+
+ if (function != current_function_decl
+ && function != inline_function_decl)
+ p = find_function_data (function);
+ else
+ p = cfun;
+
+ p->expr->x_forced_labels = gen_rtx_EXPR_LIST (VOIDmode, ref,
+ p->expr->x_forced_labels);
+ return ref;
+}
/* Add an unconditional jump to LABEL as the next sequential instruction. */
/* Execute the cleanups for blocks we are exiting. */
if (block->data.block.cleanups != 0)
{
- expand_cleanups (block->data.block.cleanups, NULL_TREE, 1, 1);
+ expand_cleanups (block->data.block.cleanups, 1, 1);
do_pending_stack_adjust ();
}
}
if (TREE_ADDRESSABLE (lists)
&& TREE_VALUE (lists) != 0)
{
- expand_cleanups (TREE_VALUE (lists), NULL_TREE, 1, 1);
+ expand_cleanups (TREE_VALUE (lists), 1, 1);
/* Pop any pushes done in the cleanups,
in case function is about to return. */
do_pending_stack_adjust ();
start_sequence ();
(*lang_hooks.decls.pushlevel) (0);
(*lang_hooks.decls.set_block) (f->context);
- expand_cleanups (TREE_VALUE (lists), NULL_TREE, 1, 1);
+ expand_cleanups (TREE_VALUE (lists), 1, 1);
do_pending_stack_adjust ();
cleanup_insns = get_insns ();
(*lang_hooks.decls.poplevel) (1, 0, 0);
{
if (! TREE_SIDE_EFFECTS (exp))
{
- if ((extra_warnings || warn_unused_value)
+ if (warn_unused_value
&& !(TREE_CODE (exp) == CONVERT_EXPR
&& VOID_TYPE_P (TREE_TYPE (exp))))
- warning_with_file_and_line (emit_filename, emit_lineno,
- "statement with no effect");
+ warning ("%Hstatement with no effect", &emit_locus);
}
else if (warn_unused_value)
warn_if_unused_value (exp);
if (TREE_SIDE_EFFECTS (exp))
return 0;
- warning_with_file_and_line (emit_filename, emit_lineno,
- "value computed is not used");
+ warning ("%Hvalue computed is not used", &emit_locus);
return 1;
}
}
else
{
rtx tmp = argvec[i];
-
+ int unsignedp = TREE_UNSIGNED (TREE_TYPE (TREE_VALUE (a)));
+ promote_mode(TREE_TYPE (TREE_VALUE (a)), GET_MODE (tmp),
+ &unsignedp, 0);
if (DECL_MODE (f) != GET_MODE (DECL_RTL (f)))
{
tmp = gen_reg_rtx (DECL_MODE (f));
- convert_move (tmp, argvec[i],
- TREE_UNSIGNED (TREE_TYPE (TREE_VALUE (a))));
+ convert_move (tmp, argvec[i], unsignedp);
}
- convert_move (DECL_RTL (f), tmp,
- TREE_UNSIGNED (TREE_TYPE (TREE_VALUE (a))));
+ convert_move (DECL_RTL (f), tmp, unsignedp);
}
}
thisblock->depth = ++nesting_depth;
thisblock->data.block.stack_level = 0;
thisblock->data.block.cleanups = 0;
- thisblock->data.block.n_function_calls = 0;
thisblock->data.block.exception_region = 0;
thisblock->data.block.block_target_temp_slot_level = target_temp_slot_level;
/* If necessary, make handlers for nonlocal gotos taking
place in the function calls in this block. */
- if (function_call_count != thisblock->data.block.n_function_calls
- && nonlocal_labels
+ if (function_call_count != 0 && nonlocal_labels
/* Make handler for outermost block
if there were any nonlocal gotos to this function. */
&& (thisblock->next == 0 ? current_function_has_nonlocal_label
reachable = (! insn || GET_CODE (insn) != BARRIER);
/* Do the cleanups. */
- expand_cleanups (thisblock->data.block.cleanups, NULL_TREE, 0, reachable);
+ expand_cleanups (thisblock->data.block.cleanups, 0, reachable);
if (reachable)
do_pending_stack_adjust ();
&& !(flag_float_store
&& TREE_CODE (type) == REAL_TYPE)
&& ! TREE_THIS_VOLATILE (decl)
+ && ! DECL_NONLOCAL (decl)
&& (DECL_REGISTER (decl) || optimize))
{
/* Automatic variable that can go in a register. */
/* If something wants our address, try to use ADDRESSOF. */
if (TREE_ADDRESSABLE (decl))
- put_var_into_stack (decl);
+ put_var_into_stack (decl, /*rescan=*/false);
}
else if (TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST
/* Expand a list of cleanups LIST.
Elements may be expressions or may be nested lists.
- If DONT_DO is nonnull, then any list-element
- whose TREE_PURPOSE matches DONT_DO is omitted.
- This is sometimes used to avoid a cleanup associated with
- a value that is being returned out of the scope.
-
If IN_FIXUP is nonzero, we are generating this cleanup for a fixup
goto and handle protection regions specially in that case.
code about this finalization. */
static void
-expand_cleanups (list, dont_do, in_fixup, reachable)
+expand_cleanups (list, in_fixup, reachable)
tree list;
- tree dont_do;
int in_fixup;
int reachable;
{
tree tail;
for (tail = list; tail; tail = TREE_CHAIN (tail))
- if (dont_do == 0 || TREE_PURPOSE (tail) != dont_do)
+ if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST)
+ expand_cleanups (TREE_VALUE (tail), in_fixup, reachable);
+ else
{
- if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST)
- expand_cleanups (TREE_VALUE (tail), dont_do, in_fixup, reachable);
- else
- {
- if (! in_fixup && using_eh_for_cleanups_p)
- expand_eh_region_end_cleanup (TREE_VALUE (tail));
+ if (! in_fixup && using_eh_for_cleanups_p)
+ expand_eh_region_end_cleanup (TREE_VALUE (tail));
- if (reachable && !CLEANUP_EH_ONLY (tail))
+ if (reachable && !CLEANUP_EH_ONLY (tail))
+ {
+ /* Cleanups may be run multiple times. For example,
+ when exiting a binding contour, we expand the
+ cleanups associated with that contour. When a goto
+ within that binding contour has a target outside that
+ contour, it will expand all cleanups from its scope to
+ the target. Though the cleanups are expanded multiple
+ times, the control paths are non-overlapping so the
+ cleanups will not be executed twice. */
+
+ /* We may need to protect from outer cleanups. */
+ if (in_fixup && using_eh_for_cleanups_p)
{
- /* Cleanups may be run multiple times. For example,
- when exiting a binding contour, we expand the
- cleanups associated with that contour. When a goto
- within that binding contour has a target outside that
- contour, it will expand all cleanups from its scope to
- the target. Though the cleanups are expanded multiple
- times, the control paths are non-overlapping so the
- cleanups will not be executed twice. */
-
- /* We may need to protect from outer cleanups. */
- if (in_fixup && using_eh_for_cleanups_p)
- {
- expand_eh_region_start ();
-
- expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
+ expand_eh_region_start ();
- expand_eh_region_end_fixup (TREE_VALUE (tail));
- }
- else
- expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
+ expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
- free_temp_slots ();
+ expand_eh_region_end_fixup (TREE_VALUE (tail));
}
+ else
+ expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
+
+ free_temp_slots ();
}
}
}
/* If insn is zero, then there must have been a syntax error. */
if (insn)
- warning_with_file_and_line (NOTE_SOURCE_FILE (insn),
- NOTE_LINE_NUMBER (insn),
- "unreachable code at beginning of %s",
- case_stack->data.case_stmt.printname);
+ {
+ location_t locus;
+ locus.file = NOTE_SOURCE_FILE (insn);
+ locus.line = NOTE_LINE_NUMBER (insn);
+ warning ("%Hunreachable code at beginning of %s", &locus,
+ case_stack->data.case_stmt.printname);
+ }
break;
}
}
else if (CASE_USE_BIT_TESTS
&& ! TREE_CONSTANT (index_expr)
&& compare_tree_int (range, GET_MODE_BITSIZE (word_mode)) < 0
+ && compare_tree_int (range, 0) > 0
&& lshift_cheap_p ()
&& ((uniq == 1 && count >= 3)
|| (uniq == 2 && count >= 5)