From 71abcdeeec6c9061302251010b18415620d4d2e2 Mon Sep 17 00:00:00 2001 From: jakub Date: Thu, 7 Sep 2017 11:20:40 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@251843 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 11 +++++++++ gcc/config/rs6000/rs6000.c | 52 +++++++++++++++++++++++++++--------------- gcc/output.h | 1 + gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/pr81979.c | 32 ++++++++++++++++++++++++++ gcc/varasm.c | 10 ++++++++ 6 files changed, 92 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr81979.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8e614f675a8..4b6d9c2b233 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2017-09-07 Jakub Jelinek + + 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 * 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 fdc39d9a64d..ecdf776b986 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 e2d55031a15..e98a911c647 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 d138514b1d5..1080030cf5f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-09-07 Jakub Jelinek + + PR target/81979 + * gcc.dg/pr81979.c: New test. + 2017-09-07 Eric Botcazou PR ada/82126 diff --git a/gcc/testsuite/gcc.dg/pr81979.c b/gcc/testsuite/gcc.dg/pr81979.c new file mode 100644 index 00000000000..4ac9addbc04 --- /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 6177eec118b..a7dca89e6de 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 * -- 2.11.4.GIT