+
+;;; Like FUNCTION, but ignores local definitions and inline
+;;; expansions, and doesn't nag about undefined functions.
+;;; Used for optimizing things like (FUNCALL 'FOO).
+(def-ir1-translator global-function ((thing) start next result)
+ (with-fun-name-leaf (leaf thing start :global-function t)
+ (reference-leaf start next result leaf)))
+
+(defun constant-global-fun-name (thing)
+ (let ((constantp (sb!xc:constantp thing)))
+ (when constantp
+ (let ((name (constant-form-value thing)))
+ (when (legal-fun-name-p name)
+ name)))))
+
+(defun lvar-constant-global-fun-name (lvar)
+ (when (constant-lvar-p lvar)
+ (let ((name (lvar-value lvar)))
+ (when (legal-fun-name-p name)
+ name))))
+
+(defun ensure-source-fun-form (source &optional give-up)
+ (let ((op (when (consp source) (car source))))
+ (cond ((eq op '%coerce-callable-to-fun)
+ (ensure-source-fun-form (second source)))
+ ((member op '(function global-function lambda named-lambda))
+ (values source nil))
+ (t
+ (let ((cname (constant-global-fun-name source)))
+ (if cname
+ (values `(global-function ,cname) nil)
+ (values `(%coerce-callable-to-fun ,source) give-up)))))))
+
+(defun ensure-lvar-fun-form (lvar lvar-name &optional give-up)
+ (aver (and lvar-name (symbolp lvar-name)))
+ (if (csubtypep (lvar-type lvar) (specifier-type 'function))
+ lvar-name
+ (let ((cname (lvar-constant-global-fun-name lvar)))
+ (cond (cname
+ `(global-function ,cname))
+ (give-up
+ (give-up-ir1-transform "not known to be a function"))
+ (t
+ `(%coerce-callable-to-fun ,lvar-name))))))