aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRoman Zhuykov <zhroma@ispras.ru>2021-04-30 11:08:03 +0300
committerRoman Zhuykov <zhroma@ispras.ru>2021-04-30 11:08:03 +0300
commit4cf3b10f27b1994cf4a9eb12079d85412ebc7cad (patch)
treebb167747d3cbab6271804ab972913459d96ae480 /gcc
parent17f2908fcf058e145cff275966e34f8c7f57c2c5 (diff)
downloadgcc-4cf3b10f27b1994cf4a9eb12079d85412ebc7cad.zip
gcc-4cf3b10f27b1994cf4a9eb12079d85412ebc7cad.tar.gz
gcc-4cf3b10f27b1994cf4a9eb12079d85412ebc7cad.tar.bz2
modulo-sched: skip loops with strange register defs [PR100225]
PR84878 fix adds an assertion which can fail, e.g. when stack pointer is adjusted inside the loop. We have to prevent it and search earlier for any 'strange' instruction. The solution is to skip the whole loop if using 'note_stores' we found that one of hard registers is in 'df->regular_block_artificial_uses' set. Also patch properly prohibit not single-set instruction in loop body. gcc/ChangeLog: PR rtl-optimization/100225 PR rtl-optimization/84878 * modulo-sched.c (sms_schedule): Use note_stores to skip loops where we have an instruction which touches (writes) any hard register from df->regular_block_artificial_uses set. Allow not-single-set instruction only right before basic block tail. gcc/testsuite/ChangeLog: PR rtl-optimization/100225 PR rtl-optimization/84878 * gcc.dg/pr100225.c: New test. libgomp/ChangeLog: * testsuite/libgomp.oacc-c-c++-common/atomic_capture-3.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/modulo-sched.c56
-rw-r--r--gcc/testsuite/gcc.dg/pr100225.c15
2 files changed, 50 insertions, 21 deletions
diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
index 6ad960e..e72e46d 100644
--- a/gcc/modulo-sched.c
+++ b/gcc/modulo-sched.c
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "dbgcnt.h"
#include "loop-unroll.h"
+#include "hard-reg-set.h"
#ifdef INSN_SCHEDULING
@@ -1356,6 +1357,7 @@ sms_schedule (void)
basic_block condition_bb = NULL;
edge latch_edge;
HOST_WIDE_INT trip_count, max_trip_count;
+ HARD_REG_SET prohibited_regs;
loop_optimizer_init (LOOPS_HAVE_PREHEADERS
| LOOPS_HAVE_RECORDED_EXITS);
@@ -1385,6 +1387,8 @@ sms_schedule (void)
We use loop->num as index into this array. */
g_arr = XCNEWVEC (ddg_ptr, number_of_loops (cfun));
+ REG_SET_TO_HARD_REG_SET (prohibited_regs, &df->regular_block_artificial_uses);
+
if (dump_file)
{
fprintf (dump_file, "\n\nSMS analysis phase\n");
@@ -1469,23 +1473,31 @@ sms_schedule (void)
}
/* Don't handle BBs with calls or barriers
- or !single_set with the exception of instructions that include
- count_reg---these instructions are part of the control part
- that do-loop recognizes.
+ or !single_set with the exception of do-loop control part insns.
??? Should handle insns defining subregs. */
- for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn))
- {
- rtx set;
-
- if (CALL_P (insn)
- || BARRIER_P (insn)
- || (NONDEBUG_INSN_P (insn) && !JUMP_P (insn)
- && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE
- && !reg_mentioned_p (count_reg, insn))
- || (INSN_P (insn) && (set = single_set (insn))
- && GET_CODE (SET_DEST (set)) == SUBREG))
- break;
- }
+ for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn))
+ {
+ if (INSN_P (insn))
+ {
+ HARD_REG_SET regs;
+ CLEAR_HARD_REG_SET (regs);
+ note_stores (insn, record_hard_reg_sets, &regs);
+ if (hard_reg_set_intersect_p (regs, prohibited_regs))
+ break;
+ }
+
+ if (CALL_P (insn)
+ || BARRIER_P (insn)
+ || (INSN_P (insn) && single_set (insn)
+ && GET_CODE (SET_DEST (single_set (insn))) == SUBREG)
+ /* Not a single set. */
+ || (NONDEBUG_INSN_P (insn) && !JUMP_P (insn)
+ && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE
+ /* But non-single-set allowed in one special case. */
+ && (insn != prev_nondebug_insn (tail)
+ || !reg_mentioned_p (count_reg, insn))))
+ break;
+ }
if (insn != NEXT_INSN (tail))
{
@@ -1495,11 +1507,13 @@ sms_schedule (void)
fprintf (dump_file, "SMS loop-with-call\n");
else if (BARRIER_P (insn))
fprintf (dump_file, "SMS loop-with-barrier\n");
- else if ((NONDEBUG_INSN_P (insn) && !JUMP_P (insn)
- && !single_set (insn) && GET_CODE (PATTERN (insn)) != USE))
- fprintf (dump_file, "SMS loop-with-not-single-set\n");
- else
- fprintf (dump_file, "SMS loop with subreg in lhs\n");
+ else if (INSN_P (insn) && single_set (insn)
+ && GET_CODE (SET_DEST (single_set (insn))) == SUBREG)
+ fprintf (dump_file, "SMS loop with subreg in lhs\n");
+ else
+ fprintf (dump_file,
+ "SMS loop-with-not-single-set-or-prohibited-reg\n");
+
print_rtl_single (dump_file, insn);
}
diff --git a/gcc/testsuite/gcc.dg/pr100225.c b/gcc/testsuite/gcc.dg/pr100225.c
new file mode 100644
index 0000000..b321634
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr100225.c
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/100225 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fmodulo-sched" } */
+
+void
+vorbis_synthesis_lapout (void);
+
+void
+ov_info (int **lappcm, int ov_info_i)
+{
+ while (ov_info_i < 1)
+ lappcm[ov_info_i++] = __builtin_alloca (1);
+
+ vorbis_synthesis_lapout ();
+}