summaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2010-08-30 20:04:49 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2010-08-30 20:04:49 +0000
commit990495a75cd770ac6234fdd765cda3a70221644d (patch)
treeca99479811fedf830873973cdd6050ed0d345e29 /gcc/function.c
parentd16175cce35b50e4b97a0253b51546c0581ac6e4 (diff)
downloadgcc-990495a75cd770ac6234fdd765cda3a70221644d.tar.gz
Stack usage support
* common.opt (-fstack-usage): New option. * doc/invoke.texi (Debugging options): Document it. * builtins.c (expand_builtin_apply): Pass TRUE as 4th argument to allocate_dynamic_stack_space. (expand_builtin_alloca): Add 4th bool parameter CANNOT_ACCUMULATE and propagate it to allocate_dynamic_stack_space. (expand_builtin) <BUILT_IN_ALLOCA>: Adjust for above change. * calls.c (initialize_argument_information): Pass TRUE as 4th argument to allocate_dynamic_stack_space. (expand_call): Set current_function_has_unbounded_dynamic_stack_size to 1 when pushing a variable-sized argument onto the stack. Pass TRUE as 4th argument to allocate_dynamic_stack_space. Update current_function_pushed_stack_size. (emit_library_call_value_1): Likewise. * explow.c (allocate_dynamic_stack_space): Add 4th bool parameter CANNOT_ACCUMULATE. If flag_stack_usage, look into the size and attempt to find an upper bound. Remove redundant code for the SETJMP_VIA_SAVE_AREA case. * expr.h (allocate_dynamic_stack_space): Add 4th bool parameter. * function.h (struct stack_usage): New structure. (current_function_static_stack_size): New macro. (current_function_dynamic_stack_size): Likewise. (current_function_pushed_stack_size): Likewise. (current_function_dynamic_alloc_count): Likewise. (current_function_has_unbounded_dynamic_stack_size): Likewise. (current_function_allocates_dynamic_stack_space): Likewise. (struct function): Add new field 'su'. * function.c (instantiate_virtual_regs): If SETJMP_VIA_SAVE_AREA, add the value of the dynamic offset to the dynamic stack usage. (gimplify_parameters): Set ALLOCA_FOR_VAR_P on call to BUILT_IN_ALLOCA for variable-sized objects. (prepare_function_start): Allocate cfun->su if flag_stack_usage. (rest_of_handle_thread_prologue_and_epilogue): Call output_stack_usage. * gimplify.c (gimplify_decl_expr): Set ALLOCA_FOR_VAR_P on call to BUILT_IN_ALLOCA for variable-sized objects. * output.h (output_stack_usage): Declare. * toplev.c (stack_usage_file): New file pointer. (output_stack_usage): New function. (open_auxiliary_file): Likewise. (lang_dependent_init): Open file if flag_stack_usage is set. (finalize): Close file if stack_usage_file is not null. * tree.h (ALLOCA_FOR_VAR_P): New macro. * config/alpha/alpha.c (compute_frame_size): New function. (alpha_expand_prologue): Use it. (alpha_start_function): Likewise. (alpha_expand_epilogue): Likewise. Set stack usage info. * config/i386/i386.c (ix86_expand_prologue): Likewise. * config/ia64/ia64.c (ia64_expand_prologue): Likewise. * config/mips/mips.c (mips_expand_prologue): Likewise. * config/pa/pa.c (hppa_expand_prologue): Likewise. * config/rs6000/rs6000.c (rs6000_emit_prologue): Likewise. * config/sparc/sparc.c (sparc_expand_prologue): Likewise. testsuite/ * lib/gcc-dg.exp (cleanup-stack-usage): New procedure. * lib/scanasm.exp (scan-stack-usage): Likewise. (scan-stack-usage-not): Likewise. * gcc.dg/stack-usage-1.c: New test. * gcc.target/i386/stack-usage-realign.c: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@163660 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/function.c')
-rw-r--r--gcc/function.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/gcc/function.c b/gcc/function.c
index 66f95828d37..670ff80ad3c 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -1899,6 +1899,18 @@ instantiate_virtual_regs (void)
/* Indicate that, from now on, assign_stack_local should use
frame_pointer_rtx. */
virtuals_instantiated = 1;
+
+ /* See allocate_dynamic_stack_space for the rationale. */
+#ifdef SETJMP_VIA_SAVE_AREA
+ if (flag_stack_usage && cfun->calls_setjmp)
+ {
+ int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
+ dynamic_offset = (dynamic_offset + align - 1) / align * align;
+ current_function_dynamic_stack_size
+ += current_function_dynamic_alloc_count * dynamic_offset;
+ }
+#endif
+
return 0;
}
@@ -3586,6 +3598,8 @@ gimplify_parameters (void)
t = built_in_decls[BUILT_IN_ALLOCA];
t = build_call_expr (t, 1, DECL_SIZE_UNIT (parm));
+ /* The call has been built for a variable-sized object. */
+ ALLOCA_FOR_VAR_P (t) = 1;
t = fold_convert (ptr_type, t);
t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
gimplify_and_add (t, &stmts);
@@ -4365,6 +4379,12 @@ prepare_function_start (void)
init_expr ();
default_rtl_profile ();
+ if (flag_stack_usage)
+ {
+ cfun->su = ggc_alloc_cleared_stack_usage ();
+ cfun->su->static_stack_size = -1;
+ }
+
cse_not_expected = ! optimize;
/* Caller save not needed yet. */
@@ -5753,12 +5773,17 @@ rest_of_handle_thread_prologue_and_epilogue (void)
{
if (optimize)
cleanup_cfg (CLEANUP_EXPENSIVE);
+
/* On some machines, the prologue and epilogue code, or parts thereof,
can be represented as RTL. Doing so lets us schedule insns between
it and the rest of the code and also allows delayed branch
scheduling to operate in the epilogue. */
-
thread_prologue_and_epilogue_insns ();
+
+ /* The stack usage info is finalized during prologue expansion. */
+ if (flag_stack_usage)
+ output_stack_usage ();
+
return 0;
}