gcc/speed-up-DDG-analysis-and-fix-bootstrap-compare-debug.patch
eastb233 01e0ec8ea6 Upload GCC feature and bugfix patches.
- avoid-cycling-on-vertain-subreg-reloads.patch: Add patch source comment
- change-gcc-BASE-VER.patch: Likewise
- dont-generate-IF_THEN_ELSE.patch: Likewise
- fix-ICE-in-compute_live_loop_exits.patch: Likewise
- fix-ICE-in-eliminate_stmt.patch: Likewise
- fix-ICE-in-vect_create_epilog_for_reduction.patch: Likewise
- fix-ICE-in-vect_stmt_to_vectorize.patch: Likewise
- fix-ICE-in-verify_ssa.patch: Likewise
- fix-ICE-when-vectorizing-nested-cycles.patch: Likewise
- fix-cost-of-plus.patch: Likewise
- ipa-const-prop-self-recursion-bugfix.patch: Likewise
- simplify-removing-subregs.patch: Likewise
- medium-code-mode.patch: Bugfix
- fix-when-peeling-for-alignment.patch: Move to ...
- fix-PR-92351-When-peeling-for-alignment.patch: ... this
- AArch64-Fix-constraints-for-CPY-M.patch: New file
- Apply-maximum-nunits-for-BB-SLP.patch: New file
- Fix-EXTRACT_LAST_REDUCTION-segfault.patch: New file
- Fix-up-push_partial_def-little-endian-bitfield.patch: New file
- Fix-zero-masking-for-vcvtps2ph.patch: New file
- IRA-Handle-fully-tied-destinations.patch: New file
- SLP-VECT-Add-check-to-fix-96837.patch: New file
- aarch64-Fix-ash-lr-lshr-mode-3-expanders.patch: New file
- aarch64-Fix-bf16-and-matrix-g++-gfortran.patch: New file
- aarch64-Fix-mismatched-SVE-predicate-modes.patch: New file
- aarch64-fix-sve-acle-error.patch: New file
- adjust-vector-cost-and-move-EXTRACT_LAST_REDUCTION-costing.patch: New file
- bf16-and-matrix-characteristic.patch: New file
- fix-ICE-IPA-compare-VRP-types.patch: New file
- fix-ICE-in-affine-combination.patch: New file
- fix-ICE-in-pass-vect.patch: New file
- fix-ICE-in-vect_update_misalignment_for_peel.patch: New file
- fix-addlosymdi-ICE-in-pass-reload.patch: New file
- fix-an-ICE-in-vect_recog_mask_conversion_pattern.patch: New file
- fix-avx512vl-vcvttpd2dq-2-fail.patch: New file
- fix-issue499-add-nop-convert.patch: New file
- fix-issue604-ldist-dependency-fixup.patch: New file
- modulo-sched-Carefully-process-loop-counter-initiali.patch: New file
- re-PR-target-91124-gcc.target-i386-avx512vl-vpshldvd.patch: New file
- reduction-paths-with-unhandled-live-stmt.patch: New file
- redundant-loop-elimination.patch: New file
- sccvn-Improve-handling-of-load-masked-with-integer.patch: New file
- speed-up-DDG-analysis-and-fix-bootstrap-compare-debug.patch: New file
- store-merging-Consider-also-overlapping-stores-earlier.patch: New file
- tree-optimization-96920-another-ICE-when-vectorizing.patch: New file
- tree-optimization-97812-fix-range-query-in-VRP-asser.patch: New file
- vectorizable-comparison-Swap-operands-only-once.patch: New file
- x86-Fix-bf16-and-matrix.patch: New file
2020-12-30 09:54:10 +08:00

