* params.def (PARAM_MAX_PENDING_LIST_LENGTH): Add parameter to
limit length of dependancy flush list.
* params.h (MAX_PENDING_LIST_LENGTH): Define.
* sched-int.h (struct deps): Add pending_flush_length field.
* sched-deps.c (flush_pending_lists): Last_pending_memory_flush now
has 1 element in it.
(sched_analyze_1): Use MAX_PENDING_LIST_LENGTH.
(sched_analyze): After a jump, if the pending memory flush list is too
large, flush the pending lists.
(init_deps): Initialize pending_flush_length to 0.
* doc/invoke.texi (max_pending_list_length): Document parameter.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44398
138bc75d-0d04-0410-961f-
82ee72b054a4
+2001-07-26 Andrew MacLeod <amacleod@redhat.com>
+
+ * params.def (PARAM_MAX_PENDING_LIST_LENGTH): Add parameter to
+ limit length of dependancy flush list.
+ * params.h (MAX_PENDING_LIST_LENGTH): Define.
+ * sched-int.h (struct deps): Add pending_flush_length field.
+ * sched-deps.c (flush_pending_lists): Last_pending_memory_flush now
+ has 1 element in it.
+ (sched_analyze_1): Use MAX_PENDING_LIST_LENGTH.
+ (sched_analyze): After a jump, if the pending memory flush list is too
+ large, flush the pending lists.
+ (init_deps): Initialize pending_flush_length to 0.
+ * doc/invoke.texi (max_pending_list_length): Document parameter.
+
2001-07-26 Neil Booth <neil@daikokuya.demon.co.uk>
* toplev.c, varasm.c, final.c: Include xcoffout.h if appropriate.
@item max-gcse-passes
The maximum number of passes of GCSE to run.
+@item max-pending-list-length
+The maximum number of pending dependancies scheduling will allow
+before flushing the current state and starting over. Large functions
+with few branches or calls can create excessively large lists which
+needlessly consume memory and resources.
+
@item max-inline-insns
If an function contains more than this many instructions, it
will not be inlined. This option is precisely equivalent to
"The maximum number of instructions to consider to find accurate live register information",
333)
+/* This parameter limits the number of branch elements that the
+ scheduler will track anti-dependancies through without resetting
+ the tracking mechanism. Large functions with few calls or barriers
+ can generate lists containing many 1000's of dependancies. Generally
+ the compiler either uses all available memory, or runs for far too long. */
+DEFPARAM(PARAM_MAX_PENDING_LIST_LENGTH,
+ "max-pending-list-length",
+ "The maximum length of scheduling's pending operations list",
+ 32)
+
/* The GCSE optimization will be disabled if it would require
significantly more memory than this value. */
DEFPARAM(PARAM_MAX_GCSE_MEMORY,
PARAM_VALUE (PARAM_MAX_DELAY_SLOT_INSN_SEARCH)
#define MAX_DELAY_SLOT_LIVE_SEARCH \
PARAM_VALUE (PARAM_MAX_DELAY_SLOT_LIVE_SEARCH)
+#define MAX_PENDING_LIST_LENGTH \
+ PARAM_VALUE (PARAM_MAX_PENDING_LIST_LENGTH)
#define MAX_GCSE_MEMORY \
((size_t) PARAM_VALUE (PARAM_MAX_GCSE_MEMORY))
#define MAX_GCSE_PASSES \
#include "toplev.h"
#include "recog.h"
#include "sched-int.h"
+#include "params.h"
extern char *reg_known_equiv_p;
extern rtx *reg_known_value;
free_INSN_LIST_list (&deps->last_pending_memory_flush);
deps->last_pending_memory_flush = alloc_INSN_LIST (insn, NULL_RTX);
+ deps->pending_flush_length = 1;
}
\f
/* Analyze a single SET, CLOBBER, PRE_DEC, POST_DEC, PRE_INC or POST_INC
{
/* Writing memory. */
- if (deps->pending_lists_length > 32)
+ if (deps->pending_lists_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
- these lists get long. The number 32 was chosen because it
- seems like a reasonable number. When compiling GCC with itself,
+ these lists get long. When compiling GCC with itself,
this flush occurs 8 times for sparc, and 10 times for m88k using
- the number 32. */
+ the default value of 32. */
flush_pending_lists (deps, insn, 0);
}
else
/* Make each JUMP_INSN a scheduling barrier for memory
references. */
if (GET_CODE (insn) == JUMP_INSN)
- deps->last_pending_memory_flush
- = alloc_INSN_LIST (insn, deps->last_pending_memory_flush);
+ {
+ /* Keep the list a reasonable size. */
+ if (deps->pending_flush_length++ > MAX_PENDING_LIST_LENGTH)
+ flush_pending_lists (deps, insn, 0);
+ else
+ deps->last_pending_memory_flush
+ = alloc_INSN_LIST (insn, deps->last_pending_memory_flush);
+ }
sched_analyze_insn (deps, PATTERN (insn), insn, loop_notes);
loop_notes = 0;
}
deps->pending_write_insns = 0;
deps->pending_write_mems = 0;
deps->pending_lists_length = 0;
+ deps->pending_flush_length = 0;
deps->last_pending_memory_flush = 0;
deps->last_function_call = 0;
deps->in_post_call_group_p = 0;
a function of the length of these pending lists. */
int pending_lists_length;
+ /* Length of the pending memory flush list. Large functions with no
+ calls may build up extremely large lists. */
+ int pending_flush_length;
+
/* The last insn upon which all memory references must depend.
This is an insn which flushed the pending lists, creating a dependency
between it and all previously pending memory references. This creates