 Oh, it should be working. Let's start. So, hi everybody. So, hi everybody. So, I'm the second guy from QuaxLab, and there's a third guy there. So, I'm the only one talking about our real jobs. They all speak about their friend stuff, and I have the best friend stuff. So, as part of our job, we develop an LLVM of skater called Ipena. And we have one problem, and this problem is that we have users. And users want documentation, but we are developers, and we don't want to write documentation. And for the more, we don't want to maintain our documentation. And that's the topic of this talk, how to do the minimal stuff so that users have their documentation, and we don't write it or maintain it too much. Because there is very low support for documentation of passes in LLVM. If you ask for the documentation of jump-threading, because you don't know what this is, you can go through the help, and jump-threading is jump-threading. So, it doesn't help much. But well, we all know that the good way is to go through the code, and then read the commands, and then you know what is jump-threading, and maybe you can use it the proper way. So, our problem is that in our Opskator, we have the Opskation from LLVM byte code to LLVM byte code, and we have this user directory. So, the user can control how the compiler behaves. So, he needs to know what every pass does. So, our pass is our Opskation pass, but it's globally the same as any compiler optimization. And so, I hope you document that, because the user is not an expert in compilation, but he needs to have an int. Because there are three ways for him to control the compiler. Either he uses good hold compiler flags, but generally speaking, it's not a good way to control an Opskation, because if you say transform all constants in my code into something that is more difficult to understand, then you hand up with very large code, and it's not performance-wise a good thing. So, you can use directives. So, you say, okay, we're going to Opskate this very function with this very Opskation, and this is some parameter. And then this constant will be Opskated using the heavy mode, which regenerates more code. I think you can also write a schedule file, because it doesn't want to touch its file. So, everything is put into a separate file, and then it's globally the same. There's a very same options, and you will apply this pass, then this pass on this function, and this pass on this function. So, you have three ways to control the compiler. The problem is that, how is everything consistent, and how is everything documented without too much effort? We have one file. This file is located in the same directory as the pass, and it describes a lot of things about the pass. So, it's not like the oxygen which tries to document things. From that, we will generate various piece of information that will be used either by the super-space code or by the documentation, so that everything is consistent. So, the level is like module pass, function pass, basic block pass. Block annotable means, can you use it as a plasma on just an instruction or block of instruction, even if it's a function pass? The compile time overhead. From our measurement, when you use that, your compilation time is going to be multiplied by this factor, which is a big factor, but still. This is a textual description, and then you have all the options. This will be forwarded to CL, LIVM CL, but LIVM CL, it's global variables, which is very surprising to me, but still, that's the way it is, and it doesn't play as well with our directories, because we want passes to be parametric, to be able to instantiate different passes with different options. So, we have some wrapper to do that. We describe them or whatever. And we also have these classifiers, because for random users, you don't know about opaque constants, but it knows that it's a data obfuscation. So, when digging through his program, you know, okay, this is the pass I can use to escape my data. And it turns out that this pass supports any targets, which is not the case for old passes, things about anti-debug tools or things like that. So, from that file, you have the description. You generate some header files. So, your actual LIVM implementation will derive from that, and it will get access to options, to good pass level and several stuff. We also generate the documentation that will be forwarded to Sphinx for user documentation generation. We also generate part of these classifiers, which is a big table that summarizes everything. And we also generate parameters for our test suite, so that we can test that the documentation is actually correct. And from this, we can access to generate wrappers to CL to the pass manager code and the actual class. So, everything is generated from one file. So, that brings us back to literate programming, where you have the code and the documentation, and both are used to generate the whole tool, which consists in the documentation and the program, and we have something very similar to that. So, there are several benefits of using this approach. First, everything is always synchronized, the documentation, the code, the directive, the pass schedule, or the documentation you can get from the command line to the documentation you get from the documentation, everything is synchronized. So, once it's written, you don't need to maintain it anymore. And nothing happens like you change the code, but you forget to change the documentation because the code is generated from the documentation. So, this kind of step backward, which is really a pain, does not happen. Another thing is you need to support something else. As everything is generated from one script from all this description, you can retarget it easily instead of changing the code for every pass. So, that's very cool because we write less doc, which gives time to my teammates to write their funny tools instead of maintaining the documentation. And just to, this is the kind of documentation we generate. So, although it's generated documentation, there's actual interesting stuff here, code examples that explain how it behaves. And all this stuff here are automatically generated from the description. And it turns out that even us, we sometimes go to the documentation, copy that and paste it because that's what we want to do. And that's how the documentation is often used. That's all. If you have an equation, please feel free to write it against time.