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