aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChong Yidong2008-11-21 18:51:48 +0000
committerChong Yidong2008-11-21 18:51:48 +0000
commitcbe5b0eb180dacdf376c2977c2bafce67ea16bbf (patch)
tree8ec79aeaca3d4101021f3cc86740943bcb07a4e6
parent86edb1119d684c2ee5c1a78253844d60e4af9c73 (diff)
downloademacs-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.el187
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)))