[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: MCL optimizing



At 7:16 PM 3/5/95, Ken Tilton wrote:
>On Norvig p 279 he shows a rather contrived example that demonstrates the
>capabilities of an unspecified compiler's optimization scheme:
>
>(defun f1 (n l)
>  (let ((l1 (first l))
>         (l2 (second l)))
>    (expt (* 1 (+ n 0))
>          (- 4 (length (list l1 l2))))))
>
>The disassembly he showed came out the same as if the body were just (* n n),
>going so far as to ignore the "l" argument since all refs to it got optimized
>away. ie, The compiler figured out the length had to be two, so expt would be
>squaring, so etc.
>
>I disassembled that under MCL and came out with quite a bit more. I *did* try
>(declare (optimize (speed 3)(safety 0))) and a fixnum on "n", but did not see
>much effect.
>
>1) Is there some way I am missing to get MCL to optimize all the nonsense?

Yes. Use define-compiler-macro to perform compile-time form replacement
for optimization. For instance, here are a few compiler macros that
get most of the job done for the above function:

(define-compiler-macro + (&whole form &rest numbers)
  (let ((args (delete-if #'(lambda (number)
                             (equal number 0))
                         numbers)))
    (cond ((cdr args)
           `(+ ,@args))
          (args (car args))
          (t 0))))

(define-compiler-macro * (&whole form &rest numbers)
  (let ((args (remove-if #'(lambda (number)
                             (equal number 1))
                         numbers)))
    (cond ((cdr args)
           `(* ,@args))
          (args (car args))
          (t 1))))

(define-compiler-macro length (&whole form arg)
  (if (and (listp arg)
           (eq (car arg) 'list))
    (length (cdr arg))
    form))

(define-compiler-macro expt (&whole form base power)
  (if (and (symbolp base)
           (equal power 2))
    `(* ,base ,base)
    form))

Note that there are several problems with these, including:
- they may be replacing existing compiler macros
- they only work for a small number of cases
- they assume the functions they are analyzing have not been redefined
  or have unexpected side effects (e.g., via TRACE or STEP)
- they slow down compilation

>If not:
>
>2) Does it matter? Is optimizing away deliberate nonsense just a neat parlor
>trick? Assuming I am cagey enough not to code (expt (wawa 2)), that is. :)

It's a tradeoff. Optimizing away 'nonsense' can be very handy when there
are complex macros generating code; it may make sense to keep a macro
simple and write optimizers to handle inefficient forms that it may output.

You can write a library of compiler macros if you desire, but there will
always be optimization cases that aren't caught. The more thorough the
macros, the more complex and slow they will become, and the returns will
probably diminish rapidly.

- Steve Hain

Digitool, Inc.
______________________________________________________________________________
                       One Main Street   7th Floor   Cambridge, MA 02142   USA
                              Internet: slh@digitool.com   AppleLink: digitool
                                      World Wide Web: http://www.digitool.com/
                                         Tel: 617 441-5000   Fax: 617 576-7680