diff options
author | Jan Hubicka <jh@suse.cz> | 2001-08-25 23:08:28 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2001-08-25 21:08:28 +0000 |
commit | 6ab16dd9ad5daa079e0ad3312b1324a4dd51b8bb (patch) | |
tree | 148dfc2b03bed81cf63c2e3eb8ec9d70ddd5db7c | |
parent | 033c017cb2c0234ef0518856ce8310a11626c5b3 (diff) | |
download | gcc-6ab16dd9ad5daa079e0ad3312b1324a4dd51b8bb.zip gcc-6ab16dd9ad5daa079e0ad3312b1324a4dd51b8bb.tar.gz gcc-6ab16dd9ad5daa079e0ad3312b1324a4dd51b8bb.tar.bz2 |
predict.c (expensive_function_p): New.
* predict.c (expensive_function_p): New.
* rtl.h (expensive_function_p): Declare.
* i386.c (FAST_PROLOGUE_INSN_COUNT): New constant.
(use_fast_prologue_epilogue): New static variable.
(expand_prologue): Set it; emit short prologues if unset.
(expand_epilogue): Likewise.
From-SVN: r45176
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 21 | ||||
-rw-r--r-- | gcc/predict.c | 45 | ||||
-rw-r--r-- | gcc/rtl.h | 1 |
4 files changed, 73 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f3ad806..4b32717 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +Sat Aug 25 23:07:35 CEST 2001 Jan Hubicka <jh@suse.cz> + + * predict.c (expensive_function_p): New. + * rtl.h (expensive_function_p): Declare. + * i386.c (FAST_PROLOGUE_INSN_COUNT): New constant. + (use_fast_prologue_epilogue): New static variable. + (expand_prologue): Set it; emit short prologues if unset. + (expand_epilogue): Likewise. + 2001-08-22 Geoffrey Keating <geoffk@redhat.com> * config.gcc: Add stormy16-*-elf case. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 51d32f6..23612b6 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -319,6 +319,14 @@ const int x86_accumulate_outgoing_args = m_ATHLON | m_PENT4 | m_PPRO; const int x86_prologue_using_move = m_ATHLON | m_PENT4 | m_PPRO; const int x86_epilogue_using_move = m_ATHLON | m_PENT4 | m_PPRO; +/* In case the avreage insn count for single function invocation is + lower than this constant, emit fast (but longer) prologue and + epilogue code. */ +#define FAST_PROLOGUE_INSN_COUNT 30 +/* Set by prologue expander and used by epilogue expander to determine + the style used. */ +static int use_fast_prologue_epilogue; + #define AT_BP(mode) (gen_rtx_MEM ((mode), hard_frame_pointer_rtx)) const char * const hi_reg_name[] = HI_REGISTER_NAMES; @@ -2653,9 +2661,15 @@ ix86_expand_prologue () || current_function_uses_const_pool) && !TARGET_64BIT); struct ix86_frame frame; - int use_mov = (TARGET_PROLOGUE_USING_MOVE && !optimize_size); + int use_mov = 0; HOST_WIDE_INT allocate; + if (TARGET_PROLOGUE_USING_MOVE && !optimize_size) + { + use_fast_prologue_epilogue + = !expensive_function_p (FAST_PROLOGUE_INSN_COUNT); + use_mov = use_fast_prologue_epilogue; + } ix86_compute_frame_layout (&frame); /* Note: AT&T enter does NOT have reversed args. Enter is probably @@ -2794,10 +2808,11 @@ ix86_expand_epilogue (style) tuning in future. */ if ((!sp_valid && frame.nregs <= 1) || (TARGET_EPILOGUE_USING_MOVE && !optimize_size + && use_fast_prologue_epilogue && (frame.nregs > 1 || frame.to_allocate)) || (frame_pointer_needed && !frame.nregs && frame.to_allocate) || (frame_pointer_needed && TARGET_USE_LEAVE && !optimize_size - && frame.nregs == 1) + && use_fast_prologue_epilogue && frame.nregs == 1) || style == 2) { /* Restore registers. We can use ebp or esp to address the memory @@ -2844,7 +2859,7 @@ ix86_expand_epilogue (style) GEN_INT (frame.to_allocate + frame.nregs * UNITS_PER_WORD))); /* If not an i386, mov & pop is faster than "leave". */ - else if (TARGET_USE_LEAVE || optimize_size) + else if (TARGET_USE_LEAVE || optimize_size || !use_fast_prologue_epilogue) emit_insn (TARGET_64BIT ? gen_leave_rex64 () : gen_leave ()); else { diff --git a/gcc/predict.c b/gcc/predict.c index f7e8b6d..70460ab 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -782,6 +782,51 @@ counts_to_freqs () } } +/* Return true if function is likely to be expensive, so there is no point + to optimizer performance of prologue, epilogue or do inlining at the + expense of code size growth. THRESHOLD is the limit of number + of isntructions function can execute at average to be still considered + not expensive. */ +bool +expensive_function_p (threshold) + int threshold; +{ + unsigned int sum = 0; + int i; + int limit; + + /* We can not compute accurately for large thresholds due to scaled + frequencies. */ + if (threshold > BB_FREQ_MAX) + abort (); + + /* Frequencies are out of range. This eighter means that function contains + internal loop executing more than BB_FREQ_MAX times or profile feedback + is available and function has not been executed at all. */ + if (ENTRY_BLOCK_PTR->frequency == 0) + return true; + + /* Maximally BB_FREQ_MAX^2 so overflow won't happen. */ + limit = ENTRY_BLOCK_PTR->frequency * threshold; + for (i = 0; i < n_basic_blocks; i++) + { + basic_block bb = BASIC_BLOCK (i); + rtx insn; + + for (insn = bb->head; insn != NEXT_INSN (bb->end); + insn = NEXT_INSN (insn)) + { + if (active_insn_p (insn)) + { + sum += bb->frequency; + if (sum > limit) + return true; + } + } + } + return false; +} + /* Estimate basic blocks frequency by given branch probabilities. */ static void estimate_bb_frequencies (loops) @@ -2028,4 +2028,5 @@ extern void if_convert PARAMS ((int)); /* In predict.c */ extern void invert_br_probabilities PARAMS ((rtx)); +extern bool expensive_function_p PARAMS ((int)); #endif /* ! GCC_RTL_H */ |