Fix make-array transforms.
[sbcl.git] / OPTIMIZATIONS
index 623e433..42119ac 100644 (file)
@@ -157,20 +157,6 @@ 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)
@@ -182,26 +168,13 @@ DX is not allocated on stack.
       (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.
+Result of MAKE is not stack allocated.
 --------------------------------------------------------------------------------
 #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.
+a. Iterations on &REST lists could be rewritten with &MORE vectors.
 b. Implement local unknown-values mv-call (useful for fast type checking).
 --------------------------------------------------------------------------------
 #26
@@ -220,13 +193,20 @@ SBCL cannot derive upper bound for I and uses generic arithmetic here:
 should know the connection between an NLE and its CLEANUP.)
 --------------------------------------------------------------------------------
 #27
-(We always zeroize stack-allocated arrays of boxed elements.  The
-previous note here suggested that we could avoid that step on
-platforms with conservative GC; it's not clear to me (NJF) that
-doing so is a wise idea.)
-
-x86 and x86-64 do not zeroize stack-allocated arrays of unboxed
-elements; other platforms could copy what they do.
+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.
+
+(This is harder than it might look at first glance, as MAKE-ARRAY is smart
+enough to eliminate something like ':initial-element 0'.  Such an optimization
+is valid if the vector is being allocated in the heap, but not if it is being
+allocated on the stack.  You could remove this optimization, but that makes
+the heap-allocated case somewhat slower...)
+
+To do this, extend ALLOCATE-VECTOR with ALLOW-JUNK argument, and when
+stack allocating don't zero if it is true -- and probably ALLOW-JUNK iff
+the vector is a specialized one (cannot have pointers.)
 --------------------------------------------------------------------------------
 #28
 a. Accessing raw slots in structure instances is more inefficient than
@@ -261,21 +241,6 @@ vm-support-routine COMBINATION-IMPLEMENTATION-STYLE and its use in
 src/compiler/ir1opt.lisp, IR1-OPTIMIZE-COMBINATION.  The above
 optimizations are left as an exercise for the reader.)
 --------------------------------------------------------------------------------
-#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.
---------------------------------------------------------------------------------
 #31
 The typecheck generated for a declaration like (integer 0 45) on x86 looks
 like:
@@ -325,32 +290,6 @@ using the x86 FP stack.  It would be nice if SBCL included an SSE2-based
 floating point backend with a compile-time option to switch between the
 two.
 --------------------------------------------------------------------------------
-#34
-Compiling
-
-(defun foo (x y)
-  (declare (type (integer 0 45) x y))
-  (+ x y))
-
-results in the following error trapping code for type-checking the
-arguments:
-
-;      424: L0:   8B058CE31812     MOV EAX, [#x1218E38C]      ; '(MOD 46)
-;      42A:       0F0B0A           BREAK 10                   ; error trap
-;      42D:       05               BYTE #X05
-;      42E:       1F               BYTE #X1F                  ; OBJECT-NOT-TYPE-ERROR
-;      42F:       FECE01           BYTE #XFE, #XCE, #X01      ; EDI
-;      432:       0E               BYTE #X0E                  ; EAX
-;      433: L1:   8B0590E31812     MOV EAX, [#x1218E390]      ; '(MOD 46)
-;      439:       0F0B0A           BREAK 10                   ; error trap
-;      43C:       03               BYTE #X03
-;      43D:       1F               BYTE #X1F                  ; OBJECT-NOT-TYPE-ERROR
-;      43E:       8E               BYTE #X8E                  ; EDX
-;      43F:       0E               BYTE #X0E                  ; EAX
-
-Notice that '(MOD 46) has two entries in the constant vector.  Having
-one would be preferable.
---------------------------------------------------------------------------------
 #35
 Compiling
 
@@ -408,8 +347,60 @@ all three comparisons or b) eliminated the necessity of the MOV(s)
 altogether.  The former option is probably easier than the latter.
 
 --------------------------------------------------------------------------------
-#37
+#38
+
+(setf (subseq s1 start1 end1) (subseq s2 start2 end1))
+
+could be transformed into
+
+(let ((#:s2 s2)
+      (#:start2 start2)
+      (#:end2 end2))
+ (replace s1 #:s2 :start1 start1 :end1 end1 :start2 #:start2 :end2 #:end2))
+
+when the return value is unused, avoiding the need to cons up the new sequence.
+
+--------------------------------------------------------------------------------
+#39
+
+(let ((*foo* 42)) ...)
+
+currently compiles to code that ensures the TLS index at runtime, which
+is both a decently large chunk of code and unnecessary, as we could ensure
+the TLS index at load-time as well.
+
+--------------------------------------------------------------------------------
+#40
+
+When FTYPE is declared -- to say (function (t t t t t) t), and
+function has a compiler-macro,
+
+  (apply #'foo 'x1 x2 'x3 more)
+
+can be transformed into
+
+  (apply (lambda (x2 x4 x5) (foo 'x1 x2 'x3 x4 x5)) x2 more)
+
+which allows compiler-macro-expansion for FOO. (Only constant
+arguments can be moved inside the new lambda -- otherwise evaluation
+order is altered.)
+
+--------------------------------------------------------------------------------
+#41
+
+The unibyte external formats are written in a very generic way.  Three
+optimizations immediately applicable that could be automatically
+generated:
+
+(a) if the external format merely permutes the first 256 characters, a
+    constant-time lookup (rather than a binary search) could be
+    performed on output.  This applies at least to EBCDIC, which
+    currently has a hand-rolled mapper instead.
 
-Dynamic extent allocation doesn't currently work for one-element lists,
-since there's a source transform from (LIST X) to (CONS X NIL).
+(b) if there are no undefined characters corresponding to the 256
+    codes, then no error checking need be done on input.
 
+(c) if there is a way to use particular bits of the exceptional
+    characters, constant-time output (rather than binary search) can
+    still be achieved as used to be done by the latin-9 external
+    format before 1.0.31.