But LLVM already has a lot of good backends (emscripten, arm, ppc, x86, amd64). Why reinvent the wheel when you could just make Go a LLVM frontend and be done with it?
There can be a compile time hit, but you can use FastISel, which is not bad. The compile time hit is mitigated by the fact that you get a far, far more mature series of optimization passes. Since the Go compiler is itself written in Go, more optimizations would make the Go compiler itself faster, further reducing the performance impact.
> Flexibility over the backend ?
Writing to LLVM in no way restricts you to a backend. You simply need a language-level IR that you can retarget to different backends as you would like. This is what Swift, for example, is doing with SIL.
> Writing to LLVM in no way restricts you to a backend. You simply need a language-level IR that you can retarget to different backends as you would like.
It still ignores toolchain flexibility. Especially given the specific needs of Go's managed runtime.
It's mostly because the Go compiler was developed out of the plan9 compiler code base, which is unrelated to llvm.
The other aspect is that the Go compiler is intended to be very fast. That's not an explicit design goal of llvm - using llvm would slow the compiler down although it would have other advantages.
I wrote the arm64 and sparc64 Go backends because it was easy. If I were to have retargeted LLVM, I wouldn't even have finished the first one, and I would have hated my life.
In the meantime, Go still supports more hardware ISAs than LLVM. Apparently reinventing the wheel is much cheaper than adding wheels to the old car.
[0] https://golang.org/doc/install/gccgo