REDUCE

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.