go2ll
translates Go's
x/tools/go/ssa representation
into LLVM. It's written in pure Go (no linking to LLVM), and emits LLVM
assembly as output.
To implement various runtime functionality, it uses a few libc functions (such
as malloc
for memory allocation), so that it's easy to compile the resulting
bit-code to an ordinary executable you can run with
llc
.
This is the basis of a 30-minute live-coding session showing how to write a program from scratch which translates a simple Go program in this manner. This live-coding session was presented at Go-Sheffield on 7th March 2019.
This is an early release, I have not yet prepared instructions.
Please feel free to poke around. Don't expect anything to work unless you craft it to do so.
go2ll
is a toy project, and as such is only useful for small programs in limited
circumstances (at the moment, itch scratching). You probably want one of these
other projects which have had more manpower invested:
go2ll
. It is also written in Go andgo2ll
.I'm sure there are other similar efforts out there, please file an issue if you think I should add to this list, or modify the description of any of the above projects I will!
So far, strconv.ParseFloat
works, as does computing a SHA1. Both run faster
than equivalent code when compiled with the standard Go compiler.
I have only made a cursory check that my code hasn't been fully optimized away, it's possible that this result is incorrect or not useful.
I would love to partially lift some of the above limitations - in particular enable I/O for some other interesting benchmarks. I'm uncertain if I will get to this.
Benefits:
TODO:
I had a program whose running time was bottlenecked on parsing floating point numbers in a CSV. The question arose in my mind "What if I used C to parse these floats?". So I wrote a micro-benchmark (I know, micro-benchmarking has limitations) parsing floats. I discovered that C was slower than Go(!).
This came as a surprise, because I believe C's optimizers have been in existence longer and make a greater tradeoff towards execution speed at the expense of compilation time. That Go both faster to compile and faster to execute than C is, well, interesting.
Part of the speed difference can be explained with the fact floating point parsing is implemented differently in Go than in C. So I wondered - what if I used a powerful optimizer, such as LLVM's easy-to-use tooling, with Go's floating point implementation?
I didn't want to sit around and re-implement Go's floating point parsing in C, that would be too dull. Especially since I had another idea at my fingertips.
In a previous job I worked on a Go-To-Verilog compiler which used LLVM IR as an intermediate representation. With permission, from scratch, I recreated and extended the frontend for fun.
So, what came of the float parser?