function.c (init_function_start): Call decide_function_section.

* function.c (init_function_start): Call decide_function_section.
	* varasm.c (decide_function_section): New function.
	(assemble_start_function): When not using
	flag_reorder_blocks_and_partition, don't compute in_cold_section_p
	or first_function_block_is_cold.
	* rtl.h (decide_function_section): Declare.

	* gcc.target/arm/cold-lc.c: New test.

From-SVN: r173303
This commit is contained in:
Bernd Schmidt 2011-05-03 13:08:36 +00:00 committed by Bernd Schmidt
parent 17038fcf96
commit 2c7eebae8a
6 changed files with 67 additions and 11 deletions

View File

@ -1,3 +1,12 @@
2011-05-03 Bernd Schmidt <bernds@codesourcery.com>
* function.c (init_function_start): Call decide_function_section.
* varasm.c (decide_function_section): New function.
(assemble_start_function): When not using
flag_reorder_blocks_and_partition, don't compute in_cold_section_p
or first_function_block_is_cold.
* rtl.h (decide_function_section): Declare.
2011-05-03 Uros Bizjak <ubizjak@gmail.com>
Jakub Jelinek <jakub@redhat.com>

View File

@ -4515,6 +4515,7 @@ init_function_start (tree subr)
else
allocate_struct_function (subr, false);
prepare_function_start ();
decide_function_section (subr);
/* Warn if this value is an aggregate type,
regardless of which calling convention we are using for it. */

View File

@ -1668,6 +1668,7 @@ extern rtx get_pool_constant (rtx);
extern rtx get_pool_constant_mark (rtx, bool *);
extern enum machine_mode get_pool_mode (const_rtx);
extern rtx simplify_subtraction (rtx);
extern void decide_function_section (tree);
/* In function.c */
extern rtx assign_stack_local (enum machine_mode, HOST_WIDE_INT, int);

View File

@ -1,3 +1,7 @@
2011-05-03 Bernd Schmidt <bernds@codesourcery.com>
* gcc.target/arm/cold-lc.c: New test.
2011-05-03 Jakub Jelinek <jakub@redhat.com>
PR target/48774

View File

@ -0,0 +1,22 @@
/* { dg-do compile } */
/* { dg-options "-O2 -mlong-calls" } */
/* { dg-final { scan-assembler-not "bl\[^\n\]*dump_stack" } } */
extern void dump_stack (void) __attribute__ ((__cold__)) __attribute__ ((noinline));
struct thread_info {
struct task_struct *task;
};
extern struct thread_info *current_thread_info (void);
void dump_stack (void)
{
unsigned long stack;
show_stack ((current_thread_info ()->task), &stack);
}
void die (char *str, void *fp, int nr)
{
dump_stack ();
while (1);
}

View File

@ -1512,6 +1512,33 @@ notice_global_symbol (tree decl)
}
}
/* If not using flag_reorder_blocks_and_partition, decide early whether the
current function goes into the cold section, so that targets can use
current_function_section during RTL expansion. DECL describes the
function. */
void
decide_function_section (tree decl)
{
first_function_block_is_cold = false;
if (flag_reorder_blocks_and_partition)
/* We will decide in assemble_start_function. */
return;
if (DECL_SECTION_NAME (decl))
{
struct cgraph_node *node = cgraph_get_node (current_function_decl);
/* Calls to function_section rely on first_function_block_is_cold
being accurate. */
first_function_block_is_cold = (node
&& node->frequency
== NODE_FREQUENCY_UNLIKELY_EXECUTED);
}
in_cold_section_p = first_function_block_is_cold;
}
/* Output assembler code for the constant pool of a function and associated
with defining the name of the function. DECL describes the function.
NAME is the function's name. For the constant pool, we use the current
@ -1524,7 +1551,6 @@ assemble_start_function (tree decl, const char *fnname)
char tmp_label[100];
bool hot_label_written = false;
first_function_block_is_cold = false;
if (flag_reorder_blocks_and_partition)
{
ASM_GENERATE_INTERNAL_LABEL (tmp_label, "LHOTB", const_labelno);
@ -1559,6 +1585,8 @@ assemble_start_function (tree decl, const char *fnname)
if (flag_reorder_blocks_and_partition)
{
first_function_block_is_cold = false;
switch_to_section (unlikely_text_section ());
assemble_align (DECL_ALIGN (decl));
ASM_OUTPUT_LABEL (asm_out_file, crtl->subsections.cold_section_label);
@ -1575,18 +1603,9 @@ assemble_start_function (tree decl, const char *fnname)
hot_label_written = true;
first_function_block_is_cold = true;
}
}
else if (DECL_SECTION_NAME (decl))
{
struct cgraph_node *node = cgraph_get_node (current_function_decl);
/* Calls to function_section rely on first_function_block_is_cold
being accurate. */
first_function_block_is_cold = (node
&& node->frequency
== NODE_FREQUENCY_UNLIKELY_EXECUTED);
in_cold_section_p = first_function_block_is_cold;
}
in_cold_section_p = first_function_block_is_cold;
/* Switch to the correct text section for the start of the function. */