Re: Compilers for systems programming (was: A C style compiler)

"Dr Richard A. O'Keefe" <>
7 May 1998 17:07:53 -0400

          From comp.compilers

Related articles
Compilers for systems programming (was: A C style compiler) (Francois-Rene Rideau) (1998-05-04)
Re: Compilers for systems programming (was: A C style compiler) (eric dahlman) (1998-05-07)
Re: Compilers for systems programming (was: A C style compiler) (Dr Richard A. O'Keefe) (1998-05-07)
Re: Compilers for systems programming (was: A C style compiler) (1998-05-12)
Re: Compilers for systems programming (was: A C style compiler) (Eric Eide) (1998-05-12)
Re: Compilers for systems programming (was: A C style compiler) (William D Clinger) (1998-05-12)
Re: Compilers for systems programming (was: A C style compiler) (W. Craig Trader) (1998-05-15)
Re: Compilers for systems programming (was: A C style compiler) (1998-05-15)
Re: Compilers for systems programming (was: A C style compiler) (1998-05-17)
[1 later articles]
| List of all articles for this month |

From: "Dr Richard A. O'Keefe" <>
Newsgroups: comp.compilers
Date: 7 May 1998 17:07:53 -0400
Organization: Department of Computer Science, University of Otago
References: 98-05-017
Keywords: practice, history, comment

Francois-Rene Rideau wrote:
> To revert to more on-topic tracks, I wonder if there are other
> language besides C and cousins (Pascal, Ada, Modula-3, Oberon), whose
> design/implementation combos were fit for programming systems
> internals.

Burroughs ESPOL, ESPL, PL/360, PL/516, PL/11, BCPL, IBM's "systems
programming" dialect of PL/I (PL/S, wasn't it?), Prime Fortran (I kid
you not), BLISS-10, BLISS-32, BLISS-11, Algol 68/R (I believe), then
of course there's Lisp, with the Xerox Lisp machines programmed down
to just above the microcode level in Lisp and the LMI and Symbolics
machines all the way down to occasional microcode in Lisp, not to
mention more recent things like Ada 83 and Ada 95.

> This is clearly a compiler problem as well as a language problem,
> since it requires a way to interface actual hardware capabilities into
> high-level programming constructs, which interferes with the both the
> high-level language semantics, and the implementation choices of the
> compiler, hence with compiler "optimizations".

Not so's you'd notice it. To start with, a lot of these compilers
didn't _do_ much optimisation. It was _years_ before C compilers were
anything other than very direct, and that was quite good enough to be
going on with. The Bliss compilers, on the other hand, were famed for
optimisation (Bliss-11 and Bliss-32 anyway, Bliss-10 wasn't all that
hot). As long as you can tell the compiler what an instruction
depends on and what it alters, it isn't any worse than a call to a
library procedure that depends on and alters the same things. Indeed,
there are probably C programmers reading this who remember the old way
to get machine code into 4.2BSD Vax code: use a 'sed' script to
replace 'calls foo...' with the appropriate inline code.

> Because C was designed to be low-level, and current processors are
> "optimized for C", and mapping from C semantics to the hardware is
> standard and pretty straightforward (a matter of saying which register
> is the stack, which hold results and parameters, which are
> callee-saved or caller-saved, and how the stack is laid out), C
> compilers only have to deal with the way inline assembly interacts
> with optimization (see constraints in GCC inline assembly), without
> having to worry much about any kind of typing.

C is not in fact a noticeably low-level language. It is not, for
example, as low level as PL/360 or BCPL. It is very nearly as high
level as Pascal, and has been known to have a rather larger run-time
support library. It's not that C is low-level, it's just a
medium-level language with low-level lapses that make it hard to reap
the gains medium-level languages should provide.

> How do other, higher-level languages, handle the semantic mismatch
> between design and implementation, if at all? How can they allow
> global invariants to be broken in the middle of some system internal
> routine, and ensure (or not) that it is restored before the end?

C does not do these things! Unlike Ada, there is no provision for
embedded assembly code in the standard language, and if you _do_ use
any embedded assembly code (with at least four different approaches to
doing that in use) it is _entirely up to the programmer_ to ensure (or
not) that such global invariants as the C compiler may have been
relying on are preserved or restored.

> How can they (or not) allow to specify additional low-level
> invariants to be added when manipulating some hardware specific
> objects? How do these specifications (or lack thereof) interact
> with compiler code generation and optimization?

The same way C does: it's up to you, matey! Go outside the
standardised language and *you* are responsible. Your best bet is
something like Ada+Anna, where you can encapsulate the low-level
operations is possibly-inlined procedures and annotate them, and then
use Anna to check that the program uses the operations consistently.

> As an important example, what language with automatic memory
> management could be used to *fully* implement its own (efficient) GC
> without hiding lots of details in custom hardware, or arbitrary
> software implementation choices?

I don't fully understand this question. Xerox Lisp (was Interlisp,
became Xerox Common Lisp) was partly implemented in custom microcode
and mostly implemented in Lisp. The Lisp code for GC was full of low
level extensions like (\GETWORD <pointer> <offset>) which basically
bypassed the Lisp type system. If you used the low-level operations,
you were ``voiding the guarantee'' and could get into a state where
the machine would lock up with a fault code on the maintenance panel,
just as badly as if you were using C. The Xerox D machines weren't
custom *Lisp* hardware, they were also used for Smalltalk and Mesa,
and I think may have been used for Smalltalk and Mesa _first_.

What language *without* automatic memory management could be used to
*fully* implement its own run-time system without ``opening the box''
and ``voiding the guarantee''?

> I know for instance, that LISP Machines were fully programmed in LISP,
> down to the "assembly". How did they handle the situation?
> It seems to me they did rely on many details and implementation choices
> provided by custom hardware. How far can the approach be recycled
> for common hardware architectures?

Xerox spun off their Lisp development to a new company whose name I
can no longer recall. One of the first things they did was to port
the Xerox lisp system off the Xerox D-machine hardware onto SPARCs,
and this Lisp system has been running happily on SPARCs ever since.

There was some work done on a Scheme system where the data
representations &c were bound very late; I think that may have been
done at Xerox too.
[Don't forget IBM's Fortran H compiler, which was the state of the art
optimizing compiler for most the 1960s and 1970s and was written in
itself, using some struct-like extensions. Even by modern standards,
its optimizations weren't (aren't, it's still around) bad. -John]

Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.