summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/byte-opt.el
Commit message (Collapse)AuthorAgeFilesLines
* Merge from origin/emacs-28Eli Zaretskii2022-01-011-1/+1
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 836be7a112 ; * etc/refcards/ru-refcard.tex: Update Copyright year. 86cbc6ee4a * lisp/net/tramp-sh.el: Adapt copyright year ebe8772f65 ; Minor fixes related to copyright years 23c1ee6989 ; * test/manual/etags/ETAGS.good_N: Adjust to copyright ye... 8d3fc7ec89 * src/xfaces.c (face_for_font): Make 'hash' be uintptr_t. 19dcb237b5 ; Add 2022 to copyright years. # Conflicts: # etc/NEWS # etc/refcards/ru-refcard.tex # lib/cdefs.h # lisp/erc/erc-dcc.el # lisp/erc/erc-imenu.el # lisp/erc/erc-replace.el # lisp/image-dired.el # lisp/progmodes/xref.el # m4/alloca.m4 # m4/byteswap.m4 # m4/errno_h.m4 # m4/getopt.m4 # m4/gnulib-common.m4 # m4/inttypes.m4 # m4/stddef_h.m4 # m4/stdint.m4 # m4/sys_socket_h.m4
| * ; Add 2022 to copyright years.Eli Zaretskii2022-01-011-1/+1
| |
* | Treat base64 string encode/decode as pure functionsMattias Engdegård2021-12-201-0/+2
| | | | | | | | | | | | * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns, pure-fns): Mark base64-decode-string, base64-encode-string and base64url-encode-string as pure and side-effect-free.
* | Constant-propagate access to captured variablesMattias Engdegård2021-12-111-2/+6
| | | | | | | | | | | | | | | | | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize--substitutable-p): Treat (internal-get-closed-var N) as constants for propagation purposes, because that is effectively what such forms will be compiled to. This allows for the elimination of some lexical variables. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases): Add test case.
* | Add new 'keymap-*' functionsLars Ingebrigtsen2021-11-161-66/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * lisp/keymap.el: New file with all the new keymap-* functions. * lisp/loadup.el ("keymap"): Load. * lisp/subr.el (kbd): Refactor out all the code to key-parse. (define-key-after, keyboard-translate, global-set-key) (local-set-key, global-unset-key, local-unset-key) (local-key-binding, global-key-binding) (substitute-key-definition): Note in doc strings that these are legacy functions. (define-keymap--define): Use keymap-set. * lisp/emacs-lisp/byte-opt.el: Remove the optimizations for defvar-keymap and define-keymap since the macros now only understand the kbd syntax. * lisp/emacs-lisp/bytecomp.el (byte-compile-define-keymap) (byte-compile-define-keymap--define): Warn about invalid key definitions in all keymap-* functions. * lisp/emacs-lisp/shortdoc.el (keymaps): Add shortdocs form keymap* functions. * src/keymap.c (possibly_translate_key_sequence): Adjust callers to key-valid-p and key-parse. (syms_of_keymap): Adjust defs.
* | Optimise (cond) => nil at source levelMattias Engdegård2021-11-021-1/+1
| | | | | | | | | | | | | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize-cond): Optimise clause-free `cond`, which can arise from earlier transformations. This enables further optimisations. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases): Add test cases.
* | Error out on invalid `define-keymap' keywordsLars Ingebrigtsen2021-10-191-0/+3
| | | | | | | | | | | | | | | | | | * lisp/subr.el (define-keymap--define): Error out on invalid keywords (bug#51268). * lisp/emacs-lisp/byte-opt.el (byte-optimize-define-keymap): Check keywords at compile time. * lisp/vc/cvs-status.el (cvs-status-mode-map): Fix keyword.
* | Reinstate defvar-keymap expansionLars Ingebrigtsen2021-10-171-8/+11
| | | | | | | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize-define-keymap--define): Make more robust.
* | Back out `define-keymap' optimization -- it leads to a build errorLars Ingebrigtsen2021-10-171-3/+2
| |
* | Support a new ["..."] key binding syntaxLars Ingebrigtsen2021-10-171-0/+61
|/ | | | | | | | | | | | | * doc/lispref/keymaps.texi (Key Sequences): (Changing Key Bindings): Document the various key syntaxes. * lisp/emacs-lisp/byte-opt.el (byte-optimize-define-key) (byte-optimize-define-keymap) (byte-optimize-define-keymap--define): New functions to check and expand ["..."] syntax at compile time. * src/keymap.c (Fdefine_key): Understand the ["..."] syntax. (syms_of_keymap): Define `kbd' symbols.
* Fix byte-compiler crash for legal dynamic-binding codeMattias Engdegård2021-09-251-5/+12
| | | | | | | | | | This should really be taken care of by a syntax normalisation step in the frontend, but there is no such step for non-lexbind code yet. * lisp/emacs-lisp/byte-opt.el (byte-optimize-letX): Tolerate bindingsa without initialising expressions. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases): Add test cases.
* Constant-propagate variables bound outside loopsMattias Engdegård2021-09-251-18/+34
| | | | | | | | | | | | | | Previously, variables bound outside `while` loops were not substituted inside even in the absense of mutation. Add the necessary mutation checking inside loops to allow propagation of values and aliased variables. * lisp/emacs-lisp/byte-opt.el (byte-optimize--inhibit-outside-loop-constprop): New variable. (byte-optimize-form-code-walker): First traverse each loop without substitution to discover mutation, then without restrictions. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-test-loop): New. (bytecomp-tests--test-cases): Add test cases.
* ; More stylistic docfixes in emacs-lisp/*.el found by checkdocStefan Kangas2021-09-181-2/+2
|
* Remove obsolete variableMattias Engdegård2021-09-111-59/+32
| | | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize--vars-outside-condition): Remove. (byte-optimize-form-code-walker): Remove bindings.
* Propagate aliased lexical variables in byte compilerMattias Engdegård2021-09-111-17/+140
| | | | | | | | | | | | | | | | | | | | | | Replace uses of a variable aliasing another variable with that aliased variable, to allow for variable removal when possible. This also enables opportunities for other optimisations. Example: (let ((y x)) (f y)) => (f x) The optimisation is only performed if both aliased and aliasing variables are lexically bound. Shadowing bindings are α-renamed when necessary for correctness. Example: (let* ((b a) (a EXPR)) (f a b)) => (let* ((a{new} EXPR)) (f a{new} a)) * lisp/emacs-lisp/byte-opt.el (byte-optimize--aliased-vars): New. (byte-optimize-form-code-walker): Cancel aliasing upon mutation. (byte-optimize--rename-var-body, byte-optimize--rename-var): New. (byte-optimize-let-form): Add the optimisation. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases): Add relevant test cases.
* Normalise nested `progn` forms in byte-code optimiserMattias Engdegård2021-09-061-2/+6
| | | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize-body): Flatten body. This simplifies the source tree and reduces the number of different cases that other optimisations need to take into account.
* More robust optimisation of `ignore`Mattias Engdegård2021-09-061-8/+3
| | | | | | | | | | | | | | Treat `ignore` as any other function during source-level optimisation, to avoid having its warning-suppression effects cancelled by repeated passes. Instead, define a custom code generation function. * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Don't treat `ignore' specially here. (side-effect-free-fns): Don't mark `ignore` as side-effect-free or error-free (although it is), since that would allow the optimiser to elide calls. * lisp/emacs-lisp/bytecomp.el (ignore, byte-compile-ignore): Define and register a code-gen function.
* Optimise `member` and `assoc` (etc) with constant empty listMattias Engdegård2021-09-061-25/+41
| | | | | | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize-assq): New. (byte-optimize-member, byte-optimize-assoc, byte-optimize-memq): When the list argument is constant nil, the result is always nil. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases): Add test cases.
* Cease attempts to const-propagate through setqMattias Engdegård2021-08-051-9/+3
| | | | | | | | | | | | | | | The current method of propagating constants through setq was unsound because it relied on each setq form only being traversed at most once during optimisation, which isn't necessarily true in general; it could be made to miscompile code in rare cases. Since it was only used in limited circumstances, disabling this optimisation doesn't cost us much. * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Don't update the known value when traversing `setq`. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases): Add test case.
* file-name-concat is not error freeLars Ingebrigtsen2021-08-031-1/+1
| | | | | * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Declare file-name-concat as side-effect free.
* Declare file-name-concat as side-effect freeLars Ingebrigtsen2021-08-031-0/+1
| | | | | * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Declare file-name-concat as side-effect (and error) free.
* Declare `match-beginning` and `match-end` as side-effect-freeMattias Engdegård2021-08-031-0/+1
| | | | * lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Add functions.
* Simplify lexical let-optimisationsMattias Engdegård2021-07-301-30/+16
| | | | | | | | | | | | | | | | | | Ensure in cconv that let-bindings have the normal form (VAR EXPR) where VAR is a valid variable name, so that we don't need to keep re-checking this all the time in the optimiser. * lisp/emacs-lisp/byte-opt.el (byte-optimize-enable-variable-constprop) (byte-optimize-warn-eliminated-variable): Remove; these were mainly used for debugging. * lisp/emacs-lisp/byte-opt.el (byte-optimize-let-form): Assume normalised let-bindings (with lexical-binding). Stop using the variables removed above. * lisp/emacs-lisp/cconv.el (cconv-convert): Ensure normalised let-bindings. Malformed bindings are dropped after warning. remove byte-optimize-warn-eliminated-variable
* Optimise let and let* whose body is constant or the last variableMattias Engdegård2021-07-301-12/+25
| | | | | | | | | | | | | | | | | | Simplify (let ((X1 E1) ... (Xn En)) Xn) => (progn E1 ... En) and (let* ((X1 E1) ... (Xn En)) Xn) => (let* ((X1 E1) ... (Xn-1 En-1)) En) and similarly the case where the body is a constant, extending a previous optimisation that only applied to the constant nil. This reduces the number of bound variables, shortens the code, and enables further optimisations. * lisp/emacs-lisp/byte-opt.el (byte-optimize-letX): Rewrite using `pcase` and add the aforementioned transformations. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases): Add test cases.
* Move warnings about bad let-bindings from source optimiser to cconvMattias Engdegård2021-07-301-10/+5
| | | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize-let-form): Move warnings... * lisp/emacs-lisp/cconv.el (cconv-convert): ...here, which is an overall better place (closer to the front-end).
* Optimise prog1 betterMattias Engdegård2021-07-301-5/+8
| | | | | | | | | | Rewrite (prog1 CONST FORMS...) => (progn FORMS... CONST) where CONST is a compile-time constant, because putting the value last allows the lapcode peephole pass to do important improvements like branch elimination. Also use progn instead of prog1 for `ignore`. * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): New `prog1` and `ignore` transforms.
* Elide lexical variables in for-effect context in source optimiserMattias Engdegård2021-07-301-10/+15
| | | | | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Remove for-effect uses of lexical variables. We previously relied on this being done by the lapcode peephole optimiser but at source level it enables more optimisation opportunities. Keywords are elided for the same reason.
* Single source optimiser entry pointMattias Engdegård2021-07-301-1/+8
| | | | | | | | | | | | Make the optimiser aware of lexical arguments. Otherwise we cannot know for sure whether a variable is lexical or dynamic during traversal. * lisp/emacs-lisp/byte-opt.el (byte-optimize-one-form): New optimiser entry point, replacing the recursive byte-optimize-form. * lisp/emacs-lisp/bytecomp.el (byte-optimize-one-form): Autoload. (byte-compile-keep-pending, byte-compile-top-level): Use byte-optimize-one-form.
* Warn about arity errors in inlining calls (bug#12299)Mattias Engdegård2021-07-231-1/+4
| | | | | | | | | | | | | | | Wrong number of arguments in inlining function calls (to `defsubst` or explicitly using `inline`) did not result in warnings, or in very cryptic ones. * lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand): Add calls to `byte-compile--check-arity-bytecode`. * lisp/emacs-lisp/bytecomp.el (byte-compile-emit-callargs-warn) (byte-compile--check-arity-bytecode): New functions. (byte-compile-callargs-warn): Use factored-out function. * test/lisp/emacs-lisp/bytecomp-resources/warn-callargs-defsubst.el: * test/lisp/emacs-lisp/bytecomp-tests.el ("warn-callargs-defsubst.el"): New test case.
* Fix mistake in `quote` optimiserMattias Engdegård2021-07-211-4/+3
| | | | | | | | | | Found by Pip Cet. * lisp/emacs-lisp/byte-opt.el (byte-optimize-quote): Fix mistake that made this optimiser ineffective at removing quoting of nil, t, and keywords. The only obvious consequence is that we no longer need... (byte-optimize-form): ...a 'nil => nil normalising step here; remove. (byte-optimize-form-code-walker): Make the compiler warn about (quote).
* ; * lisp/emacs-lisp/byte-opt.el (byte-optimize-eq): Fix last change.Mattias Engdegård2021-07-201-4/+3
|
* Strength-reduce (eq X nil) to (not X)Mattias Engdegård2021-07-201-1/+7
| | | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize-eq): New optimisation, which results in better test and branch code generation where it applies.
* Constant-propagate (function SYMBOL)Mattias Engdegård2021-06-031-1/+1
| | | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize--substitutable-p): Consider #'SYMBOL a constant for compile-time propagation purposes.
* Optimise (cons X nil) to (list X)Mattias Engdegård2021-06-031-0/+8
| | | | * lisp/emacs-lisp/byte-opt.el (byte-optimize-cons): New function.
* * lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand): Silence warningsStefan Monnier2021-05-271-18/+28
| | | | | (byte-optimize--lexvars): Move before first use instead of using `dlet` on that first use.
* 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.