common.opt (flag_stack_usage_info): New variable.

* common.opt (flag_stack_usage_info): New variable.
	(-Wstack-usage): New option.
	* doc/invoke.texi (Warning options): Document -Wstack-usage.
	* opts.c (common_handle_option) <OPT_Wstack_usage_>: New case.
	<OPT_fstack_usage>: Likewise.
	* toplev.c (output_stack_usage): Handle -Wstack-usage.
	* calls.c (expand_call): Test flag_stack_usage_info variable instead
	of flag_stack_usage.
	(emit_library_call_value_1): Likewise.
	* explow.c (allocate_dynamic_stack_space): Likewise.
	* function.c (instantiate_virtual_regs ): Likewise.
	(prepare_function_start): Likewise.
	(rest_of_handle_thread_prologue_and_epilogue): Likewise.
	* config/alpha/alpha.c (alpha_expand_prologue): Likewise.
	* config/arm/arm.c (arm_expand_prologue): Likewise.
	(thumb1_expand_prologue): Likewise.
	* config/avr/avr.c (expand_prologue): Likewise.
	* config/i386/i386.c (ix86_expand_prologue): Likewise.
	* config/ia64/ia64.c (ia64_expand_prologue): Likewise.
	* config/m68k/m68k.c (m68k_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/s390/s390.c (s390_emit_prologue): Likewise.
	* config/sh/sh.c (sh_expand_prologue): Likewise.
	* config/sparc/sparc.c (sparc_expand_prologue): Likewise.
	* config/spu/spu.c (spu_expand_prologue): Likewise.

From-SVN: r174182
This commit is contained in:
Eric Botcazou 2011-05-25 11:00:14 +00:00 committed by Eric Botcazou
parent e7cfe2413f
commit a11e0df4da
24 changed files with 181 additions and 46 deletions

View file

@ -1,3 +1,33 @@
2011-05-25 Eric Botcazou <ebotcazou@adacore.com>
* common.opt (flag_stack_usage_info): New variable.
(-Wstack-usage): New option.
* doc/invoke.texi (Warning options): Document -Wstack-usage.
* opts.c (common_handle_option) <OPT_Wstack_usage_>: New case.
<OPT_fstack_usage>: Likewise.
* toplev.c (output_stack_usage): Handle -Wstack-usage.
* calls.c (expand_call): Test flag_stack_usage_info variable instead
of flag_stack_usage.
(emit_library_call_value_1): Likewise.
* explow.c (allocate_dynamic_stack_space): Likewise.
* function.c (instantiate_virtual_regs ): Likewise.
(prepare_function_start): Likewise.
(rest_of_handle_thread_prologue_and_epilogue): Likewise.
* config/alpha/alpha.c (alpha_expand_prologue): Likewise.
* config/arm/arm.c (arm_expand_prologue): Likewise.
(thumb1_expand_prologue): Likewise.
* config/avr/avr.c (expand_prologue): Likewise.
* config/i386/i386.c (ix86_expand_prologue): Likewise.
* config/ia64/ia64.c (ia64_expand_prologue): Likewise.
* config/m68k/m68k.c (m68k_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/s390/s390.c (s390_emit_prologue): Likewise.
* config/sh/sh.c (sh_expand_prologue): Likewise.
* config/sparc/sparc.c (sparc_expand_prologue): Likewise.
* config/spu/spu.c (spu_expand_prologue): Likewise.
2011-05-25 Richard Guenther <rguenther@suse.de>
* gimple.c (iterative_hash_canonical_type): Skip non-FIELD_DECLs.

View file

@ -2501,7 +2501,7 @@ expand_call (tree exp, rtx target, int ignore)
stack_arg_under_construction = 0;
}
argblock = push_block (ARGS_SIZE_RTX (adjusted_args_size), 0, 0);
if (flag_stack_usage)
if (flag_stack_usage_info)
current_function_has_unbounded_dynamic_stack_size = 1;
}
else
@ -2708,7 +2708,7 @@ expand_call (tree exp, rtx target, int ignore)
/* Record the maximum pushed stack space size. We need to delay
doing it this far to take into account the optimization done
by combine_pending_stack_adjustment_and_call. */
if (flag_stack_usage
if (flag_stack_usage_info
&& !ACCUMULATE_OUTGOING_ARGS
&& pass
&& adjusted_args_size.var == 0)
@ -3573,7 +3573,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
if (args_size.constant > crtl->outgoing_args_size)
crtl->outgoing_args_size = args_size.constant;
if (flag_stack_usage && !ACCUMULATE_OUTGOING_ARGS)
if (flag_stack_usage_info && !ACCUMULATE_OUTGOING_ARGS)
{
int pushed = args_size.constant + pending_stack_adjust;
if (pushed > current_function_pushed_stack_size)

View file

@ -138,6 +138,10 @@ enum vect_verbosity_levels user_vect_verbosity_level = MAX_VERBOSITY_LEVEL
Variable
enum stack_check_type flag_stack_check = NO_STACK_CHECK
; True if stack usage information needs to be computed.
Variable
bool flag_stack_usage_info = false
; -dA causes debug commentary information to be produced in
; the generated assembly code (to make it more readable). This option
; is generally only of use to those who actually need to read the
@ -575,6 +579,10 @@ Wstack-protector
Common Var(warn_stack_protect) Warning
Warn when not issuing stack smashing protection for some reason
Wstack-usage=
Common Joined RejectNegative UInteger Var(warn_stack_usage) Init(-1) Warning
Warn if stack usage might be larger than specified amount
Wstrict-aliasing
Common Warning
Warn about code which might break strict aliasing rules

View file

@ -7522,7 +7522,7 @@ alpha_expand_prologue (void)
sa_size = alpha_sa_size ();
frame_size = compute_frame_size (get_frame_size (), sa_size);
if (flag_stack_usage)
if (flag_stack_usage_info)
current_function_static_stack_size = frame_size;
if (TARGET_ABI_OPEN_VMS)

View file

@ -15815,7 +15815,7 @@ arm_expand_prologue (void)
}
}
if (flag_stack_usage)
if (flag_stack_usage_info)
current_function_static_stack_size
= offsets->outgoing_args - offsets->saved_args;
@ -20800,7 +20800,7 @@ thumb1_expand_prologue (void)
emit_move_insn (gen_rtx_REG (Pmode, ARM_HARD_FRAME_POINTER_REGNUM),
stack_pointer_rtx);
if (flag_stack_usage)
if (flag_stack_usage_info)
current_function_static_stack_size
= offsets->outgoing_args - offsets->saved_args;

