A lit test for the ThinLtoJIT example from D72486. It will only run in builds configured with -DLLVM_BUILD_EXAMPLES=ON (just like the tests for the Kaleidoscope examples).
The ThinLtoJIT example implements "per-module speculation" for lazy loading and compilation of bitcode. Thus, the test is not self-contained in a single module, but comes with a number .ll files in the Inputs subfolder. These files are excluded from test discovery via the local lit config file.
The test uses a workload() function to simulate CPU load. It's used to give the speculator a chance to submit modules, that will likely be executed soon, asynchronously, before execution reaches them. It's supposed to maximize code coverage and NOT a requirement for the test to succeed. I wanted to use a sleep system function first, but I didn't know how to implement it cross-platform in LLVM IR. So, I chose a function that finds the largest prime-factor of the Nth Fibonacci number. It has exponential complexity and can easily be made dependent on the input argc.
The test's call graph looks like this:
sub1() - workload(3) / --> main() -- workload(40) \ \ sub21() - workload(4) \ / sub2() - sub22() - workload(5) \ sub23() - workload(6)
All functions are defined in separate .ll files. The module that contains the main entry point is always loaded synchronously (not via the speculator). The same will happen for sub1, workload and sub2, because execution reaches their caller too soon. It will then be blocked for a bit in workload(40) and the speculator will likely be faster to discover the sub2x modules.
The ThinLtoJIT executable is invoked with -print-stats, which dumps the number of synchronously/asynchronously loaded modules on shutdown. Getting these two lines of output is what the test currently checks. The JITed code itself doesn't print anything.
The input files must be assembled into .bc files, because the ThinLTO bitcode reader is not designed for human-readable .ll files.