diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3527b6e58aa4acfb00c4c94c6d5f1474d61055a5..93b086231a13a6f09a18c070cd4a23c0a6186b17 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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> diff --git a/gcc/function.c b/gcc/function.c index 973e5a1d34e1cf45f8b9d867f3e4ecf740f6b2d8..ab1ca9ecf52e06416f9ace41050cd0091c865ec9 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -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. */ diff --git a/gcc/rtl.h b/gcc/rtl.h index 04021a3f29d9a270207bba3350a5fb94a6f46e08..62b677ac3c06226245f8cac560860096a2c18f21 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8c4d5f755e671d9cf4bdec289d3f333ad724e0d8..c1c1fbe5e6024307d845e18473d193b9fe849818 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.target/arm/cold-lc.c b/gcc/testsuite/gcc.target/arm/cold-lc.c new file mode 100644 index 0000000000000000000000000000000000000000..295c29fe8f0c946d679e46fe44e1ceffaf777f91 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/cold-lc.c @@ -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); +} + diff --git a/gcc/varasm.c b/gcc/varasm.c index b4f38058e224cc3fe3288cc52aa7430403225436..f46c21b3bde0affad8e8f382ffabe63eed08088f 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -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. */