comparison lisp/byte-optimize.el @ 446:1ccc32a20af4 r21-2-38

Import from CVS: tag r21-2-38
author cvs
date Mon, 13 Aug 2007 11:37:21 +0200
parents 576fb035e263
children 3078fd1074e8
comparison
equal deleted inserted replaced
445:34f3776fcf0e 446:1ccc32a20af4
1 ;;; byte-optimize.el --- the optimization passes of the emacs-lisp byte compiler. 1 ;;; byte-optimize.el --- the optimization passes of the emacs-lisp byte compiler.
2 2
3 ;;; Copyright (c) 1991, 1994 Free Software Foundation, Inc. 3 ;;; Copyright (c) 1991, 1994 Free Software Foundation, Inc.
4 4
5 ;; Author: Jamie Zawinski <jwz@jwz.org> 5 ;; Authors: Jamie Zawinski <jwz@jwz.org>
6 ;; Hallvard Furuseth <hbf@ulrik.uio.no> 6 ;; Hallvard Furuseth <hbf@ulrik.uio.no>
7 ;; Martin Buchholz <martin@xemacs.org>
7 ;; Keywords: internal 8 ;; Keywords: internal
8 9
9 ;; This file is part of XEmacs. 10 ;; This file is part of XEmacs.
10 11
11 ;; XEmacs is free software; you can redistribute it and/or modify it 12 ;; XEmacs is free software; you can redistribute it and/or modify it
564 (setq opt (get (car form) 'byte-optimizer))) 565 (setq opt (get (car form) 'byte-optimizer)))
565 (not (eq form (setq new (funcall opt form))))) 566 (not (eq form (setq new (funcall opt form)))))
566 (progn 567 (progn
567 ;; (if (equal form new) (error "bogus optimizer -- %s" opt)) 568 ;; (if (equal form new) (error "bogus optimizer -- %s" opt))
568 (byte-compile-log " %s\t==>\t%s" form new) 569 (byte-compile-log " %s\t==>\t%s" form new)
569 (setq new (byte-optimize-form new for-effect)) 570 (byte-optimize-form new for-effect))
570 new)
571 form))) 571 form)))
572 572
573 573
574 (defun byte-optimize-body (forms all-for-effect) 574 (defun byte-optimize-body (forms all-for-effect)
575 ;; Optimize the cdr of a progn or implicit progn; `forms' is a list of 575 ;; Optimize the cdr of a progn or implicit progn; `forms' is a list of
697 (setq form orig) 697 (setq form orig)
698 (setq form (nconc (delq nil form) 698 (setq form (nconc (delq nil form)
699 (list (apply fun (nreverse constants))))))))) 699 (list (apply fun (nreverse constants)))))))))
700 form)) 700 form))
701 701
702 ;;; It is not safe to optimize calls to arithmetic ops with one arg
703 ;;; away entirely (actually, it would be safe if we know the sole arg
704 ;;; is not a marker or if it appears in other arithmetic).
705
706 ;;; But this degree of paranoia is normally unjustified, so optimize unless
707 ;;; the user has done (declaim (safety 3)). Implemented in bytecomp.el.
708
702 (defun byte-optimize-plus (form) 709 (defun byte-optimize-plus (form)
703 (setq form (byte-optimize-delay-constants-math form 1 '+)) 710 (byte-optimize-predicate (byte-optimize-delay-constants-math form 1 '+)))
704 (if (memq 0 form) (setq form (delq 0 (copy-sequence form))))
705 ;;(setq form (byte-optimize-associative-two-args-math form))
706
707 (case (length (cdr form))
708 ((0) ; (+)
709 (condition-case ()
710 (eval form)
711 (error form)))
712
713 ;; It is not safe to delete the function entirely
714 ;; (actually, it would be safe if we knew the sole arg
715 ;; is not a marker).
716 ;; ((1)
717 ;; (nth 1 form))
718
719 ((2) ; (+ x y)
720 (byte-optimize-predicate
721 (cond
722 ;; `add1' and `sub1' are a marginally fewer instructions
723 ;; than `plus' and `minus', so use them when possible.
724 ((eq (nth 1 form) 1) `(1+ ,(nth 2 form))) ; (+ 1 x) --> (1+ x)
725 ((eq (nth 2 form) 1) `(1+ ,(nth 1 form))) ; (+ x 1) --> (1+ x)
726 ((eq (nth 1 form) -1) `(1- ,(nth 2 form))) ; (+ -1 x) --> (1- x)
727 ((eq (nth 2 form) -1) `(1- ,(nth 1 form))) ; (+ x -1) --> (1- x)
728 (t form))))
729
730 (t (byte-optimize-predicate form))))
731
732 (defun byte-optimize-minus (form)
733 ;; Put constants at the end, except the last constant.
734 (setq form (byte-optimize-delay-constants-math form 2 '+))
735 ;; Now only first and last element can be an integer.
736 (let ((last (last (nthcdr 3 form))))
737 (cond ((eq 0 last)
738 ;; (- x y ... 0) --> (- x y ...)
739 (setq form (copy-sequence form))
740 (setcdr (cdr (cdr form)) (delq 0 (nthcdr 3 form))))
741 ;; If form is (- CONST foo... CONST), merge first and last.
742 ((and (numberp (nth 1 form))
743 (numberp last))
744 (setq form (nconc (list '- (- (nth 1 form) last) (nth 2 form))
745 (delq last (copy-sequence (nthcdr 3 form))))))))
746
747 (case (length (cdr form))
748 ((0) ; (-)
749 (condition-case ()
750 (eval form)
751 (error form)))
752
753 ;; It is not safe to delete the function entirely
754 ;; (actually, it would be safe if we knew the sole arg
755 ;; is not a marker).
756 ;; ((1)
757 ;; (nth 1 form)
758
759 ((2) ; (+ x y)
760 (byte-optimize-predicate
761 (cond
762 ;; `add1' and `sub1' are a marginally fewer instructions than `plus'
763 ;; and `minus', so use them when possible.
764 ((eq (nth 2 form) 1) `(1- ,(nth 1 form))) ; (- x 1) --> (1- x)
765 ((eq (nth 2 form) -1) `(1+ ,(nth 1 form))) ; (- x -1) --> (1+ x)
766 ((eq (nth 1 form) 0) `(- ,(nth 2 form))) ; (- 0 x) --> (- x)
767 (t form))))
768
769 (t (byte-optimize-predicate form))))
770 711
771 (defun byte-optimize-multiply (form) 712 (defun byte-optimize-multiply (form)
772 (setq form (byte-optimize-delay-constants-math form 1 '*)) 713 (setq form (byte-optimize-delay-constants-math form 1 '*))
773 ;; If there is a constant integer in FORM, it is now the last element. 714 ;; If there is a constant integer in FORM, it is now the last element.
774 (cond ((null (cdr form)) 1) 715
775 ;;; It is not safe to delete the function entirely 716 (case (car (last form))
776 ;;; (actually, it would be safe if we know the sole arg 717 ;; (* x y 0) --> (progn x y 0)
777 ;;; is not a marker or if it appears in other arithmetic). 718 (0 (cons 'progn (cdr form)))
778 ;;; ((null (cdr (cdr form))) (nth 1 form)) 719 (t (byte-optimize-predicate form))))
779 ((let ((last (last form))) 720
780 (byte-optimize-predicate 721 (defun byte-optimize-minus (form)
781 (cond ((eq 0 last) (cons 'progn (cdr form))) 722 ;; Put constants at the end, except the first arg.
782 ((eq 1 last) (delq 1 (copy-sequence form))) 723 (setq form (byte-optimize-delay-constants-math form 2 '+))
783 ((eq -1 last) (list '- (delq -1 (copy-sequence form)))) 724 ;; Now only the first and last args can be integers.
784 ((and (eq 2 last) 725 (let ((last (car (last (nthcdr 3 form)))))
785 (memq t (mapcar 'symbolp (cdr form)))) 726 (cond
786 (prog1 (setq form (delq 2 (copy-sequence form))) 727 ;; If form is (- CONST foo... CONST), merge first and last.
787 (while (not (symbolp (car (setq form (cdr form)))))) 728 ((and (numberp (nth 1 form)) (numberp last))
788 (setcar form (list '+ (car form) (car form))))) 729 (decf (nth 1 form) last)
789 (form))))))) 730 (butlast form))
731
732 ;; (- 0 x ...) --> (- (- x) ...)
733 ((and (eq 0 (nth 1 form)) (>= (length form) 3))
734 `(- (- ,(nth 2 form)) ,@(nthcdr 3 form)))
735
736 (t (byte-optimize-predicate form)))))
790 737
791 (defun byte-optimize-divide (form) 738 (defun byte-optimize-divide (form)
739 ;; Put constants at the end, except the first arg.
792 (setq form (byte-optimize-delay-constants-math form 2 '*)) 740 (setq form (byte-optimize-delay-constants-math form 2 '*))
793 ;; If there is a constant integer in FORM, it is now the last element. 741 ;; Now only the first and last args can be integers.
794 (let ((last (last (cdr (cdr form))))) 742 (let ((last (car (last (nthcdr 3 form)))))
795 (if (numberp last)
796 (cond ((= (length form) 3)
797 (if (and (numberp (nth 1 form))
798 (not (zerop last))
799 (condition-case nil
800 (/ (nth 1 form) last)
801 (error nil)))
802 (setq form (list 'progn (/ (nth 1 form) last)))))
803 ((= last 1)
804 (setq form (butlast form)))
805 ((numberp (nth 1 form))
806 (setq form (cons (car form)
807 (cons (/ (nth 1 form) last)
808 (butlast (cdr (cdr form)))))
809 last nil))))
810 (cond 743 (cond
811 ;;; ((null (cdr (cdr form))) 744 ;; If form is (/ CONST foo... CONST), merge first and last.
812 ;;; (nth 1 form)) 745 ((and (numberp (nth 1 form)) (numberp last))
746 (condition-case nil
747 (cons (nth 0 form)
748 (cons (/ (nth 1 form) last)
749 (butlast (cdr (cdr form)))))
750 (error form)))
751
752 ;; (/ 0 x y) --> (progn x y 0)
813 ((eq (nth 1 form) 0) 753 ((eq (nth 1 form) 0)
814 (append '(progn) (cdr (cdr form)) '(0))) 754 (append '(progn) (cdr (cdr form)) '(0)))
815 ((eq last -1) 755
816 (list '- (if (nthcdr 3 form) 756 ;; We don't have to check for divide-by-zero because `/' does.
817 (butlast form) 757 (t (byte-optimize-predicate form)))))
818 (nth 1 form))))
819 (form))))
820 758
821 (defun byte-optimize-logmumble (form) 759 (defun byte-optimize-logmumble (form)
822 (setq form (byte-optimize-delay-constants-math form 1 (car form))) 760 (setq form (byte-optimize-delay-constants-math form 1 (car form)))
823 (byte-optimize-predicate 761 (byte-optimize-predicate
824 (cond ((memq 0 form) 762 (cond ((memq 0 form)
846 (rest (cdr form))) 784 (rest (cdr form)))
847 (while (and rest ok) 785 (while (and rest ok)
848 (setq ok (byte-compile-constp (car rest)) 786 (setq ok (byte-compile-constp (car rest))
849 rest (cdr rest))) 787 rest (cdr rest)))
850 (if ok 788 (if ok
851 (condition-case () 789 (condition-case err
852 (list 'quote (eval form)) 790 (list 'quote (eval form))
853 (error form)) 791 (error
792 (byte-compile-warn "evaluating %s: %s" form err)
793 form))
854 form))) 794 form)))
855 795
856 (defun byte-optimize-identity (form) 796 (defun byte-optimize-identity (form)
857 (if (and (cdr form) (null (cdr (cdr form)))) 797 (if (and (cdr form) (null (cdr (cdr form))))
858 (nth 1 form) 798 (nth 1 form)
903 843
904 (put '+ 'byte-optimizer 'byte-optimize-plus) 844 (put '+ 'byte-optimizer 'byte-optimize-plus)
905 (put '* 'byte-optimizer 'byte-optimize-multiply) 845 (put '* 'byte-optimizer 'byte-optimize-multiply)
906 (put '- 'byte-optimizer 'byte-optimize-minus) 846 (put '- 'byte-optimizer 'byte-optimize-minus)
907 (put '/ 'byte-optimizer 'byte-optimize-divide) 847 (put '/ 'byte-optimizer 'byte-optimize-divide)
848 (put '% 'byte-optimizer 'byte-optimize-predicate)
908 (put 'max 'byte-optimizer 'byte-optimize-associative-math) 849 (put 'max 'byte-optimizer 'byte-optimize-associative-math)
909 (put 'min 'byte-optimizer 'byte-optimize-associative-math) 850 (put 'min 'byte-optimizer 'byte-optimize-associative-math)
910 851
911 (put '= 'byte-optimizer 'byte-optimize-binary-predicate) 852 (put '= 'byte-optimizer 'byte-optimize-binary-predicate)
912 (put 'eq 'byte-optimizer 'byte-optimize-binary-predicate) 853 (put 'eq 'byte-optimizer 'byte-optimize-binary-predicate)
1072 (put 'or 'byte-optimizer 'byte-optimize-or) 1013 (put 'or 'byte-optimizer 'byte-optimize-or)
1073 (put 'cond 'byte-optimizer 'byte-optimize-cond) 1014 (put 'cond 'byte-optimizer 'byte-optimize-cond)
1074 (put 'if 'byte-optimizer 'byte-optimize-if) 1015 (put 'if 'byte-optimizer 'byte-optimize-if)
1075 (put 'while 'byte-optimizer 'byte-optimize-while) 1016 (put 'while 'byte-optimizer 'byte-optimize-while)
1076 1017
1077 ;; Remove any reason for avoiding `char-before'. 1018 ;; The supply of bytecodes is small and constrained by backward compatibility.
1019 ;; Several functions have byte-coded versions and hence are very efficient.
1020 ;; Related functions which can be expressed in terms of the byte-coded
1021 ;; ones should be transformed into bytecoded calls for efficiency.
1022 ;; This is especially the case for functions with a backward- and
1023 ;; forward- version, but with a bytecode only for the forward one.
1024
1025 ;; Some programmers have hand-optimized calls like (backward-char)
1026 ;; into the call (forward-char -1).
1027 ;; But it's so much nicer for the byte-compiler to do this automatically!
1028
1029 ;; (char-before) ==> (char-after (1- (point)))
1030 (put 'char-before 'byte-optimizer 'byte-optimize-char-before)
1078 (defun byte-optimize-char-before (form) 1031 (defun byte-optimize-char-before (form)
1079 `(char-after (1- ,(or (nth 1 form) '(point))) ,@(cdr (cdr form)))) 1032 `(char-after
1080 1033 ,(cond
1081 (put 'char-before 'byte-optimizer 'byte-optimize-char-before) 1034 ((null (nth 1 form))
1035 '(1- (point)))
1036 ((equal '(point) (nth 1 form))
1037 '(1- (point)))
1038 (t `(1- (or ,(nth 1 form) (point)))))
1039 ,@(cdr (cdr form))))
1040
1041 ;; (backward-char n) ==> (forward-char (- n))
1042 (put 'backward-char 'byte-optimizer 'byte-optimize-backward-char)
1043 (defun byte-optimize-backward-char (form)
1044 `(forward-char
1045 ,(typecase (nth 1 form)
1046 (null -1)
1047 (integer (- (nth 1 form)))
1048 (t `(- (or ,(nth 1 form) 1))))
1049 ,@(cdr (cdr form))))
1050
1051 ;; (backward-word n) ==> (forward-word (- n))
1052 (put 'backward-word 'byte-optimizer 'byte-optimize-backward-word)
1053 (defun byte-optimize-backward-word (form)
1054 `(forward-word
1055 ,(typecase (nth 1 form)
1056 (null -1)
1057 (integer (- (nth 1 form)))
1058 (t `(- (or ,(nth 1 form) 1))))
1059 ,@(cdr (cdr form))))
1060
1061 ;; The following would be a valid optimization of the above kind, but
1062 ;; the gain in performance is very small, since the saved funcall is
1063 ;; counterbalanced by the necessity of adding a bytecode for (point).
1064 ;;
1065 ;; Also, users are more likely to have modified the behavior of
1066 ;; delete-char via advice or some similar mechanism. This is much
1067 ;; less of a problem for the previous functions because it wouldn't
1068 ;; make sense to modify the behaviour of `backward-char' without also
1069 ;; modifying `forward-char', for example.
1070
1071 ;; (delete-char n) ==> (delete-region (point) (+ (point) n))
1072 ;; (put 'delete-char 'byte-optimizer 'byte-optimize-delete-char)
1073 ;; (defun byte-optimize-delete-char (form)
1074 ;; (case (length (cdr form))
1075 ;; (0 `(delete-region (point) (1+ (point))))
1076 ;; (1 `(delete-region (point) (+ (point) ,(nth 1 form))))
1077 ;; (t form)))
1082 1078
1083 ;; byte-compile-negation-optimizer lives in bytecomp.el 1079 ;; byte-compile-negation-optimizer lives in bytecomp.el
1084 ;(put '/= 'byte-optimizer 'byte-compile-negation-optimizer) 1080 ;(put '/= 'byte-optimizer 'byte-compile-negation-optimizer)
1085 (put 'atom 'byte-optimizer 'byte-compile-negation-optimizer) 1081 (put 'atom 'byte-optimizer 'byte-compile-negation-optimizer)
1086 (put 'nlistp 'byte-optimizer 'byte-compile-negation-optimizer) 1082 (put 'nlistp 'byte-optimizer 'byte-compile-negation-optimizer)
1087
1088 1083
1089 (defun byte-optimize-funcall (form) 1084 (defun byte-optimize-funcall (form)
1090 ;; (funcall '(lambda ...) ...) ==> ((lambda ...) ...) 1085 ;; (funcall '(lambda ...) ...) ==> ((lambda ...) ...)
1091 ;; (funcall 'foo ...) ==> (foo ...) 1086 ;; (funcall 'foo ...) ==> (foo ...)
1092 (let ((fn (nth 1 form))) 1087 (let ((fn (nth 1 form)))
1253 (put fn 'side-effect-free 'error-free))) 1248 (put fn 'side-effect-free 'error-free)))
1254 1249
1255 1250
1256 (defun byte-compile-splice-in-already-compiled-code (form) 1251 (defun byte-compile-splice-in-already-compiled-code (form)
1257 ;; form is (byte-code "..." [...] n) 1252 ;; form is (byte-code "..." [...] n)
1258 (if (not (memq byte-optimize '(t lap))) 1253 (if (not (memq byte-optimize '(t byte)))
1259 (byte-compile-normal-call form) 1254 (byte-compile-normal-call form)
1260 (byte-inline-lapcode 1255 (byte-inline-lapcode
1261 (byte-decompile-bytecode-1 (nth 1 form) (nth 2 form) t)) 1256 (byte-decompile-bytecode-1 (nth 1 form) (nth 2 form) t))
1262 (setq byte-compile-maxdepth (max (+ byte-compile-depth (nth 3 form)) 1257 (setq byte-compile-maxdepth (max (+ byte-compile-depth (nth 3 form))
1263 byte-compile-maxdepth)) 1258 byte-compile-maxdepth))