Subject: Re: bug#23967: 25.1.50; Slow compilation of ns-win.el

From: [email-masked]
Date: Sun, 17 Jul 2016 12:20:14 -0400

Eli Zaretskii <[email-masked]> writes:

>> Could we call `byte-compile' on the byte-compiler functions after loading them?
>
> Maybe, you will have to try.  The bootstrap of the byte compiler is
> somewhat tricky, given all the dependencies (see COMPILE_FIRST in
> lisp/Makefile.in).

So I tried moving the COMPILE_FIRST into loadup.el, which does bring
bootstrapping[1] down from 1m5s to 0m47s for me.  But IIUC it
reduces parallelism when compiling these files, so possibly it's
actually a loss overall.

[1]: Timed with compile-command = "rm -f bootstrap-emacs ../lisp/emacs-lisp/*.elc && time make bootstrap-emacs"

diff --git a/lisp/Makefile.in b/lisp/Makefile.in
index 12bb9c7..e0d4522 100644
--- a/lisp/Makefile.in
+++ b/lisp/Makefile.in
@@ -100,20 +100,6 @@ AUTOGENEL =
 BYTE_COMPILE_FLAGS = \
   --eval '(setq load-prefer-newer t)' $(BYTE_COMPILE_EXTRA_FLAGS)
 
-# Files to compile before others during a bootstrap.  This is done to
-# speed up the bootstrap process.  They're ordered by size, so we use
-# the slowest-compiler on the smallest file and move to larger files as the
-# compiler gets faster.  'autoload.elc' comes last because it is not used by
-# the compiler (so its compilation does not speed up subsequent compilations),
-# it's only placed here so as to speed up generation of the loaddefs.el file.
-
-COMPILE_FIRST = \
-	$(lisp)/emacs-lisp/macroexp.elc \
-	$(lisp)/emacs-lisp/cconv.elc    \
-	$(lisp)/emacs-lisp/byte-opt.elc \
-	$(lisp)/emacs-lisp/bytecomp.elc \
-	$(lisp)/emacs-lisp/autoload.elc
-
 # Prevent any settings in the user environment causing problems.
 unexport EMACSDATA EMACSDOC EMACSPATH
 
@@ -281,9 +267,7 @@ .SUFFIXES:
 .el.elc:
 	$(AM_V_ELC)$(emacs) $(BYTE_COMPILE_FLAGS) -f batch-byte-compile $<
 
-.PHONY: compile-first compile-main compile compile-always
-
-compile-first: $(COMPILE_FIRST)
+.PHONY: compile-main compile compile-always
 
 # In 'compile-main' we could directly do
 #    ... | xargs $(MAKE)
@@ -336,7 +320,7 @@ semantic:
 # date.  Some .el files don't get compiled because they set the
 # local variable no-byte-compile.
 # Calling make recursively because suffix rule cannot have prerequisites.
-compile: $(LOADDEFS) autoloads compile-first
+compile: $(LOADDEFS) autoloads
 	$(MAKE) compile-main
 
 # Compile all Lisp files.  This is like 'compile' but compiles files
@@ -375,7 +359,7 @@ compile-after-backup:
 # There is no reason to use this rule unless you only have a single
 # core and CPU time is an issue.
 .PHONY: compile-one-process
-compile-one-process: $(LOADDEFS) compile-first
+compile-one-process: $(LOADDEFS)
 	$(emacs) $(BYTE_COMPILE_FLAGS) \
 	    --eval "(batch-byte-recompile-directory 0)" $(lisp)
 
diff --git a/lisp/loadup.el b/lisp/loadup.el
index 5c16464..183944b 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -245,6 +245,31 @@
 (load "progmodes/elisp-mode")
 (load "textmodes/text-mode")
 (load "textmodes/fill")
+
+;; Compile the byte compiler.  This is done to speed up the bootstrap
+;; process.  They're ordered by size, so we use the slowest-compiler
+;; on the smallest file and move to larger files as the compiler gets
+;; faster.  'autoload' comes last because it is not used by the
+;; compiler (so its compilation does not speed up subsequent
+;; compilations), it's only placed here so as to speed up generation
+;; of the loaddefs.el file.
+;;
+;; The byte compiler requires elisp-mode for parsing, and fill
+;; functions for printing warnings.
+(if (equal (member "bootstrap" command-line-args) '("bootstrap"))
+    (let (;; $HOME is not defined(!?), so (expand-file-name "~")
+          ;; crashes (called from `abbreviate-file-name').
+          (abbreviated-home-dir "/home/dir")
+          ;; dir locals needs time-date(?)
+          (enable-dir-local-variables nil))
+      (message "byte compiling the byte compiler...")
+      (setq debug-on-error t)
+      (mapc (lambda (file)
+              (setq file (locate-file file load-path '(".elc" ".el")))
+              (or (equal (substring file -4) ".elc")
+                  (byte-compile-file file t)))
+            '("macroexp" "cconv" "byte-opt" "bytecomp" "autoload"))))
+
 (load "newcomment")
 
 (load "replace")
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index f360791..b8d1d51 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -235,7 +235,7 @@ emacs-lisp-mode
               (append '((?\` . ?\') (?‘ . ?’)) electric-pair-text-pairs))
   (setq-local electric-quote-string t)
   (setq imenu-case-fold-search nil)
-  (add-function :before-until (local 'eldoc-documentation-function)
+  (add-function :before-until (local 'eldoc-documentation-functions)
                 #'elisp-el