lp#994528)
* optimization: EQUAL and EQUALP transforms are smarter.
(thanks to Elias Martenson, lp#1220084)
+ * optimization: CHAR-EQUAL is faster for constant and base-char arguments.
* bug fix: probe-file now can access symlinks to pipes and sockets in
/proc/pid/fd on Linux. (reported by Eric Schulte)
* bug fix: SBCL can now be built on Solaris x86-64.
"TWO-ARG-CHAR-EQUAL" "TWO-ARG-CHAR-NOT-EQUAL"
"TWO-ARG-CHAR-LESSP" "TWO-ARG-CHAR-NOT-LESSP"
"TWO-ARG-CHAR-GREATERP" "TWO-ARG-CHAR-NOT-GREATERP"
+ "CHAR-EQUAL-CONSTANT"
;; FIXME: potential SB!EXT exports
"CHARACTER-CODING-ERROR"
"CHARACTER-DECODING-ERROR" "CHARACTER-DECODING-ERROR-OCTETS"
(defun two-arg-char-equal (c1 c2)
(or (eq c1 c2)
- (= (equal-char-code c1) (equal-char-code c2))))
+ (typecase c1
+ (base-char
+ (and (base-char-p c2)
+ (let* ((code1 (char-code c1))
+ (code2 (char-code c2))
+ (sum (logxor code1 code2)))
+ (when (eql sum #x20)
+ (let ((sum (+ code1 code2)))
+ (or (and (> sum 161) (< sum 213))
+ (and (> sum 415) (< sum 461))
+ (and (> sum 463) (< sum 477))))))))
+ (t
+ (= (equal-char-code c1) (equal-char-code c2))))))
+
+(defun char-equal-constant (x char reverse-case-char)
+ (declare (type character x))
+ (or (eq char x)
+ (eq reverse-case-char x)))
(defun char-equal (character &rest more-characters)
#!+sb-doc
two-arg-char-not-greaterp)
(character character) boolean (movable foldable flushable))
+(defknown char-equal-constant (character character character)
+ boolean
+ (movable foldable flushable explicit-check))
+
(defknown character (t) character (movable foldable unsafely-flushable))
(defknown char-code (character) char-code (movable foldable flushable))
(defknown (char-upcase char-downcase) (character) character
,(lvar-value x))
(give-up-ir1-transform)))
-(dolist (x '(= char= + * logior logand logxor logtest))
+(dolist (x '(= char= two-arg-char-equal + * logior logand logxor logtest))
(%deftransform x '(function * *) #'commutative-arg-swap
"place constant arg last"))
\f
;;;; character operations
-(deftransform char-equal ((a b) (base-char base-char))
+(deftransform two-arg-char-equal ((a b) (base-char base-char) *
+ :policy (> speed space))
"open code"
'(let* ((ac (char-code a))
(bc (char-code b))
(and (> sum 415) (< sum 461))
(and (> sum 463) (< sum 477))))))))
+(deftransform two-arg-char-equal ((a b) (* (constant-arg character)) *
+ :node node)
+ (let ((char (lvar-value b)))
+ (if (both-case-p char)
+ (let ((reverse (if (upper-case-p char)
+ (char-downcase char)
+ (char-upcase char))))
+ (if (policy node (> speed space))
+ `(or (char= a ,char)
+ (char= a ,reverse))
+ `(char-equal-constant a ,char ,reverse)))
+ '(char= a b))))
+
(deftransform char-upcase ((x) (base-char))
"open code"
'(let ((n-code (char-code x)))
(compile nil `(lambda (x)
(declare (character x) (optimize speed))
(,name x))))
- (dolist (name '(char= char/= char< char> char<= char>= char-equal
- char-not-equal char-lessp char-greaterp char-not-greaterp
+ (dolist (name '(char= char/= char< char> char<= char>=
+ char-lessp char-greaterp char-not-greaterp
char-not-lessp))
(setf current name)
(compile nil `(lambda (x y)