12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286 |
- PSL Manual 7 February 1983 Compiler and Loader
- section 18.0 page 18.1
- CHAPTER 18
CHAPTER 18
CHAPTER 18
- LOADER AND COMPILER
LOADER AND COMPILER
LOADER AND COMPILER
- 18.1. Introduction . . . . . . . . . . . . . . . 18.1
- 18.2. The Compiler . . . . . . . . . . . . . . . 18.2
- 18.2.1. Compiling Functions into Memory . . . . . . 18.2
- 18.2.2. Compiling Functions into FASL Files . . . . . 18.3
- 18.2.3. Loading FASL Files. . . . . . . . . . . 18.3
- 18.2.4. Functions to Control the Time When Something is Done 18.5
- .
- 18.2.5. Order of Functions for Compilation . . . . . 18.6
- 18.2.6. Fluid and Global Declarations . . . . . . . 18.6
- 18.2.7. Switches Controlling Compiler . . . . . . . 18.8
- 18.2.8. Differences between Compiled and Interpreted Code 18.10
- 18.2.9. Compiler Errors. . . . . . . . . . . . 18.11
- 18.3. The Loader. . . . . . . . . . . . . . . . 18.13
- 18.3.1. Legal LAP Format and Pseudos . . . . . . . 18.14
- 18.3.2. Examples of LAP for DEC-20, VAX and Apollo. . . 18.14
- 18.3.3. Lap Switches. . . . . . . . . . . . . 18.17
- 18.4. Structure and Customization of the Compiler. . . . . 18.18
- 18.5. First PASS of Compiler. . . . . . . . . . . . 18.19
- 18.5.1. Tagging Information . . . . . . . . . . 18.19
- 18.5.2. Source to Source Transformations . . . . . . 18.20
- 18.6. Second PASS - Basic Code Generation . . . . . . . 18.20
- 18.6.1. The Cmacros . . . . . . . . . . . . . 18.20
- 18.6.2. Classes of Functions . . . . . . . . . . 18.23
- 18.6.3. Open Functions . . . . . . . . . . . . 18.24
- 18.7. Third PASS - Optimizations . . . . . . . . . . 18.29
- 18.8. Some Structural Notes on the Compiler. . . . . . . 18.30
- 18.1. Introduction
18.1. Introduction
18.1. Introduction
- The functions and facilities in the PSL LISP/SYSLISP compiler and
- supporting loaders (LAP and FASL) are described in this chapter.
- [??? This chapter is out of date and will be rewritten soon. ???]
[??? This chapter is out of date and will be rewritten soon. ???]
[??? This chapter is out of date and will be rewritten soon. ???]
- 18.2. The Compiler
18.2. The Compiler
18.2. The Compiler
- The compiler is a version of the Portable LISP Compiler [Griss 81],
Compiler and Loader 7 February 1983 PSL Manual
- page 18.2 section 18.2
- 1
- modified and extended to more efficiently support both LISP and SYSLISP
- compilation. See the later sections in this chapter and references [Griss
- 81] and [Benson 81] for more details.
- 18.2.1. Compiling Functions into Memory
18.2.1. Compiling Functions into Memory
18.2.1. Compiling Functions into Memory
- __________ ______
!*COMP [Initially: NIL] switch
- If the compiler is loaded (which is usually the case, otherwise
- on
on
execute LOAD COMPILER;), turning on the switch !*COMP (via on
- comp; in RLISP) causes all subsequent procedure definitions of
- appropriate type to be compiled automatically and a message of
- the form
- <function-name> COMPILED, <words> WORDS, <words> LEFT
- to be printed. The first number is the number of words of binary
- program space the compiled function took, and the second number
- the number of words left unused in binary program space. See
- !*PWRDS in Section 18.2.7.
- ____ _____ _____ _____
____ _____ _____ _____
____ _____ _____ _____
expr fexpr nexpr macro
expr fexpr nexpr macro
Currently, exprs, fexprs, nexprs and macros may be compiled. This is
- controlled by a flag ('COMPILE) on the property list of the procedure type.
- If desired, uncompiled functions already resident may be compiled by
- using
- Compile
Compile _____ __ ____ ___ ____
(Compile NAMES:id-list): any expr
- 18.2.2. Compiling Functions into FASL Files
18.2.2. Compiling Functions into FASL Files
18.2.2. Compiling Functions into FASL Files
- Load FaslIn
Load FaslIn
In order to produce files that may be input using Load or FaslIn, the
- FaslOut FaslEnd
FaslOut FaslEnd
FaslOut and FaslEnd pair may be used in RLISP mode:
- FaslOut
FaslOut ____ ______ ___ ____
(FaslOut FILE:string): NIL expr
- _______________
- 1
- Many of the recent extensions to the PLC were implemented by John
- Peterson.
PSL Manual 7 February 1983 Compiler and Loader
- section 18.2 page 18.3
- FaslEnd
FaslEnd ___ ____
(FaslEnd ): NIL expr
- FaslOut
FaslOut
After the command FaslOut has been given, all subsequent
- S-expressions and function definitions typed in or input from
- files are processed by the Compiler, LAP and FASL as needed, and
- ____
output to FILE. Functions are compiled and partially assembled,
- and output as in a compressed binary form, involving blocks of
- code and relocation bits. This activity continues until the
- FaslEnd
FaslEnd
function FaslEnd terminates this process.
- FaslOut FaslEnd
FaslOut FaslEnd
The FaslOut and FaslEnd pair also use the DFPRINT!* mechanism, turning on
- the switch !*DEFN, and redefining DFPRINT!* to trap the parsed input in the
- RLISP top-loop. Currently this is not useable from pure LISP level.
- [??? Fix, by adding !*DEFN mechanism to basic top-loop. ???]
[??? Fix, by adding !*DEFN mechanism to basic top-loop. ???]
[??? Fix, by adding !*DEFN mechanism to basic top-loop. ???]
- 18.2.3. Loading FASL Files
18.2.3. Loading FASL Files
18.2.3. Loading FASL Files
- Two convenient procedures are available for loading FASL files (.b files
- on the VAX); see Section 18.2.2 for information on producing FASL files.
- Load
Load ____ ______ __ ___ _____
(Load [FILE:{string, id}]): NIL macro
- ____
Each FILE is converted into a file name of the form
- "/u/local/lib/psl/file.b" on the VAX, "pl:file.b" on the DEC-20.
- FaslIn
FaslIn
An attempt is made to execute the function FaslIn on it. Once
- ____
loaded, the symbol FILE is added to the GLOBAL variable
- OPTIONS!*.
- FaslIn
FaslIn ________ ______ ___ ____
(FaslIn FILENAME:string): NIL expr
- This is an efficient binary read loop, which fetches blocks of
- __
code, constants and compactly stored ids. It uses a bit-table to
- relocate code and to identify special LISP-oriented constructs.
- ________
FILENAME must be a complete file name.
- ReLoad
ReLoad ____ ______ __ ___ _____
(ReLoad [FILE:{string,id}]): NIL macro
- Removes the filename from the list OPTIONS!* and executes the
- Load
Load
function Load.
- Imports
Imports ___________ ____ ___ ____
(Imports MODULENAMES:list): NIL expr
- LOAD
___________ __ LOAD
MODULENAMES is a list of ids representing modules to be LOAD'ed
- after the module containing this function has been loaded.
- Imports
Imports
Imports works only in compiled code.
Compiler and Loader 7 February 1983 PSL Manual
- page 18.4 section 18.2
- __________ ______
LOADDIRECTORIES!* [Initially: A list of strings] global
- Contains a list of strings to append to the front of file names
- Load
Load
given in Load commands. This list may be one of the following,
- if your system is an Apollo, Dec-20, or Vax:
- ("" "/utah/psl/lap/")
- ("" "pl:")
- ("" "/usr/local/src/cmd/psl/dist/lap/")
- __________ ______
LOADEXTENSIONS!* [Initially: An a-list] global
- Contains an a-list of (str . fn) in which the str is an extension
- to append to the end of the filename and fn is a function to
- apply. The a-list contains
- ((".b" . FaslIn)(".lap" . LapIn)(".sl" . LapIN))
- [??? Describe FASL format in more detail ???]
[??? Describe FASL format in more detail ???]
[??? Describe FASL format in more detail ???]
- 18.2.4. Functions to Control the Time When Something is Done
18.2.4. Functions to Control the Time When Something is Done
18.2.4. Functions to Control the Time When Something is Done
- Which expressions are evaluated during compilation ONLY, which output to
- the file for LOAD TIME evaluation, and which do both (such as macro
- definitions) can be controlled by the properties 'EVAL and 'IGNORE on
- certain function names, or the following functions.
- CommentOutCode
CommentOutCode _ ____ ___ _____
(CommentOutCode U:form): NIL macro
- _
Comment out a single expression; use <<U>> to comment out a block
- of code.
- CompileTime
CompileTime _ ____ ___ ____
(CompileTime U:form): NIL expr
- _
Evaluate the expression U at compile time only, such as defining
- auxiliary smacros and macros that should not go into the file.
- Certain functions have the FLAG 'IGNORE on their property lists
- to achieve the same effect. E.g. FLAG('(LAPOUT LAPEND),'IGNORE)
- has been done.
- BothTimes
BothTimes _ ____ _ ____ ____
(BothTimes U:form): U:form expr
- Evaluate at compile and load time. This is equivalent in effect
- Flag
Flag
to executing Flag('(f1 f2),'EVAL) for certain functions.
PSL Manual 7 February 1983 Compiler and Loader
- section 18.2 page 18.5
- LoadTime
LoadTime _ ____ _ ____ ____
(LoadTime U:form): U:form expr
- Evaluate at load time only. Should not even compile code, just
- pass direct to file.
- [??? EVAL and IGNORE are for compatibility, and enable the above sort
[??? EVAL and IGNORE are for compatibility, and enable the above sort
[??? EVAL and IGNORE are for compatibility, and enable the above sort
- of functions to be easily written. The user should AVOID EVAL and
of functions to be easily written. The user should AVOID EVAL and
of functions to be easily written. The user should AVOID EVAL and
- IGNORE flags, if Possible ???]
IGNORE flags, if Possible ???]
IGNORE flags, if Possible ???]
- 18.2.5. Order of Functions for Compilation
18.2.5. Order of Functions for Compilation
18.2.5. Order of Functions for Compilation
- ____
____
____
expr
expr
Non-expr procedures must be defined before their use in a compiled
- function, since the compiler treats the various function types differently.
- _____ _____
_____ _____
_____ _____
Macro fexpr
Macro fexpr
Macros are expanded and then compiled; the argument list fexprs quoted; the
- _____
_____
_____
nexpr
nexpr
arguments of nexprs are collected into a single list. Sometimes it is
- convenient to define a Dummy version of the function of appropriate type,
- to be redefined later. This acts as an "External or Forward" declaration
- of the function.
- [??? Add such a declaration. ???]
[??? Add such a declaration. ???]
[??? Add such a declaration. ???]
- 18.2.6. Fluid and Global Declarations
18.2.6. Fluid and Global Declarations
18.2.6. Fluid and Global Declarations
- The FLUID and GLOBAL declarations must be used to indicate variables that
- are to be used as non-LOCALs in compiled code. Currently, the compiler
- defaults variables bound in a particular procedure to LOCAL. The effect of
- this is that the variable only exists as an "anonymous" stack location; its
- name is compiled away and called routines cannot see it (i.e. they would
- have to use the name). Undeclared non-LOCAL variables are automatically
- declared FLUID by the compiler with a warning. In many cases, this means
- that a previous procedure that bound this variable should have known about
- this as a FLUID. Declare it with FLUID, below, and recompile, since the
- caller cannot be automatically fixed.
- [??? Should we provide an !*AllFluid switch to make the default Fluid,
[??? Should we provide an !*AllFluid switch to make the default Fluid,
[??? Should we provide an !*AllFluid switch to make the default Fluid,
- or should we make Interpreter have a LOCAL variable as default, or both
or should we make Interpreter have a LOCAL variable as default, or both
or should we make Interpreter have a LOCAL variable as default, or both
- ???]
???]
???]
- Fluid
Fluid _____ __ ____ ___ ____
(Fluid NAMES:id-list): any expr
- Declares each variable FLUID (if not previously declared); this
- Prog
Prog
means that it can be used as a Prog LOCAL, or as a parameter. On
- entry to the procedure, its current value is saved on the Binding
- Stack (BSTACK), and all access is always to the VALUE cell
- Throw Error
Throw Error
(SYMVAL) of the variable; on exit (or Throw or Error), the old
- values are restored.
Compiler and Loader 7 February 1983 PSL Manual
- page 18.6 section 18.2
- Global
Global _____ __ ____ ___ ____
(Global NAMES:id-list): any expr
- Declares each variable GLOBAL (if not previously declared); this
- means that it cannot be used as a LOCAL, or as a parameter.
- Access is always to the VALUE cell (SYMVAL) of the variable.
- [??? Should we eliminate GLOBALs ???]
[??? Should we eliminate GLOBALs ???]
[??? Should we eliminate GLOBALs ???]
- 18.2.7. Switches Controlling Compiler
18.2.7. Switches Controlling Compiler
18.2.7. Switches Controlling Compiler
- The compilation process is controlled by a number of switches, as well as
- the above declarations and the !*COMP switch, of course.
- __________ ______
!*R2I [Initially: T] switch
- T
T
If T, causes recursion removal if possible, converting recursive
- calls on a function into a jump to its start. If this is not
- possible, it uses a faster call to its own "internal" entry,
- rather than going via the Symbol Table function cell. The effect
- in both cases is that tracing this function does not show the
- internal or eliminated recursive calls, nor the backtrace
- information.
- __________ ______
!*NOLINKE [Initially: NIL] switch
- T NIL
T NIL
If T, inhibits use of !*LINKE cmacro. If NIL, "exit" calls on
- functions that would then immediately return. For example, the
- calls on FOO(x) and FEE(X) in
- PROCEDURE DUM(X,Y);
- IF X=Y THEN FOO(X) ELSE FEE(X+Y);
- can be converted into direct JUMP's to FEE or FOO's entry point.
- This is known as a "tail-recursive" call being converted to a
- jump. If this happens, there is no indication of the call of DUM
- on the backtrace stack if FEE or FOO cause an error.
- __________ ______
!*ORD [Initially: NIL] switch
- T
T
If T, forces the compiler to compile arguments in Left-Right
- Order, even though more optimal code can be generated.
- [??? !*ORD currently has a bug, and may not be fixed for some
[??? !*ORD currently has a bug, and may not be fixed for some
[??? !*ORD currently has a bug, and may not be fixed for some
- time. Thus do NOT depend on evaluation order in argument
time. Thus do NOT depend on evaluation order in argument
time. Thus do NOT depend on evaluation order in argument
- lists ???]
lists ???]
lists ???]
PSL Manual 7 February 1983 Compiler and Loader
- section 18.2 page 18.7
- __________ ______
!*MODULE [Initially: NIL] switch
- Indicates block compilation (a future extension of this
- compiler). When implemented, even more function and variable
- names are "compiled away".
- The following switches control the printing of information during the
- compilation process:
- __________ ______
!*PWRDS [Initially: NIL] switch
- T
T
If T, causes the compiled size to be printed in the form
- *** NAME: base NNN, length MMM
- The base is in octal, the length is in current Radix.
- [??? more mnemonic name ???]
[??? more mnemonic name ???]
[??? more mnemonic name ???]
- __________ ______
!*PLAP [Initially: NIL] switch
- T
T
If T, causes the printing of the portable cmacros produced by the
- the compiler.
- Most of this information is printed by the resident LAP, and controlled
- by its switches, described below.
- 18.2.8. Differences between Compiled and Interpreted Code
18.2.8. Differences between Compiled and Interpreted Code
18.2.8. Differences between Compiled and Interpreted Code
- The following just re-iterates some of the points made above and in other
- Sections of the manual regarding the "obscure" differences that compilation
- introduces.
- [??? This needs some careful work, and perhaps some effort to reduce
[??? This needs some careful work, and perhaps some effort to reduce
[??? This needs some careful work, and perhaps some effort to reduce
- the list of differences ???]
the list of differences ???]
the list of differences ???]
- In the process of compilation, many functions are open-coded, and hence
- cannot be redefined or traced in the compiled code. Such functions are
- noted to be OPEN-CODED in the manual. If called from compiled code, the
- call on an open-compiled function is replaced by a series of online
- instructions. Most of these functions have some sort of indicator on their
- property lists: 'OPEN, 'ANYREG, 'CMACRO, 'COMPFN, etc. For example: SETQ,
- CAR, CDR, COND, WPLUS2, MAP functions, PROG, PROGN, etc. Also note that
- _____
_____
_____
macro
macro
some functions are defined as macros, which convert to some other form
- (such as PROG), which itself might compile open.
- Some optimizations are performed that cause inaccessible or redundant
- code to be removed, e.g. 0*foo(x) could cause foo(x) not to be called.
Compiler and Loader 7 February 1983 PSL Manual
- page 18.8 section 18.2
- _____ ______
_____ ______
_____ ______
Fluid global
Fluid global
Unless variables are declared (or detected) to be Fluid or global, they
- _____
_____
_____
local
local
are compiled as local variables. This causes their names to disappear, and
- so are not visible on the Binding Stack. Further more, these variables are
- NOT available to functions called in the dynamic scope of the function
- containing their binding.
- _____ _____ _____
_____ _____ _____
_____ _____ _____
macro fexpr nexpr
macro fexpr nexpr
Since compiled calls on macros, fexprs and nexprs are different from the
- ____
____
____
expr
expr
default exprs, these functions must be declared (or defined) before
- _____ _____
_____ _____
_____ _____
fexpr nexpr
fexpr nexpr
compiling the code that uses them. While fexprs and nexprs may
- _____
_____
_____
macro
macro
subsequently be redefined (as new functions of same type), macros are
- executed by the compiler to get the replacement form, which is then
- compiled. The interpreter of course picks up the most recent definition of
- ANY function, and so functions can switch type as well as body.
- [??? If we expand macros at PUTD time, then this difference will go
[??? If we expand macros at PUTD time, then this difference will go
[??? If we expand macros at PUTD time, then this difference will go
- away. ???]
away. ???]
away. ???]
- As noted above, the !*R2I, !*NOLINKE and !*MODULE switches cause certain
- functions to call other functions (or themselves usually) by a faster route
- (JUMP or internal call). This means that the recursion or call may not be
- visible during tracing or backtrace.
- 18.2.9. Compiler Errors
18.2.9. Compiler Errors
18.2.9. Compiler Errors
- A number of compiler errors are listed below with possible explanations
- of the error.
- *** Function form converted to APPLY
- Car
Car
This message indicates that the Car of a form is either
- a. Non-atomic,
- b. a local variable, or
- c. a global or fluid variable.
- The compiler converts (F X1 X2 ...), where F is one of the above, to (APPLY
- F (LIST X1 X2 ...)).
- *** NAME already SYSLISP non-local
- This indicates that NAME is either a WVAR or WARRAY in SYSLISP mode, but is
- being used as a local variable in LISP mode. No special action is taken.
- *** WVAR NAME used as local
- This indicates that NAME is a WVAR, but is being used as a bound variable
- in SYSLISP mode. The variable is treated as an an anonymous local variable
- within the scope of its binding.
PSL Manual 7 February 1983 Compiler and Loader
- section 18.2 page 18.9
- *** NAME already SYSLISP non-local
- This indicates that a variable was previously declared as a SYSLISP WVAR or
- WARRAY and is now being used as a LISP fluid or global. No special action
- is taken.
- *** NAME already LISP non-local
- This indicates that a variable was previously declared as a LISP fluid or
- global and is now being used as a SYSLISP WVAR or WARRAY. No special
- action is taken.
- *** Undefined symbol NAME in Syslisp, treated as WVAR
- A variable was encountered in SYSLISP mode which is not local nor a WVAR or
- WARRAY. The compiler declares it a WVAR. This is an error, all WVARs
- should be explicitly declared.
- *** NAME declared fluid
- A variable was encountered in LISP mode which is not local nor a previously
- declared fluid or global. The compiler declares it fluid. This is
- sometimes an error, if the variable was used strictly locally in an earlier
- function definition, but was intended to be bound non-locally. All fluids
- should be declared before being used.
- 18.3. The Loader
18.3. The Loader
18.3. The Loader
- [??? update ???]
[??? update ???]
[??? update ???]
- Currently, PSL on the DEC-20 provides a simple LISP assembler, LAP. This
- is modeled after the original LISP 1.6 LAP, although completely
- reimplemented to take advantage of PSL constructs, and to support the
- additional requirements of SYSLISP. In the process of implementing the VAX
- LAP and developing the LAP-to-ASM translator required to bootstrap PSL onto
- the next machine (Apollo MC68000), a much more table-driven form of LAP was
- designed to make all LAP's, LAP-to-ASM's and FASL's (fast loaders,
- sometimes called FAP) easier to maintain. This is now in use on the VAX
- and being used to implement Apollo PSL.
- [??? FASL now works ???]
[??? FASL now works ???]
[??? FASL now works ???]
- Until that is complete, we will briefly describe the available functions,
- and give a sample of current and future LAP; this Section will be
- completely rewritten in the next revision. LAP is currently a full two
- pass assembler; on the VAX and Apollo it also includes a pass to optimize
- long and short jumps.
Compiler and Loader 7 February 1983 PSL Manual
- page 18.10 section 18.3
- LAP
LAP ____ ____ ____ _______ ____
(LAP CODE:list): code-pointer expr
- ____
CODE is a list of legal LAP forms, including:
- a. Machine specific Mnemonics (using opcode-names from the
- assembler on the DEC-20, VAX or Apollo).
- b. Compiler cmacros (which expand in a machine specific way).
- These can be thought of as "generic" or LISP-oriented
- instructions. See the next Section on the Compiler details, and
- list of legal cmacros.
- c. LAP pseudo instructions, to declare entry points, indicate data
- and constants, etc.
- The first pass of LAP converts mnemonics into LISP integers, doing as
- much of the assembly as possible, allocating labels and constants. The
- second (and third?) pass fills in labels and completes the assembly,
- depositing code into the next available locations in BPS, or creating FASL
- or LAP files.
- [??? What is BPS (binary program space) ???]
[??? What is BPS (binary program space) ???]
[??? What is BPS (binary program space) ???]
- 18.3.1. Legal LAP Format and Pseudos
18.3.1. Legal LAP Format and Pseudos
18.3.1. Legal LAP Format and Pseudos
- [??? Describe LAP format in detail ???]
[??? Describe LAP format in detail ???]
[??? Describe LAP format in detail ???]
- 18.3.2. Examples of LAP for DEC-20, VAX and Apollo
18.3.2. Examples of LAP for DEC-20, VAX and Apollo
18.3.2. Examples of LAP for DEC-20, VAX and Apollo
- The following is a piece of VAX specific LAP, using the current "new"
- format. Apart from the VAX mnemonics, notice the extra tags around the
- register names, and the symbols to indicate addressing modes (essentially
- PREFIX syntax rather then INFIX @ etc.). This is from PV:APPLY-LAP.RED.
- Note they are almost ENTIRELY written in cmacros, to aid in re-coding for
- the next machine.
PSL Manual 7 February 1983 Compiler and Loader
- section 18.3 page 18.11
- lap '((!*entry FastApply expr 0)
- %. Apply with arguments loaded
- % Called with arguments in the registers and functional form in t1
- (!*FIELD (reg t2) (reg t1)
- (WConst TagStartingBit) (WConst TagBitLength))
- (!*FIELD (reg t1) (reg t1)
- (WConst InfStartingBit) (WConst InfBitLength))
- (!*JUMPNOTEQ (Label NotAnID) (reg t2) (WConst ID))
- (!*WTIMES2 (reg t1) (WConst AddressingUnitsPerFunctionCell))
- (!*JUMP (MEMORY (reg t1) (WArray SymFnc)))
- NotAnID
- (!*JUMPNOTEQ (Label NotACodePointer) (reg t2) (WConst CODE))
- (!*JUMP (MEMORY (reg t1) (WConst 0)))
- NotACodePointer
- (!*JUMPNOTEQ (Label IllegalFunctionalForm) (reg t2) (WConst
- (!*MOVE (MEMORY (reg t1) (WConst 0)) (reg t2))
- % CAR with pair already unta
- (!*JUMPNOTEQ (Label IllegalFunctionalForm) (reg t2) (QUOTE L
- (!*MOVE (reg t1) (reg t2)) % put lambda form in t2
- (!*PUSH (QUOTE NIL)) % align stack
- (!*JCALL FastLambdaApply)
- IllegalFunctionalForm
- (!*MOVE (QUOTE "Illegal functional form in Apply") (reg 1))
- (!*MOVE (reg t1) (reg 2))
- (!*CALL List2)
- (!*JCALL StdError)
- );
- lap '((!*entry UndefinedFunction expr 0)
- %. Error Handler for non code
- % Called by JSB
- %
- (subl3 (immediate (plus2 (WArray SymFnc) 6))
- (autoincrement (reg st))
- (reg t1))
- (divl2 6 (reg t1))
- (!*MKITEM (reg t1) (WConst ID))
- (!*MOVE (reg t1) (reg 2))
- (!*MOVE (QUOTE "Undefined function %r called from compiled c
- (reg 1))
- (!*CALL BldMsg)
- (!*JCALL StdError)
- );
- The following is a piece of Apollo specific LAP, using the current NEW
- format. Apart from the MC68000 mnemonics, notice the extra tags around the
- register names, and the symbols to indicate addressing modes (essentially
- PREFIX syntax rather then INFIX @ etc.). This is from P68:M68K-USEFUL-
- LAP.RED.
Compiler and Loader 7 February 1983 PSL Manual
- page 18.12 section 18.3
- % Signed multiply of 32 bits numbers in A1 and A2,
- % returns 64 bits in A1 and A2, low in A1 high in A2
- % Clobbers D1,D2,D3,D4,D5,D6,D7, no saving
- % [Can insert MOVEM!.L D1-D7,-(SP)
- % and MOVEM!.L (SP)+,D1-D7]
- LAP '((!*entry Mult32 expr 2) % Arguments in A1 and A2
- (move!.l (reg a1) (reg d1))
- (move!.l (reg a1) (reg d6))
- (move!.l (reg a2) (reg d2))
- (move!.l (reg a2) (reg d7)) % Need copies
- % Now do Unsigned Multiply
- (move!.l (reg d1) (reg d3))
- (move!.l (reg d1) (reg d4))
- (swap (reg d4))
- (move!.l (reg d2) (reg d5))
- (swap (reg d5)) % Swapped for partial products
- (mulu!.w (reg d2) (reg d1)) % partial products (pp1)
- (mulu!.w (reg d4) (reg d2)) % pp2
- (mulu!.w (reg d5) (reg d3)) % pp3
- (mulu!.w (reg d5) (reg d4)) % pp4
- (swap (reg d1)) % sum1=pp#2low+pp#1hi
- (add (reg d2) (reg d1))
- (clr!.l (reg d5))
- (addx!.l (reg d5) (reg d4)) % propagate carry
- (add (reg d3) (reg d1)) % sum2=sum1+pp#3low
- (addx!.l (reg d5) (reg d4)) % carry inot pp#4
- (swap (reg d1)) % low order product
- (clr (reg d2))
- (swap (reg d2))
- (clr (reg d3))
- (swap (reg d3))
- (add!.l (reg d3) (reg d2)) % Sum3=pp2low+pp3Hi
- (add!.l (reg d4) (reg d2)) % Sum4=Sum3+pp4
- % Now do adjustment
- (tst!.l (reg d7)) % Negative
- (bpl!.s chkd6) % nope
- (sub!.l (reg d6) (reg d2)) % Flip
- chkd6
- (tst!.l (reg d6)) % Negative
- (bpl!.s done) % nope
- (sub!.l (reg d7) (reg d2)) % Flip
- done
- (movea!.l (reg d1) (reg a1)) % low part
- (movea!.l (reg d2) (reg a2)) % high part
- (rts));
PSL Manual 7 February 1983 Compiler and Loader
- section 18.3 page 18.13
- 18.3.3. Lap Switches
18.3.3. Lap Switches
18.3.3. Lap Switches
- The following switches control the printing of information from LAP and
- other optional behavior of LAP:
- __________ ______
!*PLAP [Initially: NIL] switch
- Causes LAP forms to printed before expansion. Used mainly to see
- output of compiler before assembly.
- __________ ______
!*PGWD [Initially: NIL] switch
- Causes LAP to print the actual DEC-20 mnemonics and corresponding
- assembled instruction in octal, displaying OPCODE, REGISTER,
- INDIRECT, INDEX and ADDRESS fields.
- __________ ______
!*PWRDS [Initially: T] switch
- Prints a LAP message of the form
- *** NAME: base NNN, length MMM
- The base is in octal, the length is in current Radix.
- __________ ______
!*SAVECOM [Initially: T] switch
- If T, the LAP is deposited in BPS, and the returned Code-Pointer
- used to (re)define the procedure associated with the (!*entry
- name type n).
- __________ ______
!*SAVEDEF [Initially: NIL] switch
- If T, and if !*SAVECOM is T, saves any preexisting procedure
- definition under '!*SAVEDEF on the property list of the procedure
- name, "just in case".
- LAP also uses the following indicators on property lists:
- 'MC Cmacros and some mnemonics have associated PASS1 expansions in
- terms of simpler instructions or operations. The form (mc a1 ...
- an) has its associated function applied to (a1 ... an).
- For more details, see "P20:LAP.RED".
Compiler and Loader 7 February 1983 PSL Manual
- page 18.14 section 18.4
- 18.4. Structure and Customization of the Compiler
18.4. Structure and Customization of the Compiler
18.4. Structure and Customization of the Compiler
- The following is a brief summary of the compiler structure and model.
- The purpose of this Section is to aid the user to add new compilation
- forms, and to understand the task of bootstrapping a new version of PSL.
- The original paper on the Portable LISP Compiler [Griss 81] has complete
- details on the original version of the compiler, and should be read in
- conjunction with this Section. It might be useful to also examine the
- paper on recent work on the compiler [Griss 82].
- [??? This needs a LOT of work ???]
[??? This needs a LOT of work ???]
[??? This needs a LOT of work ???]
- The compiler is basically three-pass:
- ______
______
______
macros
macros
a. The first pass expands ordinary macros, and compiler specific
- cmacros. It also uses some special purpose 'PA1REFORM and
- 'PA1FN functions on the property lists of certain functions to
- produce a simpler and more explicit LISP for the next pass.
- Variables and constants, x, are explicitly tagged as (FLUID x),
- (GLOBAL x), (QUOTE x), (WCONST x), etc.
- b. The second pass recursively compiles the code, using 'COMPFN's
- to handle special cases, and the recursive function !&COMPILE
- for the general case. In general, code is compiled to cause
- function arguments to be loaded into R1...Rn in order, a CALL to
- the function to be made, and the returned value to appear in R1.
- Temporaries and function arguments to be reused later are saved
- on the stack. The compiler allocates a single FRAME for the
- maximum stack space that might be needed, and then trims it down
- in the third pass. PSL requires registers R1 ... R15, though
- not all need be "REAL registers"; the extra are simulated as
- memory locations. Special cases avoid a lot of LOAD/STORES to
- move arguments around. The compiled code is emitted as a
- sequence of abstract LISP machine cmacros. The current set of
- cmacros is described below.
- c. The third pass scans the list of cmacros for patterns, removing
- LOADs and STOREs, redundant JUMP's and LABEL's, compressings the
- stack frame, and possibly mapping temporaries stored on the
- stack into any of the REAL registers that would otherwise be
- unused. This optimized cmacro list is then passed to LAP.
- 18.5. First PASS of Compiler
18.5. First PASS of Compiler
18.5. First PASS of Compiler
PSL Manual 7 February 1983 Compiler and Loader
- section 18.5 page 18.15
- 18.5.1. Tagging Information
18.5.1. Tagging Information
18.5.1. Tagging Information
- This affects many parts of the compiler. The basic idea is that all
- information is to be tagged. These tags fit in three categories: variable
- tags, location (register and frame) tags, and constant tags. Tags used for
- variables must be flagged 'VAR; tags for constants must be flagged 'CONST.
- Currently, the register tag is REG and the frame tag is FRAME. Frame
- locations are always positive integers.
- These tags are used everywhere; thus, register 1 is always described by
- (REG 1) in both emitted cmacros and internally in the register list REGS.
- Pass 1 tags all variable references with a source to source transformation
- of the variables (suitably obscure names must be used for these tags to
- prevent conflicts with named functions).
- The purpose behind this tagging is to make the compiler easier to work
- with in adding new features; new notions of registers, constants, and
- variables can all be accommodated through new tags. Also, the components
- of the cmacros are more clearly identified for pass 3.
- 18.5.2. Source to Source Transformations
18.5.2. Source to Source Transformations
18.5.2. Source to Source Transformations
- A PA1REFORMFN has been provided to augment PA1FN's. The only difference
- between these functions is that the PA1REFORM function is passed code which
- has already been through PASS1. This was previously done by calling pass 1
- within a PA1FN.
- 18.6. Second PASS - Basic Code Generation
18.6. Second PASS - Basic Code Generation
18.6. Second PASS - Basic Code Generation
- 18.6.1. The Cmacros
18.6.1. The Cmacros
18.6.1. The Cmacros
- The compiler second pass compiles the input LISP into a series of
- abstract machine instructions, called cmacros. These are instructions for
- a LISP-oriented Register machine.
- ___ _______ ______ _______
The current DEC-20 cmacros
- Definitions of arguments
- reg: (REG n) n = 1,2,... MAXNARGS
- var: frame | (GLOBAL name) | (FLUID name)
- frame: (FRAME n) n = 0,1,2, ..
- const: (QUOTE value) | (WCONST value)
- label: (LABEL symbol)
- regn: reg | NIL | frame
- regf: reg | frame
- loc: reg | var | const
Compiler and Loader 7 February 1983 PSL Manual
- page 18.16 section 18.6
- anyreg: (CAR anyreg) | (CDR anyreg) | loc
- Basic Cmacros for LISP and SYSLISP
- (!*ALLOC nframe)
- (!*DEALLOC nframe)
- (!*ENTRY fname ftype nargs)
- (!*EXIT nframe)
- (!*FREERSTR (NONLOCALVARS f1 f2 ...))
- (!*JUMP label)
- (!*JUMPxx label loc loc')
- where xx = ATOM, EQ, NOTEQ, NOTTYPE, PAIRP, TYPE
- (!*JUMPON lower upper (label-1 ... Label-n))
- (!*LINK fname ftype nargs)
- (!*LINKE nframe fn type nargs)
- (!*LINKF nargs reg) where reg contains the function name,
- nargs an integer
- (!*LINKEF nframe nargs reg) %/ ?
- (!*LBL label)
- (!*LAMBIND (REGISTERS reg1 reg2 ...) (NONLOCALVARS f1 f2 ...))
- where f1, f2, ... = (FLUID name )
- No frame location will be allocated (depends on switch)
- (!*LOAD reg anyreg)
- (!*PROGBIND (NONLOCALVARS f1 f2 ...))
- (!*PUSH reg)
- (!*RPLACA regf loc)
- (!*RPLACD regf loc)
- (!*STORE regn var) | (!*STORE regn reg)
- SYSLISP oriented Cmacros
- (!*ADDMEM loc)
- (!*ADJSP ?)
- (!*DECMEM loc)
- (!*INCMEM loc)
- (!*INTINF loc)
- (!*JUMPWGEQ label loc loc')
- (!*JUMPWGREATERP label loc loc')
- (!*JUMPWITHIN label loc loc')
- (!*JUMPWLEQ label loc loc')
- (!*JUMPWLESSP label loc loc')
- (!*MKITEM loc loc')
- (!*MPYMEM loc loc')
- (!*NEGMEM loc)
- (!*SUBMEM loc loc')
- (!*WAND loc loc')
- (!*WDIFFERENCE loc loc')
- (!*WMINUS loc)
- (!*WNOT loc)
- (!*WOR loc loc')
- (!*WPLUS2 loc loc')
- (!*WSHIFT loc loc')
- (!*WTIMES2 loc loc')
PSL Manual 7 February 1983 Compiler and Loader
- section 18.6 page 18.17
- (!*WXOR loc loc')
- _____ _______
68000 Cmacros
- Basic LISP and SYSLISP Cmacros
- (!*ALLOC nframe)
- (!*CALL fname)
- (!*DEALLOC nframe)
- (!*ENTRY fname ftype nargs)
- (!*EXIT nframe)
- (!*JCALL fname)
- (!*JUMP label)
- (!*JUMPEQ label loc loc')
- (!*JUMPINTYPE label type)
- (!*JUMPNOTEQ label loc loc')
- (!*JUMPNOTINTYPE label loc type)
- (!*JUMPNOTTYPE label loc type)
- (!*JUMPTYPE label loc type)
- (!*LAMBIND label loc loc')
- (!*LBL label)
- (!*LINK fname ftype nargs)
- (!*LINKE fname ftype nargs nframe)
- (!*MOVE loc loc')
- (!*PROGBIND label loc loc')
- (!*PUSH loc)
- SYSLISP specific Cmacros
- (!*APOLLOCALL label loc loc')
- (!*ASHIFT loc loc')
- (!*FIELD loc loc')
- (!*FOREIGNLINK loc loc')
- (!*INF loc loc')
- (!*JUMPON loc loc')
- (!*JUMPWGEQ loc loc')
- (!*JUMPWGREATERP loc loc')
- (!*JUMPWITHIN loc loc')
- (!*JUMPWLEQ loc loc')
- (!*JUMPWLESSP loc loc')
- (!*LOC loc loc')
- (!*MKITEM loc loc')
- (!*PUTFIELD loc loc')
- (!*PUTINF loc loc')
- (!*PUTTAG loc loc')
- (!*SIGNEDFIELD loc loc')
- (!*TAG loc loc')
- (!*WAND loc loc')
- (!*WDIFFERENCE loc loc')
- (!*WMINUS loc loc')
- (!*WNOT loc loc')
- (!*WOR loc loc')
Compiler and Loader 7 February 1983 PSL Manual
- page 18.18 section 18.6
- (!*WPLUS2 loc loc')
- (!*WSHIFT loc loc')
- (!*WTIMES2 loc loc')
- (!*WXOR loc loc')
- 18.6.2. Classes of Functions
18.6.2. Classes of Functions
18.6.2. Classes of Functions
- The compiler groups functions into four basic classes:
- a. ANYREG functions. No side effects and can be done in a single
- register. Passed directly to CMACROs. Viewed as a form of
- "extended addressing" mode.
- b. Specially compiled or "OPEN" functions. These are functions
- have a special compiling function stored under a 'COMPFN
- indicator. While many of these functions are specially coded,
- many are written with the aid of supporting patterns; these are
- called 'OPENFN or 'OPENTST patterns. Some OPEN functions alter
- registers which are in use, allocate new frames or obtain unused
- registers. These open functions also include open compilation
- of tests.
- c. Built-in or 'stable' functions. These functions are called in
- the standard fashion by the compiler, but they have properties
- which are useful to the compiler and are assumed to always hold.
- Currently, a function may be flagged as NOSIDEEFFECT and have
- the property DESTROYS, which contains a list of registers
- destroyed by the function.
- d. All other functions are assumed to be totally random, destroying
- every register and causing side effects.
- [??? Mark non-random functions of various levels elsewhere ???]
[??? Mark non-random functions of various levels elsewhere ???]
[??? Mark non-random functions of various levels elsewhere ???]
- The most important of these categories is the OPEN function. It is hoped
- that improved OPEN functions will eliminate the need for temporary
- registers to be allocated by the assembler. Most OPEN functions emit
- cmacros especially tailored for each function.
- 18.6.3. Open Functions
18.6.3. Open Functions
18.6.3. Open Functions
- [??? Explain how to CODE them ???]
[??? Explain how to CODE them ???]
[??? Explain how to CODE them ???]
- There are 3 basic kinds of open function:
- a. Test: the destination is a LABEL.
PSL Manual 7 February 1983 Compiler and Loader
- section 18.6 page 18.19
- b. Value: the result is to be placed in a particular register.
- c. Effect: the result is a side effect, and no destination is
- needed.
- Note that an EFFECT open function does not have a destination. It is not
- really a separate class of function, just a separate usage. Example:
- (PROGN (SETQ X 0) ... )
- - the SETQ is for effect only - could be implemented with a "clear"
- instruction.
- (FOO (SETQ X 0) ... )
- - here the 0 is also placed in a register (the destination register).
- The use of OPENTST is also derived from context: in
- (COND ((EQ A B) ...))
- - EQ is interpreted as a test.
- (RETURN (EQ A B))
- , though, must have a value. It should be noted that a pseudo
- source-source transformation occurs if an OPENTST is called for value:
- (RETURN (EQ A B)) ->
- (RETURN (COND ((EQ A B) T) (T NIL)))
- An OPENTST function always returns T/NIL if called for value. No separate
- handling for non test cases is needed (as opposed to the effect/value cases
- for normal OPEN funs in which two separate expansions can be supplied)
- Also, there are 3 basic issues encountered in generating the code:
- a. Bringing arguments into registers as needed.
- b. Emitting the actual code.
- c. Updating the final register contents.
- Initially, the arguments to an open function are removed of all but
- ANYREG functions. Thus, these arguments fall into four classes:
- a. Registers
- b. Memory locations (FLUID, GLOBAL, FRAME, !*MEMORY)
- c. Constants
- d. ANYREG functions (viewed as extended addressing modes)
Compiler and Loader 7 February 1983 PSL Manual
- page 18.20 section 18.6
- Also, along with the arguments coming in is the destination (register or
- label).
- The first step is to replace some arguments by registers by emitting
- LOAD's. This step can be controlled by a function, called the adjust
- function, which emits LOAD's and replaces the corresponding arguments by
- registers. Next, cmacros are emitted. These cmacros are selected through
- a pattern which defines the format of the particular OPEN function call.
- Note that the pattern is matching the locations of the arguments to the
- open function. For example, assume that FOO is OPEN, and the call
- (FOO 'A (CDR B) C D)
- is encountered. Assume also that B is frame 1, C is frame 2, and D was
- found in reg 1.
- The argument list being matched is thus
- ('A (CDR (FRAME 1)) (FRAME 2) (REG 1))
- For most purposes, this would be interpreted as (const anyreg mem reg). Of
- course, a pattern can use the value of a constant (you might recognize
- (!*WPLUS2 1 X) as an increment). Also, the actual register may be
- important for register args, especially if one of the args is also the
- destination. You would probably emit different code for
- (REG 1) := (!*WPLUS2 (REG 2) (REG 3))
- than
- (REG 1) := (!*WPLUS2 (REG 1) (REG 2))
- To avoid a profusion of properties which would be associated with an OPEN
- function, two properties of the function name are used to hold all
- information associated with OPEN compiling. These properties are OPENFN
- and OPENTST.
- The OPENFN and OPENTST properties have the following format:
- (PATTERN MACRONAME PARAMETERS)
- or function name.
- The PATTERN field contains either the pattern itself or a pattern name.
- __
A pattern name is an id having the PATTERN property. In the following
- material, DEST refers to the destination label in an OPENTST and to the
- destination register in an OPENFN. If the function is being evaluated for
- effect only, DEST is a temporary register which need not be used.
- A pattern has the following format:
PSL Manual 7 February 1983 Compiler and Loader
- section 18.6 page 18.21
- (ADJUST_FN
- REG_FN
- (P1 M11 M12 M13 ..)
- (P2 M21 M22 M23 ..)
- ...)
- The Pi are patterns and Mij are cmacros or pseudo cmacros. ADJUST_FN is a
- register adjustment function used to place things in registers as required,
- and to factor out basic properties of the function from the pattern. For
- example, you almost never could do anything with ANYREG stuff except load
- it somewhere (emitting (!*WPLUS2 X (CDR (CAR Y))) directly probably won't
- work - you must bring (CDR (CAR Y)) into a reg before further progress can
- be made). The most common adjust function is NOANYREG, which replaces
- ANYREG stuff with registers. This eliminates the problem of having to test
- for ANYREG stuff in the patterns.
- Some pattern elements currently supported are:
- ANY matches anything
- DEST matches the destination register or label
- NOTDEST matches any register except the destination
- REG matches any register
- REGN Any register or 'NIL or a frame location
- VAR A LOCAL, GLOBAL, or FLUID variable
- MEM A memory address, currently constants + vars (NOT REGS)
- ANYREGFN matches an ANYREG function
- 'literal matches the literal
- (p1 p2 ... pn)
- matches a field whose components match p1 ... pn
- NOVAL matches only if STATUS > 1; must be the first component of a
- pattern, consumes no part of the subject.
- The cmacros associated with the patterns fall into two classes: actual
- cmacros to be emitted and pseudo cmacros which are interpreted by the
- compiler. In either case, the components of the cmacros are handled in the
- same fashion. The cmacros contain:
- Ai replaced by the ith argument to the OPEN function (after
- adjustment)
- Ti replaced by a temporary register
- Li replaced by a temporary label
- Pi replaced by corresponding parameter from OPENFN
- DEST replaced by the destination register or label (depending on
- OPENFN or OPENTST).
- FN replaced by the name of the OPEN function
- MAC synonym for P1, by convention a cmacro name
- 'literal
- (x1 x2 ... )
- xi as above, forms a list
Compiler and Loader 7 February 1983 PSL Manual
- page 18.22 section 18.6
- The pseudo cmacros currently supported are:
- !*DESTROY
!*DESTROY __ __ ____ ______
(!*DESTROY R1, R2, ...): list cmacro
- __ __
Remove any register values from R1 ... RN.
- !*DO
!*DO ________ ____ ____ ____ ______
(!*DO FUNCTION ARG1 ARG2 ...): list cmacro
- ________
Call the FUNCTION.
- !*SET
!*SET ___ ___ ____ ______
(!*SET REG VAL): list cmacro
- ___ ___
Set the value in REG to VAL.
- The cmacros which are known to the compiler are
- !*LOAD
!*LOAD ____ ______
(!*LOAD ): list cmacro
- !*STORE
!*STORE ____ ______
(!*STORE ): list cmacro
- !*JUMP
!*JUMP ____ ______
(!*JUMP ): list cmacro
- !*LBL
!*LBL ____ ______
(!*LBL ): list cmacro
- These cmacros have special emit functions which are called as they are
- emitted; otherwise the cmacro is directly attached to CODELIST.
- 18.7. Third PASS - Optimizations
18.7. Third PASS - Optimizations
18.7. Third PASS - Optimizations
- The third pass of the compiler is responsible for doing optimizations,
- getting rid of extra labels and jumps, removing redundant code, adjusting
- the stack frame to squeeze out "holes" or even reallocating temporaries to
- excess registers if no "random" functions are called by this function.
- This pass also does "peephole" optimizations (controlled by patterns that
- examine the Output CMACRO list for cmacros that can be merged). These
- tables can be adjusted by the user. This pass also gathers information on
- register usage that may be accumulated to aid block compilation or
- recompilation of a set of functions that are NOT redefined, and so can use
- information about each other (i.e. become "stable").
- The 'OPTFN property is used to associate an optimization function with a
- particular CMACRO name. This function looks at the CMACRO arguments and
PSL Manual 7 February 1983 Compiler and Loader
- section 18.7 page 18.23
- some subsequent CMACROs in the code-list, to see if a transformation is
- possible. The OPTFN takes a single argument, the code-list in reverse
- order starting at the associated CMACRO. The OPTFN can also examine
- certain parameters. Currently !*LBL, !*MOVE and !*JUMP have 'OPTFNS. For
- example, !&STOPT, associated with !*MOVE, checks if previous CMACRO was
- !*ALLOC, and that this !*MOVE moves a register to the slot just allocated.
- If so, it converts the !*ALLOC and !*MOVE into a single !*PUSH. Likewise,
- !&LBLOPT removes duplicate labels defined at one place, aliasing one with
- the other, and so permitting certain JUMP optimizations to take place.
- Tags in the cmacros are processed in a final pass through the code. At
- this time the compiler can do substitutions using functions attached to
- these tags. Currently, (!*FRAMESIZE) is converted to the frame size and
- holes are squeezed out (using the FRAME tag) by !&REFORMMACROS.
- Transformation functions are attached to tags (or any function) through the
- TRANFN property currently.
- 18.8. Some Structural Notes on the Compiler
18.8. Some Structural Notes on the Compiler
18.8. Some Structural Notes on the Compiler
- [??? This Section is very ROUGH, just to give some additional
[??? This Section is very ROUGH, just to give some additional
[??? This Section is very ROUGH, just to give some additional
- information in interim ???]
information in interim ???]
information in interim ???]
- External variables and properties used by the compiler:
- _________ ___ ________
Variables and Switches
- __________ ______
!*ERFG [Initially: ] switch
- __________ ______
!*INSTALLDESTROY [Initially: NIL] switch
- If true, causes the compiler to install the DESTROYS property on
- any function compiled which leaves one or more registers
- unchanged
- __________ ______
!*INT [Initially: T] switch
- __________ ______
!*NOFRAMEFLUID [Initially: T] switch
- If true, inhibits allocation of frame locations for FLUIDS
- __________ ______
!*SHOWDEST [Initially: NIL] switch
- If true, compiler prints out which registers a function destroys
- unless all are destroyed
Compiler and Loader 7 February 1983 PSL Manual
- page 18.24 section 18.8
- __________ ______
!*SYSLISP [Initially: NIL] switch
- Switch compilation mode from default of LISP to SYSLISP. This
- affects constant tagging, and in RLISP also causes LISP functions
- to be replaced by SYSLISP equivalents. Also, non-locals default
- to WVAR's rather than FLUIDs. See Chapter 20.
- __________ ______
!*UNSAFEBINDER [Initially: NIL] switch
- for Don's BAKER problem...GC may be called in Binder, so regs
- cannot be preserved, and Binder called as regular function.
- __________ ______
!*USEREGFLUID [Initially: NIL] switch
- If true, LAMBIND and PROGBIND cmacros may contain registers as
- well as frame locations (through FIXFRM).
- _______
Globals:
- __________ ______
LASTACTUALREG [Initially: 5] global
- The number of the last real register; FIXFRM does not map stack
- locations into registers > LASTACTUALREG. Also, temporary
- registers are actual registers if possible.
- __________ ______
MAXNARGS [Initially: 15] global
- Number of registers
- __________ ___ _____
Properties and Flags:
- CONST A tag property, indicates tags for constants (WCONST and QUOTE)
- EXTVAR A tag property, indicates a variable type whose name is
- externally known (!$FLUID, !$GLOBAL, !$WVAR)
- MEMMOD A cmacro property, indicates in place memory operations. The
- first argument to the cmacro is assumed to be the memory location
- (var or !*MEMORY)
- NOSIDEEFFECT
- A function property, used both in dealing with !*ORD and to
- determine if the result should be placed in register status
- REG A tag property, indicates a register (REG)
- TERMINAL A tag property, indicates terminals (leaves) whose arguments are
- not tagged items (!$FLUID !$GLOBAL !$WVAR REG LABEL QUOTE WCONST
- FRAME !*FRAMESIZE IREG)
- TRANSFER A property of cmacros and functions, indicates cmacros &
- functions which cause unconditional transfers (!*JUMP !*EXIT
- !*LINKE !*LINKEF ERROR)
PSL Manual 7 February 1983 Compiler and Loader
- section 18.8 page 18.25
- VAR A tag property, indicates a variable type (!$LOCAL !$FLUID
- !$GLOBAL !$WVAR)
- __________
Properties:
- ANYREG A function property, non-NIL indicates an ANYREG function
- CFNTYPE Used in compiler to relate to Recursion-to-iteration conversion.
- DESTROYS A function property, contains a (tagged) list of registers
- destroyed by the function
- DOFN A function property, contains the name of a compile time
- evaluation function for numeric arguments.
- EMITFN A cmacro or pseudo cmacro property, contains the name of a
- special function for emitting (or executing) the cmacro, such as
- !&ATTJMP for !*JUMP.
- EXITING A cmacro property, used in FIXLINKS. Contains the name of an
- associated exiting cmacro (!*LINK : !*LINKE, !*LINKF : !*LINKEF)
- FLIPTST A function property, contains the name of the opposite of a test
- function. All open compiled test functions must have one. (EQ :
- NOTEQ, ATOM : PAIRP)
- GROUPOPS A function property, used in constant folding. Attached to the
- three functions of a group, always a list of the three functions
- in the order +, -, MINUS. (!*WPLUS2, !*WDIFFERENCE, !*WMINUS :
- (!*WPLUS2 !*WDIFFERENCE !*WMINUS))
- MATCHFN A property attached to an atom in a pattern. Contains the name
- of a boolean function for use in pattern matching.
- NEGJMP A cmacro property, contains the inverted test jump cmacro name.
- (!*JUMPEQ : !*JUMPNOTEQ, !*JUMPNOTEQ : !*JUMPEQ ...)
- ONE A function property, contains the (numeric) value of an identity
- associated with the function (!*WPLUS2 : 0, !*WTIMES2 : 1, ...)
- PATTERN A property associated with atoms appearing in OPENFN or OPENTST
- properties, contains a pattern for open coding of functions.
- SUBSTFN A property of atoms found in cmacros which are inside patterns.
- Contains a function name; the function value is substituted into
- the cmacro as emitted.
- ZERO Like ONE, designates a value which acts as a 0 in a ring over *.
- (!*WTIMES2 : 0 , !*LOGAND : 0)
|