diff options
author | Jan Hubicka <jh@suse.cz> | 2003-06-04 09:50:27 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2003-06-04 07:50:27 +0000 |
commit | 253c7a0090928522c2bca312dc227ebf53b2dd99 (patch) | |
tree | ed3cdb18a97f6744254714f5f804504fd7ad402a /gcc | |
parent | 01d3224a48291c181104b127a4490379f54b9a31 (diff) | |
download | gcc-253c7a0090928522c2bca312dc227ebf53b2dd99.zip gcc-253c7a0090928522c2bca312dc227ebf53b2dd99.tar.gz gcc-253c7a0090928522c2bca312dc227ebf53b2dd99.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 20 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 16 |
3 files changed, 34 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5c58596..b918c90 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +Wed Jun 4 09:49:21 CEST 2003 Jan Hubicka <jh@suse.cz> + + * 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 <ebotcazou@libertysurf.fr> PR optimization/11018 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 968bcde..7386ba5 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 181cf7e..d192cc8 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" ""))] |