From: Stas Boukarev Date: Sun, 28 Jul 2013 15:42:41 +0000 (+0400) Subject: Microoptimize type-tests on x86oids. X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=2056118835600a7c4e372c796568ddada5824cf6;p=sbcl.git Microoptimize type-tests on x86oids. On x86-64 in %test-lowtag instead of doing: MOV EAX, ECX AND AL, 15 CMP AL, 15 do LEA EAX, [RCX-15] TEST AL, 15 Which allows to save one byte. On x86 this optimization is already applied, but since LEA loads a 32-bit integer, EAX can be later used as an already untagged pointer in %test-headers: MOV EAX, [ECX-7] => MOV EAX, [EAX], which takes one byte less to encode. --- diff --git a/src/compiler/x86-64/type-vops.lisp b/src/compiler/x86-64/type-vops.lisp index 589b2cb..7c12dc3 100644 --- a/src/compiler/x86-64/type-vops.lisp +++ b/src/compiler/x86-64/type-vops.lisp @@ -80,10 +80,9 @@ (%test-headers value target not-p nil headers drop-through)) (defun %test-lowtag (value target not-p lowtag) - (move-qword-to-eax value) - (inst and al-tn lowtag-mask) - (inst cmp al-tn lowtag) - (inst jmp (if not-p :ne :e) target)) + (inst lea eax-tn (make-ea :dword :base value :disp (- lowtag))) + (inst test al-tn lowtag-mask) + (inst jmp (if not-p :nz :z) target)) (defun %test-headers (value target not-p function-p headers &optional (drop-through (gen-label))) diff --git a/src/compiler/x86/type-vops.lisp b/src/compiler/x86/type-vops.lisp index aca94f3..a1c6655 100644 --- a/src/compiler/x86/type-vops.lisp +++ b/src/compiler/x86/type-vops.lisp @@ -65,6 +65,8 @@ (if not-p (values :ne :a :b drop-through target) (values :e :na :nb target drop-through)) + ;; %test-lowtag loads an untagged pointer into EAX, which allows + ;; to avoid untagging below (%test-lowtag value when-false t lowtag) (cond ((and (null (cdr headers)) @@ -75,10 +77,10 @@ ;; [BIGNUM-WIDETAG..FOO-WIDETAG]) is also possible, but such ;; opportunities don't come up very often and the code would ;; get pretty hairy... - (inst cmp (make-ea :byte :base value :disp (- lowtag)) (car headers)) + (inst cmp (make-ea :byte :base eax-tn) (car headers)) (inst jmp equal target)) (t - (inst mov al-tn (make-ea :byte :base value :disp (- lowtag))) + (inst mov al-tn (make-ea :byte :base eax-tn)) (do ((remaining headers (cdr remaining))) ((null remaining)) (let ((header (car remaining))