* On X86 I is represented as a tagged integer.
-* EQL uses "CMP reg,reg" instead of "CMP reg,im". This causes
- allocation of an extra register and an extra move.
-
* Unnecessary move:
3: SLOT S!11[EDX] {SB-C::VECTOR-LENGTH 1 7} => t23[EAX]
4: MOVE t23[EAX] => t24[EBX]
* And why two moves?
--------------------------------------------------------------------------------
-#5
-(loop repeat 1.5)
-
-uses generic arithmetic
---------------------------------------------------------------------------------
-#6
-09:49:05 <jtra> I have found a case in those where suboptimal code is
- generate with nested loops, it might be moderately easy to fix that
-09:49:28 <jtra> see
- http://www.bagley.org/~doug/shootout/bench/nestedloop/nestedloop.cmucl
-09:50:30 <jtra> if you add declarations to dotimes, generated code is
- almost optimal, but most inner loops run out of registers and use
- memory location for iteration variable
-
-;;; -*- mode: lisp -*-
-;;; $Id$
-;;; http://www.bagley.org/~doug/shootout/
-;;; from Friedrich Dominicus
-
-(defun main ()
- (let ((n (parse-integer (or (car (last extensions:*command-line-strings*)) "1")))
- (x 0))
- (declare (fixnum n)
- (fixnum x)
- (optimize (speed 3) (debug 0) (safety 0)))
- (dotimes (a n)
- (dotimes (b n)
- (dotimes (c n)
- (dotimes (d n)
- (dotimes (e n)
- (dotimes (f n)
- (incf x)))))))
- (format t "~A~%" x)))
---------------------------------------------------------------------------------
-#7
-(defun foo (x)
- (declare (optimize speed (debug 0)))
- (if (< x 0) x (foo (1- x))))
-
-SBCL generates a full call of FOO (but CMUCL does not).
---------------------------------------------------------------------------------
#8
(defun foo (d)
(declare (optimize (speed 3) (safety 0) (debug 0)))
(declare (type (double-float 0d0 1d0) d))
(loop for i fixnum from 1 to 5
- for x1 double-float = (sin d) ;;; !!!
- do (loop for j fixnum from 1 to 4
- sum x1 double-float)))
+ for x1 double-float = (sin d) ;;; !!!
+ do (loop for j fixnum from 1 to 4
+ sum x1 double-float)))
Without the marked declaration Python will use boxed representation for X1.
DOUBLE-FLOAT. Unhopefully, IR1 does not optimize away effectless
SETs/bindings, and IR2 does not perform type inference.
--------------------------------------------------------------------------------
-#9
+#9 "Multi-path constant folding"
(defun foo (x)
(if (= (cond ((irgh x) 0)
((buh x) 1)
((buh x) :no)
(t :no)))
--------------------------------------------------------------------------------
-#10
-Reported by Robert E. Brown on sbcl-devel 2003-01-21:
-
-(defstruct trace-info
- (foo nil :type (or null function)))
+#11
+(inverted variant of #9)
-(defun bad (x)
- (declare (optimize (speed 3) (safety 0)))
- (let ((wow (trace-info-foo x)))
- (or (not wow) (funcall wow 1 2 3))))
+(lambda (x)
+ (let ((y (sap-alien x c-string)))
+ (list (alien-sap y)
+ (alien-sap y))))
-Python does not derive that FUNCALL is applied to FUNCTION.
+It could be optimized to
-(OR ...) is equivalent to
+(lambda (x) (list x x))
-(LET ((G2407 (NOT WOW)))
- (IF G2407 G2407 (FUNCALL WOW 1 2 3)))
+(if Y were used only once, the current compiler would optimize it)
+--------------------------------------------------------------------------------
+#12
+(typep (truly-the (simple-array * (*)) x) 'simple-vector)
-or to
+tests lowtag.
+--------------------------------------------------------------------------------
+#13
+FAST-+/FIXNUM and similar should accept unboxed arguments in interests
+of representation selection. Problem: inter-TN dependencies.
+--------------------------------------------------------------------------------
+#14
+The derived type of (/ (THE (DOUBLE-FLOAT (0D0)) X) (THE (DOUBLE-FLOAT
+1D0) Y)) is (DOUBLE-FLOAT 0.0d0). While it might be reasonable, it is
+better to derive (OR (MEMBER 0.0d0) (DOUBLE-FLOAT (0.0d0))).
+--------------------------------------------------------------------------------
+#15
+On the alpha, the system is reluctant to refer directly to a constant bignum,
+preferring to load a large constant through a slow sequence of instructions,
+then cons up a bignum for it:
+
+(LAMBDA (A)
+ (DECLARE (OPTIMIZE (SAFETY 1) (SPEED 3) (DEBUG 1))
+ (TYPE (INTEGER -10000 10000) A)
+ (IGNORABLE A))
+ (CASE A
+ ((89 125 16) (ASH A (MIN 18 -706)))
+ (T (DPB -3 (BYTE 30 30) -1))))
+--------------------------------------------------------------------------------
+#16
+(do ((i 0 (1+ i)))
+ ((= i (the (integer 0 100) n)))
+ ...)
-(LET ((G2407 (IF WOW NIL T)))
- (IF G2407 G2407 (FUNCALL WOW 1 2 3)))
+It is commonly expected for Python to derive (FIXNUMP I). (If ``='' is
+replaced with ``>='', Python will do.)
+--------------------------------------------------------------------------------
+#17
+Type tests for (ARRAY BIT), (ARRAY T) and similar go through full
+%TYPEP, even though it is relatively simple to establish the arrayness
+of an object and also to obtain the element type of an array. As of
+sbcl-0.8.12.30, this affects at least DUMP-OBJECT through
+COMPOUND-OBJECT-P, and (LABELS MAYBE-EMIT-MAKE-LOAD-FORMS GROVEL)
+through TYPEP UNBOXED-ARRAY, within the compiler itself.
+--------------------------------------------------------------------------------
+#18
+(lambda (x) (declare (null x)) (sxhash x)) goes through SYMBOL-HASH
+rather than either constant-folding or manipulating NIL-VALUE or
+NULL-TN directly.
+--------------------------------------------------------------------------------
+#19
+ (let ((dx (if (foo)
+ (list x)
+ (list y z))))
+ (declare (dynamic-extent dx))
+ ...)
+
+DX is not allocated on stack.
+--------------------------------------------------------------------------------
+#20
+(defun-with-dx foo (x)
+ (flet ((make (x)
+ (let ((l (list nil nil)))
+ (setf (first l) x)
+ (setf (second l) (1- x))
+ l)))
+ (let ((l (make x)))
+ (declare (dynamic-extent l))
+ (mapc #'print l))))
+
+Result of MAKE is not stack allocated, which means that
+stack-allocation of structures is impossible.
+--------------------------------------------------------------------------------
+#21
+(defun-with-dx foo ()
+ (let ((dx (list (list 1 2) (list 3 4)
+ (declare (dynamic-extent dx))
+ ...)))))
-so this is similar to #9.
+External list in DX is allocated on stack, but internal are not.
+--------------------------------------------------------------------------------
+#22
+IR2 does not perform unused code flushing.
+--------------------------------------------------------------------------------
+#23
+Python does not know that &REST lists are LISTs (and cannot derive it).
--------------------------------------------------------------------------------
+#24
+a. Iterations on &REST lists, returning them as VALUES could be
+ rewritten with &MORE vectors.
+b. Implement local unknown-values mv-call (useful for fast type checking).