(setf (lvar-dynamic-extent old) nil)
(unless (lvar-dynamic-extent new)
(setf (lvar-dynamic-extent new) it)
- (setf (cleanup-info it) (substitute new old (cleanup-info it)))))
+ (setf (cleanup-info it) (subst new old (cleanup-info it)))))
(when (lvar-dynamic-extent new)
(do-uses (node new)
(node-ends-block node))))
(defun known-dx-combination-p (use dx)
(and (eq (combination-kind use) :known)
- (awhen (fun-info-stack-allocate-result (combination-fun-info use))
- (funcall it use dx))))
+ (let ((info (combination-fun-info use)))
+ (or (awhen (fun-info-stack-allocate-result info)
+ (funcall it use dx))
+ (awhen (fun-info-result-arg info)
+ (let ((args (combination-args use)))
+ (lvar-good-for-dx-p (if (zerop it)
+ (car args)
+ (nth it args))
+ dx)))))))
(defun dx-combination-p (use dx)
(and (combination-p use)
;;; arguments.
(defun splice-fun-args (lvar fun num-args)
#!+sb-doc
- "If LVAR is a call to FUN with NUM-ARGS args, change those arguments
- to feed directly to the LVAR-DEST of LVAR, which must be a
- combination."
+ "If LVAR is a call to FUN with NUM-ARGS args, change those arguments to feed
+directly to the LVAR-DEST of LVAR, which must be a combination. If FUN
+is :ANY, the function name is not checked."
(declare (type lvar lvar)
(type symbol fun)
(type index num-args))
(unless (combination-p inside)
(give-up-ir1-transform))
(let ((inside-fun (combination-fun inside)))
- (unless (eq (lvar-fun-name inside-fun) fun)
+ (unless (or (eq fun :any)
+ (eq (lvar-fun-name inside-fun) fun))
(give-up-ir1-transform))
(let ((inside-args (combination-args inside)))
(unless (= (length inside-args) num-args)
(combination-kind inside) :known)
(setf (node-derived-type inside) *wild-type*)
(flush-dest lvar)
- (values))))))
+ inside-args)))))
+
+;;; Eliminate keyword arguments from the call (leaving the
+;;; parameters in place.
+;;;
+;;; (FOO ... :BAR X :QUUX Y)
+;;; becomes
+;;; (FOO ... X Y)
+;;;
+;;; SPECS is a list of (:KEYWORD PARAMETER) specifications.
+;;; Returns the list of specified parameters names in the
+;;; order they appeared in the call. N-POSITIONAL is the
+;;; number of positional arguments in th call.
+(defun eliminate-keyword-args (call n-positional specs)
+ (let* ((specs (copy-tree specs))
+ (all (combination-args call))
+ (new-args (reverse (subseq all 0 n-positional)))
+ (key-args (subseq all n-positional))
+ (parameters nil))
+ (loop while key-args
+ do (let* ((key (pop key-args))
+ (val (pop key-args))
+ (keyword (if (constant-lvar-p key)
+ (lvar-value key)
+ (give-up-ir1-transform)))
+ (spec (or (assoc keyword specs :test #'eq)
+ (give-up-ir1-transform))))
+ (push val new-args)
+ (flush-dest key)
+ (push (second spec) parameters)
+ ;; In case of duplicate keys.
+ (setf (second spec) (gensym))))
+ (setf (combination-args call) (reverse new-args))
+ (reverse parameters)))
(defun extract-fun-args (lvar fun num-args)
(declare (type lvar lvar)
((atom y) (file-coalesce-p y))
(unless (file-coalesce-p (car y))
(return nil)))))
- ;; We *could* coalesce base-strings as well, but we'd need
- ;; a separate hash-table for that, since we are not allowed to
- ;; coalesce base-strings with non-base-strings.
- (typep x '(or (vector character) bit-vector)))))
+ ;; We *could* coalesce base-strings as well,
+ ;; but we'd need a separate hash-table for
+ ;; that, since we are not allowed to coalesce
+ ;; base-strings with non-base-strings.
+ (typep x
+ '(or bit-vector
+ ;; in the cross-compiler, we coalesce
+ ;; all strings with the same contents,
+ ;; because we will end up dumping them
+ ;; as base-strings anyway. In the
+ ;; real compiler, we're not allowed to
+ ;; coalesce regardless of string
+ ;; specialized element type, so we
+ ;; KLUDGE by coalescing only character
+ ;; strings (the common case) and
+ ;; punting on the other types.
+ #+sb-xc-host
+ string
+ #-sb-xc-host
+ (vector character))))))
(coalescep (x)
(if faslp (file-coalesce-p x) (core-coalesce-p x))))
(if (and (boundp '*constants*) (coalescep object))
(eq (global-var-kind leaf) :global-function)
(not (null (member (leaf-source-name leaf) names
:test #'equal))))))))
+
+(defun lvar-matches (lvar &key fun-names arg-count)
+ (let ((use (lvar-use lvar)))
+ (and (combination-p use)
+ (or (not fun-names)
+ (member (combination-fun-source-name use)
+ fun-names :test #'eq))
+ (or (not arg-count)
+ (= arg-count (length (combination-args use)))))))