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

Constant-Function



   From:	IN%"edsel!jonl@labrea.stanford.EDU"  "Jon L White" 10-MAY-1988

   re:  Basically, a compiler can't make *any* assumptions at all about a function
        it is compiling a call to without assuming "constant-function" also.  This
        is as true of FTYPE and INLINE declarations as it would be for the more 
        limiting items you mention like number of required arguments, etc.
   
       This is not true.  If there has been an FTYPE declaration, the
       compiler may make assumptions about the types of arguments and values
       of a function, but certainly not about the implementation.
   
   I fail to see your point, since the compiler will also have to assume that
   the function won't be redefined incompatibly.  I hate to keep harping on a
   point, but the first two lines I sent out on this topic say just about
   all there is to be said:
       Isn't it the case that *any* proclaim about a function is equivalent to
       saying that that aspect of the function is "constant"?  

Knowing the FTYPE of sqrt does not allow a compiler to substitute 2.23 for
(sqrt 5).  You might redefine SQRT as SIN without violating the FTYPE.
Declaring SQRT a 'constant-function' does make this legitimate (as would
'inline'.)  Thus FTYPE declarations absolutely *do not* imply 
'Constant-Function' declarations.
   
   Comments by Zacharis and Hornig also confirm that CONSTANT-FUNCTION as a 
   declaration gives you nothing beyond what is already implicit in the 
   collection of INLINE, FTYPE etc.; and CONSTANT-FUNCTION by itself cannot 
   substitute for any one of them individually.  I particularly like Hornig's
   explanation that unless the user explicitly declares a name NOTINLINE,
   the symbolics compiler will make whatever assumptions of constantness it 
   feels like.  You may not even know which aspect is relevant.

Some Symbolics users use ' in place of #' to get around this bug. (!)
I think it exists exactly because the 'constant-function' declaration
is missing, so there has not been a good global way to make it
happen legitimately.  I certainly hope I never see a compiler that
feels it can open-code a random DEFUN without some sort of legitimizing
declaration.  That's what zl:defsubst, 'inline' and 'constant-function' are
for.  

'Inline' is a mistake.  It specifies "that it is desirable for the
compiler to open-code calls to the specified functions" (CLtL 159).
This is a kludge.  It expresses the fact that the functions are
'constant-functions' but then it goes too far and tries to tell the
compiler what to do with that knowledge.  'Constant-Function' is
clean.  It says exactly what you mean, declaratively, without
trying to interfere with the compiler's decision about how to use
the information.  The compiler is in a much better position to
decide whether it is "desirable" to open-code a function.  It can
look at the speed/space optimization settings, the body of the function
and predicted code simplifications after the substitution.

'Constant-Function' should be thought of as a primitive for declaring
where the current boundary of a layered system lies.  I might put
these forms into my INIT file:

   (defun fix-base-system (pkg)
     (do-all-external-symbols (sym pkg)
       (when (fboundp sym)
         (proclaim (list 'constant-function sym))))))

   (fix-base-system 'lisp)
   (fix-base-system 'kee)
   (fix-base-system 'umass-utilities)

It doesn't make sense to do wholesale proclamations like this
using 'inline'.  To me FORMAT is a 'constant-function' but it is
not "desirable for the compiler to open-code calls to" FORMAT.
Many other functions should be considered part of the fixed base
that I am building a system on, without being "desirable" subjects
for open-coding.

I think that a compiler should avoid doing anything that affects
tracability/redefinability until a function has been declared
a 'constant-function'.  After that it may be desirable to declare
some 'constant functions' as 'inline' to encourage open-coding in
situations where the compiler's normal decision is wrong or not
trusted.