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