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 fold them up, so consider The above. If y₁ resolves to true, then we know that X₃ == X₁, and we can fold up that all up. Or if we have a case like

X₁ = dependency('', required : false)
Y₁ = X₁
Z₁ = Y₁

We know that Z₁ is actually X₁ and can fold that up.

Then we can propagate out variables into their uses as well,

X₁ = 7
Y₁ = 9 
Z₁ = [X₁, Y₁]

In this case we can propagate the values of X₁ and Y₁ into Z₁, and eliminate them. This works really well for Meson, which is mostly immutable objects with shadowing. What remains is copy on assignment, like `configuration_data`.

Now that that is (mostly) in place we start reducing the instructions in our IR, and combining them. This is particularly important for making things like linking work. After all, most targets are in fact defined in the form like

lib = static_library(...)
main = executable(..., link_with : lib)

In this case, we need to be able to put lib into the main executable, which you can see we can now solve.

Build Targets and Include Directories

Now that we have phi nodes, const folding, and const propagation, it's possible to start linking things. Which is now possible. I only have executables and static libraries currently, but I've done some cleanups using templates to simplify code sharing between them. And c++17's constexpr comes to the rescue here.

This allows us to write awesome code like
template <typename T>
T build_target(const Object & obj) {
  if constexpr (std::is_same<T, Executable>::value) {
    ...
  } else {
    ...
  }
}

And the c++ compiler will resolve that conditional at compile time. This makes it much easier to specialize templates for specific cases while sharing the majority of the code that's the same. This is especially true for cases like meson's build targets, where they're mostly the same, but with small differences between them.

I've also added support for include_directories, so now you can have headers. Because those are useful.

Messages, Warnings, and Errors

Also, present now are support for message, warn, and error, though only if using string values or arrays of strings. There's more work to specialize the flattening pass to not act on message functions, but that's a down the road kind of problem.

What's next?

I'm working on find_program, getting method calls actually working, and assert. Stay tuned for the next irregular installment of this "This Weekend in Meson++"

Comments

Popular posts from this blog

This Weekend in Meson++ (February 6th)

Introducing Meson++

Rust in Meson — 0.57 Edition