On Wed, Sep 06, 2017 at 11:48:00AM -0500, Segher Boessenkool wrote:
> On Wed, Sep 06, 2017 at 06:26:10PM +0200, Jakub Jelinek wrote:
> > > Maybe this "switch to the other section" thing should be abstracted out?
> > > Messing with in_cold_section_p is a bit dirty.
> > 
> > But it reflects the reality, and is what final.c and varasm.c also do.
> 
> Yes, but those aren't target code :-)
> 
> I'm suggesting adding a generic 
> switch_from_hot_to_cold_or_the_other_way_around
> function (but with a better name ;-) ) that just does these same two lines,
> only not in target code.  Seems cleaner to me, less surprising.

Richard, is this generic change ok?

2017-09-07  Jakub Jelinek  <ja...@redhat.com>

        PR target/81979
        * output.h (switch_to_other_text_partition): New declaration.
        * varasm.c (switch_to_other_text_partition): New function.
        * config/rs6000/rs6000.c (uses_TOC): Return 2 if
        NOTE_INSN_SWITCH_TEXT_SECTIONS is seen before finding load_toc_* insn.
        (rs6000_elf_declare_function_name): If uses_TOC returned 2, switch
        to the other text partition before emitting LCL label and switch back
        after emitting the word after it.

        * gcc.dg/pr81979.c: New test.

--- gcc/output.h.jj     2017-09-01 09:26:48.000000000 +0200
+++ gcc/output.h        2017-09-07 11:38:48.668090305 +0200
@@ -537,6 +537,7 @@ extern section *mergeable_constant_secti
 extern section *function_section (tree);
 extern section *unlikely_text_section (void);
 extern section *current_function_section (void);
+extern void switch_to_other_text_partition (void);
 
 /* Return the numbered .ctors.N (if CONSTRUCTOR_P) or .dtors.N (if
    not) section for PRIORITY.  */
--- gcc/varasm.c.jj     2017-09-06 11:09:39.000000000 +0200
+++ gcc/varasm.c        2017-09-07 11:35:34.366442544 +0200
@@ -695,6 +695,16 @@ unlikely_text_section_p (section *sect)
   return sect == function_section_1 (current_function_decl, true);
 }
 
+/* Switch to the other function partition (if inside of hot section
+   into cold section, otherwise into the hot section).  */
+
+void
+switch_to_other_text_partition (void)
+{
+  in_cold_section_p = !in_cold_section_p;
+  switch_to_section (current_function_section ());
+}
+
 /* Return the read-only data section associated with function DECL.  */
 
 section *
--- gcc/config/rs6000/rs6000.c.jj       2017-09-05 23:28:22.238928428 +0200
+++ gcc/config/rs6000/rs6000.c  2017-09-07 11:39:25.781640963 +0200
@@ -25324,32 +25324,41 @@ get_TOC_alias_set (void)
 
 /* This returns nonzero if the current function uses the TOC.  This is
    determined by the presence of (use (unspec ... UNSPEC_TOC)), which
-   is generated by the ABI_V4 load_toc_* patterns.  */
+   is generated by the ABI_V4 load_toc_* patterns.
+   Return 2 instead of 1 if the load_toc_* pattern is in the function
+   partition that doesn't start the function.  */
 #if TARGET_ELF
 static int
 uses_TOC (void)
 {
   rtx_insn *insn;
+  int ret = 1;
 
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
-    if (INSN_P (insn))
-      {
-       rtx pat = PATTERN (insn);
-       int i;
+    {
+      if (INSN_P (insn))
+       {
+         rtx pat = PATTERN (insn);
+         int i;
 
-       if (GET_CODE (pat) == PARALLEL)
-         for (i = 0; i < XVECLEN (pat, 0); i++)
-           {
-             rtx sub = XVECEXP (pat, 0, i);
-             if (GET_CODE (sub) == USE)
-               {
-                 sub = XEXP (sub, 0);
-                 if (GET_CODE (sub) == UNSPEC
-                     && XINT (sub, 1) == UNSPEC_TOC)
-                   return 1;
-               }
-           }
-      }
+         if (GET_CODE (pat) == PARALLEL)
+           for (i = 0; i < XVECLEN (pat, 0); i++)
+             {
+               rtx sub = XVECEXP (pat, 0, i);
+               if (GET_CODE (sub) == USE)
+                 {
+                   sub = XEXP (sub, 0);
+                   if (GET_CODE (sub) == UNSPEC
+                       && XINT (sub, 1) == UNSPEC_TOC)
+                     return ret;
+                 }
+             }
+       }
+      else if (crtl->has_bb_partition
+              && NOTE_P (insn)
+              && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
+       ret = 2;
+    }
   return 0;
 }
 #endif
@@ -33380,14 +33389,17 @@ rs6000_elf_declare_function_name (FILE *
       return;
     }
 
+  int uses_toc;
   if (DEFAULT_ABI == ABI_V4
       && (TARGET_RELOCATABLE || flag_pic > 1)
       && !TARGET_SECURE_PLT
       && (!constant_pool_empty_p () || crtl->profile)
-      && uses_TOC ())
+      && (uses_toc = uses_TOC ()))
     {
       char buf[256];
 
+      if (uses_toc == 2)
+       switch_to_other_text_partition ();
       (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
 
       fprintf (file, "\t.long ");
@@ -33397,6 +33409,8 @@ rs6000_elf_declare_function_name (FILE *
       ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
       assemble_name (file, buf);
       putc ('\n', file);
+      if (uses_toc == 2)
+       switch_to_other_text_partition ();
     }
 
   ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
--- gcc/testsuite/gcc.dg/pr81979.c.jj   2017-09-07 11:31:15.893566211 +0200
+++ gcc/testsuite/gcc.dg/pr81979.c      2017-09-07 11:31:15.893566211 +0200
@@ -0,0 +1,32 @@
+/* PR target/81979 */
+/* { dg-do link } */
+/* { dg-options "-O2 -w" } */
+/* { dg-additional-options "-fPIC" { target fpic } } */
+/* { dg-additional-options "-freorder-blocks-and-partition" { target freorder 
} } */
+
+int d;
+
+__attribute__((noinline, noclone)) void
+foo (int x)
+{
+  int c;
+  while (c < 1)
+    {
+      int o;
+      for (o = 0; o < 4; ++o)
+       c /= (x != 0) ? 2 : x;
+    }
+
+  d = 1;
+  for (;;)
+    ;
+}
+
+int
+main ()
+{
+  asm volatile ("" : : "r" (&d) : "memory");
+  foo (d);
+  asm volatile ("" : : "r" (&d) : "memory");
+  return 0;
+}


        Jakub

Reply via email to