View file

@ -892,7 +892,7 @@ expand_prologue (void)
}
}
if (flag_stack_usage)
if (flag_stack_usage_info)
current_function_static_stack_size = cfun->machine->stack_usage;
}

View file

@ -10546,7 +10546,7 @@ ix86_expand_prologue (void)
allocate = frame.stack_pointer_offset - m->fs.sp_offset;
if (flag_stack_usage)
if (flag_stack_usage_info)
{
/* We start to count from ARG_POINTER. */
HOST_WIDE_INT stack_size = frame.stack_pointer_offset;

View file

@ -3183,7 +3183,7 @@ ia64_expand_prologue (void)
ia64_compute_frame_size (get_frame_size ());
last_scratch_gr_reg = 15;
if (flag_stack_usage)
if (flag_stack_usage_info)
current_function_static_stack_size = current_frame_info.total_size;
if (dump_file)

View file

@ -981,7 +981,7 @@ m68k_expand_prologue (void)
m68k_compute_frame_layout ();
if (flag_stack_usage)
if (flag_stack_usage_info)
current_function_static_stack_size
= current_frame.size + current_frame.offset;

View file

@ -10008,7 +10008,7 @@ mips_expand_prologue (void)
frame = &cfun->machine->frame;
size = frame->total_size;
if (flag_stack_usage)
if (flag_stack_usage_info)
current_function_static_stack_size = size;
/* Save the registers. Allocate up to MIPS_MAX_FIRST_STACK_STEP

View file

@ -3807,7 +3807,7 @@ hppa_expand_prologue (void)
local_fsize += STARTING_FRAME_OFFSET;
actual_fsize = compute_frame_size (size, &save_fregs);
if (flag_stack_usage)
if (flag_stack_usage_info)
current_function_static_stack_size = actual_fsize;
/* Compute a few things we will use often. */

View file

@ -20116,7 +20116,7 @@ rs6000_emit_prologue (void)
&& call_used_regs[STATIC_CHAIN_REGNUM]);
HOST_WIDE_INT sp_offset = 0;
if (flag_stack_usage)
if (flag_stack_usage_info)
current_function_static_stack_size = info->total_size;
if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)

View file

@ -8097,7 +8097,7 @@ s390_emit_prologue (void)
if (!TARGET_PACKED_STACK)
next_fpr = cfun_save_high_fprs_p ? 31 : 0;
if (flag_stack_usage)
if (flag_stack_usage_info)
current_function_static_stack_size = cfun_frame_layout.frame_size;
/* Decrement stack pointer. */

View file

@ -7349,7 +7349,7 @@ sh_expand_prologue (void)
emit_insn (gen_shcompact_incoming_args ());
}
if (flag_stack_usage)
if (flag_stack_usage_info)
current_function_static_stack_size = stack_usage;
}

View file

