Fix modulo-scheduler -fcompare-debug issues
Richard Biener
rguenther@suse.de
Wed Mar 11 08:14:08 GMT 2020
On Tue, 10 Mar 2020, Roman Zhuykov wrote:
> Hi!
>
> Current modulo-sched implementation is a bit faulty from -fcompile-debug perspective.
>
> I found that few years ago, the most simple example is pr42631.c which fails (with just -fmodulo-sched or together with -fmodulo-sched-allow-regmoves) on powerpc64le with at least any gcc-4.9 or newer compiler.
> I've investigated that difference about 3 years ago, it is mostly technical, dumps shows there are some "flying" NOTE_INSN_DELETED items.
> I understood that it is minor, and I planned to commit the fix only when my other modulo-sched stuff will be ready.
>
> But right now I see that when I enable -fmodulo-sched by default, powerpc64le bootstrap give comparison failure as of r10-7056.
>
> Comparing stages 2 and 3
> Bootstrap comparison failure!
> gcc/ggc-page.o differs
>
> That doesn't happen on released branches, so it is a kind of "regression" (certainly, nobody runs bootstrap with -fmodulo-sched).
>
> Is that a good reason to commit the patch right now in stage4?
Yes from a RM perspective, no comments about the technical details of
the patch.
Richard.
> Patch was successfully regstrapped (based on r10-7056) using x86_64 and powerpc64le, both with default options and with -fmodulo-sched enabled.
>
> Roman
>
> --
> modulo-sched: fix compare-debug issues
>
> This patch fixes bootstrap comparison failure on powerpc64le when running it
> with -fmodulo-sched enabled.
>
> When applying the schedule we have to move debug insns in the same
> way as we move note insns. Also we have to discard adding debug insns
> to SCCs in DDG graph.
>
> 20YY-MM-DD Roman Zhuykov <zhroma@ispras.ru>
>
> * ddg.c (create_ddg_dep_from_intra_loop_link): Adjust assertions.
> (create_ddg_dep_no_link): Likewise.
> (add_inter_loop_mem_dep): Do not create "debug --> non-debug" anti-deps.
> (create_ddg): Adjust first_note field filling.
> (check_sccs): Assert if any debug instruction is in SCC.
> * modulo-sched.c (ps_first_note): Add an assertion if first_note
> is empty.
>
> testsuite:
>
> 20YY-MM-DD Roman Zhuykov <zhroma@ispras.ru>
>
> * gcc.dg/pr42631-sms1.c: New test.
> * gcc.dg/pr42631-sms2.c: New test.
>
> diff --git a/gcc/ddg.c b/gcc/ddg.c
> index ca8cb74823..048207a354 100644
> --- a/gcc/ddg.c
> +++ b/gcc/ddg.c
> @@ -185,8 +185,8 @@ create_ddg_dep_from_intra_loop_link (ddg_ptr g, ddg_node_ptr src_node,
> else if (DEP_TYPE (link) == REG_DEP_OUTPUT)
> t = OUTPUT_DEP;
>
> - gcc_assert (!DEBUG_INSN_P (dest_node->insn) || t == ANTI_DEP);
> - gcc_assert (!DEBUG_INSN_P (src_node->insn) || t == ANTI_DEP);
> + gcc_assert (NONDEBUG_INSN_P (dest_node->insn) || t == ANTI_DEP);
> + gcc_assert (NONDEBUG_INSN_P (src_node->insn) || DEBUG_INSN_P (dest_node->insn));
>
> /* We currently choose not to create certain anti-deps edges and
> compensate for that by generating reg-moves based on the life-range
> @@ -222,9 +222,9 @@ create_ddg_dep_from_intra_loop_link (ddg_ptr g, ddg_node_ptr src_node,
> }
> }
>
> - latency = dep_cost (link);
> - e = create_ddg_edge (src_node, dest_node, t, dt, latency, distance);
> - add_edge_to_ddg (g, e);
> + latency = dep_cost (link);
> + e = create_ddg_edge (src_node, dest_node, t, dt, latency, distance);
> + add_edge_to_ddg (g, e);
> }
>
> /* The same as the above function, but it doesn't require a link parameter. */
> @@ -237,8 +237,8 @@ create_ddg_dep_no_link (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to,
> enum reg_note dep_kind;
> struct _dep _dep, *dep = &_dep;
>
> - gcc_assert (!DEBUG_INSN_P (to->insn) || d_t == ANTI_DEP);
> - gcc_assert (!DEBUG_INSN_P (from->insn) || d_t == ANTI_DEP);
> + gcc_assert (NONDEBUG_INSN_P (to->insn) || d_t == ANTI_DEP);
> + gcc_assert (NONDEBUG_INSN_P (from->insn) || DEBUG_INSN_P (to->insn));
>
> if (d_t == ANTI_DEP)
> dep_kind = REG_DEP_ANTI;
> @@ -455,8 +455,12 @@ add_inter_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to)
> return;
> else if (from->cuid != to->cuid)
> {
> - create_ddg_dep_no_link (g, from, to, ANTI_DEP, MEM_DEP, 1);
> - if (DEBUG_INSN_P (from->insn) || DEBUG_INSN_P (to->insn))
> + gcc_assert (NONDEBUG_INSN_P (to->insn));
> +
> + if (NONDEBUG_INSN_P (from->insn))
> + create_ddg_dep_no_link (g, from, to, ANTI_DEP, MEM_DEP, 1);
> +
> + if (DEBUG_INSN_P (from->insn))
> create_ddg_dep_no_link (g, to, from, ANTI_DEP, MEM_DEP, 1);
> else
> create_ddg_dep_no_link (g, to, from, TRUE_DEP, MEM_DEP, 1);
> @@ -607,28 +611,34 @@ create_ddg (basic_block bb, int closing_branch_deps)
> if (! INSN_P (insn))
> {
> if (! first_note && NOTE_P (insn)
> - && NOTE_KIND (insn) != NOTE_INSN_BASIC_BLOCK)
> + && NOTE_KIND (insn) != NOTE_INSN_BASIC_BLOCK)
> first_note = insn;
> continue;
> }
> +
> if (JUMP_P (insn))
> {
> gcc_assert (!g->closing_branch);
> g->closing_branch = &g->nodes[i];
> }
> - else if (GET_CODE (PATTERN (insn)) == USE)
> - {
> - if (! first_note)
> - first_note = insn;
> - continue;
> - }
> +
> + if (! first_note)
> + first_note = insn;
> +
> + if (GET_CODE (PATTERN (insn)) == USE)
> + continue;
>
> g->nodes[i].cuid = i;
> g->nodes[i].successors = sbitmap_alloc (num_nodes);
> bitmap_clear (g->nodes[i].successors);
> g->nodes[i].predecessors = sbitmap_alloc (num_nodes);
> bitmap_clear (g->nodes[i].predecessors);
> - g->nodes[i].first_note = (first_note ? first_note : insn);
> +
> + if (! DEBUG_INSN_P (insn))
> + {
> + g->nodes[i].first_note = first_note;
> + first_note = NULL;
> + }
>
> g->nodes[i].aux.count = -1;
> g->nodes[i].max_dist = XCNEWVEC (int, num_nodes);
> @@ -636,7 +646,6 @@ create_ddg (basic_block bb, int closing_branch_deps)
> g->nodes[i].max_dist[j] = -1;
>
> g->nodes[i++].insn = insn;
> - first_note = NULL;
> }
>
> /* We must have found a branch in DDG. */
> @@ -1002,13 +1011,19 @@ order_sccs (ddg_all_sccs_ptr g)
> static void
> check_sccs (ddg_all_sccs_ptr sccs, int num_nodes)
> {
> - int i = 0;
> + int i;
> + unsigned int j;
> auto_sbitmap tmp (num_nodes);
>
> bitmap_clear (tmp);
> for (i = 0; i < sccs->num_sccs; i++)
> {
> + sbitmap_iterator sbi;
> gcc_assert (!bitmap_empty_p (sccs->sccs[i]->nodes));
> + /* Debug insns should not be in found SCCs. */
> + EXECUTE_IF_SET_IN_BITMAP (sccs->sccs[i]->nodes, 0, j, sbi)
> + gcc_assert (NONDEBUG_INSN_P (sccs->ddg->nodes[j].insn));
> +
> /* Verify that every node in sccs is in exactly one strongly
> connected component. */
> gcc_assert (!bitmap_intersect_p (tmp, sccs->sccs[i]->nodes));
> diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
> index e16e023243..3f6aa8c7c2 100644
> --- a/gcc/modulo-sched.c
> +++ b/gcc/modulo-sched.c
> @@ -318,6 +318,7 @@ static rtx_insn *
> ps_first_note (partial_schedule_ptr ps, int id)
> {
> gcc_assert (id < ps->g->num_nodes);
> + gcc_assert (ps->g->nodes[id].first_note);
> return ps->g->nodes[id].first_note;
> }
>
> diff --git a/gcc/testsuite/gcc.dg/pr42631-sms1.c b/gcc/testsuite/gcc.dg/pr42631-sms1.c
> new file mode 100644
> index 0000000000..0117276c73
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr42631-sms1.c
> @@ -0,0 +1,9 @@
> +/* { dg-do compile } */
> +/* { dg-options "-g -O1 -funroll-loops -fmodulo-sched -fcompare-debug" } */
> +/* { dg-xfail-if "" { powerpc-ibm-aix* } } */
> +
> +void foo()
> +{
> + unsigned k;
> + while (--k > 0);
> +}
> diff --git a/gcc/testsuite/gcc.dg/pr42631-sms2.c b/gcc/testsuite/gcc.dg/pr42631-sms2.c
> new file mode 100644
> index 0000000000..2555da4522
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr42631-sms2.c
> @@ -0,0 +1,9 @@
> +/* { dg-do compile } */
> +/* { dg-options "-g -O1 -funroll-loops -fmodulo-sched -fmodulo-sched-allow-regmoves -fcompare-debug" } */
> +/* { dg-xfail-if "" { powerpc-ibm-aix* } } */
> +
> +void foo()
> +{
> + unsigned k;
> + while (--k > 0);
> +}
>
--
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)
More information about the Gcc-patches
mailing list