Subject: access to declaration information?
From: Erik Naggum <clerik@naggum.no>
Date: 1998/03/13
Newsgroups: comp.lang.lisp
Message-ID: <3098779525464968@naggum.no>


  when writing highly optimized code, it is important to bind a variable to
  values of a single type so the compiler can optimize out the (redundant)
  type dispatch or checks, but however useful this may be, it is not quite
  sufficient for speed when macros use local variables that bound to the
  values, yet cannot "inherit" the known type restrictions into their own
  declarations.

  e.g., DOTIMES can easily optimize the representation of the counter
  variable if the upper bound is a constant fixnum, but if the upper bound
  is an expression that ought to be a constant fixnum because the compiler
  has already been informed of the relevant types and values involved, like
  the length of a vector that has been declared with a size, it's out of
  luck, and must use generic integer arithmetic.  in traversing a vector, I
  wouldn't want to use the stupid C-approach and use DEFCONSTANT to define
  a symbol to hold the size and sprinkle that symbol around the code, I
  want to use (LENGTH <vector>) and that should be a constant if <vector>
  is in a scope with, say, (DECLARE (TYPE (VECTOR * 256) <vector>)), and
  variables whose values are tall taken from the set of indexes into this
  vector should be automatically declared (INTEGER 0 256).  also, I want a
  macro-expansion function to be able to make the appropriate declarations
  by querying the environment for the declaration of the subexpressiosn
  involved.  relying on the compiler to optimize away multiple layers of
  general macro-expansion code to divine the appropriate clauses that fit
  the type is just too optimistic.

  suppose I have a vector or some kind, and want to utilize SVREF when the
  vector is a simple vector.  if I could know that the vector is simple in
  function calls that take this vector as argument, I could write a
  compiler macro to differentiate between the simple-vector case and the
  general case.  if I knew some index arguments were declared to be less
  than the length of the vector, I could skip both bignum tests and range
  checks, but I would still want them if the function is called when I
  don't know that.

  I could use generic functions that specialize on all the argument types
  and _hope_ the compiler does compile-time dispatch to methods when it
  knows the types of all the arguments, but this, too, is removing some of
  the control that you want when your code is going to be squeezed to the
  last drop of performance.  of course, you could write your own functions
  that encode the types of the arguments like som manual C++ name-mangler
  and write all optimized code with them, but that is _so_ disgusting.

  this may sound (too) hairy for Lisp, but this is the kind of stuff that
  strongly typed languages so readily exploit.  if it were available for
  Lisp, too, the programmer and the compiler could cooperate on the speed
  of the code, instead of the programmer guessing and hoping he knows what
  makes the compiler happy enough to produce optimal code.

  am I out of luck?

  (note: other languages with these properties are not interesting at this
  time.  Common Lisp doesn't get better by leaving it whenever you need
  something that isn't readily available, and porting applications to
  another language is not an option, anyway.)

#:Erik
-- 
  God grant me serenity to accept the code I cannot change,
  courage to change the code I can, and wisdom to know the difference.