Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Annotate intrinsic calls with inlining decisions.
When using intrinsics, such as `memcpy`, in LLVM IR, the compiler may decide to inline/optimise them during codegen, or leave them as is. This makes mapping a PT trace back to LLVM IR difficult, since we don't know whether to expect a hole in the trace (from the call to the intrinsic) or not. There's two ways to solve this: 1) Remove all optimisations that inline intrinsic 2) annotate intrinsics with metadata so we can identify inlined intrinsics during trace construction (in `JITModBuilder`). The problem with the first approach is that these optimisations are not in a single place and spread out through different optimisation levels and even architectures. This makes them easy to miss, which we will only notice when traces behave in unexpected ways (if we're lucky the trace compiler crashes). We can solve this problem with the second approach. By annotating an intrinsic, we can check during trace construction if it was inlined and behave accordingly. And by annotating an intrisinc in both inlined and not inlined cases, we can check if we've missed an intrinsic (i.e. it has no annotation) and crash the trace compiler. This second solution sounds much better, but comes with a small caveat. It requires a nasty cast from a constant to a non-constant in the codegen part of LLVM. I can picture the horror written in @ltratt's face upon reading this, but here's my reasoning: 1) casting from const to non-const is only UB if the variable is a real `const`, which LLVM IR is not 2) I believe the reason LLVM makes instructions `const` is so they don't accidentally alter the IR during codegen. Adding metadata doesn't semantically change the IR and so has no effect on the codegen. I thus believe the second solution to be the better option, which I have implemented here, starting with the `memcpy` intrinsic.
- Loading branch information