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

Why does my Macro get expanded 8 times?



    Date: Fri, 1 Jul 88 18:28 EDT
    From: SWM@sapsucker.scrc.symbolics.com (Scott McKay)

	Date: Fri, 1 Jul 88 14:18 PDT
	From: Siskind.pa@Xerox.COM

    This is a known problem in the current Lisp compiler.  Our best and
    brightest have failed in their attempts to fix it (and we have tried
    several times).  The problem is inherent in the way "phase-1" of our
    compiler is structured; the only good solutions we know of require
    completely scrapping phase-1, and all other solutions fail in one way or
    another.  We hate this as much as you do, but I regret to say that
    you'll have to live with it for a while.  Sorry.

	I have the following function, which is automatically generated
	from a Prolog query (my own Prolog compiler).

	(DEFUN TOP-LEVEL (MODE)
	  (QUERY SIMPLE-EXAMPLE ((P C)) (:STATISTICS? T :SELECTIVE-BACKTRACKING? T :FAILURE
.....

Actually, you can save at least three of the macro expansions by inserting a NIL as the
first form in the body.  E.G. 

(DEFUN TOP-LEVEL (MODE)
  nil
  (QUERY SIMPLE-EXAMPLE ((P C)) (:STATISTICS? T :SELECTIVE-BACKTRACKING? T :FAILURE

Why ?  The compiler must always expand the first form in a body to see if it will turn
into a DECLARE form.  By putting a NIL there, the compiler doesn't have to do the
expansion.  This is true everywhere a declare can be (e.g. LET, DO, DOTIMES, etc.)

Macroexpansions that turn into nested DOTIMES can really be sped up using this
technique.

Symbolics would do well to do this optimization in their own macros.  One particularly
annoying macro is ECASE which always and needlessly expands twice :
Macro form  (ecase foo (test bar))
  (CLI::EXCASE CASE (MEMBER TEST) FOO
     (TEST BAR))
  (LET ((#:|get-arg-15890| FOO))
     (CASE #:|get-arg-15890|
       (TEST BAR)
       (OTHERWISE (COMPILER:%ERROR-UNLESS NIL (DBG:CHECK-TYPE-1 'FOO #:|get-arg-15890| '(MEMBER TEST) NIL T) NIL))))


If the definition of CLI::EXCASE were changed to have a NIL after the LET, ECASEs would
macroexpand twice as fast.  [Anyone listening there at Symbolics ?]

-- jim