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
This commit is contained in:
Jan Hubicka 2003-06-04 09:50:27 +02:00 committed by Jan Hubicka
parent 01d3224a48
commit 253c7a0090
3 changed files with 34 additions and 8 deletions

View File

@ -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

View File

@ -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);
}
}

View File

@ -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" ""))]