int current_function_contains_functions;
+/* Nonzero if function being compiled doesn't modify the stack pointer
+ (ignoring the prologue and epilogue). This is only valid after
+ life_analysis has run. */
+
+int current_function_sp_is_unchanging;
+
/* Nonzero if the current function is a thunk (a lightweight function that
just adjusts one of its arguments and forwards to another function), so
we should try to cut corners where we can. */
generated. */
int current_function_instrument_entry_exit;
+/* Nonzero if memory access checking be enabled in the current function. */
+int current_function_check_memory_usage;
+
/* The FUNCTION_DECL for an inline function currently being expanded. */
tree inline_function_decl;
p->fixup_var_refs_queue = 0;
p->epilogue_delay_list = current_function_epilogue_delay_list;
p->args_info = current_function_args_info;
+ p->check_memory_usage = current_function_check_memory_usage;
p->instrument_entry_exit = current_function_instrument_entry_exit;
save_tree_status (p, context);
current_function_epilogue_delay_list = p->epilogue_delay_list;
reg_renumber = 0;
current_function_args_info = p->args_info;
+ current_function_check_memory_usage = p->check_memory_usage;
current_function_instrument_entry_exit = p->instrument_entry_exit;
restore_tree_status (p, context);
else
return;
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
XEXP (reg, 0), ptr_mode,
GEN_INT (GET_MODE_SIZE (GET_MODE (reg))),
TREE_USED (decl) || DECL_INITIAL (decl) != 0);
}
+/* List of replacements made below in purge_addressof_1 when creating
+ bitfield insertions. */
+static rtx purge_addressof_replacements;
+
/* Helper function for purge_addressof. See if the rtx expression at *LOC
in INSN needs to be changed. If FORCE, always put any ADDRESSOFs into
the stack. */
insns = gen_sequence ();
end_sequence ();
- emit_insns_before (insns, insn);
+ emit_insn_before (insns, insn);
return;
}
else if (code == MEM && GET_CODE (XEXP (x, 0)) == ADDRESSOF && ! force)
{
int size_x, size_sub;
+ if (!insn)
+ {
+ /* When processing REG_NOTES look at the list of
+ replacements done on the insn to find the register that X
+ was replaced by. */
+ rtx tem;
+
+ for (tem = purge_addressof_replacements; tem != NULL_RTX;
+ tem = XEXP (XEXP (tem, 1), 1))
+ if (rtx_equal_p (x, XEXP (tem, 0)))
+ {
+ *loc = XEXP (XEXP (tem, 1), 0);
+ return;
+ }
+
+ /* There should always be such a replacement. */
+ abort ();
+ }
+
size_x = GET_MODE_BITSIZE (GET_MODE (x));
size_sub = GET_MODE_BITSIZE (GET_MODE (sub));
/* Don't even consider working with paradoxical subregs,
or the moral equivalent seen here. */
- if (size_x < size_sub
+ if (size_x <= size_sub
&& int_mode_for_mode (GET_MODE (sub)) != BLKmode)
{
/* Do a bitfield insertion to mirror what would happen
if (store)
{
- /* If we can't replace with a register, be afraid. */
-
start_sequence ();
val = gen_reg_rtx (GET_MODE (x));
if (! validate_change (insn, loc, val, 0))
- abort ();
+ {
+ /* Discard the current sequence and put the
+ ADDRESSOF on stack. */
+ end_sequence ();
+ goto give_up;
+ }
seq = gen_sequence ();
end_sequence ();
emit_insn_before (seq, insn);
GET_MODE_SIZE (GET_MODE (sub)),
GET_MODE_SIZE (GET_MODE (sub)));
- /* If we can't replace with a register, be afraid. */
if (! validate_change (insn, loc, val, 0))
- abort ();
+ {
+ /* Discard the current sequence and put the
+ ADDRESSOF on stack. */
+ end_sequence ();
+ goto give_up;
+ }
seq = gen_sequence ();
end_sequence ();
emit_insn_before (seq, insn);
}
+ /* Remember the replacement so that the same one can be done
+ on the REG_NOTES. */
+ purge_addressof_replacements
+ = gen_rtx_EXPR_LIST (VOIDmode, x,
+ gen_rtx_EXPR_LIST (VOIDmode, val,
+ purge_addressof_replacements));
+
/* We replaced with a reg -- all done. */
return;
}
}
else if (validate_change (insn, loc, sub, 0))
goto restart;
+ give_up:;
/* else give up and put it into the stack */
}
else if (code == ADDRESSOF)
purge_addressof_1 (&PATTERN (insn), insn,
asm_noperands (PATTERN (insn)) > 0, 0);
purge_addressof_1 (®_NOTES (insn), NULL_RTX, 0, 0);
+ purge_addressof_replacements = 0;
}
}
\f
store_expr (parm, copy, 0);
emit_move_insn (parmreg, XEXP (copy, 0));
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
XEXP (copy, 0), ptr_mode,
GEN_INT (int_size_in_bytes (type)),
emit_move_insn (validize_mem (stack_parm),
validize_mem (entry_parm));
}
- if (flag_check_memory_usage)
+ if (current_function_check_memory_usage)
{
push_to_sequence (conversion_insns);
emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
&& ! AGGREGATE_TYPE_P (TREE_TYPE (decl))
&& DECL_RTL (decl) != 0
&& GET_CODE (DECL_RTL (decl)) == REG
+ /* Global optimizations can make it difficult to determine if a
+ particular variable has been initialized. However, a VAR_DECL
+ with a nonzero DECL_INITIAL had an initializer, so do not
+ claim it is potentially uninitialized.
+
+ We do not care about the actual value in DECL_INITIAL, so we do
+ not worry that it may be a dangling pointer. */
+ && DECL_INITIAL (decl) == NULL_TREE
&& regno_uninitialized (REGNO (DECL_RTL (decl))))
warning_with_decl (decl,
"`%s' might be used uninitialized in this function");
current_function_has_nonlocal_label = 0;
current_function_has_nonlocal_goto = 0;
current_function_contains_functions = 0;
+ current_function_sp_is_unchanging = 0;
current_function_is_thunk = 0;
current_function_returns_pcc_struct = 0;
valid operands of arithmetic insns. */
init_recog_no_volatile ();
+ /* Set this before generating any memory accesses. */
+ current_function_check_memory_usage
+ = (flag_check_memory_usage
+ && ! DECL_NO_CHECK_MEMORY_USAGE (current_function_decl));
+
current_function_instrument_entry_exit
= (flag_instrument_function_entry_exit
&& ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (subr));
void
thread_prologue_and_epilogue_insns (f)
- rtx f;
+ rtx f ATTRIBUTE_UNUSED;
{
#ifdef HAVE_prologue
if (HAVE_prologue)
void
reposition_prologue_and_epilogue_notes (f)
- rtx f;
+ rtx f ATTRIBUTE_UNUSED;
{
#if defined (HAVE_prologue) || defined (HAVE_epilogue)
/* Reposition the prologue and epilogue notes. */