i386.c (ix86_reorg): Replace the jump instead of adding nop.
authorJan Hubicka <jh@suse.cz>
Wed, 4 Jun 2003 07:50:27 +0000 (09:50 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 4 Jun 2003 07:50:27 +0000 (07:50 +0000)
* 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

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.md

index 5c58596..b918c90 100644 (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
index 968bcde..7386ba5 100644 (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);
   }
 }
 
index 181cf7e..d192cc8 100644 (file)
    ; x87 Floating point
    (UNSPEC_FPATAN              65)
    (UNSPEC_FYL2X               66)
+
+   ; REP instruction
+   (UNSPEC_REP                 67)
   ])
 
 (define_constants
    (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" ""))]