Mercurial > hg > xemacs-beta
comparison lisp/byte-optimize.el @ 5656:e9c3fe82127d
Co-operate with the byte-optimizer in the bytecomp.el labels implementation.
lisp/ChangeLog addition:
2012-05-05 Aidan Kehoe <kehoea@parhasard.net>
Co-operate with the byte-optimizer in the bytecomp.el labels
implementation, don't work against it.
* byte-optimize.el:
* byte-optimize.el (byte-compile-inline-expand):
Call #'byte-compile-unfold-lambda explicitly here, don't assume
that the byte-optimizer will do it.
* byte-optimize.el (byte-compile-unfold-lambda):
Call #'byte-optimize-body on the body, don't just mapcar
#'byte-optimize-form along it.
* byte-optimize.el (byte-optimize-lambda): New. Optimize a lambda
form.
* byte-optimize.el (byte-optimize-form-code-walker):
Descend lambda expressions, defun, and defmacro, relevant for
lexically-oriented operators like #'labels.
* byte-optimize.el (byte-optimize-body): Only return a non-eq
object if we've actually optimized something
* bytecomp.el (byte-compile-initial-macro-environment):
In the labels implementation, work with the byte optimizer, not
against it; warn when labels are defined but not used,
automatically inline labels that are used only once.
* bytecomp.el (byte-recompile-directory):
No need to wrap #'byte-compile-report-error in a lambda with
#'call-with-condition-handler here.
* bytecomp.el (byte-compile-form):
Don't inline compiled-function objects, they're probably labels.
* bytecomp.el (byte-compile-funcall):
No longer inline lambdas, trust the byte optimizer to have done it
properly, even for labels.
* cl-extra.el (cl-macroexpand-all):
Treat labels established by the byte compiler distinctly from
those established by cl-macs.el.
* cl-macs.el (cl-do-proclaim):
Treat labels established by the byte compiler distinctly from
those established by cl-macs.el.
* gui.el (make-gui-button):
When referring to the #'gui-button-action label, quote it using
function, otherwise there's a warning from the byte compiler.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sat, 05 May 2012 20:48:24 +0100 |
parents | cc6f0266bc36 |
children | 2a870a7b86bd |
comparison
equal
deleted
inserted
replaced
5655:b7ae5f44b950 | 5656:e9c3fe82127d |
---|---|
282 (and (fboundp name) (symbol-function name)))))) | 282 (and (fboundp name) (symbol-function name)))))) |
283 (if (and (consp fn) (eq (car fn) 'autoload)) | 283 (if (and (consp fn) (eq (car fn) 'autoload)) |
284 (error "file \"%s\" didn't define \"%s\"" (nth 1 fn) name)) | 284 (error "file \"%s\" didn't define \"%s\"" (nth 1 fn) name)) |
285 (if (symbolp fn) | 285 (if (symbolp fn) |
286 (byte-compile-inline-expand (cons fn (cdr form))) | 286 (byte-compile-inline-expand (cons fn (cdr form))) |
287 (if (compiled-function-p fn) | 287 (if (or (eq (car-safe fn) 'lambda) (compiled-function-p fn)) |
288 (progn | 288 (byte-compile-unfold-lambda (cons fn (cdr form))) |
289 (fetch-bytecode fn) | 289 ;; Give up on inlining. |
290 (cons (list 'lambda (compiled-function-arglist fn) | 290 form))))) |
291 (list 'byte-code | |
292 (compiled-function-instructions fn) | |
293 (compiled-function-constants fn) | |
294 (compiled-function-stack-depth fn))) | |
295 (cdr form))) | |
296 (if (eq (car-safe fn) 'lambda) | |
297 (cons fn (cdr form)) | |
298 ;; Give up on inlining. | |
299 form)))))) | |
300 | 291 |
301 ;;; ((lambda ...) ...) | 292 ;;; ((lambda ...) ...) |
302 ;;; | 293 ;;; |
303 (defun byte-compile-unfold-lambda (form &optional name) | 294 (defun byte-compile-unfold-lambda (form &optional name) |
304 (or name (setq name "anonymous lambda")) | 295 (or name (setq name "anonymous lambda")) |
352 (progn | 343 (progn |
353 (or (eq values 'too-few) | 344 (or (eq values 'too-few) |
354 (byte-compile-warn | 345 (byte-compile-warn |
355 "attempt to open-code %s with too many arguments" name)) | 346 "attempt to open-code %s with too many arguments" name)) |
356 form) | 347 form) |
357 (setq body (mapcar 'byte-optimize-form body)) | 348 (setq body (byte-optimize-body body nil)) |
358 (let ((newform | 349 (let ((newform |
359 (if bindings | 350 (if bindings |
360 (cons 'let (cons (nreverse bindings) body)) | 351 (cons 'let (cons (nreverse bindings) body)) |
361 (cons 'progn body)))) | 352 (cons 'progn body)))) |
362 (byte-compile-log " %s\t==>\t%s" form newform) | 353 (byte-compile-log " %s\t==>\t%s" form newform) |
363 newform))))) | 354 newform))))) |
364 | 355 |
365 | 356 |
357 (defun byte-optimize-lambda (form) | |
358 (let* ((offset 2) (body (nthcdr offset form))) | |
359 (if (stringp (car body)) (setq body (nthcdr (incf offset) form))) | |
360 (if (eq 'interactive (car-safe (car body))) | |
361 (setq body (nthcdr (incf offset) form))) | |
362 (if (eq body (setq body (byte-optimize-body body nil))) | |
363 form | |
364 (nconc (subseq form 0 offset) body)))) | |
365 | |
366 ;;; implementing source-level optimizers | 366 ;;; implementing source-level optimizers |
367 | 367 |
368 (defun byte-optimize-form-code-walker (form for-effect) | 368 (defun byte-optimize-form-code-walker (form for-effect) |
369 ;; | 369 ;; |
370 ;; For normal function calls, We can just mapcar the optimizer the cdr. But | 370 ;; For normal function calls, We can just mapcar the optimizer the cdr. But |
388 ;; map (quote nil) to nil to simplify optimizer logic. | 388 ;; map (quote nil) to nil to simplify optimizer logic. |
389 ;; map quoted constants to nil if for-effect (just because). | 389 ;; map quoted constants to nil if for-effect (just because). |
390 (and (nth 1 form) | 390 (and (nth 1 form) |
391 (not for-effect) | 391 (not for-effect) |
392 form)) | 392 form)) |
393 ((or (compiled-function-p fn) | 393 ((eq fn 'function) |
394 (eq 'lambda (car-safe fn))) | 394 (when (cddr form) |
395 (byte-compile-unfold-lambda form)) | 395 (byte-compile-warn "malformed function form: %S" form)) |
396 (cond | |
397 (for-effect nil) | |
398 ((and (eq (car-safe (cadr form)) 'lambda) | |
399 (not (eq (cadr form) (setq tmp (byte-optimize-lambda | |
400 (cadr form)))))) | |
401 (list fn tmp)) | |
402 (t form))) | |
403 ((and (eq 'lambda (car-safe fn)) | |
404 (not (eq form (setq form (byte-compile-unfold-lambda form))))) | |
405 form) | |
396 ((memq fn '(let let*)) | 406 ((memq fn '(let let*)) |
397 ;; recursively enter the optimizer for the bindings and body | 407 ;; recursively enter the optimizer for the bindings and body |
398 ;; of a let or let*. This for depth-firstness: forms that | 408 ;; of a let or let*. This for depth-firstness: forms that |
399 ;; are more deeply nested are optimized first. | 409 ;; are more deeply nested are optimized first. |
400 (cons fn | 410 (cons fn |
488 ((eq fn 'interactive) | 498 ((eq fn 'interactive) |
489 (byte-compile-warn "misplaced interactive spec: %s" | 499 (byte-compile-warn "misplaced interactive spec: %s" |
490 (prin1-to-string form)) | 500 (prin1-to-string form)) |
491 nil) | 501 nil) |
492 | 502 |
493 ((memq fn '(defun defmacro function | 503 ((memq fn '(defun defmacro)) |
494 condition-case save-window-excursion)) | 504 (if (eq (setq tmp (cons 'lambda (cddr form))) |
495 ;; These forms are compiled as constants or by breaking out | 505 (setq tmp (byte-optimize-lambda tmp))) |
496 ;; all the subexpressions and compiling them separately. | 506 (cons fn (cdr tmp)) |
497 form) | 507 form)) |
508 | |
509 ((eq fn 'condition-case) | |
510 (list* fn (nth 1 form) (byte-optimize-form (nth 2 form) for-effect) | |
511 (mapcar #'(lambda (handler) | |
512 (cons (car handler) | |
513 (byte-optimize-body (cdr handler) | |
514 for-effect))) | |
515 (cdddr form)))) | |
498 | 516 |
499 ((eq fn 'unwind-protect) | 517 ((eq fn 'unwind-protect) |
500 ;; the "protected" part of an unwind-protect is compiled (and thus | 518 ;; the "protected" part of an unwind-protect is compiled (and thus |
501 ;; optimized) as a top-level form, so don't do it here. But the | 519 ;; optimized) as a top-level form, so don't do it here. But the |
502 ;; non-protected part has the same for-effect status as the | 520 ;; non-protected part has the same for-effect status as the |
522 ((not (eq form | 540 ((not (eq form |
523 (setq form (macroexpand form | 541 (setq form (macroexpand form |
524 byte-compile-macro-environment)))) | 542 byte-compile-macro-environment)))) |
525 (byte-optimize-form form for-effect)) | 543 (byte-optimize-form form for-effect)) |
526 | 544 |
545 ((compiled-function-p fn) | |
546 (cons fn (mapcar #'byte-optimize-form (cdr form)))) | |
547 | |
527 ((not (symbolp fn)) | 548 ((not (symbolp fn)) |
528 (byte-compile-warn "%s is a malformed function" (prin1-to-string fn)) | 549 (byte-compile-warn "%S is a malformed function" fn) |
529 form) | 550 form) |
530 | 551 |
531 ;; Support compiler macros as in cl.el. | 552 ;; Support compiler macros as in cl.el. |
532 ((and (get fn 'cl-compiler-macro) | 553 ((and (get fn 'cl-compiler-macro) |
533 (not (eq form (setq form (compiler-macroexpand form))))) | 554 (not (eq form (setq form (compiler-macroexpand form))))) |
591 ;; forms, all but the last of which are optimized with the assumption that | 612 ;; forms, all but the last of which are optimized with the assumption that |
592 ;; they are being called for effect. The last is for-effect as well if | 613 ;; they are being called for effect. The last is for-effect as well if |
593 ;; all-for-effect is true. Returns a new list of forms. | 614 ;; all-for-effect is true. Returns a new list of forms. |
594 (let ((rest forms) | 615 (let ((rest forms) |
595 (result nil) | 616 (result nil) |
617 (modified nil) | |
596 fe new) | 618 fe new) |
597 (while rest | 619 (while rest |
598 (setq fe (or all-for-effect (cdr rest))) | 620 (setq fe (or all-for-effect (cdr rest))) |
599 (setq new (and (car rest) (byte-optimize-form (car rest) fe))) | 621 (setq new (and (car rest) (byte-optimize-form (car rest) fe))) |
600 (if (or new (not fe)) | 622 (if (or new (not fe)) |
601 (setq result (cons new result))) | 623 (setq result (cons new result) |
624 modified (or modified (not (eq new (car rest))))) | |
625 (setq modified t)) | |
602 (setq rest (cdr rest))) | 626 (setq rest (cdr rest))) |
603 (nreverse result))) | 627 (if modified (nreverse result) forms))) |
604 | 628 |
605 | 629 |
606 ;;; some source-level optimizers | 630 ;;; some source-level optimizers |
607 ;;; | 631 ;;; |
608 ;;; when writing optimizers, be VERY careful that the optimizer returns | 632 ;;; when writing optimizers, be VERY careful that the optimizer returns |