From: Jan Hubicka Date: Wed, 4 Jun 2003 07:50:27 +0000 (+0200) Subject: i386.c (ix86_reorg): Replace the jump instead of adding nop. X-Git-Tag: releases/gcc-3.4.0~6183 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=253c7a0090928522c2bca312dc227ebf53b2dd99;p=thirdparty%2Fgcc.git i386.c (ix86_reorg): Replace the jump instead of adding nop. * i386.c (ix86_reorg): Replace the jump instead of adding nop. * i386.md (UNSPEC_REP): New constant. (return_internal_long): New pattern. From-SVN: r67432 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5c585961cc1e..b918c909fb36 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +Wed Jun 4 09:49:21 CEST 2003 Jan Hubicka + + * i386.c (ix86_reorg): Replace the jump instead of adding nop. + * i386.md (UNSPEC_REP): New constant. + (return_internal_long): New pattern. + 2003-06-04 Eric Botcazou PR optimization/11018 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 968bcde1ccd8..7386ba55131d 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -15543,9 +15543,10 @@ ix86_reorg () basic_block bb = e->src; rtx ret = bb->end; rtx prev; - bool insert = false; + bool replace = false; - if (!returnjump_p (ret) || !maybe_hot_bb_p (bb)) + if (GET_CODE (ret) != JUMP_INSN || GET_CODE (PATTERN (ret)) != RETURN + || !maybe_hot_bb_p (bb)) continue; for (prev = PREV_INSN (ret); prev; prev = PREV_INSN (prev)) if (active_insn_p (prev) || GET_CODE (prev) == CODE_LABEL) @@ -15556,22 +15557,25 @@ ix86_reorg () for (e = bb->pred; e; e = e->pred_next) if (EDGE_FREQUENCY (e) && e->src->index >= 0 && !(e->flags & EDGE_FALLTHRU)) - insert = 1; + replace = true; } - if (!insert) + if (!replace) { prev = prev_active_insn (ret); if (prev && ((GET_CODE (prev) == JUMP_INSN && any_condjump_p (prev)) || GET_CODE (prev) == CALL_INSN)) - insert = 1; + replace = true; /* Empty functions get branch misspredict even when the jump destination is not visible to us. */ if (!prev && cfun->function_frequency > FUNCTION_FREQUENCY_UNLIKELY_EXECUTED) - insert = 1; + replace = true; + } + if (replace) + { + emit_insn_before (gen_return_internal_long (), ret); + delete_insn (ret); } - if (insert) - emit_insn_before (gen_nop (), ret); } } diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 181cf7e56aa1..d192cc8b1cfc 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -113,6 +113,9 @@ ; x87 Floating point (UNSPEC_FPATAN 65) (UNSPEC_FYL2X 66) + + ; REP instruction + (UNSPEC_REP 67) ]) (define_constants @@ -14236,6 +14239,19 @@ (set_attr "length_immediate" "0") (set_attr "modrm" "0")]) +;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET +;; instruction Athlon and K8 have. + +(define_insn "return_internal_long" + [(return) + (unspec [(const_int 0)] UNSPEC_REP)] + "reload_completed" + "rep {;} ret" + [(set_attr "length" "1") + (set_attr "length_immediate" "0") + (set_attr "prefix_rep" "1") + (set_attr "modrm" "0")]) + (define_insn "return_pop_internal" [(return) (use (match_operand:SI 0 "const_int_operand" ""))]