Move interrupt branch from start to end of block, on x86-64.
authorTaylor R Campbell <campbell@mumble.net>
Sun, 26 Jun 2011 19:45:40 +0000 (19:45 +0000)
committerTaylor R Campbell <campbell@mumble.net>
Sun, 26 Jun 2011 19:45:40 +0000 (19:45 +0000)
src/compiler/machines/x86-64/rules3.scm

index 08b13f0ecb08e82c4f13c3edafc23402be50c1f1..1f83d0b1c4df662b087d14565dfcea0c05cb891c 100644 (file)
@@ -380,14 +380,23 @@ USA.
 
 (define (interrupt-check interrupt-label checks)
   ;; This always does interrupt checks in line.
-  (LAP ,@(if (or (memq 'INTERRUPT checks) (memq 'HEAP checks))
-            (LAP (CMP Q (R ,regnum:free-pointer) ,reg:compiled-memtop)
-                 (JGE (@PCR ,interrupt-label)))
-            (LAP))
-       ,@(if (memq 'STACK checks)
-            (LAP (CMP Q (R ,regnum:stack-pointer) ,reg:stack-guard)
-                 (JL (@PCR ,interrupt-label)))
-            (LAP))))
+  (let ((branch-target (generate-label 'INTERRUPT)))
+    ;; Put the interrupt check branch target after the branch so that
+    ;; it is a forward branch, which Intel and AMD CPUs will predict
+    ;; not taken by default, in the absence of dynamic branch
+    ;; prediction profile data.
+    (add-end-of-block-code!
+     (lambda ()
+       (LAP (LABEL ,branch-target)
+           (JMP (@PCR ,interrupt-label)))))
+    (LAP ,@(if (or (memq 'INTERRUPT checks) (memq 'HEAP checks))
+              (LAP (CMP Q (R ,regnum:free-pointer) ,reg:compiled-memtop)
+                   (JGE (@PCR ,branch-target)))
+              (LAP))
+        ,@(if (memq 'STACK checks)
+              (LAP (CMP Q (R ,regnum:stack-pointer) ,reg:stack-guard)
+                   (JL (@PCR ,branch-target)))
+              (LAP)))))
 
 (define (simple-procedure-header code-word label entry)
   (let ((checks (get-entry-interrupt-checks)))