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. */
static void
instantiate_decls (tree fndecl)
{
- tree decl;
+ tree decl, t, next;
/* Process all parameters of the function. */
for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl))
/* Now process all variables defined in the function or its subblocks. */
instantiate_decls_1 (DECL_INITIAL (fndecl));
+
+ t = cfun->local_decls;
+ cfun->local_decls = NULL_TREE;
+ for (; t; t = next)
+ {
+ next = TREE_CHAIN (t);
+ decl = TREE_VALUE (t);
+ if (DECL_RTL_SET_P (decl))
+ instantiate_decl_rtl (DECL_RTL (decl));
+ ggc_free (t);
+ }
}
/* Pass through the INSNS of function FNDECL and convert virtual register
{
case CALL_EXPR:
fndecl = get_callee_fndecl (fntype);
- fntype = fndecl ? TREE_TYPE (fndecl) : 0;
+ fntype = (fndecl
+ ? TREE_TYPE (fndecl)
+ : TREE_TYPE (CALL_EXPR_FN (fntype)));
break;
case FUNCTION_DECL:
fndecl = fntype;
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)));
+ {
+ set_mem_size (stack_parm, GEN_INT (GET_MODE_SIZE (data->promoted_mode)));
+ if (MEM_EXPR (stack_parm) && MEM_OFFSET (stack_parm))
+ {
+ int offset = subreg_lowpart_offset (DECL_MODE (parm),
+ data->promoted_mode);
+ if (offset)
+ set_mem_offset (stack_parm,
+ plus_constant (MEM_OFFSET (stack_parm), -offset));
+ }
+ }
boundary = data->locate.boundary;
align = BITS_PER_UNIT;
if (GET_CODE (entry_parm) == PARALLEL && GET_MODE (entry_parm) != BLKmode)
{
rtx parmreg = gen_reg_rtx (GET_MODE (entry_parm));
- emit_group_store (parmreg, entry_parm, NULL_TREE,
+ emit_group_store (parmreg, entry_parm, data->passed_type,
GET_MODE_SIZE (GET_MODE (entry_parm)));
entry_parm = parmreg;
}
{
local = create_tmp_var (type, get_name (parm));
DECL_IGNORED_P (local) = 0;
+ /* If PARM was addressable, move that flag over
+ to the local copy, as its address will be taken,
+ not the PARMs. */
+ if (TREE_ADDRESSABLE (parm))
+ {
+ TREE_ADDRESSABLE (parm) = 0;
+ TREE_ADDRESSABLE (local) = 1;
+ }
}
else
{
locate->size.constant -= part_size_in_regs;
#endif /* ARGS_GROW_DOWNWARD */
+
+#ifdef FUNCTION_ARG_OFFSET
+ locate->offset.constant += FUNCTION_ARG_OFFSET (passed_mode, type);
+#endif
}
/* Round the stack offset in *OFFSET_PTR up to a multiple of BOUNDARY.
}
}
-/* 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;
OVERRIDE_ABI_FORMAT (fndecl);
#endif
+ invoke_set_current_function_hook (fndecl);
+
if (fndecl != NULL_TREE)
{
DECL_STRUCT_FUNCTION (fndecl) = cfun;
cfun->va_list_gpr_size = VA_LIST_MAX_GPR_SIZE;
cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE;
}
-
- invoke_set_current_function_hook (fndecl);
}
/* This is like allocate_struct_function, but pushes a new cfun for FNDECL