aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-09-07 13:20:40 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2017-09-07 13:20:40 +0200
commit86373d9214e40b5a05b1469da4b7a1d92b4a60fc (patch)
treee19f3204ac224f9a848867cd139c2f2267adc1ab
parented323421344929d7b6104566d8301ce4f88fd00c (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--gcc/config/rs6000/rs6000.c52
-rw-r--r--gcc/output.h1
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr81979.c32
-rw-r--r--gcc/varasm.c10
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 *