The other comments get the general idea, but here's a slightly more detailed explanation.
Code generation backends in the Zig compiler work by lowering an SSA-like structured IR called AIR to machine code (or actually first to another intermediate data structure called MIR, but don't worry about that). The thing is, AIR is intentionally quite high-level, the intention being that the code emitting AIR (which is complex and difficult to parallelize) doesn't have to waste loads of valuable single-threaded time turning e.g. a single line of Zig code into tens or hundreds of instructions.
However, this approach sort of just moves this work of "expanding" these high-level operations into low-level instructions, from the code producing AIR, into the codegen backend. That's good for compiler performance (and also actually for avoiding spaghetti in the compiler :P), but it makes it much more difficult to write backends, because you need to implement much more complex lowerings, and for a much greater number of operations.
To solve this problem, `Legalize` is a new system we've introduced to the compiler which effectively performs "rewrites" on AIR. The idea is that if a codegen backend doesn't want to support a certain high-level operation, it can set a flag which tells `Legalize` that before sending the AIR to codegen, it should rewrite all occurences of that instruction to a longer string of simpler instructions. This could hugely simplify the task of writing a backend; we don't have that many legalizations implemented right now, but they could, for instance, convert arithmetic on large integer types (e.g. u256) into multiple operations on a "native" integer size (e.g. u64), significantly decreasing the number of integer sizes which you need to handle in order to get a functional backend. The resulting implementation might not emit as efficient machine code as it otherwise should (generally speaking, manually implementing "expansions" like the one I just mentioned in the backend rather than in `Legalize` will lead to better code because the backend can sort of "plan ahead" better), but you can implement it with way less work. Then, if you want, you can gradually extend the list of operations which the backend actually supports directly lowering, and just turn off the corresponding legalizations; so everything works before and after, but you get better code (and possibly slightly faster compilation) from implementing the operation "directly".
Every few years I look into D and read it and think it's really good and want to write something in it. But then I come across comments on HN that make me feel like it's not good enough compared to something like C++ or Rust. I know I should ignore those, and I do like having a GC, so D seems like maybe a better Go. But one thing I always put ahead of everything else is developer convenience, for example, autocompletion and hover-docs in VS Code. I assume D has these, but I also assume that it's not as well supported as it is in Rust, mostly thanks to some sort of principle that probably has a name by now, where the more hype a language has, the more support its entire ecosystem has, regardless of whether it's a good language or not. Kind of like how writing TypeScript for the web is now amazing to work with, being a zeroeth-class citizen in VS Code (soon to be lowered to first-class after the Go rewrite), simply because JavaScript is the only native language the web speaks. Anyway, if D has wrapper libs for SDL3 and V8, decent docs, works well on both Win&Mac, and has good enough VS Code support, I'd be glad to give it a shot.
afaict its a new pass that transforms Air generated from Sema into Air understood by a particular backend, since theyre not all at the same level of maturity
Sorry, what?