aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2004-03-22 15:21:08 +0000
committerStefan Monnier2004-03-22 15:21:08 +0000
commite856a453a1c1ce1907b3b582841bce3e9cff8cec (patch)
tree2ca95a77f03942d7a05cfeeed20bfe1c152ba279
parent1de9630d9ba42a033a42a2466924ea98d9ba75b4 (diff)
downloademacs-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.el245
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.
1124This assumes that the function will not have any side-effects and that
1125its return value depends solely on its arguments.
1126If the function can signal an error, this might change the semantics
1127of 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.
1502If 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