@ -4522,7 +4522,7 @@ sparc_expand_prologue (void)
/* Advertise that the data calculated just above are now valid. */
sparc_prologue_data_valid_p = true;
if (flag_stack_usage)
if (flag_stack_usage_info)
current_function_static_stack_size = actual_fsize;
if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && actual_fsize)

View file

@ -2101,7 +2101,7 @@ spu_expand_prologue (void)
}
}
if (flag_stack_usage)
if (flag_stack_usage_info)
current_function_static_stack_size = total_size;
}

View file

@ -260,7 +260,7 @@ Objective-C and Objective-C++ Dialects}.
-Wredundant-decls @gol
-Wreturn-type -Wsequence-point -Wshadow @gol
-Wsign-compare -Wsign-conversion -Wstack-protector @gol
-Wstrict-aliasing -Wstrict-aliasing=n @gol
-Wstack-usage=@var{len} -Wstrict-aliasing -Wstrict-aliasing=n @gol
-Wstrict-overflow -Wstrict-overflow=@var{n} @gol
-Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{]} @gol
-Wswitch -Wswitch-default -Wswitch-enum -Wsync-nand @gol
@ -3924,6 +3924,37 @@ via @code{alloca}, variable-length arrays, or related constructs
is not included by the compiler when determining
whether or not to issue a warning.
@item -Wstack-usage=@var{len}
@opindex Wstack-usage
Warn if the stack usage of a function might be larger than @var{len} bytes.
The computation done to determine the stack usage is conservative.
Any space allocated via @code{alloca}, variable-length arrays, or related
constructs is included by the compiler when determining whether or not to
issue a warning.
The message is in keeping with the output of @option{-fstack-usage}.
@itemize
@item
If the stack usage is fully static but exceeds the specified amount, it's:
@smallexample
  warning: stack usage is 1120 bytes
@end smallexample
@item
If the stack usage is (partly) dynamic but bounded, it's:
@smallexample
  warning: stack usage might be 1648 bytes
@end smallexample
@item
If the stack usage is (partly) dynamic and not bounded, it's:
@smallexample
  warning: stack usage might be unbounded
@end smallexample
@end itemize
@item -Wunsafe-loop-optimizations
@opindex Wunsafe-loop-optimizations
@opindex Wno-unsafe-loop-optimizations

View file

