1 ;;;; miscellaneous types and macros used in writing the compiler
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
14 (declaim (special *wild-type* *universal-type* *compiler-error-context*))
16 ;;; An INLINEP value describes how a function is called. The values
17 ;;; have these meanings:
18 ;;; NIL No declaration seen: do whatever you feel like, but don't
19 ;;; dump an inline expansion.
20 ;;; :NOTINLINE NOTINLINE declaration seen: always do full function call.
21 ;;; :INLINE INLINE declaration seen: save expansion, expanding to it
24 ;;; Retain expansion, but only use it opportunistically.
25 (deftype inlinep () '(member :inline :maybe-inline :notinline nil))
27 ;;;; source-hacking defining forms
29 ;;; to be passed to PARSE-DEFMACRO when we want compiler errors
30 ;;; instead of real errors
31 #!-sb-fluid (declaim (inline convert-condition-into-compiler-error))
32 (defun convert-condition-into-compiler-error (datum &rest stuff)
34 (apply #'compiler-error datum stuff)
37 (apply #'make-condition datum stuff)
40 ;;; Parse a DEFMACRO-style lambda-list, setting things up so that a
41 ;;; compiler error happens if the syntax is invalid.
43 ;;; Define a function that converts a special form or other magical
44 ;;; thing into IR1. LAMBDA-LIST is a defmacro style lambda list.
45 ;;; START-VAR and CONT-VAR are bound to the start and result
46 ;;; continuations for the resulting IR1. KIND is the function kind to
47 ;;; associate with NAME.
48 (defmacro def-ir1-translator (name (lambda-list start-var cont-var
49 &key (kind :special-form))
51 (let ((fn-name (symbolicate "IR1-CONVERT-" name))
54 (multiple-value-bind (body decls doc)
55 (parse-defmacro lambda-list n-form body name "special form"
57 :error-fun 'convert-condition-into-compiler-error)
59 (declaim (ftype (function (continuation continuation t) (values))
61 (defun ,fn-name (,start-var ,cont-var ,n-form)
62 (let ((,n-env *lexenv*))
67 `((setf (fdocumentation ',name 'function) ,doc)))
68 ;; FIXME: Evidently "there can only be one!" -- we overwrite any
69 ;; other :IR1-CONVERT value. This deserves a warning, I think.
70 (setf (info :function :ir1-convert ',name) #',fn-name)
71 (setf (info :function :kind ',name) ,kind)
72 ;; It's nice to do this for error checking in the target
73 ;; SBCL, but it's not nice to do this when we're running in
74 ;; the cross-compilation host Lisp, which owns the
75 ;; SYMBOL-FUNCTION of its COMMON-LISP symbols.
77 ,@(when (eq kind :special-form)
78 `((setf (symbol-function ',name)
80 (declare (ignore rest))
81 (error "can't FUNCALL the SYMBOL-FUNCTION of ~
82 special forms")))))))))
84 ;;; (This is similar to DEF-IR1-TRANSLATOR, except that we pass if the
85 ;;; syntax is invalid.)
87 ;;; Define a macro-like source-to-source transformation for the
88 ;;; function NAME. A source transform may "pass" by returning a
89 ;;; non-nil second value. If the transform passes, then the form is
90 ;;; converted as a normal function call. If the supplied arguments are
91 ;;; not compatible with the specified LAMBDA-LIST, then the transform
92 ;;; automatically passes.
94 ;;; Source transforms may only be defined for functions. Source
95 ;;; transformation is not attempted if the function is declared
96 ;;; NOTINLINE. Source transforms should not examine their arguments.
97 ;;; If it matters how the function is used, then DEFTRANSFORM should
98 ;;; be used to define an IR1 transformation.
100 ;;; If the desirability of the transformation depends on the current
101 ;;; OPTIMIZE parameters, then the POLICY macro should be used to
102 ;;; determine when to pass.
103 (defmacro def-source-transform (name lambda-list &body body)
110 (apply #'symbolicate "SOURCE-TRANSFORM" (pieces)))
111 (symbolicate "SOURCE-TRANSFORM-" name)))
114 (multiple-value-bind (body decls)
115 (parse-defmacro lambda-list n-form body name "form"
117 :error-fun `(lambda (&rest stuff)
118 (declare (ignore stuff))
119 (return-from ,fn-name
122 (defun ,fn-name (,n-form)
123 (let ((,n-env *lexenv*))
126 (setf (info :function :source-transform ',name) #',fn-name)))))
128 ;;; Define a function that converts a use of (%PRIMITIVE NAME ..)
129 ;;; into Lisp code. LAMBDA-LIST is a DEFMACRO-style lambda list.
130 (defmacro def-primitive-translator (name lambda-list &body body)
131 (let ((fn-name (symbolicate "PRIMITIVE-TRANSLATE-" name))
134 (multiple-value-bind (body decls)
135 (parse-defmacro lambda-list n-form body name "%primitive"
137 :error-fun 'convert-condition-into-compiler-error)
139 (defun ,fn-name (,n-form)
140 (let ((,n-env *lexenv*))
143 (setf (gethash ',name *primitive-translators*) ',fn-name)))))
145 ;;;; boolean attribute utilities
147 ;;;; We need to maintain various sets of boolean attributes for known
148 ;;;; functions and VOPs. To save space and allow for quick set
149 ;;;; operations, we represent the attributes as bits in a fixnum.
151 (deftype attributes () 'fixnum)
153 (eval-when (:compile-toplevel :load-toplevel :execute)
155 ;;; Given a list of attribute names and an alist that translates them
156 ;;; to masks, return the OR of the masks.
157 (defun compute-attribute-mask (names alist)
158 (collect ((res 0 logior))
160 (let ((mask (cdr (assoc name alist))))
162 (error "unknown attribute name: ~S" name))
168 ;;; Define a new class of boolean attributes, with the attributes
169 ;;; having the specified Attribute-Names. Name is the name of the
170 ;;; class, which is used to generate some macros to manipulate sets of
173 ;;; NAME-attributep attributes attribute-name*
174 ;;; Return true if one of the named attributes is present, false
175 ;;; otherwise. When set with SETF, updates the place Attributes
176 ;;; setting or clearing the specified attributes.
178 ;;; NAME-attributes attribute-name*
179 ;;; Return a set of the named attributes.
181 ;;; KLUDGE: This is expanded out twice, by cut-and-paste, in a
182 ;;; (DEF!MACRO FOO (..) .. CL:GET-SETF-EXPANSION ..)
184 ;;; (SB!XC:DEFMACRO FOO (..) .. SB!XC:GET-SETF-EXPANSION ..)
185 ;;; arrangement, in order to get it to work in cross-compilation. This
186 ;;; duplication should be removed, perhaps by rewriting the macro in a
187 ;;; more cross-compiler-friendly way, or perhaps just by using some
188 ;;; (MACROLET ((FROB ..)) .. FROB .. FROB) form, but I don't want to
189 ;;; do it now, because the system isn't running yet, so it'd be too
190 ;;; hard to check that my changes were correct -- WHN 19990806
191 (def!macro def-boolean-attribute (name &rest attribute-names)
193 (let ((translations-name (symbolicate "*" name "-ATTRIBUTE-TRANSLATIONS*"))
194 (test-name (symbolicate name "-ATTRIBUTEP")))
196 (do ((mask 1 (ash mask 1))
197 (names attribute-names (cdr names)))
199 (alist (cons (car names) mask)))
203 (eval-when (:compile-toplevel :load-toplevel :execute)
204 (defparameter ,translations-name ',(alist)))
206 (defmacro ,test-name (attributes &rest attribute-names)
207 "Automagically generated boolean attribute test function. See
208 Def-Boolean-Attribute."
209 `(logtest ,(compute-attribute-mask attribute-names
211 (the attributes ,attributes)))
213 (define-setf-expander ,test-name (place &rest attributes
215 "Automagically generated boolean attribute setter. See
216 Def-Boolean-Attribute."
217 #-sb-xc-host (declare (type sb!c::lexenv env))
218 ;; FIXME: It would be better if &ENVIRONMENT arguments
219 ;; were automatically declared to have type LEXENV by the
220 ;; hairy-argument-handling code.
221 (multiple-value-bind (temps values stores set get)
222 (get-setf-expansion place env)
224 (error "multiple store variables for ~S" place))
225 (let ((newval (gensym))
227 (mask (compute-attribute-mask attributes
228 ,translations-name)))
229 (values `(,@temps ,n-place)
232 `(let ((,(first stores)
234 (logior ,n-place ,mask)
235 (logand ,n-place ,(lognot mask)))))
238 `(,',test-name ,n-place ,@attributes)))))
240 (defmacro ,(symbolicate name "-ATTRIBUTES") (&rest attribute-names)
241 "Automagically generated boolean attribute creation function. See
242 Def-Boolean-Attribute."
243 (compute-attribute-mask attribute-names ,translations-name))))))
244 ;;; #+SB-XC-HOST SB!XC:DEFMACRO version is in late-macros.lisp. -- WHN 19990806
246 ;;; And now for some gratuitous pseudo-abstraction...
249 ;;; Return the union of all the sets of boolean attributes which are its
251 ;;; ATTRIBUTES-INTERSECTION
252 ;;; Return the intersection of all the sets of boolean attributes which
253 ;;; are its arguments.
255 ;;; True if the attributes present in Attr1 are identical to
257 (defmacro attributes-union (&rest attributes)
259 (logior ,@(mapcar #'(lambda (x) `(the attributes ,x)) attributes))))
260 (defmacro attributes-intersection (&rest attributes)
262 (logand ,@(mapcar #'(lambda (x) `(the attributes ,x)) attributes))))
263 (declaim (ftype (function (attributes attributes) boolean) attributes=))
264 #!-sb-fluid (declaim (inline attributes=))
265 (defun attributes= (attr1 attr2)
268 ;;;; lambda-list parsing utilities
270 ;;;; IR1 transforms, optimizers and type inferencers need to be able
271 ;;;; to parse the IR1 representation of a function call using a
272 ;;;; standard function lambda-list.
274 (eval-when (:compile-toplevel :load-toplevel :execute)
276 ;;; Given a DEFTRANSFORM-style lambda-list, generate code that parses
277 ;;; the arguments of a combination with respect to that lambda-list.
278 ;;; BODY is the the list of forms which are to be evaluated within the
279 ;;; bindings. ARGS is the variable that holds list of argument
280 ;;; continuations. ERROR-FORM is a form which is evaluated when the
281 ;;; syntax of the supplied arguments is incorrect or a non-constant
282 ;;; argument keyword is supplied. Defaults and other gunk are ignored.
283 ;;; The second value is a list of all the arguments bound. We make the
284 ;;; variables IGNORABLE so that we don't have to manually declare them
285 ;;; Ignore if their only purpose is to make the syntax work.
286 (defun parse-deftransform (lambda-list body args error-form)
287 (multiple-value-bind (req opt restp rest keyp keys allowp)
288 (parse-lambda-list lambda-list)
289 (let* ((min-args (length req))
290 (max-args (+ min-args (length opt)))
298 (binds `(,arg (nth ,(pos) ,args)))
302 (let ((var (if (atom arg) arg (first arg))))
304 (binds `(,var (nth ,(pos) ,args)))
309 (binds `(,rest (nthcdr ,(pos) ,args))))
312 (if (or (atom spec) (atom (first spec)))
313 (let* ((var (if (atom spec) spec (first spec)))
314 (key (keywordicate var)))
316 (binds `(,var (find-keyword-continuation ,n-keys ,key)))
318 (let* ((head (first spec))
322 (binds `(,var (find-keyword-continuation ,n-keys ,key)))
325 (let ((n-length (gensym))
326 (limited-legal (not (or restp keyp))))
328 `(let ((,n-length (length ,args))
329 ,@(when keyp `((,n-keys (nthcdr ,(pos) ,args)))))
331 ;; FIXME: should be PROPER-LIST-OF-LENGTH-P
333 `(<= ,min-args ,n-length ,max-args)
334 `(<= ,min-args ,n-length))
337 `((check-key-args-constant ,n-keys))
338 `((check-transform-keys ,n-keys ',(keywords))))))
341 (declare (ignorable ,@(vars)))
349 ;;; Define an IR1 transformation for NAME. An IR1 transformation
350 ;;; computes a lambda that replaces the function variable reference
351 ;;; for the call. A transform may pass (decide not to transform the
352 ;;; call) by calling the GIVE-UP-IR1-TRANSFORM function. LAMBDA-LIST
353 ;;; both determines how the current call is parsed and specifies the
354 ;;; LAMBDA-LIST for the resulting lambda.
356 ;;; We parse the call and bind each of the lambda-list variables to
357 ;;; the continuation which represents the value of the argument. When
358 ;;; parsing the call, we ignore the defaults, and always bind the
359 ;;; variables for unsupplied arguments to NIL. If a required argument
360 ;;; is missing, an unknown keyword is supplied, or an argument keyword
361 ;;; is not a constant, then the transform automatically passes. The
362 ;;; DECLARATIONS apply to the bindings made by DEFTRANSFORM at
363 ;;; transformation time, rather than to the variables of the resulting
364 ;;; lambda. Bound-but-not-referenced warnings are suppressed for the
365 ;;; lambda-list variables. The DOC-STRING is used when printing
366 ;;; efficiency notes about the defined transform.
368 ;;; Normally, the body evaluates to a form which becomes the body of
369 ;;; an automatically constructed lambda. We make LAMBDA-LIST the
370 ;;; lambda-list for the lambda, and automatically insert declarations
371 ;;; of the argument and result types. If the second value of the body
372 ;;; is non-null, then it is a list of declarations which are to be
373 ;;; inserted at the head of the lambda. Automatic lambda generation
374 ;;; may be inhibited by explicitly returning a lambda from the body.
376 ;;; The ARG-TYPES and RESULT-TYPE are used to create a function type
377 ;;; which the call must satisfy before transformation is attempted.
378 ;;; The function type specifier is constructed by wrapping (FUNCTION
379 ;;; ...) around these values, so the lack of a restriction may be
380 ;;; specified by omitting the argument or supplying *. The argument
381 ;;; syntax specified in the ARG-TYPES need not be the same as that in
382 ;;; the LAMBDA-LIST, but the transform will never happen if the
383 ;;; syntaxes can't be satisfied simultaneously. If there is an
384 ;;; existing transform for the same function that has the same type,
385 ;;; then it is replaced with the new definition.
387 ;;; These are the legal keyword options:
388 ;;; :RESULT - A variable which is bound to the result continuation.
389 ;;; :NODE - A variable which is bound to the combination node for the call.
390 ;;; :POLICY - A form which is supplied to the POLICY macro to determine
391 ;;; whether this transformation is appropriate. If the result
392 ;;; is false, then the transform automatically gives up.
394 ;;; - The name and argument/result types are actually forms to be
395 ;;; evaluated. Useful for getting closures that transform similar
398 ;;; - Don't actually instantiate a transform, instead just DEFUN
399 ;;; Name with the specified transform definition function. This
400 ;;; may be later instantiated with %DEFTRANSFORM.
402 ;;; - If supplied and non-NIL, note this transform as ``important,''
403 ;;; which means efficiency notes will be generated when this
404 ;;; transform fails even if INHIBIT-WARNINGS=SPEED (but not if
405 ;;; INHIBIT-WARNINGS>SPEED).
406 ;;; :WHEN {:NATIVE | :BYTE | :BOTH}
407 ;;; - Indicates whether this transform applies to native code,
408 ;;; byte-code or both (default :native.)
409 (defmacro deftransform (name (lambda-list &optional (arg-types '*)
411 &key result policy node defun-only
412 eval-name important (when :native))
413 &body body-decls-doc)
414 (when (and eval-name defun-only)
415 (error "can't specify both DEFUN-ONLY and EVAL-NAME"))
416 (multiple-value-bind (body decls doc) (parse-body body-decls-doc)
417 (let ((n-args (gensym))
418 (n-node (or node (gensym)))
421 (decls-body `(,@decls ,@body)))
422 (multiple-value-bind (parsed-form vars)
423 (parse-deftransform lambda-list
425 `((unless (policy ,n-node ,policy)
426 (give-up-ir1-transform))
430 '(give-up-ir1-transform))
433 (let* ((,n-args (basic-combination-args ,n-node))
435 `((,result (node-cont ,n-node)))))
436 (multiple-value-bind (,n-lambda ,n-decls)
438 (if (and (consp ,n-lambda) (eq (car ,n-lambda) 'lambda))
440 `(lambda ,',lambda-list
441 (declare (ignorable ,@',vars))
445 `(defun ,name ,@(when doc `(,doc)) ,@stuff)
447 ,(if eval-name name `',name)
449 ``(function ,,arg-types ,,result-type)
450 `'(function ,arg-types ,result-type))
453 ,(if important t nil)
456 ;;;; DEFKNOWN and DEFOPTIMIZER
458 ;;; This macro should be the way that all implementation independent
459 ;;; information about functions is made known to the compiler.
461 ;;; FIXME: The comment above suggests that perhaps some of my added
462 ;;; FTYPE declarations are in poor taste. Should I change my
463 ;;; declarations, or change the comment, or what?
465 ;;; FIXME: DEFKNOWN is needed only at build-the-system time. Figure
466 ;;; out some way to keep it from appearing in the target system.
468 ;;; Declare the function NAME to be a known function. We construct a
469 ;;; type specifier for the function by wrapping (FUNCTION ...) around
470 ;;; the ARG-TYPES and RESULT-TYPE. ATTRIBUTES is an unevaluated list
471 ;;; of boolean attributes of the function. These attributes are
475 ;;; May call functions that are passed as arguments. In order
476 ;;; to determine what other effects are present, we must find
477 ;;; the effects of all arguments that may be functions.
480 ;;; May incorporate arguments in the result or somehow pass
484 ;;; May fail to return during correct execution. Errors
488 ;;; The (default) worst case. Includes all the other bad
489 ;;; things, plus any other possible bad thing.
492 ;;; May be constant-folded. The function has no side effects,
493 ;;; but may be affected by side effects on the arguments. E.g.
497 ;;; May be eliminated if value is unused. The function has
498 ;;; no side effects except possibly CONS. If a function is
499 ;;; defined to signal errors, then it is not flushable even
500 ;;; if it is movable or foldable.
503 ;;; May be moved with impunity. Has no side effects except
504 ;;; possibly CONS, and is affected only by its arguments.
507 ;;; A true predicate likely to be open-coded. This is a
508 ;;; hint to IR1 conversion that it should ensure calls always
509 ;;; appear as an IF test. Not usually specified to DEFKNOWN,
510 ;;; since this is implementation dependent, and is usually
511 ;;; automatically set by the DEFINE-VOP :CONDITIONAL option.
513 ;;; NAME may also be a list of names, in which case the same
514 ;;; information is given to all the names. The keywords specify the
515 ;;; initial values for various optimizers that the function might
517 (defmacro defknown (name arg-types result-type &optional (attributes '(any))
519 (when (and (intersection attributes '(any call unwind))
520 (intersection attributes '(movable)))
521 (error "function cannot have both good and bad attributes: ~S" attributes))
523 `(%defknown ',(if (and (consp name)
524 (not (eq (car name) 'setf)))
527 '(function ,arg-types ,result-type)
528 (ir1-attributes ,@(if (member 'any attributes)
529 (union '(call unsafe unwind) attributes)
533 ;;; Create a function which parses combination args according to WHAT
534 ;;; and LAMBDA-LIST, where WHAT is either a function name or a list
535 ;;; (FUN-NAME KIND) and does some KIND of optimization.
537 ;;; The FUN-NAME must name a known function. LAMBDA-LIST is used
538 ;;; to parse the arguments to the combination as in DEFTRANSFORM. If
539 ;;; the argument syntax is invalid or there are non-constant keys,
540 ;;; then we simply return NIL.
542 ;;; The function is DEFUN'ed as FUNCTION-KIND-OPTIMIZER. Possible
543 ;;; kinds are DERIVE-TYPE, OPTIMIZER, LTN-ANNOTATE and IR2-CONVERT. If
544 ;;; a symbol is specified instead of a (FUNCTION KIND) list, then we
545 ;;; just do a DEFUN with the symbol as its name, and don't do anything
546 ;;; with the definition. This is useful for creating optimizers to be
547 ;;; passed by name to DEFKNOWN.
549 ;;; If supplied, NODE-VAR is bound to the combination node being
550 ;;; optimized. If additional VARS are supplied, then they are used as
551 ;;; the rest of the optimizer function's lambda-list. LTN-ANNOTATE
552 ;;; methods are passed an additional POLICY argument, and IR2-CONVERT
553 ;;; methods are passed an additional IR2-BLOCK argument.
554 (defmacro defoptimizer (what (lambda-list &optional (n-node (gensym))
557 (let ((name (if (symbolp what) what
558 (symbolicate (first what) "-" (second what) "-OPTIMIZER"))))
560 (let ((n-args (gensym)))
562 (defun ,name (,n-node ,@vars)
563 (let ((,n-args (basic-combination-args ,n-node)))
564 ,(parse-deftransform lambda-list body n-args
565 `(return-from ,name nil))))
567 `((setf (,(symbolicate "FUNCTION-INFO-" (second what))
568 (function-info-or-lose ',(first what)))
571 ;;;; IR groveling macros
573 ;;; Iterate over the blocks in a component, binding BLOCK-VAR to each
574 ;;; block in turn. The value of ENDS determines whether to iterate
575 ;;; over dummy head and tail blocks:
576 ;;; NIL -- Skip Head and Tail (the default)
577 ;;; :HEAD -- Do head but skip tail
578 ;;; :TAIL -- Do tail but skip head
579 ;;; :BOTH -- Do both head and tail
581 ;;; If supplied, RESULT-FORM is the value to return.
582 (defmacro do-blocks ((block-var component &optional ends result) &body body)
583 (unless (member ends '(nil :head :tail :both))
584 (error "losing ENDS value: ~S" ends))
585 (let ((n-component (gensym))
587 `(let* ((,n-component ,component)
588 (,n-tail ,(if (member ends '(:both :tail))
590 `(component-tail ,n-component))))
591 (do ((,block-var ,(if (member ends '(:both :head))
592 `(component-head ,n-component)
593 `(block-next (component-head ,n-component)))
594 (block-next ,block-var)))
595 ((eq ,block-var ,n-tail) ,result)
597 ;;; like DO-BLOCKS, only iterating over the blocks in reverse order
598 (defmacro do-blocks-backwards ((block-var component &optional ends result) &body body)
599 (unless (member ends '(nil :head :tail :both))
600 (error "losing ENDS value: ~S" ends))
601 (let ((n-component (gensym))
603 `(let* ((,n-component ,component)
604 (,n-head ,(if (member ends '(:both :head))
606 `(component-head ,n-component))))
607 (do ((,block-var ,(if (member ends '(:both :tail))
608 `(component-tail ,n-component)
609 `(block-prev (component-tail ,n-component)))
610 (block-prev ,block-var)))
611 ((eq ,block-var ,n-head) ,result)
614 ;;; Iterate over the uses of CONTINUATION, binding NODE to each one
617 ;;; XXX Could change it not to replicate the code someday perhaps...
618 (defmacro do-uses ((node-var continuation &optional result) &body body)
619 (once-only ((n-cont continuation))
620 `(ecase (continuation-kind ,n-cont)
624 (let ((,node-var (continuation-use ,n-cont)))
627 ((:block-start :deleted-block-start)
628 (dolist (,node-var (block-start-uses (continuation-block ,n-cont))
632 ;;; Iterate over the nodes in BLOCK, binding NODE-VAR to the each node
633 ;;; and CONT-VAR to the node's CONT. The only keyword option is
634 ;;; RESTART-P, which causes iteration to be restarted when a node is
635 ;;; deleted out from under us. (If not supplied, this is an error.)
637 ;;; In the forward case, we terminate on LAST-CONT so that we don't
638 ;;; have to worry about our termination condition being changed when
639 ;;; new code is added during the iteration. In the backward case, we
640 ;;; do NODE-PREV before evaluating the body so that we can keep going
641 ;;; when the current node is deleted.
643 ;;; When RESTART-P is supplied to DO-NODES, we start iterating over
644 ;;; again at the beginning of the block when we run into a
645 ;;; continuation whose block differs from the one we are trying to
646 ;;; iterate over, either because the block was split, or because a
647 ;;; node was deleted out from under us (hence its block is NIL.) If
648 ;;; the block start is deleted, we just punt. With RESTART-P, we are
649 ;;; also more careful about termination, re-indirecting the BLOCK-LAST
651 (defmacro do-nodes ((node-var cont-var block &key restart-p) &body body)
652 (let ((n-block (gensym))
653 (n-last-cont (gensym)))
654 `(let* ((,n-block ,block)
656 `((,n-last-cont (node-cont (block-last ,n-block))))))
657 (do* ((,node-var (continuation-next (block-start ,n-block))
660 ((eq (continuation-block ,cont-var) ,n-block)
661 (aver (continuation-next ,cont-var))
662 (continuation-next ,cont-var))
664 (let ((start (block-start ,n-block)))
665 (unless (eq (continuation-kind start)
668 (continuation-next start))))
669 `(continuation-next ,cont-var)))
670 (,cont-var (node-cont ,node-var) (node-cont ,node-var)))
674 `(eq ,node-var (block-last ,n-block))
675 `(eq ,cont-var ,n-last-cont))
677 ;;; like Do-Nodes, only iterating in reverse order
678 (defmacro do-nodes-backwards ((node-var cont-var block) &body body)
679 (let ((n-block (gensym))
683 `(let* ((,n-block ,block)
684 (,n-start (block-start ,n-block))
685 (,n-last (block-last ,n-block)))
686 (do* ((,cont-var (node-cont ,n-last) ,n-next)
687 (,node-var ,n-last (continuation-use ,cont-var))
688 (,n-next (node-prev ,node-var) (node-prev ,node-var)))
691 (when (eq ,n-next ,n-start)
694 ;;; Bind the IR1 context variables so that IR1 conversion can be done
695 ;;; after the main conversion pass has finished.
697 ;;; The lexical environment is presumably already null...
698 (defmacro with-ir1-environment (node &rest forms)
699 (let ((n-node (gensym)))
700 `(let* ((,n-node ,node)
701 (*current-component* (block-component (node-block ,n-node)))
702 (*lexenv* (node-lexenv ,n-node))
703 (*current-path* (node-source-path ,n-node)))
706 ;;; Bind the hashtables used for keeping track of global variables,
707 ;;; functions, &c. Also establish condition handlers.
708 (defmacro with-ir1-namespace (&body forms)
709 `(let ((*free-variables* (make-hash-table :test 'eq))
710 (*free-functions* (make-hash-table :test 'equal))
711 (*constants* (make-hash-table :test 'equal))
712 (*source-paths* (make-hash-table :test 'eq)))
713 (handler-bind ((compiler-error #'compiler-error-handler)
714 (style-warning #'compiler-style-warning-handler)
715 (warning #'compiler-warning-handler))
718 ;;; Look up NAME in the lexical environment namespace designated by
719 ;;; SLOT, returning the <value, T>, or <NIL, NIL> if no entry. The
720 ;;; :TEST keyword may be used to determine the name equality
722 (defmacro lexenv-find (name slot &key test)
723 (once-only ((n-res `(assoc ,name (,(symbolicate "LEXENV-" slot) *lexenv*)
724 :test ,(or test '#'eq))))
726 (values (cdr ,n-res) t)
729 ;;;; the EVENT statistics/trace utility
731 ;;; FIXME: This seems to be useful for troubleshooting and
732 ;;; experimentation, not for ordinary use, so it should probably
733 ;;; become conditional on SB-SHOW.
735 (eval-when (:compile-toplevel :load-toplevel :execute)
737 (defstruct (event-info (:copier nil))
738 ;; The name of this event.
739 (name (required-argument) :type symbol)
740 ;; The string rescribing this event.
741 (description (required-argument) :type string)
742 ;; The name of the variable we stash this in.
743 (var (required-argument) :type symbol)
744 ;; The number of times this event has happened.
745 (count 0 :type fixnum)
746 ;; The level of significance of this event.
747 (level (required-argument) :type unsigned-byte)
748 ;; If true, a function that gets called with the node that the event
750 (action nil :type (or function null)))
752 ;;; A hashtable from event names to event-info structures.
753 (defvar *event-info* (make-hash-table :test 'eq))
755 ;;; Return the event info for Name or die trying.
756 (declaim (ftype (function (t) event-info) event-info-or-lose))
757 (defun event-info-or-lose (name)
758 (let ((res (gethash name *event-info*)))
760 (error "~S is not the name of an event." name))
765 ;;; Return the number of times that EVENT has happened.
766 (declaim (ftype (function (symbol) fixnum) event-count))
767 (defun event-count (name)
768 (event-info-count (event-info-or-lose name)))
770 ;;; Return the function that is called when Event happens. If this is
771 ;;; null, there is no action. The function is passed the node to which
772 ;;; the event happened, or NIL if there is no relevant node. This may
773 ;;; be set with SETF.
774 (declaim (ftype (function (symbol) (or function null)) event-action))
775 (defun event-action (name)
776 (event-info-action (event-info-or-lose name)))
777 (declaim (ftype (function (symbol (or function null)) (or function null))
779 (defun %set-event-action (name new-value)
780 (setf (event-info-action (event-info-or-lose name))
782 (defsetf event-action %set-event-action)
784 ;;; Return the non-negative integer which represents the level of
785 ;;; significance of the event Name. This is used to determine whether
786 ;;; to print a message when the event happens. This may be set with
788 (declaim (ftype (function (symbol) unsigned-byte) event-level))
789 (defun event-level (name)
790 (event-info-level (event-info-or-lose name)))
791 (declaim (ftype (function (symbol unsigned-byte) unsigned-byte) %set-event-level))
792 (defun %set-event-level (name new-value)
793 (setf (event-info-level (event-info-or-lose name))
795 (defsetf event-level %set-event-level)
797 ;;; Define a new kind of event. Name is a symbol which names the event
798 ;;; and Description is a string which describes the event. Level
799 ;;; (default 0) is the level of significance associated with this
800 ;;; event; it is used to determine whether to print a Note when the
802 (defmacro defevent (name description &optional (level 0))
803 (let ((var-name (symbolicate "*" name "-EVENT-INFO*")))
804 `(eval-when (:compile-toplevel :load-toplevel :execute)
806 (make-event-info :name ',name
807 :description ',description
810 (setf (gethash ',name *event-info*) ,var-name)
813 ;;; the lowest level of event that will print a note when it occurs
814 (declaim (type unsigned-byte *event-note-threshold*))
815 (defvar *event-note-threshold* 1)
817 ;;; Note that the event with the specified Name has happened. Node is
818 ;;; evaluated to determine the node to which the event happened.
819 (defmacro event (name &optional node)
820 ;; Increment the counter and do any action. Mumble about the event if
822 `(%event ,(event-info-var (event-info-or-lose name)) ,node))
824 ;;; Print a listing of events and their counts, sorted by the count.
825 ;;; Events that happened fewer than Min-Count times will not be
826 ;;; printed. Stream is the stream to write to.
827 (declaim (ftype (function (&optional unsigned-byte stream) (values)) event-statistics))
828 (defun event-statistics (&optional (min-count 1) (stream *standard-output*))
830 (maphash #'(lambda (k v)
832 (when (>= (event-info-count v) min-count)
835 (dolist (event (sort (info) #'> :key #'event-info-count))
836 (format stream "~6D: ~A~%" (event-info-count event)
837 (event-info-description event)))
841 (declaim (ftype (function nil (values)) clear-event-statistics))
842 (defun clear-event-statistics ()
843 (maphash #'(lambda (k v)
845 (setf (event-info-count v) 0))
849 ;;;; functions on directly-linked lists (linked through specialized
850 ;;;; NEXT operations)
852 #!-sb-fluid (declaim (inline find-in position-in map-in))
854 ;;; Find Element in a null-terminated List linked by the accessor
855 ;;; function Next. Key, Test and Test-Not are the same as for generic
856 ;;; sequence functions.
863 (test-not nil not-p))
864 (when (and test-p not-p)
865 (error "It's silly to supply both :TEST and :TEST-NOT arguments."))
867 (do ((current list (funcall next current)))
869 (unless (funcall test-not (funcall key current) element)
871 (do ((current list (funcall next current)))
873 (when (funcall test (funcall key current) element)
876 ;;; Return the position of Element (or NIL if absent) in a
877 ;;; null-terminated List linked by the accessor function Next. Key,
878 ;;; Test and Test-Not are the same as for generic sequence functions.
879 (defun position-in (next
885 (test-not nil not-p))
886 (when (and test-p not-p)
887 (error "It's silly to supply both :TEST and :TEST-NOT arguments."))
889 (do ((current list (funcall next current))
892 (unless (funcall test-not (funcall key current) element)
894 (do ((current list (funcall next current))
897 (when (funcall test (funcall key current) element)
900 ;;; Map FUNCTION over the elements in a null-terminated LIST linked by the
901 ;;; accessor function NEXT, returning an ordinary list of the results.
902 (defun map-in (next function list)
904 (do ((current list (funcall next current)))
906 (res (funcall function current)))
909 ;;; KLUDGE: This is expanded out twice, by cut-and-paste, in a
910 ;;; (DEF!MACRO FOO (..) .. CL:GET-SETF-EXPANSION ..)
912 ;;; (SB!XC:DEFMACRO FOO (..) .. SB!XC:GET-SETF-EXPANSION ..)
913 ;;; arrangement, in order to get it to work in cross-compilation. This
914 ;;; duplication should be removed, perhaps by rewriting the macro in a more
915 ;;; cross-compiler-friendly way, or perhaps just by using some (MACROLET ((FROB
916 ;;; ..)) .. FROB .. FROB) form, or perhaps by completely eliminating this macro
917 ;;; and its partner PUSH-IN, but I don't want to do it now, because the system
918 ;;; isn't running yet, so it'd be too hard to check that my changes were
919 ;;; correct -- WHN 19990806
920 (def!macro deletef-in (next place item &environment env)
921 (multiple-value-bind (temps vals stores store access)
922 (get-setf-expansion place env)
924 (error "multiple store variables for ~S" place))
925 (let ((n-item (gensym))
929 `(let* (,@(mapcar #'list temps vals)
932 (if (eq ,n-place ,n-item)
933 (let ((,(first stores) (,next ,n-place)))
935 (do ((,n-prev ,n-place ,n-current)
936 (,n-current (,next ,n-place)
938 ((eq ,n-current ,n-item)
939 (setf (,next ,n-prev)
940 (,next ,n-current)))))
942 ;;; #+SB-XC-HOST SB!XC:DEFMACRO version is in late-macros.lisp. -- WHN 19990806
944 ;;; Push ITEM onto a list linked by the accessor function NEXT that is
947 ;;; KLUDGE: This is expanded out twice, by cut-and-paste, in a
948 ;;; (DEF!MACRO FOO (..) .. CL:GET-SETF-EXPANSION ..)
950 ;;; (SB!XC:DEFMACRO FOO (..) .. SB!XC:GET-SETF-EXPANSION ..)
951 ;;; arrangement, in order to get it to work in cross-compilation. This
952 ;;; duplication should be removed, perhaps by rewriting the macro in a more
953 ;;; cross-compiler-friendly way, or perhaps just by using some (MACROLET ((FROB
954 ;;; ..)) .. FROB .. FROB) form, or perhaps by completely eliminating this macro
955 ;;; and its partner DELETEF-IN, but I don't want to do it now, because the
956 ;;; system isn't running yet, so it'd be too hard to check that my changes were
957 ;;; correct -- WHN 19990806
958 (def!macro push-in (next item place &environment env)
959 (multiple-value-bind (temps vals stores store access)
960 (get-setf-expansion place env)
962 (error "multiple store variables for ~S" place))
963 `(let (,@(mapcar #'list temps vals)
964 (,(first stores) ,item))
965 (setf (,next ,(first stores)) ,access)
968 ;;; #+SB-XC-HOST SB!XC:DEFMACRO version is in late-macros.lisp. -- WHN 19990806
970 (defmacro position-or-lose (&rest args)
971 `(or (position ,@args)
972 (error "shouldn't happen?")))