3 ms·
What I talk about when I talk about IRs is the principle of isolated ugliness. A good IR means that the only contract between compiler passes is the IR itself.
by pizlonator 1y ago
What I talk about when I talk about IRs is the principle of isolated ugliness.
A good IR means that the only contract between compiler passes is the IR itself. This means that individual passes might get as ugly as they need to get without affecting other passes. This then means that lots of different folks can write lots of different passes, and then you can glue them together somehow in a pass pipeline and it all works.
LLVM is a great example of this. You can be productive at writing LLVM passes without understanding any of the other passes in LLVM. Maybe you’ll come to understand some of them just because it’s informative and there’s cool stuff to learn. But even then you don’t have to understand the other passes that deeply. Writing a cool new pass that obeys the IR’s laws is not going to break the other passes. You’ll only break the other passes by breaking IR law.
So what makes a good IR is, more than any other single thing, about whether that IR has easy to understand laws and whether those laws are really followed. This allows you to isolate ugliness. Which allows you to have a large team writing lots of passes. And then your compiler can drink the tears of your defeated competitors.
- almostgotcaught 1y ago> A good IR means that the only contract between compiler passes is the IR itself. this is like impossible (or at least np-hard). phase ordering exists and will always exist - SLP vectorizer will dramatically affect passes after it and sometimes even passes before it! > Writing a cool new pass that obeys the IR’s laws is not going to break the other passes. I don't really get how you can fail to obey the IR's laws other than just emitting unparseable IR? alternatively if you like have uses without defs or flip-flopping types, the verifier needs to catch that after the guilty pass and just bail (not put the onus on the subsequent passes to fix). Anyway IMHO (even though no one asked me), IR needs to have enough structure/info that you can quickly reproduce whatever metadata you need for XYZ arbitrary analysis. Meaning it should represent all of the useful/necessary things (don't make me infer non-negativity structurally if I can just annotate) and it should propagate those things across rewrites.
- pizlonator 1y ago> this is like impossible (or at least np-hard). phase ordering exists and will always exist - SLP vectorizer will dramatically affect passes after it and sometimes even passes before it! It's not impossible. SLP vectorizer will affect the performance upside of passes before/after it. It won't affect their correctness. > I don't really get how you can fail to obey the IR's laws other than just emitting unparseable IR? alternatively if you like have uses without defs or flip-flopping types, the verifier needs to catch that after the guilty pass and just bail (not put the onus on the subsequent passes to fix). Lots of compilers - not LLVM IR - have a totally different kind of phase ordering problem than what you are thinking of: if you reorder the phases then the compiler crashes and burns. Some of these compiler are in production, sadly. I've heard some crazy horror stories. And it's all too easy to find yourself in that situation if you're not careful. LLVM IR is an example of being careful.
- almostgotcaught 1y ago> SLP vectorizer will affect the performance upside of passes before/after it. It won't affect their correctness. maybe. it's late so i can't think of a counter-example off the top of my head where someone downstream of SLP somehow took something for granted and then it blew up in their faces. even if it is somehow magically not true for SLP, it's definitely true for other sequences of passes, where subsequent passes depend on prior passes. > if you reorder the phases then the compiler crashes and burns. Some of these compiler are in production, sadly. I've heard some crazy horror stories. And it's all too easy to find yourself in that situation if you're not careful. i mean i have witnessed this in a prod MLIR compiler i have personally worked on - it's exactly what i had in mind above. did it crash because it tried to deref some pointer to some attribute/node/whatever? no that's true - it crashed via llvm::report_fatal_error (or assert) - but it crashed nonetheless.
- pizlonator 1y ago> it's definitely true for other sequences of passes, where subsequent passes depend on prior passes. I don’t think it’s true for optimization passes in llvm and that’s what makes llvm kinda great. I would love to hear of a counter example. But say that you found a counterexample. That would still not be as bad as what happens in a lot of compilers out there where being able to reorder passes (or even run them a second time) is the exception rather than the norm, and our debate would be about whether there exists even a single pair of passes that could be safely reordered.
- tekknolagi 1y agoI like this. Especially the last paragraph. Mind if I quote you and expand?