diff options
| author | Stefan Monnier | 2004-03-22 15:21:08 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2004-03-22 15:21:08 +0000 |
| commit | e856a453a1c1ce1907b3b582841bce3e9cff8cec (patch) | |
| tree | 2ca95a77f03942d7a05cfeeed20bfe1c152ba279 | |
| parent | 1de9630d9ba42a033a42a2466924ea98d9ba75b4 (diff) | |
| download | emacs-e856a453a1c1ce1907b3b582841bce3e9cff8cec.tar.gz emacs-e856a453a1c1ce1907b3b582841bce3e9cff8cec.zip | |
(byte-compile-log-lap, byte-compile-inline-expand): Use backquote.
(byte-optimize-pure-func): Rename from byte-optimize-concat.
(symbol-name, regexp-opt, regexp-quote): Mark as pure.
| -rw-r--r-- | lisp/emacs-lisp/byte-opt.el | 245 |
1 files changed, 126 insertions, 119 deletions
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index a07eb64d737..da8e7583438 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | ;;; byte-opt.el --- the optimization passes of the emacs-lisp byte compiler | 1 | ;;; byte-opt.el --- the optimization passes of the emacs-lisp byte compiler |
| 2 | 2 | ||
| 3 | ;;; Copyright (c) 1991, 1994, 2000, 2001, 2002 Free Software Foundation, Inc. | 3 | ;; Copyright (c) 1991,1994,2000,01,02,2004 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Jamie Zawinski <jwz@lucid.com> | 5 | ;; Author: Jamie Zawinski <jwz@lucid.com> |
| 6 | ;; Hallvard Furuseth <hbf@ulrik.uio.no> | 6 | ;; Hallvard Furuseth <hbf@ulrik.uio.no> |
| @@ -148,37 +148,37 @@ | |||
| 148 | 148 | ||
| 149 | ;; Other things to consider: | 149 | ;; Other things to consider: |
| 150 | 150 | ||
| 151 | ;;;;; Associative math should recognize subcalls to identical function: | 151 | ;; ;; Associative math should recognize subcalls to identical function: |
| 152 | ;;;(disassemble (lambda (x) (+ (+ (foo) 1) (+ (bar) 2)))) | 152 | ;; (disassemble (lambda (x) (+ (+ (foo) 1) (+ (bar) 2)))) |
| 153 | ;;;;; This should generate the same as (1+ x) and (1- x) | 153 | ;; ;; This should generate the same as (1+ x) and (1- x) |
| 154 | 154 | ||
| 155 | ;;;(disassemble (lambda (x) (cons (+ x 1) (- x 1)))) | 155 | ;; (disassemble (lambda (x) (cons (+ x 1) (- x 1)))) |
| 156 | ;;;;; An awful lot of functions always return a non-nil value. If they're | 156 | ;; ;; An awful lot of functions always return a non-nil value. If they're |
| 157 | ;;;;; error free also they may act as true-constants. | 157 | ;; ;; error free also they may act as true-constants. |
| 158 | 158 | ||
| 159 | ;;;(disassemble (lambda (x) (and (point) (foo)))) | 159 | ;; (disassemble (lambda (x) (and (point) (foo)))) |
| 160 | ;;;;; When | 160 | ;; ;; When |
| 161 | ;;;;; - all but one arguments to a function are constant | 161 | ;; ;; - all but one arguments to a function are constant |
| 162 | ;;;;; - the non-constant argument is an if-expression (cond-expression?) | 162 | ;; ;; - the non-constant argument is an if-expression (cond-expression?) |
| 163 | ;;;;; then the outer function can be distributed. If the guarding | 163 | ;; ;; then the outer function can be distributed. If the guarding |
| 164 | ;;;;; condition is side-effect-free [assignment-free] then the other | 164 | ;; ;; condition is side-effect-free [assignment-free] then the other |
| 165 | ;;;;; arguments may be any expressions. Since, however, the code size | 165 | ;; ;; arguments may be any expressions. Since, however, the code size |
| 166 | ;;;;; can increase this way they should be "simple". Compare: | 166 | ;; ;; can increase this way they should be "simple". Compare: |
| 167 | 167 | ||
| 168 | ;;;(disassemble (lambda (x) (eq (if (point) 'a 'b) 'c))) | 168 | ;; (disassemble (lambda (x) (eq (if (point) 'a 'b) 'c))) |
| 169 | ;;;(disassemble (lambda (x) (if (point) (eq 'a 'c) (eq 'b 'c)))) | 169 | ;; (disassemble (lambda (x) (if (point) (eq 'a 'c) (eq 'b 'c)))) |
| 170 | 170 | ||
| 171 | ;;;;; (car (cons A B)) -> (progn B A) | 171 | ;; ;; (car (cons A B)) -> (prog1 A B) |
| 172 | ;;;(disassemble (lambda (x) (car (cons (foo) 42)))) | 172 | ;; (disassemble (lambda (x) (car (cons (foo) 42)))) |
| 173 | 173 | ||
| 174 | ;;;;; (cdr (cons A B)) -> (progn A B) | 174 | ;; ;; (cdr (cons A B)) -> (progn A B) |
| 175 | ;;;(disassemble (lambda (x) (cdr (cons 42 (foo))))) | 175 | ;; (disassemble (lambda (x) (cdr (cons 42 (foo))))) |
| 176 | 176 | ||
| 177 | ;;;;; (car (list A B ...)) -> (progn B ... A) | 177 | ;; ;; (car (list A B ...)) -> (prog1 A B ...) |
| 178 | ;;;(disassemble (lambda (x) (car (list (foo) 42 (bar))))) | 178 | ;; (disassemble (lambda (x) (car (list (foo) 42 (bar))))) |
| 179 | 179 | ||
| 180 | ;;;;; (cdr (list A B ...)) -> (progn A (list B ...)) | 180 | ;; ;; (cdr (list A B ...)) -> (progn A (list B ...)) |
| 181 | ;;;(disassemble (lambda (x) (cdr (list 42 (foo) (bar))))) | 181 | ;; (disassemble (lambda (x) (cdr (list 42 (foo) (bar))))) |
| 182 | 182 | ||
| 183 | 183 | ||
| 184 | ;;; Code: | 184 | ;;; Code: |
| @@ -217,10 +217,8 @@ | |||
| 217 | args))))) | 217 | args))))) |
| 218 | 218 | ||
| 219 | (defmacro byte-compile-log-lap (format-string &rest args) | 219 | (defmacro byte-compile-log-lap (format-string &rest args) |
| 220 | (list 'and | 220 | `(and (memq byte-optimize-log '(t byte)) |
| 221 | '(memq byte-optimize-log '(t byte)) | 221 | (byte-compile-log-lap-1 ,format-string ,@args))) |
| 222 | (cons 'byte-compile-log-lap-1 | ||
| 223 | (cons format-string args)))) | ||
| 224 | 222 | ||
| 225 | 223 | ||
| 226 | ;;; byte-compile optimizers to support inlining | 224 | ;;; byte-compile optimizers to support inlining |
| @@ -274,18 +272,18 @@ | |||
| 274 | (let (string) | 272 | (let (string) |
| 275 | (fetch-bytecode fn) | 273 | (fetch-bytecode fn) |
| 276 | (setq string (aref fn 1)) | 274 | (setq string (aref fn 1)) |
| 275 | ;; Isn't it an error for `string' not to be unibyte?? --stef | ||
| 277 | (if (fboundp 'string-as-unibyte) | 276 | (if (fboundp 'string-as-unibyte) |
| 278 | (setq string (string-as-unibyte string))) | 277 | (setq string (string-as-unibyte string))) |
| 279 | (cons (list 'lambda (aref fn 0) | 278 | (cons `(lambda ,(aref fn 0) |
| 280 | (list 'byte-code string (aref fn 2) (aref fn 3))) | 279 | (byte-code ,string ,(aref fn 2) ,(aref fn 3))) |
| 281 | (cdr form))) | 280 | (cdr form))) |
| 282 | (if (eq (car-safe fn) 'lambda) | 281 | (if (eq (car-safe fn) 'lambda) |
| 283 | (cons fn (cdr form)) | 282 | (cons fn (cdr form)) |
| 284 | ;; Give up on inlining. | 283 | ;; Give up on inlining. |
| 285 | form)))))) | 284 | form)))))) |
| 286 | 285 | ||
| 287 | ;;; ((lambda ...) ...) | 286 | ;; ((lambda ...) ...) |
| 288 | ;;; | ||
| 289 | (defun byte-compile-unfold-lambda (form &optional name) | 287 | (defun byte-compile-unfold-lambda (form &optional name) |
| 290 | (or name (setq name "anonymous lambda")) | 288 | (or name (setq name "anonymous lambda")) |
| 291 | (let ((lambda (car form)) | 289 | (let ((lambda (car form)) |
| @@ -604,14 +602,14 @@ | |||
| 604 | (nreverse result))) | 602 | (nreverse result))) |
| 605 | 603 | ||
| 606 | 604 | ||
| 607 | ;;; some source-level optimizers | 605 | ;; some source-level optimizers |
| 608 | ;;; | 606 | ;; |
| 609 | ;;; when writing optimizers, be VERY careful that the optimizer returns | 607 | ;; when writing optimizers, be VERY careful that the optimizer returns |
| 610 | ;;; something not EQ to its argument if and ONLY if it has made a change. | 608 | ;; something not EQ to its argument if and ONLY if it has made a change. |
| 611 | ;;; This implies that you cannot simply destructively modify the list; | 609 | ;; This implies that you cannot simply destructively modify the list; |
| 612 | ;;; you must return something not EQ to it if you make an optimization. | 610 | ;; you must return something not EQ to it if you make an optimization. |
| 613 | ;;; | 611 | ;; |
| 614 | ;;; It is now safe to optimize code such that it introduces new bindings. | 612 | ;; It is now safe to optimize code such that it introduces new bindings. |
| 615 | 613 | ||
| 616 | ;; I'd like this to be a defsubst, but let's not be self-referential... | 614 | ;; I'd like this to be a defsubst, but let's not be self-referential... |
| 617 | (defmacro byte-compile-trueconstp (form) | 615 | (defmacro byte-compile-trueconstp (form) |
| @@ -721,10 +719,10 @@ | |||
| 721 | (condition-case () | 719 | (condition-case () |
| 722 | (eval form) | 720 | (eval form) |
| 723 | (error form))) | 721 | (error form))) |
| 724 | ;;; It is not safe to delete the function entirely | 722 | ;;; It is not safe to delete the function entirely |
| 725 | ;;; (actually, it would be safe if we know the sole arg | 723 | ;;; (actually, it would be safe if we know the sole arg |
| 726 | ;;; is not a marker). | 724 | ;;; is not a marker). |
| 727 | ;; ((null (cdr (cdr form))) (nth 1 form)) | 725 | ;;; ((null (cdr (cdr form))) (nth 1 form)) |
| 728 | ((null (cddr form)) | 726 | ((null (cddr form)) |
| 729 | (if (numberp (nth 1 form)) | 727 | (if (numberp (nth 1 form)) |
| 730 | (nth 1 form) | 728 | (nth 1 form) |
| @@ -763,9 +761,9 @@ | |||
| 763 | (numberp last)) | 761 | (numberp last)) |
| 764 | (setq form (nconc (list '- (- (nth 1 form) last) (nth 2 form)) | 762 | (setq form (nconc (list '- (- (nth 1 form) last) (nth 2 form)) |
| 765 | (delq last (copy-sequence (nthcdr 3 form)))))))) | 763 | (delq last (copy-sequence (nthcdr 3 form)))))))) |
| 766 | ;;; It is not safe to delete the function entirely | 764 | ;;; It is not safe to delete the function entirely |
| 767 | ;;; (actually, it would be safe if we know the sole arg | 765 | ;;; (actually, it would be safe if we know the sole arg |
| 768 | ;;; is not a marker). | 766 | ;;; is not a marker). |
| 769 | ;;; (if (eq (nth 2 form) 0) | 767 | ;;; (if (eq (nth 2 form) 0) |
| 770 | ;;; (nth 1 form) ; (- x 0) --> x | 768 | ;;; (nth 1 form) ; (- x 0) --> x |
| 771 | (byte-optimize-predicate | 769 | (byte-optimize-predicate |
| @@ -780,9 +778,9 @@ | |||
| 780 | (setq form (byte-optimize-delay-constants-math form 1 '*)) | 778 | (setq form (byte-optimize-delay-constants-math form 1 '*)) |
| 781 | ;; If there is a constant in FORM, it is now the last element. | 779 | ;; If there is a constant in FORM, it is now the last element. |
| 782 | (cond ((null (cdr form)) 1) | 780 | (cond ((null (cdr form)) 1) |
| 783 | ;;; It is not safe to delete the function entirely | 781 | ;;; It is not safe to delete the function entirely |
| 784 | ;;; (actually, it would be safe if we know the sole arg | 782 | ;;; (actually, it would be safe if we know the sole arg |
| 785 | ;;; is not a marker or if it appears in other arithmetic). | 783 | ;;; is not a marker or if it appears in other arithmetic). |
| 786 | ;;; ((null (cdr (cdr form))) (nth 1 form)) | 784 | ;;; ((null (cdr (cdr form))) (nth 1 form)) |
| 787 | ((let ((last (car (reverse form)))) | 785 | ((let ((last (car (reverse form)))) |
| 788 | (cond ((eq 0 last) (cons 'progn (cdr form))) | 786 | (cond ((eq 0 last) (cons 'progn (cdr form))) |
| @@ -1117,8 +1115,16 @@ | |||
| 1117 | (byte-optimize-predicate form)) | 1115 | (byte-optimize-predicate form)) |
| 1118 | form)) | 1116 | form)) |
| 1119 | 1117 | ||
| 1120 | (put 'concat 'byte-optimizer 'byte-optimize-concat) | 1118 | (put 'concat 'byte-optimizer 'byte-optimize-pure-func) |
| 1121 | (defun byte-optimize-concat (form) | 1119 | (put 'symbol-name 'byte-optimizer 'byte-optimize-pure-func) |
| 1120 | (put 'regexp-opt 'byte-optimizer 'byte-optimize-pure-func) | ||
| 1121 | (put 'regexp-quote 'byte-optimizer 'byte-optimize-pure-func) | ||
| 1122 | (defun byte-optimize-pure-func (form) | ||
| 1123 | "Do constant folding for pure functions. | ||
| 1124 | This assumes that the function will not have any side-effects and that | ||
| 1125 | its return value depends solely on its arguments. | ||
| 1126 | If the function can signal an error, this might change the semantics | ||
| 1127 | of FORM by signalling the error at compile-time." | ||
| 1122 | (let ((args (cdr form)) | 1128 | (let ((args (cdr form)) |
| 1123 | (constant t)) | 1129 | (constant t)) |
| 1124 | (while (and args constant) | 1130 | (while (and args constant) |
| @@ -1181,28 +1187,28 @@ | |||
| 1181 | `(progn ,(cadr form) (setq ,(cadr var) ,@(cddr form)))) | 1187 | `(progn ,(cadr form) (setq ,(cadr var) ,@(cddr form)))) |
| 1182 | (t form)))) | 1188 | (t form)))) |
| 1183 | 1189 | ||
| 1184 | ;;; enumerating those functions which need not be called if the returned | 1190 | ;; enumerating those functions which need not be called if the returned |
| 1185 | ;;; value is not used. That is, something like | 1191 | ;; value is not used. That is, something like |
| 1186 | ;;; (progn (list (something-with-side-effects) (yow)) | 1192 | ;; (progn (list (something-with-side-effects) (yow)) |
| 1187 | ;;; (foo)) | 1193 | ;; (foo)) |
| 1188 | ;;; may safely be turned into | 1194 | ;; may safely be turned into |
| 1189 | ;;; (progn (progn (something-with-side-effects) (yow)) | 1195 | ;; (progn (progn (something-with-side-effects) (yow)) |
| 1190 | ;;; (foo)) | 1196 | ;; (foo)) |
| 1191 | ;;; Further optimizations will turn (progn (list 1 2 3) 'foo) into 'foo. | 1197 | ;; Further optimizations will turn (progn (list 1 2 3) 'foo) into 'foo. |
| 1192 | 1198 | ||
| 1193 | ;;; Some of these functions have the side effect of allocating memory | 1199 | ;; Some of these functions have the side effect of allocating memory |
| 1194 | ;;; and it would be incorrect to replace two calls with one. | 1200 | ;; and it would be incorrect to replace two calls with one. |
| 1195 | ;;; But we don't try to do those kinds of optimizations, | 1201 | ;; But we don't try to do those kinds of optimizations, |
| 1196 | ;;; so it is safe to list such functions here. | 1202 | ;; so it is safe to list such functions here. |
| 1197 | ;;; Some of these functions return values that depend on environment | 1203 | ;; Some of these functions return values that depend on environment |
| 1198 | ;;; state, so that constant folding them would be wrong, | 1204 | ;; state, so that constant folding them would be wrong, |
| 1199 | ;;; but we don't do constant folding based on this list. | 1205 | ;; but we don't do constant folding based on this list. |
| 1200 | 1206 | ||
| 1201 | ;;; However, at present the only optimization we normally do | 1207 | ;; However, at present the only optimization we normally do |
| 1202 | ;;; is delete calls that need not occur, and we only do that | 1208 | ;; is delete calls that need not occur, and we only do that |
| 1203 | ;;; with the error-free functions. | 1209 | ;; with the error-free functions. |
| 1204 | 1210 | ||
| 1205 | ;;; I wonder if I missed any :-\) | 1211 | ;; I wonder if I missed any :-\) |
| 1206 | (let ((side-effect-free-fns | 1212 | (let ((side-effect-free-fns |
| 1207 | '(% * + - / /= 1+ 1- < <= = > >= abs acos append aref ash asin atan | 1213 | '(% * + - / /= 1+ 1- < <= = > >= abs acos append aref ash asin atan |
| 1208 | assoc assq | 1214 | assoc assq |
| @@ -1298,8 +1304,8 @@ | |||
| 1298 | (defconst byte-constref-ops | 1304 | (defconst byte-constref-ops |
| 1299 | '(byte-constant byte-constant2 byte-varref byte-varset byte-varbind)) | 1305 | '(byte-constant byte-constant2 byte-varref byte-varset byte-varbind)) |
| 1300 | 1306 | ||
| 1301 | ;;; This function extracts the bitfields from variable-length opcodes. | 1307 | ;; This function extracts the bitfields from variable-length opcodes. |
| 1302 | ;;; Originally defined in disass.el (which no longer uses it.) | 1308 | ;; Originally defined in disass.el (which no longer uses it.) |
| 1303 | 1309 | ||
| 1304 | (defun disassemble-offset () | 1310 | (defun disassemble-offset () |
| 1305 | "Don't call this!" | 1311 | "Don't call this!" |
| @@ -1336,11 +1342,11 @@ | |||
| 1336 | (aref bytes ptr)))) | 1342 | (aref bytes ptr)))) |
| 1337 | 1343 | ||
| 1338 | 1344 | ||
| 1339 | ;;; This de-compiler is used for inline expansion of compiled functions, | 1345 | ;; This de-compiler is used for inline expansion of compiled functions, |
| 1340 | ;;; and by the disassembler. | 1346 | ;; and by the disassembler. |
| 1341 | ;;; | 1347 | ;; |
| 1342 | ;;; This list contains numbers, which are pc values, | 1348 | ;; This list contains numbers, which are pc values, |
| 1343 | ;;; before each instruction. | 1349 | ;; before each instruction. |
| 1344 | (defun byte-decompile-bytecode (bytes constvec) | 1350 | (defun byte-decompile-bytecode (bytes constvec) |
| 1345 | "Turns BYTECODE into lapcode, referring to CONSTVEC." | 1351 | "Turns BYTECODE into lapcode, referring to CONSTVEC." |
| 1346 | (let ((byte-compile-constants nil) | 1352 | (let ((byte-compile-constants nil) |
| @@ -1461,38 +1467,39 @@ | |||
| 1461 | byte-member byte-assq byte-quo byte-rem) | 1467 | byte-member byte-assq byte-quo byte-rem) |
| 1462 | byte-compile-side-effect-and-error-free-ops)) | 1468 | byte-compile-side-effect-and-error-free-ops)) |
| 1463 | 1469 | ||
| 1464 | ;;; This crock is because of the way DEFVAR_BOOL variables work. | 1470 | ;; This crock is because of the way DEFVAR_BOOL variables work. |
| 1465 | ;;; Consider the code | 1471 | ;; Consider the code |
| 1466 | ;;; | 1472 | ;; |
| 1467 | ;;; (defun foo (flag) | 1473 | ;; (defun foo (flag) |
| 1468 | ;;; (let ((old-pop-ups pop-up-windows) | 1474 | ;; (let ((old-pop-ups pop-up-windows) |
| 1469 | ;;; (pop-up-windows flag)) | 1475 | ;; (pop-up-windows flag)) |
| 1470 | ;;; (cond ((not (eq pop-up-windows old-pop-ups)) | 1476 | ;; (cond ((not (eq pop-up-windows old-pop-ups)) |
| 1471 | ;;; (setq old-pop-ups pop-up-windows) | 1477 | ;; (setq old-pop-ups pop-up-windows) |
| 1472 | ;;; ...)))) | 1478 | ;; ...)))) |
| 1473 | ;;; | 1479 | ;; |
| 1474 | ;;; Uncompiled, old-pop-ups will always be set to nil or t, even if FLAG is | 1480 | ;; Uncompiled, old-pop-ups will always be set to nil or t, even if FLAG is |
| 1475 | ;;; something else. But if we optimize | 1481 | ;; something else. But if we optimize |
| 1476 | ;;; | 1482 | ;; |
| 1477 | ;;; varref flag | 1483 | ;; varref flag |
| 1478 | ;;; varbind pop-up-windows | 1484 | ;; varbind pop-up-windows |
| 1479 | ;;; varref pop-up-windows | 1485 | ;; varref pop-up-windows |
| 1480 | ;;; not | 1486 | ;; not |
| 1481 | ;;; to | 1487 | ;; to |
| 1482 | ;;; varref flag | 1488 | ;; varref flag |
| 1483 | ;;; dup | 1489 | ;; dup |
| 1484 | ;;; varbind pop-up-windows | 1490 | ;; varbind pop-up-windows |
| 1485 | ;;; not | 1491 | ;; not |
| 1486 | ;;; | 1492 | ;; |
| 1487 | ;;; we break the program, because it will appear that pop-up-windows and | 1493 | ;; we break the program, because it will appear that pop-up-windows and |
| 1488 | ;;; old-pop-ups are not EQ when really they are. So we have to know what | 1494 | ;; old-pop-ups are not EQ when really they are. So we have to know what |
| 1489 | ;;; the BOOL variables are, and not perform this optimization on them. | 1495 | ;; the BOOL variables are, and not perform this optimization on them. |
| 1490 | 1496 | ||
| 1491 | ;;; The variable `byte-boolean-vars' is now primitive and updated | 1497 | ;; The variable `byte-boolean-vars' is now primitive and updated |
| 1492 | ;;; automatically by DEFVAR_BOOL. | 1498 | ;; automatically by DEFVAR_BOOL. |
| 1493 | 1499 | ||
| 1494 | (defun byte-optimize-lapcode (lap &optional for-effect) | 1500 | (defun byte-optimize-lapcode (lap &optional for-effect) |
| 1495 | "Simple peephole optimizer. LAP is both modified and returned." | 1501 | "Simple peephole optimizer. LAP is both modified and returned. |
| 1502 | If FOR-EFFECT is non-nil, the return value is assumed to be of no importance." | ||
| 1496 | (let (lap0 | 1503 | (let (lap0 |
| 1497 | lap1 | 1504 | lap1 |
| 1498 | lap2 | 1505 | lap2 |