xref: /plan9-contrib/sys/doc/compiler.ms (revision 82f6abee43a55f41b2fe672a88aaa23f21f003ab)
1426d2b71SDavid du Colombier.HTML "Plan 9 C Compilers
2219b2ee8SDavid du Colombier.TL
3219b2ee8SDavid du ColombierPlan 9 C Compilers
4219b2ee8SDavid du Colombier.AU
5219b2ee8SDavid du ColombierKen Thompson
67dd7cddfSDavid du Colombierken@plan9.bell-labs.com
7219b2ee8SDavid du Colombier.AB
8219b2ee8SDavid du Colombier.FS
9219b2ee8SDavid du ColombierOriginally appeared, in a different form, in
10219b2ee8SDavid du Colombier.I
11219b2ee8SDavid du ColombierProceedings of the Summer 1990 UKUUG Conference,
12219b2ee8SDavid du Colombier.R
13219b2ee8SDavid du Colombierpp. 41-51,
14219b2ee8SDavid du ColombierLondon, 1990.
15219b2ee8SDavid du Colombier.FE
16219b2ee8SDavid du ColombierThis paper describes the overall structure and function of the Plan 9 C compilers.
17219b2ee8SDavid du ColombierA more detailed implementation document
18219b2ee8SDavid du Colombierfor any one of the compilers
19219b2ee8SDavid du Colombieris yet to be written.
20219b2ee8SDavid du Colombier.AE
21219b2ee8SDavid du Colombier.NH
22219b2ee8SDavid du ColombierIntroduction
23219b2ee8SDavid du Colombier.LP
247dd7cddfSDavid du ColombierThere are many compilers in the series.
25*82f6abeeSDavid du ColombierFive of the compilers (Intel 386, AMD64, PowerPC, PowerPC 64-bit, ARM)
26219b2ee8SDavid du Colombierare considered active and are used to compile
27219b2ee8SDavid du Colombiercurrent versions of Plan 9.
28*82f6abeeSDavid du ColombierFour of the compilers (MIPS 3000, SPARC, DEC Alpha, and Motorola 68020)
29*82f6abeeSDavid du Colombierare maintained but are for older machines
30*82f6abeeSDavid du Colombierfor which we have no current ports of Plan 9;
31*82f6abeeSDavid du Colombierother than the MIPS, we are unlikely to port to any such machines.
32*82f6abeeSDavid du ColombierSeveral others (Motorola 68000, Intel 960, AMD 29000) have had only limited use, such as
337dd7cddfSDavid du Colombierto program peripherals or experimental devices.
34219b2ee8SDavid du Colombier.NH
35219b2ee8SDavid du ColombierStructure
36219b2ee8SDavid du Colombier.LP
37219b2ee8SDavid du ColombierThe compiler is a single program that produces an
38219b2ee8SDavid du Colombierobject file.
39219b2ee8SDavid du ColombierCombined in the compiler are the traditional
40219b2ee8SDavid du Colombierroles of preprocessor, lexical analyzer, parser, code generator,
41219b2ee8SDavid du Colombierlocal optimizer,
42219b2ee8SDavid du Colombierand first half of the assembler.
43219b2ee8SDavid du ColombierThe object files are binary forms of assembly
44219b2ee8SDavid du Colombierlanguage,
45219b2ee8SDavid du Colombiersimilar to what might be passed between
46219b2ee8SDavid du Colombierthe first and second passes of an assembler.
47219b2ee8SDavid du Colombier.LP
48219b2ee8SDavid du ColombierObject files and libraries
49219b2ee8SDavid du Colombierare combined by a loader
50219b2ee8SDavid du Colombierprogram to produce the executable binary.
51219b2ee8SDavid du ColombierThe loader combines the roles of second half
52219b2ee8SDavid du Colombierof the assembler, global optimizer, and loader.
53219b2ee8SDavid du ColombierThe names of the compliers, loaders, and assemblers
54219b2ee8SDavid du Colombierare as follows:
55219b2ee8SDavid du Colombier.DS
56219b2ee8SDavid du Colombier.ta 1.5i
57219b2ee8SDavid du Colombier.de Ta
58219b2ee8SDavid du Colombier\\$1	\f(CW\\$2\fP  \f(CW\\$3\fP  \f(CW\\$4\fP
59219b2ee8SDavid du Colombier..
60219b2ee8SDavid du Colombier.Ta SPARC kc kl ka
61*82f6abeeSDavid du Colombier.Ta PowerPC qc ql qa
627dd7cddfSDavid du Colombier.Ta MIPS vc vl va
63*82f6abeeSDavid du Colombier.Ta MIPS\ little-endian 0c 0l 0a
647dd7cddfSDavid du Colombier.Ta Motorola\ 68000 1c 1l 1a
65219b2ee8SDavid du Colombier.Ta Motorola\ 68020 2c 2l 2a
66*82f6abeeSDavid du Colombier.Ta ARM 5c 5l 5a
67*82f6abeeSDavid du Colombier.Ta AMD64 6c 6l 6a
687dd7cddfSDavid du Colombier.Ta DEC\ Alpha 7c 7l 7a
697dd7cddfSDavid du Colombier.Ta Intel\ 386 8c 8l 8a
70*82f6abeeSDavid du Colombier.Ta PowerPC\ 64-bit 9c 9l 9a
71219b2ee8SDavid du Colombier.DE
72219b2ee8SDavid du ColombierThere is a further breakdown
73219b2ee8SDavid du Colombierin the source of the compilers into
74219b2ee8SDavid du Colombierobject-independent and
75219b2ee8SDavid du Colombierobject-dependent
76219b2ee8SDavid du Colombierparts.
77219b2ee8SDavid du ColombierAll of the object-independent parts
78219b2ee8SDavid du Colombierare combined into source files in the
79219b2ee8SDavid du Colombierdirectory
80219b2ee8SDavid du Colombier.CW /sys/src/cmd/cc .
81219b2ee8SDavid du ColombierThe object-dependent parts are collected
82219b2ee8SDavid du Colombierin a separate directory for each compiler,
83219b2ee8SDavid du Colombierfor example
84219b2ee8SDavid du Colombier.CW /sys/src/cmd/vc .
85219b2ee8SDavid du ColombierAll of the code,
86219b2ee8SDavid du Colombierboth object-independent and
87219b2ee8SDavid du Colombierobject-dependent,
88219b2ee8SDavid du Colombieris machine-independent
89219b2ee8SDavid du Colombierand may be cross-compiled and executed on any
90219b2ee8SDavid du Colombierof the architectures.
91219b2ee8SDavid du Colombier.NH
92219b2ee8SDavid du ColombierThe Language
93219b2ee8SDavid du Colombier.LP
94219b2ee8SDavid du ColombierThe compiler implements ANSI C with some
95219b2ee8SDavid du Colombierrestrictions and extensions
96219b2ee8SDavid du Colombier[ANSI90].
97219b2ee8SDavid du ColombierMost of the restrictions are due to
98219b2ee8SDavid du Colombierpersonal preference, while
99219b2ee8SDavid du Colombiermost of the extensions were to help in
100219b2ee8SDavid du Colombierthe implementation of Plan 9.
101219b2ee8SDavid du ColombierThere are other departures from the standard,
102219b2ee8SDavid du Colombierparticularly in the libraries,
103219b2ee8SDavid du Colombierthat are beyond the scope of this
104219b2ee8SDavid du Colombierpaper.
105219b2ee8SDavid du Colombier.NH 2
106219b2ee8SDavid du ColombierRegister, volatile, const
107219b2ee8SDavid du Colombier.LP
1087dd7cddfSDavid du ColombierThe keyword
1097dd7cddfSDavid du Colombier.CW register
1107dd7cddfSDavid du Colombieris recognized syntactically
1117dd7cddfSDavid du Colombierbut is semantically ignored.
1127dd7cddfSDavid du ColombierThus taking the address of a
1137dd7cddfSDavid du Colombier.CW register
1147dd7cddfSDavid du Colombiervariable is not diagnosed.
1157dd7cddfSDavid du ColombierThe keyword
1167dd7cddfSDavid du Colombier.CW volatile
1177dd7cddfSDavid du Colombierdisables all optimizations, in particular registerization, of the corresponding variable.
1187dd7cddfSDavid du ColombierThe keyword
119219b2ee8SDavid du Colombier.CW const
1207dd7cddfSDavid du Colombiergenerates warnings (if warnings are enabled by the compiler's
1217dd7cddfSDavid du Colombier.CW -w
1227dd7cddfSDavid du Colombieroption) of non-constant use of the variable,
1237dd7cddfSDavid du Colombierbut does not affect the generated code.
124219b2ee8SDavid du Colombier.NH 2
125219b2ee8SDavid du ColombierThe preprocessor
126219b2ee8SDavid du Colombier.LP
127219b2ee8SDavid du ColombierThe C preprocessor is probably the
128219b2ee8SDavid du Colombierbiggest departure from the ANSI standard.
129219b2ee8SDavid du Colombier.LP
130219b2ee8SDavid du ColombierThe preprocessor built into the Plan 9 compilers does not support
131219b2ee8SDavid du Colombier.CW #if ,
132219b2ee8SDavid du Colombieralthough it does handle
133219b2ee8SDavid du Colombier.CW #ifdef
134219b2ee8SDavid du Colombierand
135219b2ee8SDavid du Colombier.CW #include .
136219b2ee8SDavid du ColombierIf it is necessary to be more standard,
137219b2ee8SDavid du Colombierthe source text can first be run through the separate ANSI C
138219b2ee8SDavid du Colombierpreprocessor,
139219b2ee8SDavid du Colombier.CW cpp .
140219b2ee8SDavid du Colombier.NH 2
141219b2ee8SDavid du ColombierUnnamed substructures
142219b2ee8SDavid du Colombier.LP
143219b2ee8SDavid du ColombierThe most important and most heavily used of the
144219b2ee8SDavid du Colombierextensions is the declaration of an
145219b2ee8SDavid du Colombierunnamed substructure or subunion.
146219b2ee8SDavid du ColombierFor example:
147219b2ee8SDavid du Colombier.DS
148219b2ee8SDavid du Colombier.CW
149219b2ee8SDavid du Colombier.ta .1i .6i 1.1i 1.6i
150219b2ee8SDavid du Colombier	typedef
151219b2ee8SDavid du Colombier	struct	lock
152219b2ee8SDavid du Colombier	{
153219b2ee8SDavid du Colombier		int    locked;
154219b2ee8SDavid du Colombier	} Lock;
155219b2ee8SDavid du Colombier
156219b2ee8SDavid du Colombier	typedef
157219b2ee8SDavid du Colombier	struct	node
158219b2ee8SDavid du Colombier	{
159219b2ee8SDavid du Colombier		int	type;
160219b2ee8SDavid du Colombier		union
161219b2ee8SDavid du Colombier		{
162219b2ee8SDavid du Colombier			double dval;
163219b2ee8SDavid du Colombier			float  fval;
164219b2ee8SDavid du Colombier			long   lval;
165219b2ee8SDavid du Colombier		};
166219b2ee8SDavid du Colombier		Lock;
167219b2ee8SDavid du Colombier	} Node;
168219b2ee8SDavid du Colombier
169219b2ee8SDavid du Colombier	Lock*	lock;
170219b2ee8SDavid du Colombier	Node*	node;
171219b2ee8SDavid du Colombier.DE
172219b2ee8SDavid du ColombierThe declaration of
173219b2ee8SDavid du Colombier.CW Node
174219b2ee8SDavid du Colombierhas an unnamed substructure of type
175219b2ee8SDavid du Colombier.CW Lock
176219b2ee8SDavid du Colombierand an unnamed subunion.
177219b2ee8SDavid du ColombierOne use of this feature allows references to elements of the
178219b2ee8SDavid du Colombiersubunit to be accessed as if they were in
179219b2ee8SDavid du Colombierthe outer structure.
180219b2ee8SDavid du ColombierThus
181219b2ee8SDavid du Colombier.CW node->dval
182219b2ee8SDavid du Colombierand
183219b2ee8SDavid du Colombier.CW node->locked
184219b2ee8SDavid du Colombierare legitimate references.
185219b2ee8SDavid du Colombier.LP
186219b2ee8SDavid du ColombierWhen an outer structure is used
187219b2ee8SDavid du Colombierin a context that is only legal for
188219b2ee8SDavid du Colombieran unnamed substructure,
189219b2ee8SDavid du Colombierthe compiler promotes the reference to the
190219b2ee8SDavid du Colombierunnamed substructure.
191219b2ee8SDavid du ColombierThis is true for references to structures and
192219b2ee8SDavid du Colombierto references to pointers to structures.
193219b2ee8SDavid du ColombierThis happens in assignment statements and
194219b2ee8SDavid du Colombierin argument passing where prototypes have been
195219b2ee8SDavid du Colombierdeclared.
196219b2ee8SDavid du ColombierThus, continuing with the example,
197219b2ee8SDavid du Colombier.DS
198219b2ee8SDavid du Colombier.CW
199219b2ee8SDavid du Colombier.ta .1i .6i 1.1i 1.6i
200219b2ee8SDavid du Colombier	lock = node;
201219b2ee8SDavid du Colombier.DE
202219b2ee8SDavid du Colombierwould assign a pointer to the unnamed
203219b2ee8SDavid du Colombier.CW Lock
204219b2ee8SDavid du Colombierin
205219b2ee8SDavid du Colombierthe
206219b2ee8SDavid du Colombier.CW Node
207219b2ee8SDavid du Colombierto the variable
208219b2ee8SDavid du Colombier.CW lock .
209219b2ee8SDavid du ColombierAnother example,
210219b2ee8SDavid du Colombier.DS
211219b2ee8SDavid du Colombier.CW
212219b2ee8SDavid du Colombier.ta .1i .6i 1.1i 1.6i
213219b2ee8SDavid du Colombier	extern void lock(Lock*);
214219b2ee8SDavid du Colombier	func(...)
215219b2ee8SDavid du Colombier	{
216219b2ee8SDavid du Colombier		...
217219b2ee8SDavid du Colombier		lock(node);
218219b2ee8SDavid du Colombier		...
219219b2ee8SDavid du Colombier	}
220219b2ee8SDavid du Colombier.DE
221219b2ee8SDavid du Colombierwill pass a pointer to the
222219b2ee8SDavid du Colombier.CW Lock
223219b2ee8SDavid du Colombiersubstructure.
2247dd7cddfSDavid du Colombier.LP
2257dd7cddfSDavid du ColombierFinally, in places where context is insufficient to identify the unnamed structure,
2267dd7cddfSDavid du Colombierthe type name (it must be a
2277dd7cddfSDavid du Colombier.CW typedef )
2287dd7cddfSDavid du Colombierof the unnamed structure can be used as an identifier.
2297dd7cddfSDavid du ColombierIn our example,
2307dd7cddfSDavid du Colombier.CW &node->Lock
2317dd7cddfSDavid du Colombiergives the address of the anonymous
2327dd7cddfSDavid du Colombier.CW Lock
2337dd7cddfSDavid du Colombierstructure.
234219b2ee8SDavid du Colombier.NH 2
235219b2ee8SDavid du ColombierStructure displays
236219b2ee8SDavid du Colombier.LP
237219b2ee8SDavid du ColombierA structure cast followed by a list of expressions in braces is
238219b2ee8SDavid du Colombieran expression with the type of the structure and elements assigned from
239219b2ee8SDavid du Colombierthe corresponding list.
240219b2ee8SDavid du ColombierStructures are now almost first-class citizens of the language.
241219b2ee8SDavid du ColombierIt is common to see code like this:
242219b2ee8SDavid du Colombier.DS
243219b2ee8SDavid du Colombier.CW
244219b2ee8SDavid du Colombier.ta .1i
245219b2ee8SDavid du Colombier	r = (Rectangle){point1, (Point){x,y+2}};
246219b2ee8SDavid du Colombier.DE
247219b2ee8SDavid du Colombier.NH 2
248219b2ee8SDavid du ColombierInitialization indexes
249219b2ee8SDavid du Colombier.LP
250219b2ee8SDavid du ColombierIn initializers of arrays,
251219b2ee8SDavid du Colombierone may place a constant expression
252219b2ee8SDavid du Colombierin square brackets before an initializer.
253219b2ee8SDavid du ColombierThis causes the next initializer to assign
254219b2ee8SDavid du Colombierthe indicated element.
255219b2ee8SDavid du ColombierFor example:
256219b2ee8SDavid du Colombier.DS
257219b2ee8SDavid du Colombier.CW
258219b2ee8SDavid du Colombier.ta .1i .6i 1.6i
259219b2ee8SDavid du Colombier	enum	errors
260219b2ee8SDavid du Colombier	{
261219b2ee8SDavid du Colombier		Etoobig,
262219b2ee8SDavid du Colombier		Ealarm,
263219b2ee8SDavid du Colombier		Egreg
264219b2ee8SDavid du Colombier	};
265219b2ee8SDavid du Colombier	char* errstrings[] =
266219b2ee8SDavid du Colombier	{
267219b2ee8SDavid du Colombier		[Ealarm]	"Alarm call",
268219b2ee8SDavid du Colombier		[Egreg]	"Panic: out of mbufs",
269219b2ee8SDavid du Colombier		[Etoobig]	"Arg list too long",
270219b2ee8SDavid du Colombier	};
271219b2ee8SDavid du Colombier.DE
272219b2ee8SDavid du ColombierIn the same way,
273219b2ee8SDavid du Colombierindividual structures members may
274219b2ee8SDavid du Colombierbe initialized in any order by preceding the initialization with
275219b2ee8SDavid du Colombier.CW .tagname .
276219b2ee8SDavid du ColombierBoth forms allow an optional
277219b2ee8SDavid du Colombier.CW = ,
278219b2ee8SDavid du Colombierto be compatible with a proposed
279219b2ee8SDavid du Colombierextension to ANSI C.
280219b2ee8SDavid du Colombier.NH 2
281219b2ee8SDavid du ColombierExternal register
282219b2ee8SDavid du Colombier.LP
283219b2ee8SDavid du ColombierThe declaration
284219b2ee8SDavid du Colombier.CW extern
285219b2ee8SDavid du Colombier.CW register
286219b2ee8SDavid du Colombierwill dedicate a register to
287219b2ee8SDavid du Colombiera variable on a global basis.
288219b2ee8SDavid du ColombierIt can be used only under special circumstances.
289219b2ee8SDavid du ColombierExternal register variables must be identically
290219b2ee8SDavid du Colombierdeclared in all modules and
291219b2ee8SDavid du Colombierlibraries.
292219b2ee8SDavid du ColombierThe feature is not intended for efficiency,
293219b2ee8SDavid du Colombieralthough it can produce efficient code;
294219b2ee8SDavid du Colombierrather it represents a unique storage class that
295219b2ee8SDavid du Colombierwould be hard to get any other way.
296219b2ee8SDavid du ColombierOn a shared-memory multi-processor,
297219b2ee8SDavid du Colombieran external register is
298219b2ee8SDavid du Colombierone-per-processor and neither one-per-procedure (automatic)
299219b2ee8SDavid du Colombieror one-per-system (external).
300219b2ee8SDavid du ColombierIt is used for two variables in the Plan 9 kernel,
301219b2ee8SDavid du Colombier.CW u
302219b2ee8SDavid du Colombierand
303219b2ee8SDavid du Colombier.CW m .
304219b2ee8SDavid du Colombier.CW U
305219b2ee8SDavid du Colombieris a pointer to the structure representing the currently running process
306219b2ee8SDavid du Colombierand
307219b2ee8SDavid du Colombier.CW m
308219b2ee8SDavid du Colombieris a pointer to the per-machine data structure.
309219b2ee8SDavid du Colombier.NH 2
310219b2ee8SDavid du ColombierLong long
311219b2ee8SDavid du Colombier.LP
312219b2ee8SDavid du ColombierThe compilers accept
313219b2ee8SDavid du Colombier.CW long
314219b2ee8SDavid du Colombier.CW long
315219b2ee8SDavid du Colombieras a basic type meaning 64-bit integer.
316219b2ee8SDavid du ColombierOn all of the machines
317219b2ee8SDavid du Colombierthis type is synthesized from 32-bit instructions.
318219b2ee8SDavid du Colombier.NH 2
319219b2ee8SDavid du ColombierPragma
320219b2ee8SDavid du Colombier.LP
321219b2ee8SDavid du ColombierThe compilers accept
322219b2ee8SDavid du Colombier.CW #pragma
323219b2ee8SDavid du Colombier.CW lib
324219b2ee8SDavid du Colombier.I libname
325219b2ee8SDavid du Colombierand pass the
326219b2ee8SDavid du Colombierlibrary name string uninterpreted
327219b2ee8SDavid du Colombierto the loader.
328219b2ee8SDavid du ColombierThe loader uses the library name to
329219b2ee8SDavid du Colombierfind libraries to load.
330219b2ee8SDavid du ColombierIf the name contains
331*82f6abeeSDavid du Colombier.CW $O ,
332219b2ee8SDavid du Colombierit is replaced with
333219b2ee8SDavid du Colombierthe single character object type of the compiler
334219b2ee8SDavid du Colombier(e.g.,
335219b2ee8SDavid du Colombier.CW v
336219b2ee8SDavid du Colombierfor the MIPS).
337219b2ee8SDavid du ColombierIf the name contains
338*82f6abeeSDavid du Colombier.CW $M ,
339219b2ee8SDavid du Colombierit is replaced with
340219b2ee8SDavid du Colombierthe architecture type for the compiler
341219b2ee8SDavid du Colombier(e.g.,
342219b2ee8SDavid du Colombier.CW mips
343219b2ee8SDavid du Colombierfor the MIPS).
344219b2ee8SDavid du ColombierIf the name starts with
345219b2ee8SDavid du Colombier.CW /
346219b2ee8SDavid du Colombierit is an absolute pathname;
347219b2ee8SDavid du Colombierif it starts with
348219b2ee8SDavid du Colombier.CW .
349219b2ee8SDavid du Colombierthen it is searched for in the loader's current directory.
350219b2ee8SDavid du ColombierOtherwise, the name is searched from
351*82f6abeeSDavid du Colombier.CW /$M/lib .
352219b2ee8SDavid du ColombierSuch
353219b2ee8SDavid du Colombier.CW #pragma
354219b2ee8SDavid du Colombierstatements in header files guarantee that the correct
355219b2ee8SDavid du Colombierlibraries are always linked with a program without the
356219b2ee8SDavid du Colombierneed to specify them explicitly at link time.
3577dd7cddfSDavid du Colombier.LP
3587dd7cddfSDavid du ColombierThey also accept
3597dd7cddfSDavid du Colombier.CW #pragma
360*82f6abeeSDavid du Colombier.CW packed
3617dd7cddfSDavid du Colombier.CW on
3627dd7cddfSDavid du Colombier(or
3637dd7cddfSDavid du Colombier.CW yes
3647dd7cddfSDavid du Colombieror
3657dd7cddfSDavid du Colombier.CW 1 )
3667dd7cddfSDavid du Colombierto cause subsequently declared data, until
3677dd7cddfSDavid du Colombier.CW #pragma
368*82f6abeeSDavid du Colombier.CW packed
3697dd7cddfSDavid du Colombier.CW off
3707dd7cddfSDavid du Colombier(or
3717dd7cddfSDavid du Colombier.CW no
3727dd7cddfSDavid du Colombieror
3737dd7cddfSDavid du Colombier.CW 0 ),
3747dd7cddfSDavid du Colombierto be laid out in memory tightly packed in successive bytes, disregarding
3757dd7cddfSDavid du Colombierthe usual alignment rules.
3767dd7cddfSDavid du ColombierAccessing such data can cause faults.
3777dd7cddfSDavid du Colombier.LP
378e288d156SDavid du ColombierSimilarly,
379e288d156SDavid du Colombier.CW #pragma
380e288d156SDavid du Colombier.CW profile
381e288d156SDavid du Colombier.CW off
382e288d156SDavid du Colombier(or
383e288d156SDavid du Colombier.CW no
384e288d156SDavid du Colombieror
385e288d156SDavid du Colombier.CW 0 )
386e288d156SDavid du Colombiercauses subsequently declared functions, until
387e288d156SDavid du Colombier.CW #pragma
388e288d156SDavid du Colombier.CW profile
389e288d156SDavid du Colombier.CW on
390e288d156SDavid du Colombier(or
391e288d156SDavid du Colombier.CW yes
392e288d156SDavid du Colombieror
393e288d156SDavid du Colombier.CW 1 ),
394e288d156SDavid du Colombierto be marked as unprofiled.
395e288d156SDavid du ColombierSuch functions will not be profiled when
396e288d156SDavid du Colombierprofiling is enabled for the rest of the program.
397e288d156SDavid du Colombier.LP
3987dd7cddfSDavid du ColombierTwo
3997dd7cddfSDavid du Colombier.CW #pragma
4007dd7cddfSDavid du Colombierstatements allow type-checking of
4017dd7cddfSDavid du Colombier.CW print -like
4027dd7cddfSDavid du Colombierfunctions.
4037dd7cddfSDavid du ColombierThe first, of the form
4047dd7cddfSDavid du Colombier.P1
4057dd7cddfSDavid du Colombier#pragma varargck argpos error 2
4067dd7cddfSDavid du Colombier.P2
4077dd7cddfSDavid du Colombiertells the compiler that the second argument to
4087dd7cddfSDavid du Colombier.CW error
4097dd7cddfSDavid du Colombieris a
4107dd7cddfSDavid du Colombier.CW print
4117dd7cddfSDavid du Colombierformat string (see the manual page
4127dd7cddfSDavid du Colombier.I print (2))
4137dd7cddfSDavid du Colombierthat specifies how to format
4147dd7cddfSDavid du Colombier.CW error 's
4157dd7cddfSDavid du Colombiersubsequent arguments.
4167dd7cddfSDavid du ColombierThe second, of the form
4177dd7cddfSDavid du Colombier.P1
4187dd7cddfSDavid du Colombier#pragma varargck type "s" char*
4197dd7cddfSDavid du Colombier.P2
4207dd7cddfSDavid du Colombiersays that the
4217dd7cddfSDavid du Colombier.CW print
4227dd7cddfSDavid du Colombierformat verb
4237dd7cddfSDavid du Colombier.CW s
4247dd7cddfSDavid du Colombierprocesses an argument of
4257dd7cddfSDavid du Colombiertype
4267dd7cddfSDavid du Colombier.CW char* .
4277dd7cddfSDavid du ColombierIf the compiler's
4287dd7cddfSDavid du Colombier.CW -F
4297dd7cddfSDavid du Colombieroption is enabled, the compiler will use this information
4307dd7cddfSDavid du Colombierto report type violations in the arguments to
4317dd7cddfSDavid du Colombier.CW print ,
4327dd7cddfSDavid du Colombier.CW error ,
4337dd7cddfSDavid du Colombierand similar routines.
434219b2ee8SDavid du Colombier.NH
435219b2ee8SDavid du ColombierObject module conventions
436219b2ee8SDavid du Colombier.LP
437219b2ee8SDavid du ColombierThe overall conventions of the runtime environment
438219b2ee8SDavid du Colombierare important
439219b2ee8SDavid du Colombierto runtime efficiency.
440219b2ee8SDavid du ColombierIn this section,
441219b2ee8SDavid du Colombierseveral of these conventions are discussed.
442219b2ee8SDavid du Colombier.NH 2
443219b2ee8SDavid du ColombierRegister saving
444219b2ee8SDavid du Colombier.LP
445219b2ee8SDavid du ColombierIn the Plan 9 compilers,
446219b2ee8SDavid du Colombierthe caller of a procedure saves the registers.
447219b2ee8SDavid du ColombierWith caller-saves,
448219b2ee8SDavid du Colombierthe leaf procedures can use all the
449219b2ee8SDavid du Colombierregisters and never save them.
450219b2ee8SDavid du ColombierIf you spend a lot of time at the leaves,
451219b2ee8SDavid du Colombierthis seems preferable.
452219b2ee8SDavid du ColombierWith callee-saves,
453219b2ee8SDavid du Colombierthe saving of the registers is done
454219b2ee8SDavid du Colombierin the single point of entry and return.
455219b2ee8SDavid du ColombierIf you are interested in space,
456219b2ee8SDavid du Colombierthis seems preferable.
457219b2ee8SDavid du ColombierIn both,
458219b2ee8SDavid du Colombierthere is a degree of uncertainty
459219b2ee8SDavid du Colombierabout what registers need to be saved.
460219b2ee8SDavid du ColombierCallee-saved registers make it difficult to
461219b2ee8SDavid du Colombierfind variables in registers in debuggers.
462219b2ee8SDavid du ColombierCallee-saved registers also complicate
463219b2ee8SDavid du Colombierthe implementation of
464219b2ee8SDavid du Colombier.CW longjmp .
465219b2ee8SDavid du ColombierThe convincing argument is
466219b2ee8SDavid du Colombierthat with caller-saves,
467219b2ee8SDavid du Colombierthe decision to registerize a variable
468219b2ee8SDavid du Colombiercan include the cost of saving the register
469219b2ee8SDavid du Colombieracross calls.
470219b2ee8SDavid du ColombierFor a further discussion of caller- vs. callee-saves,
471219b2ee8SDavid du Colombiersee the paper by Davidson and Whalley [Dav91].
472219b2ee8SDavid du Colombier.LP
473219b2ee8SDavid du ColombierIn the Plan 9 operating system,
474219b2ee8SDavid du Colombiercalls to the kernel look like normal procedure
475219b2ee8SDavid du Colombiercalls, which means
476219b2ee8SDavid du Colombierthe caller
477219b2ee8SDavid du Colombierhas saved the registers and the system
478219b2ee8SDavid du Colombierentry does not have to.
479219b2ee8SDavid du ColombierThis makes system calls considerably faster.
480219b2ee8SDavid du ColombierSince this is a potential security hole,
481219b2ee8SDavid du Colombierand can lead to non-determinism,
482219b2ee8SDavid du Colombierthe system may eventually save the registers
483219b2ee8SDavid du Colombieron entry,
484219b2ee8SDavid du Colombieror more likely clear the registers on return.
485219b2ee8SDavid du Colombier.NH 2
486219b2ee8SDavid du ColombierCalling convention
487219b2ee8SDavid du Colombier.LP
488219b2ee8SDavid du ColombierOlder C compilers maintain a frame pointer, which is at a known constant
489219b2ee8SDavid du Colombieroffset from the stack pointer within each function.
490219b2ee8SDavid du ColombierFor machines where the stack grows towards zero,
491219b2ee8SDavid du Colombierthe argument pointer is at a known constant offset
492219b2ee8SDavid du Colombierfrom the frame pointer.
493219b2ee8SDavid du ColombierSince the stack grows down in Plan 9,
494219b2ee8SDavid du Colombierthe Plan 9 compilers
495219b2ee8SDavid du Colombierkeep neither an
496219b2ee8SDavid du Colombierexplicit frame pointer nor
497219b2ee8SDavid du Colombieran explicit argument pointer;
498219b2ee8SDavid du Colombierinstead they generate addresses relative to the stack pointer.
499219b2ee8SDavid du Colombier.LP
500219b2ee8SDavid du ColombierOn some architectures, the first argument to a subroutine is passed in a register.
501219b2ee8SDavid du Colombier.NH 2
502219b2ee8SDavid du ColombierFunctions returning structures
503219b2ee8SDavid du Colombier.LP
504219b2ee8SDavid du ColombierStructures longer than one word are awkward to implement
505219b2ee8SDavid du Colombiersince they do not fit in registers and must
506219b2ee8SDavid du Colombierbe passed around in memory.
507219b2ee8SDavid du ColombierFunctions that return structures
508219b2ee8SDavid du Colombierare particularly clumsy.
509219b2ee8SDavid du ColombierThe Plan 9 compilers pass the return address of
510219b2ee8SDavid du Colombiera structure as the first argument of a
511219b2ee8SDavid du Colombierfunction that has a structure return value.
512219b2ee8SDavid du ColombierThus
513219b2ee8SDavid du Colombier.DS
514219b2ee8SDavid du Colombier.CW
515219b2ee8SDavid du Colombier.ta .1i .6i 1.1i 1.6i
516219b2ee8SDavid du Colombier	x = f(...)
517219b2ee8SDavid du Colombier.DE
518219b2ee8SDavid du Colombieris rewritten as
519219b2ee8SDavid du Colombier.DS
520219b2ee8SDavid du Colombier.CW
521219b2ee8SDavid du Colombier.ta .1i .6i 1.1i 1.6i
522219b2ee8SDavid du Colombier	f(&x, ...)\f1.
523219b2ee8SDavid du Colombier.DE
524219b2ee8SDavid du ColombierThis saves a copy and makes the compilation
525219b2ee8SDavid du Colombiermuch less clumsy.
526219b2ee8SDavid du ColombierA disadvantage is that if you call this
527219b2ee8SDavid du Colombierfunction without an assignment,
528219b2ee8SDavid du Colombiera dummy location must be invented.
529219b2ee8SDavid du Colombier.LP
530219b2ee8SDavid du ColombierThere is also a danger of calling a function
531219b2ee8SDavid du Colombierthat returns a structure without declaring
532219b2ee8SDavid du Colombierit as such.
533219b2ee8SDavid du ColombierWith ANSI C function prototypes,
534219b2ee8SDavid du Colombierthis error need never occur.
535219b2ee8SDavid du Colombier.NH
536219b2ee8SDavid du ColombierImplementation
537219b2ee8SDavid du Colombier.LP
538219b2ee8SDavid du ColombierThe compiler is divided internally into
539219b2ee8SDavid du Colombierfour machine-independent passes,
540219b2ee8SDavid du Colombierfour machine-dependent passes,
541219b2ee8SDavid du Colombierand an output pass.
542219b2ee8SDavid du ColombierThe next nine sections describe each pass in order.
543219b2ee8SDavid du Colombier.NH 2
544219b2ee8SDavid du ColombierParsing
545219b2ee8SDavid du Colombier.LP
546219b2ee8SDavid du ColombierThe first pass is a YACC-based parser
547219b2ee8SDavid du Colombier[Joh79].
548219b2ee8SDavid du ColombierDeclarations are interpreted immediately,
549219b2ee8SDavid du Colombierbuilding a block structured symbol table.
550219b2ee8SDavid du ColombierExecutable statements are put into a parse tree
551219b2ee8SDavid du Colombierand collected,
552219b2ee8SDavid du Colombierwithout interpretation.
553219b2ee8SDavid du ColombierAt the end of each procedure,
554219b2ee8SDavid du Colombierthe parse tree for the function is
555219b2ee8SDavid du Colombierexamined by the other passes of the compiler.
556219b2ee8SDavid du Colombier.LP
557219b2ee8SDavid du ColombierThe input stream of the parser is
558219b2ee8SDavid du Colombiera pushdown list of input activations.
559219b2ee8SDavid du ColombierThe preprocessor
560219b2ee8SDavid du Colombierexpansions of
561219b2ee8SDavid du Colombiermacros
562219b2ee8SDavid du Colombierand
563219b2ee8SDavid du Colombier.CW #include
564219b2ee8SDavid du Colombierare implemented as pushdowns.
565219b2ee8SDavid du ColombierThus there is no separate
566219b2ee8SDavid du Colombierpass for preprocessing.
567219b2ee8SDavid du Colombier.NH 2
568219b2ee8SDavid du ColombierTyping
569219b2ee8SDavid du Colombier.LP
570219b2ee8SDavid du ColombierThe next pass distributes typing information
571219b2ee8SDavid du Colombierto every node of the tree.
572219b2ee8SDavid du ColombierImplicit operations on the tree are added,
573219b2ee8SDavid du Colombiersuch as type promotions and taking the
574219b2ee8SDavid du Colombieraddress of arrays and functions.
575219b2ee8SDavid du Colombier.NH 2
576219b2ee8SDavid du ColombierMachine-independent optimization
577219b2ee8SDavid du Colombier.LP
578219b2ee8SDavid du ColombierThe next pass performs optimizations
579219b2ee8SDavid du Colombierand transformations of the tree, such as converting
580219b2ee8SDavid du Colombier.CW &*x
581219b2ee8SDavid du Colombierand
582219b2ee8SDavid du Colombier.CW *&x
583219b2ee8SDavid du Colombierinto
584219b2ee8SDavid du Colombier.CW x .
585219b2ee8SDavid du ColombierConstant expressions are converted to constants in this pass.
586219b2ee8SDavid du Colombier.NH 2
587219b2ee8SDavid du ColombierArithmetic rewrites
588219b2ee8SDavid du Colombier.LP
589219b2ee8SDavid du ColombierThis is another machine-independent optimization.
590219b2ee8SDavid du ColombierSubtrees of add, subtract, and multiply of integers are
591219b2ee8SDavid du Colombierrewritten for easier compilation.
592219b2ee8SDavid du ColombierThe major transformation is factoring:
593219b2ee8SDavid du Colombier.CW 4+8*a+16*b+5
594219b2ee8SDavid du Colombieris transformed into
595219b2ee8SDavid du Colombier.CW 9+8*(a+2*b) .
596219b2ee8SDavid du ColombierSuch expressions arise from address
597219b2ee8SDavid du Colombiermanipulation and array indexing.
598219b2ee8SDavid du Colombier.NH 2
599219b2ee8SDavid du ColombierAddressability
600219b2ee8SDavid du Colombier.LP
601219b2ee8SDavid du ColombierThis is the first of the machine-dependent passes.
602219b2ee8SDavid du ColombierThe addressability of a processor is defined as the set of
603219b2ee8SDavid du Colombierexpressions that is legal in the address field
604219b2ee8SDavid du Colombierof a machine language instruction.
605219b2ee8SDavid du ColombierThe addressability of different processors varies widely.
606219b2ee8SDavid du ColombierAt one end of the spectrum are the 68020 and VAX,
607219b2ee8SDavid du Colombierwhich allow a complex mix of incrementing,
608219b2ee8SDavid du Colombierdecrementing,
609219b2ee8SDavid du Colombierindexing, and relative addressing.
610219b2ee8SDavid du ColombierAt the other end is the MIPS,
611219b2ee8SDavid du Colombierwhich allows only registers and constant offsets from the
612219b2ee8SDavid du Colombiercontents of a register.
613219b2ee8SDavid du ColombierThe addressability can be different for different instructions
614219b2ee8SDavid du Colombierwithin the same processor.
615219b2ee8SDavid du Colombier.LP
616219b2ee8SDavid du ColombierIt is important to the code generator to know when a
617219b2ee8SDavid du Colombiersubtree represents an address of a particular type.
618219b2ee8SDavid du ColombierThis is done with a bottom-up walk of the tree.
619219b2ee8SDavid du ColombierIn this pass, the leaves are labeled with small integers.
620219b2ee8SDavid du ColombierWhen an internal node is encountered,
621219b2ee8SDavid du Colombierit is labeled by consulting a table indexed by the
622219b2ee8SDavid du Colombierlabels on the left and right subtrees.
623219b2ee8SDavid du ColombierFor example,
624219b2ee8SDavid du Colombieron the 68020 processor,
625219b2ee8SDavid du Colombierit is possible to address an
626219b2ee8SDavid du Colombieroffset from a named location.
627219b2ee8SDavid du ColombierIn C, this is represented by the expression
628219b2ee8SDavid du Colombier.CW *(&name+constant) .
629219b2ee8SDavid du ColombierThis is marked addressable by the following table.
630219b2ee8SDavid du ColombierIn the table,
631219b2ee8SDavid du Colombiera node represented by the left column is marked
632219b2ee8SDavid du Colombierwith a small integer from the right column.
633219b2ee8SDavid du ColombierMarks of the form
634219b2ee8SDavid du Colombier.CW A\s-2\di\u\s0
635219b2ee8SDavid du Colombierare addressable while
636219b2ee8SDavid du Colombiermarks of the form
637219b2ee8SDavid du Colombier.CW N\s-2\di\u\s0
638219b2ee8SDavid du Colombierare not addressable.
639219b2ee8SDavid du Colombier.DS
640219b2ee8SDavid du Colombier.B
641219b2ee8SDavid du Colombier.ta .1i 1.1i
642219b2ee8SDavid du Colombier	Node	Marked
643219b2ee8SDavid du Colombier.CW
644219b2ee8SDavid du Colombier	name	A\s-2\d1\u\s0
645219b2ee8SDavid du Colombier	const	A\s-2\d2\u\s0
646219b2ee8SDavid du Colombier	&A\s-2\d1\u\s0	A\s-2\d3\u\s0
647219b2ee8SDavid du Colombier	A\s-2\d3\u\s0+A\s-2\d1\u\s0	N\s-2\d1\u\s0 \fR(note that this is not addressable)\fP
648219b2ee8SDavid du Colombier	*N\s-2\d1\u\s0	A\s-2\d4\u\s0
649219b2ee8SDavid du Colombier.DE
650219b2ee8SDavid du ColombierHere there is a distinction between
651219b2ee8SDavid du Colombiera node marked
652219b2ee8SDavid du Colombier.CW A\s-2\d1\u\s0
653219b2ee8SDavid du Colombierand a node marked
654219b2ee8SDavid du Colombier.CW A\s-2\d4\u\s0
655219b2ee8SDavid du Colombierbecause the address operator of an
656219b2ee8SDavid du Colombier.CW A\s-2\d4\u\s0
657219b2ee8SDavid du Colombiernode is not addressable.
658219b2ee8SDavid du ColombierSo to extend the table:
659219b2ee8SDavid du Colombier.DS
660219b2ee8SDavid du Colombier.B
661219b2ee8SDavid du Colombier.ta .1i 1.1i
662219b2ee8SDavid du Colombier	Node	Marked
663219b2ee8SDavid du Colombier.CW
664219b2ee8SDavid du Colombier	&A\s-2\d4\u\s0	N\s-2\d2\u\s0
665219b2ee8SDavid du Colombier	N\s-2\d2\u\s0+N\s-2\d1\u\s0	N\s-2\d1\u\s0
666219b2ee8SDavid du Colombier.DE
667219b2ee8SDavid du ColombierThe full addressability of the 68020 is expressed
668219b2ee8SDavid du Colombierin 18 rules like this,
669219b2ee8SDavid du Colombierwhile the addressability of the MIPS is expressed
670219b2ee8SDavid du Colombierin 11 rules.
671219b2ee8SDavid du ColombierWhen one ports the compiler,
672219b2ee8SDavid du Colombierthis table is usually initialized
673219b2ee8SDavid du Colombierso that leaves are labeled as addressable and nothing else.
674219b2ee8SDavid du ColombierThe code produced is poor,
675219b2ee8SDavid du Colombierbut porting is easy.
676219b2ee8SDavid du ColombierThe table can be extended later.
677219b2ee8SDavid du Colombier.LP
678219b2ee8SDavid du ColombierThis pass also rewrites some complex operators
679219b2ee8SDavid du Colombierinto procedure calls.
680219b2ee8SDavid du ColombierExamples include 64-bit multiply and divide.
681219b2ee8SDavid du Colombier.LP
682219b2ee8SDavid du ColombierIn the same bottom-up pass of the tree,
683219b2ee8SDavid du Colombierthe nodes are labeled with a Sethi-Ullman complexity
684219b2ee8SDavid du Colombier[Set70].
685219b2ee8SDavid du ColombierThis number is roughly the number of registers required
686219b2ee8SDavid du Colombierto compile the tree on an ideal machine.
687219b2ee8SDavid du ColombierAn addressable node is marked 0.
688219b2ee8SDavid du ColombierA function call is marked infinite.
689219b2ee8SDavid du ColombierA unary operator is marked as the
690219b2ee8SDavid du Colombiermaximum of 1 and the mark of its subtree.
691219b2ee8SDavid du ColombierA binary operator with equal marks on its subtrees is
692219b2ee8SDavid du Colombiermarked with a subtree mark plus 1.
693219b2ee8SDavid du ColombierA binary operator with unequal marks on its subtrees is
694219b2ee8SDavid du Colombiermarked with the maximum mark of its subtrees.
695219b2ee8SDavid du ColombierThe actual values of the marks are not too important,
696219b2ee8SDavid du Colombierbut the relative values are.
697219b2ee8SDavid du ColombierThe goal is to compile the harder
698219b2ee8SDavid du Colombier(larger mark)
699219b2ee8SDavid du Colombiersubtree first.
700219b2ee8SDavid du Colombier.NH 2
701219b2ee8SDavid du ColombierCode generation
702219b2ee8SDavid du Colombier.LP
703219b2ee8SDavid du ColombierCode is generated by recursive
704219b2ee8SDavid du Colombierdescent.
705219b2ee8SDavid du ColombierThe Sethi-Ullman complexity completely guides the
706219b2ee8SDavid du Colombierorder.
707219b2ee8SDavid du ColombierThe addressability defines the leaves.
708219b2ee8SDavid du ColombierThe only difficult part is compiling a tree
709219b2ee8SDavid du Colombierthat has two infinite (function call)
710219b2ee8SDavid du Colombiersubtrees.
711219b2ee8SDavid du ColombierIn this case,
712219b2ee8SDavid du Colombierone subtree is compiled into the return register
713219b2ee8SDavid du Colombier(usually the most convenient place for a function call)
714219b2ee8SDavid du Colombierand then stored on the stack.
715219b2ee8SDavid du ColombierThe other subtree is compiled into the return register
716219b2ee8SDavid du Colombierand then the operation is compiled with
717219b2ee8SDavid du Colombieroperands from the stack and the return register.
718219b2ee8SDavid du Colombier.LP
719219b2ee8SDavid du ColombierThere is a separate boolean code generator that compiles
720219b2ee8SDavid du Colombierconditional expressions.
721219b2ee8SDavid du ColombierThis is fundamentally different from compiling an arithmetic expression.
722219b2ee8SDavid du ColombierThe result of the boolean code generator is the
723219b2ee8SDavid du Colombierposition of the program counter and not an expression.
724219b2ee8SDavid du ColombierThe boolean code generator makes extensive use of De Morgan's rule.
725219b2ee8SDavid du ColombierThe boolean code generator is an expanded version of that described
726219b2ee8SDavid du Colombierin chapter 8 of Aho, Sethi, and Ullman
727219b2ee8SDavid du Colombier[Aho87].
728219b2ee8SDavid du Colombier.LP
729219b2ee8SDavid du ColombierThere is a considerable amount of talk in the literature
730219b2ee8SDavid du Colombierabout automating this part of a compiler with a machine
731219b2ee8SDavid du Colombierdescription.
732219b2ee8SDavid du ColombierSince this code generator is so small
733219b2ee8SDavid du Colombier(less than 500 lines of C)
734219b2ee8SDavid du Colombierand easy,
735219b2ee8SDavid du Colombierit hardly seems worth the effort.
736219b2ee8SDavid du Colombier.NH 2
737219b2ee8SDavid du ColombierRegisterization
738219b2ee8SDavid du Colombier.LP
739219b2ee8SDavid du ColombierUp to now,
740219b2ee8SDavid du Colombierthe compiler has operated on syntax trees
741219b2ee8SDavid du Colombierthat are roughly equivalent to the original source language.
742219b2ee8SDavid du ColombierThe previous pass has produced machine language in an internal
743219b2ee8SDavid du Colombierformat.
744219b2ee8SDavid du ColombierThe next two passes operate on the internal machine language
745219b2ee8SDavid du Colombierstructures.
746219b2ee8SDavid du ColombierThe purpose of the next pass is to reintroduce
747219b2ee8SDavid du Colombierregisters for heavily used variables.
748219b2ee8SDavid du Colombier.LP
749219b2ee8SDavid du ColombierAll of the variables that can be
750219b2ee8SDavid du Colombierpotentially registerized within a procedure are
751219b2ee8SDavid du Colombierplaced in a table.
752219b2ee8SDavid du Colombier(Suitable variables are any automatic or external
753219b2ee8SDavid du Colombierscalars that do not have their addresses extracted.
754219b2ee8SDavid du ColombierSome constants that are hard to reference are also
755219b2ee8SDavid du Colombierconsidered for registerization.)
756219b2ee8SDavid du ColombierFour separate data flow equations are evaluated
757219b2ee8SDavid du Colombierover the procedure on all of these variables.
758219b2ee8SDavid du ColombierTwo of the equations are the normal set-behind
759219b2ee8SDavid du Colombierand used-ahead
760219b2ee8SDavid du Colombierbits that define the life of a variable.
761219b2ee8SDavid du ColombierThe two new bits tell if a variable life
762219b2ee8SDavid du Colombiercrosses a function call ahead or behind.
763219b2ee8SDavid du ColombierBy examining a variable over its lifetime,
764219b2ee8SDavid du Colombierit is possible to get a cost
765219b2ee8SDavid du Colombierfor registerizing.
766219b2ee8SDavid du ColombierLoops are detected and the costs are multiplied
767219b2ee8SDavid du Colombierby three for every level of loop nesting.
768219b2ee8SDavid du ColombierCosts are sorted and the variables
769219b2ee8SDavid du Colombierare replaced by available registers on a greedy basis.
770219b2ee8SDavid du Colombier.LP
771219b2ee8SDavid du ColombierThe 68020 has two different
772219b2ee8SDavid du Colombiertypes of registers.
773219b2ee8SDavid du ColombierFor the 68020,
774219b2ee8SDavid du Colombiertwo different costs are calculated for
775219b2ee8SDavid du Colombiereach variable life and the register type that
776219b2ee8SDavid du Colombieraffords the better cost is used.
777219b2ee8SDavid du ColombierTies are broken by counting the number of available
778219b2ee8SDavid du Colombierregisters of each type.
779219b2ee8SDavid du Colombier.LP
780219b2ee8SDavid du ColombierNote that externals are registerized together with automatics.
781219b2ee8SDavid du ColombierThis is done by evaluating the semantics of a ``call'' instruction
782219b2ee8SDavid du Colombierdifferently for externals and automatics.
783219b2ee8SDavid du ColombierSince a call goes outside the local procedure,
784219b2ee8SDavid du Colombierit is assumed that a call references all externals.
785219b2ee8SDavid du ColombierSimilarly,
786219b2ee8SDavid du Colombierexternals are assumed to be set before an ``entry'' instruction
787219b2ee8SDavid du Colombierand assumed to be referenced after a ``return'' instruction.
788219b2ee8SDavid du ColombierThis makes sure that externals are in memory across calls.
789219b2ee8SDavid du Colombier.LP
790219b2ee8SDavid du ColombierThe overall results are satisfactory.
791219b2ee8SDavid du ColombierIt would be nice to be able to do this processing in
792219b2ee8SDavid du Colombiera machine-independent way,
793219b2ee8SDavid du Colombierbut it is impossible to get all of the costs and
794219b2ee8SDavid du Colombierside effects of different choices by examining the parse tree.
795219b2ee8SDavid du Colombier.LP
796219b2ee8SDavid du ColombierMost of the code in the registerization pass is machine-independent.
797219b2ee8SDavid du ColombierThe major machine-dependency is in
798219b2ee8SDavid du Colombierexamining a machine instruction to ask if it sets or references
799219b2ee8SDavid du Colombiera variable.
800219b2ee8SDavid du Colombier.NH 2
801219b2ee8SDavid du ColombierMachine code optimization
802219b2ee8SDavid du Colombier.LP
803219b2ee8SDavid du ColombierThe next pass walks the machine code
804219b2ee8SDavid du Colombierfor opportunistic optimizations.
805219b2ee8SDavid du ColombierFor the most part,
806219b2ee8SDavid du Colombierthis is highly specific to a particular
807219b2ee8SDavid du Colombierprocessor.
808219b2ee8SDavid du ColombierOne optimization that is performed
809219b2ee8SDavid du Colombieron all of the processors is the
810219b2ee8SDavid du Colombierremoval of unnecessary ``move''
811219b2ee8SDavid du Colombierinstructions.
812219b2ee8SDavid du ColombierIronically,
813219b2ee8SDavid du Colombiermost of these instructions were inserted by
814219b2ee8SDavid du Colombierthe previous pass.
815219b2ee8SDavid du ColombierThere are two patterns that are repetitively
816219b2ee8SDavid du Colombiermatched and replaced until no more matches are
817219b2ee8SDavid du Colombierfound.
818219b2ee8SDavid du ColombierThe first tries to remove ``move'' instructions
819219b2ee8SDavid du Colombierby relabeling variables.
820219b2ee8SDavid du Colombier.LP
821219b2ee8SDavid du ColombierWhen a ``move'' instruction is encountered,
822219b2ee8SDavid du Colombierif the destination variable is set before the
823219b2ee8SDavid du Colombiersource variable is referenced,
824219b2ee8SDavid du Colombierthen all of the references to the destination
825219b2ee8SDavid du Colombiervariable can be renamed to the source and the ``move''
826219b2ee8SDavid du Colombiercan be deleted.
827219b2ee8SDavid du ColombierThis transformation uses the reverse data flow
828219b2ee8SDavid du Colombierset up in the previous pass.
829219b2ee8SDavid du Colombier.LP
830219b2ee8SDavid du ColombierAn example of this pattern is depicted in the following
831219b2ee8SDavid du Colombiertable.
832219b2ee8SDavid du ColombierThe pattern is in the left column and the
833219b2ee8SDavid du Colombierreplacement action is in the right column.
834219b2ee8SDavid du Colombier.DS
835219b2ee8SDavid du Colombier.CW
836219b2ee8SDavid du Colombier.ta .1i .6i 1.6i 2.1i 2.6i
837219b2ee8SDavid du Colombier	MOVE	a->b		\fR(remove)\fP
838219b2ee8SDavid du Colombier.R
839219b2ee8SDavid du Colombier	(sequence with no mention of \f(CWa\fP)
840219b2ee8SDavid du Colombier.CW
841219b2ee8SDavid du Colombier	USE	b		USE	a
842219b2ee8SDavid du Colombier.R
843219b2ee8SDavid du Colombier	(sequence with no mention of \f(CWa\fP)
844219b2ee8SDavid du Colombier.CW
845219b2ee8SDavid du Colombier	SET	b		SET	b
846219b2ee8SDavid du Colombier.DE
847219b2ee8SDavid du Colombier.LP
848219b2ee8SDavid du ColombierExperiments have shown that it is marginally
849219b2ee8SDavid du Colombierworthwhile to rename uses of the destination variable
850219b2ee8SDavid du Colombierwith uses of the source variable up to
851219b2ee8SDavid du Colombierthe first use of the source variable.
852219b2ee8SDavid du Colombier.LP
853219b2ee8SDavid du ColombierThe second transform will do relabeling
854219b2ee8SDavid du Colombierwithout deleting instructions.
855219b2ee8SDavid du ColombierWhen a ``move'' instruction is encountered,
856219b2ee8SDavid du Colombierif the source variable has been set prior
857219b2ee8SDavid du Colombierto the use of the destination variable
858219b2ee8SDavid du Colombierthen all of the references to the source
859219b2ee8SDavid du Colombiervariable are replaced by the destination and
860219b2ee8SDavid du Colombierthe ``move'' is inverted.
861219b2ee8SDavid du ColombierTypically,
862219b2ee8SDavid du Colombierthis transformation will alter two ``move''
863219b2ee8SDavid du Colombierinstructions and allow the first transformation
864219b2ee8SDavid du Colombieranother chance to remove code.
865219b2ee8SDavid du ColombierThis transformation uses the forward data flow
866219b2ee8SDavid du Colombierset up in the previous pass.
867219b2ee8SDavid du Colombier.LP
868219b2ee8SDavid du ColombierAgain,
869219b2ee8SDavid du Colombierthe following is a depiction of the transformation where
870219b2ee8SDavid du Colombierthe pattern is in the left column and the
871219b2ee8SDavid du Colombierrewrite is in the right column.
872219b2ee8SDavid du Colombier.DS
873219b2ee8SDavid du Colombier.CW
874219b2ee8SDavid du Colombier.ta .1i .6i 1.6i 2.1i 2.6i
875219b2ee8SDavid du Colombier	SET	a		SET	b
876219b2ee8SDavid du Colombier.R
877219b2ee8SDavid du Colombier	(sequence with no use of \f(CWb\fP)
878219b2ee8SDavid du Colombier.CW
879219b2ee8SDavid du Colombier	USE	a		USE	b
880219b2ee8SDavid du Colombier.R
881219b2ee8SDavid du Colombier	(sequence with no use of \f(CWb\fP)
882219b2ee8SDavid du Colombier.CW
883219b2ee8SDavid du Colombier	MOVE	a->b		MOVE	b->a
884219b2ee8SDavid du Colombier.DE
885219b2ee8SDavid du ColombierIterating these transformations
886219b2ee8SDavid du Colombierwill usually get rid of all redundant ``move'' instructions.
887219b2ee8SDavid du Colombier.LP
888219b2ee8SDavid du ColombierA problem with this organization is that the costs
889219b2ee8SDavid du Colombierof registerization calculated in the previous pass
890219b2ee8SDavid du Colombiermust depend on how well this pass can detect and remove
891219b2ee8SDavid du Colombierredundant instructions.
892219b2ee8SDavid du ColombierOften,
893219b2ee8SDavid du Colombiera fine candidate for registerization is rejected
894219b2ee8SDavid du Colombierbecause of the cost of instructions that are later
895219b2ee8SDavid du Colombierremoved.
896219b2ee8SDavid du Colombier.NH 2
897219b2ee8SDavid du ColombierWriting the object file
898219b2ee8SDavid du Colombier.LP
899219b2ee8SDavid du ColombierThe last pass walks the internal assembly language
900219b2ee8SDavid du Colombierand writes the object file.
901219b2ee8SDavid du ColombierThe object file is reduced in size by about a factor
902219b2ee8SDavid du Colombierof three with simple compression
903219b2ee8SDavid du Colombiertechniques.
904219b2ee8SDavid du ColombierThe most important aspect of the object file
905219b2ee8SDavid du Colombierformat is that it is independent of the compiling machine.
906219b2ee8SDavid du ColombierAll integer and floating numbers in the object
907219b2ee8SDavid du Colombiercode are converted to known formats and byte
908219b2ee8SDavid du Colombierorders.
909219b2ee8SDavid du Colombier.NH
910219b2ee8SDavid du ColombierThe loader
911219b2ee8SDavid du Colombier.LP
912219b2ee8SDavid du ColombierThe loader is a multiple pass program that
913219b2ee8SDavid du Colombierreads object files and libraries and produces
914219b2ee8SDavid du Colombieran executable binary.
915219b2ee8SDavid du ColombierThe loader also does some minimal
916219b2ee8SDavid du Colombieroptimizations and code rewriting.
917219b2ee8SDavid du ColombierMany of the operations performed by the
918219b2ee8SDavid du Colombierloader are machine-dependent.
919219b2ee8SDavid du Colombier.LP
920219b2ee8SDavid du ColombierThe first pass of the loader reads the
921219b2ee8SDavid du Colombierobject modules into an internal data
922219b2ee8SDavid du Colombierstructure that looks like binary assembly language.
923219b2ee8SDavid du ColombierAs the instructions are read,
924219b2ee8SDavid du Colombiercode is reordered to remove
925219b2ee8SDavid du Colombierunconditional branch instructions.
926219b2ee8SDavid du ColombierConditional branch instructions are inverted
927219b2ee8SDavid du Colombierto prevent the insertion of unconditional branches.
928219b2ee8SDavid du ColombierThe loader will also make a copy of a few instructions
929219b2ee8SDavid du Colombierto remove an unconditional branch.
930219b2ee8SDavid du Colombier.LP
931219b2ee8SDavid du ColombierThe next pass allocates addresses for
932219b2ee8SDavid du Colombierall external data.
933219b2ee8SDavid du ColombierTypical of processors is the MIPS,
934219b2ee8SDavid du Colombierwhich can reference ±32K bytes from a
935219b2ee8SDavid du Colombierregister.
936219b2ee8SDavid du ColombierThe loader allocates the register
937219b2ee8SDavid du Colombier.CW R30
938219b2ee8SDavid du Colombieras the static pointer.
939219b2ee8SDavid du ColombierThe value placed in
940219b2ee8SDavid du Colombier.CW R30
941219b2ee8SDavid du Colombieris the base of the data segment plus 32K.
942219b2ee8SDavid du ColombierIt is then cheap to reference all data in the
943219b2ee8SDavid du Colombierfirst 64K of the data segment.
944219b2ee8SDavid du ColombierExternal variables are allocated to
945219b2ee8SDavid du Colombierthe data segment
946219b2ee8SDavid du Colombierwith the smallest variables allocated first.
947219b2ee8SDavid du ColombierIf all of the data cannot fit into the first
948219b2ee8SDavid du Colombier64K of the data segment,
949219b2ee8SDavid du Colombierthen usually only a few large arrays
950219b2ee8SDavid du Colombierneed more expensive addressing modes.
951219b2ee8SDavid du Colombier.LP
952219b2ee8SDavid du ColombierFor the MIPS processor,
953219b2ee8SDavid du Colombierthe loader makes a pass over the internal
954219b2ee8SDavid du Colombierstructures,
955219b2ee8SDavid du Colombierexchanging instructions to try
956219b2ee8SDavid du Colombierto fill ``delay slots'' with useful work.
957219b2ee8SDavid du ColombierIf a useful instruction cannot be found
958219b2ee8SDavid du Colombierto fill a delay slot,
959219b2ee8SDavid du Colombierthe loader will insert
960219b2ee8SDavid du Colombier``noop''
961219b2ee8SDavid du Colombierinstructions.
962219b2ee8SDavid du ColombierThis pass is very expensive and does not
963219b2ee8SDavid du Colombierdo a good job.
964219b2ee8SDavid du ColombierAbout 40% of all instructions are in
965219b2ee8SDavid du Colombierdelay slots.
966219b2ee8SDavid du ColombierAbout 65% of these are useful instructions and
967219b2ee8SDavid du Colombier35% are ``noops.''
968219b2ee8SDavid du ColombierThe vendor-supplied assembler does this job
969219b2ee8SDavid du Colombiermore effectively,
970219b2ee8SDavid du Colombierfilling about 80%
971219b2ee8SDavid du Colombierof the delay slots with useful instructions.
972219b2ee8SDavid du Colombier.LP
973219b2ee8SDavid du ColombierOn the 68020 processor,
974219b2ee8SDavid du Colombierbranch instructions come in a variety of
975219b2ee8SDavid du Colombiersizes depending on the relative distance
976219b2ee8SDavid du Colombierof the branch.
977219b2ee8SDavid du ColombierThus the size of branch instructions
978219b2ee8SDavid du Colombiercan be mutually dependent.
979219b2ee8SDavid du ColombierThe loader uses a multiple pass algorithm
980219b2ee8SDavid du Colombierto resolve the branch lengths
981219b2ee8SDavid du Colombier[Szy78].
982219b2ee8SDavid du ColombierInitially, all branches are assumed minimal length.
983219b2ee8SDavid du ColombierOn each subsequent pass,
984219b2ee8SDavid du Colombierthe branches are reassessed
985219b2ee8SDavid du Colombierand expanded if necessary.
986219b2ee8SDavid du ColombierWhen no more expansions occur,
987219b2ee8SDavid du Colombierthe locations of the instructions in
988219b2ee8SDavid du Colombierthe text segment are known.
989219b2ee8SDavid du Colombier.LP
990219b2ee8SDavid du ColombierOn the MIPS processor,
991219b2ee8SDavid du Colombierall instructions are one size.
992219b2ee8SDavid du ColombierA single pass over the instructions will
993219b2ee8SDavid du Colombierdetermine the locations of all addresses
994219b2ee8SDavid du Colombierin the text segment.
995219b2ee8SDavid du Colombier.LP
996219b2ee8SDavid du ColombierThe last pass of the loader produces the
997219b2ee8SDavid du Colombierexecutable binary.
998219b2ee8SDavid du ColombierA symbol table and other tables are
999219b2ee8SDavid du Colombierproduced to help the debugger to
1000219b2ee8SDavid du Colombierinterpret the binary symbolically.
1001219b2ee8SDavid du Colombier.LP
1002219b2ee8SDavid du ColombierThe loader places absolute source line numbers in the symbol table.
1003219b2ee8SDavid du ColombierThe name and absolute line number of all
1004219b2ee8SDavid du Colombier.CW #include
1005219b2ee8SDavid du Colombierfiles is also placed in the
1006219b2ee8SDavid du Colombiersymbol table so that the debuggers can
1007219b2ee8SDavid du Colombierassociate object code to source files.
1008219b2ee8SDavid du Colombier.NH
1009219b2ee8SDavid du ColombierPerformance
1010219b2ee8SDavid du Colombier.LP
1011219b2ee8SDavid du ColombierThe following is a table of the source size of the MIPS
1012219b2ee8SDavid du Colombiercompiler.
1013219b2ee8SDavid du Colombier.DS
1014219b2ee8SDavid du Colombier.ta .1i .6i
1015219b2ee8SDavid du Colombier	lines	module
1016219b2ee8SDavid du Colombier	\0509	machine-independent headers
1017219b2ee8SDavid du Colombier	1070	machine-independent YACC source
1018219b2ee8SDavid du Colombier	6090	machine-independent C source
1019219b2ee8SDavid du Colombier
1020219b2ee8SDavid du Colombier	\0545	machine-dependent headers
1021219b2ee8SDavid du Colombier	6532	machine-dependent C source
1022219b2ee8SDavid du Colombier
1023219b2ee8SDavid du Colombier	\0298	loader headers
1024219b2ee8SDavid du Colombier	5215	loader C source
1025219b2ee8SDavid du Colombier.DE
1026219b2ee8SDavid du Colombier.LP
1027219b2ee8SDavid du ColombierThe following table shows timing
1028219b2ee8SDavid du Colombierof a test program
1029219b2ee8SDavid du Colombierthat plays checkers, running on a MIPS R4000.
1030219b2ee8SDavid du ColombierThe test program is 26 files totaling 12600 lines of C.
1031219b2ee8SDavid du ColombierThe execution time does not significantly
1032219b2ee8SDavid du Colombierdepend on library implementation.
1033219b2ee8SDavid du ColombierSince no other compiler runs on Plan 9,
1034219b2ee8SDavid du Colombierthe Plan 9 tests were done with the Plan 9 operating system;
1035219b2ee8SDavid du Colombierthe other tests were done on the vendor's operating system.
1036219b2ee8SDavid du ColombierThe hardware was identical in both cases.
1037219b2ee8SDavid du ColombierThe optimizer in the vendor's compiler
1038219b2ee8SDavid du Colombieris reputed to be extremely good.
1039219b2ee8SDavid du Colombier.DS
1040219b2ee8SDavid du Colombier.ta .1i .9i
1041219b2ee8SDavid du Colombier	\0\04.49s	Plan 9 \f(CWvc\fP \f(CW-N\fP compile time (opposite of \f(CW-O\fP)
1042219b2ee8SDavid du Colombier	\0\01.72s	Plan 9 \f(CWvc\fP \f(CW-N\fP load time
1043219b2ee8SDavid du Colombier	148.69s	Plan 9 \f(CWvc\fP \f(CW-N\fP run time
1044219b2ee8SDavid du Colombier
1045219b2ee8SDavid du Colombier	\015.07s	Plan 9 \f(CWvc\fP compile time (\f(CW-O\fP implicit)
1046219b2ee8SDavid du Colombier	\0\01.66s	Plan 9 \f(CWvc\fP load time
1047219b2ee8SDavid du Colombier	\089.96s	Plan 9 \f(CWvc\fP run time
1048219b2ee8SDavid du Colombier
1049219b2ee8SDavid du Colombier	\014.83s	vendor \f(CWcc\fP compile time
1050219b2ee8SDavid du Colombier	\0\00.38s	vendor \f(CWcc\fP load time
1051219b2ee8SDavid du Colombier	104.75s	vendor \f(CWcc\fP run time
1052219b2ee8SDavid du Colombier
1053219b2ee8SDavid du Colombier	\043.59s	vendor \f(CWcc\fP \f(CW-O\fP compile time
1054219b2ee8SDavid du Colombier	\0\00.38s	vendor \f(CWcc\fP \f(CW-O\fP load time
1055219b2ee8SDavid du Colombier	\076.19s	vendor \f(CWcc\fP \f(CW-O\fP run time
1056219b2ee8SDavid du Colombier
1057219b2ee8SDavid du Colombier	\0\08.19s	vendor \f(CWcc\fP \f(CW-O3\fP compile time
1058219b2ee8SDavid du Colombier	\035.97s	vendor \f(CWcc\fP \f(CW-O3\fP load time
1059219b2ee8SDavid du Colombier	\071.16s	vendor \f(CWcc\fP \f(CW-O3\fP run time
1060219b2ee8SDavid du Colombier.DE
1061219b2ee8SDavid du Colombier.LP
1062219b2ee8SDavid du ColombierTo compare the Intel compiler,
1063219b2ee8SDavid du Colombiera program that is about 40% bit manipulation and
1064219b2ee8SDavid du Colombierabout 60% single precision floating point was
1065219b2ee8SDavid du Colombierrun on the same 33 MHz 486, once under Windows
1066219b2ee8SDavid du Colombiercompiled with the Watcom compiler, version 10.0,
1067219b2ee8SDavid du Colombierin 16-bit mode and once under
1068219b2ee8SDavid du ColombierPlan 9 in 32-bit mode.
1069219b2ee8SDavid du ColombierThe Plan 9 execution time was 27 sec while the Windows
1070219b2ee8SDavid du Colombierexecution time was 31 sec.
1071219b2ee8SDavid du Colombier.NH
1072219b2ee8SDavid du ColombierConclusions
1073219b2ee8SDavid du Colombier.LP
1074219b2ee8SDavid du ColombierThe new compilers compile
1075219b2ee8SDavid du Colombierquickly,
1076219b2ee8SDavid du Colombierload slowly,
1077219b2ee8SDavid du Colombierand produce
1078219b2ee8SDavid du Colombiermedium quality
1079219b2ee8SDavid du Colombierobject code.
1080219b2ee8SDavid du ColombierThe compilers are relatively
1081219b2ee8SDavid du Colombierportable,
1082219b2ee8SDavid du Colombierrequiring but a couple of weeks' work to
1083219b2ee8SDavid du Colombierproduce a compiler for a different computer.
1084219b2ee8SDavid du ColombierFor Plan 9,
1085219b2ee8SDavid du Colombierwhere we needed several compilers
1086219b2ee8SDavid du Colombierwith specialized features and
1087219b2ee8SDavid du Colombierour own object formats,
1088219b2ee8SDavid du Colombierthis project was indispensable.
1089219b2ee8SDavid du ColombierIt is also necessary for us to
1090219b2ee8SDavid du Colombierbe able to freely distribute our compilers
1091219b2ee8SDavid du Colombierwith the Plan 9 distribution.
1092219b2ee8SDavid du Colombier.LP
1093219b2ee8SDavid du ColombierTwo problems have come up in retrospect.
1094219b2ee8SDavid du ColombierThe first has to do with the
1095219b2ee8SDavid du Colombierdivision of labor between compiler and loader.
1096219b2ee8SDavid du ColombierPlan 9 runs on multi-processors and as such
1097219b2ee8SDavid du Colombiercompilations are often done in parallel.
1098219b2ee8SDavid du ColombierUnfortunately,
1099219b2ee8SDavid du Colombierall compilations must be complete before loading
1100219b2ee8SDavid du Colombiercan begin.
1101219b2ee8SDavid du ColombierThe load is then single-threaded.
1102219b2ee8SDavid du ColombierWith this model,
1103219b2ee8SDavid du Colombierany shift of work from compile to load
1104219b2ee8SDavid du Colombierresults in a significant increase in real time.
1105219b2ee8SDavid du ColombierThe same is true of libraries that are compiled
1106219b2ee8SDavid du Colombierinfrequently and loaded often.
1107219b2ee8SDavid du ColombierIn the future,
1108219b2ee8SDavid du Colombierwe may try to put some of the loader work
1109219b2ee8SDavid du Colombierback into the compiler.
1110219b2ee8SDavid du Colombier.LP
1111219b2ee8SDavid du ColombierThe second problem comes from
1112219b2ee8SDavid du Colombierthe various optimizations performed over several
1113219b2ee8SDavid du Colombierpasses.
1114219b2ee8SDavid du ColombierOften optimizations in different passes depend
1115219b2ee8SDavid du Colombieron each other.
1116219b2ee8SDavid du ColombierIterating the passes could compromise efficiency,
1117219b2ee8SDavid du Colombieror even loop.
1118219b2ee8SDavid du ColombierWe see no real solution to this problem.
1119219b2ee8SDavid du Colombier.NH
1120219b2ee8SDavid du ColombierReferences
1121219b2ee8SDavid du Colombier.LP
1122219b2ee8SDavid du Colombier[Aho87] A. V. Aho, R. Sethi, and J. D. Ullman,
1123219b2ee8SDavid du Colombier.I
1124219b2ee8SDavid du ColombierCompilers \- Principles, Techniques, and Tools,
1125219b2ee8SDavid du Colombier.R
1126219b2ee8SDavid du ColombierAddison Wesley,
1127219b2ee8SDavid du ColombierReading, MA,
1128219b2ee8SDavid du Colombier1987.
1129219b2ee8SDavid du Colombier.LP
1130219b2ee8SDavid du Colombier[ANSI90] \f2American National Standard for Information Systems \-
1131219b2ee8SDavid du ColombierProgramming Language C\f1, American National Standards Institute, Inc.,
1132219b2ee8SDavid du ColombierNew York, 1990.
1133219b2ee8SDavid du Colombier.LP
1134219b2ee8SDavid du Colombier[Dav91] J. W. Davidson and D. B. Whalley,
1135219b2ee8SDavid du Colombier``Methods for Saving and Restoring Register Values across Function Calls'',
1136219b2ee8SDavid du Colombier.I
1137219b2ee8SDavid du ColombierSoftware\-Practice and Experience,
1138219b2ee8SDavid du Colombier.R
1139219b2ee8SDavid du ColombierVol 21(2), pp. 149-165, February 1991.
1140219b2ee8SDavid du Colombier.LP
1141219b2ee8SDavid du Colombier[Joh79] S. C. Johnson,
1142219b2ee8SDavid du Colombier``YACC \- Yet Another Compiler Compiler'',
1143219b2ee8SDavid du Colombier.I
1144219b2ee8SDavid du ColombierUNIX Programmer's Manual, Seventh Ed., Vol. 2A,
1145219b2ee8SDavid du Colombier.R
1146219b2ee8SDavid du ColombierAT&T Bell Laboratories,
1147219b2ee8SDavid du ColombierMurray Hill, NJ,
1148219b2ee8SDavid du Colombier1979.
1149219b2ee8SDavid du Colombier.LP
1150219b2ee8SDavid du Colombier[Set70] R. Sethi and J. D. Ullman,
1151219b2ee8SDavid du Colombier``The Generation of Optimal Code for Arithmetic Expressions'',
1152219b2ee8SDavid du Colombier.I
1153219b2ee8SDavid du ColombierJournal of the ACM,
1154219b2ee8SDavid du Colombier.R
1155219b2ee8SDavid du ColombierVol 17(4), pp. 715-728, 1970.
1156219b2ee8SDavid du Colombier.LP
1157219b2ee8SDavid du Colombier[Szy78] T. G. Szymanski,
1158219b2ee8SDavid du Colombier``Assembling Code for Machines with Span-dependent Instructions'',
1159219b2ee8SDavid du Colombier.I
1160219b2ee8SDavid du ColombierCommunications of the ACM,
1161219b2ee8SDavid du Colombier.R
1162219b2ee8SDavid du ColombierVol 21(4), pp. 300-308, 1978.
1163