Message ID | 20160129163824.GQ17028@bubble.grove.modra.org |
---|---|
State | New |
Headers | show |
On Fri, Jan 29, 2016 at 11:38 AM, Alan Modra <amodra@gmail.com> wrote: > Since 4c4a180d, LTO has turned off flag_pic when linking a fixed > position executable. This results in flag_pic being zero in > rs6000_file_start, and no definition of ".LCTOC1". > > However, when we get to actually emitting code, flag_pic may be on > again, and references made to ".LCTOC1". How flag_pic comes to be > enabled again is quite a story. It goes like this.. If a function is > compiled with -fPIC then sysv4.h SUBTARGET_OVERRIDE_OPTIONS will set > TARGET_RELOCATABLE. Conversely, if TARGET_RELOCATABLE is set and > flag_pic is zero, then SUBTARGET_OVERRIDE_OPTIONS will set flag_pic=2. > It also happens that TARGET_RELOCATABLE is a bit in rs6000_isa_flags, > which is handled by rs6000_function_specific_save and > rs6000_function_specific_restore. That last fact means lto streaming > keeps track of the state of TARGET_RELOCATABLE for functions, and when > options are restored for a given function we'll set flag_pic=2 if the > function was originally compiled with -fPIC. That's bad because it > defeats the purpose of the 4c4a180d lto change, resulting in worse > optimization of ppc32 executables. What's more, we don't seem to turn > off flag_pic once it is on. > > We should really untangle the flag_pic/TARGET_RELOCATABLE mess, but > that change is probably a little dangerous for stage4. Instead, this > patch removes the toc symbol initialization from file_start and does > so when the first item is emitted to the toc, or after the function > epilogue in the cases where we emit code to initialize a toc pointer > but don't actually use it (-O0 mostly, I think). > > Bootstrapped and regression tested powerpc64-linux biarch with all > languages enabled. OK to apply? > > PR target/68662 > * config/rs6000/rs6000.c (need_toc_init): New var, set it > whenever toc_label_name used. > (rs6000_file_start): Don't set up toc section here, > (rs6000_output_function_epilogue): do so here instead, > (rs6000_xcoff_file_start): and here. > * config/rs6000/rs6000.md (load_toc_aix_si): Set need_toc_init. > (load_toc_aix_di): Likewise. I'm worried about how this is going to interact with AIX. AIX assembler is single pass and this patch moves the initialization from the beginning of the file to the end of the file, which means there will be references to a label whose definition is delayed until the end. - David
On Fri, Jan 29, 2016 at 01:20:08PM -0500, David Edelsohn wrote: > On Fri, Jan 29, 2016 at 11:38 AM, Alan Modra <amodra@gmail.com> wrote: > > PR target/68662 > > * config/rs6000/rs6000.c (need_toc_init): New var, set it > > whenever toc_label_name used. > > (rs6000_file_start): Don't set up toc section here, > > (rs6000_output_function_epilogue): do so here instead, > > (rs6000_xcoff_file_start): and here. > > * config/rs6000/rs6000.md (load_toc_aix_si): Set need_toc_init. > > (load_toc_aix_di): Likewise. > > I'm worried about how this is going to interact with AIX. AIX > assembler is single pass and this patch moves the initialization from > the beginning of the file to the end of the file, which means there > will be references to a label whose definition is delayed until the > end. AIX toc init is still done at the start of the file. The code to emit .toc or set .LCTOC..1 has moved from rs6000_file_start to rs6000_xcoff_file_start.
On Fri, Jan 29, 2016 at 11:38 AM, Alan Modra <amodra@gmail.com> wrote: > Since 4c4a180d, LTO has turned off flag_pic when linking a fixed > position executable. This results in flag_pic being zero in > rs6000_file_start, and no definition of ".LCTOC1". > > However, when we get to actually emitting code, flag_pic may be on > again, and references made to ".LCTOC1". How flag_pic comes to be > enabled again is quite a story. It goes like this.. If a function is > compiled with -fPIC then sysv4.h SUBTARGET_OVERRIDE_OPTIONS will set > TARGET_RELOCATABLE. Conversely, if TARGET_RELOCATABLE is set and > flag_pic is zero, then SUBTARGET_OVERRIDE_OPTIONS will set flag_pic=2. > It also happens that TARGET_RELOCATABLE is a bit in rs6000_isa_flags, > which is handled by rs6000_function_specific_save and > rs6000_function_specific_restore. That last fact means lto streaming > keeps track of the state of TARGET_RELOCATABLE for functions, and when > options are restored for a given function we'll set flag_pic=2 if the > function was originally compiled with -fPIC. That's bad because it > defeats the purpose of the 4c4a180d lto change, resulting in worse > optimization of ppc32 executables. What's more, we don't seem to turn > off flag_pic once it is on. > > We should really untangle the flag_pic/TARGET_RELOCATABLE mess, but > that change is probably a little dangerous for stage4. Instead, this > patch removes the toc symbol initialization from file_start and does > so when the first item is emitted to the toc, or after the function > epilogue in the cases where we emit code to initialize a toc pointer > but don't actually use it (-O0 mostly, I think). > > Bootstrapped and regression tested powerpc64-linux biarch with all > languages enabled. OK to apply? > > PR target/68662 > * config/rs6000/rs6000.c (need_toc_init): New var, set it > whenever toc_label_name used. > (rs6000_file_start): Don't set up toc section here, > (rs6000_output_function_epilogue): do so here instead, > (rs6000_xcoff_file_start): and here. > * config/rs6000/rs6000.md (load_toc_aix_si): Set need_toc_init. > (load_toc_aix_di): Likewise. This is okay as an interim fix for GCC 6. Thanks, David
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 4704d00..4ea4efb 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -209,7 +209,7 @@ tree rs6000_builtin_types[RS6000_BTI_MAX]; tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT]; /* Flag to say the TOC is initialized */ -int toc_initialized; +int toc_initialized, need_toc_init; char toc_label_name[10]; /* Cached value of rs6000_variable_issue. This is cached in @@ -5682,13 +5682,6 @@ rs6000_file_start (void) if (DEFAULT_ABI == ABI_ELFv2) fprintf (file, "\t.abiversion 2\n"); - - if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2 - || (TARGET_ELF && flag_pic == 2)) - { - switch_to_section (toc_section); - switch_to_section (text_section); - } } @@ -20375,6 +20368,7 @@ rs6000_output_addr_const_extra (FILE *file, rtx x) { putc ('-', file); assemble_name (file, toc_label_name); + need_toc_init = 1; } else if (TARGET_ELF) fputs ("@toc", file); @@ -24003,7 +23997,10 @@ rs6000_emit_load_toc_table (int fromprolog) ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab)); lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); if (flag_pic == 2) - got = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (toc_label_name)); + { + got = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (toc_label_name)); + need_toc_init = 1; + } else got = rs6000_got_sym (); tmp1 = tmp2 = dest; @@ -24048,6 +24045,7 @@ rs6000_emit_load_toc_table (int fromprolog) rtx tocsym, lab; tocsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (toc_label_name)); + need_toc_init = 1; lab = gen_label_rtx (); emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab)); emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO)); @@ -24062,6 +24060,7 @@ rs6000_emit_load_toc_table (int fromprolog) /* This is for AIX code running in non-PIC ELF32. */ rtx realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (toc_label_name)); + need_toc_init = 1; emit_insn (gen_elf_high (dest, realsym)); emit_insn (gen_elf_low (dest, dest, realsym)); } @@ -27598,6 +27597,17 @@ rs6000_output_function_epilogue (FILE *file, fputs ("\t.align 2\n", file); } + + /* Arrange to define .LCTOC1 label, if not already done. */ + if (need_toc_init) + { + need_toc_init = 0; + if (!toc_initialized) + { + switch_to_section (toc_section); + switch_to_section (current_function_section ()); + } + } } /* -fsplit-stack support. */ @@ -31745,6 +31755,7 @@ rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl) fprintf (file, "\t.long "); assemble_name (file, toc_label_name); + need_toc_init = 1; putc ('-', file); ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); assemble_name (file, buf); @@ -32137,6 +32148,7 @@ rs6000_xcoff_file_start (void) fputc ('\n', asm_out_file); if (write_symbols != NO_DEBUG) switch_to_section (private_data_section); + switch_to_section (toc_section); switch_to_section (text_section); if (profile_flag) fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT); diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 6e22c52..fe19853 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -9475,6 +9475,8 @@ "* { char buf[30]; + extern int need_toc_init; + need_toc_init = 1; ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1); operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); operands[2] = gen_rtx_REG (Pmode, 2); @@ -9492,6 +9494,8 @@ "* { char buf[30]; + extern int need_toc_init; + need_toc_init = 1; #ifdef TARGET_RELOCATABLE ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE);