unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Paul Eggert <eggert@cs.ucla.edu>
To: Emacs development discussions <emacs-devel@gnu.org>
Subject: Floating-point constant folding in Emacs byte compiler
Date: Thu, 22 Mar 2018 16:04:52 -0700	[thread overview]
Message-ID: <2ce39e5c-cd1b-65d6-b125-719caad67932@cs.ucla.edu> (raw)

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

While preparing and installing the attached patch to Emacs master, I 
noticed that the byte optimizer assumes that floating-point arithmetic 
behaves the same at compile-time that it does at runtime. For example, 
on my x86-64 platform the byte compiler optimizes (/ 0 0.0) to -NaN, (- 
1 1.0000000000000001) to 0.0, and (< 1 1.0000000000000001) to nil, even 
though these expressions will evaluate to different values on (say) an 
IBM mainframe that uses IBM floating point, and the first expression 
yields +NaN on some IEEE platforms (e.g., ARM).

These discrepancies mean that .elc files containing floating-point 
constants might not be platform-independent, in that byte-compiling a 
file on one machine X and running it on another machine Y can yield 
different results than byte-compiling and running the same file on Y. Is 
this sort of discrepancy intended? If so, should it be documented in the 
Emacs Lisp manual? On the one hand, I doubt whether this sort of 
optimization buys us much performance; on the other, I doubt whether 
many users care about the discrepancies.


[-- Attachment #2: 0001-Fix-byte-opt-lists-of-pure-functions-etc.txt --]
[-- Type: text/plain, Size: 5339 bytes --]

From 3b1024ac8162a66cc6baf6f7f339d9f73bcb6b90 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Thu, 22 Mar 2018 11:25:42 -0700
Subject: [PATCH] Fix byte-opt lists of pure functions etc.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This fixes a bug where a byte-compiler running on 64-bit Emacs
optimized (lsh -1 -1) to #x1fffffffffffffff, an optimization
that is incorrect for .elc files intended for either 32- or
64-bit Emacs.  While I was in the neighborhood, I noticed other
glitches in the lists of pure and side-effect-free functions, and
fixed the errors that I found.
* lisp/emacs-lisp/byte-opt.el (side-effect-free-fns):
Move some functions here from side-effect-and-error-free-fns,
since they can now signal errors.  The affected functions are
current-time-string, current-time-zone,
line-beginning-position, line-end-position.  Rename langinfo
to locale-info.  Add logcount.  Remove string-to-int.
(side-effect-and-error-free-fns): Remove minibuffer-window, a
function that can signal errors, and that is already in
side-effect-free-fns.
(pure-fns): Remove ash, lsh, and logb, since they are
platform-dependent and .elc files should be
platform-independent.  Add %, logand, logcount.  Sort.
Clarify what is meant by “pure”.
---
 lisp/emacs-lisp/byte-opt.el | 37 +++++++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index a316364761..55343e1e3a 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -1186,6 +1186,7 @@ byte-optimize-set
 	 char-equal char-to-string char-width compare-strings
 	 compare-window-configurations concat coordinates-in-window-p
 	 copy-alist copy-sequence copy-marker cos count-lines
+	 current-time-string current-time-zone
 	 decode-char
 	 decode-time default-boundp default-value documentation downcase
 	 elt encode-char exp expt encode-time error-message-string
@@ -1199,8 +1200,9 @@ byte-optimize-set
 	 hash-table-count
 	 int-to-string intern-soft
 	 keymap-parent
-	 length local-variable-if-set-p local-variable-p log log10 logand
-	 logb logior lognot logxor lsh langinfo
+	 length line-beginning-position line-end-position
+	 local-variable-if-set-p local-variable-p locale-info
+	 log log10 logand logb logcount logior lognot logxor lsh
 	 make-list make-string make-symbol marker-buffer max member memq min
 	 minibuffer-selected-window minibuffer-window
 	 mod multibyte-char-to-unibyte next-window nth nthcdr number-to-string
@@ -1210,7 +1212,7 @@ byte-optimize-set
 	 radians-to-degrees rassq rassoc read-from-string regexp-quote
 	 region-beginning region-end reverse round
 	 sin sqrt string string< string= string-equal string-lessp string-to-char
-	 string-to-int string-to-number substring
+	 string-to-number substring
 	 sxhash sxhash-equal sxhash-eq sxhash-eql
 	 symbol-function symbol-name symbol-plist symbol-value string-make-unibyte
 	 string-make-multibyte string-as-multibyte string-as-unibyte
@@ -1240,7 +1242,6 @@ byte-optimize-set
 	 charsetp commandp cons consp
 	 current-buffer current-global-map current-indentation
 	 current-local-map current-minor-mode-maps current-time
-	 current-time-string current-time-zone
 	 eobp eolp eq equal eventp
 	 floatp following-char framep
 	 get-largest-window get-lru-window
@@ -1248,9 +1249,9 @@ byte-optimize-set
 	 identity ignore integerp integer-or-marker-p interactive-p
 	 invocation-directory invocation-name
 	 keymapp keywordp
-	 line-beginning-position line-end-position list listp
+	 list listp
 	 make-marker mark mark-marker markerp max-char
-	 memory-limit minibuffer-window
+	 memory-limit
 	 mouse-movement-p
 	 natnump nlistp not null number-or-marker-p numberp
 	 one-window-p overlayp
@@ -1275,16 +1276,24 @@ byte-optimize-set
   nil)
 
 \f
