Posts

This Weekend in Meson++ (December 15th)

 It's been a while since I wrote about Meson++, or even worked on it, but I have made some changes since the last time I posted, and I thought it would be a good idea to write about them. Rewriting How Basic Blocks and Instructions are iterated, twice.  The two biggest changes are tightly coupled, and hard to talk about separately. The rewriting of the Basic Block iteration code and the rewriting of the Global Value Numbering pass (GVN). GVN is a critical piece of an SSA based compiler, it tags every variable read and write with a globally unique number. With this information (and with phi nodes), we can easily simplify the program, and eventually propagate raw values into function calls. Our original block walking code had some issues. Those were correctness, and performance. On the correctness side it had two problems, the first is that it didn't necessarily walk the CFG (Control Flow Graph) such that a blocks predecessors were all visited before it was, despite the fact tha...

This Weekend in Meson++ (February 6th)

 Meson++ is 1 year old! It's strange to think that February 9th, 2021, was the first commit to meson++, and a year later, we have a working flex+bison C++ frontend, an optimizing mid level IR, a file based backend IR, and the ability to generate simple ninja programs! It's a strange and proud feeling.  Anyway, I haven't implemented any sweepingly huge features this week, but we have landed support for `declare_dependency`, an important first step toward real dependencies (like those found by pkg-config). I also implemented a simple optimization for finding unreachable code. In this case, we look for the `error` function, and mark any instructions after that as dead, as well as removing any next block. Currently, there are no other non-returning functions implemented, but eventually `subdir_done()` will also need to be handled (though `subdir_done()` may present other problems for me). I also started implementing some neat argument pack based variant argument extractors. The...

This Weekend in Meson++ (January 31st)

 It's been a busy week(end) for Meson++ this last week, with lots of exciting features landing. We're rushing toward the possibility of self-hosting, which is a very, very exciting milestone for me. Preliminary custom_target support This is one of the biggest features still missing from meson++, and is one of the biggest reasons to use a build system like meson instead of plain makefiles. The support is rather basic, it only includes support for outputs, with inputs not yet working, as well as some of the templatizing parameters (such as @BASENAME@ and @PLAINNAME@ not yet implemented). Those should be smaller, more incremental improvements though, and meson++ itself needs this for flex and bison Splitting the Ninja Backend One of the design issues in meson, is that ninja was the first backend written, and thus a lot of assumptions are made about backends in general. We have to a fair amount of rematerialization in the xcode and vscode backends, because the generic backend is ve...

This Weekend in Meson++ (January 23rd)

 Assert() and unary operations We have assertions, which are super useful for unit tests. There's still a bit of work as we don't print location data (like messages), but it's enough to be useful for testing, which is frankly what assert() is for. Interestingly, with assert() we really need at least the `not` keyword. This wasn't too hard to implement, but turned up some bugs. Basically at the MIR level, we treat everything as control flow or an object. Function calls are objects too. In this case the not keyword is lowered to a not() function, which takes a boolean and returns a boolean. I did uncover a parser bug in the process, which was thankfully easy to fix. I wrote the following code: assert(not x.found(), 'message') The way this is supposed  to be parsed is as assert(not(x.found()), 'message') but it was getting parsed as: assert(not(x).found(), 'message') Which is obviously wrong, and not what we want (thankfully booleans don't have ...

This Weekend in Meson++ (January 15th)

 It's been a while, so this is going to cover more than a weekend, but I've hit some nice milestones, and it's pretty exciting.  Let's talk about phi nodes. I'm not an expert on phi's, but basically they're a way to represent values that change in branched code, without actually computing them. In a way it's a sort of "promise" of a value. if y₁ X₁ = true else X₂ = false endif X₃ = ϕ(X₁, X₃) In this case, until we can resolve Y  we can't know what X  is, it could be true  or false.  The Phi node lets us represent that by creating a new version of X , which is either true or false. Then, when we can prune the branches down to one value of X , we can propagate out the value of X that wasn't erased. This is pretty much the thing that makes SSA possible, and what makes it awesome. This then makes two more important passes really easy, constant folding and constant propagation. The First pass allows us to take variable aliases and ...

This Weekend in Meson++ (October 3rd Edition)

 I thought I might try to write a series of light blog posts on the ongoing status of Meson++, and since I'm mostly working on it in my weekend free time, It's called "This Weekend in Meson++" (I stole this name from Emma Anholt, who called their series on VC4 "This Week in VC4", so thanks Emma). Target Linking Since I've already gotten basic targets working, I've started pushing toward getting linking between targets working, which is more difficult than it sounds. Meson++ uses a flat IR, and relies on IR optimizations to reduce the instruction stream from the Meson DSL into a vector of Targets (and eventually tests), then the backend has the responsibility to convert that stream of Targets into a file that can be consumed by the runner tool (ninja, make, msbuild, etc). This means to take something very simple like: project('foo', 'cpp') lib = static_library('lib, 'lib.cpp') executable('main.cpp', link_with : ...

Introducing Meson++

I've been semi-quietly working on a new project for the last few months on and off, and today I've gotten far enough that I want to talk about it more widely: Meson++ . Meson++ is now capable of compiling very simply projects, if they meet the following criteria:  they use only C++ they don't have any external dependencies they only build executables they don't do any code generation you're okay using ninja you're using clang or gcc This may seem like a lot of restrictions, and it is, but there's a lot of code that has gone into getting to this point. I'd like to thank stackoverflow for answering a lot of questions. Motivation My primary motivation is to solve bootstrapping issues, imagine if python wanted to use Meson, currently that would create a bootstrap loop, where you need an old version of python to run an old version of Meson, etc. Or, imagine you want to build something like your compiler with Meson, now you need to build python bef...