719 lines
22 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This backport contains 2 patchs from gcc main stream tree.
The commit id of these patchs list as following in the order of time.
728c2e5eeaa91cf708f2b1b1f996653a7eebae59
0001-modulo-sched-speed-up-DDG-analysis-PR90001.patch
06d5d63d9944691bb4286e5f6b2422cc97148336
0001-modulo-sched-fix-bootstrap-compare-debug-issue.patch
diff -Nurp a/gcc/ddg.c b/gcc/ddg.c
--- a/gcc/ddg.c 2020-11-28 18:40:12.371633230 +0800
+++ b/gcc/ddg.c 2020-11-28 18:38:33.835633230 +0800
@@ -32,9 +32,6 @@ along with GCC; see the file COPYING3.
#ifdef INSN_SCHEDULING
-/* A flag indicating that a ddg edge belongs to an SCC or not. */
-enum edge_flag {NOT_IN_SCC = 0, IN_SCC};
-
/* Forward declarations. */
static void add_backarc_to_ddg (ddg_ptr, ddg_edge_ptr);
static void add_backarc_to_scc (ddg_scc_ptr, ddg_edge_ptr);
@@ -188,9 +185,6 @@ create_ddg_dep_from_intra_loop_link (ddg
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);
-
/* We currently choose not to create certain anti-deps edges and
compensate for that by generating reg-moves based on the life-range
analysis. The anti-deps that will be deleted are the ones which
@@ -225,9 +219,9 @@ create_ddg_dep_from_intra_loop_link (ddg
}
}
- 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. */
@@ -240,9 +234,6 @@ create_ddg_dep_no_link (ddg_ptr g, ddg_n
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);
-
if (d_t == ANTI_DEP)
dep_kind = REG_DEP_ANTI;
else if (d_t == OUTPUT_DEP)
@@ -275,16 +266,15 @@ create_ddg_dep_no_link (ddg_ptr g, ddg_n
static void
add_cross_iteration_register_deps (ddg_ptr g, df_ref last_def)
{
- int regno = DF_REF_REGNO (last_def);
struct df_link *r_use;
int has_use_in_bb_p = false;
- rtx_insn *def_insn = DF_REF_INSN (last_def);
- ddg_node_ptr last_def_node = get_node_of_insn (g, def_insn);
- ddg_node_ptr use_node;
+ int regno = DF_REF_REGNO (last_def);
+ ddg_node_ptr last_def_node = get_node_of_insn (g, DF_REF_INSN (last_def));
df_ref first_def = df_bb_regno_first_def_find (g->bb, regno);
+ ddg_node_ptr first_def_node = get_node_of_insn (g, DF_REF_INSN (first_def));
+ ddg_node_ptr use_node;
- gcc_assert (last_def_node);
- gcc_assert (first_def);
+ gcc_assert (last_def_node && first_def && first_def_node);
if (flag_checking && DF_REF_ID (last_def) != DF_REF_ID (first_def))
{
@@ -303,6 +293,9 @@ add_cross_iteration_register_deps (ddg_p
rtx_insn *use_insn = DF_REF_INSN (r_use->ref);
+ if (DEBUG_INSN_P (use_insn))
+ continue;
+
/* ??? Do not handle uses with DF_REF_IN_NOTE notes. */
use_node = get_node_of_insn (g, use_insn);
gcc_assert (use_node);
@@ -313,35 +306,28 @@ add_cross_iteration_register_deps (ddg_p
iteration. Any such upwards exposed use appears before
the last_def def. */
create_ddg_dep_no_link (g, last_def_node, use_node,
- DEBUG_INSN_P (use_insn) ? ANTI_DEP : TRUE_DEP,
- REG_DEP, 1);
+ TRUE_DEP, REG_DEP, 1);
}
- else if (!DEBUG_INSN_P (use_insn))
+ else
{
/* Add anti deps from last_def's uses in the current iteration
to the first def in the next iteration. We do not add ANTI
dep when there is an intra-loop TRUE dep in the opposite
direction, but use regmoves to fix such disregarded ANTI
deps when broken. If the first_def reaches the USE then
- there is such a dep. */
- ddg_node_ptr first_def_node = get_node_of_insn (g,
- DF_REF_INSN (first_def));
-
- gcc_assert (first_def_node);
-
- /* Always create the edge if the use node is a branch in
- order to prevent the creation of reg-moves.
- If the address that is being auto-inc or auto-dec in LAST_DEF
- is used in USE_INSN then do not remove the edge to make sure
- reg-moves will not be created for that address. */
- if (DF_REF_ID (last_def) != DF_REF_ID (first_def)
- || !flag_modulo_sched_allow_regmoves
+ there is such a dep.
+ Always create the edge if the use node is a branch in
+ order to prevent the creation of reg-moves.
+ If the address that is being auto-inc or auto-dec in LAST_DEF
+ is used in USE_INSN then do not remove the edge to make sure
+ reg-moves will not be created for that address. */
+ if (DF_REF_ID (last_def) != DF_REF_ID (first_def)
+ || !flag_modulo_sched_allow_regmoves
|| JUMP_P (use_node->insn)
- || autoinc_var_is_used_p (DF_REF_INSN (last_def), use_insn)
+ || autoinc_var_is_used_p (DF_REF_INSN (last_def), use_insn)
|| def_has_ccmode_p (DF_REF_INSN (last_def)))
- create_ddg_dep_no_link (g, use_node, first_def_node, ANTI_DEP,
- REG_DEP, 1);
-
+ create_ddg_dep_no_link (g, use_node, first_def_node, ANTI_DEP,
+ REG_DEP, 1);
}
}
/* Create an inter-loop output dependence between LAST_DEF (which is the
@@ -351,19 +337,11 @@ add_cross_iteration_register_deps (ddg_p
defs starting with a true dependence to a use which can be in the
next iteration; followed by an anti dependence of that use to the
first def (i.e. if there is a use between the two defs.) */
- if (!has_use_in_bb_p)
- {
- ddg_node_ptr dest_node;
-
- if (DF_REF_ID (last_def) == DF_REF_ID (first_def))
- return;
-
- dest_node = get_node_of_insn (g, DF_REF_INSN (first_def));
- gcc_assert (dest_node);
- create_ddg_dep_no_link (g, last_def_node, dest_node,
- OUTPUT_DEP, REG_DEP, 1);
- }
+ if (!has_use_in_bb_p && DF_REF_ID (last_def) != DF_REF_ID (first_def))
+ create_ddg_dep_no_link (g, last_def_node, first_def_node,
+ OUTPUT_DEP, REG_DEP, 1);
}
+
/* Build inter-loop dependencies, by looking at DF analysis backwards. */
static void
build_inter_loop_deps (ddg_ptr g)
@@ -420,13 +398,9 @@ add_intra_loop_mem_dep (ddg_ptr g, ddg_n
if (mem_write_insn_p (from->insn))
{
if (mem_read_insn_p (to->insn))
- create_ddg_dep_no_link (g, from, to,
- DEBUG_INSN_P (to->insn)
- ? ANTI_DEP : TRUE_DEP, MEM_DEP, 0);
+ create_ddg_dep_no_link (g, from, to, TRUE_DEP, MEM_DEP, 0);
else
- create_ddg_dep_no_link (g, from, to,
- DEBUG_INSN_P (to->insn)
- ? ANTI_DEP : OUTPUT_DEP, MEM_DEP, 0);
+ create_ddg_dep_no_link (g, from, to, OUTPUT_DEP, MEM_DEP, 0);
}
else if (!mem_read_insn_p (to->insn))
create_ddg_dep_no_link (g, from, to, ANTI_DEP, MEM_DEP, 0);
@@ -444,13 +418,9 @@ add_inter_loop_mem_dep (ddg_ptr g, ddg_n
if (mem_write_insn_p (from->insn))
{
if (mem_read_insn_p (to->insn))
- create_ddg_dep_no_link (g, from, to,
- DEBUG_INSN_P (to->insn)
- ? ANTI_DEP : TRUE_DEP, MEM_DEP, 1);
+ create_ddg_dep_no_link (g, from, to, TRUE_DEP, MEM_DEP, 1);
else if (from->cuid != to->cuid)
- create_ddg_dep_no_link (g, from, to,
- DEBUG_INSN_P (to->insn)
- ? ANTI_DEP : OUTPUT_DEP, MEM_DEP, 1);
+ create_ddg_dep_no_link (g, from, to, OUTPUT_DEP, MEM_DEP, 1);
}
else
{
@@ -459,13 +429,9 @@ add_inter_loop_mem_dep (ddg_ptr g, ddg_n
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))
- 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);
+ create_ddg_dep_no_link (g, to, from, TRUE_DEP, MEM_DEP, 1);
}
}
-
}
/* Perform intra-block Data Dependency analysis and connect the nodes in
@@ -494,20 +460,10 @@ build_intra_loop_deps (ddg_ptr g)
sd_iterator_def sd_it;
dep_t dep;
- if (! INSN_P (dest_node->insn))
- continue;
-
FOR_EACH_DEP (dest_node->insn, SD_LIST_BACK, sd_it, dep)
{
rtx_insn *src_insn = DEP_PRO (dep);
- ddg_node_ptr src_node;
-
- /* Don't add dependencies on debug insns to non-debug insns
- to avoid codegen differences between -g and -g0. */
- if (DEBUG_INSN_P (src_insn) && !DEBUG_INSN_P (dest_node->insn))
- continue;
-
- src_node = get_node_of_insn (g, src_insn);
+ ddg_node_ptr src_node = get_node_of_insn (g, src_insn);
if (!src_node)
continue;
@@ -524,8 +480,7 @@ build_intra_loop_deps (ddg_ptr g)
for (j = 0; j <= i; j++)
{
ddg_node_ptr j_node = &g->nodes[j];
- if (DEBUG_INSN_P (j_node->insn))
- continue;
+
if (mem_access_insn_p (j_node->insn))
{
/* Don't bother calculating inter-loop dep if an intra-loop dep
@@ -564,7 +519,7 @@ create_ddg (basic_block bb, int closing_
{
ddg_ptr g;
rtx_insn *insn, *first_note;
- int i;
+ int i, j;
int num_nodes = 0;
g = (ddg_ptr) xcalloc (1, sizeof (struct ddg));
@@ -576,23 +531,21 @@ create_ddg (basic_block bb, int closing_
for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
{
- if (! INSN_P (insn) || GET_CODE (PATTERN (insn)) == USE)
+ if (!INSN_P (insn) || GET_CODE (PATTERN (insn)) == USE)
continue;
- if (DEBUG_INSN_P (insn))
- g->num_debug++;
- else
+ if (NONDEBUG_INSN_P (insn))
{
if (mem_read_insn_p (insn))
g->num_loads++;
if (mem_write_insn_p (insn))
g->num_stores++;
+ num_nodes++;
}
- num_nodes++;
}
/* There is nothing to do for this BB. */
- if ((num_nodes - g->num_debug) <= 1)
+ if (num_nodes <= 1)
{
free (g);
return NULL;
@@ -607,32 +560,39 @@ create_ddg (basic_block bb, int closing_
for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
{
- if (! INSN_P (insn))
- {
- if (! first_note && NOTE_P (insn)
- && NOTE_KIND (insn) != NOTE_INSN_BASIC_BLOCK)
- first_note = insn;
- continue;
- }
+ if (LABEL_P (insn) || NOTE_INSN_BASIC_BLOCK_P (insn))
+ continue;
+
+ if (!first_note && (INSN_P (insn) || NOTE_P (insn)))
+ first_note = insn;
+
+ if (!INSN_P (insn) || GET_CODE (PATTERN (insn)) == USE)
+ continue;
+
if (JUMP_P (insn))
{
gcc_assert (!g->closing_branch);
g->closing_branch = &g->nodes[i];
}
- else if (GET_CODE (PATTERN (insn)) == USE)
+
+ if (NONDEBUG_INSN_P (insn))
{
- if (! first_note)
- first_note = insn;
- 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);
+
+ gcc_checking_assert (first_note);
+ g->nodes[i].first_note = first_note;
+
+ g->nodes[i].aux.count = -1;
+ g->nodes[i].max_dist = XCNEWVEC (int, num_nodes);
+ for (j = 0; j < num_nodes; j++)
+ g->nodes[i].max_dist[j] = -1;
- 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);
- g->nodes[i++].insn = insn;
+ g->nodes[i++].insn = insn;
+ }
first_note = NULL;
}
@@ -668,6 +628,7 @@ free_ddg (ddg_ptr g)
}
sbitmap_free (g->nodes[i].successors);
sbitmap_free (g->nodes[i].predecessors);
+ free (g->nodes[i].max_dist);
}
if (g->num_backarcs > 0)
free (g->backarcs);
@@ -792,7 +753,7 @@ create_ddg_edge (ddg_node_ptr src, ddg_n
e->latency = l;
e->distance = d;
e->next_in = e->next_out = NULL;
- e->aux.info = 0;
+ e->in_scc = false;
return e;
}
@@ -820,7 +781,7 @@ add_edge_to_ddg (ddg_ptr g ATTRIBUTE_UNU
for now that cycles in the data dependence graph contain a single backarc.
This simplifies the algorithm, and can be generalized later. */
static void
-set_recurrence_length (ddg_scc_ptr scc, ddg_ptr g)
+set_recurrence_length (ddg_scc_ptr scc)
{
int j;
int result = -1;
@@ -828,17 +789,14 @@ set_recurrence_length (ddg_scc_ptr scc,
for (j = 0; j < scc->num_backarcs; j++)
{
ddg_edge_ptr backarc = scc->backarcs[j];
- int length;
int distance = backarc->distance;
ddg_node_ptr src = backarc->dest;
ddg_node_ptr dest = backarc->src;
+ int length = src->max_dist[dest->cuid];
+
+ if (length < 0)
+ continue;
- length = longest_simple_path (g, src->cuid, dest->cuid, scc->nodes);
- if (length < 0 )
- {
- /* fprintf (stderr, "Backarc not on simple cycle in SCC.\n"); */
- continue;
- }
length += backarc->latency;
result = MAX (result, (length / distance));
}
@@ -846,9 +804,9 @@ set_recurrence_length (ddg_scc_ptr scc,
}
/* Create a new SCC given the set of its nodes. Compute its recurrence_length
- and mark edges that belong to this scc as IN_SCC. */
+ and mark edges that belong to this scc. */
static ddg_scc_ptr
-create_scc (ddg_ptr g, sbitmap nodes)
+create_scc (ddg_ptr g, sbitmap nodes, int id)
{
ddg_scc_ptr scc;
unsigned int u = 0;
@@ -866,16 +824,18 @@ create_scc (ddg_ptr g, sbitmap nodes)
ddg_edge_ptr e;
ddg_node_ptr n = &g->nodes[u];
+ gcc_assert (n->aux.count == -1);
+ n->aux.count = id;
+
for (e = n->out; e; e = e->next_out)
if (bitmap_bit_p (nodes, e->dest->cuid))
{
- e->aux.count = IN_SCC;
+ e->in_scc = true;
if (e->distance > 0)
add_backarc_to_scc (scc, e);
}
}
- set_recurrence_length (scc, g);
return scc;
}
@@ -1018,7 +978,7 @@ check_sccs (ddg_all_sccs_ptr sccs, int n
ddg_all_sccs_ptr
create_ddg_all_sccs (ddg_ptr g)
{
- int i;
+ int i, j, k, scc, way;
int num_nodes = g->num_nodes;
auto_sbitmap from (num_nodes);
auto_sbitmap to (num_nodes);
@@ -1038,7 +998,7 @@ create_ddg_all_sccs (ddg_ptr g)
ddg_node_ptr dest = backarc->dest;
/* If the backarc already belongs to an SCC, continue. */
- if (backarc->aux.count == IN_SCC)
+ if (backarc->in_scc)
continue;
bitmap_clear (scc_nodes);
@@ -1049,10 +1009,52 @@ create_ddg_all_sccs (ddg_ptr g)
if (find_nodes_on_paths (scc_nodes, g, from, to))
{
- scc = create_scc (g, scc_nodes);
+ scc = create_scc (g, scc_nodes, sccs->num_sccs);
add_scc_to_ddg (sccs, scc);
}
}
+
+ /* Init max_dist arrays for Floyd–Warshall-like
+ longest patch calculation algorithm. */
+ for (k = 0; k < num_nodes; k++)
+ {
+ ddg_edge_ptr e;
+ ddg_node_ptr n = &g->nodes[k];
+
+ if (n->aux.count == -1)
+ continue;
+
+ n->max_dist[k] = 0;
+ for (e = n->out; e; e = e->next_out)
+ if (e->distance == 0 && g->nodes[e->dest->cuid].aux.count == n->aux.count)
+ n->max_dist[e->dest->cuid] = e->latency;
+ }
+
+ /* Run main Floid-Warshall loop. We use only non-backarc edges
+ inside each scc. */
+ for (k = 0; k < num_nodes; k++)
+ {
+ scc = g->nodes[k].aux.count;
+ if (scc != -1)
+ {
+ for (i = 0; i < num_nodes; i++)
+ if (g->nodes[i].aux.count == scc)
+ for (j = 0; j < num_nodes; j++)
+ if (g->nodes[j].aux.count == scc
+ && g->nodes[i].max_dist[k] >= 0
+ && g->nodes[k].max_dist[j] >= 0)
+ {
+ way = g->nodes[i].max_dist[k] + g->nodes[k].max_dist[j];
+ if (g->nodes[i].max_dist[j] < way)
+ g->nodes[i].max_dist[j] = way;
+ }
+ }
+ }
+
+ /* Calculate recurrence_length using max_dist info. */
+ for (i = 0; i < sccs->num_sccs; i++)
+ set_recurrence_length (sccs->sccs[i]);
+
order_sccs (sccs);
if (flag_checking)
@@ -1155,72 +1157,4 @@ find_nodes_on_paths (sbitmap result, ddg
return bitmap_and (result, reachable_from, reach_to);
}
-
-/* Updates the counts of U_NODE's successors (that belong to NODES) to be
- at-least as large as the count of U_NODE plus the latency between them.
- Sets a bit in TMP for each successor whose count was changed (increased).
- Returns nonzero if any count was changed. */
-static int
-update_dist_to_successors (ddg_node_ptr u_node, sbitmap nodes, sbitmap tmp)
-{
- ddg_edge_ptr e;
- int result = 0;
-
- for (e = u_node->out; e; e = e->next_out)
- {
- ddg_node_ptr v_node = e->dest;
- int v = v_node->cuid;
-
- if (bitmap_bit_p (nodes, v)
- && (e->distance == 0)
- && (v_node->aux.count < u_node->aux.count + e->latency))
- {
- v_node->aux.count = u_node->aux.count + e->latency;
- bitmap_set_bit (tmp, v);
- result = 1;
- }
- }
- return result;
-}
-
-
-/* Find the length of a longest path from SRC to DEST in G,
- going only through NODES, and disregarding backarcs. */
-int
-longest_simple_path (struct ddg * g, int src, int dest, sbitmap nodes)
-{
- int i;
- unsigned int u = 0;
- int change = 1;
- int num_nodes = g->num_nodes;
- auto_sbitmap workset (num_nodes);
- auto_sbitmap tmp (num_nodes);
-
-
- /* Data will hold the distance of the longest path found so far from
- src to each node. Initialize to -1 = less than minimum. */
- for (i = 0; i < g->num_nodes; i++)
- g->nodes[i].aux.count = -1;
- g->nodes[src].aux.count = 0;
-
- bitmap_clear (tmp);
- bitmap_set_bit (tmp, src);
-
- while (change)
- {
- sbitmap_iterator sbi;
-
- change = 0;
- bitmap_copy (workset, tmp);
- bitmap_clear (tmp);
- EXECUTE_IF_SET_IN_BITMAP (workset, 0, u, sbi)
- {
- ddg_node_ptr u_node = &g->nodes[u];
-
- change |= update_dist_to_successors (u_node, nodes, tmp);
- }
- }
- return g->nodes[dest].aux.count;
-}
-
#endif /* INSN_SCHEDULING */
diff -Nurp a/gcc/ddg.h b/gcc/ddg.h
--- a/gcc/ddg.h 2020-03-12 19:07:21.000000000 +0800
+++ b/gcc/ddg.h 2020-11-28 18:38:33.835633230 +0800
@@ -64,6 +64,10 @@ struct ddg_node
sbitmap successors;
sbitmap predecessors;
+ /* Temporary array used for Floyd-Warshall algorithm to find
+ scc recurrence length. */
+ int *max_dist;
+
/* For general use by algorithms manipulating the ddg. */
union {
int count;
@@ -95,11 +99,8 @@ struct ddg_edge
ddg_edge_ptr next_in;
ddg_edge_ptr next_out;
- /* For general use by algorithms manipulating the ddg. */
- union {
- int count;
- void *info;
- } aux;
+ /* Is true when edge is already in scc. */
+ bool in_scc;
};
/* This structure holds the Data Dependence Graph for a basic block. */
@@ -115,9 +116,6 @@ struct ddg
int num_loads;
int num_stores;
- /* Number of debug instructions in the BB. */
- int num_debug;
-
/* This array holds the nodes in the graph; it is indexed by the node
cuid, which follows the order of the instructions in the BB. */
ddg_node_ptr nodes;
@@ -178,7 +176,6 @@ ddg_all_sccs_ptr create_ddg_all_sccs (dd
void free_ddg_all_sccs (ddg_all_sccs_ptr);
int find_nodes_on_paths (sbitmap result, ddg_ptr, sbitmap from, sbitmap to);
-int longest_simple_path (ddg_ptr, int from, int to, sbitmap via);
bool autoinc_var_is_used_p (rtx_insn *, rtx_insn *);
diff -Nurp a/gcc/modulo-sched.c b/gcc/modulo-sched.c
--- a/gcc/modulo-sched.c 2020-03-12 19:07:21.000000000 +0800
+++ b/gcc/modulo-sched.c 2020-11-28 18:38:33.835633230 +0800
@@ -370,7 +370,7 @@ doloop_register_get (rtx_insn *head, rtx
: prev_nondebug_insn (tail));
for (insn = head; insn != first_insn_not_to_check; insn = NEXT_INSN (insn))
- if (!DEBUG_INSN_P (insn) && reg_mentioned_p (reg, insn))
+ if (NONDEBUG_INSN_P (insn) && reg_mentioned_p (reg, insn))
{
if (dump_file)
{
@@ -429,7 +429,7 @@ res_MII (ddg_ptr g)
if (targetm.sched.sms_res_mii)
return targetm.sched.sms_res_mii (g);
- return ((g->num_nodes - g->num_debug) / issue_rate);
+ return g->num_nodes / issue_rate;
}
@@ -2156,11 +2156,7 @@ sms_schedule_by_order (ddg_ptr g, int mi
ddg_node_ptr u_node = &ps->g->nodes[u];
rtx_insn *insn = u_node->insn;
- if (!NONDEBUG_INSN_P (insn))
- {
- bitmap_clear_bit (tobe_scheduled, u);
- continue;
- }
+ gcc_checking_assert (NONDEBUG_INSN_P (insn));
if (bitmap_bit_p (sched_nodes, u))
continue;
@@ -3162,9 +3158,6 @@ ps_has_conflicts (partial_schedule_ptr p
{
rtx_insn *insn = ps_rtl_insn (ps, crr_insn->id);
- if (!NONDEBUG_INSN_P (insn))
- continue;
-
/* Check if there is room for the current insn. */
if (!can_issue_more || state_dead_lock_p (curr_state))
return true;
diff -Nurp a/gcc/testsuite/gcc.c-torture/execute/pr70127-debug-sms.c b/gcc/testsuite/gcc.c-torture/execute/pr70127-debug-sms.c
--- a/gcc/testsuite/gcc.c-torture/execute/pr70127-debug-sms.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.c-torture/execute/pr70127-debug-sms.c 2020-11-28 18:38:33.835633230 +0800
@@ -0,0 +1,23 @@
+/* { dg-additional-options "-fcompare-debug -fmodulo-sched" } */
+
+struct S { int f; signed int g : 2; } a[1], c = {5, 1}, d;
+short b;
+
+__attribute__((noinline, noclone)) void
+foo (int x)
+{
+ if (x != 1)
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+ while (b++ <= 0)
+ {
+ struct S e = {1, 1};
+ d = e = a[0] = c;
+ }
+ foo (a[0].g);
+ return 0;
+}
diff -Nurp a/gcc/testsuite/gcc.dg/torture/pr87197-debug-sms.c b/gcc/testsuite/gcc.dg/torture/pr87197-debug-sms.c
--- a/gcc/testsuite/gcc.dg/torture/pr87197-debug-sms.c 1970-01-01 08:00:00.000000000 +0800
+++ b/gcc/testsuite/gcc.dg/torture/pr87197-debug-sms.c 2020-11-28 18:38:33.835633230 +0800
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fcompare-debug -fmodulo-sched --param sms-min-sc=1" } */
+
+int a, c, e, f, g;
+void
+h (int i)
+{
+ a = i;
+}
+void
+j (char *i, long k)
+{
+ while (k--)
+ c = *i++;
+}
+void
+l (unsigned char *i, long k)
+{
+ unsigned char *b = i + k;
+ while (i < b)
+ {
+ h (*i);
+ i++;
+ }
+}
+void
+m ()
+{
+ while (e)
+ {
+ float d = g;
+ l ((char *) &d, sizeof (g));
+ if (f)
+ j ((char *) &d, sizeof (g));
+ }
+}