bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#1334: 23.0.60; bug of bytecomp arithmetic operations


From: Shigeru Fukaya
Subject: bug#1334: 23.0.60; bug of bytecomp arithmetic operations
Date: Wed, 19 Nov 2008 21:27:01 +0900

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 <cyd@stupidchicken.com>:
> "Shigeru Fukaya" <shigeru.fukaya@gmail.com> 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!
>

Attachment: bc2.tgz
Description: GNU Zip compressed data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]