@ -1150,7 +1150,7 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
/* If stack usage info is requested, look into the size we are passed.
We need to do so this early to avoid the obfuscation that may be
introduced later by the various alignment operations. */
if (flag_stack_usage)
if (flag_stack_usage_info)
{
if (CONST_INT_P (size))
stack_usage_size = INTVAL (size);
@ -1242,7 +1242,7 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
size = plus_constant (size, extra);
size = force_operand (size, NULL_RTX);
if (flag_stack_usage)
if (flag_stack_usage_info)
stack_usage_size += extra;
if (extra && size_align > extra_align)
@ -1273,7 +1273,7 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
/* The above dynamic offset cannot be computed statically at this
point, but it will be possible to do so after RTL expansion is
done. Record how many times we will need to add it. */
if (flag_stack_usage)
if (flag_stack_usage_info)
current_function_dynamic_alloc_count++;
/* ??? Can we infer a minimum of STACK_BOUNDARY here? */
@ -1298,7 +1298,7 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
{
size = round_push (size);
if (flag_stack_usage)
if (flag_stack_usage_info)
{
int align = crtl->preferred_stack_boundary / BITS_PER_UNIT;
stack_usage_size = (stack_usage_size + align - 1) / align * align;
@ -1309,7 +1309,7 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
/* The size is supposed to be fully adjusted at this point so record it
if stack usage info is requested. */
if (flag_stack_usage)
if (flag_stack_usage_info)
{
current_function_dynamic_stack_size += stack_usage_size;

View file

@ -1939,7 +1939,7 @@ instantiate_virtual_regs (void)
/* See allocate_dynamic_stack_space for the rationale. */
#ifdef SETJMP_VIA_SAVE_AREA
if (flag_stack_usage && cfun->calls_setjmp)
if (flag_stack_usage_info && cfun->calls_setjmp)
{
int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
dynamic_offset = (dynamic_offset + align - 1) / align * align;
@ -4465,7 +4465,7 @@ prepare_function_start (void)
init_expr ();
default_rtl_profile ();
if (flag_stack_usage)
if (flag_stack_usage_info)
{
cfun->su = ggc_alloc_cleared_stack_usage ();
cfun->su->static_stack_size = -1;
@ -5939,7 +5939,7 @@ rest_of_handle_thread_prologue_and_epilogue (void)
thread_prologue_and_epilogue_insns ();
/* The stack usage info is finalized during prologue expansion. */
if (flag_stack_usage)
if (flag_stack_usage_info)
output_stack_usage ();
return 0;

View file

@ -1422,6 +1422,11 @@ common_handle_option (struct gcc_options *opts,
opts->x_warn_frame_larger_than = value != -1;
break;
case OPT_Wstack_usage_:
opts->x_warn_stack_usage = value;
opts->x_flag_stack_usage_info = value != -1;
break;
case OPT_Wstrict_aliasing:
set_Wstrict_aliasing (opts, value);
break;
@ -1643,6 +1648,11 @@ common_handle_option (struct gcc_options *opts,
/* Deferred. */
break;
case OPT_fstack_usage:
opts->x_flag_stack_usage = value;
opts->x_flag_stack_usage_info = value != 0;
break;
case OPT_ftree_vectorizer_verbose_:
vect_set_verbosity_level (opts, value);
break;

View file

@ -1,3 +1,8 @@
2011-05-25 Eric Botcazou <ebotcazou@adacore.com>
* gcc.dg/stack-usage-1.c: Adjust comment.
* gcc.dg/stack-usage-2.c: New test.
2011-05-25 Jakub Jelinek <jakub@redhat.com>
PR c++/49136

View file

@ -2,7 +2,7 @@
/* { dg-options "-fstack-usage" } */
/* This is aimed at testing basic support for -fstack-usage in the back-ends.
See the SPARC back-end for an example (grep flag_stack_usage in sparc.c).
See the SPARC back-end for example (grep flag_stack_usage_info in sparc.c).
Once it is implemented, adjust SIZE below so that the stack usage for the
function FOO is reported as 256 or 264 in the stack usage (.su) file.
Then check that this is the actual stack usage in the assembly file. */

View file

@ -0,0 +1,33 @@
/* { dg-do compile } */
/* { dg-options "-Wstack-usage=512" } */
int foo1 (void)
{
char arr[16];
arr[0] = 1;
return 0;
} /* { dg-bogus "stack usage" } */
int foo2 (void)
{
char arr[1024];
arr[0] = 1;
return 0;
} /* { dg-warning "stack usage is \[0-9\]* bytes" } */
int foo3 (void)
{
char arr[1024] __attribute__((aligned (512)));
arr[0] = 1;
/* Force dynamic realignment of argument pointer. */
__builtin_apply ((void (*)()) foo2, 0, 0);
return 0;
} /* { dg-warning "stack usage might be \[0-9\]* bytes" } */
int foo4 (int n)
{
char arr[n];
arr[0] = 1;
return 0;
} /* { dg-warning "stack usage might be unbounded" } */

View file

@ -1048,14 +1048,12 @@ output_stack_usage (void)
};
HOST_WIDE_INT stack_usage = current_function_static_stack_size;
enum stack_usage_kind_type stack_usage_kind;
expanded_location loc;
const char *raw_id, *id;
if (stack_usage < 0)
{
if (!warning_issued)
{
warning (0, "-fstack-usage not supported for this target");
warning (0, "stack usage computation not supported for this target");
warning_issued = true;
}
return;
@ -1082,24 +1080,44 @@ output_stack_usage (void)
stack_usage += current_function_dynamic_stack_size;
}
loc = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
if (flag_stack_usage)
{
expanded_location loc
= expand_location (DECL_SOURCE_LOCATION (current_function_decl));
const char *raw_id, *id;
/* Strip the scope prefix if any. */
raw_id = lang_hooks.decl_printable_name (current_function_decl, 2);
id = strrchr (raw_id, '.');
if (id)
id++;
else
id = raw_id;
/* Strip the scope prefix if any. */
raw_id = lang_hooks.decl_printable_name (current_function_decl, 2);
id = strrchr (raw_id, '.');
if (id)
id++;
else
id = raw_id;
fprintf (stack_usage_file,
"%s:%d:%d:%s\t"HOST_WIDE_INT_PRINT_DEC"\t%s\n",
lbasename (loc.file),
loc.line,
loc.column,
id,
stack_usage,
stack_usage_kind_str[stack_usage_kind]);
fprintf (stack_usage_file,
"%s:%d:%d:%s\t"HOST_WIDE_INT_PRINT_DEC"\t%s\n",
lbasename (loc.file),
loc.line,
loc.column,
id,
stack_usage,
stack_usage_kind_str[stack_usage_kind]);
}
if (warn_stack_usage >= 0)
{
if (stack_usage_kind == DYNAMIC)
warning (OPT_Wstack_usage_, "stack usage might be unbounded");
else if (stack_usage > warn_stack_usage)
{
if (stack_usage_kind == DYNAMIC_BOUNDED)
warning (OPT_Wstack_usage_, "stack usage might be %wd bytes",
stack_usage);
else
warning (OPT_Wstack_usage_, "stack usage is %wd bytes",
stack_usage);
}
}
}
/* Open an auxiliary output file. */