Naturally, a program compiled with checks is very much larger and less efficient than the corresponding optimised program—a factor of 3 is common. Nevertheless, the checking and diagnostic facilities greatly ease the problems of debugging large programs and have proved to be one of the most valuable features of IMP. IMP—A brief critique The following remarks are proffered in the full knowledge that originators are often totally blind to the defects of their brain children. It seems to us that IMP has struck a reasonable balance between what is desirable and what is possible to implement efficiently. It may err a little on the side of verbosity but it remains easy to read. Its most successful features seem to be the logical operations, strings and diagnostic facilities. Real arithmetic and routine parameters have been almost completely ignored by system programmers although both features are used by applications packages. Arguments continue whether or not the IMP structure with its three types of bracketing (begin . . . end, start . . . finish, cycle repeat) produces more or less readable programs than ALGOL. Its principal failure lies in the area of contingency handling. The fault statement is insufficiently flexible for system programmers who tend to call Director's Signal mechanism directly (Rees, 1973). A system programming language requires some form of on condition that permits the resumption of the interrupted program. Purists have criticised IMP for not having a variable of type logical, and it is true that allowing bit operations on integer variables presumes a conversion between integers and bit representation. Nevertheless, IMP programs have been transferred between the ones-complement Univac 1108 and the twos-complement 4-75 without raising any problems in this particular area. A more serious obstacle to machine independent software is the use of mapping functions which can assume an addressing structure. However, mapping functions have proved too valuable for abolition or amendment to be possible. The choice of the term byte integer was unfortunate as it causes an emotional reaction, particularly among those who dislike IBM System 360 and its architecture. A neutral term such as character would have been preferable. It remains the implementer's conviction that the language would have aroused wider interest if it had been christened Implementation ALGOL or ALGOL (I) rather than IMP. 2. The IMP compiler Compiler objectives The EMAS project started two years before the delivery of the 4-75. In the meantime, a KDF9 was available for preliminary testing. The initial objectives were: 3. To provide an IMP compiler for KDF9, simulating as far as possible byte addressing and 32-bit arithmetic on a 48-bit word address machine. 4. To have a preliminary version of the 4-75 compiler ready as soon as the machine arrived. 5. To concentrate, in the first instance at least, on robust compilers with good diagnostics. The first compilers were to be single pass to simplify the bootstrap between machines with very different device handling philosophies. Compiler development The starting point was the Atlas Autocode compiler for KDF9 (Bratley et al., 1965). This compiler had been written entirely in Atlas Autocode. It was compiled on the Manchester Atlas and then bootstrapped to the KDF9. The IMP compiler for KDF9 was written in the Atlas Autocode compatible subset of IMP and simulated byte addressing and 32-bit arithmetic by extensive use of subroutines. Arithmetic operations were 2-4 times slower than in Atlas Autocode and array access some 6 times slower. However, the bootstrapped compiler was only about 50 per cent slower than the Atlas Autocode compiler, thus showing what a small portion of compiling time is spent in arithmetic operations. For System 4, the compiler was bootstrapped from the KDF9 compiler via assembly language (due to difficulties with the manufacturers early operating systems). This compiler was also bootstrapped onto the IBM 360/50 (Yarwood, 1970). The early EMAS components were compiled on the manufacturers J level operating system and transferred to the EMAS system as binary magnetic tape. As soon as the supervisor was sufficiently robust, the IMP compiler followed this by now well worn route. Since its establishment on System 4, the IMP compiler has been bootstrapped through itself seven times. Two of these were due to changes in register conventions and sub-system standards inevitable in the 'iterative' design of complex software. One was due to hand-coding of several routines to produce faster compiling times. (A 20 per cent increase in speed was obtained after the usual difficulties of debugging assembler coding had wasted several months.) The remaining four bootstraps were to enable improvements to be made in the following areas: Release routine entry and exit effort = three months Release 6 register allocation effort = two months Release 7 expression optimisation effort = six months Release 8 simple loop optimisation effort = five months Of these, the register allocation required the fewest source statements and produced the biggest improvement in object code. The expression optimisation required the most new source code and produced the least effect. The effect of these changes is that the Release 8 compiler produces about half the amount of object code that Release 1 produced for the same program. Release 8 object code is rather more than twice as fast as Release 1 object code. Since the compiler is written in IMP, compiling speeds have increased similarly. These figures enable the four months spent hand coding analysis routines to be seen as the waste of effort it undoubtedly was. Object program The object program produced by the compiler consists of three areas. A shareable area of code, constants and symbol tables, a non-shareable area of own variables and external references, and lastly some linkage data. The object program format is described elsewhere (Millard and Whitfield, 1973). Note, however that EMAS program sharing (Whitfield and Wight, 1973) demands that a shared program executes correctly even if it is at a different address in virtual memory. This causes the compiler writer some problems—for example by preventing the use of address constants—although the effect on object code efficiency is small. The IMP object program uses a stack for variables and temporary space. Each routine claims its 'stack frame' on entry and releases it on exit. A 'display' points to the stack frames available at any instant as defined by the scope rules. In IMP, this display is kept in the general registers, thus making local variables directly addressable at all times. This leads to efficient object code except when passing routines as parameters, but requires a limit to be placed on the depth of nested blocks. On a routine call the parameters are placed ahead of the stack top such that they will appear in the local variable space of the called routine when it claims its stack frame.