-;; pure functions are side-effect free functions whose values depend
-;; only on their arguments. For these functions, calls with constant
-;; arguments can be evaluated at compile time. This may shift run time
-;; errors to compile time.
+;; 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.
+;;
+;; When deciding whether a function is pure, do not worry about
+;; mutable strings or markers, as they are so unlikely in real code
+;; that they are not worth worrying about.  Thus string-to-char is
+;; pure even though it might return different values if a string is
+;; changed, and logand is pure even though it might return different
+;; values if a marker is moved.
 
 (let ((pure-fns
-       '(concat symbol-name regexp-opt regexp-quote string-to-syntax
-         string-to-char
-         ash lsh logb lognot logior logxor
-         ceiling floor)))
+       '(% concat logand logcount logior lognot logxor
+	 regexp-opt regexp-quote
+	 string-to-char string-to-syntax symbol-name)))
   (while pure-fns
     (put (car pure-fns) 'pure t)
     (setq pure-fns (cdr pure-fns)))
-- 
2.14.3


             reply	other threads:[~2018-03-22 23:04 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-22 23:04 Paul Eggert [this message]
2018-03-23  1:26 ` Floating-point constant folding in Emacs byte compiler Stefan Monnier
2018-03-23  5:22   ` Paul Eggert
2018-03-23  8:24     ` Eli Zaretskii
2018-03-23 20:00       ` Paul Eggert
2018-03-23  8:15   ` Eli Zaretskii
2018-03-23 20:52 ` Pip Cet
2018-03-24  6:25   ` Eli Zaretskii
2018-03-26  9:39     ` Robert Pluim
2018-03-26 15:13       ` Eli Zaretskii
2018-03-26 15:57         ` Robert Pluim
2018-03-26 16:02           ` Eli Zaretskii
2018-03-26 18:23             ` Pip Cet
2018-03-26 18:29               ` Eli Zaretskii
2018-03-27  0:28               ` Paul Eggert
2018-03-27 23:28                 ` Paul Eggert
2018-03-30 16:26                   ` Pip Cet
2018-03-30 16:31                     ` Noam Postavsky
2018-03-30 16:39                     ` Paul Eggert
2018-04-02 10:56                       ` Pip Cet
2018-04-02 11:22                         ` Eli Zaretskii
2018-04-02 11:42                           ` Pip Cet
2018-04-02 12:50                             ` Eli Zaretskii
2018-04-02 14:50                         ` Stefan Monnier
2018-04-02 15:02                           ` Pip Cet
2018-04-02 12:57                     ` Noam Postavsky
2018-04-02 13:30                       ` Eli Zaretskii
2018-04-02 14:48                         ` Stefan Monnier
2018-04-02 19:20                           ` Paul Eggert
2018-04-02 19:39                             ` Pip Cet
2018-04-02 19:58                               ` Eli Zaretskii
2018-04-02 20:55                                 ` Pip Cet
     [not found]                       ` <<83y3i568i0.fsf@gnu.org>
2018-04-02 13:37                         ` Drew Adams
2018-04-02 14:05                           ` Eli Zaretskii
2018-04-02 14:54                           ` Pip Cet
2018-04-02 15:02                             ` Drew Adams
2018-03-26 17:52         ` Stefan Monnier
2018-03-26 18:30           ` Eli Zaretskii
2018-03-27  0:08           ` Paul Eggert

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=2ce39e5c-cd1b-65d6-b125-719caad67932@cs.ucla.edu \
    --to=eggert@cs.ucla.edu \
    --cc=emacs-devel@gnu.org \
    /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).