0.9.14.13:
authorNathan Froyd <froydnj@cs.rice.edu>
Sat, 15 Jul 2006 04:26:24 +0000 (04:26 +0000)
committerNathan Froyd <froydnj@cs.rice.edu>
Sat, 15 Jul 2006 04:26:24 +0000 (04:26 +0000)
Micro-optimize bit-vector accesses on x86 and x86-64:
... processor does the necessary masking for us, so we can
  eliminate an AND instruction;
... in the process, remove dodgy interior pointer usage lurking
  inside the small data-vector-ref VOPs.

src/compiler/x86-64/array.lisp
src/compiler/x86/array.lisp
version.lisp-expr

index a144c56..be4823d 100644 (file)
                           :disp (- (* vector-data-offset n-word-bytes)
                                    other-pointer-lowtag)))
            (move ecx index)
-           (inst and ecx ,(1- elements-per-word))
+           ;; We used to mask ECX for all values of BITS, but since
+           ;; Intel's documentation says that the chip will mask shift
+           ;; and rotate counts by 63 automatically, we can safely move
+           ;; the masking operation under the protection of this UNLESS
+           ;; in the bit-vector case.  --njf, 2006-07-14
            ,@(unless (= bits 1)
-               `((inst shl ecx ,(1- (integer-length bits)))))
+               `((inst and ecx ,(1- elements-per-word))
+                 (inst shl ecx ,(1- (integer-length bits)))))
            (inst shr result :cl)
            (inst and result ,(1- (ash 1 bits)))))
        (define-vop (,(symbolicate 'data-vector-ref-c/ type))
          (:note "inline array store")
          (:translate data-vector-set)
          (:policy :fast-safe)
-         (:args (object :scs (descriptor-reg) :target ptr)
+         (:args (object :scs (descriptor-reg))
                 (index :scs (unsigned-reg) :target ecx)
                 (value :scs (unsigned-reg immediate) :target result))
          (:arg-types ,type positive-fixnum positive-fixnum)
          (:results (result :scs (unsigned-reg)))
          (:result-types positive-fixnum)
          (:temporary (:sc unsigned-reg) word-index)
-         (:temporary (:sc unsigned-reg :from (:argument 0)) ptr old)
-         (:temporary (:sc unsigned-reg :offset ecx-offset :from (:argument 1))
-                     ecx)
+         (:temporary (:sc unsigned-reg) old)
+         (:temporary (:sc unsigned-reg :offset ecx-offset) ecx)
          (:generator 25
            (move word-index index)
            (inst shr word-index ,bit-shift)
-           (inst lea ptr
+           (inst mov old
                  (make-ea :qword :base object :index word-index
                           :scale n-word-bytes
                           :disp (- (* vector-data-offset n-word-bytes)
                                    other-pointer-lowtag)))
-           (loadw old ptr)
            (move ecx index)
-           (inst and ecx ,(1- elements-per-word))
+           ;; We used to mask ECX for all values of BITS, but since
+           ;; Intel's documentation says that the chip will mask shift
+           ;; and rotate counts by 63 automatically, we can safely move
+           ;; the masking operation under the protection of this UNLESS
+           ;; in the bit-vector case.  --njf, 2006-07-14
            ,@(unless (= bits 1)
-               `((inst shl ecx ,(1- (integer-length bits)))))
+               `((inst and ecx ,(1- elements-per-word))
+                 (inst shl ecx ,(1- (integer-length bits)))))
            (inst ror old :cl)
            (unless (and (sc-is value immediate)
                         (= (tn-value value) ,(1- (ash 1 bits))))
              (unsigned-reg
               (inst or old value)))
            (inst rol old :cl)
-           (storew old ptr)
+           (mov (make-ea :qword :base object :index word-index
+                          :scale n-word-bytes
+                          :disp (- (* vector-data-offset n-word-bytes)
+                                   other-pointer-lowtag))
+                old)
            (sc-case value
              (immediate
               (inst mov result (tn-value value)))
index 7e6b27c..40926d7 100644 (file)
                           :disp (- (* vector-data-offset n-word-bytes)
                                    other-pointer-lowtag)))
            (move ecx index)
-           (inst and ecx ,(1- elements-per-word))
-           ,@(unless (= bits 1)
-               `((inst shl ecx ,(1- (integer-length bits)))))
+           ;; We used to mask ECX for all values of ELEMENT-PER-WORD,
+           ;; but since Intel's documentation says that the chip will
+           ;; mask shift and rotate counts by 31 automatically, we can
+           ;; safely move the masking operation under the protection of
+           ;; this UNLESS in the bit-vector case.  --njf, 2006-07-14
+           ,@(unless (= elements-per-word n-word-bits)
+               `((inst and ecx ,(1- elements-per-word))
+                 (inst shl ecx ,(1- (integer-length bits)))))
            (inst shr result :cl)
            (inst and result ,(1- (ash 1 bits)))))
        (define-vop (,(symbolicate 'data-vector-ref-c/ type))
          (:note "inline array store")
          (:translate data-vector-set)
          (:policy :fast-safe)
-         (:args (object :scs (descriptor-reg) :target ptr)
+         (:args (object :scs (descriptor-reg))
                 (index :scs (unsigned-reg) :target ecx)
                 (value :scs (unsigned-reg immediate) :target result))
          (:arg-types ,type positive-fixnum positive-fixnum)
          (:results (result :scs (unsigned-reg)))
          (:result-types positive-fixnum)
          (:temporary (:sc unsigned-reg) word-index)
-         (:temporary (:sc unsigned-reg :from (:argument 0)) ptr old)
-         (:temporary (:sc unsigned-reg :offset ecx-offset :from (:argument 1))
-                     ecx)
+         (:temporary (:sc unsigned-reg) old)
+         (:temporary (:sc unsigned-reg :offset ecx-offset) ecx)
          (:generator 25
            (move word-index index)
            (inst shr word-index ,bit-shift)
-           (inst lea ptr
+           (inst mov old
                  (make-ea :dword :base object :index word-index :scale 4
                           :disp (- (* vector-data-offset n-word-bytes)
                                    other-pointer-lowtag)))
-           (loadw old ptr)
            (move ecx index)
-           (inst and ecx ,(1- elements-per-word))
-           ,@(unless (= bits 1)
-               `((inst shl ecx ,(1- (integer-length bits)))))
+           ;; We used to mask ECX for all values of ELEMENT-PER-WORD,
+           ;; but since Intel's documentation says that the chip will
+           ;; mask shift and rotate counts by 31 automatically, we can
+           ;; safely move the masking operation under the protection of
+           ;; this UNLESS in the bit-vector case.  --njf, 2006-07-14
+           ,@(unless (= elements-per-word n-word-bits)
+               `((inst and ecx ,(1- elements-per-word))
+                 (inst shl ecx ,(1- (integer-length bits)))))
            (inst ror old :cl)
            (unless (and (sc-is value immediate)
                         (= (tn-value value) ,(1- (ash 1 bits))))
              (unsigned-reg
               (inst or old value)))
            (inst rol old :cl)
-           (storew old ptr)
+           (inst mov (make-ea :dword :base object :index word-index :scale 4
+                              :disp (- (* vector-data-offset n-word-bytes)
+                                       other-pointer-lowtag))
+                 old)
            (sc-case value
              (immediate
               (inst mov result (tn-value value)))
index 7d1ce15..04f334c 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.9.14.12"
+"0.9.14.13"