unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: "Mattias Engdegård" <mattiase@acm.org>
To: Andrea Corallo <andrea_corallo@yahoo.it>
Cc: Paul Eggert <eggert@cs.ucla.edu>,
	Stefan Monnier <monnier@iro.umontreal.ca>,
	42147@debbugs.gnu.org
Subject: bug#42147: 28.0.50; pure vs side-effect-free, missing optimizations?
Date: Sun, 5 Jul 2020 15:00:32 +0200	[thread overview]
Message-ID: <374F2E9C-E8C2-4362-8BEF-E6AA5EEE5C79@acm.org> (raw)
In-Reply-To: <1690361185.4397117.1593879228865@mail.yahoo.com>

[-- Attachment #1: Type: text/plain, Size: 1940 bytes --]

4 juli 2020 kl. 18.13 skrev Andrea Corallo <andrea_corallo@yahoo.it>:

> (defun bbb ()
>   (let ((x (list 1 2)))
>     (f x)        ; f is not pure
>     (1+ (car x)) ; <= cannot optimize
>     ))

(A more precise property for 'f' in your examples would be 'side-effect-free' rather than 'pure'.)

> BTW reading the code of the native compiler I realized I am already
> extrapolating for use a very similar list of optimizable functions to the one
> proposed.  I still think would quite cleaner to classify these in
> byte-opt.el.

Certainly, but be sure to state your criteria with clarity. There must be no doubt whether or not a function should have a certain property!

> Attached the updated patch where I'm adding car, car-safe, cdr,
> cdr-safe, max, min.

Thank you Andrea! Attached is an update with the following modifications:

* I tried to segregate pure functions that operate on mutable objects, such as car, length and equal, from the rest. This way we can more easily separate them entirely (using different properties) later on if desired.

* The list of pure functions was expanded further. Related functions were grouped rather than ordered alphabetically, because I found it easier to read this way -- you may disagree.

* 'expt' was prudently removed because it doesn't necessarily give portable results for arbitrary floating-point arguments. (exp, sin etc were not included either for the same reason.)

* It turned out that in order to bootstrap, we have to prevent the constant evaluation in the byte compiler from raising errors on invalid input. For example, the macro dired-map-over-marks expands to (essentially)

	     (if (integerp ARG)
		 (< ARG 0)

where ARG is a macro argument that can be nil. Since < is now pure, compilation would fail despite the offending code being unreachable. As this style of code exists and is not unreasonable, the error has to be suppressed.


[-- Attachment #2: 0001-Mark-more-functions-pure-bug-42147.patch --]
[-- Type: application/octet-stream, Size: 4245 bytes --]

From bc387b56233798fb5a2a821c58632ca9c8a9044b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= <mattiase@acm.org>
Date: Sun, 5 Jul 2020 13:47:34 +0200
Subject: [PATCH] Mark more functions pure (bug#42147)

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.
---
 lisp/emacs-lisp/byte-opt.el | 49 +++++++++++++++++++++++++++++++------
 1 file changed, 42 insertions(+), 7 deletions(-)

diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index bf9e6a728a..92c2374a07 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -557,7 +557,10 @@ byte-optimize-form-code-walker
 	   (let ((args (mapcar #'byte-optimize-form (cdr form))))
 	     (if (and (get fn 'pure)
 		      (byte-optimize-all-constp args))
-		   (list 'quote (apply fn (mapcar #'eval args)))
+                 (let ((arg-values (mapcar #'eval args)))
+                   (condition-case nil
+                       (list 'quote (apply fn arg-values))
+                     (error (cons fn args))))
 	       (cons fn args)))))))
 
 (defun byte-optimize-all-constp (list)
@@ -1274,9 +1277,9 @@ byte-optimize-set
 ;; Pure functions are side-effect free functions whose values depend
 ;; only on their arguments, not on the platform.  For these functions,
 ;; calls with constant arguments can be evaluated at compile time.
-;; This may shift runtime errors to compile time.  For example, logand
-;; is pure since its results are machine-independent, whereas ash is
-;; not pure because (ash 1 29)'s value depends on machine word size.
+;; For example, ash is pure since its results are machine-independent,
+;; whereas lsh is not pure because (lsh -1 -1)'s value depends on the
+;; fixnum range.
 ;;
 ;; When deciding whether a function is pure, do not worry about
 ;; mutable strings or markers, as they are so unlikely in real code
@@ -1286,9 +1289,41 @@ byte-optimize-set
 ;; values if a marker is moved.
 
 (let ((pure-fns
-       '(% concat logand logcount logior lognot logxor
-	 regexp-opt regexp-quote
-	 string-to-char string-to-syntax symbol-name)))
+       '(concat regexp-opt regexp-quote
+	 string-to-char string-to-syntax symbol-name
+         eq eql
+         = /= < <= => > min max
+         + - * / % mod abs ash 1+ 1- sqrt
+         logand logior lognot logxor logcount
+         copysign isnan ldexp float logb
+         floor ceiling round truncate
+         ffloor fceiling fround ftruncate
+         string= string-equal string< string-lessp
+         consp atom listp nlistp propert-list-p
+         sequencep arrayp vectorp stringp bool-vector-p hash-table-p
+         null not
+         numberp integerp floatp natnump characterp
+         integer-or-marker-p number-or-marker-p char-or-string-p
+         symbolp keywordp
+         type-of
+         identity ignore
+
+         ;; The following functions are pure up to mutation of their
+         ;; arguments.  This is pure enough for the purposes of
+         ;; constant folding, but not necessarily for all kinds of
+         ;; code motion.
+         car cdr car-safe cdr-safe nth nthcdr last
+         equal
+         length safe-length
+         memq memql member
+         ;; `assoc' and `assoc-default' are excluded since they are
+         ;; impure if the test function is (consider `string-match').
+         assq assql rassq rassoc
+         plist-get lax-plist-get plist-member
+         aref elt
+         bool-vector-subsetp
+         bool-vector-count-population bool-vector-count-consecutive
+         )))
   (while pure-fns
     (put (car pure-fns) 'pure t)
     (setq pure-fns (cdr pure-fns)))
-- 
2.21.1 (Apple Git-122.3)


  reply	other threads:[~2020-07-05 13:00 UTC|newest]

Thread overview: 98+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1583748933.1069307.1593556032592.ref@mail.yahoo.com>
2020-06-30 22:27 ` bug#42147: 28.0.50; pure vs side-effect-free, missing optimizations? Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-06-30 23:14   ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-01 12:46     ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-01 12:44   ` Mattias Engdegård
2020-07-01 16:08     ` Mattias Engdegård
2020-07-01 21:31       ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-02 10:26         ` Mattias Engdegård
2020-07-02 10:59           ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-02 12:46             ` Mattias Engdegård
2020-07-02 13:56               ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-02 14:51                 ` Mattias Engdegård
2020-07-02 15:32                   ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-02 15:49                   ` Stefan Monnier
2020-07-02 18:01                     ` Mattias Engdegård
2020-07-02 18:55                       ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-02 19:38                       ` Stefan Monnier
2020-07-02 20:09                         ` Paul Eggert
2020-07-03  9:32                           ` Mattias Engdegård
2020-07-03 13:39                             ` bug#42147: Hash-consing bignums (was: bug#42147: 28.0.50; pure vs side-effect-free, missing optimizations?) Stefan Monnier
2020-07-02 20:31                       ` bug#42147: 28.0.50; pure vs side-effect-free, missing optimizations? Paul Eggert
2020-07-02 21:41                       ` Stefan Monnier
2020-07-02 23:16                         ` Paul Eggert
2020-07-03  8:32                           ` Mattias Engdegård
2020-07-03 13:11                             ` Stefan Monnier
2020-07-03 18:35                               ` Mattias Engdegård
2020-07-03 18:43                                 ` Mattias Engdegård
2020-07-03 19:05                                 ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-04 14:58                                   ` Mattias Engdegård
2020-07-04 15:06                                 ` Stefan Monnier
2020-07-04 16:13                                   ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-05 13:00                                     ` Mattias Engdegård [this message]
2020-07-05 13:16                                       ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-06 17:20                                         ` Mattias Engdegård
2020-07-06 21:23                                           ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-07 15:54                                             ` Mattias Engdegård
2020-07-07 16:24                                               ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-07 16:55                                                 ` Mattias Engdegård
2020-07-07 17:42                                                   ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-08 19:14                                                   ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-08 21:25                                                     ` Mattias Engdegård
2020-07-08 22:19                                                       ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-09 10:20                                                         ` Mattias Engdegård
2020-07-09 12:47                                                           ` Stefan Monnier
2020-07-09 12:57                                                             ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-09 14:35                                                               ` Stefan Monnier
2020-07-09 15:19                                                                 ` Paul Eggert
2020-07-09 15:37                                                                 ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-05 15:26                                   ` Mattias Engdegård
2020-07-03 18:31                             ` Paul Eggert
2020-07-03 18:47                               ` Mattias Engdegård
2020-07-04 15:57                                 ` Paul Eggert
2020-07-04 16:15                                   ` Eli Zaretskii
2020-07-04 16:27                                     ` Paul Eggert
2020-07-04 16:33                                       ` Stefan Monnier
2020-07-04 16:44                                         ` Mattias Engdegård
2020-07-04 17:00                                         ` Paul Eggert
2020-07-04 18:37                                           ` Pip Cet
2020-07-04 21:05                                             ` Stefan Monnier
2020-07-04 22:25                                               ` Pip Cet
2020-07-05  2:38                                                 ` Eli Zaretskii
2020-07-05  8:28                                                   ` Paul Eggert
2020-07-05  8:39                                                     ` Andreas Schwab
2020-07-05 14:47                                                     ` Eli Zaretskii
2020-07-05 15:30                                                       ` Stefan Monnier
2020-07-06  0:14                                                         ` Paul Eggert
2020-07-05 15:11                                                     ` Stefan Monnier
2020-07-06  0:10                                                       ` Paul Eggert
2020-07-05  9:56                                             ` Paul Eggert
2020-07-05 10:03                                               ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-07-05 23:57                                                 ` Paul Eggert
2020-07-04 19:01                                           ` Mattias Engdegård
2020-07-04 17:10                                       ` Eli Zaretskii
2020-07-04 19:26                                         ` Paul Eggert
2020-07-02 19:09           ` Philipp Stephani
2020-07-03  9:25             ` Mattias Engdegård
2020-07-25 17:09               ` Philipp Stephani
2020-07-25 18:10                 ` Stefan Monnier
2020-07-25 20:03                   ` Philipp Stephani
2020-07-25 20:07                     ` Stefan Monnier
2020-07-25 20:11                       ` Philipp Stephani
2020-07-25 21:00                         ` Mattias Engdegård
2020-07-25 21:29                           ` Stefan Monnier
2020-07-25 21:39                             ` Philipp Stephani
2020-07-25 22:27                               ` Stefan Monnier
2020-07-29 12:53                                 ` Philipp Stephani
2020-07-29 14:28                                   ` Stefan Monnier
2020-07-25 21:54                             ` Mattias Engdegård
2020-07-25 22:30                               ` Stefan Monnier
2020-07-26  9:05                                 ` Mattias Engdegård
2020-07-29 16:03                                   ` Mattias Engdegård
2020-07-29 20:39                                     ` Stefan Monnier
2020-08-03 15:07                                       ` Mattias Engdegård
2020-08-10 13:39                                         ` Philipp Stephani
2020-08-10 22:07                                           ` Stefan Monnier
2020-08-10 13:42                                       ` Philipp Stephani
2020-08-10 22:10                                         ` Stefan Monnier
2020-07-29 13:10                           ` Philipp Stephani
2020-07-25 21:09                         ` Stefan Monnier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=374F2E9C-E8C2-4362-8BEF-E6AA5EEE5C79@acm.org \
    --to=mattiase@acm.org \
    --cc=42147@debbugs.gnu.org \
    --cc=andrea_corallo@yahoo.it \
    --cc=eggert@cs.ucla.edu \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).