Mercurial > emacs
comparison lisp/emacs-lisp/byte-opt.el @ 86056:e0931ee6cc83
* emacs-lisp/byte-opt.el (byte-compile-trueconstp): Handle more
constant forms.
(byte-compile-nilconstp): New function.
(byte-optimize-cond): Kill subsequent branches when a branch is
know to be taken or not taken.
(byte-optimize-if): Use byte-compile-nilconstp instead of hand
coding.
author | Dan Nicolaescu <dann@ics.uci.edu> |
---|---|
date | Tue, 13 Nov 2007 16:10:14 +0000 |
parents | e33327200372 |
children | bd6f75b64f62 |
comparison
equal
deleted
inserted
replaced
86055:f064a093bf93 | 86056:e0931ee6cc83 |
---|---|
183 | 183 |
184 | 184 |
185 ;;; Code: | 185 ;;; Code: |
186 | 186 |
187 (require 'bytecomp) | 187 (require 'bytecomp) |
188 (eval-when-compile (require 'cl)) | |
188 | 189 |
189 (defun byte-compile-log-lap-1 (format &rest args) | 190 (defun byte-compile-log-lap-1 (format &rest args) |
190 (if (aref byte-code-vector 0) | 191 (if (aref byte-code-vector 0) |
191 (error "The old version of the disassembler is loaded. Reload new-bytecomp as well")) | 192 (error "The old version of the disassembler is loaded. Reload new-bytecomp as well")) |
192 (byte-compile-log-1 | 193 (byte-compile-log-1 |
624 ;; you must return something not EQ to it if you make an optimization. | 625 ;; you must return something not EQ to it if you make an optimization. |
625 ;; | 626 ;; |
626 ;; It is now safe to optimize code such that it introduces new bindings. | 627 ;; It is now safe to optimize code such that it introduces new bindings. |
627 | 628 |
628 ;; I'd like this to be a defsubst, but let's not be self-referential... | 629 ;; I'd like this to be a defsubst, but let's not be self-referential... |
629 (defmacro byte-compile-trueconstp (form) | 630 (defsubst byte-compile-trueconstp (form) |
630 ;; Returns non-nil if FORM is a non-nil constant. | 631 "Return non-nil if FORM always evaluates to a non-nil value." |
631 `(cond ((consp ,form) (eq (car ,form) 'quote)) | 632 (cond ((consp form) |
632 ((not (symbolp ,form))) | 633 (case (car form) |
633 ((eq ,form t)) | 634 (quote (cadr form)) |
634 ((keywordp ,form)))) | 635 (progn (byte-compile-trueconstp (car (last (cdr form))))))) |
636 ((not (symbolp form))) | |
637 ((eq form t)) | |
638 ((keywordp form)))) | |
639 | |
640 (defsubst byte-compile-nilconstp (form) | |
641 "Return non-nil if FORM always evaluates to a nil value." | |
642 (cond ((consp form) | |
643 (case (car form) | |
644 (quote (null (cadr form))) | |
645 (progn (byte-compile-nilconstp (car (last (cdr form))))))) | |
646 ((not (symbolp form)) nil) | |
647 ((null form)))) | |
635 | 648 |
636 ;; If the function is being called with constant numeric args, | 649 ;; If the function is being called with constant numeric args, |
637 ;; evaluate as much as possible at compile-time. This optimizer | 650 ;; evaluate as much as possible at compile-time. This optimizer |
638 ;; assumes that the function is associative, like + or *. | 651 ;; assumes that the function is associative, like + or *. |
639 (defun byte-optimize-associative-math (form) | 652 (defun byte-optimize-associative-math (form) |
988 (if (memq nil (cdr form)) | 1001 (if (memq nil (cdr form)) |
989 (setq form (delq nil (copy-sequence form)))) | 1002 (setq form (delq nil (copy-sequence form)))) |
990 (setq rest form) | 1003 (setq rest form) |
991 (while (setq rest (cdr rest)) | 1004 (while (setq rest (cdr rest)) |
992 (cond ((byte-compile-trueconstp (car-safe (car rest))) | 1005 (cond ((byte-compile-trueconstp (car-safe (car rest))) |
993 (cond ((eq rest (cdr form)) | 1006 ;; This branch will always be taken: kill the subsequent ones. |
994 (setq form | 1007 (cond ((eq rest (cdr form)) ;First branch of `cond'. |
995 (if (cdr (car rest)) | 1008 (setq form `(progn ,@(car rest)))) |
996 (if (cdr (cdr (car rest))) | |
997 (cons 'progn (cdr (car rest))) | |
998 (nth 1 (car rest))) | |
999 (car (car rest))))) | |
1000 ((cdr rest) | 1009 ((cdr rest) |
1001 (setq form (copy-sequence form)) | 1010 (setq form (copy-sequence form)) |
1002 (setcdr (memq (car rest) form) nil))) | 1011 (setcdr (memq (car rest) form) nil))) |
1003 (setq rest nil))))) | 1012 (setq rest nil)) |
1013 ((and (consp (car rest)) | |
1014 (byte-compile-nilconstp (caar rest))) | |
1015 ;; This branch will never be taken: kill its body. | |
1016 (setcdr (car rest) nil))))) | |
1004 ;; | 1017 ;; |
1005 ;; Turn (cond (( <x> )) ... ) into (or <x> (cond ... )) | 1018 ;; Turn (cond (( <x> )) ... ) into (or <x> (cond ... )) |
1006 (if (eq 'cond (car-safe form)) | 1019 (if (eq 'cond (car-safe form)) |
1007 (let ((clauses (cdr form))) | 1020 (let ((clauses (cdr form))) |
1008 (if (and (consp (car clauses)) | 1021 (if (and (consp (car clauses)) |
1029 (nconc (butlast clause) | 1042 (nconc (butlast clause) |
1030 (list | 1043 (list |
1031 (byte-optimize-if | 1044 (byte-optimize-if |
1032 `(if ,(car (last clause)) ,@(nthcdr 2 form))))))) | 1045 `(if ,(car (last clause)) ,@(nthcdr 2 form))))))) |
1033 ((byte-compile-trueconstp clause) | 1046 ((byte-compile-trueconstp clause) |
1034 (nth 2 form)) | 1047 `(progn ,clause ,(nth 2 form))) |
1035 ((null clause) | 1048 ((byte-compile-nilconstp clause) |
1036 (if (nthcdr 4 form) | 1049 `(progn ,clause ,@(nthcdr 3 form))) |
1037 (cons 'progn (nthcdr 3 form)) | |
1038 (nth 3 form))) | |
1039 ((nth 2 form) | 1050 ((nth 2 form) |
1040 (if (equal '(nil) (nthcdr 3 form)) | 1051 (if (equal '(nil) (nthcdr 3 form)) |
1041 (list 'if clause (nth 2 form)) | 1052 (list 'if clause (nth 2 form)) |
1042 form)) | 1053 form)) |
1043 ((or (nth 3 form) (nthcdr 4 form)) | 1054 ((or (nth 3 form) (nthcdr 4 form)) |