aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-08-25 23:08:28 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2001-08-25 21:08:28 +0000
commit6ab16dd9ad5daa079e0ad3312b1324a4dd51b8bb (patch)
tree148dfc2b03bed81cf63c2e3eb8ec9d70ddd5db7c
parent033c017cb2c0234ef0518856ce8310a11626c5b3 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/config/i386/i386.c21
-rw-r--r--gcc/predict.c45
-rw-r--r--gcc/rtl.h1
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)
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 819bf51..3a0a019 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -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 */