Firm: a C library with graph-based IR suitable for compilers
pp.ipd.kit.edu
pp.ipd.kit.edu
static float b5[0][0] = {};
int main(void)
{
return 0;
}
I have filed a bug report.In ISO C99, they're only permitted as the last member of a struct with another member, and are written with an empty pair of brackets[] and no 0.
1. Exceptions. There are several ways to implement exceptions: stack walking or stack cutting.
2. Calling conventions. A language might want to use internally a different calling convention than the one dictated by the ABI.
3. Garbage collection. This requires interaction with the runtime system which must know which values are pointers into the heap.
4. Tail call optimization.
There are probably other modern language features that require support from the code generator. Could you comment on how the design of the code generator (in rough sketches) account for these?
1. How exceptions are to be implemented is dictated by the runtime environment. Support for exceptions in general is currently work in progress.
2. libFirm's register alloctor does not make any restrictions about the calling convention. If you want to have a call, which passes the first and seventh parameter in %esi and %edx, then you can specify that in the intermediate representation and the register allocator will handle that. Of course there is no generic mechanism to export this insanity to the frontend, but the backend itself can generate code for that without problem.
3. There is currently no support for GCs, i.e. we do not readily export information, where pointers are. Though libFirm's type system is strong enough to contain that information, but somebody has to do the work to export this and connect it to a GC. There was not enough interest and too little manpower available to do this so far. For all projects, where a GC is used, we use a Boehm GC.
4. Yes, libFirm has a pass for this. It can even eliminate pseudo-tail calls like 'int fac(int n) { return n == 0 ? 1 : n * fac(n - 1); }'. This is no proper tail call, because the '' is the last operation, which happens (and not the call to fac()). Because '' is associative and commutative, we can still transform this into a loop. And it has many more analyses and transformations: local optimizations (aka "instcombine"), common subexpression elimination, partial redundancy elimination, scalar replacement, reassociation, implicit (due to being dependency-graph based) dead code elimination, Click's combo optimization, bitwise constant information, load-store optimization, control-flow optimization, conditional jump threading, if-conversion, operator strength reduction, division-by-constant optmization, function inlining, register-pressure aware instruction scheduling, block scheduling, belady spiller, SSA-based register allocation and copy coalescing, ...
Firm is well suited for anything natively compiled (Rust, Go, etc). Support for precise garbage collection would be nice. Nobody is working on this atm.
Also there's been a lot of work on the AMD64 backend and for example it is able to run the SPEC benchmarks. The info on the page is just a bit stale. (Note to self: Update the page)