mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2025-12-06 02:40:26 -08:00
cmp: add support for precompiled header files
Improves compilation speed for single functions by about 40-50 percent. Precompiled headers are specific to the compiler version and options in use. Due to this, we regenerate the header whenever the compiler configuration changes.
This commit is contained in:
parent
46e158e912
commit
636cb4cf60
4 changed files with 87 additions and 0 deletions
|
|
@ -32,6 +32,9 @@
|
|||
** Enhancements
|
||||
** Issues fixed
|
||||
- The generational and precise garbage collector modes work again
|
||||
- ECL can now use precompiled headers to speed up compilation. Use ~(setq
|
||||
c::*use-precompiled-headers* nil)~ to disable this feature
|
||||
** Issues fixed
|
||||
** API changes
|
||||
* 20.4.24 changes since 16.1.3
|
||||
** Announcement
|
||||
|
|
|
|||
|
|
@ -212,6 +212,11 @@ slashes before special characters.")
|
|||
and standalone programs. It is not required to surround values with quotes or use
|
||||
slashes before special characters.")
|
||||
|
||||
(defvar *use-precompiled-headers* #+msvc nil #-msvc t
|
||||
"This variable controls whether the C compiler uses precompiled header files.")
|
||||
(defvar *precompiled-header-flags* nil)
|
||||
(defvar *precompiled-header-cc-config* nil)
|
||||
|
||||
;;;
|
||||
;;; Compiler program and flags.
|
||||
;;;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ the environment variable TMPDIR to a different value." template))
|
|||
(:program (setf format +executable-file-format+))
|
||||
#+msvc
|
||||
(:import-library (setf extension "implib"))
|
||||
(:precompiled-header (setf format #-msvc "~a.h.gch" #+msvc "~a.pch"))
|
||||
((:fasl :fas) (setf extension "fas")))
|
||||
(cond ((not (member output-file '(T NIL)))
|
||||
output-file)
|
||||
|
|
@ -973,6 +974,7 @@ from the C language code. NIL means \"do not create the file\"."
|
|||
(safe-run-program
|
||||
*cc*
|
||||
`("-I."
|
||||
,@(precompiled-header-flags)
|
||||
,(concatenate 'string "-I" (fix-for-mingw (ecl-include-directory)))
|
||||
,@(split-program-options *cc-flags*)
|
||||
,@(and (>= (cmp-env-optimization 'speed) 2)
|
||||
|
|
@ -1001,6 +1003,78 @@ from the C language code. NIL means \"do not create the file\"."
|
|||
(declare (ignore options))
|
||||
`(progn ,@body))
|
||||
|
||||
(defun need-to-dump-precompiled-header ()
|
||||
(let* ((config *precompiled-header-cc-config*)
|
||||
(need-to-dump (or (null config)
|
||||
(not (eq (svref config 0) *cc*))
|
||||
(not (eq (svref config 1) (ecl-include-directory)))
|
||||
(not (eq (svref config 2) *cc-flags*))
|
||||
(not (eq (svref config 3) *cc-optimize*))
|
||||
(not (eq (svref config 4) *user-cc-flags*)))))
|
||||
(when need-to-dump
|
||||
(setf *precompiled-header-cc-config*
|
||||
(vector *cc* (ecl-include-directory) *cc-flags*
|
||||
*cc-optimize* *user-cc-flags*)))
|
||||
need-to-dump))
|
||||
|
||||
(defun precompiled-header-flags ()
|
||||
(when *use-precompiled-headers*
|
||||
(when (need-to-dump-precompiled-header)
|
||||
(handler-case
|
||||
(dump-precompiled-header)
|
||||
(error (err)
|
||||
(setf *use-precompiled-headers* nil
|
||||
*precompiled-header-flags* nil
|
||||
*precompiled-header-cc-config* nil)
|
||||
(cmpnote "Disabling precompiled header files due to error:~% ~A" err))))
|
||||
*precompiled-header-flags*))
|
||||
|
||||
#+msvc
|
||||
(defun dump-precompiled-header ()
|
||||
;; The way precompiled headers work on msvc is not compatible with
|
||||
;; what we want to use them for. The msvc compiler creates a
|
||||
;; precompiled header file out of ordinary source files by
|
||||
;; processing them up to a certain point at which all needed headers
|
||||
;; are included. This creates both a precompiled header and a object
|
||||
;; file. The object file created by this compilation must be
|
||||
;; included in all binaries which are linked together from other
|
||||
;; source files compiled using the precompiled header. Thus, we
|
||||
;; would need to include the first object file created in a session
|
||||
;; in all further object files if we wanted to support that.
|
||||
(error "Precompiled headers are not supported for msvc."))
|
||||
|
||||
#-msvc
|
||||
(defun dump-precompiled-header ()
|
||||
(let* ((input-file (make-pathname
|
||||
:directory (append (pathname-directory (ecl-include-directory))
|
||||
'("ecl"))
|
||||
:defaults (ecl-include-directory)
|
||||
:name "ecl-cmp"
|
||||
:type "h"))
|
||||
(output-dir (merge-pathnames
|
||||
(format nil "ecl-include~4,'0x/" (random #xffff))
|
||||
(translate-logical-pathname "TMP:")))
|
||||
(output-file (compile-file-pathname
|
||||
(make-pathname :name "ecl-cmp" :defaults output-dir)
|
||||
:type :precompiled-header)))
|
||||
(ensure-directories-exist output-dir)
|
||||
(push output-dir *files-to-be-deleted*)
|
||||
(safe-run-program
|
||||
*cc*
|
||||
`("-x" "c-header"
|
||||
,(fix-for-mingw (namestring input-file))
|
||||
,(concatenate 'string "-I" (fix-for-mingw (ecl-include-directory)))
|
||||
,@(split-program-options *cc-flags*)
|
||||
,@(split-program-options *cc-optimize*)
|
||||
"-o"
|
||||
,(fix-for-mingw (namestring output-file))
|
||||
,@(split-program-options *user-cc-flags*)))
|
||||
(push output-file *files-to-be-deleted*)
|
||||
(setf *precompiled-header-flags*
|
||||
(list (concatenate 'string "-I" (namestring output-dir))
|
||||
"-include"
|
||||
(concatenate 'string (namestring output-dir) "ecl-cmp.h")))))
|
||||
|
||||
(ext:package-lock "CL" t)
|
||||
|
||||
(setf *features* (delete :ecl-bytecmp *features*))
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
See file '../Copyright' for full details.
|
||||
*/
|
||||
|
||||
#ifndef ECL_CMP_H
|
||||
#define ECL_CMP_H
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
/* Recent versions of cygwin do not define fd_set when WINSOCKAPI is
|
||||
* defined */
|
||||
|
|
@ -61,3 +64,5 @@ struct ecl_var_debug_info {
|
|||
|
||||
#define _ecl_check_narg(n) \
|
||||
do { if (ecl_unlikely(narg != (n))) FEwrong_num_arguments_anonym();} while(0)
|
||||
|
||||
#endif /* ECL_CMP_H */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue