X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fir1opt.lisp;h=909cd1f96a998c3072790f399006254c59553149;hb=f705c517d8606a9a72edd11a96725f9c4e4be93d;hp=1ada2651afd01e9191d0601bc990cb2b7e027ee2;hpb=a208de2a9ab6a63c27f3e6c291fea9f7c4d774a1;p=sbcl.git diff --git a/src/compiler/ir1opt.lisp b/src/compiler/ir1opt.lisp index 1ada265..909cd1f 100644 --- a/src/compiler/ir1opt.lisp +++ b/src/compiler/ir1opt.lisp @@ -323,19 +323,29 @@ (when (block-start next) ; NEXT is not an END-OF-COMPONENT marker (cond ( ;; We cannot combine with a successor block if: (or - ;; The successor has more than one predecessor. + ;; the successor has more than one predecessor; (rest (block-pred next)) - ;; The successor is the current block (infinite loop). + ;; the successor is the current block (infinite loop); (eq next block) - ;; The next block has a different cleanup, and thus + ;; the next block has a different cleanup, and thus ;; we may want to insert cleanup code between the - ;; two blocks at some point. + ;; two blocks at some point; (not (eq (block-end-cleanup block) (block-start-cleanup next))) - ;; The next block has a different home lambda, and + ;; the next block has a different home lambda, and ;; thus the control transfer is a non-local exit. (not (eq (block-home-lambda block) - (block-home-lambda next)))) + (block-home-lambda next))) + ;; Stack analysis phase wants ENTRY to start a block... + (entry-p (block-start-node next)) + (let ((last (block-last block))) + (and (valued-node-p last) + (awhen (node-lvar last) + (or + ;; ... and a DX-allocator to end a block. + (lvar-dynamic-extent it) + ;; FIXME: This is a partial workaround for bug 303. + (consp (lvar-uses it))))))) nil) (t (join-blocks block next) @@ -389,8 +399,9 @@ (delete-ref node) (unlink-node node)) (combination - (let ((info (combination-kind node))) - (when (fun-info-p info) + (let ((kind (combination-kind node)) + (info (combination-fun-info node))) + (when (and (eq kind :known) (fun-info-p info)) (let ((attr (fun-info-attributes info))) (when (and (not (ir1-attributep attr call)) ;; ### For now, don't delete potentially @@ -637,23 +648,36 @@ (propagate-fun-change node) (maybe-terminate-block node nil)) (let ((args (basic-combination-args node)) - (kind (basic-combination-kind node))) - (case kind + (kind (basic-combination-kind node)) + (info (basic-combination-fun-info node))) + (ecase kind (:local (let ((fun (combination-lambda node))) (if (eq (functional-kind fun) :let) (propagate-let-args node fun) (propagate-local-call-args node fun)))) - ((:full :error) + (:error (dolist (arg args) (when arg (setf (lvar-reoptimize arg) nil)))) - (t + (:full + (dolist (arg args) + (when arg + (setf (lvar-reoptimize arg) nil))) + (when info + (let ((fun (fun-info-derive-type info))) + (when fun + (let ((res (funcall fun node))) + (when res + (derive-node-type node (coerce-to-values res)) + (maybe-terminate-block node nil))))))) + (:known + (aver info) (dolist (arg args) (when arg (setf (lvar-reoptimize arg) nil))) - (let ((attr (fun-info-attributes kind))) + (let ((attr (fun-info-attributes info))) (when (and (ir1-attributep attr foldable) ;; KLUDGE: The next test could be made more sensitive, ;; only suppressing constant-folding of functions with @@ -679,16 +703,16 @@ (constant-fold-call node) (return-from ir1-optimize-combination))) - (let ((fun (fun-info-derive-type kind))) + (let ((fun (fun-info-derive-type info))) (when fun (let ((res (funcall fun node))) (when res (derive-node-type node (coerce-to-values res)) (maybe-terminate-block node nil))))) - (let ((fun (fun-info-optimizer kind))) + (let ((fun (fun-info-optimizer info))) (unless (and fun (funcall fun node)) - (dolist (x (fun-info-transforms kind)) + (dolist (x (fun-info-transforms info)) #!+sb-show (when *show-transforms-p* (let* ((lvar (basic-combination-fun node)) @@ -724,6 +748,7 @@ (ctran (node-next node)) (tail (component-tail (block-component block))) (succ (first (block-succ block)))) + (declare (ignore lvar)) (unless (or (and (eq node (block-last block)) (eq succ tail)) (block-delete-p block)) (when (eq (node-derived-type node) *empty-type*) @@ -775,7 +800,11 @@ (defined-fun-inlinep leaf) :no-chance))) (cond - ((eq inlinep :notinline) (values nil nil)) + ((eq inlinep :notinline) + (let ((info (info :function :info (leaf-source-name leaf)))) + (when info + (setf (basic-combination-fun-info call) info)) + (values nil nil))) ((not (and (global-var-p leaf) (eq (global-var-kind leaf) :global-function))) (values leaf nil)) @@ -793,10 +822,11 @@ ;; called semi-inlining? A more descriptive name would ;; be nice. -- WHN 2002-01-07 (frob () - (let ((res (ir1-convert-lambda-for-defun - (defined-fun-inline-expansion leaf) - leaf t - #'ir1-convert-inline-lambda))) + (let ((res (let ((*allow-instrumenting* t)) + (ir1-convert-lambda-for-defun + (defined-fun-inline-expansion leaf) + leaf t + #'ir1-convert-inline-lambda)))) (setf (defined-fun-functional leaf) res) (change-ref-leaf ref res)))) (if ir1-converting-not-optimizing-p @@ -810,7 +840,10 @@ (t (let ((info (info :function :info (leaf-source-name leaf)))) (if info - (values leaf (setf (basic-combination-kind call) info)) + (values leaf + (progn + (setf (basic-combination-kind call) :known) + (setf (basic-combination-fun-info call) info))) (values leaf nil))))))) ;;; Check whether CALL satisfies TYPE. If so, apply the type to the @@ -829,7 +862,7 @@ (recognize-known-call call ir1-converting-not-optimizing-p)) ((valid-fun-use call type :argument-test #'always-subtypep - :result-test #'always-subtypep + :result-test nil ;; KLUDGE: Common Lisp is such a dynamic ;; language that all we can do here in ;; general is issue a STYLE-WARNING. It @@ -881,7 +914,9 @@ (lvar-uses (basic-combination-fun call)) call)) ((not leaf)) - ((and (leaf-has-source-name-p leaf) + ((and (global-var-p leaf) + (eq (global-var-kind leaf) :global-function) + (leaf-has-source-name-p leaf) (or (info :function :source-transform (leaf-source-name leaf)) (and info (ir1-attributep (fun-info-attributes info) @@ -947,7 +982,7 @@ (:aborted (setf (combination-kind node) :error) (when args - (apply #'compiler-warn args)) + (apply #'warn args)) (remhash node table) nil) (:failure @@ -1054,10 +1089,9 @@ (block-next (node-block call))) (let ((new-fun (ir1-convert-inline-lambda res - :debug-name (debug-namify "LAMBDA-inlined ~A" - (as-debug-name - source-name - "")))) + :debug-name (debug-namify "LAMBDA-inlined " + source-name + ""))) (ref (lvar-use (combination-fun call)))) (change-ref-leaf ref new-fun) (setf (combination-kind call) :full) @@ -1168,7 +1202,8 @@ (() (null (rest sets)) :exit-if-null) (set-use (principal-lvar-use (set-value set))) (() (and (combination-p set-use) - (fun-info-p (combination-kind set-use)) + (eq (combination-kind set-use) :known) + (fun-info-p (combination-fun-info set-use)) (not (node-to-be-deleted-p set-use)) (eq (combination-fun-source-name set-use) '+)) :exit-if-null) @@ -1280,7 +1315,8 @@ (dest (lvar-dest lvar))) (when (and ;; Think about (LET ((A ...)) (IF ... A ...)): two - ;; LVAR-USEs should not be met on one path. + ;; LVAR-USEs should not be met on one path. Another problem + ;; is with dynamic-extent. (eq (lvar-uses lvar) ref) (typecase dest ;; we should not change lifetime of unknown values lvars @@ -1305,7 +1341,9 @@ (eq (node-home-lambda ref) (lambda-home (lambda-var-home var)))) (setf (node-derived-type ref) *wild-type*) - (substitute-lvar-uses lvar arg) + (substitute-lvar-uses lvar arg + ;; Really it is (EQ (LVAR-USES LVAR) REF): + t) (delete-lvar-use ref) (change-ref-leaf ref (find-constant nil)) (delete-ref ref) @@ -1326,6 +1364,9 @@ (unlink-node call) (unlink-node (lambda-bind clambda)) (setf (lambda-bind clambda) nil)) + (setf (functional-kind clambda) :zombie) + (let ((home (lambda-home clambda))) + (setf (lambda-lets home) (delete clambda (lambda-lets home)))) (values)) ;;; This function is called when one of the arguments to a LET @@ -1717,7 +1758,10 @@ (immediately-used-p value use)) (unless next-block (when ctran (ensure-block-start ctran)) - (setq next-block (first (block-succ (node-block cast))))) + (setq next-block (first (block-succ (node-block cast)))) + (ensure-block-start (node-prev cast)) + (reoptimize-lvar lvar) + (setf (lvar-%derived-type value) nil)) (%delete-lvar-use use) (add-lvar-use use lvar) (unlink-blocks (node-block use) (node-block cast)) @@ -1738,7 +1782,9 @@ ;; FIXME: Do it in one step. (filter-lvar value - `(multiple-value-call #'list 'dummy)) + (if (cast-single-value-p cast) + `(list 'dummy) + `(multiple-value-call #'list 'dummy))) (filter-lvar (cast-value cast) ;; FIXME: Derived type.