diff --git a/src/c/compiler.d b/src/c/compiler.d index 097a93bc50c182d01aaccc3a28211abdc6d3a7d1..9be698e234a83c97334338bbdeadbdca647e044d 100644 --- a/src/c/compiler.d +++ b/src/c/compiler.d @@ -377,11 +377,13 @@ asm_op2c(cl_env_ptr env, int code, cl_object o) { * (:function function-name used-p [location]) | * (var-name {:special | nil} bound-p [location]) | * (symbol si::symbol-macro macro-function) | + * (:declare type arguments) | * SI:FUNCTION-BOUNDARY | * SI:UNWIND-PROTECT-BOUNDARY * (:declare declaration-arguments*) * macro-record = (function-name FUNCTION [| function-object]) | * (macro-name si::macro macro-function) | + * (:declare name declaration) | * SI:FUNCTION-BOUNDARY | * SI:UNWIND-PROTECT-BOUNDARY * diff --git a/src/c/symbols_list.h b/src/c/symbols_list.h index e6334e529ae8abcdf99faf75d85992151b22e3d8..5379959ac34e92f27f7f3ad326b50b669310097a 100644 --- a/src/c/symbols_list.h +++ b/src/c/symbols_list.h @@ -2149,8 +2149,6 @@ cl_symbols[] = { {EXT_ "UNIX-SIGNAL-RECEIVED-CODE" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, {KEY_ "CODE" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)}, -{EXT_ "ASSUME-RIGHT-TYPE" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, - {SYS_ "FLOAT-TO-DIGITS" ECL_FUN("si_float_to_digits", si_float_to_digits, 4) ECL_VAR(SI_ORDINARY, OBJNULL)}, {SYS_ "FLOAT-TO-STRING-FREE" ECL_FUN("si_float_to_string_free", si_float_to_string_free, 4) ECL_VAR(SI_ORDINARY, OBJNULL)}, {SYS_ "INTEGER-TO-STRING" ECL_FUN("si_integer_to_string", si_integer_to_string, 5) ECL_VAR(SI_ORDINARY, OBJNULL)}, @@ -2328,14 +2326,28 @@ cl_symbols[] = { {SYS_ "SETF-DEFINITION" ECL_FUN("si_setf_definition", ECL_NAME(si_setf_definition), 2) ECL_VAR(SI_ORDINARY, OBJNULL)}, {EXT_ "ASSUME-NO-ERRORS" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, -{EXT_ "ASSUME-TYPES-DONT-CHANGE" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, -{EXT_ "CHECK-ARGUMENTS-TYPE" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, -{EXT_ "INLINE-ACCESSORS" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, -{EXT_ "INLINE-TYPE-CHECKS" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, -{EXT_ "EVALUATE-FORMS" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, +{EXT_ "ASSUME-RIGHT-TYPE" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, {EXT_ "TYPE-ASSERTIONS" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, {EXT_ "CHECK-STACK-OVERFLOW" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, +{EXT_ "CHECK-ARGUMENTS-TYPE" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, {EXT_ "ARRAY-BOUNDS-CHECK" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, +{EXT_ "GLOBAL-VAR-CHECKING" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, +{EXT_ "GLOBAL-FUNCTION-CHECKING" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, +{EXT_ "CHECK-NARGS" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, +{EXT_ "THE-IS-CHECKED" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, + +{EXT_ "ASSUME-TYPES-DONT-CHANGE" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, +{EXT_ "INLINE-SLOT-ACCESS" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, +{EXT_ "INLINE-ACCESSORS" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, +{EXT_ "INLINE-BIT-OPERATIONS" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, +{EXT_ "OPEN-CODE-AREF/ASET" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, +{EXT_ "EVALUATE-FORMS" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, +{EXT_ "USE-DIRECT-C-CALL" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, +{EXT_ "INLINE-TYPE-CHECKS" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, +{EXT_ "INLINE-SEQUENCE-FUNCTIONS" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, + +{EXT_ "DEBUG-VARIABLE-BINDINGS" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, +{EXT_ "DEBUG-IHS-FRAME" ECL_FUN(NULL, NULL, -1) ECL_VAR(EXT_ORDINARY, OBJNULL)}, {KEY_ "VALUE" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)}, {KEY_ "KEY-AND-VALUE" ECL_FUN(NULL, NULL, -1) ECL_VAR(KEYWORD, OBJNULL)}, diff --git a/src/clos/method.lsp b/src/clos/method.lsp index 852b061daee05546209c03eb1131e119c1d6d4e1..7d242f31b9033b63da92c19b4f4c2af59a0bf28f 100644 --- a/src/clos/method.lsp +++ b/src/clos/method.lsp @@ -64,6 +64,7 @@ (parse-specialized-lambda-list specialized-lambda-list) (multiple-value-bind (lambda-form declarations documentation) (make-raw-lambda name lambda-list required-parameters specializers body env) + (declare (ignore declarations)) (multiple-value-bind (proto-gf proto-method) (prototypes-for-make-method-lambda name) (multiple-value-bind (fn-form options) @@ -181,6 +182,7 @@ (declare (ignore method gf)) (multiple-value-bind (call-next-method-p next-method-p-p in-closure-p) (walk-method-lambda method-lambda env) + (declare (ignore call-next-method-p next-method-p-p)) (values `(lambda (.combined-method-args. *next-methods*) (declare (special .combined-method-args. *next-methods*)) (apply ,(if in-closure-p diff --git a/src/clos/stdmethod.lsp b/src/clos/stdmethod.lsp index d22337a833aae70c89493db0bac3825a1e1c786f..97429c850ba5fed87d14fb22af021ab4bfa896d1 100644 --- a/src/clos/stdmethod.lsp +++ b/src/clos/stdmethod.lsp @@ -33,7 +33,7 @@ &key (specializers nil spec-supplied-p) (lambda-list nil lambda-supplied-p) generic-function) - (declare (ignore initargs method slot-names)) + (declare (ignore initargs method slot-names generic-function)) (when slot-names (unless spec-supplied-p (error "Specializer list not supplied in method initialization")) diff --git a/src/cmp/cmparray.lsp b/src/cmp/cmparray.lsp index e1e6e77136bb5dd6fa1a3c0bf9d6d3ee3a2dfa47..1a6540da8876e8a9abddd49a2660d5dcfabb70ab 100644 --- a/src/cmp/cmparray.lsp +++ b/src/cmp/cmparray.lsp @@ -80,8 +80,8 @@ ,%displaced-to ,%displaced-index-offset))) ;; Then we may fill the array with a given value (when initial-element-supplied-p - (setf form `(si::fill-array-with-elt ,form ,%initial-element 0 nil))) - (setf form `(truly-the (array ,guessed-element-type ,dimensions-type) + (setf form `(si:fill-array-with-elt ,form ,%initial-element 0 nil))) + (setf form `(ext:truly-the (array ,guessed-element-type ,dimensions-type) ,form)))) form) @@ -92,7 +92,7 @@ (defun expand-vector-push (whole env extend &aux (args (rest whole))) (declare (si::c-local) (ignore env)) - (with-clean-symbols (value vector index dimension) + (ext:with-clean-symbols (value vector index dimension) (when (or (eq (first args) 'value) ; No infinite recursion (not (policy-open-code-aref/aset))) (return-from expand-vector-push @@ -114,8 +114,8 @@ (declare (fixnum index dimension) (:read-only index dimension)) (cond ((< index dimension) - (sys::fill-pointer-set vector (truly-the fixnum (+ 1 index))) - (sys::aset vector index value) + (si:fill-pointer-set vector (ext:truly-the fixnum (+ 1 index))) + (si:aset vector index value) index) (t ,(if extend `(vector-push-extend value vector ,@(cddr args)) @@ -137,7 +137,7 @@ form)) (defun expand-aref (array indices env) - (with-clean-symbols (%array) + (ext:with-clean-symbols (%array) `(let ((%array ,array)) (declare (:read-only %array) (optimize (safety 0))) @@ -162,11 +162,11 @@ `(let* ((,%array ,array)) (declare (:read-only ,%array) (optimize (safety 0))) - (si::row-major-aset ,%array ,(expand-row-major-index %array indices env) ,value)))) + (si:row-major-aset ,%array ,(expand-row-major-index %array indices env) ,value)))) (define-compiler-macro array-row-major-index (&whole form array &rest indices &environment env) (if (policy-open-code-aref/aset env) - (with-clean-symbols (%array) + (ext:with-clean-symbols (%array) `(let ((%array ,array)) (declare (:read-only %array) (optimize (safety 0))) @@ -188,7 +188,7 @@ (check-vector-in-bounds ,a ,index) ,index))) (if (policy-type-assertions env) - (with-clean-symbols (%array-index) + (ext:with-clean-symbols (%array-index) `(let ((%array-index ,index)) (declare (:read-only %array-index)) ,(expansion a '%array-index))) @@ -207,7 +207,7 @@ for index in indices collect `(,(gentemp "DIM") (array-dimension-fast ,a ,i)))) (dim-names (mapcar #'first dims))) - (with-clean-symbols (%ndx-var %output-var %dim-var) + (ext:with-clean-symbols (%ndx-var %output-var %dim-var) `(let* (,@dims (%output-var 0)) (declare (type ext:array-index %output-var ,@dim-names) @@ -221,32 +221,32 @@ for dim-var in dim-names when (plusp i) collect `(setf %output-var - (truly-the ext:array-index (* %output-var ,dim-var))) + (ext:truly-the ext:array-index (* %output-var ,dim-var))) collect `(let ((%ndx-var ,index)) (declare (ext:array-index %ndx-var)) ,(and check `(check-index-in-bounds ,a %ndx-var ,dim-var)) (setf %output-var - (truly-the ext:array-index (+ %output-var %ndx-var))))) + (ext:truly-the ext:array-index (+ %output-var %ndx-var))))) %output-var)))) ;(trace c::expand-row-major-index c::expand-aset c::expand-aref) (defmacro check-expected-rank (a expected-rank) - `(c-inline + `(ffi:c-inline (,a ,expected-rank) (:object :fixnum) :void "if (ecl_unlikely((#0)->array.rank != (#1))) FEwrong_dimensions(#0,#1);" :one-liner nil)) (defmacro check-index-in-bounds (array index limit) - `(c-inline + `(ffi:c-inline (,array ,index ,limit) (:object :fixnum :fixnum) :void "if (ecl_unlikely((#1)>=(#2))) FEwrong_index(ECL_NIL,#0,-1,ecl_make_fixnum(#1),#2);" :one-liner nil)) (defmacro check-vector-in-bounds (vector index) - `(c-inline + `(ffi:c-inline (,vector ,index) (:object :fixnum) :void "if (ecl_unlikely((#1)>=(#0)->vector.dim)) FEwrong_index(ECL_NIL,#0,-1,ecl_make_fixnum(#1),(#0)->vector.dim);" @@ -262,7 +262,7 @@ for c-code = (format nil "(#0)->array.dims[~D]" i) collect `((:object) :fixnum ,c-code :one-liner t :side-effects nil))))) - `(c-inline (,array) ,@(aref tails n)))) + `(ffi:c-inline (,array) ,@(aref tails n)))) (defmacro array-dimension-fast (array n) (if (typep n '(integer 0 #.(1- array-rank-limit))) diff --git a/src/cmp/cmpc-inliner.lsp b/src/cmp/cmpc-inliner.lsp index ed0540d419b03b9adc2536f400444bdfde737d85..a507a4d232eb41d99ae6982215bb43d178667b4e 100644 --- a/src/cmp/cmpc-inliner.lsp +++ b/src/cmp/cmpc-inliner.lsp @@ -51,14 +51,14 @@ ;; the variable *INLINE-BLOCKS*. (and (inline-possible fname) (not (gethash fname *c2-dispatch-table*)) - (let* ((dest-rep-type (loc-representation-type *destination*)) + (let* (;; (dest-rep-type (loc-representation-type *destination*)) (ii (get-inline-info fname arg-types return-type return-rep-type))) ii))) (defun apply-inline-info (ii inlined-locs) (let* ((arg-types (inline-info-arg-types ii)) (out-rep-type (inline-info-return-rep-type ii)) - (out-type (inline-info-return-type ii)) + ;; (out-type (inline-info-return-type ii)) (side-effects-p (function-may-have-side-effects (inline-info-name ii))) (fun (inline-info-expansion ii)) (one-liner (inline-info-one-liner ii))) diff --git a/src/cmp/cmpc-wt.lsp b/src/cmp/cmpc-wt.lsp index 1a681455c5e3888fffdc59637900a0123e339758..4514a4640642ba9fb96c0244506cd519de96bbc5 100644 --- a/src/cmp/cmpc-wt.lsp +++ b/src/cmp/cmpc-wt.lsp @@ -64,14 +64,16 @@ (mapc #'wt1 forms)) ;;; Blocks beyond this value will not be indented -(defvar +max-depth+ 10) +(eval-when (:compile-toplevel :load-toplevel :execute) + (defvar +max-depth+ 10)) + (defvar +c-newline-indent-strings+ #.(coerce (let ((basis (make-array (1+ +max-depth+) :initial-element #\Space :element-type 'base-char))) (setf (aref basis 0) #\Newline) (loop for i from 0 to +max-depth+ - collect (subseq basis 0 (1+ i)))) + collect (subseq basis 0 (1+ i)))) 'vector)) (defun wt-nl-indent () @@ -136,7 +138,7 @@ ((or (eq c #\Newline) (eq c #\Tab)) (princ c stream)) ((or (< code 32) (> code 127)) - (format stream "\ux" code)) + (format stream "\u~x" code)) ((and (char= c #\*) (char= (schar text (1+ n)) #\/)) (princ #\\ stream)) (t @@ -178,12 +180,13 @@ :element-type 'base-char :adjustable t :fill-pointer 0)) - (stream (make-sequence-output-stream output :external-format format))) + (stream (ext:make-sequence-output-stream output :external-format format))) (write-string string stream) output)) (defun wt-filtered-data (string stream &key one-liner (external-format #-unicode :default #+unicode :utf-8)) + (declare (ignorable external-format)) #+unicode (setf string (encode-string string external-format)) (let ((N (length string)) diff --git a/src/cmp/cmpcond.lsp b/src/cmp/cmpcond.lsp new file mode 100644 index 0000000000000000000000000000000000000000..c16cae49ee0297b0d32809a8cf6c8aeec1aed008 --- /dev/null +++ b/src/cmp/cmpcond.lsp @@ -0,0 +1,212 @@ + +;;;; Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya +;;;; Copyright (c) 1990, Giuseppe Attardi +;;;; Copyright (c) 2003, Juan Jose Garcia-Ripoll +;;;; Copyright (c) 2023, Daniel Kochmański +;;;; +;;;; See file 'LICENSE' for the copyright details. + +(in-package #:compiler) + +#+cmu-format +(progn + (defconstant +note-format+ "~&~@< ~;~?~;~:@>") + (defconstant +warn-format+ "~&~@< ! ~;~?~;~:@>") + (defconstant +error-format+ "~&~@< * ~;~?~;~:@>") + (defconstant +fatal-format+ "~&~@< ** ~;~?~;~:@>")) +#-cmu-format +(progn + (defconstant +note-format+ "~& ~?") + (defconstant +warn-format+ "~& ! ~?") + (defconstant +error-format+ "~& * ~?") + (defconstant +fatal-format+ "~& ** ~?")) + +;; For indirect use in :REPORT functions +(defun compiler-message-report (stream c format-control &rest format-arguments) + (let ((position (compiler-message-file-position c)) + (prefix (compiler-message-prefix c)) + (file (compiler-message-file c)) + (form (innermost-non-expanded-form (compiler-message-toplevel-form c)))) + (if (and form + position + (not (minusp position)) + (not (equalp form '|compiler preprocess|))) + (let* ((*print-length* 2) + (*print-level* 2)) + (format stream + "~A:~% in file ~A, position ~D~& at ~A" + prefix + (make-pathname :name (pathname-name file) + :type (pathname-type file) + :version (pathname-version file)) + position + form)) + (format stream "~A:" prefix)) + (format stream (compiler-message-format c) + format-control + format-arguments))) + +(define-condition compiler-message (simple-condition) + ((prefix :initform "Note" :accessor compiler-message-prefix) + (format :initform +note-format+ :accessor compiler-message-format) + (file :initarg :file :initform *compile-file-pathname* + :accessor compiler-message-file) + (position :initarg :file :initform *compile-file-position* + :accessor compiler-message-file-position) + (toplevel-form :initarg :form :initform *current-toplevel-form* + :accessor compiler-message-toplevel-form) + (form :initarg :form :initform *current-form* + :accessor compiler-message-form)) + (:report (lambda (c stream) + (apply #'compiler-message-report stream c + (simple-condition-format-control c) + (simple-condition-format-arguments c))))) + +(define-condition compiler-note (compiler-message) ()) + +(define-condition compiler-debug-note (compiler-note) ()) + +(define-condition compiler-warning (compiler-message style-warning) + ((prefix :initform "Warning") + (format :initform +warn-format+))) + +(define-condition compiler-macro-expansion-failed (compiler-warning) + ()) + +(define-condition compiler-error (compiler-message) + ((prefix :initform "Error") + (format :initform +error-format+))) + +(define-condition compiler-fatal-error (compiler-error) + ((format :initform +fatal-format+))) + +(define-condition compiler-internal-error (compiler-fatal-error) + ((prefix :initform "Internal error"))) + +(define-condition compiler-style-warning (compiler-message style-warning) + ((prefix :initform "Style warning") + (format :initform +warn-format+))) + +(define-condition compiler-undefined-variable (compiler-style-warning) + ((variable :initarg :name :initform nil)) + (:report + (lambda (c stream) + (compiler-message-report stream c + "Variable ~A was undefined. ~ + Compiler assumes it is a global." + (slot-value c 'variable))))) + +(define-condition circular-dependency (compiler-error) + () + (:report + (lambda (c stream) + (compiler-message-report stream c + "Circular references in creation form for ~S." + (compiler-message-form c))))) + +(defun print-compiler-message (c stream) + (unless (typep c *suppress-compiler-messages*) + #+cmu-format + (format stream "~&~@<;;; ~@;~A~:>" c) + #-cmu-format + (format stream "~&;;; ~A" c))) + +;;; A few notes about the following handlers. We want the user to be +;;; able to capture, collect and perhaps abort on the different +;;; conditions signaled by the compiler. Since the compiler uses +;;; HANDLER-BIND, the only way to let this happen is either let the +;;; handler return or use SIGNAL at the beginning of the handler and +;;; let the outer handler intercept. +;;; +;;; In neither case do we want to enter the the debugger. That means +;;; we can not derive the compiler conditions from SERIOUS-CONDITION. +;;; +(defun handle-compiler-note (c) + (declare (ignore c)) + nil) + +(defun handle-compiler-warning (c) + (push c *compiler-conditions*) + nil) + +(defun handle-compiler-error (c) + (signal c) + (push c *compiler-conditions*) + (print-compiler-message c t) + (abort)) + +(defun handle-compiler-internal-error (c) + (when *compiler-break-enable* + (invoke-debugger c)) + (setf c (make-condition 'compiler-internal-error + :format-control "~A" + :format-arguments (list c))) + (push c *compiler-conditions*) + (signal c) + (print-compiler-message c t) + (abort)) + +(defmacro cmpck (condition string &rest args) + `(if ,condition (cmperr ,string ,@args))) + +(defmacro cmpassert (condition string &rest args) + `(unless ,condition (cmperr ,string ,@args))) + +(defun cmperr (string &rest args) + (let ((c (make-condition 'compiler-error + :format-control string + :format-arguments args))) + (signal c) + (print-compiler-message c t) + (abort))) + +(defun too-many-args (name upper-bound n &aux (*print-case* :upcase)) + (cmperr "~S requires at most ~R argument~:p, but ~R ~:*~[were~;was~:;were~] supplied.~%" + name upper-bound n)) + +(defun too-few-args (name lower-bound n) + (cmperr "~S requires at least ~R argument~:p, but only ~R ~:*~[were~;was~:;were~] supplied.~%" + name lower-bound n)) + +(defun do-cmpwarn (&rest args) + (declare (si::c-local)) + (let ((condition (apply #'make-condition args))) + (restart-case (signal condition) + (muffle-warning () + :REPORT "Skip warning" + (return-from do-cmpwarn nil))) + (print-compiler-message condition t))) + +(defun cmpwarn-style (string &rest args) + (do-cmpwarn 'compiler-style-warning :format-control string :format-arguments args)) + +(defun cmpwarn (string &rest args) + (do-cmpwarn 'compiler-warning :format-control string :format-arguments args)) + +(defun cmpnote (string &rest args) + (do-cmpwarn 'compiler-note :format-control string :format-arguments args)) + +(defun cmpdebug (string &rest args) + (do-cmpwarn 'compiler-debug-note :format-control string :format-arguments args)) + +(defun undefined-variable (sym) + (do-cmpwarn 'compiler-undefined-variable :name sym)) + +(defun baboon (&key (format-control "A bug was found in the compiler") + format-arguments) + (signal 'compiler-internal-error + :format-control format-control + :format-arguments format-arguments)) + +;;; This is not used (left for debugging). +(defmacro with-cmp-protection (main-form error-form) + `(let* ((si::*break-enable* *compiler-break-enable*) + (throw-flag t)) + (unwind-protect + (multiple-value-prog1 + (if *compiler-break-enable* + (handler-bind ((error #'invoke-debugger)) + ,main-form) + ,main-form) + (setf throw-flag nil)) + (when throw-flag ,error-form)))) diff --git a/src/cmp/cmpct.lsp b/src/cmp/cmpct.lsp index 5d37608b677ea2c6305fd76264bfc1102b159173..09a4265ec073cbfe9742239292d6b7a8918978d2 100644 --- a/src/cmp/cmpct.lsp +++ b/src/cmp/cmpct.lsp @@ -24,15 +24,15 @@ (cond ((symbolp name) (let* ((value (symbol-value name)) (type (lisp-type->rep-type (type-of value)))) - (cons value `(c-inline () () ,type ,c-value - :one-liner t :side-effects nil)))) + (cons value `(ffi:c-inline () () ,type ,c-value + :one-liner t :side-effects nil)))) ((floatp name) (let* ((value name) (type (type-of value)) (loc-type (case type - (single-float 'single-float-value) - (double-float 'double-float-value) - (long-float 'long-float-value) + (cl:single-float 'single-float-value) + (cl:double-float 'double-float-value) + (cl:long-float 'long-float-value) (si:complex-single-float 'csfloat-value) (si:complex-double-float 'cdfloat-value) (si:complex-long-float 'clfloat-value))) @@ -54,12 +54,12 @@ '( ;; Order is important: on platforms where 0.0 and -0.0 are the same ;; the last one is prioritized. - (#.(coerce 0 'single-float) "cl_core.singlefloat_zero") - (#.(coerce 0 'double-float) "cl_core.doublefloat_zero") - (#.(coerce -0.0 'single-float) "cl_core.singlefloat_minus_zero") - (#.(coerce -0.0 'double-float) "cl_core.doublefloat_minus_zero") - (#.(coerce 0 'long-float) "cl_core.longfloat_zero") - (#.(coerce -0.0 'long-float) "cl_core.longfloat_minus_zero") + (#.(coerce 0 'cl:single-float) "cl_core.singlefloat_zero") + (#.(coerce 0 'cl:double-float) "cl_core.doublefloat_zero") + (#.(coerce -0.0 'cl:single-float) "cl_core.singlefloat_minus_zero") + (#.(coerce -0.0 'cl:double-float) "cl_core.doublefloat_minus_zero") + (#.(coerce 0 'cl:long-float) "cl_core.longfloat_zero") + (#.(coerce -0.0 'cl:long-float) "cl_core.longfloat_minus_zero") ;; We temporarily remove this constant, because the bytecodes compiler ;; does not know how to externalize it. @@ -74,45 +74,45 @@ ) (when (eq machine *default-machine*) ;; Constants which are not portable - `((MOST-POSITIVE-SHORT-FLOAT "FLT_MAX") - (MOST-POSITIVE-SINGLE-FLOAT "FLT_MAX") - - (MOST-NEGATIVE-SHORT-FLOAT "-FLT_MAX") - (MOST-NEGATIVE-SINGLE-FLOAT "-FLT_MAX") - - (LEAST-POSITIVE-SHORT-FLOAT "FLT_TRUE_MIN") - (LEAST-POSITIVE-SINGLE-FLOAT "FLT_TRUE_MIN") - (LEAST-POSITIVE-NORMALIZED-SHORT-FLOAT "FLT_MIN") - (LEAST-POSITIVE-NORMALIZED-SINGLE-FLOAT" FLT_MIN") - - (LEAST-NEGATIVE-SHORT-FLOAT "-FLT_TRUE_MIN") - (LEAST-NEGATIVE-SINGLE-FLOAT "-FLT_TRUE_MIN") - (LEAST-NEGATIVE-NORMALIZED-SHORT-FLOAT "-FLT_MIN") - (LEAST-NEGATIVE-NORMALIZED-SINGLE-FLOAT "-FLT_MIN") - - (MOST-POSITIVE-DOUBLE-FLOAT "DBL_MAX") - (MOST-NEGATIVE-DOUBLE-FLOAT "-DBL_MAX") - (LEAST-POSITIVE-DOUBLE-FLOAT "DBL_TRUE_MIN") - (LEAST-POSITIVE-NORMALIZED-DOUBLE-FLOAT "DBL_MIN") - (LEAST-NEGATIVE-DOUBLE-FLOAT "-DBL_TRUE_MIN") - (LEAST-NEGATIVE-NORMALIZED-DOUBLE-FLOAT "-DBL_MIN") + `((cl:most-positive-short-float "FLT_MAX") + (cl:most-positive-single-float "FLT_MAX") + + (cl:most-negative-short-float "-FLT_MAX") + (cl:most-negative-single-float "-FLT_MAX") + + (cl:least-positive-short-float "FLT_TRUE_MIN") + (cl:least-positive-single-float "FLT_TRUE_MIN") + (cl:least-positive-normalized-short-float "FLT_MIN") + (cl:least-positive-normalized-single-float" FLT_MIN") + + (cl:least-negative-short-float "-FLT_TRUE_MIN") + (cl:least-negative-single-float "-FLT_TRUE_MIN") + (cl:least-negative-normalized-short-float "-FLT_MIN") + (cl:least-negative-normalized-single-float "-FLT_MIN") + + (cl:most-positive-double-float "DBL_MAX") + (cl:most-negative-double-float "-DBL_MAX") + (cl:least-positive-double-float "DBL_TRUE_MIN") + (cl:least-positive-normalized-double-float "DBL_MIN") + (cl:least-negative-double-float "-DBL_TRUE_MIN") + (cl:least-negative-normalized-double-float "-DBL_MIN") #+ieee-floating-point - ,@'((SHORT-FLOAT-POSITIVE-INFINITY "INFINITY") - (SINGLE-FLOAT-POSITIVE-INFINITY "INFINITY") - (DOUBLE-FLOAT-POSITIVE-INFINITY "INFINITY") - - (SHORT-FLOAT-NEGATIVE-INFINITY "-INFINITY") - (SINGLE-FLOAT-NEGATIVE-INFINITY "-INFINITY") - (DOUBLE-FLOAT-NEGATIVE-INFINITY "-INFINITY")) - - ,@'((MOST-POSITIVE-LONG-FLOAT "LDBL_MAX") - (MOST-NEGATIVE-LONG-FLOAT "-LDBL_MAX") - (LEAST-POSITIVE-LONG-FLOAT "LDBL_TRUE_MIN") - (LEAST-POSITIVE-NORMALIZED-LONG-FLOAT" LDBL_MIN") - (LEAST-NEGATIVE-LONG-FLOAT "-LDBL_TRUE_MIN") - (LEAST-NEGATIVE-NORMALIZED-LONG-FLOAT "-LDBL_MIN") + ,@'((ext:short-float-positive-infinity "INFINITY") + (ext:single-float-positive-infinity "INFINITY") + (ext:double-float-positive-infinity "INFINITY") + + (ext:short-float-negative-infinity "-INFINITY") + (ext:single-float-negative-infinity "-INFINITY") + (ext:double-float-negative-infinity "-INFINITY")) + + ,@'((cl:most-positive-long-float "LDBL_MAX") + (cl:most-negative-long-float "-LDBL_MAX") + (cl:least-positive-long-float "LDBL_TRUE_MIN") + (cl:least-positive-normalized-long-float" LDBL_MIN") + (cl:least-negative-long-float "-LDBL_TRUE_MIN") + (cl:least-negative-normalized-long-float "-LDBL_MIN") #+ieee-floating-point - (LONG-FLOAT-POSITIVE-INFINITY "INFINITY") + (ext:long-float-positive-infinity "INFINITY") #+ieee-floating-point - (LONG-FLOAT-NEGATIVE-INFINITY "-INFINITY")))))) + (ext:long-float-negative-infinity "-INFINITY")))))) diff --git a/src/cmp/cmpenv-api.lsp b/src/cmp/cmpenv-api.lsp index 8967c1d64a868e7357a37251d66a74a738919664..8f4aed3fef5e09103a75c6375b66b8976a086477 100644 --- a/src/cmp/cmpenv-api.lsp +++ b/src/cmp/cmpenv-api.lsp @@ -19,86 +19,18 @@ (defun cmp-env-root (&optional (env *cmp-env-root*)) "Provide a root environment for toplevel forms storing all declarations that are susceptible to be changed by PROCLAIM." - (let* ((env (cmp-env-copy env))) + (let ((env (cmp-env-copy env))) (add-default-optimizations env))) (defun cmp-env-copy (&optional (env *cmp-env*)) (cons (car env) (cdr env))) -(defun set-closure-env (definition lexenv &optional (env *cmp-env*)) - "Set up an environment for compilation of closures: Register closed -over macros in the compiler environment and enclose the definition of -the closure in let/flet forms for variables/functions it closes over." - (loop for record in lexenv - do (cond ((not (listp record)) - (multiple-value-bind (record-def record-lexenv) - (function-lambda-expression record) - (cond ((eql (car record-def) 'LAMBDA) - (setf record-def (cdr record-def))) - ((eql (car record-def) 'EXT:LAMBDA-BLOCK) - (setf record-def (cddr record-def))) - (t - (error "~&;;; Error: Not a valid lambda expression: ~s." record-def))) - ;; allow for closures which close over closures. - ;; (first record-def) is the lambda list, (rest - ;; record-def) the definition of the local function - ;; in record - (setf (rest record-def) - (list (set-closure-env (if (= (length record-def) 2) - (second record-def) - `(progn ,@(rest record-def))) - record-lexenv env))) - (setf definition - `(flet ((,(compiled-function-name record) - ,@record-def)) - ,definition)))) - ((and (listp record) (symbolp (car record))) - (cond ((eq (car record) 'si::macro) - (cmp-env-register-macro (cddr record) (cadr record) env)) - ((eq (car record) 'si::symbol-macro) - (cmp-env-register-symbol-macro-function (cddr record) (cadr record) env)) - (t - (setf definition - `(let ((,(car record) ',(cdr record))) - ,definition))) - )) - ;; ((and (integerp (cdr record)) (= (cdr record) 0)) - ;; Tags: We have lost the information, which tag - ;; corresponds to the lex-env record. If we are - ;; compiling a closure over a tag, we will get an - ;; error later on. - ;; ) - ;; (t - ;; Blocks: Not yet implemented - ) - finally (return definition))) - (defmacro cmp-env-variables (&optional (env '*cmp-env*)) `(car ,env)) (defmacro cmp-env-functions (&optional (env '*cmp-env*)) `(cdr ,env)) -(defun cmp-env-cleanups (env) - (loop with specials = '() - with end = (cmp-env-variables env) - with cleanup-forms = '() - with aux - for records-list on (cmp-env-variables *cmp-env*) - until (eq records-list end) - do (let ((record (first records-list))) - (cond ((atom record)) - ((and (symbolp (first record)) - (eq (second record) :special)) - (push (fourth record) specials)) - ((eq (first record) :cleanup) - (push (second record) cleanup-forms)))) - finally (progn - (unless (eq records-list end) - (error "Inconsistency in environment.")) - (return (values specials - (apply #'nconc (mapcar #'copy-list cleanup-forms))))))) - (defun cmp-env-register-var (var &optional (env *cmp-env*) (boundp t)) (push (list (var-name var) (if (member (var-kind var) '(special global)) @@ -109,13 +41,6 @@ the closure in let/flet forms for variables/functions it closes over." (cmp-env-variables env)) env) -(defun cmp-env-declare-special (name &optional (env *cmp-env*)) - (when (cmp-env-search-symbol-macro name env) - (cmperr "Symbol ~A cannot be declared special and appear in a symbol-macrolet." name)) - (cmp-env-register-var (c::c1make-global-variable name :warn nil :kind 'SPECIAL) - env nil) - env) - (defun cmp-env-add-declaration (type arguments &optional (env *cmp-env*)) (push (list* :declare type arguments) (cmp-env-variables env)) @@ -137,7 +62,7 @@ the closure in let/flet forms for variables/functions it closes over." (values)) (defun cmp-env-register-macro (name function &optional (env *cmp-env*)) - (push (list name 'si::macro function) + (push (list name 'si:macro function) (cmp-env-functions env)) env) @@ -154,7 +79,7 @@ the closure in let/flet forms for variables/functions it closes over." (defun cmp-env-register-symbol-macro-function (name function &optional (env *cmp-env*)) (when (or (constant-variable-p name) (special-variable-p name)) (cmperr "Cannot bind the special or constant variable ~A with symbol-macrolet." name)) - (push (list name 'si::symbol-macro function) + (push (list name 'si:symbol-macro function) (cmp-env-variables env)) env) @@ -168,10 +93,6 @@ the closure in let/flet forms for variables/functions it closes over." (cmp-env-variables env)) env) -(defun cmp-env-register-cleanup (form &optional (env *cmp-env*)) - (push (list :cleanup (copy-list form)) (cmp-env-variables env)) - env) - (defun cmp-env-search-function (name &optional (env *cmp-env*)) (let ((cfb nil) (unw nil) @@ -211,12 +132,12 @@ the closure in let/flet forms for variables/functions it closes over." (when (member name (second record) :test #'eql) (setf found record) (return))) - ((eq name 'si::symbol-macro) - (when (eq (second record) 'si::symbol-macro) + ((eq name 'si:symbol-macro) + (when (eq (second record) 'si:symbol-macro) (setf found record)) (return)) (t - (when (not (eq (second record) 'si::symbol-macro)) + (when (not (eq (second record) 'si:symbol-macro)) (setf found record)) (return)))) (values (first (last found)) cfb unw))) @@ -228,14 +149,22 @@ the closure in let/flet forms for variables/functions it closes over." (cmp-env-search-variables :tag name env)) (defun cmp-env-search-symbol-macro (name &optional (env *cmp-env*)) - (cmp-env-search-variables name 'si::symbol-macro env)) + (cmp-env-search-variables name 'si:symbol-macro env)) (defun cmp-env-search-var (name &optional (env *cmp-env*)) (cmp-env-search-variables name t env)) (defun cmp-env-search-macro (name &optional (env *cmp-env*)) (let ((f (cmp-env-search-function name env))) - (if (functionp f) f nil))) + (if (functionp f) + f + nil))) + +;;; Like macro-function except it searches the lexical environment, +;;; to determine if the macro is shadowed by a function or a macro. +(defun cmp-macro-function (name) + (or (cmp-env-search-macro name) + (macro-function name))) (defun cmp-env-search-ftype (name &optional (env *cmp-env*)) (dolist (i env nil) diff --git a/src/cmp/cmpenv-declaim.lsp b/src/cmp/cmpenv-declaim.lsp index c93efbe0016b235d852459e22d7f16cae6da9b49..4b189b79d241d71737ce0775264de7bd5b2e81ac 100644 --- a/src/cmp/cmpenv-declaim.lsp +++ b/src/cmp/cmpenv-declaim.lsp @@ -20,18 +20,18 @@ ;;;; stem from. ;;;; -(in-package #-ecl-new "COMPILER" #+ecl-new "C-ENV") +(in-package "COMPILER") (defun process-declaim-args (args) (flet ((add-variables (env types specials) (loop for name in specials unless (assoc name types) - do (let ((v (c1make-global-variable name :kind 'special))) + do (let ((v (make-global-var name :kind 'special))) (setf env (cmp-env-register-var v env nil)))) (loop for (name . type) in types - for specialp = (or (sys:specialp name) (member name specials)) + for specialp = (or (si:specialp name) (member name specials)) for kind = (if specialp 'SPECIAL 'GLOBAL) - for v = (c1make-global-variable name :type type :kind kind) + for v = (make-global-var name :type type :kind kind) do (setf env (cmp-env-register-var v env nil))) env)) (multiple-value-bind (body specials types ignored others doc all) diff --git a/src/cmp/cmpenv-declare.lsp b/src/cmp/cmpenv-declare.lsp index a7b6c75bb7f7954e22b50414143ba0321cbedc5b..9e709970f93300ccfec2209ff8d63bdd8dd2da26 100644 --- a/src/cmp/cmpenv-declare.lsp +++ b/src/cmp/cmpenv-declare.lsp @@ -18,10 +18,10 @@ ;;;; compiled file and do not propagate beyond it. ;;;; -(in-package #-ecl-new "COMPILER" #+ecl-new "C-ENV") +(in-package "COMPILER") (defun valid-form-p (x &optional test) - (and (si::proper-list-p x) + (and (si:proper-list-p x) (or (null test) (every test x)))) @@ -43,16 +43,19 @@ (member name (cmp-env-search-declaration 'alien env si::*alien-declarations*) :test 'eq))) +(defun policy-declaration-p (name) + (and (gethash name *optimization-quality-switches*) t)) + (defun parse-ignore-declaration (decl-args expected-ref-number tail) (declare (si::c-local)) (loop for name in decl-args - do (if (symbolp name) - (push (cons name expected-ref-number) tail) - (cmpassert (and (consp name) - (= (length name) 2) - (eq (first name) 'function)) - "Invalid argument to IGNORE/IGNORABLE declaration:~&~A" - name))) + do (if (symbolp name) + (push (cons name expected-ref-number) tail) + (cmpassert (and (consp name) + (= (length name) 2) + (eq (first name) 'function)) + "Invalid argument to IGNORE/IGNORABLE declaration:~&~A" + name))) tail) (defun collect-declared (type var-list tail) @@ -80,16 +83,16 @@ and a possible documentation string (only accepted when DOC-P is true)." (valid-type-specifier decl-name)))) "Syntax error in declaration ~s" decl) do (case decl-name - (SPECIAL) - (IGNORE + (cl:SPECIAL) + (cl:IGNORE (cmpassert (valid-form-p decl-args) "Syntax error in declaration ~s" decl) (setf ignored (parse-ignore-declaration decl-args -1 ignored))) - (IGNORABLE + (cl:IGNORABLE (cmpassert (valid-form-p decl-args) "Syntax error in declaration ~s" decl) (setf ignored (parse-ignore-declaration decl-args 0 ignored))) - (TYPE + (cl:TYPE (cmpassert (and (consp decl-args) (valid-form-p (rest decl-args) #'symbolp)) "Syntax error in declaration ~s" decl) @@ -100,14 +103,14 @@ and a possible documentation string (only accepted when DOC-P is true)." (cmpassert (valid-form-p decl-args #'symbolp) "Syntax error in declaration ~s" decl) (setf types (collect-declared 'OBJECT decl-args types))) - ((OPTIMIZE FTYPE INLINE NOTINLINE DECLARATION SI::C-LOCAL - SI::C-GLOBAL DYNAMIC-EXTENT IGNORABLE VALUES + ((cl:OPTIMIZE cl:FTYPE cl:INLINE cl:NOTINLINE cl:DECLARATION SI::C-LOCAL + SI::C-GLOBAL cl:DYNAMIC-EXTENT cl:VALUES SI::NO-CHECK-TYPE POLICY-DEBUG-IHS-FRAME :READ-ONLY) (push decl others)) (SI:FUNCTION-BLOCK-NAME) (otherwise (if (or (alien-declaration-p decl-name) - (policy-declaration-name-p decl-name)) + (policy-declaration-p decl-name)) (push decl others) (multiple-value-bind (ok type) (if (machine-c-type-p decl-name) @@ -123,7 +126,7 @@ and a possible documentation string (only accepted when DOC-P is true)." "Add to the environment one declarations which is not type, ignorable or special variable declarations, as these have been extracted before." (case (car decl) - (OPTIMIZE + (cl:OPTIMIZE (cmp-env-add-optimizations (rest decl) env)) (POLICY-DEBUG-IHS-FRAME (let ((flag (or (rest decl) '(t)))) @@ -134,7 +137,7 @@ special variable declarations, as these have been extracted before." env) (cmp-env-add-declaration 'policy-debug-ihs-frame flag env)))) - (FTYPE + (cl:FTYPE (if (atom (rest decl)) (cmpwarn "Syntax error in declaration ~a" decl) (multiple-value-bind (type-name args) @@ -145,18 +148,18 @@ special variable declarations, as these have been extracted before." (cmpwarn "In an FTYPE declaration, found ~A which is not a function type." (second decl))))) env) - (INLINE + (cl:INLINE (loop for name in (rest decl) do (setf env (declare-inline name env))) env) - (NOTINLINE + (cl:NOTINLINE (loop for name in (rest decl) do (setf env (declare-notinline name env))) env) - (DECLARATION + (cl:DECLARATION (validate-alien-declaration (rest decl) #'cmperr) (cmp-env-extend-declaration 'alien (rest decl) env si::*alien-declarations*)) ((SI::C-LOCAL SI::C-GLOBAL SI::NO-CHECK-TYPE :READ-ONLY) env) - ((DYNAMIC-EXTENT IGNORABLE SI:FUNCTION-BLOCK-NAME) + ((cl:DYNAMIC-EXTENT cl:IGNORABLE SI:FUNCTION-BLOCK-NAME) ;; FIXME! SOME ARE IGNORED! env) (otherwise @@ -168,7 +171,7 @@ special variable declarations, as these have been extracted before." env))))) (defun symbol-macro-declaration-p (name type) - (when-let ((record (cmp-env-search-symbol-macro name))) + (ext:when-let ((record (cmp-env-search-symbol-macro name))) (let* ((expression (funcall record name nil))) (cmp-env-register-symbol-macro name `(the ,type ,expression))) t)) diff --git a/src/cmp/cmpenv-fun.lsp b/src/cmp/cmpenv-fun.lsp index 479d31ab999434df49ee40e5d5d15f1ee6e7b35c..0c55a5165f3248bb22cdead8b8af3da105d89451 100644 --- a/src/cmp/cmpenv-fun.lsp +++ b/src/cmp/cmpenv-fun.lsp @@ -64,37 +64,33 @@ env) (defun get-arg-types (fname &optional (env *cmp-env*) (may-be-global t)) - (let ((x (cmp-env-search-ftype fname env))) - (if x - (let ((arg-types (first x))) - (unless (eq arg-types '*) - (values arg-types t))) - (when may-be-global - (let ((fun (cmp-env-search-function fname env))) - (when (or (null fun) (and (fun-p fun) (fun-global fun))) - (sys:get-sysprop fname 'PROCLAIMED-ARG-TYPES))))))) + (ext:if-let ((x (cmp-env-search-ftype fname env))) + (let ((arg-types (first x))) + (unless (eq arg-types '*) + (values arg-types t))) + (when may-be-global + (let ((fun (cmp-env-search-function fname env))) + (when (or (null fun) (and (fun-p fun) (fun-global fun))) + (si:get-sysprop fname 'PROCLAIMED-ARG-TYPES)))))) (defun get-return-type (fname &optional (env *cmp-env*)) - (let ((x (cmp-env-search-ftype fname env))) - (if x - (let ((return-types (second x))) - (unless (eq return-types '*) - (values return-types t))) - (let ((fun (cmp-env-search-function fname env))) - (when (or (null fun) (and (fun-p fun) (fun-global fun))) - (sys:get-sysprop fname 'PROCLAIMED-RETURN-TYPE)))))) + (ext:if-let ((x (cmp-env-search-ftype fname env))) + (let ((return-types (second x))) + (unless (eq return-types '*) + (values return-types t))) + (let ((fun (cmp-env-search-function fname env))) + (when (or (null fun) (and (fun-p fun) (fun-global fun))) + (si:get-sysprop fname 'PROCLAIMED-RETURN-TYPE))))) (defun get-local-arg-types (fun &optional (env *cmp-env*)) - (let ((x (cmp-env-search-ftype (fun-name fun) env))) - (if x - (values (first x) t) - (values nil nil)))) + (ext:if-let ((x (cmp-env-search-ftype (fun-name fun) env))) + (values (first x) t) + (values nil nil))) (defun get-local-return-type (fun &optional (env *cmp-env*)) - (let ((x (cmp-env-search-ftype (fun-name fun) env))) - (if x - (values (second x) t) - (values nil nil)))) + (ext:if-let ((x (cmp-env-search-ftype (fun-name fun) env))) + (values (second x) t) + (values nil nil))) (defun get-proclaimed-narg (fun &optional (env *cmp-env*)) (multiple-value-bind (arg-list found) @@ -131,30 +127,30 @@ (dolist (fun fname-list) (unless (si::valid-function-name-p fun) (error "Not a valid function name ~s in INLINE proclamation" fun)) - (unless (sys:get-sysprop fun 'INLINE) - (sys:put-sysprop fun 'INLINE t) - (sys:rem-sysprop fun 'NOTINLINE)))) + (unless (si:get-sysprop fun 'INLINE) + (si:put-sysprop fun 'INLINE t) + (si:rem-sysprop fun 'NOTINLINE)))) (defun proclaim-notinline (fname-list) (dolist (fun fname-list) (unless (si::valid-function-name-p fun) (error "Not a valid function name ~s in NOTINLINE proclamation" fun)) - (sys:rem-sysprop fun 'INLINE) - (sys:put-sysprop fun 'NOTINLINE t))) + (si:rem-sysprop fun 'INLINE) + (si:put-sysprop fun 'NOTINLINE t))) (defun declared-inline-p (fname &optional (env *cmp-env*)) (let* ((x (cmp-env-search-declaration 'inline env)) (flag (assoc fname x :test #'same-fname-p))) (if flag (cdr flag) - (sys:get-sysprop fname 'INLINE)))) + (si:get-sysprop fname 'INLINE)))) (defun declared-notinline-p (fname &optional (env *cmp-env*)) (let* ((x (cmp-env-search-declaration 'inline env)) (flag (assoc fname x :test #'same-fname-p))) (if flag (null (cdr flag)) - (sys:get-sysprop fname 'NOTINLINE)))) + (si:get-sysprop fname 'NOTINLINE)))) (defun inline-possible (fname &optional (env *cmp-env*)) (not (declared-notinline-p fname env))) @@ -177,3 +173,50 @@ `(eval-when (:load-toplevel :execute) (si:put-sysprop ',fname 'inline ',form)))) +(defun set-closure-env (definition lexenv &optional (env *cmp-env*)) + "Set up an environment for compilation of closures: Register closed +over macros in the compiler environment and enclose the definition of +the closure in let/flet forms for variables/functions it closes over." + (loop for record in lexenv + do (cond ((not (listp record)) + (multiple-value-bind (record-def record-lexenv) + (function-lambda-expression record) + (cond ((eql (car record-def) 'LAMBDA) + (setf record-def (cdr record-def))) + ((eql (car record-def) 'EXT:LAMBDA-BLOCK) + (setf record-def (cddr record-def))) + (t + (error "~&;;; Error: Not a valid lambda expression: ~s." record-def))) + ;; allow for closures which close over closures. + ;; (first record-def) is the lambda list, (rest + ;; record-def) the definition of the local function + ;; in record + (setf (rest record-def) + (list (set-closure-env (if (= (length record-def) 2) + (second record-def) + `(progn ,@(rest record-def))) + record-lexenv env))) + (setf definition + `(flet ((,(ext:compiled-function-name record) + ,@record-def)) + ,definition)))) + ((and (listp record) (symbolp (car record))) + (cond ((eq (car record) 'si:macro) + (cmp-env-register-macro (cddr record) (cadr record) env)) + ((eq (car record) 'si:symbol-macro) + (cmp-env-register-symbol-macro-function (cddr record) (cadr record) env)) + (t + (setf definition + `(let ((,(car record) ',(cdr record))) + ,definition))) + )) + ;; ((and (integerp (cdr record)) (= (cdr record) 0)) + ;; Tags: We have lost the information, which tag + ;; corresponds to the lex-env record. If we are + ;; compiling a closure over a tag, we will get an + ;; error later on. + ;; ) + ;; (t + ;; Blocks: Not yet implemented + ) + finally (return definition))) diff --git a/src/cmp/cmpenv-optimize.lsp b/src/cmp/cmpenv-optimize.lsp new file mode 100644 index 0000000000000000000000000000000000000000..7ac1af9d7f3d97be13ee3d2c2cd898d2e84e374a --- /dev/null +++ b/src/cmp/cmpenv-optimize.lsp @@ -0,0 +1,170 @@ + +;;;; Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya +;;;; Copyright (c) 1990, Giuseppe Attardi +;;;; Copyright (c) 2003, Juan Jose Garcia-Ripoll +;;;; Copyright (c) 2023, Daniel Kochmański +;;;; +;;;; See the file 'LICENSE' for the copyright details. + +(in-package #:compiler) + +(defun default-policy () + (compute-policy `((space ,*space*) + (safety ,*safety*) + (debug ,*debug*) + (speed ,*speed*) + (compilation-speed ,*compilation-speed*)) + 0)) + +(defun cmp-env-policy (env) + (or (first (cmp-env-search-declaration 'optimization env)) + (default-policy))) + +(defun add-default-optimizations (env) + (if (cmp-env-search-declaration 'optimization env) + env + (cmp-env-add-declaration 'optimization (list (default-policy)) env))) + +(defun cmp-env-add-optimizations (decl &optional (env *cmp-env*)) + (let* ((old (cmp-env-policy env)) + (new (compute-policy decl old))) + (cmp-env-add-declaration 'optimization (list new) env))) + +(defun maybe-add-policy (decl &optional (env *cmp-env*)) + (when (and (consp decl) + (<= (list-length decl) 2) + (gethash (first decl) *optimization-quality-switches*)) + (let* ((name (first decl)) + (value (if (or (endp (rest decl)) (second decl)) + (if (standard-optimization-quality-p name) + 3 + 1) + 0)) + (old-policy (cmp-env-policy env)) + (new-policy (compute-policy (list (list name value)) old-policy))) + (cmp-env-add-declaration 'optimization (list new-policy) env)))) + +(defun cmp-env-all-optimizations (&optional (env *cmp-env*)) + (let ((o (cmp-env-policy env))) + (list (policy-to-debug-level o) + (policy-to-safety-level o) + (policy-to-space-level o) + (policy-to-speed-level o)))) + +(defun cmp-env-optimization (property &optional (env *cmp-env*)) + (let ((o (cmp-env-policy env))) + (case property + (debug (policy-to-debug-level o)) + (safety (policy-to-safety-level o)) + (space (policy-to-space-level o)) + (speed (policy-to-speed-level o))))) + +(defun safe-compile () + (>= (cmp-env-optimization 'safety) 2)) + +(defun compiler-push-events () + (>= (cmp-env-optimization 'safety) 3)) + + + +;; +;; ERROR CHECKING POLICY +;; + +(define-policy ext:assume-no-errors + "All bets are off." + (:off safety 1)) + +(define-policy-alias ext:assume-right-type + "Don't insert optional runtime type checks for known types." + (:alias ext:assume-no-errors)) + +(define-policy-alias ext:type-assertions + "Generate type assertions when inlining accessors and other functions." + (:anti-alias ext:assume-no-errors)) + +(define-policy ext:check-stack-overflow + "Add a stack check to every function" + (:on safety 2)) + +(define-policy ext:check-arguments-type + "Generate CHECK-TYPE forms for function arguments with type declarations." + (:on safety 1)) + +(define-policy ext:array-bounds-check + "Check out of bounds access to arrays." + (:on safety 1)) + +(define-policy ext:global-var-checking + "Read the value of a global variable even if it is discarded, ensuring it is bound." + (:on safety 3)) + +(define-policy ext:global-function-checking + "Read the binding of a global function even if it is discarded." + (:on safety 3)) + +(define-policy ext:check-nargs + "Check that the number of arguments a function receives is within bounds." + (:on safety 1) + (:only-on ext:check-arguments-type)) + +(define-policy ext:the-is-checked + "THE is equivalent to EXT:CHECKED-VALUE. Otherwise THE is equivalent to EXT:TRULY-THE." + (:on safety 1)) + +;; +;; INLINING POLICY +;; + +(define-policy ext:assume-types-dont-change + "Assume that type and class definitions will not change." + (:off safety 1)) + +(define-policy ext:inline-slot-access + "Inline access to structures and sealed classes." + (:on speed 1) + (:off debug 2) + (:off safety 2)) + +(define-policy ext:inline-accessors + "Inline access to object slots, including conses and arrays." + (:off debug 2) + (:off space 2)) + +(define-policy ext:inline-bit-operations + "Inline LDB and similar functions." + (:off space 2)) + +(define-policy-alias ext:open-code-aref/aset + "Inline access to arrays." + (:alias ext:inline-accessors)) + +(define-policy ext:evaluate-forms + "Pre-evaluate a function that takes constant arguments." + (:off debug 1)) + +(define-policy ext:use-direct-C-call + "Emit direct calls to a function whose C name is known." + (:off debug 2)) + +(define-policy ext:inline-type-checks + "Expand TYPEP and similar forms in terms of simpler functions, such as FLOATP, INTGERP, STRINGP." + (:off space 2)) + +(define-policy ext:inline-sequence-functions + "Inline functions such as MAP, MEMBER, FIND, etc." + (:off space 2)) + +;; +;; DEBUG POLICY +;; + +(define-policy ext:debug-variable-bindings + "Create a debug vector with the bindings of each LET/LET*/LAMBDA form." + ;; We can only create variable bindings when the function has an IHS frame!!! + (:requires (policy-debug-ihs-frame env)) + (:on debug 3)) + +(define-policy ext:debug-ihs-frame + "Let the functions appear in backtraces." + (:on debug 3)) diff --git a/src/cmp/cmpenv-proclaim.lsp b/src/cmp/cmpenv-proclaim.lsp index 2d955b1e7c39fe94823c4d4f71cacc6a53e41d7c..de0bcc6f496506e44d9b4a2e1c631fa31adda2d2 100644 --- a/src/cmp/cmpenv-proclaim.lsp +++ b/src/cmp/cmpenv-proclaim.lsp @@ -25,17 +25,16 @@ (in-package #-ecl-new "COMPILER" #+ecl-new "C-ENV") -#-:CCL (defun proclaim (decl &aux decl-name) (unless (listp decl) (error "The proclamation specification ~s is not a list" decl)) (case (setf decl-name (car decl)) - (SPECIAL + (cl:SPECIAL (dolist (var (cdr decl)) (if (symbolp var) - (sys:*make-special var) + (si:*make-special var) (error "Syntax error in proclamation ~s" decl)))) - (OPTIMIZE + (cl:OPTIMIZE (dolist (x (cdr decl)) (when (symbolp x) (setq x (list x 3))) (if (or (not (consp x)) @@ -48,13 +47,13 @@ (SAFETY (setq *safety* (second x))) (SPACE (setq *space* (second x))) (SPEED (setq *speed* (second x))) - (COMPILATION-SPEED (setq *speed* (- 3 (second x)))) + (COMPILATION-SPEED (setq *compilation-speed* (second x))) (t (warn "The OPTIMIZE quality ~s is unknown." (car x))))))) - (TYPE + (cl:TYPE (if (consp (cdr decl)) (proclaim-var (second decl) (cddr decl)) (error "Syntax error in proclamation ~s" decl))) - (FTYPE + (cl:FTYPE (if (atom (rest decl)) (error "Syntax error in proclamation ~a" decl) (multiple-value-bind (type-name args) @@ -64,16 +63,16 @@ (proclaim-function v args)) (error "In an FTYPE proclamation, found ~A which is not a function type." (second decl)))))) - (INLINE + (cl:INLINE (proclaim-inline (cdr decl))) - (NOTINLINE + (cl:NOTINLINE (proclaim-notinline (cdr decl))) - ((OBJECT IGNORE DYNAMIC-EXTENT IGNORABLE) + ((OBJECT cl:IGNORE cl:DYNAMIC-EXTENT cl:IGNORABLE) ;; FIXME! IGNORED! (dolist (var (cdr decl)) (unless (si::valid-function-name-p var) (error "Not a valid function name ~s in ~s proclamation" var decl-name)))) - (DECLARATION + (cl:DECLARATION (validate-alien-declaration (rest decl) #'error) (setf si::*alien-declarations* (append (rest decl) si:*alien-declarations*))) (SI::C-EXPORT-FNAME @@ -91,12 +90,12 @@ (si:put-sysprop lisp-name 'Lfun c-name)))) (t (error "Syntax error in proclamation ~s" decl))))) - ((ARRAY ATOM BASE-CHAR BIGNUM BIT BIT-VECTOR CHARACTER COMPILED-FUNCTION - COMPLEX CONS DOUBLE-FLOAT EXTENDED-CHAR FIXNUM FLOAT HASH-TABLE INTEGER KEYWORD LIST - LONG-FLOAT NIL NULL NUMBER PACKAGE PATHNAME RANDOM-STATE RATIO RATIONAL - READTABLE SEQUENCE SHORT-FLOAT SIMPLE-ARRAY SIMPLE-BIT-VECTOR - SIMPLE-STRING SIMPLE-VECTOR SINGLE-FLOAT STANDARD-CHAR STREAM STRING - SYMBOL T VECTOR SIGNED-BYTE UNSIGNED-BYTE FUNCTION) + ((cl:ARRAY cl:ATOM cl:BASE-CHAR cl:BIGNUM cl:BIT cl:BIT-VECTOR cl:CHARACTER cl:COMPILED-FUNCTION + cl:COMPLEX cl:CONS cl:DOUBLE-FLOAT cl:EXTENDED-CHAR cl:FIXNUM cl:FLOAT cl:HASH-TABLE cl:INTEGER cl:KEYWORD cl:LIST + cl:LONG-FLOAT cl:NIL cl:NULL cl:NUMBER cl:PACKAGE cl:PATHNAME cl:RANDOM-STATE cl:RATIO cl:RATIONAL + cl:READTABLE cl:SEQUENCE cl:SHORT-FLOAT cl:SIMPLE-ARRAY cl:SIMPLE-BIT-VECTOR + cl:SIMPLE-STRING cl:SIMPLE-VECTOR cl:SINGLE-FLOAT cl:STANDARD-CHAR cl:STREAM cl:STRING + cl:SYMBOL cl:T cl:VECTOR cl:SIGNED-BYTE cl:UNSIGNED-BYTE cl:FUNCTION) (proclaim-var decl-name (cdr decl))) (otherwise (cond ((member (car decl) si:*alien-declarations*)) diff --git a/src/cmp/cmpenv-var.lsp b/src/cmp/cmpenv-var.lsp new file mode 100644 index 0000000000000000000000000000000000000000..295a97fc59ae3e495acb0775645d12966045e4e7 --- /dev/null +++ b/src/cmp/cmpenv-var.lsp @@ -0,0 +1,64 @@ + +;;;; Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya +;;;; Copyright (c) 1990, Giuseppe Attardi +;;;; Copyright (c) 2003, Juan Jose Garcia-Ripoll +;;;; Copyright (c) 2023, Daniel Kochmański +;;;; +;;;; See file 'LICENSE' for the copyright details. + +(in-package #:compiler) + +(defun declare-special (name &optional (env *cmp-env*)) + (when (cmp-env-search-symbol-macro name env) + (cmperr "Symbol ~A cannot be declared special and appear in a symbol-macrolet." name)) + (cmp-env-register-var (make-global-var name :warn nil :kind 'SPECIAL) env nil)) + +;;; A special binding creates a var object with the kind field SPECIAL, +;;; whereas a special declaration without binding creates a var object with +;;; the kind field GLOBAL. Thus a reference to GLOBAL may need to make sure +;;; that the variable has a value. + +;;; Bootstrap problem: proclaim needs this function: +;;; +;;; Check if a variable has been declared as a special variable with a global +;;; value. + +(defun check-global (name) + (member name *global-vars*)) + +(defun si::register-global (name) + (pushnew name *global-vars*) + (values)) + +(defun special-variable-p (name) + "Return true if NAME is associated to a special variable in the lexical environment." + (or (si::specialp name) + (check-global name) + (let ((v (cmp-env-search-var name *cmp-env-root*))) + ;; Fixme! Revise the declamation code to ensure whether + ;; we also have to consider 'GLOBAL here. + (and v (eq (var-kind v) 'SPECIAL))))) + +(defun constant-variable-p (name) + (si::constp name)) + +(defun local-variable-p (name &optional (env *cmp-env*)) + (let ((record (cmp-env-search-var name env))) + (and record (var-p record)))) + +(defun symbol-macro-p (name &optional (env *cmp-env*)) + (let ((record (cmp-env-search-var name env))) + (and record (not (var-p record))))) + +(defun read-only-variable-p (name other-decls) + (dolist (i other-decls nil) + (when (and (eq (car i) :READ-ONLY) + (member name (rest i))) + (return t)))) + +(defun variable-type-in-env (name &optional (env *cmp-env*)) + (let ((var (cmp-env-search-var name env))) + (cond ((var-p var) + (var-type var)) + ((si:get-sysprop name 'CMP-TYPE)) + (t)))) diff --git a/src/cmp/cmpform.lsp b/src/cmp/cmpform.lsp index d4800579ec37d68531dcd2c29af9dabed65f4ba8..e5ede9ad016ef87d1430c9381529adead3a0713c 100644 --- a/src/cmp/cmpform.lsp +++ b/src/cmp/cmpform.lsp @@ -26,9 +26,6 @@ ;;; lambda-list = (requireds optionals rest key-flag keywords allow-other-keys) ;;; -(defun print-c1form (form stream) - (format stream "#