summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/byte-opt.el
Commit message (Collapse)AuthorAgeFilesLines
...
* Don't propagate lexical variables into inlined functionsMattias Engdegård2021-05-271-1/+4
| | | | | | | | | | | | | | | | Functions compiled when inlined (thus from inside the optimiser) mustn't retain the lexical environment of the caller or there will be tears. See discussion at https://lists.gnu.org/archive/html/emacs-devel/2021-05/msg01227.html . Bug found by Stefan Monnier. * lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand): Bind byte-optimize--lexvars to nil when re-entering the compiler recursively. * test/lisp/emacs-lisp/bytecomp-resources/bc-test-alpha.el: * test/lisp/emacs-lisp/bytecomp-resources/bc-test-beta.el: New files. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-defsubst): New test.
* * lisp/emacs-lisp/byte-opt.el: Make the build more reproducibleStefan Monnier2021-05-251-27/+13
| | | | | | (byte-compile-inline-expand): When inlining code from another file, always inline the byte-code version of the function. (byte-optimize--pcase): Simplify edebug spec.
* Optimize calls to 'eql', 'memql' and similar for fixnums.Philipp Stephani2021-05-161-6/+20
| | | | | | | | | | | | | It's good practice to compare integers using 'eql' because two bignum objects representing the same integer might not be 'eq'. However, 'eql' is slower and doesn't have its own byte code. Therefore, replace it with 'eq' if one argument is guaranteed to be a fixnum on all platforms. * lisp/emacs-lisp/byte-opt.el (byte-optimize--fixnump): New helper function. (byte-optimize-equal, byte-optimize-member, byte-optimize-assoc): Use it to optimize 'eql' etc. to 'eq' if it will always compare fixnums.
* Merge branch 'feature/native-comp' into into trunkAndrea Corallo2021-04-251-0/+1
|\
| * Merge remote-tracking branch 'savannah/master' into native-compAndrea Corallo2021-04-131-2/+8
| |\
| * | * lisp/emacs-lisp/byte-opt.el: Fix native re-compilation (bug#47161).Eli Zaretskii2021-03-151-0/+1
| | |
* | | Don't erroneously declare `mark` as error-freeMattias Engdegård2021-04-211-2/+2
| |/ |/| | | | | | | | | * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns) (side-effect-and-error-free-fns): `mark` is side-effect-free but not error-free.
* | Fix condition-case optimiser bugMattias Engdegård2021-04-091-2/+8
|/ | | | | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Don't perform incorrect optimisations when a condition-case variable shadows another lexical variable. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases): New test case.
* Mark string predicates side-effect-freeMattias Engdegård2021-03-101-0/+2
| | | | | | * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Add string>, string-greaterp, string-empty-p, string-prefix-p, string-suffix-p and string-blank-p, all recently marked pure.
* Don't ignore lexically-bound variables in a defvar (bug#46912)Pip Cet2021-03-051-3/+6
| | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Walk the value form of a defvar.
* Declare more string predicates as pureMattias Engdegård2021-02-281-1/+2
| | | | | | * lisp/emacs-lisp/byte-opt.el (pure-fns): Treat string>, string-greaterp, string-empty-p, string-blank-p, string-prefix-p and string-suffix-p as pure functions in the compiler.
* Add the `always' functionLars Ingebrigtsen2021-02-201-1/+1
| | | | | | | | * doc/lispref/functions.texi (Calling Functions): Document it. * lisp/subr.el (always): New function. * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Mark it as side effect free.
* Simplify expression in byte-code decompilerMattias Engdegård2021-02-121-4/+1
| | | | | * lisp/emacs-lisp/byte-opt.el (byte-decompile-bytecode-1): Replace roundabout expression with what it essentially does.
* byte-opt.el: More concise expressionMattias Engdegård2021-02-121-10/+9
| | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Refactor `setq` clause.
* Avoid traversing dead `if` branches in bytecode optimiserMattias Engdegård2021-02-121-32/+32
| | | | | | | | | | | | | | | | | | | | There is no point in traversing conditional branches that are statically known never to be executed. This saves some optimisation effort, but more importantly prevents variable assignments and references in those branches from blocking effective constant propagation. Also attempt to traverse as much as possible in an unconditional context, which enables constant-propagation through (linear) assignments. * lisp/emacs-lisp/byte-opt.el (byte-optimize-form): Rewrite the (tail) recursion into an explicit loop. Normalise a return value of (quote nil) to nil, for easier subsequent optimisations. * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Don't traverse dead `if` branches. Use unconditional traversion context when possible.
* Fix local defvar scoping error (bug#46387)Mattias Engdegård2021-02-101-2/+2
| | | | | | | | | | | | This bug was introduced by the lexical variable constant propagation mechanism. It was discovered by Michael Heerdegen. * lisp/emacs-lisp/byte-opt.el (byte-optimize-let-form) (byte-optimize-body): Let the effects of a local defvar declaration be scoped by let and let*, not any arbitrary Lisp expression body (such as progn). * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--get-vars) (bytecomp-local-defvar): New test.
* * lisp/emacs-lisp/byte-opt.el (byte-optimize--pcase): New macroStefan Monnier2021-02-091-20/+50
| | | | (byte-optimize-form-code-walker): Use it.
* * lisp/emacs-lisp/macroexp.el: Break cycle with bytecomp/byte-optStefan Monnier2021-02-091-70/+2
| | | | | | | | | | | | | | | | | The recent change in macroexp triggered a cyclic dependency error during eager macroexpansion when neither `bytecomp` nor `byte-opt` had been byte-compiled yet. This fixes it by moving the offending function to macroexp.el. * lisp/emacs-lisp/macroexp.el (macroexp--unfold-lambda): Move from byte-opt.el and rename. (macroexp--expand-all): Use it. * lisp/emacs-lisp/byte-opt.el (byte-compile-unfold-lambda): Move to macroexp.el. (byte-compile-inline-expand, byte-optimize-form-code-walker): * lisp/emacs-lisp/bytecomp.el (byte-compile-form): Use `macroexp--unfold-lambda` instead.
* ; * lisp/emacs-lisp/byte-opt.el: improved commentMattias Engdegård2021-02-071-1/+1
|
* ; Improved commentary in the variable constprop mechanismMattias Engdegård2021-02-071-8/+13
| | | | | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize--lexvars) (byte-optimize--vars-outside-condition) (byte-optimize-form-code-walker, byte-optimize-let-form): Clarify various aspects in the variable constant-propagation code, as kindly pointed out by Stefan Monnier.
* Constprop of lexical variablesMattias Engdegård2021-02-061-70/+244
| | | | | | | | | | | | | | | | | | | | | | | | | | | Lexical variables bound to a constant value (symbol, number or string) are substituted at their point of use and the variable then eliminated if possible. Example: (let ((x (+ 2 3))) (f x)) => (f 5) This reduces code size, eliminates stack operations, and enables further optimisations. The implementation is conservative, and is strongly curtailed by the presence of variable mutation, conditions and loops. * lisp/emacs-lisp/byte-opt.el (byte-optimize-enable-variable-constprop) (byte-optimize-warn-eliminated-variable): New constants. (byte-optimize--lexvars, byte-optimize--vars-outside-condition) (byte-optimize--vars-outside-loop, byte-optimize--dynamic-vars): New dynamic variables. (byte-optimize--substitutable-p, byte-optimize-let-form): New functions. (byte-optimize-form-code-walker): Adapt clauses for variable constprop, and add clauses for 'setq' and 'defvar'. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-test-var) (bytecomp-test-get-var, bytecomp-test-identity) (byte-opt-testsuite-arith-data): Add test cases.
* Fix spurious "Lexical argument shadows the dynamic variable" due to inliningStefan Monnier2021-01-211-2/+4
| | | | | | | | | | | | | | | | | | | Before this patch doing: rm lisp/calendar/calendar.elc make lisp/calendar/cal-hebrew.elc would spew out lots of spurious such warnings about a `date` argument, pointing to code which has no `date` argument in sight. This was because that code had calls to inlinable functions (taking a `date` argument) defined in `calendar.el`, and while `date` is a normal lexical var at the site of those functions' definitions, it was declared as dynbound at the call site. * lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand): Don't impose our local context onto the inlined function. * test/lisp/emacs-lisp/bytecomp-tests.el: Add matching test.
* * lisp/emacs-lisp/byte-opt.el (byte-optimize-lapcode): Add 2 new optsStefan Monnier2021-01-201-0/+31
| | | | | | | | | | | | | | | | This introduces two new optimizations. They're designed for code like (while (let (...) (if ... (progn blabla t) (progn blabla nil))) ...) and they allow the elimination of the test internal to `while` since we can immediately know when we return `t` or `nil` what the result of the test will be. `cl-labels` tends to generate this kind of code when it applies the tail-call optimization.
* * lisp/emacs-lisp/byte-opt.el (byte-optimize-lapcode): Move some opts.Stefan Monnier2021-01-201-49/+50
| | | | | | | This moves two optimizations from the final pass to the main loop. Both may enable further optimizations (and the second can be applied repeatedly but "from the end", so the loop in the final pass only gets to apply it once).
* * lisp/emacs-lisp/byte-opt.el (byte-optimize-lapcode): Re-indentStefan Monnier2021-01-201-457/+457
|
* * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Use pcaseStefan Monnier2021-01-161-176/+175
|
* Update copyright year to 2021Paul Eggert2021-01-011-1/+1
| | | | Run "TZ=UTC0 admin/update-copyright".
* Add new predicates for sequence lengthsLars Ingebrigtsen2020-12-271-1/+3
| | | | | | | | | | | | | * doc/lispref/sequences.texi (Sequence Functions): Document them. * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Mark them as side-effect-free. * lisp/emacs-lisp/shortdoc.el (list): Mention them. * src/fns.c (Flength): Mention them in the doc string. (length_internal): New function. (Flength_less, Flength_greater, Flength_equal): New defuns. (syms_of_fns): Sym them.
* Don't quote lambdas in several placesStefan Kangas2020-11-121-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * lisp/allout-widgets.el (allout-widgets-adjusting-message) (allout-widgets-exposure-change-processor) (allout-widgets-count-buttons-in-region): * lisp/ansi-color.el (ansi-color-make-color-map): * lisp/case-table.el (describe-buffer-case-table): * lisp/emacs-lisp/byte-opt.el (byte-decompile-bytecode-1): * lisp/gnus/gnus-agent.el (gnus-agent-regenerate-group): * lisp/gnus/nnir.el (nnir-run-swish++, nnir-run-swish-e) (nnir-run-hyrex, nnir-run-namazu): * lisp/hippie-exp.el (make-hippie-expand-function) (try-complete-lisp-symbol, try-complete-lisp-symbol-partially) (try-expand-all-abbrevs): * lisp/international/mule-cmds.el (sort-coding-systems) (select-safe-coding-system, select-message-coding-system) (read-language-name, encoded-string-description): * lisp/international/quail.el (quail-keyseq-translate) (quail-get-translations, quail-build-decode-map) (quail-insert-decode-map): * lisp/jka-compr.el (jka-compr-uninstall): * lisp/locate.el (locate-in-alternate-database): * lisp/mail/mailabbrev.el (mail-resolve-all-aliases-1) (mail-abbrev-make-syntax-table): * lisp/mh-e/mh-seq.el (mh-read-folder-sequences): * lisp/net/eudcb-ldap.el (eudc-ldap-simple-query-internal): * lisp/progmodes/make-mode.el (makefile-query-targets) (makefile-prompt-for-gmake-funargs): * lisp/shadowfile.el (shadow-cancel, shadow-shadows-of): * lisp/sort.el (sort-pages, sort-fields, sort-regexp-fields): * lisp/subr.el (listify-key-sequence): * lisp/term/wyse50.el (terminal-init-wyse50): * lisp/textmodes/ispell.el (ispell-help) (ispell-begin-tex-skip-regexp): * lisp/textmodes/page-ext.el (pages-sort-region): * lisp/textmodes/refer.el (refer-find-entry-in-file): * lisp/url/url-expand.el (url-expand-file-name): Don't quote lambdas.
* Add missing side-effect-free and error-free propertiesMattias Engdegård2020-11-011-8/+10
| | | | | | | | | | | | Any function that is pure is also side-effect-free and some are also error-free. Right now these have to be declared separately. * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Add bool-vector-count-consecutive, bool-vector-count-population, bool-vector-subsetp, copysign, isnan, lax-plist-get, ldexp, memql, regexp-opt and string-to-syntax. (side-effect-and-error-free-fns): Add type-of. * lisp/subr.el (kbd, string-replace): Declare side-effect-free.
* * lisp/emacs-lisp/byte-opt.el (pure-fns): Fix typos.Mattias Engdegård2020-11-011-2/+2
|
* 'assoc' is not side-effect-free; constprop its pure subsetMattias Engdegård2020-10-311-6/+8
| | | | | | | | | | | Since a supplied test function can do anything, assoc is not side-effect-free (bug#44018). However, with only two arguments it is pure and should be optimised accordingly. * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Remove 'assoc'. (byte-optimize-assoc): Constant-propagate through 2-arg assoc calls. * test/lisp/emacs-lisp/bytecomp-tests.el (byte-opt-testsuite-arith-data): Add test cases.
* Handle single-argument `apply' consistently (bug#40968)Pip Cet2020-09-271-13/+16
| | | | | | | | | * src/eval.c (Fapply): Handle (apply nil) without crashing. Document single-argument form. * lisp/emacs-lisp/byte-opt.el (byte-optimize-apply): Don't attempt to optimize single-argument apply. * doc/lispref/functions.texi (Calling Functions): Document single-argument apply. Provide example (bug#40968).
* string-search robustness and documentation improvement (bug#43598)Mattias Engdegård2020-09-251-0/+1
| | | | | | | | * src/fns.c (Fstring_search): Check START-POS argument range. Simplify logic. Improve doc string. * test/src/fns-tests.el (string-search): Add test cases. * doc/lispref/strings.texi (Text Comparison): Elaborate. * lisp/emacs-lisp/byte-opt.el (pure-fns): Mark string-search as pure.
* Mark string-search as being side effect freeLars Ingebrigtsen2020-09-251-1/+2
| | | | | * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Add string-search.
* Clean up and improve compilation of arithmetic (bug#42597)Mattias Engdegård2020-08-071-10/+19
| | | | | | | | | | | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize-associative-math) (byte-optimize-min-max): Transform 3-arg min/max call into two 2-arg calls, which is faster. * lisp/emacs-lisp/bytecomp.el (byte-compile-associative): Rename to... (byte-compile-variadic-numeric): ...this function and simplify, fixing incorrect comments. The 3-arg strength reduction is now always done in the optimisers and is no longer needed here. (byte-compile-min-max): New function. (byte-compile-minus): Simplify, remove incorrect comment, and use byte-compile-variadic-numeric. (byte-compile-quo): Simplify and fix comment.
* * lisp/emacs-lisp/byte-opt.el: Minor simplificationsStefan Monnier2020-07-311-77/+45
| | | | | | | | | (byte-optimize-form-code-walker): Use `byte-optimize-form` after inlining, so optimizations are also applied to the top level call. Simplify the code for `pure` functions using `byte-optimize-constant-args`. (byte-optimize-all-constp): Remove, not used any more. (byte-optimize-1+, byte-optimize-1-): Remove, they are redundant with the `pure` annotation.
* Simplify and streamline optimizer clausesMattias Engdegård2020-07-281-14/+9
| | | | | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Remove clause for 'with-output-to-temp-buffer', since it is a macro and will have been expanded before reaching this point. Move clauses for 'lambda' and 'closure' to avoid splitting a cond jump table.
* Optimise 3-arg +, - and *Mattias Engdegård2020-07-251-0/+10
| | | | | | | | | | Turn (+ a b c) into (+ (+ a b) c), and do the same for - and *. The 2-arg operations have their own bytecode which results in a 1.5× speed-up. Furthermore, the transform enables other optimisations; for example, (+ a 1 b) -> (+ (1+ a) b). * lisp/emacs-lisp/byte-opt.el (byte-optimize-plus, byte-optimize-minus) (byte-optimize-multiply): Transform (OP a b c) into (OP (OP a b) c).
* Optimise assoc and rassoc with symbol key to assq and rassqMattias Engdegård2020-07-071-0/+11
| | | | | | | This is the same transformation made for member to memq. * lisp/emacs-lisp/byte-opt.el (byte-optimize-assoc): New function. (assoc, rassoc): Set the byte-optimizer property.
* Simplify byte-code optimisation of pure functionsMattias Engdegård2020-07-061-43/+14
| | | | | | | | | | | | | | | | | Most pure functions need no explicit optimisation; we can do away with almost all uses of byte-optimize-predicate (now renamed to byte-optimize-constant-args, since it is not just for predicates). Also remove some superfluous arity warnings. * lisp/emacs-lisp/byte-opt.el (byte-optimize-identity, byte-optimize-memq) (byte-optimize-nth, byte-optimize-nthcdr): Remove arity warnings and simplify. * lisp/emacs-lisp/byte-opt.el (<, >, <=, >=, not, null, consp, listp) (symbolp, stringp, string<, string-lessp, proper-list-p, logand) (logior, logxor, lognot, car, cdr, car-safe, cdr-safe): Remove superfluous byte-optimizer property. (byte-optimize-predicate): Rename to byte-optimize-constant-args. All uses changed.
* Mark more functions pure (bug#42147)Mattias Engdegård2020-07-061-7/+42
| | | | | | | | | | | | | Extend the list of 'pure' functions to many predicates and numerical functions that we are reasonably confident will give portable results. Also include various list and array accessors, because our use of purity in the byte compiler isn't affected by the mutability of arguments. * lisp/emacs-lisp/byte-opt.el: Update example in comment. (pure-fns): Add many functions. (byte-optimize-form-code-walker) Don't signal errors during evaluation of calls to pure functions with constant arguments at compile time, since such calls are not necessarily reachable.
* Relax portable number check in byte compiler (bug#42147)Mattias Engdegård2020-07-051-30/+9
| | | | | | | | | | | | | | With bignums, the set of representable integers is no longer platform-dependent, and since we use nothing but IEEE754 64-bit floats, all numbers are now portable. Take advantage of this fact to simplify constant-folding in the byte compiler, allowing it to be applied more widely. * lisp/emacs-lisp/byte-opt.el (byte-opt--portable-max) (byte-opt--portable-min, byte-opt--portable-numberp): Remove. (byte-opt--arith-reduce, byte-optimize-minus, byte-optimize-1+) (byte-optimize-1-): Simplify: any number will do, and if N is a number, then so are -N, N+1 and N-1.
* * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Add `make-byte-code'.Andrea Corallo2020-06-071-2/+2
| | | | | | `make-byte-code' wraps `vector' doing some sanity check on the input arguments. `vector' is in side-effect-and-error-free-fns so add `make-byte-code' to side-effect-free-fns.
* Don’t attempt to modify constant consesPaul Eggert2020-05-161-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | From a patch privately suggested by Mattias Engdegård on 2020-05-11 in a followup to Bug#40671. * admin/charsets/cp51932.awk: * admin/charsets/eucjp-ms.awk: Generate code that does not modify constant conses. * doc/misc/emacs-mime.texi (Encoding Customization): * lisp/emacs-lisp/byte-opt.el (byte-compile-side-effect-free-ops): * lisp/frameset.el (frameset-persistent-filter-alist): * lisp/gnus/gnus-sum.el (gnus-article-mode-line-format-alist): Use append instead of nconc. * lisp/language/japanese.el (japanese-ucs-cp932-to-jis-map) (jisx0213-to-unicode): Use mapcar instead of mapc. * lisp/language/lao-util.el (lao-transcription-consonant-alist) (lao-transcription-vowel-alist): * lisp/language/tibetan.el (tibetan-subjoined-transcription-alist): Use copy-sequence. * test/src/fns-tests.el (fns-tests-nreverse): (fns-tests-sort, fns-tests-collate-sort) (fns-tests-string-version-lessp, fns-tests-mapcan): Use copy-sequence, vector, and list.
* Generate 'substring' byte op (bug#39709)Mattias Engdegård2020-02-251-1/+1
| | | | | | | | | | | | The 'substring' byte op was not emitted, apparently by mistake. Fix. Suggested by Mark Oteiza <mvoteiza@udel.edu>. * lisp/emacs-lisp/bytecomp.el (byte-defop-compiler): Add '1-3' clause. (byte-compile-one-to-three-args): New. * lisp/emacs-lisp/byte-opt.el (byte-compile-side-effect-free-ops): Add 'byte-substring'. * test/lisp/emacs-lisp/bytecomp-tests.el (byte-opt-testsuite-arith-data): Test 'substring'.
* Remove generation of old bytecodes for catch/unwindMattias Engdegård2020-01-051-15/+7
| | | | | | | | | | | | * lisp/emacs-lisp/bytecomp.el (byte-compile--use-old-handlers) (byte-compile-condition-case, byte-compile-condition-case--old): Remove. (byte-compile-condition-case--new): Rename to byte-compile-condition-case. (byte-compile-catch, byte-compile-unwind-protect): * lisp/emacs-lisp/cconv.el (cconv-convert, cconv-analyze-form): * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Simplify.
* Merge from origin/emacs-27Paul Eggert2020-01-011-1/+1
|\ | | | | | | | | | | | | | | | | | | | | 186152ba40 Pacify gcc -Wunused-function on Ubuntu 18.04.3 4cd143aded Fix copyright years by hand 365e01cc9f Update copyright year to 2020 cd2c156163 ; * etc/NEWS: Make the description of XDG fallback more ac... # Conflicts: # etc/NEWS # etc/refcards/ru-refcard.tex
| * Update copyright year to 2020Paul Eggert2020-01-011-1/+1
| | | | | | | | Run "TZ=UTC0 admin/update-copyright $(git ls-files)".
* | Optimise 'while' bodies for effectMattias Engdegård2019-12-261-0/+7
|/ | | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Treat all expressions in the body of 'while' as for-effect, since their values are discarded. This also finds some errors.