static void do_use_return_reg (rtx, void *);
static void set_insn_locators (rtx, int) ATTRIBUTE_UNUSED;
\f
-/* Pointer to chain of `struct function' for containing functions. */
-struct function *outer_function_chain;
-
-/* Given a function decl for a containing function,
- return the `struct function' for it. */
-
-struct function *
-find_function_data (tree decl)
-{
- struct function *p;
+/* Stack of nested functions. */
+/* Keep track of the cfun stack. */
- for (p = outer_function_chain; p; p = p->outer)
- if (p->decl == decl)
- return p;
+typedef struct function *function_p;
- gcc_unreachable ();
-}
+DEF_VEC_P(function_p);
+DEF_VEC_ALLOC_P(function_p,heap);
+static VEC(function_p,heap) *function_context_stack;
/* Save the current context for compilation of a nested function.
This is called from language-specific code. */
if (cfun == 0)
allocate_struct_function (NULL, false);
- cfun->outer = outer_function_chain;
- outer_function_chain = cfun;
+ VEC_safe_push (function_p, heap, function_context_stack, cfun);
set_cfun (NULL);
}
void
pop_function_context (void)
{
- struct function *p = outer_function_chain;
-
+ struct function *p = VEC_pop (function_p, function_context_stack);
set_cfun (p);
- outer_function_chain = p->outer;
current_function_decl = p->decl;
/* Reset variables that have known state during rtx generation. */
f->cfg = NULL;
regno_reg_rtx = NULL;
+ insn_locators_free ();
}
\f
/* Return size needed for stack frame based on slots so far allocated.
}
x = simplify_gen_subreg (recog_data.operand_mode[i], new_rtx,
GET_MODE (new_rtx), SUBREG_BYTE (x));
+ gcc_assert (x);
break;
default:
stack_parm = gen_rtx_MEM (data->promoted_mode, stack_parm);
set_mem_attributes (stack_parm, parm, 1);
+ /* set_mem_attributes could set MEM_SIZE to the passed mode's size,
+ while promoted mode's size is needed. */
+ if (data->promoted_mode != BLKmode
+ && data->promoted_mode != DECL_MODE (parm))
+ set_mem_size (stack_parm, GEN_INT (GET_MODE_SIZE (data->promoted_mode)));
boundary = data->locate.boundary;
align = BITS_PER_UNIT;
walk_tree_without_duplicates (&data.passed_type,
gimplify_parm_type, &stmts);
- if (!TREE_CONSTANT (DECL_SIZE (parm)))
+ if (TREE_CODE (DECL_SIZE_UNIT (parm)) != INTEGER_CST)
{
gimplify_one_sizepos (&DECL_SIZE (parm), &stmts);
gimplify_one_sizepos (&DECL_SIZE_UNIT (parm), &stmts);
{
tree local, t;
- /* For constant sized objects, this is trivial; for
+ /* For constant-sized objects, this is trivial; for
variable-sized objects, we have to play games. */
- if (TREE_CONSTANT (DECL_SIZE (parm)))
+ if (TREE_CODE (DECL_SIZE_UNIT (parm)) == INTEGER_CST
+ && !(flag_stack_check == GENERIC_STACK_CHECK
+ && compare_tree_int (DECL_SIZE_UNIT (parm),
+ STACK_CHECK_MAX_VAR_SIZE) > 0))
{
local = create_tmp_var (type, get_name (parm));
DECL_IGNORED_P (local) = 0;
}
}
-/* Keep track of the cfun stack. */
-
-typedef struct function *function_p;
-
-DEF_VEC_P(function_p);
-DEF_VEC_ALLOC_P(function_p,heap);
-
/* Initialized with NOGC, making this poisonous to the garbage collector. */
static VEC(function_p,heap) *cfun_stack;
if (arg_pointer_save_area && ! crtl->arg_pointer_save_area_init)
get_arg_pointer_save_area ();
- /* If we are doing stack checking and this function makes calls,
+ /* If we are doing generic stack checking and this function makes calls,
do a stack probe at the start of the function to ensure we have enough
space for another stack frame. */
- if (flag_stack_check && ! STACK_CHECK_BUILTIN)
+ if (flag_stack_check == GENERIC_STACK_CHECK)
{
rtx insn, seq;
if (CALL_P (insn))
{
start_sequence ();
- probe_stack_range (STACK_CHECK_PROTECT,
+ probe_stack_range (STACK_OLD_CHECK_PROTECT,
GEN_INT (STACK_CHECK_MAX_FRAME_SIZE));
seq = get_insns ();
end_sequence ();
#endif
edge_iterator ei;
+ rtl_profile_for_bb (ENTRY_BLOCK_PTR);
#ifdef HAVE_prologue
if (HAVE_prologue)
{
if (e == NULL)
goto epilogue_done;
+ rtl_profile_for_bb (EXIT_BLOCK_PTR);
#ifdef HAVE_return
if (optimize && HAVE_return)
{
cfg_layout_finalize ();
}
epilogue_done:
+ default_rtl_profile ();
if (inserted)
{