Of course, there are a few no-brainers that I'd really like to see at some point, that are missing:
This is excellent news. I hoped it would support ARC/ORC given that most of the implementation is done as an AST transformation. But not a big issue, maybe you should skip 1.4 altogether, 1.6 has many internal changes already in preparation for IC and IC could change how nlvm's code base looks like in quite fundamental ways.
My vision is that the frontend produces a set of .rod files (inspired by Java's and .NET's bytecode files) and backends turn the set of .rod files into binary code (via C, C++, LLVM or whatever seems fit).
I hoped it would support ARC/ORC
it's probably not too much work - the biggest issue is the new runtime string - the layout changed so everything that touches strings (and seq I presume) now needs a new implementation - the more string stuff that could move into the std library, the better (ie why is appending an element special-cased/magic in the compiler?). Most of all though, until ARC/ORC is stable enough to use on the Nim compiler itself, it's a bit too much of a moving target to keep up with, timewise, for me - generally, nlvm must implement the cgen bug-for-bug because there's code out there that depends on the bugs as well.
frontend produces a set of .rod files
well, presumably there will be some in-memory represenation. what's difficult in the compiler right now is that even the cgen does semantic and transformation stuff, updating the AST itself, so it's a bit hard to know what "shapes" of AST need to be supported and which AST node kinds appear for the backend to process - it also makes any kind of caching or pre-calculation steps hard - ideally by the time things reach the backend, the AST would be.. immutable-ish.
The other thing is incremental compilation and the VM - right now, the VM is tightly coupled but for something like LLVM it would make a lot of sense to generate IR early for leaf functions and use the LLVM JIT - that would probably save a fair bit of processing and make the nim stage of the compiler a fair bit faster because compile-time stuff can now contribute to the final IR without having to first compile to VM format then compile to backend IR - I imagine there would be some sort of API between the semantic passes and the VM so that either can be used during compilation.
What happens next is that llvm has two kinds of optimizations: function-level and global - the function-level optimizations can easily be run at any point in in the compilation process - put another way, instead of rod files, the most sensible thing for nlvm to store would be llvm ir snippets - not sure if it's possible to make that backend-specific. It doesn't really matter if it's done this way from the start, but it's a nice thought - it would complicate some other things though - in particular it might complicate the cgen, so it might not be a price worth paying - maintaining a single backend is hard enough, end-user code tends to start relying on both bugs and features in there - maintaining multiple middle-layers might simply not be worth whatever gains there might be, unless the Nim compiler is significantly refactored.
... unless the Nim compiler is significantly refactored.
That's what we're doing, but it's a slow process and "hacks" have the annoying tendency to live long. "Nothing is more permanent than a makeshift"...