Live data from Hacker News

Gollvm from Google

go.googlesource.com

11–20 of 51 posts

Re: Gollvm from Google

#11
post #5

So question for llvm devs here: what benefit does this provide? How does it enhance go? Does it make go programs compile into more efficient binaries targeted to specific cpu architectures?

A big problem intermediate code solves is that, you don't need a big monolithic compiler for both front-end language parsing and back-end architecture instructions. They call it MxN problem, so instead of MxN combinations of architectures and languages in a monolithic compiler - you get M+N components where M handle the language parsing etc.. while N handle the conversion from the single intermediate language/instructions to the target architecture's instructions.

Re: Gollvm from Google

#12
post #7

"At the moment llvm-goparse is not capable of building the Go libraries + runtime (libgo), which makes it difficult/unwieldy to use for running actual Go programs. As an interim workaround, I've written a shim/wrapper script that allows you to use llvm-goparse in combination with an existing GCCGO installation, using gccgo for the runtime/libraries and the linking step, but llvm-goparse for any compilation." Not sure…

go-llvm/llvm appears to be a set of Go bindings to LLVM, i.e., the ability to access libllvm (embed LLVM and use it programatically) from a normal Go program. That is, you're using Go to drive LLVM, not LLVM to compile Go.

See the factorial example, where they build up some LLVM IR (in memory) for computing factorials: https://github.com/go-llvm/llvm/blob/master/examples/factori...

I'd guess the advantage of this is using LLVM's JIT at runtime.

Re: Gollvm from Google

#13
post #9

> define hidden i64 @foo.bar() { > entry: > %"$ret0" = alloca i64 > store i64 0, i64* %"$ret0" > store i64 1, i64* %"$ret0" > %"$ret0.ld.0" = load i64, i64* %"$ret0" > ret i64 %"$ret0.ld.0" > } Can someone knowledgeable with Go, explain what's happening here? Why does it store a 0 and then a 1 in "$ret0"? Why does it allocate a single integer on the stack? (is it because this is just intermediate code for a virtual m…

> Why does it store a 0

Go language semantics define that variables receive a zero initialization.[0]

> and then a 1 in "$ret0"?

The 1 is because the code explicitly stores a 1 :-).

Clearly the output code has not been through an optimization pass.

[0]: https://gobyexample.com/variables

Re: Gollvm from Google

#14
post #9

> define hidden i64 @foo.bar() { > entry: > %"$ret0" = alloca i64 > store i64 0, i64* %"$ret0" > store i64 1, i64* %"$ret0" > %"$ret0.ld.0" = load i64, i64* %"$ret0" > ret i64 %"$ret0.ld.0" > } Can someone knowledgeable with Go, explain what's happening here? Why does it store a 0 and then a 1 in "$ret0"? Why does it allocate a single integer on the stack? (is it because this is just intermediate code for a virtual m…

Why zero first, that's already been explained. Why alloca from the stack: this is because there is a pass in LLVM which converts alloca locations into SSA form[1], and SSA is what many of the other optimizations in LLVM are built around. The rules around SSA mean that variables are renamed rather than modified (every assignment is final, except for phi nodes where control flow merges), so producing SSA output from an imperative language is a bit more difficult. Since LLVM comes with something that converts mutable stack allocations into SSA, it's easier to just leverage it.

The pass is called mem2reg:

http://llvm.org/docs/Passes.html#mem2reg-promote-memory-to-r...

[1] https://en.wikipedia.org/wiki/Static_single_assignment_form

Re: Gollvm from Google

#15
post #11
post #5

So question for llvm devs here: what benefit does this provide? How does it enhance go? Does it make go programs compile into more efficient binaries targeted to specific cpu architectures?

A big problem intermediate code solves is that, you don't need a big monolithic compiler for both front-end language parsing and back-end architecture instructions. They call it MxN problem, so instead of MxN combinations of architectures and languages in a monolithic compiler - you get M+N components where M handle the language parsing etc.. while N handle the conversion from the single intermediate language/instruc…

Go already has its own intermediate representation to solve this problem, so this project must solve some other problem.

Re: Gollvm from Google

#16
post #15
post #11

Earlier quoted context omitted.

A big problem intermediate code solves is that, you don't need a big monolithic compiler for both front-end language parsing and back-end architecture instructions. They call it MxN problem, so instead of MxN combinations of architectures and languages in a monolithic compiler - you get M+N components where M handle the language parsing etc.. while N handle the conversion from the single intermediate language/instruc…

Go already has its own intermediate representation to solve this problem, so this project must solve some other problem.

Better optimizations? AFAIR, the go compiler does some optimizations, but it does not bend over backwards, exactly. Maybe hooking up to llvm can help with that, if it is a goal. (Mmmh, does LLVM optmize at all, or does it just provide a framework for people trying to build optimizing compilers? I don't really know.)

Also, llvm by now reaches far more platforms than the current go compiler. I think that this is the most likely explanation.

Re: Gollvm from Google

#17
post #16
post #15

Earlier quoted context omitted.

Go already has its own intermediate representation to solve this problem, so this project must solve some other problem.

Better optimizations? AFAIR, the go compiler does some optimizations, but it does not bend over backwards, exactly. Maybe hooking up to llvm can help with that, if it is a goal. (Mmmh, does LLVM optmize at all, or does it just provide a framework for people trying to build optimizing compilers? I don't really know.) Also, llvm by now reaches far more platforms than the current go compiler. I think that this is the mo…

But gccgo already exists, and provides an optimizing compiler backend and extended platform support. And the tools in LLVM's ecosystem seem largely useless to Go (no need for asan et al when you have a GC, and no need for tsan when Go already has an optional race detector). Other than the compiler itself having a permissive license, I see no urgent impetus for an LLVM backend for Go, which likely explains why it's taking so long coming.

Re: Gollvm from Google

#19
post #18

I am somewhat confused by this. The LLVM project already has an official Go frontend that lowers to LLVM IR: * https://llvm.org/svn/llvm-project/llgo/trunk/README.TXT

Does Google think they can do a better job?

Re: Gollvm from Google

#20
post #19
post #18

I am somewhat confused by this. The LLVM project already has an official Go frontend that lowers to LLVM IR: * https://llvm.org/svn/llvm-project/llgo/trunk/README.TXT

Does Google think they can do a better job?

I don't really know, but I would be suprised if that is the intent of the project because:

  1. The maintainer of llgo is a Google employee (and a very talented LLVM engineer).

  2. I don't imagine there would be tremendous differences in the strategies used to generate LLVM IR between the tools.  ISTM, if there are deficiencies in llgo, then it would be better to fix them rather than creating a whole new tool.
Post reply on HN