X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=OPTIMIZATIONS;h=0c8e790a86ae463ece5795b9fcaac1d1312cf8b3;hb=2e86a718672b73c942e51dfbda7eb9db8746b6f4;hp=53438ab4a996f18951a81d5f7b69e453200b522a;hpb=f846a7a310d630cf538811959916492a28a75fb1;p=sbcl.git diff --git a/OPTIMIZATIONS b/OPTIMIZATIONS index 53438ab..0c8e790 100644 --- a/OPTIMIZATIONS +++ b/OPTIMIZATIONS @@ -187,9 +187,9 @@ stack-allocation of structures is impossible. -------------------------------------------------------------------------------- #21 (defun-with-dx foo () - (let ((dx (list (list 1 2) (list 3 4) + (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. -------------------------------------------------------------------------------- @@ -204,20 +204,6 @@ 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). -------------------------------------------------------------------------------- -#25 -EQL is implemented generically in situations where this isn't necessary. - -(defun f (x y) - (declare (type (or symbol fixnum) x) - (optimize speed (safety 0) (debug 0))) - (eql x y)) - -SUBTYPEP is smart enough to determine that this type is a subtype -of (and (or (not number) fixnum) (not character)) - -This sitation where the type is (OR NULL FIXNUM) comes up -in cl-bench, for example in the value returned by POSITION. --------------------------------------------------------------------------------- #26 SBCL cannot derive upper bound for I and uses generic arithmetic here: @@ -232,3 +218,65 @@ SBCL cannot derive upper bound for I and uses generic arithmetic here: (So the constraint propagator or a possible future SSA-convertor should know the connection between an NLE and its CLEANUP.) +-------------------------------------------------------------------------------- +#27 +Initialization of stack-allocated arrays is inefficient: we always +fill the vector with zeroes, even when it is not needed (as for +platforms with conservative GC or for arrays of unboxed objectes) and +is performed later explicitely. +-------------------------------------------------------------------------------- +#28 +a. Accessing raw slots in structure instances is more inefficient than +it could be; if we placed raw slots before the header word, we would +not need to do arithmetic at runtime to access them. (But beware: +this would complicate handling of the interior pointer). + +b. (Also note that raw slots are currently disabled on HPPA) +-------------------------------------------------------------------------------- +#29 +Python is overly zealous when converting high-level CL functions, such +as MIN/MAX, LOGBITP, and LOGTEST, to low-level CL functions. Reducing +Python's aggressiveness would make it easier to effect changes such as + +x86-64: +* direct MIN/MAX on {SINGLE,DOUBLE}-FLOATs ({MIN,MAX}S{S,D}) + +x86{,-64}: +* direct LOGBITP on word-sized integers and fixnums (BT + JC) + +x86{,-64}/PPC: +* branch-free MIN/MAX on word-sized integers and fixnums +* efficient LOGTESTs on word-sized integers and fixnums (TEST / AND.) + +PPC: +* efficient LDB on word-sized integers and fixnums (RLWINM) + +etc., etc. + +The "easier" part claimed above would come about because the functions +would be available for :TRANSLATE through a VOP or similar, whereas with +the current architecture, one would have to pattern-match IR1. While +IR1 pattern-matching would be useful in other contexts, it seems better +here to attempt the direct :TRANSLATE route. + +I (NJF) don't know how to implement such architecture-specific +optimizations whilst keeping the high->low transformations for other +architectures. Certainly adding #!+/- magic in compiler/*.lisp could be +done, but such a solution is somewhat inelegant. Moving the relevant +DEFTRANSFORMs to the architecture-specific compiler/* areas is also +possible, but that would duplicate quite a bit of code. +-------------------------------------------------------------------------------- +#30 +(defun foo (x y) + (< x y)) + +FOO's IR1 representation is roughly: + +(defun foo (x y) + (if (< x y) + T + NIL)) + +However, if a full call is generated for < (and similarly for other +predicate functions), then the IF is unnecessary, since the return value +of (< x y) is already T or NIL.