Commit bdbf40a5 by Maxim Kuvyrkov Committed by Maxim Kuvyrkov

re PR middle-end/28071 (A file that can not be compiled in reasonable time/space)

PR middle-end/28071
* sched-int.h (struct deps): Split field 'pending_lists_length' into
'pending_read_list_length' and 'pending_write_list_length'.  Update
comment.
* sched-deps.c (add_insn_mem_dependence): Change signature.  Update
to handle two length counters instead of one.  Update all uses.
(flush_pending_lists, sched_analyze_1, init_deps): Update to handle
two length counters instead of one.
* sched-rgn.c (propagate_deps): Update to handle two length counters
instead of one.

From-SVN: r123874
parent b3ea5d8e
2007-04-16 Maxim Kuvyrkov <mkuvyrkov@ispras.ru>
PR middle-end/28071
* sched-int.h (struct deps): Split field 'pending_lists_length' into
'pending_read_list_length' and 'pending_write_list_length'. Update
comment.
* sched-deps.c (add_insn_mem_dependence): Change signature. Update
to handle two length counters instead of one. Update all uses.
(flush_pending_lists, sched_analyze_1, init_deps): Update to handle
two length counters instead of one.
* sched-rgn.c (propagate_deps): Update to handle two length counters
instead of one.
2007-04-16 H.J. Lu <hongjiu.lu@intel.com>
PR target/31582
......
......@@ -1017,11 +1017,26 @@ fixup_sched_groups (rtx insn)
so that we can do memory aliasing on it. */
static void
add_insn_mem_dependence (struct deps *deps, rtx *insn_list, rtx *mem_list,
add_insn_mem_dependence (struct deps *deps, bool read_p,
rtx insn, rtx mem)
{
rtx *insn_list;
rtx *mem_list;
rtx link;
if (read_p)
{
insn_list = &deps->pending_read_insns;
mem_list = &deps->pending_read_mems;
deps->pending_read_list_length++;
}
else
{
insn_list = &deps->pending_write_insns;
mem_list = &deps->pending_write_mems;
deps->pending_write_list_length++;
}
link = alloc_INSN_LIST (insn, *insn_list);
*insn_list = link;
......@@ -1032,8 +1047,6 @@ add_insn_mem_dependence (struct deps *deps, rtx *insn_list, rtx *mem_list,
}
link = alloc_EXPR_LIST (VOIDmode, canon_rtx (mem), *mem_list);
*mem_list = link;
deps->pending_lists_length++;
}
/* Make a dependency between every memory reference on the pending lists
......@@ -1049,12 +1062,13 @@ flush_pending_lists (struct deps *deps, rtx insn, int for_read,
add_dependence_list_and_free (insn, &deps->pending_read_insns, 1,
REG_DEP_ANTI);
free_EXPR_LIST_list (&deps->pending_read_mems);
deps->pending_read_list_length = 0;
}
add_dependence_list_and_free (insn, &deps->pending_write_insns, 1,
for_read ? REG_DEP_ANTI : REG_DEP_OUTPUT);
free_EXPR_LIST_list (&deps->pending_write_mems);
deps->pending_lists_length = 0;
deps->pending_write_list_length = 0;
add_dependence_list_and_free (insn, &deps->last_pending_memory_flush, 1,
for_read ? REG_DEP_ANTI : REG_DEP_OUTPUT);
......@@ -1218,7 +1232,8 @@ sched_analyze_1 (struct deps *deps, rtx x, rtx insn)
}
t = canon_rtx (t);
if (deps->pending_lists_length > MAX_PENDING_LIST_LENGTH)
if ((deps->pending_read_list_length + deps->pending_write_list_length)
> MAX_PENDING_LIST_LENGTH)
{
/* Flush all pending reads and writes to prevent the pending lists
from getting any larger. Insn scheduling runs too slowly when
......@@ -1258,8 +1273,7 @@ sched_analyze_1 (struct deps *deps, rtx x, rtx insn)
add_dependence_list (insn, deps->last_pending_memory_flush, 1,
REG_DEP_ANTI);
add_insn_mem_dependence (deps, &deps->pending_write_insns,
&deps->pending_write_mems, insn, dest);
add_insn_mem_dependence (deps, false, insn, dest);
}
sched_analyze_2 (deps, XEXP (dest, 0), insn);
}
......@@ -1380,8 +1394,7 @@ sched_analyze_2 (struct deps *deps, rtx x, rtx insn)
/* Always add these dependencies to pending_reads, since
this insn may be followed by a write. */
add_insn_mem_dependence (deps, &deps->pending_read_insns,
&deps->pending_read_mems, insn, x);
add_insn_mem_dependence (deps, true, insn, x);
/* Take advantage of tail recursion here. */
sched_analyze_2 (deps, XEXP (x, 0), insn);
......@@ -2081,7 +2094,8 @@ init_deps (struct deps *deps)
deps->pending_read_mems = 0;
deps->pending_write_insns = 0;
deps->pending_write_mems = 0;
deps->pending_lists_length = 0;
deps->pending_read_list_length = 0;
deps->pending_write_list_length = 0;
deps->pending_flush_length = 0;
deps->last_pending_memory_flush = 0;
deps->last_function_call = 0;
......
......@@ -278,11 +278,16 @@ struct deps
/* An EXPR_LIST containing all MEM rtx's which are pending writes. */
rtx pending_write_mems;
/* Indicates the combined length of the two pending lists. We must prevent
these lists from ever growing too large since the number of dependencies
produced is at least O(N*N), and execution time is at least O(4*N*N), as
a function of the length of these pending lists. */
int pending_lists_length;
/* We must prevent the above lists from ever growing too large since
the number of dependencies produced is at least O(N*N),
and execution time is at least O(4*N*N), as a function of the
length of these pending lists. */
/* Indicates the length of the pending_read list. */
int pending_read_list_length;
/* Indicates the length of the pending_write list. */
int pending_write_list_length;
/* Length of the pending memory flush list. Large functions with no
calls may build up extremely large lists. */
......
......@@ -2463,7 +2463,10 @@ propagate_deps (int bb, struct deps *pred_deps)
= concat_INSN_LIST (pred_deps->last_pending_memory_flush,
succ_deps->last_pending_memory_flush);
succ_deps->pending_lists_length += pred_deps->pending_lists_length;
succ_deps->pending_read_list_length
+= pred_deps->pending_read_list_length;
succ_deps->pending_write_list_length
+= pred_deps->pending_write_list_length;
succ_deps->pending_flush_length += pred_deps->pending_flush_length;
/* last_function_call is inherited by successor. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment