Live data from Hacker News

C as an intermediate language (2012)

yosefk.com

21–30 of 32 posts

Re: C as an intermediate language (2012)

#21
I worked at a company that did a very large amount of data processing on a relatively small number of machines using a well-optimized c++ library. The library did everything, including the calculations and the data storage. This made it hard to write one-off queries that the executive team would request from time to time, since we would write a custom c++ program every time.

One day we came up with an idea: what if we could query the data store with SQL? The first iteration actually attempted to embed sqlite3 into the data access layer, which was functional but extremely slow because of all the type marshaling going on. A coworker and I came up with the second iteration which worked like this: a custom SQL-like language would be parsed by a Perl program using Parse::RecDescent, a recursive parser generator. The parse tree would then be translated into C++ that used the data access layers and processing layers directly. The compiled program was distributed to the cluster in the same way as the daily processes.

As far as I know this monstrosity still gets daily use, four years later.

Re: C as an intermediate language (2012)

#22
post #13

If you want to use C as intermediate language, you may be interested in the CIL project[1]. It stands for "C intermediate language"--might be relevant :P. Fundamentally, CIL is a nice subset of C wrapped up into a nicely usable API. The idea is to shave off as many of C's inconsistent sharp edges as possible. You won't have to worry about quirks in the syntax or odd behavior because you have a nice high-level, curate…

I've used CIL (if only for school projects), and I can vouch for it being a joy to use, at least if you like OCaml. Also, their page on wacky C edge cases ("Who says C is simple?", link to frame contents: http://www.cs.berkeley.edu/~necula/cil/cil016.html") is great.

Re: C as an intermediate language (2012)

#23
Some of these aren't as simple as they seem at first glance:

> Dynamic binding: easy enough.

That technique won't be fast enough for dynamic languages. You really need polymorphic inline caches to make dynamic binding fast, which requires careful cooperation between the code generator, the front end, and the IR. A C compiler won't give you that level of control.

> Garbage collection

It doesn't work that well. The problem is that C compilers don't provide a way for the runtime to find all roots on the stack (tell apart integers from pointers). You pretty much either have to be conservative on the stack or spill all roots to the stack across function calls. Neither of them is very good: the former costs accuracy and prevents you from using a bump allocator in the nursery, and the latter costs performance.

There are other issues to consider as well, for example tail call optimization and undefined behavior.

Re: C as an intermediate language (2012)

#24
post #20
post #10

Earlier quoted context omitted.

Wouldn't that be even easier if you used LLVM IR, as you'd then be able to write your runtime in any language that LLVM supports?

You lose a lot of things the C compiler does for you by targeting LLVM directly. A big one is debug info. The C compiler will emit debug information for you, and with some line directives, as shown in the article, or maybe scripts, you can get minimally usable source-level debugging without having to generate your own debug info.

LLVM has high-level support for debug info. (You have to actually generate it, which isn't free, but neither is generating #line directives, so it's arguably a wash.)

Re: C as an intermediate language (2012)

#26

Some of these aren't as simple as they seem at first glance: > Dynamic binding: easy enough. That technique won't be fast enough for dynamic languages. You really need polymorphic inline caches to make dynamic binding fast, which requires careful cooperation between the code generator, the front end, and the IR. A C compiler won't give you that level of control. > Garbage collection It doesn't work that well. The pro…

I agree that compiling to C will not give you a great language implementation if you need this type of features; I think the implementation will be good enough for many cases though. To take an extreme example, CPython isn't a bleeding edge Python implementation perhaps, but it's still the most popular and practically relevant one; this is in fact true for many popular dynamic languages, one big exception in recent years being JavaScript.

Languages where a really great implementation might involve C code generation are probably indeed quite static, however. An example is Synopsys's VCS which AFAIK compiles Verilog to C++.

My own hands-on experience with this type of thing is with an in-house HDL and an in-house C dialect with (sizable, static) extensions for accelerator programming.

Re: C as an intermediate language (2012)

#27
post #10
post #3

There's a lot of extra stuff you get with targeting C: being able to write the run time in C very easily. For example its a lot easier to write your entire OO system in C in a few hundred lines, and keeping that easily debuggable is a massive time saver.

Wouldn't that be even easier if you used LLVM IR, as you'd then be able to write your runtime in any language that LLVM supports?

LLVM IR is less portable than C; and even where an LLVM back-end is available (say, x86 Windows machines), it's really nice to be able to compile everything with another compiler (say, VS) and get debug info and browse info in the generated files.

Re: C as an intermediate language (2012)

#28
post #2

For anyone wanting to read about C as intermediate language, Compiler Design in C (1990) http://www.amazon.com/Compiler-Design-C-Prentice-Hall-softwa... EDIT: Adding some extra remarks I think might also be interesting to share. Another approach, that I really like, is to output bytecodes that are mapped directly to macros in typical macro assemblers like NASM/MASM/TASM. Those macro assemblers provide very powerful m…

C: AKA "portable assembler" :-)

TI has a DSP processor where the assembly looks quite much like the early days of C:

    mov reg1, reg2    ==>  reg1 = reg2
    mov reg1, [reg2]  ==>  reg1 = *reg2
    add reg1, reg2    ==>  reg1 += reg2
And so on.
Post reply on HN