From: amacleod Date: Thu, 26 Jul 2001 13:59:22 +0000 (+0000) Subject: 2001-07-26 Andrew MacLeod X-Git-Tag: upstream/4.9.2~93003 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=85de291ed5d11eab35e18498b64be4c807cb39f5;p=platform%2Fupstream%2Flinaro-gcc.git 2001-07-26 Andrew MacLeod * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aad462c..8bc8788 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2001-07-26 Andrew MacLeod + + * 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 * toplev.c, varasm.c, final.c: Include xcoffout.h if appropriate. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 3b13ad8..f3b3e8e 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -3808,6 +3808,12 @@ optimization will not be done. @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 diff --git a/gcc/params.def b/gcc/params.def index d7e9bc0..ca952c1 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -68,6 +68,16 @@ DEFPARAM(PARAM_MAX_DELAY_SLOT_LIVE_SEARCH, "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, diff --git a/gcc/params.h b/gcc/params.h index 2b29094..e8eb2852 100644 --- a/gcc/params.h +++ b/gcc/params.h @@ -90,6 +90,8 @@ typedef enum compiler_param 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 \ diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index 422b394..3f4b129 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -38,6 +38,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "toplev.h" #include "recog.h" #include "sched-int.h" +#include "params.h" extern char *reg_known_equiv_p; extern rtx *reg_known_value; @@ -534,6 +535,7 @@ flush_pending_lists (deps, insn, only_write) 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; } /* Analyze a single SET, CLOBBER, PRE_DEC, POST_DEC, PRE_INC or POST_INC @@ -675,14 +677,13 @@ sched_analyze_1 (deps, x, insn) { /* 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 @@ -1246,8 +1247,14 @@ sched_analyze (deps, head, tail) /* 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; } @@ -1473,6 +1480,7 @@ init_deps (deps) 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; diff --git a/gcc/sched-int.h b/gcc/sched-int.h index 0eb2e66..0b7ebab 100644 --- a/gcc/sched-int.h +++ b/gcc/sched-int.h @@ -53,6 +53,10 @@ struct deps 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