Implement EQ of unboxed characters and small integers on x86oids
authorPaul Khuong <pvk@pvk.ca>
Tue, 21 May 2013 20:20:40 +0000 (16:20 -0400)
committerPaul Khuong <pvk@pvk.ca>
Tue, 21 May 2013 20:23:45 +0000 (16:23 -0400)
 More important now that we actually weaken EQL of EQ-comparable
 types into EQ.  We just have to re-purpose pre-existing EQL and
 CHAR= templates (and adjust the generic test's cost to be less
 attractive), but I can't test on !x86oids.

 Spotted by Douglas Katzman.

src/compiler/x86-64/pred.lisp
src/compiler/x86/pred.lisp

index 428c2c1..e66a11d 100644 (file)
   (:conditional :e)
   (:policy :fast-safe)
   (:translate eq)
-  (:generator 3
+  (:generator 8
     (cond
      ((sc-is y immediate)
       (let ((val (tn-value y)))
                                character-widetag))))))
       (t
        (inst cmp x y)))))
+
+;; The template above is a very good fallback for the generic
+;; case.  However, it is sometimes possible to perform unboxed
+;; comparisons.  Repurpose char= and eql templates here, instead
+;; of forcing values to be boxed and then compared.
+;;
+;; We only weaken EQL => EQ for characters and fixnums, and detect
+;; when types definitely mismatch.  No need to import other EQL
+;; VOPs (e.g. floats).
+(macrolet ((def (eq-name eql-name)
+             `(define-vop (,eq-name ,eql-name)
+                (:translate eq))))
+  (def fast-if-eq-character fast-char=/character)
+  (def fast-if-eq-character/c fast-char=/character/c)
+  (def fast-if-eq/signed fast-if-eql/signed)
+  (def fast-if-eq-c/signed fast-if-eql-c/signed)
+  (def fast-if-eq/unsigned fast-if-eql/unsigned)
+  (def fast-if-eq-c/unsigned fast-if-eql-c/unsigned))
index da77d6f..7be691e 100644 (file)
   (:info)
   (:policy :fast-safe)
   (:translate eq)
-  (:generator 3
+  (:generator 8
     (let ((x-val (encode-value-if-immediate x))
           (y-val (encode-value-if-immediate y)))
       (cond
         ((sc-is x immediate) (inst cmp y x-val))
 
         (t (inst cmp x y-val))))))
+
+(macrolet ((def (eq-name eql-name)
+             `(define-vop (,eq-name ,eql-name)
+                (:translate eq))))
+  (def fast-if-eq-character fast-char=/character)
+  (def fast-if-eq-character/c fast-char=/character/c)
+  (def fast-if-eq/signed fast-if-eql/signed)
+  (def fast-if-eq-c/signed fast-if-eql-c/signed)
+  (def fast-if-eq/unsigned fast-if-eql/unsigned)
+  (def fast-if-eq-c/unsigned fast-if-eql-c/unsigned))