How CPython Uses LLVM to JIT ============================ This document tries to provide a high-level overview of how LLVM is used inside Python, including details of all the optimizations implemented for LLVM-generated Python machine code. This document should be as developer-centric as possible: it should be able to answer questions like, "how does Python determine function hotness" and also "where is that implemented?". Hotness model: finding critical functions ----------------------------------------- TODO: Hotness is currently only measured, not acted on. We use an online model to estimate which functions are most critical to an application's performance. This model is as follows: - Each code object has a hotness level (the co_hotness field). - For each function entry, add 10 to the hotness level. - For each loop backedge, add 1 to the hotness level. - If the hotness level exceeds a given threshold (see ceval.c), compile the code object to machine code via LLVM. This check is done on function-entry and generator re-entry. There several classes of functions we're trying to catch with this model: - Straight-line utility functions (lots of invocations, low running time). - Loop-heavy main functions (few invocations, high running time). - Long-running generators (few invocations, long lifetime). Miscellaneous notes: - JIT compilation is always disabled during startup by temporarily forcing `-j never`. This improves startup time by disabling compilation and feedback collection. Previous models: - Simple call count-based model (10000 calls == hot). This was implemented as an obviously-deficient baseline to be improved upon. - Previously, we didn't check code hotness on generator re-entry, which we changed to catch long-running generators that are called once. Relevant Files: - Python/ceval.c - definition, use of the hotness model.