* function.c (init_function_start): Call decide_function_section.
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 May 2011 13:08:36 +0000 (13:08 +0000)
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 May 2011 13:08:36 +0000 (13:08 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@173303 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/function.c
gcc/rtl.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/cold-lc.c [new file with mode: 0644]
gcc/varasm.c

index 3527b6e..93b0862 100644 (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>
 
index 973e5a1..ab1ca9e 100644 (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.  */
index 04021a3..62b677a 100644 (file)
--- 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);
index 8c4d5f7..c1c1fbe 100644 (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
diff --git a/gcc/testsuite/gcc.target/arm/cold-lc.c b/gcc/testsuite/gcc.target/arm/cold-lc.c
new file mode 100644 (file)
index 0000000..295c29f
--- /dev/null
@@ -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);
+}
+
index b4f3805..f46c21b 100644 (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.  */