annotate lisp/byte-optimize.el @ 826:6728e641994e

[xemacs-hg @ 2002-05-05 11:30:15 by ben] syntax cache, 8-bit-format, lots of code cleanup README.packages: Update info about --package-path. i.c: Create an inheritable event and pass it on to XEmacs, so that ^C can be handled properly. Intercept ^C and signal the event. "Stop Build" in VC++ now works. bytecomp-runtime.el: Doc string changes. compat.el: Some attempts to redo this to make it truly useful and fix the "multiple versions interacting with each other" problem. Not yet done. Currently doesn't work. files.el: Use with-obsolete-variable to avoid warnings in new revert-buffer code. xemacs.mak: Split up CFLAGS into a version without flags specifying the C library. The problem seems to be that minitar depends on zlib, which depends specifically on libc.lib, not on any of the other C libraries. Unless you compile with libc.lib, you get errors -- specifically, no _errno in the other libraries, which must make it something other than an int. (#### But this doesn't seem to obtain in XEmacs, which also uses zlib, and can be linked with any of the C libraries. Maybe zlib is used differently and doesn't need errno, or maybe XEmacs provides an int errno; ... I don't understand. Makefile.in.in: Fix so that packages are around when testing. abbrev.c, alloc.c, buffer.c, buffer.h, bytecode.c, callint.c, casefiddle.c, casetab.c, casetab.h, charset.h, chartab.c, chartab.h, cmds.c, console-msw.h, console-stream.c, console-x.c, console.c, console.h, data.c, device-msw.c, device.c, device.h, dialog-msw.c, dialog-x.c, dired-msw.c, dired.c, doc.c, doprnt.c, dumper.c, editfns.c, elhash.c, emacs.c, eval.c, event-Xt.c, event-gtk.c, event-msw.c, event-stream.c, events.c, events.h, extents.c, extents.h, faces.c, file-coding.c, file-coding.h, fileio.c, fns.c, font-lock.c, frame-gtk.c, frame-msw.c, frame-x.c, frame.c, frame.h, glade.c, glyphs-gtk.c, glyphs-msw.c, glyphs-msw.h, glyphs-x.c, glyphs.c, glyphs.h, gui-msw.c, gui-x.c, gui.h, gutter.h, hash.h, indent.c, insdel.c, intl-win32.c, intl.c, keymap.c, lisp-disunion.h, lisp-union.h, lisp.h, lread.c, lrecord.h, lstream.c, lstream.h, marker.c, menubar-gtk.c, menubar-msw.c, menubar-x.c, menubar.c, minibuf.c, mule-ccl.c, mule-charset.c, mule-coding.c, mule-wnnfns.c, nas.c, objects-msw.c, objects-x.c, opaque.c, postgresql.c, print.c, process-nt.c, process-unix.c, process.c, process.h, profile.c, rangetab.c, redisplay-gtk.c, redisplay-msw.c, redisplay-output.c, redisplay-x.c, redisplay.c, redisplay.h, regex.c, regex.h, scrollbar-msw.c, search.c, select-x.c, specifier.c, specifier.h, symbols.c, symsinit.h, syntax.c, syntax.h, syswindows.h, tests.c, text.c, text.h, tooltalk.c, ui-byhand.c, ui-gtk.c, unicode.c, win32.c, window.c: Another big Ben patch. -- FUNCTIONALITY CHANGES: add partial support for 8-bit-fixed, 16-bit-fixed, and 32-bit-fixed formats. not quite done yet. (in particular, needs functions to actually convert the buffer.) NOTE: lots of changes to regex.c here. also, many new *_fmt() inline funs that take an Internal_Format argument. redo syntax cache code. make the cache per-buffer; keep the cache valid across calls to functions that use it. also keep it valid across insertions/deletions and extent changes, as much as is possible. eliminate the junky regex-reentrancy code by passing in the relevant lisp info to the regex routines as local vars. add general mechanism in extents code for signalling extent changes. fix numerous problems with the case-table implementation; yoshiki never properly transferred many algorithms from old-style to new-style case tables. redo char tables to support a default argument, so that mapping only occurs over changed args. change many chartab functions to accept Lisp_Object instead of Lisp_Char_Table *. comment out the code in font-lock.c by default, because font-lock.el no longer uses it. we should consider eliminating it entirely. Don't output bell as ^G in console-stream when not a TTY. add -mswindows-termination-handle to interface with i.c, so we can properly kill a build. add more error-checking to buffer/string macros. add some additional buffer_or_string_() funs. -- INTERFACE CHANGES AFFECTING MORE CODE: switch the arguments of write_c_string and friends to be consistent with write_fmt_string, which must have printcharfun first. change BI_* macros to BYTE_* for increased clarity; similarly for bi_* local vars. change VOID_TO_LISP to be a one-argument function. eliminate no-longer-needed CVOID_TO_LISP. -- char/string macro changes: rename MAKE_CHAR() to make_emchar() for slightly less confusion with make_char(). (The former generates an Emchar, the latter a Lisp object. Conceivably we should rename make_char() -> wrap_char() and similarly for make_int(), make_float().) Similar changes for other *CHAR* macros -- we now consistently use names with `emchar' whenever we are working with Emchars. Any remaining name with just `char' always refers to a Lisp object. rename macros with XSTRING_* to string_* except for those that reference actual fields in the Lisp_String object, following conventions used elsewhere. rename set_string_{data,length} macros (the only ones to work with a Lisp_String_* instead of a Lisp_Object) to set_lispstringp_* to make the difference clear. try to be consistent about caps vs. lowercase in macro/inline-fun names for chars and such, which wasn't the case before. we now reserve caps either for XFOO_ macros that reference object fields (e.g. XSTRING_DATA) or for things that have non-function semantics, e.g. directly modifying an arg (BREAKUP_EMCHAR) or evaluating an arg (any arg) more than once. otherwise, use lowercase. here is a summary of most of the macros/inline funs changed by all of the above changes: BYTE_*_P -> byte_*_p XSTRING_BYTE -> string_byte set_string_data/length -> set_lispstringp_data/length XSTRING_CHAR_LENGTH -> string_char_length XSTRING_CHAR -> string_emchar INTBYTE_FIRST_BYTE_P -> intbyte_first_byte_p INTBYTE_LEADING_BYTE_P -> intbyte_leading_byte_p charptr_copy_char -> charptr_copy_emchar LEADING_BYTE_* -> leading_byte_* CHAR_* -> EMCHAR_* *_CHAR_* -> *_EMCHAR_* *_CHAR -> *_EMCHAR CHARSET_BY_ -> charset_by_* BYTE_SHIFT_JIS* -> byte_shift_jis* BYTE_BIG5* -> byte_big5* REP_BYTES_BY_FIRST_BYTE -> rep_bytes_by_first_byte char_to_unicode -> emchar_to_unicode valid_char_p -> valid_emchar_p Change intbyte_strcmp -> qxestrcmp_c (duplicated functionality). -- INTERFACE CHANGES AFFECTING LESS CODE: use DECLARE_INLINE_HEADER in various places. remove '#ifdef emacs' from XEmacs-only files. eliminate CHAR_TABLE_VALUE(), which duplicated the functionality of get_char_table(). add BUFFER_TEXT_LOOP to simplify iterations over buffer text. define typedefs for signed and unsigned types of fixed sizes (INT_32_BIT, UINT_32_BIT, etc.). create ALIGN_FOR_TYPE as a higher-level interface onto ALIGN_SIZE; fix code to use it. add charptr_emchar_len to return the text length of the character pointed to by a ptr; use it in place of charcount_to_bytecount(..., 1). add emchar_len to return the text length of a given character. add types Bytexpos and Charxpos to generalize Bytebpos/Bytecount and Charbpos/Charcount, in code (particularly, the extents code and redisplay code) that works with either kind of index. rename redisplay struct params with names such as `charbpos' to e.g. `charpos' when they are e.g. a Charxpos, not a Charbpos. eliminate xxDEFUN in place of DEFUN; no longer necessary with changes awhile back to doc.c. split up big ugly combined list of EXFUNs in lisp.h on a file-by-file basis, since other prototypes are similarly split. rewrite some "*_UNSAFE" macros as inline funs and eliminate the _UNSAFE suffix. move most string code from lisp.h to text.h; the string code and text.h code is now intertwined in such a fashion that they need to be in the same place and partially interleaved. (you can't create forward references for inline funs) automated/lisp-tests.el, automated/symbol-tests.el, automated/test-harness.el: Fix test harness to output FAIL messages to stderr when in batch mode. Fix up some problems in lisp-tests/symbol-tests that were causing spurious failures.
author ben
date Sun, 05 May 2002 11:33:57 +0000
parents 1638aacf421d
children 6c21360a544b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 ;;; byte-optimize.el --- the optimization passes of the emacs-lisp byte compiler.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3 ;;; Copyright (c) 1991, 1994 Free Software Foundation, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
5 ;; Authors: Jamie Zawinski <jwz@jwz.org>
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
6 ;; Hallvard Furuseth <hbf@ulrik.uio.no>
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
7 ;; Martin Buchholz <martin@xemacs.org>
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 ;; Keywords: internal
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10 ;; This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12 ;; XEmacs is free software; you can redistribute it and/or modify it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 ;; under the terms of the GNU General Public License as published by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 ;; the Free Software Foundation; either version 2, or (at your option)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 ;; any later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17 ;; XEmacs is distributed in the hope that it will be useful, but
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 ;; General Public License for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22 ;; You should have received a copy of the GNU General Public License
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
23 ;; along with XEmacs; see the file COPYING. If not, write to the
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 ;; Boston, MA 02111-1307, USA.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
27 ;;; Synched up with: FSF 20.7.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29 ;;; Commentary:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31 ;; ========================================================================
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 ;; "No matter how hard you try, you can't make a racehorse out of a pig.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33 ;; You can, however, make a faster pig."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 ;; Or, to put it another way, the emacs byte compiler is a VW Bug. This code
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
36 ;; makes it be a VW Bug with fuel injection and a turbocharger... You're
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 ;; still not going to make it go faster than 70 mph, but it might be easier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38 ;; to get it there.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 ;; TO DO:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 ;; (apply #'(lambda (x &rest y) ...) 1 (foo))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 ;; maintain a list of functions known not to access any global variables
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 ;; (actually, give them a 'dynamically-safe property) and then
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 ;; (let ( v1 v2 ... vM vN ) <...dynamically-safe...> ) ==>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 ;; (let ( v1 v2 ... vM ) vN <...dynamically-safe...> )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 ;; by recursing on this, we might be able to eliminate the entire let.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 ;; However certain variables should never have their bindings optimized
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51 ;; away, because they affect everything.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 ;; (put 'debug-on-error 'binding-is-magic t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53 ;; (put 'debug-on-abort 'binding-is-magic t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 ;; (put 'debug-on-next-call 'binding-is-magic t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55 ;; (put 'mocklisp-arguments 'binding-is-magic t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 ;; (put 'inhibit-quit 'binding-is-magic t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 ;; (put 'quit-flag 'binding-is-magic t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 ;; (put 't 'binding-is-magic t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 ;; (put 'nil 'binding-is-magic t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 ;; possibly also
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 ;; (put 'gc-cons-threshold 'binding-is-magic t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 ;; (put 'track-mouse 'binding-is-magic t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63 ;; others?
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 ;; Simple defsubsts often produce forms like
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 ;; (let ((v1 (f1)) (v2 (f2)) ...)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 ;; (FN v1 v2 ...))
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
68 ;; It would be nice if we could optimize this to
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 ;; (FN (f1) (f2) ...)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 ;; but we can't unless FN is dynamically-safe (it might be dynamically
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71 ;; referring to the bindings that the lambda arglist established.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 ;; One of the uncountable lossages introduced by dynamic scope...
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 ;;
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
74 ;; Maybe there should be a control-structure that says "turn on
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 ;; fast-and-loose type-assumptive optimizations here." Then when
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 ;; we see a form like (car foo) we can from then on assume that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 ;; the variable foo is of type cons, and optimize based on that.
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
78 ;; But, this won't win much because of (you guessed it) dynamic
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79 ;; scope. Anything down the stack could change the value.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 ;; (Another reason it doesn't work is that it is perfectly valid
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 ;; to call car with a null argument.) A better approach might
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 ;; be to allow type-specification of the form
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 ;; (put 'foo 'arg-types '(float (list integer) dynamic))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 ;; (put 'foo 'result-type 'bool)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85 ;; It should be possible to have these types checked to a certain
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 ;; degree.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 ;; collapse common subexpressions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90 ;; It would be nice if redundant sequences could be factored out as well,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 ;; when they are known to have no side-effects:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 ;; (list (+ a b c) (+ a b c)) --> a b add c add dup list-2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 ;; but beware of traps like
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 ;; (cons (list x y) (list x y))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 ;; Tail-recursion elimination is not really possible in Emacs Lisp.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 ;; Tail-recursion elimination is almost always impossible when all variables
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 ;; have dynamic scope, but given that the "return" byteop requires the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 ;; binding stack to be empty (rather than emptying it itself), there can be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 ;; no truly tail-recursive Emacs Lisp functions that take any arguments or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 ;; make any bindings.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 ;; Here is an example of an Emacs Lisp function which could safely be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 ;; byte-compiled tail-recursively:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 ;; (defun tail-map (fn list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107 ;; (cond (list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 ;; (funcall fn (car list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 ;; (tail-map fn (cdr list)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 ;; However, if there was even a single let-binding around the COND,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 ;; it could not be byte-compiled, because there would be an "unbind"
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
113 ;; byte-op between the final "call" and "return." Adding a
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 ;; Bunbind_all byteop would fix this.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 ;; (defun foo (x y z) ... (foo a b c))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 ;; ... (const foo) (varref a) (varref b) (varref c) (call 3) END: (return)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 ;; ... (varref a) (varbind x) (varref b) (varbind y) (varref c) (varbind z) (goto 0) END: (unbind-all) (return)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 ;; ... (varref a) (varset x) (varref b) (varset y) (varref c) (varset z) (goto 0) END: (return)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 ;; this also can be considered tail recursion:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 ;; ... (const foo) (varref a) (call 1) (goto X) ... X: (return)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 ;; could generalize this by doing the optimization
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 ;; (goto X) ... X: (return) --> (return)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 ;; But this doesn't solve all of the problems: although by doing tail-
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 ;; recursion elimination in this way, the call-stack does not grow, the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 ;; binding-stack would grow with each recursive step, and would eventually
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 ;; overflow. I don't believe there is any way around this without lexical
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 ;; scope.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 ;; Wouldn't it be nice if Emacs Lisp had lexical scope.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 ;;
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
135 ;; Idea: the form (lexical-scope) in a file means that the file may be
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
136 ;; compiled lexically. This proclamation is file-local. Then, within
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 ;; that file, "let" would establish lexical bindings, and "let-dynamic"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 ;; would do things the old way. (Or we could use CL "declare" forms.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 ;; We'd have to notice defvars and defconsts, since those variables should
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 ;; always be dynamic, and attempting to do a lexical binding of them
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 ;; should simply do a dynamic binding instead.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 ;; But! We need to know about variables that were not necessarily defvarred
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 ;; in the file being compiled (doing a boundp check isn't good enough.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 ;; Fdefvar() would have to be modified to add something to the plist.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 ;;
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
146 ;; A major disadvantage of this scheme is that the interpreter and compiler
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
147 ;; would have different semantics for files compiled with (dynamic-scope).
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 ;; Since this would be a file-local optimization, there would be no way to
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
149 ;; modify the interpreter to obey this (unless the loader was hacked
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 ;; in some grody way, but that's a really bad idea.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 ;; HA! RMS removed the following paragraph from his version of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 ;; byte-optimize.el.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 ;; Really the Right Thing is to make lexical scope the default across
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
156 ;; the board, in the interpreter and compiler, and just FIX all of
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 ;; the code that relies on dynamic scope of non-defvarred variables.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 ;; Other things to consider:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 ;; Associative math should recognize subcalls to identical function:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 ;;(disassemble #'(lambda (x) (+ (+ (foo) 1) (+ (bar) 2))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 ;; This should generate the same as (1+ x) and (1- x)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 ;;(disassemble #'(lambda (x) (cons (+ x 1) (- x 1))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 ;; An awful lot of functions always return a non-nil value. If they're
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 ;; error free also they may act as true-constants.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 ;;(disassemble #'(lambda (x) (and (point) (foo))))
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
170 ;; When
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 ;; - all but one arguments to a function are constant
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 ;; - the non-constant argument is an if-expression (cond-expression?)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 ;; then the outer function can be distributed. If the guarding
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 ;; condition is side-effect-free [assignment-free] then the other
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 ;; arguments may be any expressions. Since, however, the code size
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 ;; can increase this way they should be "simple". Compare:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 ;;(disassemble #'(lambda (x) (eq (if (point) 'a 'b) 'c)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 ;;(disassemble #'(lambda (x) (if (point) (eq 'a 'c) (eq 'b 'c))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
181 ;; (car (cons A B)) -> (prog1 A B)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 ;;(disassemble #'(lambda (x) (car (cons (foo) 42))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 ;; (cdr (cons A B)) -> (progn A B)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 ;;(disassemble #'(lambda (x) (cdr (cons 42 (foo)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
187 ;; (car (list A B ...)) -> (prog1 A ... B)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 ;;(disassemble #'(lambda (x) (car (list (foo) 42 (bar)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 ;; (cdr (list A B ...)) -> (progn A (list B ...))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 ;;(disassemble #'(lambda (x) (cdr (list 42 (foo) (bar)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 ;;; Code:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 (require 'byte-compile "bytecomp")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 (defun byte-compile-log-lap-1 (format &rest args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 (if (aref byte-code-vector 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 (error "The old version of the disassembler is loaded. Reload new-bytecomp as well."))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 (byte-compile-log-1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 (apply 'format format
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 (let (c a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 (mapcar
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205 #'(lambda (arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 (if (not (consp arg))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 (if (and (symbolp arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 (string-match "^byte-" (symbol-name arg)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 (intern (substring (symbol-name arg) 5))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 (if (integerp (setq c (car arg)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 (error "non-symbolic byte-op %s" c))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 (if (eq c 'TAG)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214 (setq c arg)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 (setq a (cond ((memq c byte-goto-ops)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 (car (cdr (cdr arg))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217 ((memq c byte-constref-ops)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 (car (cdr arg)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 (t (cdr arg))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 (setq c (symbol-name c))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 (if (string-match "^byte-." c)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 (setq c (intern (substring c 5)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 (if (eq c 'constant) (setq c 'const))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 (if (and (eq (cdr arg) 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 (not (memq c '(unbind call const))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 c
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 (format "(%s %s)" c a))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 args)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 (defmacro byte-compile-log-lap (format-string &rest args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 (list 'and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 '(memq byte-optimize-log '(t byte))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 (cons 'byte-compile-log-lap-1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 (cons format-string args))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237 ;;; byte-compile optimizers to support inlining
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 (put 'inline 'byte-optimizer 'byte-optimize-inline-handler)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 (defun byte-optimize-inline-handler (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 "byte-optimize-handler for the `inline' special-form."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 (cons
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 'progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245 (mapcar
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 #'(lambda (sexp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 (let ((fn (car-safe sexp)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 (if (and (symbolp fn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 (or (cdr (assq fn byte-compile-function-environment))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 (and (fboundp fn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 (not (or (cdr (assq fn byte-compile-macro-environment))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 (and (consp (setq fn (symbol-function fn)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 (eq (car fn) 'macro))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254 (subrp fn))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 (byte-compile-inline-expand sexp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 sexp)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 (cdr form))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 ;; Splice the given lap code into the current instruction stream.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 ;; If it has any labels in it, you're responsible for making sure there
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 ;; are no collisions, and that byte-compile-tag-number is reasonable
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 ;; after this is spliced in. The provided list is destroyed.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 (defun byte-inline-lapcode (lap)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 (setq byte-compile-output (nconc (nreverse lap) byte-compile-output)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 (defun byte-compile-inline-expand (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 (let* ((name (car form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 (fn (or (cdr (assq name byte-compile-function-environment))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 (and (fboundp name) (symbol-function name)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 (if (null fn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 (byte-compile-warn "attempt to inline %s before it was defined" name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 ;; else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 (if (and (consp fn) (eq (car fn) 'autoload))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 (load (nth 1 fn))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 (setq fn (or (cdr (assq name byte-compile-function-environment))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281 (and (fboundp name) (symbol-function name))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 (if (and (consp fn) (eq (car fn) 'autoload))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 (error "file \"%s\" didn't define \"%s\"" (nth 1 fn) name))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 (if (symbolp fn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 (byte-compile-inline-expand (cons fn (cdr form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 (if (compiled-function-p fn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 (fetch-bytecode fn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 (cons (list 'lambda (compiled-function-arglist fn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 (list 'byte-code
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 (compiled-function-instructions fn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 (compiled-function-constants fn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 (compiled-function-stack-depth fn)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 (cdr form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 (if (not (eq (car fn) 'lambda)) (error "%s is not a lambda" name))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 (cons fn (cdr form)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 ;;; ((lambda ...) ...)
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
299 ;;;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 (defun byte-compile-unfold-lambda (form &optional name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 (or name (setq name "anonymous lambda"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302 (let ((lambda (car form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 (values (cdr form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 (if (compiled-function-p lambda)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 (setq lambda (list 'lambda (compiled-function-arglist lambda)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 (list 'byte-code
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 (compiled-function-instructions lambda)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 (compiled-function-constants lambda)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 (compiled-function-stack-depth lambda)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 (let ((arglist (nth 1 lambda))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 (body (cdr (cdr lambda)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 optionalp restp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 bindings)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 (if (and (stringp (car body)) (cdr body))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 (setq body (cdr body)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316 (if (and (consp (car body)) (eq 'interactive (car (car body))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317 (setq body (cdr body)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318 (while arglist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 (cond ((eq (car arglist) '&optional)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 ;; ok, I'll let this slide because funcall_lambda() does...
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
321 ;; (if optionalp (error "multiple &optional keywords in %s" name))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322 (if restp (error "&optional found after &rest in %s" name))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
323 (if (null (cdr arglist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324 (error "nothing after &optional in %s" name))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325 (setq optionalp t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 ((eq (car arglist) '&rest)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327 ;; ...but it is by no stretch of the imagination a reasonable
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 ;; thing that funcall_lambda() allows (&rest x y) and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 ;; (&rest x &optional y) in arglists.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330 (if (null (cdr arglist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331 (error "nothing after &rest in %s" name))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 (if (cdr (cdr arglist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333 (error "multiple vars after &rest in %s" name))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 (setq restp t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 (restp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336 (setq bindings (cons (list (car arglist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337 (and values (cons 'list values)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 bindings)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339 values nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 ((and (not optionalp) (null values))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 (byte-compile-warn "attempt to open-code %s with too few arguments" name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 (setq arglist nil values 'too-few))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344 (setq bindings (cons (list (car arglist) (car values))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345 bindings)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 values (cdr values))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 (setq arglist (cdr arglist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 (if values
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 (or (eq values 'too-few)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351 (byte-compile-warn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 "attempt to open-code %s with too many arguments" name))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 form)
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
354 (let ((newform
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 (if bindings
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 (cons 'let (cons (nreverse bindings) body))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 (cons 'progn body))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 (byte-compile-log " %s\t==>\t%s" form newform)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 newform)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 ;;; implementing source-level optimizers
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 (defun byte-optimize-form-code-walker (form for-effect)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 ;; For normal function calls, We can just mapcar the optimizer the cdr. But
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 ;; we need to have special knowledge of the syntax of the special forms
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368 ;; like let and defun (that's why they're special forms :-). (Actually,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 ;; the important aspect is that they are subrs that don't evaluate all of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 ;; their args.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372 (let ((fn (car-safe form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 tmp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 (cond ((not (consp form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 (if (not (and for-effect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 (or byte-compile-delete-errors
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 (not (symbolp form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 (eq form t))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 ((eq fn 'quote)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 (if (cdr (cdr form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 (byte-compile-warn "malformed quote form: %s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 (prin1-to-string form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 ;; map (quote nil) to nil to simplify optimizer logic.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 ;; map quoted constants to nil if for-effect (just because).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 (and (nth 1 form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 (not for-effect)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 ((or (compiled-function-p fn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 (eq 'lambda (car-safe fn)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 (byte-compile-unfold-lambda form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 ((memq fn '(let let*))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 ;; recursively enter the optimizer for the bindings and body
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 ;; of a let or let*. This for depth-firstness: forms that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 ;; are more deeply nested are optimized first.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 (cons fn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397 (cons
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398 (mapcar
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399 #'(lambda (binding)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 (if (symbolp binding)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 binding
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 (if (cdr (cdr binding))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403 (byte-compile-warn "malformed let binding: %s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404 (prin1-to-string binding)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 (list (car binding)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
406 (byte-optimize-form (nth 1 binding) nil))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407 (nth 1 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408 (byte-optimize-body (cdr (cdr form)) for-effect))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
409 ((eq fn 'cond)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 (cons fn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 (mapcar
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 #'(lambda (clause)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413 (if (consp clause)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
414 (cons
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
415 (byte-optimize-form (car clause) nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416 (byte-optimize-body (cdr clause) for-effect))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417 (byte-compile-warn "malformed cond form: %s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
418 (prin1-to-string clause))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
419 clause))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
420 (cdr form))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
421 ((eq fn 'progn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
422 ;; as an extra added bonus, this simplifies (progn <x>) --> <x>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
423 (if (cdr (cdr form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
425 (setq tmp (byte-optimize-body (cdr form) for-effect))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
426 (if (cdr tmp) (cons 'progn tmp) (car tmp)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
427 (byte-optimize-form (nth 1 form) for-effect)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
428 ((eq fn 'prog1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429 (if (cdr (cdr form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
430 (cons 'prog1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
431 (cons (byte-optimize-form (nth 1 form) for-effect)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 (byte-optimize-body (cdr (cdr form)) t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433 (byte-optimize-form (nth 1 form) for-effect)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434 ((eq fn 'prog2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435 (cons 'prog2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436 (cons (byte-optimize-form (nth 1 form) t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437 (cons (byte-optimize-form (nth 2 form) for-effect)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438 (byte-optimize-body (cdr (cdr (cdr form))) t)))))
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
439
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 ((memq fn '(save-excursion save-restriction save-current-buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441 ;; those subrs which have an implicit progn; it's not quite good
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442 ;; enough to treat these like normal function calls.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 ;; This can turn (save-excursion ...) into (save-excursion) which
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 ;; will be optimized away in the lap-optimize pass.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445 (cons fn (byte-optimize-body (cdr form) for-effect)))
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
446
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447 ((eq fn 'with-output-to-temp-buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 ;; this is just like the above, except for the first argument.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449 (cons fn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450 (cons
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451 (byte-optimize-form (nth 1 form) nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452 (byte-optimize-body (cdr (cdr form)) for-effect))))
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
453
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454 ((eq fn 'if)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 (cons fn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456 (cons (byte-optimize-form (nth 1 form) nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457 (cons
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458 (byte-optimize-form (nth 2 form) for-effect)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459 (byte-optimize-body (nthcdr 3 form) for-effect)))))
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
460
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 ((memq fn '(and or)) ; remember, and/or are control structures.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 ;; take forms off the back until we can't any more.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463 ;; In the future it could conceivably be a problem that the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 ;; subexpressions of these forms are optimized in the reverse
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 ;; order, but it's ok for now.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 (if for-effect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 (let ((backwards (reverse (cdr form))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 (while (and backwards
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469 (null (setcar backwards
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470 (byte-optimize-form (car backwards)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 for-effect))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472 (setq backwards (cdr backwards)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 (if (and (cdr form) (null backwards))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 (byte-compile-log
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 " all subforms of %s called for effect; deleted" form))
452
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
476 (when backwards
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
477 ;; Now optimize the rest of the forms. We need the return
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
478 ;; values. We already did the car.
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
479 (setcdr backwards
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
480 (mapcar 'byte-optimize-form (cdr backwards))))
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
481 (cons fn (nreverse backwards)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 (cons fn (mapcar 'byte-optimize-form (cdr form)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 ((eq fn 'interactive)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 (byte-compile-warn "misplaced interactive spec: %s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486 (prin1-to-string form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487 nil)
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
488
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
489 ((memq fn '(defun defmacro function
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 condition-case save-window-excursion))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491 ;; These forms are compiled as constants or by breaking out
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
492 ;; all the subexpressions and compiling them separately.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
493 form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495 ((eq fn 'unwind-protect)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
496 ;; the "protected" part of an unwind-protect is compiled (and thus
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497 ;; optimized) as a top-level form, so don't do it here. But the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 ;; non-protected part has the same for-effect status as the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499 ;; unwind-protect itself. (The protected part is always for effect,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500 ;; but that isn't handled properly yet.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501 (cons fn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502 (cons (byte-optimize-form (nth 1 form) for-effect)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 (cdr (cdr form)))))
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
504
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 ((eq fn 'catch)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 ;; the body of a catch is compiled (and thus optimized) as a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 ;; top-level form, so don't do it here. The tag is never
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 ;; for-effect. The body should have the same for-effect status
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 ;; as the catch form itself, but that isn't handled properly yet.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 (cons fn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511 (cons (byte-optimize-form (nth 1 form) nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 (cdr (cdr form)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 ;; If optimization is on, this is the only place that macros are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 ;; expanded. If optimization is off, then macroexpansion happens
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 ;; in byte-compile-form. Otherwise, the macros are already expanded
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 ;; by the time that is reached.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 ((not (eq form
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 (setq form (macroexpand form
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 byte-compile-macro-environment))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 (byte-optimize-form form for-effect))
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
522
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
523 ((not (symbolp fn))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
524 (or (eq 'mocklisp (car-safe fn)) ; ha!
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 (byte-compile-warn "%s is a malformed function"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 (prin1-to-string fn)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 ((and for-effect (setq tmp (get fn 'side-effect-free))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530 (or byte-compile-delete-errors
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 (eq tmp 'error-free)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533 (byte-compile-warn "%s called for effect"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 (prin1-to-string form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536 (byte-compile-log " %s called for effect; deleted" fn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 ;; appending a nil here might not be necessary, but it can't hurt.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538 (byte-optimize-form
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
539 (cons 'progn (append (cdr form) '(nil))) t))
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
540
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542 ;; Otherwise, no args can be considered to be for-effect,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
543 ;; even if the called function is for-effect, because we
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
544 ;; don't know anything about that function.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545 (cons fn (mapcar 'byte-optimize-form (cdr form)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
546
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
547
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
548 (defun byte-optimize-form (form &optional for-effect)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
549 "The source-level pass of the optimizer."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
550 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
551 ;; First, optimize all sub-forms of this one.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
552 (setq form (byte-optimize-form-code-walker form for-effect))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
553 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
554 ;; After optimizing all subforms, optimize this form until it doesn't
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
555 ;; optimize any further. This means that some forms will be passed through
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
556 ;; the optimizer many times, but that's necessary to make the for-effect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
557 ;; processing do as much as possible.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
558 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
559 (let (opt new)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
560 (if (and (consp form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
561 (symbolp (car form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
562 (or (and for-effect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
563 ;; we don't have any of these yet, but we might.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
564 (setq opt (get (car form) 'byte-for-effect-optimizer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
565 (setq opt (get (car form) 'byte-optimizer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
566 (not (eq form (setq new (funcall opt form)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
567 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
568 ;; (if (equal form new) (error "bogus optimizer -- %s" opt))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
569 (byte-compile-log " %s\t==>\t%s" form new)
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
570 (byte-optimize-form new for-effect))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
571 form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
572
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
573
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
574 (defun byte-optimize-body (forms all-for-effect)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
575 ;; Optimize the cdr of a progn or implicit progn; `forms' is a list of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
576 ;; forms, all but the last of which are optimized with the assumption that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
577 ;; they are being called for effect. The last is for-effect as well if
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
578 ;; all-for-effect is true. Returns a new list of forms.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
579 (let ((rest forms)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
580 (result nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
581 fe new)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
582 (while rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
583 (setq fe (or all-for-effect (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
584 (setq new (and (car rest) (byte-optimize-form (car rest) fe)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
585 (if (or new (not fe))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
586 (setq result (cons new result)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
587 (setq rest (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
588 (nreverse result)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
589
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
590
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
591 ;;; some source-level optimizers
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
592 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
593 ;;; when writing optimizers, be VERY careful that the optimizer returns
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
594 ;;; something not EQ to its argument if and ONLY if it has made a change.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
595 ;;; This implies that you cannot simply destructively modify the list;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 ;;; you must return something not EQ to it if you make an optimization.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598 ;;; It is now safe to optimize code such that it introduces new bindings.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
599
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 ;; I'd like this to be a defsubst, but let's not be self-referential...
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
601 (defmacro byte-compile-trueconstp (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
602 ;; Returns non-nil if FORM is a non-nil constant.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
603 `(cond ((consp ,form) (eq (car ,form) 'quote))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604 ((not (symbolp ,form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
605 ((eq ,form t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
606 ((keywordp ,form))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
607
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
608 ;; If the function is being called with constant numeric args,
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
609 ;; evaluate as much as possible at compile-time. This optimizer
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
610 ;; assumes that the function is associative, like + or *.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
611 (defun byte-optimize-associative-math (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
612 (let ((args nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
613 (constants nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
614 (rest (cdr form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
615 (while rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
616 (if (numberp (car rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
617 (setq constants (cons (car rest) constants))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618 (setq args (cons (car rest) args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619 (setq rest (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
620 (if (cdr constants)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
621 (if args
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
622 (list (car form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
623 (apply (car form) constants)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
624 (if (cdr args)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
625 (cons (car form) (nreverse args))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
626 (car args)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
627 (apply (car form) constants))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
628 form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
629
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
630 ;; If the function is being called with constant numeric args,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
631 ;; evaluate as much as possible at compile-time. This optimizer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
632 ;; assumes that the function satisfies
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
633 ;; (op x1 x2 ... xn) == (op ...(op (op x1 x2) x3) ...xn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
634 ;; like - and /.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
635 (defun byte-optimize-nonassociative-math (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
636 (if (or (not (numberp (car (cdr form))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
637 (not (numberp (car (cdr (cdr form))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
638 form
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
639 (let ((constant (car (cdr form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
640 (rest (cdr (cdr form))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
641 (while (numberp (car rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
642 (setq constant (funcall (car form) constant (car rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
643 rest (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
644 (if rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
645 (cons (car form) (cons constant rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
646 constant))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
647
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
648 ;;(defun byte-optimize-associative-two-args-math (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
649 ;; (setq form (byte-optimize-associative-math form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
650 ;; (if (consp form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
651 ;; (byte-optimize-two-args-left form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
652 ;; form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
653
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
654 ;;(defun byte-optimize-nonassociative-two-args-math (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
655 ;; (setq form (byte-optimize-nonassociative-math form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
656 ;; (if (consp form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
657 ;; (byte-optimize-two-args-right form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
658 ;; form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
659
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
660 ;; jwz: (byte-optimize-approx-equal 0.0 0.0) was returning nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
661 ;; in xemacs 19.15 because it used < instead of <=.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
662 (defun byte-optimize-approx-equal (x y)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
663 (<= (* (abs (- x y)) 100) (abs (+ x y))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
664
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
665 ;; Collect all the constants from FORM, after the STARTth arg,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
666 ;; and apply FUN to them to make one argument at the end.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
667 ;; For functions that can handle floats, that optimization
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
668 ;; can be incorrect because reordering can cause an overflow
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
669 ;; that would otherwise be avoided by encountering an arg that is a float.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
670 ;; We avoid this problem by (1) not moving float constants and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
671 ;; (2) not moving anything if it would cause an overflow.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
672 (defun byte-optimize-delay-constants-math (form start fun)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
673 ;; Merge all FORM's constants from number START, call FUN on them
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
674 ;; and put the result at the end.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
675 (let ((rest (nthcdr (1- start) form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
676 (orig form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
677 ;; t means we must check for overflow.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
678 (overflow (memq fun '(+ *))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
679 (while (cdr (setq rest (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
680 (if (integerp (car rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
681 (let (constants)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
682 (setq form (copy-sequence form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
683 rest (nthcdr (1- start) form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
684 (while (setq rest (cdr rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
685 (cond ((integerp (car rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
686 (setq constants (cons (car rest) constants))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
687 (setcar rest nil))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
688 ;; If necessary, check now for overflow
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
689 ;; that might be caused by reordering.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
690 (if (and overflow
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
691 ;; We have overflow if the result of doing the arithmetic
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
692 ;; on floats is not even close to the result
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
693 ;; of doing it on integers.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
694 (not (byte-optimize-approx-equal
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
695 (apply fun (mapcar 'float constants))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
696 (float (apply fun constants)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
697 (setq form orig)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
698 (setq form (nconc (delq nil form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
699 (list (apply fun (nreverse constants)))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
700 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
701
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
702 ;;; It is not safe to optimize calls to arithmetic ops with one arg
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
703 ;;; away entirely (actually, it would be safe if we know the sole arg
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
704 ;;; is not a marker or if it appears in other arithmetic).
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
705
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
706 ;;; But this degree of paranoia is normally unjustified, so optimize unless
547
cf82e22962ce [xemacs-hg @ 2001-05-20 06:00:18 by martinb]
martinb
parents: 464
diff changeset
707 ;;; the user has done (declaim (optimize (safety 3))). See bytecomp.el.
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
708
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
709 (defun byte-optimize-plus (form)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
710 (byte-optimize-predicate (byte-optimize-delay-constants-math form 1 '+)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
711
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
712 (defun byte-optimize-multiply (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
713 (setq form (byte-optimize-delay-constants-math form 1 '*))
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
714 ;; If there is a constant integer in FORM, it is now the last element.
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
715
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
716 (case (car (last form))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
717 ;; (* x y 0) --> (progn x y 0)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
718 (0 (cons 'progn (cdr form)))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
719 (t (byte-optimize-predicate form))))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
720
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
721 (defun byte-optimize-minus (form)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
722 ;; Put constants at the end, except the first arg.
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
723 (setq form (byte-optimize-delay-constants-math form 2 '+))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
724 ;; Now only the first and last args can be integers.
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
725 (let ((last (car (last (nthcdr 3 form)))))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
726 (cond
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
727 ;; If form is (- CONST foo... CONST), merge first and last.
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
728 ((and (numberp (nth 1 form)) (numberp last))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
729 (decf (nth 1 form) last)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
730 (butlast form))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
731
464
5aa1854ad537 Import from CVS: tag r21-2-47
cvs
parents: 452
diff changeset
732 ;; (- 0 ...) -->
5aa1854ad537 Import from CVS: tag r21-2-47
cvs
parents: 452
diff changeset
733 ((eq 0 (nth 1 form))
5aa1854ad537 Import from CVS: tag r21-2-47
cvs
parents: 452
diff changeset
734 (case (length form)
5aa1854ad537 Import from CVS: tag r21-2-47
cvs
parents: 452
diff changeset
735 ;; (- 0) --> 0
5aa1854ad537 Import from CVS: tag r21-2-47
cvs
parents: 452
diff changeset
736 (2 0)
5aa1854ad537 Import from CVS: tag r21-2-47
cvs
parents: 452
diff changeset
737 ;; (- 0 x) --> (- x)
5aa1854ad537 Import from CVS: tag r21-2-47
cvs
parents: 452
diff changeset
738 (3 `(- ,(nth 2 form)))
5aa1854ad537 Import from CVS: tag r21-2-47
cvs
parents: 452
diff changeset
739 ;; (- 0 x y ...) --> (- (- x) y ...)
5aa1854ad537 Import from CVS: tag r21-2-47
cvs
parents: 452
diff changeset
740 (t `(- (- ,(nth 2 form)) ,@(nthcdr 3 form)))))
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
741
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
742 (t (byte-optimize-predicate form)))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
743
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
744 (defun byte-optimize-divide (form)
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
745 ;; Put constants at the end, except the first arg.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
746 (setq form (byte-optimize-delay-constants-math form 2 '*))
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
747 ;; Now only the first and last args can be integers.
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
748 (let ((last (car (last (nthcdr 3 form)))))
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
749 (cond
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
750 ;; If form is (/ CONST foo... CONST), merge first and last.
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
751 ((and (numberp (nth 1 form)) (numberp last))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
752 (condition-case nil
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
753 (cons (nth 0 form)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
754 (cons (/ (nth 1 form) last)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
755 (butlast (cdr (cdr form)))))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
756 (error form)))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
757
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
758 ;; (/ 0 x y) --> (progn x y 0)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
759 ((eq (nth 1 form) 0)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
760 (append '(progn) (cdr (cdr form)) '(0)))
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
761
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
762 ;; We don't have to check for divide-by-zero because `/' does.
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
763 (t (byte-optimize-predicate form)))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
764
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
765 (defun byte-optimize-logmumble (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
766 (setq form (byte-optimize-delay-constants-math form 1 (car form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
767 (byte-optimize-predicate
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
768 (cond ((memq 0 form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
769 (setq form (if (eq (car form) 'logand)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
770 (cons 'progn (cdr form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
771 (delq 0 (copy-sequence form)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
772 ((and (eq (car-safe form) 'logior)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
773 (memq -1 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
774 (cons 'progn (cdr form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
775 (form))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
776
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
777
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
778 (defun byte-optimize-binary-predicate (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
779 (if (byte-compile-constp (nth 1 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
780 (if (byte-compile-constp (nth 2 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
781 (condition-case ()
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
782 (list 'quote (eval form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
783 (error form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
784 ;; This can enable some lapcode optimizations.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
785 (list (car form) (nth 2 form) (nth 1 form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
786 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
787
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
788 (defun byte-optimize-predicate (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
789 (let ((ok t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
790 (rest (cdr form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
791 (while (and rest ok)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
792 (setq ok (byte-compile-constp (car rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
793 rest (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
794 (if ok
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
795 (condition-case err
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
796 (list 'quote (eval form))
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
797 (error
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
798 (byte-compile-warn "evaluating %s: %s" form err)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
799 form))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
800 form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
801
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
802 (defun byte-optimize-identity (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
803 (if (and (cdr form) (null (cdr (cdr form))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
804 (nth 1 form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
805 (byte-compile-warn "identity called with %d arg%s, but requires 1"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
806 (length (cdr form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
807 (if (= 1 (length (cdr form))) "" "s"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
808 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
809
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
810 (defun byte-optimize-car (form)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
811 (let ((arg (cadr form)))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
812 (cond
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
813 ((and (byte-compile-trueconstp arg)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
814 (not (and (consp arg)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
815 (eq (car arg) 'quote)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
816 (listp (cadr arg)))))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
817 (byte-compile-warn
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
818 "taking car of a constant: %s" arg)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
819 form)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
820 ((and (eq (car-safe arg) 'cons)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
821 (eq (length arg) 3))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
822 `(prog1 ,(nth 1 arg) ,(nth 2 arg)))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
823 ((eq (car-safe arg) 'list)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
824 `(prog1 ,@(cdr arg)))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
825 (t
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
826 (byte-optimize-predicate form)))))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
827
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
828 (defun byte-optimize-cdr (form)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
829 (let ((arg (cadr form)))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
830 (cond
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
831 ((and (byte-compile-trueconstp arg)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
832 (not (and (consp arg)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
833 (eq (car arg) 'quote)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
834 (listp (cadr arg)))))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
835 (byte-compile-warn
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
836 "taking cdr of a constant: %s" arg)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
837 form)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
838 ((and (eq (car-safe arg) 'cons)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
839 (eq (length arg) 3))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
840 `(progn ,(nth 1 arg) ,(nth 2 arg)))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
841 ((eq (car-safe arg) 'list)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
842 (if (> (length arg) 2)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
843 `(progn ,(cadr arg) (list ,@(cddr arg)))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
844 (cadr arg)))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
845 (t
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
846 (byte-optimize-predicate form)))))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
847
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
848 (put 'identity 'byte-optimizer 'byte-optimize-identity)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
849
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
850 (put '+ 'byte-optimizer 'byte-optimize-plus)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
851 (put '* 'byte-optimizer 'byte-optimize-multiply)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
852 (put '- 'byte-optimizer 'byte-optimize-minus)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
853 (put '/ 'byte-optimizer 'byte-optimize-divide)
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
854 (put '% 'byte-optimizer 'byte-optimize-predicate)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
855 (put 'max 'byte-optimizer 'byte-optimize-associative-math)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
856 (put 'min 'byte-optimizer 'byte-optimize-associative-math)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
857
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
858 (put 'eq 'byte-optimizer 'byte-optimize-binary-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
859 (put 'eql 'byte-optimizer 'byte-optimize-binary-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
860 (put 'equal 'byte-optimizer 'byte-optimize-binary-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
861 (put 'string= 'byte-optimizer 'byte-optimize-binary-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
862 (put 'string-equal 'byte-optimizer 'byte-optimize-binary-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
863
550
1638aacf421d [xemacs-hg @ 2001-05-21 02:15:12 by martinb]
martinb
parents: 547
diff changeset
864 (put '= 'byte-optimizer 'byte-optimize-predicate)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
865 (put '< 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
866 (put '> 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
867 (put '<= 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
868 (put '>= 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
869 (put '1+ 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
870 (put '1- 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
871 (put 'not 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
872 (put 'null 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
873 (put 'memq 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
874 (put 'consp 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
875 (put 'listp 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
876 (put 'symbolp 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
877 (put 'stringp 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
878 (put 'string< 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
879 (put 'string-lessp 'byte-optimizer 'byte-optimize-predicate)
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
880 (put 'length 'byte-optimizer 'byte-optimize-predicate)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
881
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
882 (put 'logand 'byte-optimizer 'byte-optimize-logmumble)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
883 (put 'logior 'byte-optimizer 'byte-optimize-logmumble)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
884 (put 'logxor 'byte-optimizer 'byte-optimize-logmumble)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
885 (put 'lognot 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
886
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
887 (put 'car 'byte-optimizer 'byte-optimize-car)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
888 (put 'cdr 'byte-optimizer 'byte-optimize-cdr)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
889 (put 'car-safe 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
890 (put 'cdr-safe 'byte-optimizer 'byte-optimize-predicate)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
891
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
892
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
893 ;; I'm not convinced that this is necessary. Doesn't the optimizer loop
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
894 ;; take care of this? - Jamie
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
895 ;; I think this may some times be necessary to reduce eg. (quote 5) to 5,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
896 ;; so arithmetic optimizers recognize the numeric constant. - Hallvard
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
897 (put 'quote 'byte-optimizer 'byte-optimize-quote)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
898 (defun byte-optimize-quote (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
899 (if (or (consp (nth 1 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
900 (and (symbolp (nth 1 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
901 ;; XEmacs addition:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
902 (not (keywordp (nth 1 form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
903 (not (memq (nth 1 form) '(nil t)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
904 form
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
905 (nth 1 form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
906
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
907 (defun byte-optimize-zerop (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
908 (cond ((numberp (nth 1 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
909 (eval form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
910 (byte-compile-delete-errors
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
911 (list '= (nth 1 form) 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
912 (form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
913
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
914 (put 'zerop 'byte-optimizer 'byte-optimize-zerop)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
915
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
916 (defun byte-optimize-and (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
917 ;; Simplify if less than 2 args.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
918 ;; if there is a literal nil in the args to `and', throw it and following
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
919 ;; forms away, and surround the `and' with (progn ... nil).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
920 (cond ((null (cdr form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
921 ((memq nil form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
922 (list 'progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
923 (byte-optimize-and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
924 (prog1 (setq form (copy-sequence form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
925 (while (nth 1 form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
926 (setq form (cdr form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
927 (setcdr form nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
928 nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
929 ((null (cdr (cdr form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
930 (nth 1 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
931 ((byte-optimize-predicate form))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
932
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
933 (defun byte-optimize-or (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
934 ;; Throw away nil's, and simplify if less than 2 args.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
935 ;; If there is a literal non-nil constant in the args to `or', throw away all
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
936 ;; following forms.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
937 (if (memq nil form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
938 (setq form (delq nil (copy-sequence form))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
939 (let ((rest form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
940 (while (cdr (setq rest (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
941 (if (byte-compile-trueconstp (car rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
942 (setq form (copy-sequence form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
943 rest (setcdr (memq (car rest) form) nil))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
944 (if (cdr (cdr form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
945 (byte-optimize-predicate form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
946 (nth 1 form))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
947
448
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
948 ;;; For the byte optimizer, `cond' is just overly sweet syntactic sugar.
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
949 ;;; So we rewrite (cond ...) in terms of `if' and `or',
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
950 ;;; which are easier to optimize.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
951 (defun byte-optimize-cond (form)
448
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
952 (byte-optimize-cond-1 (cdr form)))
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
953
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
954 (defun byte-optimize-cond-1 (clauses)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
955 (cond
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
956 ((null clauses) nil)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
957 ((consp (car clauses))
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
958 (nconc
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
959 (case (length (car clauses))
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
960 (1 `(or ,(nth 0 (car clauses))))
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
961 (2 `(if ,(nth 0 (car clauses)) ,(nth 1 (car clauses))))
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
962 (t `(if ,(nth 0 (car clauses)) (progn ,@(cdr (car clauses))))))
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
963 (when (cdr clauses) (list (byte-optimize-cond-1 (cdr clauses))))))
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents: 446
diff changeset
964 (t (error "malformed cond clause %s" (car clauses)))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
965
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
966 (defun byte-optimize-if (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
967 ;; (if <true-constant> <then> <else...>) ==> <then>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
968 ;; (if <false-constant> <then> <else...>) ==> (progn <else...>)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
969 ;; (if <test> nil <else...>) ==> (if (not <test>) (progn <else...>))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
970 ;; (if <test> <then> nil) ==> (if <test> <then>)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
971 (let ((clause (nth 1 form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
972 (cond ((byte-compile-trueconstp clause)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
973 (nth 2 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
974 ((null clause)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
975 (if (nthcdr 4 form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
976 (cons 'progn (nthcdr 3 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
977 (nth 3 form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
978 ((nth 2 form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
979 (if (equal '(nil) (nthcdr 3 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
980 (list 'if clause (nth 2 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
981 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
982 ((or (nth 3 form) (nthcdr 4 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
983 (list 'if
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
984 ;; Don't make a double negative;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
985 ;; instead, take away the one that is there.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
986 (if (and (consp clause) (memq (car clause) '(not null))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
987 (= (length clause) 2)) ; (not xxxx) or (not (xxxx))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
988 (nth 1 clause)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
989 (list 'not clause))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
990 (if (nthcdr 4 form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
991 (cons 'progn (nthcdr 3 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
992 (nth 3 form))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
993 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
994 (list 'progn clause nil)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
995
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
996 (defun byte-optimize-while (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
997 (if (nth 1 form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
998 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
999
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1000 (put 'and 'byte-optimizer 'byte-optimize-and)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1001 (put 'or 'byte-optimizer 'byte-optimize-or)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1002 (put 'cond 'byte-optimizer 'byte-optimize-cond)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1003 (put 'if 'byte-optimizer 'byte-optimize-if)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1004 (put 'while 'byte-optimizer 'byte-optimize-while)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1005
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1006 ;; The supply of bytecodes is small and constrained by backward compatibility.
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1007 ;; Several functions have byte-coded versions and hence are very efficient.
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1008 ;; Related functions which can be expressed in terms of the byte-coded
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1009 ;; ones should be transformed into bytecoded calls for efficiency.
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1010 ;; This is especially the case for functions with a backward- and
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1011 ;; forward- version, but with a bytecode only for the forward one.
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1012
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1013 ;; Some programmers have hand-optimized calls like (backward-char)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1014 ;; into the call (forward-char -1).
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1015 ;; But it's so much nicer for the byte-compiler to do this automatically!
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1016
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1017 ;; (char-before) ==> (char-after (1- (point)))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1018 (put 'char-before 'byte-optimizer 'byte-optimize-char-before)
434
9d177e8d4150 Import from CVS: tag r21-2-25
cvs
parents: 428
diff changeset
1019 (defun byte-optimize-char-before (form)
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1020 `(char-after
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1021 ,(cond
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1022 ((null (nth 1 form))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1023 '(1- (point)))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1024 ((equal '(point) (nth 1 form))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1025 '(1- (point)))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1026 (t `(1- (or ,(nth 1 form) (point)))))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1027 ,@(cdr (cdr form))))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1028
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1029 ;; (backward-char n) ==> (forward-char (- n))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1030 (put 'backward-char 'byte-optimizer 'byte-optimize-backward-char)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1031 (defun byte-optimize-backward-char (form)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1032 `(forward-char
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1033 ,(typecase (nth 1 form)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1034 (null -1)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1035 (integer (- (nth 1 form)))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1036 (t `(- (or ,(nth 1 form) 1))))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1037 ,@(cdr (cdr form))))
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
1038
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1039 ;; (backward-word n) ==> (forward-word (- n))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1040 (put 'backward-word 'byte-optimizer 'byte-optimize-backward-word)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1041 (defun byte-optimize-backward-word (form)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1042 `(forward-word
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1043 ,(typecase (nth 1 form)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1044 (null -1)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1045 (integer (- (nth 1 form)))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1046 (t `(- (or ,(nth 1 form) 1))))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1047 ,@(cdr (cdr form))))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1048
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1049 ;; The following would be a valid optimization of the above kind, but
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1050 ;; the gain in performance is very small, since the saved funcall is
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1051 ;; counterbalanced by the necessity of adding a bytecode for (point).
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1052 ;;
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1053 ;; Also, users are more likely to have modified the behavior of
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1054 ;; delete-char via advice or some similar mechanism. This is much
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1055 ;; less of a problem for the previous functions because it wouldn't
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1056 ;; make sense to modify the behaviour of `backward-char' without also
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1057 ;; modifying `forward-char', for example.
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1058
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1059 ;; (delete-char n) ==> (delete-region (point) (+ (point) n))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1060 ;; (put 'delete-char 'byte-optimizer 'byte-optimize-delete-char)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1061 ;; (defun byte-optimize-delete-char (form)
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1062 ;; (case (length (cdr form))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1063 ;; (0 `(delete-region (point) (1+ (point))))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1064 ;; (1 `(delete-region (point) (+ (point) ,(nth 1 form))))
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1065 ;; (t form)))
434
9d177e8d4150 Import from CVS: tag r21-2-25
cvs
parents: 428
diff changeset
1066
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1067 ;; byte-compile-negation-optimizer lives in bytecomp.el
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1068 ;(put '/= 'byte-optimizer 'byte-compile-negation-optimizer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1069 (put 'atom 'byte-optimizer 'byte-compile-negation-optimizer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1070 (put 'nlistp 'byte-optimizer 'byte-compile-negation-optimizer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1071
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1072 (defun byte-optimize-funcall (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1073 ;; (funcall '(lambda ...) ...) ==> ((lambda ...) ...)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1074 ;; (funcall 'foo ...) ==> (foo ...)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1075 (let ((fn (nth 1 form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1076 (if (memq (car-safe fn) '(quote function))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1077 (cons (nth 1 fn) (cdr (cdr form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1078 form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1079
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1080 (defun byte-optimize-apply (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1081 ;; If the last arg is a literal constant, turn this into a funcall.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1082 ;; The funcall optimizer can then transform (funcall 'foo ...) -> (foo ...).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1083 (let ((fn (nth 1 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1084 (last (nth (1- (length form)) form))) ; I think this really is fastest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1085 (or (if (or (null last)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1086 (eq (car-safe last) 'quote))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1087 (if (listp (nth 1 last))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1088 (let ((butlast (nreverse (cdr (reverse (cdr (cdr form)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1089 (nconc (list 'funcall fn) butlast
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1090 (mapcar #'(lambda (x) (list 'quote x)) (nth 1 last))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1091 (byte-compile-warn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1092 "last arg to apply can't be a literal atom: %s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1093 (prin1-to-string last))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1094 nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1095 form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1096
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1097 (put 'funcall 'byte-optimizer 'byte-optimize-funcall)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1098 (put 'apply 'byte-optimizer 'byte-optimize-apply)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1099
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1100
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1101 (put 'let 'byte-optimizer 'byte-optimize-letX)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1102 (put 'let* 'byte-optimizer 'byte-optimize-letX)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1103 (defun byte-optimize-letX (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1104 (cond ((null (nth 1 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1105 ;; No bindings
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1106 (cons 'progn (cdr (cdr form))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1107 ((or (nth 2 form) (nthcdr 3 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1108 form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1109 ;; The body is nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1110 ((eq (car form) 'let)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1111 (append '(progn) (mapcar 'car-safe (mapcar 'cdr-safe (nth 1 form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1112 '(nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1113 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1114 (let ((binds (reverse (nth 1 form))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1115 (list 'let* (reverse (cdr binds)) (nth 1 (car binds)) nil)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1116
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1117
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1118 (put 'nth 'byte-optimizer 'byte-optimize-nth)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1119 (defun byte-optimize-nth (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1120 (if (and (= (safe-length form) 3) (memq (nth 1 form) '(0 1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1121 (list 'car (if (zerop (nth 1 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1122 (nth 2 form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1123 (list 'cdr (nth 2 form))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1124 (byte-optimize-predicate form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1125
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1126 (put 'nthcdr 'byte-optimizer 'byte-optimize-nthcdr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1127 (defun byte-optimize-nthcdr (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1128 (if (and (= (safe-length form) 3) (not (memq (nth 1 form) '(0 1 2))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1129 (byte-optimize-predicate form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1130 (let ((count (nth 1 form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1131 (setq form (nth 2 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1132 (while (>= (setq count (1- count)) 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1133 (setq form (list 'cdr form)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1134 form)))
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1135
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1136 (put 'concat 'byte-optimizer 'byte-optimize-concat)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1137 (defun byte-optimize-concat (form)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1138 (let ((args (cdr form))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1139 (constant t))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1140 (while (and args constant)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1141 (or (byte-compile-constp (car args))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1142 (setq constant nil))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1143 (setq args (cdr args)))
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1144 (if constant
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1145 (eval form)
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1146 form)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1147
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
1148 ;;; enumerating those functions which need not be called if the returned
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1149 ;;; value is not used. That is, something like
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1150 ;;; (progn (list (something-with-side-effects) (yow))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1151 ;;; (foo))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1152 ;;; may safely be turned into
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1153 ;;; (progn (progn (something-with-side-effects) (yow))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1154 ;;; (foo))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1155 ;;; Further optimizations will turn (progn (list 1 2 3) 'foo) into 'foo.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1156
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1157 ;;; I wonder if I missed any :-\)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1158 (let ((side-effect-free-fns
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1159 '(% * + - / /= 1+ 1- < <= = > >= abs acos append aref ash asin atan
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1160 assoc assq
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1161 boundp buffer-file-name buffer-local-variables buffer-modified-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1162 buffer-substring
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1163 capitalize car-less-than-car car cdr ceiling concat
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1164 ;; coordinates-in-window-p not in XEmacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1165 copy-marker cos count-lines
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1166 default-boundp default-value documentation downcase
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1167 elt exp expt fboundp featurep
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1168 file-directory-p file-exists-p file-locked-p file-name-absolute-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1169 file-newer-than-file-p file-readable-p file-symlink-p file-writable-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1170 float floor format
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1171 get get-buffer get-buffer-window getenv get-file-buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1172 ;; hash-table functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1173 make-hash-table copy-hash-table
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1174 gethash
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1175 hash-table-count
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1176 hash-table-rehash-size
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1177 hash-table-rehash-threshold
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1178 hash-table-size
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1179 hash-table-test
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1180 hash-table-type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1181 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1182 int-to-string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1183 length log log10 logand logb logior lognot logxor lsh
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1184 marker-buffer max member memq min mod
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1185 next-window nth nthcdr number-to-string
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
1186 parse-colon-path plist-get previous-window
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1187 radians-to-degrees rassq regexp-quote reverse round
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1188 sin sqrt string< string= string-equal string-lessp string-to-char
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1189 string-to-int string-to-number substring symbol-plist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1190 tan upcase user-variable-p vconcat
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1191 ;; XEmacs change: window-edges -> window-pixel-edges
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1192 window-buffer window-dedicated-p window-pixel-edges window-height
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1193 window-hscroll window-minibuffer-p window-width
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1194 zerop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1195 ;; functions defined by cl
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1196 oddp evenp plusp minusp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1197 abs expt signum last butlast ldiff
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1198 pairlis gcd lcm
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1199 isqrt floor* ceiling* truncate* round* mod* rem* subseq
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
1200 list-length getf
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1201 ))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1202 (side-effect-and-error-free-fns
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1203 '(arrayp atom
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1204 bobp bolp buffer-end buffer-list buffer-size buffer-string bufferp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1205 car-safe case-table-p cdr-safe char-or-string-p char-table-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1206 characterp commandp cons
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1207 consolep console-live-p consp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1208 current-buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1209 ;; XEmacs: extent functions, frame-live-p, various other stuff
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1210 devicep device-live-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1211 dot dot-marker eobp eolp eq eql equal eventp extentp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1212 extent-live-p floatp framep frame-live-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1213 get-largest-window get-lru-window
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1214 hash-table-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1215 identity ignore integerp integer-or-marker-p interactive-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1216 invocation-directory invocation-name
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1217 keymapp list listp
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1218 make-marker mark mark-marker markerp memory-limit minibuffer-window
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1219 ;; mouse-movement-p not in XEmacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1220 natnump nlistp not null number-or-marker-p numberp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1221 one-window-p ;; overlayp not in XEmacs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1222 point point-marker point-min point-max processp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1223 range-table-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1224 selected-window sequencep stringp subrp symbolp syntax-table-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1225 user-full-name user-login-name user-original-login-name
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1226 user-real-login-name user-real-uid user-uid
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1227 vector vectorp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1228 window-configuration-p window-live-p windowp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1229 ;; Functions defined by cl
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1230 eql floatp-safe list* subst acons equalp random-state-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1231 copy-tree sublis
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1232 )))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1233 (dolist (fn side-effect-free-fns)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1234 (put fn 'side-effect-free t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1235 (dolist (fn side-effect-and-error-free-fns)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1236 (put fn 'side-effect-free 'error-free)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1237
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1238
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1239 (defun byte-compile-splice-in-already-compiled-code (form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1240 ;; form is (byte-code "..." [...] n)
446
1ccc32a20af4 Import from CVS: tag r21-2-38
cvs
parents: 444
diff changeset
1241 (if (not (memq byte-optimize '(t byte)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1242 (byte-compile-normal-call form)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1243 (byte-inline-lapcode
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1244 (byte-decompile-bytecode-1 (nth 1 form) (nth 2 form) t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1245 (setq byte-compile-maxdepth (max (+ byte-compile-depth (nth 3 form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1246 byte-compile-maxdepth))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1247 (setq byte-compile-depth (1+ byte-compile-depth))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1248
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1249 (put 'byte-code 'byte-compile 'byte-compile-splice-in-already-compiled-code)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1250
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1251
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1252 (defconst byte-constref-ops
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1253 '(byte-constant byte-constant2 byte-varref byte-varset byte-varbind))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1254
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1255 ;;; This function extracts the bitfields from variable-length opcodes.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1256 ;;; Originally defined in disass.el (which no longer uses it.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1257
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1258 (defun disassemble-offset ()
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1259 "Don't call this!"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1260 ;; fetch and return the offset for the current opcode.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1261 ;; return NIL if this opcode has no offset
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1262 ;; OP, PTR and BYTES are used and set dynamically
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1263 (declare (special op ptr bytes))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1264 (cond ((< op byte-nth)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1265 (let ((tem (logand op 7)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1266 (setq op (logand op 248))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1267 (cond ((eq tem 6)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1268 (setq ptr (1+ ptr)) ;offset in next byte
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1269 ;; char-to-int to avoid downstream problems
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1270 ;; caused by chars appearing where ints are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1271 ;; expected. In bytecode the bytes in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1272 ;; opcode string are always interpreted as ints.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1273 (char-to-int (aref bytes ptr)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1274 ((eq tem 7)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1275 (setq ptr (1+ ptr)) ;offset in next 2 bytes
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1276 (+ (aref bytes ptr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1277 (progn (setq ptr (1+ ptr))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1278 (lsh (aref bytes ptr) 8))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1279 (t tem)))) ;offset was in opcode
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1280 ((>= op byte-constant)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1281 (prog1 (- op byte-constant) ;offset in opcode
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1282 (setq op byte-constant)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1283 ((and (>= op byte-constant2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1284 (<= op byte-goto-if-not-nil-else-pop))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1285 (setq ptr (1+ ptr)) ;offset in next 2 bytes
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1286 (+ (aref bytes ptr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1287 (progn (setq ptr (1+ ptr))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1288 (lsh (aref bytes ptr) 8))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1289 ;; XEmacs: this code was here before. FSF's first comparison
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1290 ;; is (>= op byte-listN). It appears that the rel-goto stuff
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1291 ;; does not exist in FSF 19.30. It doesn't exist in 19.28
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1292 ;; either, so I'm going to assume that this is an improvement
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1293 ;; on our part and leave it in. --ben
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1294 ((and (>= op byte-rel-goto)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1295 (<= op byte-insertN))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1296 (setq ptr (1+ ptr)) ;offset in next byte
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1297 ;; Use char-to-int to avoid downstream problems caused by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1298 ;; chars appearing where ints are expected. In bytecode
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1299 ;; the bytes in the opcode string are always interpreted as
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1300 ;; ints.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1301 (char-to-int (aref bytes ptr)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1302
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1303
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1304 ;;; This de-compiler is used for inline expansion of compiled functions,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1305 ;;; and by the disassembler.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1306 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1307 ;;; This list contains numbers, which are pc values,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1308 ;;; before each instruction.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1309 (defun byte-decompile-bytecode (bytes constvec)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1310 "Turns BYTECODE into lapcode, referring to CONSTVEC."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1311 (let ((byte-compile-constants nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1312 (byte-compile-variables nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1313 (byte-compile-tag-number 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1314 (byte-decompile-bytecode-1 bytes constvec)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1315
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1316 ;; As byte-decompile-bytecode, but updates
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1317 ;; byte-compile-{constants, variables, tag-number}.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1318 ;; If MAKE-SPLICEABLE is true, then `return' opcodes are replaced
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1319 ;; with `goto's destined for the end of the code.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1320 ;; That is for use by the compiler.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1321 ;; If MAKE-SPLICEABLE is nil, we are being called for the disassembler.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1322 ;; In that case, we put a pc value into the list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1323 ;; before each insn (or its label).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1324 (defun byte-decompile-bytecode-1 (bytes constvec &optional make-spliceable)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1325 (let ((length (length bytes))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1326 (ptr 0) optr tags op offset
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1327 ;; tag unused
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1328 lap tmp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1329 endtag
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1330 ;; (retcount 0) unused
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1331 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1332 (while (not (= ptr length))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1333 (or make-spliceable
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1334 (setq lap (cons ptr lap)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1335 (setq op (aref bytes ptr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1336 optr ptr
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1337 offset (disassemble-offset)) ; this does dynamic-scope magic
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1338 (setq op (aref byte-code-vector op))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1339 ;; XEmacs: the next line in FSF 19.30 reads
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1340 ;; (cond ((memq op byte-goto-ops)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1341 ;; see the comment above about byte-rel-goto in XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1342 (cond ((or (memq op byte-goto-ops)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1343 (cond ((memq op byte-rel-goto-ops)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1344 (setq op (aref byte-code-vector
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1345 (- (symbol-value op)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1346 (- byte-rel-goto byte-goto))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1347 (setq offset (+ ptr (- offset 127)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1348 t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1349 ;; it's a pc
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1350 (setq offset
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1351 (cdr (or (assq offset tags)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1352 (car (setq tags
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1353 (cons (cons offset
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1354 (byte-compile-make-tag))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1355 tags)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1356 ((cond ((eq op 'byte-constant2) (setq op 'byte-constant) t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1357 ((memq op byte-constref-ops)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1358 (setq tmp (aref constvec offset)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1359 offset (if (eq op 'byte-constant)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1360 (byte-compile-get-constant tmp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1361 (or (assq tmp byte-compile-variables)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1362 (car (setq byte-compile-variables
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1363 (cons (list tmp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1364 byte-compile-variables)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1365 ((and make-spliceable
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1366 (eq op 'byte-return))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1367 (if (= ptr (1- length))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1368 (setq op nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1369 (setq offset (or endtag (setq endtag (byte-compile-make-tag)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1370 op 'byte-goto))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1371 ;; lap = ( [ (pc . (op . arg)) ]* )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1372 (setq lap (cons (cons optr (cons op (or offset 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1373 lap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1374 (setq ptr (1+ ptr)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1375 ;; take off the dummy nil op that we replaced a trailing "return" with.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1376 (let ((rest lap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1377 (while rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1378 (cond ((numberp (car rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1379 ((setq tmp (assq (car (car rest)) tags))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1380 ;; this addr is jumped to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1381 (setcdr rest (cons (cons nil (cdr tmp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1382 (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1383 (setq tags (delq tmp tags))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1384 (setq rest (cdr rest))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1385 (setq rest (cdr rest))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1386 (if tags (error "optimizer error: missed tags %s" tags))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1387 (if (null (car (cdr (car lap))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1388 (setq lap (cdr lap)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1389 (if endtag
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1390 (setq lap (cons (cons nil endtag) lap)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1391 ;; remove addrs, lap = ( [ (op . arg) | (TAG tagno) ]* )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1392 (mapcar #'(lambda (elt) (if (numberp elt) elt (cdr elt)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1393 (nreverse lap))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1394
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1395
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1396 ;;; peephole optimizer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1397
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1398 (defconst byte-tagref-ops (cons 'TAG byte-goto-ops))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1399
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1400 (defconst byte-conditional-ops
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1401 '(byte-goto-if-nil byte-goto-if-not-nil byte-goto-if-nil-else-pop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1402 byte-goto-if-not-nil-else-pop))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1403
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1404 (defconst byte-after-unbind-ops
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1405 '(byte-constant byte-dup
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1406 byte-symbolp byte-consp byte-stringp byte-listp byte-numberp byte-integerp
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1407 byte-eq byte-not
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1408 byte-cons byte-list1 byte-list2 ; byte-list3 byte-list4
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1409 byte-interactive-p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1410 ;; How about other side-effect-free-ops? Is it safe to move an
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1411 ;; error invocation (such as from nth) out of an unwind-protect?
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1412 ;; No, it is not, because the unwind-protect forms can alter
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1413 ;; the inside of the object to which nth would apply.
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
1414 ;; For the same reason, byte-equal was deleted from this list.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1415 "Byte-codes that can be moved past an unbind.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1416
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1417 (defconst byte-compile-side-effect-and-error-free-ops
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1418 '(byte-constant byte-dup byte-symbolp byte-consp byte-stringp byte-listp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1419 byte-integerp byte-numberp byte-eq byte-equal byte-not byte-car-safe
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1420 byte-cdr-safe byte-cons byte-list1 byte-list2 byte-point byte-point-max
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1421 byte-point-min byte-following-char byte-preceding-char
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1422 byte-current-column byte-eolp byte-eobp byte-bolp byte-bobp
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1423 byte-current-buffer byte-interactive-p))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1424
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1425 (defconst byte-compile-side-effect-free-ops
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
1426 (nconc
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1427 '(byte-varref byte-nth byte-memq byte-car byte-cdr byte-length byte-aref
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1428 byte-symbol-value byte-get byte-concat2 byte-concat3 byte-sub1 byte-add1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1429 byte-eqlsign byte-gtr byte-lss byte-leq byte-geq byte-diff byte-negate
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1430 byte-plus byte-max byte-min byte-mult byte-char-after byte-char-syntax
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1431 byte-buffer-substring byte-string= byte-string< byte-nthcdr byte-elt
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1432 byte-member byte-assq byte-quo byte-rem)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1433 byte-compile-side-effect-and-error-free-ops))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1434
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1435 ;;; This piece of shit is because of the way DEFVAR_BOOL() variables work.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1436 ;;; Consider the code
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1437 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1438 ;;; (defun foo (flag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1439 ;;; (let ((old-pop-ups pop-up-windows)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1440 ;;; (pop-up-windows flag))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1441 ;;; (cond ((not (eq pop-up-windows old-pop-ups))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1442 ;;; (setq old-pop-ups pop-up-windows)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1443 ;;; ...))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1444 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1445 ;;; Uncompiled, old-pop-ups will always be set to nil or t, even if FLAG is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1446 ;;; something else. But if we optimize
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1447 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1448 ;;; varref flag
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1449 ;;; varbind pop-up-windows
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1450 ;;; varref pop-up-windows
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1451 ;;; not
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1452 ;;; to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1453 ;;; varref flag
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1454 ;;; dup
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1455 ;;; varbind pop-up-windows
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1456 ;;; not
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1457 ;;;
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
1458 ;;; we break the program, because it will appear that pop-up-windows and
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1459 ;;; old-pop-ups are not EQ when really they are. So we have to know what
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1460 ;;; the BOOL variables are, and not perform this optimization on them.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1461 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1462
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1463 ;;; This used to hold a large list of boolean variables, which had to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1464 ;;; be updated every time a new DEFVAR_BOOL is added, making it very
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1465 ;;; hard to maintain. Such a list is not necessary under XEmacs,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1466 ;;; where we can use `built-in-variable-type' to query for boolean
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1467 ;;; variables.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1468
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1469 ;(defconst byte-boolean-vars
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1470 ; '(abbrev-all-caps purify-flag find-file-compare-truenames
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1471 ; find-file-use-truenames delete-auto-save-files byte-metering-on
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1472 ; x-seppuku-on-epipe zmacs-regions zmacs-region-active-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1473 ; zmacs-region-stays atomic-extent-goto-char-p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1474 ; suppress-early-error-handler-backtrace noninteractive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1475 ; inhibit-early-packages inhibit-autoloads debug-paths
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1476 ; inhibit-site-lisp debug-on-quit debug-on-next-call
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1477 ; modifier-keys-are-sticky x-allow-sendevents
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1478 ; mswindows-dynamic-frame-resize focus-follows-mouse
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1479 ; inhibit-input-event-recording enable-multibyte-characters
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1480 ; disable-auto-save-when-buffer-shrinks
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1481 ; allow-deletion-of-last-visible-frame indent-tabs-mode
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1482 ; load-in-progress load-warn-when-source-newer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1483 ; load-warn-when-source-only load-ignore-elc-files
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1484 ; load-force-doc-strings fail-on-bucky-bit-character-escapes
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1485 ; popup-menu-titles menubar-show-keybindings completion-ignore-case
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1486 ; canna-empty-info canna-through-info canna-underline
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1487 ; canna-inhibit-hankakukana enable-multibyte-characters
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1488 ; re-short-flag x-handle-non-fully-specified-fonts
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1489 ; print-escape-newlines print-readably delete-exited-processes
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1490 ; windowed-process-io visible-bell no-redraw-on-reenter
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1491 ; cursor-in-echo-area inhibit-warning-display
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1492 ; column-number-start-at-one parse-sexp-ignore-comments
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1493 ; words-include-escapes scroll-on-clipped-lines)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1494 ; "DEFVAR_BOOL variables. Giving these any non-nil value sets them to t.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1495 ;If this does not enumerate all DEFVAR_BOOL variables, the byte-optimizer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1496 ;may generate incorrect code.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1497
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1498 (defun byte-optimize-lapcode (lap &optional for-effect)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1499 "Simple peephole optimizer. LAP is both modified and returned."
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1500 (let (lap0
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1501 lap1
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1502 lap2
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1503 variable-frequency
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1504 (keep-going 'first-time)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1505 (add-depth 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1506 rest tmp tmp2 tmp3
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1507 (side-effect-free (if byte-compile-delete-errors
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1508 byte-compile-side-effect-free-ops
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1509 byte-compile-side-effect-and-error-free-ops)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1510 (while keep-going
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1511 (or (eq keep-going 'first-time)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1512 (byte-compile-log-lap " ---- next pass"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1513 (setq rest lap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1514 keep-going nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1515 (while rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1516 (setq lap0 (car rest)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1517 lap1 (nth 1 rest)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1518 lap2 (nth 2 rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1519
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1520 ;; You may notice that sequences like "dup varset discard" are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1521 ;; optimized but sequences like "dup varset TAG1: discard" are not.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1522 ;; You may be tempted to change this; resist that temptation.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1523 (cond ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1524 ;; <side-effect-free> pop --> <deleted>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1525 ;; ...including:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1526 ;; const-X pop --> <deleted>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1527 ;; varref-X pop --> <deleted>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1528 ;; dup pop --> <deleted>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1529 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1530 ((and (eq 'byte-discard (car lap1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1531 (memq (car lap0) side-effect-free))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1532 (setq keep-going t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1533 (setq tmp (aref byte-stack+-info (symbol-value (car lap0))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1534 (setq rest (cdr rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1535 (cond ((= tmp 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1536 (byte-compile-log-lap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1537 " %s discard\t-->\t<deleted>" lap0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1538 (setq lap (delq lap0 (delq lap1 lap))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1539 ((= tmp 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1540 (byte-compile-log-lap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1541 " %s discard\t-->\t<deleted> discard" lap0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1542 (setq lap (delq lap0 lap)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1543 ((= tmp -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1544 (byte-compile-log-lap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1545 " %s discard\t-->\tdiscard discard" lap0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1546 (setcar lap0 'byte-discard)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1547 (setcdr lap0 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1548 ((error "Optimizer error: too much on the stack"))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1549 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1550 ;; goto*-X X: --> X:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1551 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1552 ((and (memq (car lap0) byte-goto-ops)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1553 (eq (cdr lap0) lap1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1554 (cond ((eq (car lap0) 'byte-goto)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1555 (setq lap (delq lap0 lap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1556 (setq tmp "<deleted>"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1557 ((memq (car lap0) byte-goto-always-pop-ops)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1558 (setcar lap0 (setq tmp 'byte-discard))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1559 (setcdr lap0 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1560 ((error "Depth conflict at tag %d" (nth 2 lap0))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1561 (and (memq byte-optimize-log '(t byte))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1562 (byte-compile-log " (goto %s) %s:\t-->\t%s %s:"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1563 (nth 1 lap1) (nth 1 lap1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1564 tmp (nth 1 lap1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1565 (setq keep-going t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1566 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1567 ;; varset-X varref-X --> dup varset-X
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1568 ;; varbind-X varref-X --> dup varbind-X
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1569 ;; const/dup varset-X varref-X --> const/dup varset-X const/dup
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1570 ;; const/dup varbind-X varref-X --> const/dup varbind-X const/dup
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1571 ;; The latter two can enable other optimizations.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1572 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1573 ((and (eq 'byte-varref (car lap2))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1574 (eq (cdr lap1) (cdr lap2))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1575 (memq (car lap1) '(byte-varset byte-varbind)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1576 (if (and (setq tmp (eq (built-in-variable-type (car (cdr lap2)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1577 'boolean))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1578 (not (eq (car lap0) 'byte-constant)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1579 nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1580 (setq keep-going t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1581 (if (memq (car lap0) '(byte-constant byte-dup))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1582 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1583 (setq tmp (if (or (not tmp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1584 (memq (car (cdr lap0)) '(nil t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1585 (cdr lap0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1586 (byte-compile-get-constant t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1587 (byte-compile-log-lap " %s %s %s\t-->\t%s %s %s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1588 lap0 lap1 lap2 lap0 lap1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1589 (cons (car lap0) tmp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1590 (setcar lap2 (car lap0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1591 (setcdr lap2 tmp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1592 (byte-compile-log-lap " %s %s\t-->\tdup %s" lap1 lap2 lap1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1593 (setcar lap2 (car lap1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1594 (setcar lap1 'byte-dup)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1595 (setcdr lap1 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1596 ;; The stack depth gets locally increased, so we will
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1597 ;; increase maxdepth in case depth = maxdepth here.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1598 ;; This can cause the third argument to byte-code to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1599 ;; be larger than necessary.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1600 (setq add-depth 1))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1601 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1602 ;; dup varset-X discard --> varset-X
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1603 ;; dup varbind-X discard --> varbind-X
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1604 ;; (the varbind variant can emerge from other optimizations)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1605 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1606 ((and (eq 'byte-dup (car lap0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1607 (eq 'byte-discard (car lap2))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1608 (memq (car lap1) '(byte-varset byte-varbind)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1609 (byte-compile-log-lap " dup %s discard\t-->\t%s" lap1 lap1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1610 (setq keep-going t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1611 rest (cdr rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1612 (setq lap (delq lap0 (delq lap2 lap))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1613 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1614 ;; not goto-X-if-nil --> goto-X-if-non-nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1615 ;; not goto-X-if-non-nil --> goto-X-if-nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1616 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1617 ;; it is wrong to do the same thing for the -else-pop variants.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1618 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1619 ((and (eq 'byte-not (car lap0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1620 (or (eq 'byte-goto-if-nil (car lap1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1621 (eq 'byte-goto-if-not-nil (car lap1))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1622 (byte-compile-log-lap " not %s\t-->\t%s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1623 lap1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1624 (cons
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1625 (if (eq (car lap1) 'byte-goto-if-nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1626 'byte-goto-if-not-nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1627 'byte-goto-if-nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1628 (cdr lap1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1629 (setcar lap1 (if (eq (car lap1) 'byte-goto-if-nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1630 'byte-goto-if-not-nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1631 'byte-goto-if-nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1632 (setq lap (delq lap0 lap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1633 (setq keep-going t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1634 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1635 ;; goto-X-if-nil goto-Y X: --> goto-Y-if-non-nil X:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1636 ;; goto-X-if-non-nil goto-Y X: --> goto-Y-if-nil X:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1637 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1638 ;; it is wrong to do the same thing for the -else-pop variants.
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
1639 ;;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1640 ((and (or (eq 'byte-goto-if-nil (car lap0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1641 (eq 'byte-goto-if-not-nil (car lap0))) ; gotoX
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1642 (eq 'byte-goto (car lap1)) ; gotoY
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1643 (eq (cdr lap0) lap2)) ; TAG X
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1644 (let ((inverse (if (eq 'byte-goto-if-nil (car lap0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1645 'byte-goto-if-not-nil 'byte-goto-if-nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1646 (byte-compile-log-lap " %s %s %s:\t-->\t%s %s:"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1647 lap0 lap1 lap2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1648 (cons inverse (cdr lap1)) lap2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1649 (setq lap (delq lap0 lap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1650 (setcar lap1 inverse)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1651 (setq keep-going t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1652 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1653 ;; const goto-if-* --> whatever
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1654 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1655 ((and (eq 'byte-constant (car lap0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1656 (memq (car lap1) byte-conditional-ops))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1657 (cond ((if (or (eq (car lap1) 'byte-goto-if-nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1658 (eq (car lap1) 'byte-goto-if-nil-else-pop))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1659 (car (cdr lap0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1660 (not (car (cdr lap0))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1661 (byte-compile-log-lap " %s %s\t-->\t<deleted>"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1662 lap0 lap1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1663 (setq rest (cdr rest)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1664 lap (delq lap0 (delq lap1 lap))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1665 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1666 (if (memq (car lap1) byte-goto-always-pop-ops)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1667 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1668 (byte-compile-log-lap " %s %s\t-->\t%s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1669 lap0 lap1 (cons 'byte-goto (cdr lap1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1670 (setq lap (delq lap0 lap)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1671 (byte-compile-log-lap " %s %s\t-->\t%s" lap0 lap1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1672 (cons 'byte-goto (cdr lap1))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1673 (setcar lap1 'byte-goto)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1674 (setq keep-going t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1675 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1676 ;; varref-X varref-X --> varref-X dup
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1677 ;; varref-X [dup ...] varref-X --> varref-X [dup ...] dup
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1678 ;; We don't optimize the const-X variations on this here,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1679 ;; because that would inhibit some goto optimizations; we
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1680 ;; optimize the const-X case after all other optimizations.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1681 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1682 ((and (eq 'byte-varref (car lap0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1683 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1684 (setq tmp (cdr rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1685 (while (eq (car (car tmp)) 'byte-dup)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1686 (setq tmp (cdr tmp)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1687 t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1688 (eq (cdr lap0) (cdr (car tmp)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1689 (eq 'byte-varref (car (car tmp))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1690 (if (memq byte-optimize-log '(t byte))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1691 (let ((str ""))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1692 (setq tmp2 (cdr rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1693 (while (not (eq tmp tmp2))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1694 (setq tmp2 (cdr tmp2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1695 str (concat str " dup")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1696 (byte-compile-log-lap " %s%s %s\t-->\t%s%s dup"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1697 lap0 str lap0 lap0 str)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1698 (setq keep-going t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1699 (setcar (car tmp) 'byte-dup)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1700 (setcdr (car tmp) 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1701 (setq rest tmp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1702 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1703 ;; TAG1: TAG2: --> TAG1: <deleted>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1704 ;; (and other references to TAG2 are replaced with TAG1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1705 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1706 ((and (eq (car lap0) 'TAG)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1707 (eq (car lap1) 'TAG))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1708 (and (memq byte-optimize-log '(t byte))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1709 (byte-compile-log " adjacent tags %d and %d merged"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1710 (nth 1 lap1) (nth 1 lap0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1711 (setq tmp3 lap)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1712 (while (setq tmp2 (rassq lap0 tmp3))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1713 (setcdr tmp2 lap1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1714 (setq tmp3 (cdr (memq tmp2 tmp3))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1715 (setq lap (delq lap0 lap)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1716 keep-going t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1717 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1718 ;; unused-TAG: --> <deleted>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1719 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1720 ((and (eq 'TAG (car lap0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1721 (not (rassq lap0 lap)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1722 (and (memq byte-optimize-log '(t byte))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1723 (byte-compile-log " unused tag %d removed" (nth 1 lap0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1724 (setq lap (delq lap0 lap)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1725 keep-going t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1726 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1727 ;; goto ... --> goto <delete until TAG or end>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1728 ;; return ... --> return <delete until TAG or end>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1729 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1730 ((and (memq (car lap0) '(byte-goto byte-return))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1731 (not (memq (car lap1) '(TAG nil))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1732 (setq tmp rest)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1733 (let ((i 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1734 (opt-p (memq byte-optimize-log '(t lap)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1735 str deleted)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1736 (while (and (setq tmp (cdr tmp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1737 (not (eq 'TAG (car (car tmp)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1738 (if opt-p (setq deleted (cons (car tmp) deleted)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1739 str (concat str " %s")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1740 i (1+ i))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1741 (if opt-p
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
1742 (let ((tagstr
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1743 (if (eq 'TAG (car (car tmp)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1744 (format "%d:" (car (cdr (car tmp))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1745 (or (car tmp) ""))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1746 (if (< i 6)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1747 (apply 'byte-compile-log-lap-1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1748 (concat " %s" str
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1749 " %s\t-->\t%s <deleted> %s")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1750 lap0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1751 (nconc (nreverse deleted)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1752 (list tagstr lap0 tagstr)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1753 (byte-compile-log-lap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1754 " %s <%d unreachable op%s> %s\t-->\t%s <deleted> %s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1755 lap0 i (if (= i 1) "" "s")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1756 tagstr lap0 tagstr))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1757 (rplacd rest tmp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1758 (setq keep-going t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1759 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1760 ;; <safe-op> unbind --> unbind <safe-op>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1761 ;; (this may enable other optimizations.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1762 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1763 ((and (eq 'byte-unbind (car lap1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1764 (memq (car lap0) byte-after-unbind-ops))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1765 (byte-compile-log-lap " %s %s\t-->\t%s %s" lap0 lap1 lap1 lap0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1766 (setcar rest lap1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1767 (setcar (cdr rest) lap0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1768 (setq keep-going t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1769 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1770 ;; varbind-X unbind-N --> discard unbind-(N-1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1771 ;; save-excursion unbind-N --> unbind-(N-1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1772 ;; save-restriction unbind-N --> unbind-(N-1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1773 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1774 ((and (eq 'byte-unbind (car lap1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1775 (memq (car lap0) '(byte-varbind byte-save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1776 byte-save-restriction))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1777 (< 0 (cdr lap1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1778 (if (zerop (setcdr lap1 (1- (cdr lap1))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1779 (delq lap1 rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1780 (if (eq (car lap0) 'byte-varbind)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1781 (setcar rest (cons 'byte-discard 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1782 (setq lap (delq lap0 lap)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1783 (byte-compile-log-lap " %s %s\t-->\t%s %s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1784 lap0 (cons (car lap1) (1+ (cdr lap1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1785 (if (eq (car lap0) 'byte-varbind)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1786 (car rest)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1787 (car (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1788 (if (and (/= 0 (cdr lap1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1789 (eq (car lap0) 'byte-varbind))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1790 (car (cdr rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1791 ""))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1792 (setq keep-going t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1793 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1794 ;; goto*-X ... X: goto-Y --> goto*-Y
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1795 ;; goto-X ... X: return --> return
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1796 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1797 ((and (memq (car lap0) byte-goto-ops)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1798 (memq (car (setq tmp (nth 1 (memq (cdr lap0) lap))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1799 '(byte-goto byte-return)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1800 (cond ((and (not (eq tmp lap0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1801 (or (eq (car lap0) 'byte-goto)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1802 (eq (car tmp) 'byte-goto)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1803 (byte-compile-log-lap " %s [%s]\t-->\t%s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1804 (car lap0) tmp tmp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1805 (if (eq (car tmp) 'byte-return)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1806 (setcar lap0 'byte-return))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1807 (setcdr lap0 (cdr tmp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1808 (setq keep-going t))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1809 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1810 ;; goto-*-else-pop X ... X: goto-if-* --> whatever
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1811 ;; goto-*-else-pop X ... X: discard --> whatever
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1812 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1813 ((and (memq (car lap0) '(byte-goto-if-nil-else-pop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1814 byte-goto-if-not-nil-else-pop))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1815 (memq (car (car (setq tmp (cdr (memq (cdr lap0) lap)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1816 (eval-when-compile
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1817 (cons 'byte-discard byte-conditional-ops)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1818 (not (eq lap0 (car tmp))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1819 (setq tmp2 (car tmp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1820 (setq tmp3 (assq (car lap0) '((byte-goto-if-nil-else-pop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1821 byte-goto-if-nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1822 (byte-goto-if-not-nil-else-pop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1823 byte-goto-if-not-nil))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1824 (if (memq (car tmp2) tmp3)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1825 (progn (setcar lap0 (car tmp2))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1826 (setcdr lap0 (cdr tmp2))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1827 (byte-compile-log-lap " %s-else-pop [%s]\t-->\t%s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1828 (car lap0) tmp2 lap0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1829 ;; Get rid of the -else-pop's and jump one step further.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1830 (or (eq 'TAG (car (nth 1 tmp)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1831 (setcdr tmp (cons (byte-compile-make-tag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1832 (cdr tmp))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1833 (byte-compile-log-lap " %s [%s]\t-->\t%s <skip>"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1834 (car lap0) tmp2 (nth 1 tmp3))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1835 (setcar lap0 (nth 1 tmp3))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1836 (setcdr lap0 (nth 1 tmp)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1837 (setq keep-going t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1838 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1839 ;; const goto-X ... X: goto-if-* --> whatever
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1840 ;; const goto-X ... X: discard --> whatever
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1841 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1842 ((and (eq (car lap0) 'byte-constant)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1843 (eq (car lap1) 'byte-goto)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1844 (memq (car (car (setq tmp (cdr (memq (cdr lap1) lap)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1845 (eval-when-compile
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1846 (cons 'byte-discard byte-conditional-ops)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1847 (not (eq lap1 (car tmp))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1848 (setq tmp2 (car tmp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1849 (cond ((memq (car tmp2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1850 (if (null (car (cdr lap0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1851 '(byte-goto-if-nil byte-goto-if-nil-else-pop)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1852 '(byte-goto-if-not-nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1853 byte-goto-if-not-nil-else-pop)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1854 (byte-compile-log-lap " %s goto [%s]\t-->\t%s %s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1855 lap0 tmp2 lap0 tmp2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1856 (setcar lap1 (car tmp2))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1857 (setcdr lap1 (cdr tmp2))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1858 ;; Let next step fix the (const,goto-if*) sequence.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1859 (setq rest (cons nil rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1860 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1861 ;; Jump one step further
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1862 (byte-compile-log-lap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1863 " %s goto [%s]\t-->\t<deleted> goto <skip>"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1864 lap0 tmp2)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1865 (or (eq 'TAG (car (nth 1 tmp)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1866 (setcdr tmp (cons (byte-compile-make-tag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1867 (cdr tmp))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1868 (setcdr lap1 (car (cdr tmp)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1869 (setq lap (delq lap0 lap))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1870 (setq keep-going t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1871 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1872 ;; X: varref-Y ... varset-Y goto-X -->
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1873 ;; X: varref-Y Z: ... dup varset-Y goto-Z
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1874 ;; (varset-X goto-BACK, BACK: varref-X --> copy the varref down.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1875 ;; (This is so usual for while loops that it is worth handling).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1876 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1877 ((and (eq (car lap1) 'byte-varset)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1878 (eq (car lap2) 'byte-goto)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1879 (not (memq (cdr lap2) rest)) ;Backwards jump
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1880 (eq (car (car (setq tmp (cdr (memq (cdr lap2) lap)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1881 'byte-varref)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1882 (eq (cdr (car tmp)) (cdr lap1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1883 (not (eq (built-in-variable-type (car (cdr lap1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1884 'boolean)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1885 ;;(byte-compile-log-lap " Pulled %s to end of loop" (car tmp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1886 (let ((newtag (byte-compile-make-tag)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1887 (byte-compile-log-lap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1888 " %s: %s ... %s %s\t-->\t%s: %s %s: ... %s %s %s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1889 (nth 1 (cdr lap2)) (car tmp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1890 lap1 lap2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1891 (nth 1 (cdr lap2)) (car tmp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1892 (nth 1 newtag) 'byte-dup lap1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1893 (cons 'byte-goto newtag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1894 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1895 (setcdr rest (cons (cons 'byte-dup 0) (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1896 (setcdr tmp (cons (setcdr lap2 newtag) (cdr tmp))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1897 (setq add-depth 1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1898 (setq keep-going t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1899 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1900 ;; goto-X Y: ... X: goto-if*-Y --> goto-if-not-*-X+1 Y:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1901 ;; (This can pull the loop test to the end of the loop)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1902 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1903 ((and (eq (car lap0) 'byte-goto)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1904 (eq (car lap1) 'TAG)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1905 (eq lap1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1906 (cdr (car (setq tmp (cdr (memq (cdr lap0) lap))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1907 (memq (car (car tmp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1908 '(byte-goto byte-goto-if-nil byte-goto-if-not-nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1909 byte-goto-if-nil-else-pop)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1910 ;; (byte-compile-log-lap " %s %s, %s %s --> moved conditional"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1911 ;; lap0 lap1 (cdr lap0) (car tmp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1912 (let ((newtag (byte-compile-make-tag)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1913 (byte-compile-log-lap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1914 "%s %s: ... %s: %s\t-->\t%s ... %s:"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1915 lap0 (nth 1 lap1) (nth 1 (cdr lap0)) (car tmp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1916 (cons (cdr (assq (car (car tmp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1917 '((byte-goto-if-nil . byte-goto-if-not-nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1918 (byte-goto-if-not-nil . byte-goto-if-nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1919 (byte-goto-if-nil-else-pop .
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1920 byte-goto-if-not-nil-else-pop)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1921 (byte-goto-if-not-nil-else-pop .
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1922 byte-goto-if-nil-else-pop))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1923 newtag)
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 434
diff changeset
1924
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1925 (nth 1 newtag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1926 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1927 (setcdr tmp (cons (setcdr lap0 newtag) (cdr tmp)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1928 (if (eq (car (car tmp)) 'byte-goto-if-nil-else-pop)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1929 ;; We can handle this case but not the -if-not-nil case,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1930 ;; because we won't know which non-nil constant to push.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1931 (setcdr rest (cons (cons 'byte-constant
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1932 (byte-compile-get-constant nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1933 (cdr rest))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1934 (setcar lap0 (nth 1 (memq (car (car tmp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1935 '(byte-goto-if-nil-else-pop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1936 byte-goto-if-not-nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1937 byte-goto-if-nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1938 byte-goto-if-not-nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1939 byte-goto byte-goto))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1940 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1941 (setq keep-going t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1942 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1943 (setq rest (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1944 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1945 ;; Cleanup stage:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1946 ;; Rebuild byte-compile-constants / byte-compile-variables.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1947 ;; Simple optimizations that would inhibit other optimizations if they
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1948 ;; were done in the optimizing loop, and optimizations which there is no
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1949 ;; need to do more than once.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1950 (setq byte-compile-constants nil
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1951 byte-compile-variables nil
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1952 variable-frequency (make-hash-table :test 'eq))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1953 (setq rest lap)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1954 (while rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1955 (setq lap0 (car rest)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1956 lap1 (nth 1 rest))
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1957 (case (car lap0)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1958 ((byte-varref byte-varset byte-varbind)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1959 (incf (gethash (cdr lap0) variable-frequency 0))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1960 (unless (memq (cdr lap0) byte-compile-variables)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1961 (push (cdr lap0) byte-compile-variables)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1962 ((byte-constant)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1963 (unless (memq (cdr lap0) byte-compile-constants)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1964 (push (cdr lap0) byte-compile-constants))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1965 (cond (;;
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1966 ;; const-C varset-X const-C --> const-C dup varset-X
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1967 ;; const-C varbind-X const-C --> const-C dup varbind-X
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1968 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1969 (and (eq (car lap0) 'byte-constant)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1970 (eq (car (nth 2 rest)) 'byte-constant)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1971 (eq (cdr lap0) (cdr (nth 2 rest)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1972 (memq (car lap1) '(byte-varbind byte-varset)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1973 (byte-compile-log-lap " %s %s %s\t-->\t%s dup %s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1974 lap0 lap1 lap0 lap0 lap1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1975 (setcar (cdr (cdr rest)) (cons (car lap1) (cdr lap1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1976 (setcar (cdr rest) (cons 'byte-dup 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1977 (setq add-depth 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1978 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1979 ;; const-X [dup/const-X ...] --> const-X [dup ...] dup
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1980 ;; varref-X [dup/varref-X ...] --> varref-X [dup ...] dup
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1981 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1982 ((memq (car lap0) '(byte-constant byte-varref))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1983 (setq tmp rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1984 tmp2 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1985 (while (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1986 (while (eq 'byte-dup (car (car (setq tmp (cdr tmp))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1987 (and (eq (cdr lap0) (cdr (car tmp)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1988 (eq (car lap0) (car (car tmp)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1989 (setcar tmp (cons 'byte-dup 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1990 (setq tmp2 t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1991 (if tmp2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1992 (byte-compile-log-lap
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1993 " %s [dup/%s]...\t-->\t%s dup..." lap0 lap0 lap0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1994 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1995 ;; unbind-N unbind-M --> unbind-(N+M)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1996 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1997 ((and (eq 'byte-unbind (car lap0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1998 (eq 'byte-unbind (car lap1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1999 (byte-compile-log-lap " %s %s\t-->\t%s" lap0 lap1
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2000 (cons 'byte-unbind
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2001 (+ (cdr lap0) (cdr lap1))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2002 (setq keep-going t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2003 (setq lap (delq lap0 lap))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2004 (setcdr lap1 (+ (cdr lap1) (cdr lap0))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2005 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2006 (setq rest (cdr rest)))
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2007 ;; Since the first 6 entries of the compiled-function constants
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2008 ;; vector are most efficient for varref/set/bind ops, we sort by
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2009 ;; reference count. This generates maximally space efficient and
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2010 ;; pretty time-efficient byte-code. See `byte-compile-constants-vector'.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2011 (setq byte-compile-variables
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2012 (sort byte-compile-variables
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2013 #'(lambda (v1 v2)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2014 (< (gethash v1 variable-frequency)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2015 (gethash v2 variable-frequency)))))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2016 ;; Another hack - put the most used variable in position 6, for
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2017 ;; better locality of reference with adjoining constants.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2018 (let ((tail (last byte-compile-variables 6)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2019 (setq byte-compile-variables
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2020 (append (nbutlast byte-compile-variables 6)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
2021 (nreverse tail))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2022 (setq byte-compile-maxdepth (+ byte-compile-maxdepth add-depth)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2023 lap)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2024
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2025 (provide 'byte-optimize)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2026
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2027
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2028 ;; To avoid "lisp nesting exceeds max-lisp-eval-depth" when this file compiles
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2029 ;; itself, compile some of its most used recursive functions (at load time).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2030 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2031 (eval-when-compile
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2032 (or (compiled-function-p (symbol-function 'byte-optimize-form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2033 (assq 'byte-code (symbol-function 'byte-optimize-form))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2034 (let ((byte-optimize nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2035 (byte-compile-warnings nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2036 (mapcar
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2037 #'(lambda (x)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2038 (or noninteractive (message "compiling %s..." x))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2039 (byte-compile x)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2040 (or noninteractive (message "compiling %s...done" x)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2041 '(byte-optimize-form
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2042 byte-optimize-body
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2043 byte-optimize-predicate
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2044 byte-optimize-binary-predicate
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2045 ;; Inserted some more than necessary, to speed it up.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2046 byte-optimize-form-code-walker
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2047 byte-optimize-lapcode))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2048 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2049
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2050 ;;; byte-optimize.el ends here