comparison lisp/emacs-lisp/byte-opt.el @ 99772:57a488466504

(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.
author Chong Yidong <cyd@stupidchicken.com>
date Fri, 21 Nov 2008 18:51:48 +0000
parents 90a2847062be
children a9dc0e7c3f2b
comparison
equal deleted inserted replaced
99771:8fff0bee6091 99772:57a488466504
745 (setq form orig) 745 (setq form orig)
746 (setq form (nconc (delq nil form) 746 (setq form (nconc (delq nil form)
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)))
866 (byte-optimize-predicate 851 (byte-optimize-predicate
867 (cond ((memq 0 form) 852 (cond ((memq 0 form)