Re: Using C as a back end
23 Oct 2000 22:00:45 -0400

          From comp.compilers

Related articles
[2 earlier articles]
Re: Using C as a back end (Peter Gammie) (2000-10-22)
Re: Using C as a back end (Friedrich Dominicus) (2000-10-22)
Re: Using C as a back end (Joachim Durchholz) (2000-10-22)
Re: Using C as a back end (jacob navia) (2000-10-22)
Re: Using C as a back end (2000-10-22)
Re: Using C as a back end (2000-10-23)
Re: Using C as a back end (2000-10-23)
Re: Using C as a back end (Pred.) (2000-10-23)
Re: Using C as a back end (Pred.) (2000-10-23)
Re: Using C as a back end (Stephen T. Weeks) (2000-10-23)
Re: Using C as a back end (Pg Nor Jaidi Pg Tuah) (2000-10-26)
Re: Using C as a back end (Pred.) (2000-10-26)
Re: Using C as a back end (Conor O'Neill) (2000-10-26)
[20 later articles]
| List of all articles for this month |

Newsgroups: comp.compilers
Date: 23 Oct 2000 22:00:45 -0400
Organization: University of California, Berkeley
References: 00-10-148 00-10-152
Keywords: C, translator

Jim Granville <> wrote:
>[I disagree about compile time; most modern compilers are very slow. By
>comparison, the Dartmouth Basic compiler running on a 1 mips machine could
>compile most user programs in under 1/10 second, from RUN to when it started
>running. -John]

I work on a system (sfront) that translates a special-purpose language
(SAOL, the audio signal processing language of MPEG 4 Audio, see:

for the gory details), and recently spent a few weeks trying to trim down the
time "gcc -O3" takes to handle compilation, since for some users this became
the limiting step in using our system. Here are some places we found clear
wins in reducing compile time, which might help others trying to do such

[1] If your generated code has large global datastructures that are
statically initialized, think carefully about going a different route --
especially if floating-point constants form the bulk of the initialization
values. The best thing to do is to design all of your datastructures so
that the right initialization value is 0.0F :-). Failing that:

  -- If the initializations are sparse, its often worth the effort to let
        the static initializations be zero, and generate smart custom code to
        poke the non-zero values in at startup using a minimal number of lines
        of C (by smart I mean not just a laundry list of assignment statements,
        but constructing loops that exploit common regularities -- measure to
        see if the loops are actually saving compilation time).

  -- If the initialization isn't sparse, your best bet in terms of compilation
        efficiency is to use hexadecimal strings (i.e.

        char score_stdata0[69] =

        to replace (via a run-time cast)

        float score_stdata0[17] = {

        String parsing is quite tightly optimized in gcc, and runs significantly
        faster than parsing floats. Of course, this approach is:

        -- non-portable, and
        -- for some compilers, seems to not work at all -- string constants
              with embedded \x00's can premature end the constants in some non-gcc

[2] Compiling generated C code using -O3 simply takes time, and the best
        weapon is to minimize the amount of C code produced. Think hard about
        the tradeoffs between:

        -- representing work as computation to be done at runtime or as
              work that is done at "translate-to-C" time and stored as data in
              the C file.

        -- if your system parses complicated files (sfront parses all sorts of
              complex binary formats, such as MIDI files, WAV files, AIFF files,
              MP4 files), think hard about distributing the parsing over the
              "translate-to-C" and the runtime phases, to minimize the amount of
              generated C code.

        -- only "spread out computation in space" (i.e. generate lots of
              special-case code to make certain variants of a computation go
              fast) when there is a compelling performance reason to do so --
              I ended up changing many parts of the sfront codegeneration in
              ways that reduced performance by 1% while reducing the generated
              code by 50% or more! More often, the bloated code I was generating
              was slowing down run time as well as compile time.

[3] For gcc, at least, large, multi-level switch() statements can take a long
        time to compile when used in certain constructions, and the run-time
        speedup over a more compact approach is often not worth it.

In summary, I guess the overriding message is, do lots of benchmarks with
your preferred compiler target, and think hard about matching the style
of generated code to match the target. Finally, I'd recommend striving to
generate pure ANSI C by default, and only do non-portable things under
flag control -- it will reduce the amount of email in your mbox :-).

John Lazzaro -- Research Specialist -- CS Division -- EECS -- UC Berkeley
lazzaro [at] cs [dot] berkeley [dot] edu

Post a followup to this message

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