diff options
| author | Chong Yidong | 2008-11-21 18:51:48 +0000 |
|---|---|---|
| committer | Chong Yidong | 2008-11-21 18:51:48 +0000 |
| commit | cbe5b0eb180dacdf376c2977c2bafce67ea16bbf (patch) | |
| tree | 8ec79aeaca3d4101021f3cc86740943bcb07a4e6 | |
| parent | 86edb1119d684c2ee5c1a78253844d60e4af9c73 (diff) | |
| download | emacs-cbe5b0eb180dacdf376c2977c2bafce67ea16bbf.tar.gz emacs-cbe5b0eb180dacdf376c2977c2bafce67ea16bbf.zip | |
(byte-compile-butlast): Move up in file.
(byte-optimize-plus): Don't call
byte-optimize-delay-constants-math (bug#1334). Use
byte-optimize-predicate to optimize constants.
(byte-optimize-minus): Don't call
byte-optimize-delay-constants-math. Remove zero arguments first
if possible. Call byte-optimize-predicate to optimize constants.
(byte-optimize-multiply): Remove optimizations for arguments of 0
and 2, which may be inaccurate. Optimize (* x -1) to (- x). Call
byte-optimize-predicate.
(byte-optimize-divide): Leave runtime errors unchanged.
Optimize (/ x 1) to (+ x 0). Remove optimizations for arguments of
0 and 2.0, which may be inaccurate. Call byte-optimize-predicate.
| -rw-r--r-- | lisp/emacs-lisp/byte-opt.el | 187 |
1 files changed, 86 insertions, 101 deletions
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index c34c88cb72d..c83e80898dc 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el | |||
| @@ -747,119 +747,104 @@ | |||
| 747 | (list (apply fun (nreverse constants))))))))) | 747 | (list (apply fun (nreverse constants))))))))) |
| 748 | form)) | 748 | form)) |
| 749 | 749 | ||
| 750 | (defsubst byte-compile-butlast (form) | ||
| 751 | (nreverse (cdr (reverse form)))) | ||
| 752 | |||
| 750 | (defun byte-optimize-plus (form) | 753 | (defun byte-optimize-plus (form) |
| 751 | (setq form (byte-optimize-delay-constants-math form 1 '+)) | 754 | ;; Don't call `byte-optimize-delay-constants-math' (bug#1334). |
| 755 | ;;(setq form (byte-optimize-delay-constants-math form 1 '+)) | ||
| 752 | (if (memq 0 form) (setq form (delq 0 (copy-sequence form)))) | 756 | (if (memq 0 form) (setq form (delq 0 (copy-sequence form)))) |
| 753 | ;;(setq form (byte-optimize-associative-two-args-math form)) | 757 | ;; For (+ constants...), byte-optimize-predicate does the work. |
| 754 | (cond ((null (cdr form)) | 758 | (when (memq nil (mapcar 'numberp (cdr form))) |
| 755 | (condition-case () | 759 | (cond |
| 756 | (eval form) | 760 | ;; (+ x 1) --> (1+ x) and (+ x -1) --> (1- x). |
| 757 | (error form))) | 761 | ((and (= (length form) 3) |
| 758 | ;;; It is not safe to delete the function entirely | 762 | (or (memq (nth 1 form) '(1 -1)) |
| 759 | ;;; (actually, it would be safe if we know the sole arg | 763 | (memq (nth 2 form) '(1 -1)))) |
| 760 | ;;; is not a marker). | 764 | (let (integer other) |
| 761 | ;;; ((null (cdr (cdr form))) (nth 1 form)) | 765 | (if (memq (nth 1 form) '(1 -1)) |
| 762 | ((null (cddr form)) | 766 | (setq integer (nth 1 form) other (nth 2 form)) |
| 763 | (if (numberp (nth 1 form)) | 767 | (setq integer (nth 2 form) other (nth 1 form))) |
| 764 | (nth 1 form) | 768 | (setq form |
| 765 | form)) | 769 | (list (if (eq integer 1) '1+ '1-) other)))) |
| 766 | ((and (null (nthcdr 3 form)) | 770 | ;; Here, we could also do |
| 767 | (or (memq (nth 1 form) '(1 -1)) | 771 | ;; (+ x y ... 1) --> (1+ (+ x y ...)) |
| 768 | (memq (nth 2 form) '(1 -1)))) | 772 | ;; (+ x y ... -1) --> (1- (+ x y ...)) |
| 769 | ;; Optimize (+ x 1) into (1+ x) and (+ x -1) into (1- x). | 773 | ;; The resulting bytecode is smaller, but is it faster? -- cyd |
| 770 | (let ((integer | 774 | )) |
| 771 | (if (memq (nth 1 form) '(1 -1)) | 775 | (byte-optimize-predicate form)) |
| 772 | (nth 1 form) | ||
| 773 | (nth 2 form))) | ||
| 774 | (other | ||
| 775 | (if (memq (nth 1 form) '(1 -1)) | ||
| 776 | (nth 2 form) | ||
| 777 | (nth 1 form)))) | ||
| 778 | (list (if (eq integer 1) '1+ '1-) | ||
| 779 | other))) | ||
| 780 | (t form))) | ||
| 781 | 776 | ||
| 782 | (defun byte-optimize-minus (form) | 777 | (defun byte-optimize-minus (form) |
| 783 | ;; Put constants at the end, except the last constant. | 778 | ;; Don't call `byte-optimize-delay-constants-math' (bug#1334). |
| 784 | (setq form (byte-optimize-delay-constants-math form 2 '+)) | 779 | ;;(setq form (byte-optimize-delay-constants-math form 2 '+)) |
| 785 | ;; Now only first and last element can be a number. | 780 | ;; Remove zeros. |
| 786 | (let ((last (car (reverse (nthcdr 3 form))))) | 781 | (when (and (nthcdr 3 form) |
| 787 | (cond ((eq 0 last) | 782 | (memq 0 (cddr form))) |
| 788 | ;; (- x y ... 0) --> (- x y ...) | 783 | (setq form (nconc (list (car form) (cadr form)) |
| 789 | (setq form (copy-sequence form)) | 784 | (delq 0 (copy-sequence (cddr form))))) |
| 790 | (setcdr (cdr (cdr form)) (delq 0 (nthcdr 3 form)))) | 785 | ;; After the above, we must turn (- x) back into (- x 0) |
| 791 | ((equal (nthcdr 2 form) '(1)) | 786 | (or (cddr form) |
| 792 | (setq form (list '1- (nth 1 form)))) | 787 | (setq form (nconc form (list 0))))) |
| 793 | ((equal (nthcdr 2 form) '(-1)) | 788 | ;; For (- constants..), byte-optimize-predicate does the work. |
| 794 | (setq form (list '1+ (nth 1 form)))) | 789 | (when (memq nil (mapcar 'numberp (cdr form))) |
| 795 | ;; If form is (- CONST foo... CONST), merge first and last. | 790 | (cond |
| 796 | ((and (numberp (nth 1 form)) | 791 | ;; (- x 1) --> (1- x) |
| 797 | (numberp last)) | 792 | ((equal (nthcdr 2 form) '(1)) |
| 798 | (setq form (nconc (list '- (- (nth 1 form) last) (nth 2 form)) | 793 | (setq form (list '1- (nth 1 form)))) |
| 799 | (delq last (copy-sequence (nthcdr 3 form)))))))) | 794 | ;; (- x -1) --> (1+ x) |
| 800 | ;;; It is not safe to delete the function entirely | 795 | ((equal (nthcdr 2 form) '(-1)) |
| 801 | ;;; (actually, it would be safe if we know the sole arg | 796 | (setq form (list '1+ (nth 1 form)))) |
| 802 | ;;; is not a marker). | 797 | ;; (- 0 x) --> (- x) |
| 803 | ;;; (if (eq (nth 2 form) 0) | 798 | ((and (eq (nth 1 form) 0) |
| 804 | ;;; (nth 1 form) ; (- x 0) --> x | 799 | (= (length form) 3)) |
| 805 | (byte-optimize-predicate | 800 | (setq form (list '- (nth 2 form)))) |
| 806 | (if (and (null (cdr (cdr (cdr form)))) | 801 | ;; Here, we could also do |
| 807 | (eq (nth 1 form) 0)) ; (- 0 x) --> (- x) | 802 | ;; (- x y ... 1) --> (1- (- x y ...)) |
| 808 | (cons (car form) (cdr (cdr form))) | 803 | ;; (- x y ... -1) --> (1+ (- x y ...)) |
| 809 | form)) | 804 | ;; The resulting bytecode is smaller, but is it faster? -- cyd |
| 810 | ;;; ) | 805 | )) |
| 811 | ) | 806 | (byte-optimize-predicate form)) |
| 812 | 807 | ||
| 813 | (defun byte-optimize-multiply (form) | 808 | (defun byte-optimize-multiply (form) |
| 814 | (setq form (byte-optimize-delay-constants-math form 1 '*)) | 809 | (setq form (byte-optimize-delay-constants-math form 1 '*)) |
| 815 | ;; If there is a constant in FORM, it is now the last element. | 810 | ;; For (* constants..), byte-optimize-predicate does the work. |
| 816 | (cond ((null (cdr form)) 1) | 811 | (when (memq nil (mapcar 'numberp (cdr form))) |
| 817 | ;;; It is not safe to delete the function entirely | 812 | ;; After `byte-optimize-predicate', if there is a INTEGER constant |
| 818 | ;;; (actually, it would be safe if we know the sole arg | 813 | ;; in FORM, it is in the last element. |
| 819 | ;;; is not a marker or if it appears in other arithmetic). | 814 | (let ((last (car (reverse (cdr form))))) |
| 820 | ;;; ((null (cdr (cdr form))) (nth 1 form)) | 815 | (cond |
| 821 | ((let ((last (car (reverse form)))) | 816 | ;; Would handling (* ... 0) here cause floating point errors? |
| 822 | (cond ((eq 0 last) (cons 'progn (cdr form))) | 817 | ;; See bug#1334. |
| 823 | ((eq 1 last) (delq 1 (copy-sequence form))) | 818 | ((eq 1 last) (setq form (byte-compile-butlast form))) |
| 824 | ((eq -1 last) (list '- (delq -1 (copy-sequence form)))) | 819 | ((eq -1 last) |
| 825 | ((and (eq 2 last) | 820 | (setq form (list '- (if (nthcdr 3 form) |
| 826 | (memq t (mapcar 'symbolp (cdr form)))) | 821 | (byte-compile-butlast form) |
| 827 | (prog1 (setq form (delq 2 (copy-sequence form))) | 822 | (nth 1 form)))))))) |
| 828 | (while (not (symbolp (car (setq form (cdr form)))))) | 823 | (byte-optimize-predicate form)) |
| 829 | (setcar form (list '+ (car form) (car form))))) | ||
| 830 | (form)))))) | ||
| 831 | |||
| 832 | (defsubst byte-compile-butlast (form) | ||
| 833 | (nreverse (cdr (reverse form)))) | ||
| 834 | 824 | ||
| 835 | (defun byte-optimize-divide (form) | 825 | (defun byte-optimize-divide (form) |
| 836 | (setq form (byte-optimize-delay-constants-math form 2 '*)) | 826 | (setq form (byte-optimize-delay-constants-math form 2 '*)) |
| 827 | ;; After `byte-optimize-predicate', if there is a INTEGER constant | ||
| 828 | ;; in FORM, it is in the last element. | ||
| 837 | (let ((last (car (reverse (cdr (cdr form)))))) | 829 | (let ((last (car (reverse (cdr (cdr form)))))) |
| 838 | (if (numberp last) | ||
| 839 | (cond ((= (length form) 3) | ||
| 840 | (if (and (numberp (nth 1 form)) | ||
| 841 | (not (zerop last)) | ||
| 842 | (condition-case nil | ||
| 843 | (/ (nth 1 form) last) | ||
| 844 | (error nil))) | ||
| 845 | (setq form (list 'progn (/ (nth 1 form) last))))) | ||
| 846 | ((= last 1) | ||
| 847 | (setq form (byte-compile-butlast form))) | ||
| 848 | ((numberp (nth 1 form)) | ||
| 849 | (setq form (cons (car form) | ||
| 850 | (cons (/ (nth 1 form) last) | ||
| 851 | (byte-compile-butlast (cdr (cdr form))))) | ||
| 852 | last nil)))) | ||
| 853 | (cond | 830 | (cond |
| 854 | ;;; ((null (cdr (cdr form))) | 831 | ;; Runtime error (leave it intact). |
| 855 | ;;; (nth 1 form)) | 832 | ((or (null last) |
| 856 | ((eq (nth 1 form) 0) | 833 | (eq last 0) |
| 857 | (append '(progn) (cdr (cdr form)) '(0))) | 834 | (memql 0.0 (cddr form)))) |
| 858 | ((eq last -1) | 835 | ;; No constants in expression |
| 859 | (list '- (if (nthcdr 3 form) | 836 | ((not (numberp last))) |
| 860 | (byte-compile-butlast form) | 837 | ;; For (* constants..), byte-optimize-predicate does the work. |
| 861 | (nth 1 form)))) | 838 | ((null (memq nil (mapcar 'numberp (cdr form))))) |
| 862 | (form)))) | 839 | ;; (/ x y.. 1) --> (/ x y..) |
| 840 | ((and (eq last 1) (nthcdr 3 form)) | ||
| 841 | (setq form (byte-compile-butlast form))) | ||
| 842 | ;; (/ x -1), (/ x .. -1) --> (- x), (- (/ x ..)) | ||
| 843 | ((eq last -1) | ||
| 844 | (setq form (list '- (if (nthcdr 3 form) | ||
| 845 | (byte-compile-butlast form) | ||
| 846 | (nth 1 form))))))) | ||
| 847 | (byte-optimize-predicate form)) | ||
| 863 | 848 | ||
| 864 | (defun byte-optimize-logmumble (form) | 849 | (defun byte-optimize-logmumble (form) |
| 865 | (setq form (byte-optimize-delay-constants-math form 1 (car form))) | 850 | (setq form (byte-optimize-delay-constants-math form 1 (car form))) |