diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-09-07 13:20:40 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-09-07 13:20:40 +0200 |
commit | 86373d9214e40b5a05b1469da4b7a1d92b4a60fc (patch) | |
tree | e19f3204ac224f9a848867cd139c2f2267adc1ab | |
parent | ed323421344929d7b6104566d8301ce4f88fd00c (diff) | |
download | gcc-86373d9214e40b5a05b1469da4b7a1d92b4a60fc.zip gcc-86373d9214e40b5a05b1469da4b7a1d92b4a60fc.tar.gz gcc-86373d9214e40b5a05b1469da4b7a1d92b4a60fc.tar.bz2 |
re PR target/81979 (Assembler messages: Error: can't resolve `.got2' {.got2 section} - `.LCF0' {.text.unlikely section})
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.
From-SVN: r251843
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 52 | ||||
-rw-r--r-- | gcc/output.h | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr81979.c | 32 | ||||
-rw-r--r-- | gcc/varasm.c | 10 |
6 files changed, 92 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8e614f6..4b6d9c2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2017-09-07 Jakub Jelinek <jakub@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. + 2017-09-07 Richard Biener <rguenther@suse.de> * passes.def (pass_split_crit_edges): Remove instance before PRE. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index fdc39d9..ecdf776 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -25277,32 +25277,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 @@ -33336,14 +33345,17 @@ rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl) 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 "); @@ -33353,6 +33365,8 @@ rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl) 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"); diff --git a/gcc/output.h b/gcc/output.h index e2d5503..e98a911 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -537,6 +537,7 @@ extern section *mergeable_constant_section (machine_mode, 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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d138514..1080030 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-09-07 Jakub Jelinek <jakub@redhat.com> + + PR target/81979 + * gcc.dg/pr81979.c: New test. + 2017-09-07 Eric Botcazou <ebotcazou@adacore.com> PR ada/82126 diff --git a/gcc/testsuite/gcc.dg/pr81979.c b/gcc/testsuite/gcc.dg/pr81979.c new file mode 100644 index 0000000..4ac9add --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr81979.c @@ -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; +} diff --git a/gcc/varasm.c b/gcc/varasm.c index 6177eec..a7dca89 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -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 * |