X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=OPTIMIZATIONS;h=b0c8f47fe343d475fa73a9392c955dd31969ca9c;hb=eed9254936fe91e36dd4dbca02c342021917eeb1;hp=99d40ea18241b3e569326c90198055f1cdd8f1df;hpb=37496d2b1c2adb6bd77b2c6c90329af871e97dd5;p=sbcl.git diff --git a/OPTIMIZATIONS b/OPTIMIZATIONS index 99d40ea..b0c8f47 100644 --- a/OPTIMIZATIONS +++ b/OPTIMIZATIONS @@ -11,9 +11,6 @@ * 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] @@ -65,11 +62,6 @@ VOP DATA-VECTOR-SET/SIMPLE-STRING V2!14[EDI] t32[EAX] t30[S2]>t33[CL] * And why two moves? -------------------------------------------------------------------------------- -#5 -(loop repeat 1.5) - -uses generic arithmetic --------------------------------------------------------------------------------- #6 09:49:05 I have found a case in those where suboptimal code is generate with nested loops, it might be moderately easy to fix that @@ -80,7 +72,6 @@ uses generic arithmetic memory location for iteration variable ;;; -*- mode: lisp -*- -;;; $Id$ ;;; http://www.bagley.org/~doug/shootout/ ;;; from Friedrich Dominicus @@ -99,21 +90,14 @@ uses generic arithmetic (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. @@ -158,3 +142,92 @@ It could be optimized to (if Y were used only once, the current compiler would optimize it) -------------------------------------------------------------------------------- +#12 +(typep (truly-the (simple-array * (*)) x) 'simple-vector) + +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))) + ...) + +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)) + ...))))) + +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).