C Back-End Release Notes
========================

The 7.3 release introduced an important new feature: the compiler can generate output in C, which can then be compiled and linked using the usual C development tools.  This feature is being used to support architectures, such as the SPARC and IBM RS6000, for which the compiler does not have native-code support.

MIT Scheme systems that have been built using this compiler feature are referred to as C back-end systems.  This section provides a brief description of the features and known problems for such systems.

General Notes
-------------

This section describes the general design of C back-end systems.

  * The C back end was written very recently, and we do not use it ourselves for development--we have native back ends for the hardware that we use regularly.  Furthermore, most of the system-building tools and changes were put together and tested immediately preceding the release.  It is not unlikely that there are serious problems and shortcomings.  We'd like to hear about them so we can fix them or bypass them for a future release.  If something does not work, do not assume that we know about it. Please report it.  The worse that can happen is that we hear about it several times.

  * The compiler produces C code that works in the context of the MIT Scheme runtime library.  It is not stand-alone code, and there is currently no way to generate stand-alone executables.

  * We have done some performance testing on machines where we have both a native back end and the C back end.  The C back end code is somewhat larger and slower than the native code.  The speed varies depending primarily on the number of inter-C-procedure calls (even within a single source file).  In some cases the C code is somewhat faster than the native code, but it is usually noticeably slower.  The average is about 2.5 times slower.

  * The output code should work on virtually any modern general-purpose architecture with an ANSI-compliant (perhaps even a traditional K&R) C compiler.  We've tried it on several 32-bit architectures (HP PA, SPARC, Motorola 68040, RS6000/Power) and a 64-bit architecture (Alpha).

     However, there may very well be assumptions of the following form:

       * Memory is byte-addressable.

       * Addresses and ordinary data live in the same memory.  Some special-purpose processors do not satisfy this constraint.

       * unsigned data items and addresses fit into the same memory, and if union-ed, take the same space.

       * Signed integers are represented using 2s-complement representation.

       * The machine/OS uses the ASCII character set.  This is not a property of the compiler per-se, but of the MIT Scheme system.

     In addition, some configuration of the compiler, microcode and build-scripts would have to be done for new architectures/operating systems.  The things that come to mind are:

       * Dynamic loading primitives are OS-dependent.

       * Basic microcode configuration, including:

            * OS interface.

            * Choosing a new machine type (FASL numbers in config. h).

       * Build scripts dispatch on the OS and architecture type, and only understand a handful of types.

       * The compiler has a table of C compiler and linker switches for the configurations we have tried.  It needs to be extended for new configurations, although this can be done easily.

     If you are interested in bringing up the system on a new configuration, please contact us for further instructions, and to obtain the set of crude tools that we use to do this.

  * The performance of the output code could be greatly improved by judicious use of assembly language to achieve faster cross-module tail recursion.  So far, we've given more weight to portability than to performance.

  * The resulting C code can be compiled and statically linked with the MIT Scheme microcode (the runtime library is linked in this way), or compiled and dynamically loaded and linked if the operating system supports this feature.  The C code must be compiled defining the COMPILE_FOR_STATIC_LINKING if it is to be statically linked into the microcode or collected into a larger dynamically-loadable library (e.g. Edwin or the compiler).  If you'd like to put together a shared library of a large subsystem that you have written, please contact us for advice on how it can be done.

Problems with the C Back-End
----------------------------

This section details problems and shortcomings of the system that are specific to the C back-end.

  * compile-procedure and compile-scode do not work.  This will be fixed for a future release and is not very hard to bypass in most cases.  compile-procedure gives an error. compile-scode returns something which is not a compiled expression.  cf and compile-bin-file work.

  * Dynamically loaded compiled modules are not unloaded when no longer accessed.  In particular, after a disk-restore, previously loaded modules are still mapped.  In addition, at least in some versions of Unix, the shared object file cannot be deleted while it is loaded, so re-compilation of a module in place will fail if some process has it already loaded.

  * Multiple loading does not work.  This is bad for development.  After loading a compiled module once, it cannot be reloaded (presumably after re-compilation).

  * fasdump does not work for compiled code.  It gives an error. Only bands can be dumped.

  * Several C compilers are unhappy about the size of the resulting C procedures.  They often turn their optimizers off.

  * Some C compilers/optimizers produce non-working code for some of the output.  In particular, we've had serious problems with the RS6000/AIX-3.2 C compiler.

  * Several C compilers give copious ``statement not reached'' warnings about the resulting code.  This arises from the heavy use of macros expanding into the pattern

          do
          {
            BODY
          } while (0)

     Most of these macros are not really necessary, and the code generator could just issue the BODY directly.

  * The mechanism for accreting object files into large dynamically-loadable libraries is currently ad-hoc.