Live data from Hacker News

Jank now has its own custom IR

jank-lang.org

31–40 of 57 posts

Re: Jank now has its own custom IR

#31

Earlier quoted context omitted.

MLIR dialects have to be lowered into the basic LLVM one eventually, don't they? Does MLIR add anything over a custom IR for host languages that aren't deficient at manipulating data structures?

'MLIR dialects' is just a term for teaching MLIR how to manipulate and understand your own custom IR. MLIR is just very good at producing good vectorized code in the presence of stuff like nested loops compared to LLVM or even some of the most carefully crafted custom compilers. It's not about whether your custom compiler is 'deficient' at handling data structures, MLIR is just genuinely very good at some of this stu…

But AFAIK those aren't features of MLIR, but of lowering to existing MLIR dialects and running their passes. My genuine question is whether these passes provide any benefit before lowering, because otherwise a custom dialect doesn't add anything over lowering from a custom IR for anyone not using C++; and the only example I've seen is forced inlining.

Re: Jank now has its own custom IR

#32
post #29

Earlier quoted context omitted.

Julia actually has some really cool machinery for handling this that I would encourage other JIT languages to copy. Whenever you call a function, that function and any calls in that call stack occur in a 'fixed world age'. Within a given world-age, method tables and global constants are all fixed, and the langauge can be analyzed like it's statically typed (there are escape hatches like `invoke_in_world`, and `invoke…

That is very cool indeed. Are there limitations that this imposes? Is Julia a whole world compiler or does it support partial compilation?

There's two main limitations:

1. If you try and re-define a global constant or add new methods inside a running program using `eval` or whatever, then your running program won't see those changes until it advances the world-age (i.e. either by using `invokelatest`, or by returning to the top-level scope). Note though that things like closures and defining functions within functions is fine, you just can't do an arbitrary `eval` to define something completely dynamially

2. Method invalidations can cause a lot of compilation latency. If you load a package that invalidates a bunch of already compiled methods, then those methods will later need to be recompiled, which means you hit some more compiler latency than expected. These invalidations can have false postives too, so sometimes more methods get invalidated than you'd want

__________________________

> Is Julia a whole world compiler or does it support partial compilation?

On the LLVM side, we only do partial compilation. Every function method specialization in each different world (modulo inlining) is its own LLVM module that gets compiled in parallel by LLVM. Non-inlined function calls then involve linking these modules.

On the julia-side with our own custom internal IRs though, that's where we perform whole-world style interproceedural optimizations and inlining before handing the individual compilation units to LLVM. At least if I'm using "whole world" right here. What I mean is essentially everything statically known to be reachable from a compilation unit's entry-point given its signature. If by "whole world" you mean compiling every possible method signature, that's not possible in julia at all, because the space of possible method specializations is infinite due to parametric types.

We generally get the best of both worlds with these two approaches (at the cost of just using a lot of space to store all the different possible specializations and all of our differnt IRs and different pieces of machinery).

Re: Jank now has its own custom IR

#33

Probably a stupid question, but is LLVM better at optimising its IR than C compilers are at optimising C? Asked another way, why not use C as an IR, if it's compatible with your language semantics?

C is a really bad IR for a lot of reasons. it has incrediby opinionated semantics (e.g. the huge amount of UB and platform specific behavior). LLVM is a lot more verbose, but allows you to actually pick the semantics you want.

Re: Jank now has its own custom IR

#36
post #22

Earlier quoted context omitted.

These compilers aren't replacing LLVM, they are adding a compilation step with its own IR where they do certain optimizations and translations *before* handing things off to LLVM. Basically, the idea is to do as much 'high level' optimization and transformation stuff as you can in your own IR, and then let LLVM handle the low-level stuff and the targeting of specific hardware vendors.

That makes sense, thanks. Is this IR at a level where the optimisations can't just be added to LLVM then?

one example of this is type inference. llvm is a statically typed ir, so if you're compiling to it from a language with an expressive type system (dynamically typed or statically typed with generics), you need to do your type inference pre llvm.

Re: Jank now has its own custom IR

#37

> we're using it to optimize jank to compete with the JVM The JVM gets a lot of hate, but that is a very high bar. The JVM is a serious piece of kit. I hope Jank succeeds. I'd love to use it in real projects.

Indeed. Most of the hate is due to slow start-up time, but once it gets warmed up, the modern JVM has state of the art dynamic compilation and GC. Thousands of man years have been spent getting it to that point.

Re: Jank now has its own custom IR

#38
post #22

Earlier quoted context omitted.

These compilers aren't replacing LLVM, they are adding a compilation step with its own IR where they do certain optimizations and translations *before* handing things off to LLVM. Basically, the idea is to do as much 'high level' optimization and transformation stuff as you can in your own IR, and then let LLVM handle the low-level stuff and the targeting of specific hardware vendors.

That makes sense, thanks. Is this IR at a level where the optimisations can't just be added to LLVM then?

In my uninformed opinion it's like the SIMD discussion from yesterday. Without their fancy SIMD library, the optimization [`sqrt(x) * sqrt(x)` === x] gets lost in a sea of C++ template incantations when using that SIMD library.

Similarly, perhaps, if there's some fancy observation of an invariant that can be made about `*.map(...)` that gets "lost in the sauce" once it's been lowered to the typical push/pop/loop mechanisms, then those higher level optimizations are better done in a language specific IR, not the "default" IR.

It's actually IR's all the way down if you think about it...

Re: Jank now has its own custom IR

#39
post #27
post #19

Earlier quoted context omitted.

> the vars are usually compiled to the moral equivalent of a global variable holding a pointer to a function. This allows you to update the function if the developer redefines it in the REPL, but it comes at a performance cost (the JVM can't inline it or otherwise optimise it) might be out of my depth but I find it surprising; I thought compilation through invokedynamic should be able to handle redefinition while sti…

Clojure (AFAIK) does not use invokedynamic, except perhaps in the latest version for some of the new interop stuff. It still officially supports JVM 1.8 bytecode. It’s a language which greatly values stability and backwards compatibility, so it’s been very slow to adopt newer JVM features.

Though there may be other reasons not to use it, invokedynamic is not a new feature of the JVM. If they're targeting 1.8 binary compatibility, they certainly have it at their disposal, since it landed in 1.7.

Re: Jank now has its own custom IR

#40
post #37

> we're using it to optimize jank to compete with the JVM The JVM gets a lot of hate, but that is a very high bar. The JVM is a serious piece of kit. I hope Jank succeeds. I'd love to use it in real projects.

Indeed. Most of the hate is due to slow start-up time, but once it gets warmed up, the modern JVM has state of the art dynamic compilation and GC. Thousands of man years have been spent getting it to that point.

With Project Leyden being implemented and JEP 516 coming very soon, those worries will be a thing of the past. Now you can get incredible AOT performance without having to depend on Babashka or GraalVM workarounds.
Post reply on HN