Hi,

On Tue, Sep 05, 2017 at 11:27:25PM +0200, Jakub Jelinek wrote:
> On powerpc with sysv4 -fPIC we emit something like
> .LCL0:
>       .long .LCTOC1-.LCF0
> before we start emitting the function, and in the prologue we emit
> .LCF0:
> and some code.  This fails to assemble if the prologue is emitted in a
> different partition from the start of the function, as e.g. the following
> testcase, where the start of the function is hot, i.e. in .text section,
> but the shrink-wrapped prologue is cold, emitted in .text.unlikely section.
> .LCL0 is still emitted in the section the function starts, thus .text, and
> there is no relocation for subtraction of two symbols in other sections
> (the second - operand has to be in the current section so that a PC-relative
> relocation can be used).  This probably never worked, but is now more
> severe, as we enable hot/cold partitioning in GCC 8, where it
> has been previously only enabled for -fprofile-use.

I wonder if that helps performance at all, for rs6000 anyway...  It's is
a never-ending source of ICEs though :-(

> --- gcc/config/rs6000/rs6000.c.jj     2017-09-04 09:55:28.000000000 +0200
> +++ gcc/config/rs6000/rs6000.c        2017-09-04 16:36:49.033213325 +0200
> @@ -25248,12 +25248,15 @@ 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))
> @@ -25270,10 +25273,14 @@ uses_TOC (void)
>                 sub = XEXP (sub, 0);
>                 if (GET_CODE (sub) == UNSPEC
>                     && XINT (sub, 1) == UNSPEC_TOC)
> -                 return 1;
> +                 return ret;
>               }
>           }
>        }
> +    else if (crtl->has_bb_partition
> +          && NOTE_P (insn)
> +          && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
> +      ret = 2;

}

>    return 0;
>  }
>  #endif


> @@ -33304,14 +33311,20 @@ 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)
> +     {
> +       in_cold_section_p = !in_cold_section_p;
> +       switch_to_section (current_function_section ());
> +     }
>        (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
>  
>        fprintf (file, "\t.long ");
> @@ -33321,6 +33334,11 @@ 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)
> +     {
> +       in_cold_section_p = !in_cold_section_p;
> +       switch_to_section (current_function_section ());
> +     }
>      }

Hrm, does that work if not hot/cold partitioning?  Oh, that cannot happen
because uses_toc==2.  Tricky.

Maybe this "switch to the other section" thing should be abstracted out?
Messing with in_cold_section_p is a bit dirty.

Otherwise looks okay; please add the {} in the first fragment.

Thanks,


Segher

Reply via email to