Hello, Chong and everybody, After bytecomp.el is revised, problems remains as follows; 1. Operations are all compiled to binary operations. It may cause overflows or truncations in floating point data operations. ==> solved. 2. Most integer constants are moved to the end of expressions and pre-calculated at compile time. Changing of order may cause different result from original expressions. (In other words, `byte-optimize-delay-constants-math' should not be called) ==> In multiplication/division, problems become not to occur. I suppose it is because difference of precision/scale size in elisp, execution level, processor internal (elisp < C < processor) take over the issue. (let ((a (expt 2 -1074)) (b 0.125)) (list (* a b 8) (* (* a b) 8))) --> (5e-324 0.0) I can't find the bad case so far. So, in multiplication and division, I suppose, at least now, changing calculation order is allowable and leave `byte-optimize-delay-constants-math'. Addition/Subtraction still show this problem. 3. Mulitiplication/Division optimization sometimes don't consider floating point operators. ==> Add patterns. Examples. (let ((a most-positive-fixnum) (b 2.0)) (* a 2 b)) --> 1073741820.0 --> -4.0 (let ((a 3) (b 2)) (/ a b 1.0)) --> 1.5 --> 1 4. In division, optimizing -1 twice and cause erroneous results. ==> Easy. To get all examples at a glance, see the attached `byte-test-minimal.el' or its log file. Changing policy / plan * Change functions byte-optimize-plus, byte-optimize-minus, byte-optimize-multiply, byte-optimize-divide. * All modifications are closed to the function itself. Don't add other functions, symbols. * Don't call `byte-optimize-delay-constants-math' in plus, minus operations. Remain to call it in multiplication, division operations. * Call `byte-optimize-predicate' at the last as in minus operation. This will optimize expressions that all arguments are constant to constant values. * Consider frequency or possibility. ** Remove/Abandon some optimizations. *** Most optimizations that need floating point data result. **** Zero in operands of multiplication or division (first operand). This case seems rare. If you do something, it's like below, Multiplication: (cond ((or (memql 0.0 (cdr form)) (and (eq 0 last) (memq t (mapcar #'floatp (cdr form))))) (setq form (nconc (list 'progn) (delq 0 (mapcar (lambda (x) (if (or (numberp x) (symbolp x)) 0 x)) (cdr form))) (list 0.0)))) Division: (cond ((or (eql (cadr form) 0.0) (and (eq (cadr form) 0) (memq t (mapcar #'floatp (cddr form))))) ;; This optimization may throw out division by zero error. (setq form (nconc (list 'progn) (delq 0 (mapcar (lambda (x) (if (or (numberp x) (symbolp x)) 0 x)) (cdr form))) (list 0.0)))) ((and (eq (cadr form 0) 0) (numberp last) (nthcdr 3 form)) (setq form (byte-compile-butlast form)) ) ** Add some optimizations. *** Optimize addtion/subtraction where their last operand is 1 or -1 to use `1+', `1-' funcitons. This pattern often appears and more effective at least in size (byte-add1 vs constant 1). *** Other small changes. Files: ChangeLog byte-opt.el - modified file. byte-opt.diff - diff by `diff -c OLD NEW >byte-opt.diff' byte-test-minimal.el - test script to compare original and revised. log.summary - sammary output by byte-test-minimal log.detail - detailed (with disassembled code) output by byte-test-minimal. byte-regress-minimal.el - simple coverage test log.regress - log output of the coverage test If something is wrong, let me know, please. Regards, Shigeru 2008/11/15 Chong Yidong : > "Shigeru Fukaya" writes: > >>> Could you separate out the byte-optimize-*-functions part of the patch? >> >> They are mutually affected. So I'll make and send a patch of >> byte-opt.el that includes minimal changes to the latest CVS. It is >> necessary because the current byte-opt.el still has problems I >> pointed. It will take a few days. >> >> Is it ok? > > That would be great. Thanks! >