
15.9     Switches That Control the Compiler
The compilation process is controlled by a number of switches. In addition to comp there are the
following switches.
*fast-vectors = [Initially: t]                                                                                        
switch
         
 
*fast-evectors = [Initially: t]                                                                                      
switch
         
 
*fast-strings = [Initially: nil]                                                                                     
switch
         
 
*fast-integers = [Initially: nil]                                                                                   
switch
         There  are  some  functions  which  are  defined  in  two  ways.  One  of  these
versions will reduce the execution time by not verifying that the arguments
are of correct type. The name of the slower version will have two properties,
FAST-FLAG and FAST-FUNCTION. The FAST-FLAG property references
a  switch  whose  value  determines  which  function  will  be  called  from
compiled  code.  An  instance  of  the  slower  function  is  replaced  by  the
faster one when the switch is set to t. Of course, to make this conversion
the  compiler  has  to  know  the  name  of  the  faster  function.  This  name  is
referenced by the FAST-FUNCTION property.
 
The property list of the function vector-fetch looks something like
(... (fast-flag . ⋆fast-vectors) (fast-function . igetv) ...)
The expression (vector-fetch vector index) will be replaced by the expression (igetv vector
index) if the switch *fast-vectors is set to t.
*r2i = [Initially: t]                                                                                                      
switch
         If non-nil, recursive calls are converted to jumps whenever possible. The
effect of this is that tracing this function will not show the recursive calls
since they have been eliminated. The function RECURSIVE-FACTORIAL
contains  a  recursive  call  which  can  be  converted  to  a  jump.  The  result
of  compiling  RECURSIVE-FACTORIAL  is  almost  identical  to  that  of
compiling ITERATIVE-FACTORIAL when r2i is non-nil.
 
    (de factorial (n)  (iterative-factorial (1 n)))
    (de recursive-factorial (accumulator count)
 
      (if (<= count 1)
 
         accumulator
 
         (recursive-factorial (⋆ accumulator count)
 
                              (sub1 count))))
     (de iterative-factorial (accumulator count)
 
      (prog ()
 
       loop
 
         (when (<= count 1) (return accumulator))
 
         (setf accumulator (⋆ accumulator count))
 
         (decr count)
 
         (go loop)))
*nolinke = [Initially: nil]                                                                                            
switch
         If  nil,  when  the  last  form  to  be  evaluated  is  a  function  call  then  the
compiler will generate an instruction which will perform two actions during
evaluation. Prior to jumping to the entry point of the function being called,
the  space  allocated  on  the  stack  for  local  variable  storage  is  reclaimed.
Although the amount of space reclaimed may be small, this does provide
the called function with more stack space. In contrast, when this switch is
non-nil a pair of instructions would be used, a call on the function followed
by an exit. In this case the stack space is not reclaimed until the exit.
 
*ord = [Initially: nil]                                                                                                  
switch
         If  non-nil,  the  compiler  is  forced  to  generate  code  which  evaluates
arguments of a function call in a left to right order. It is possible to generate
code  which  is  more  effecient  when  this  switch  is  set  to  nil.  Arguments
are  currently  passed  in  registers.  As  the  calling  function  computes  each
argument the result is stored on the stack. References to constants need not
be generated and then pushed onto the stack, the other arguments can be
compiled first, then just before the function is called the appropriate register
is loaded with the constant. A similar argument can be made for variable
references.  However,  allowing  for  side  effects  we  must  be  sure  that  the
postponed value would be the same as that fetched at the proper time.
 
*plap = [Initially: nil]                                                                                                 
switch
         If  non-nil,  the  portable  intermediate  code  produced  by  the  compiler  is
printed. This is useful for examining compiler output prior to assembly, in
particular it can be helpful in debugging macros.
 
*pgwd = [Initially: nil]                                                                                               
switch
         If non-nil, the actual assembly language mnemonics are displayed. This flag
is useful for examining the code which is generated for the initialization
function **fasl**initcode**.
 
*pcmac = [Initially: nil]                                                                                             
switch
         If non-nil, both the portable intermediate code and the assembly mnemonics
are displayed. After each intermediate instruction the assembly mnemonic
is shown.
 
*pwrds = [Initially: t]                                                                                                 
switch
         If non-nil, the address and size of compiled functions are displayed as they
are defined.