<div dir="ltr">Thanks for the information. This has been very useful!<div><br></div><div>Patch points indeed *almost* do what I need. I will try to build a similar solution.</div><div><br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>Self-modifying code for truly zero-overhead (when not enabled) instrumentation is a real thing (look at e.g. DTrace pid provider) but unless the number of instrumentation point is very large (100's of thousands? millions?) or not known beforehand (both are true for DTrace), the cost of a branch will be negligible.</div></div></div></div></blockquote><div><br></div><div>In the use case that I have in mind, there are indeed a large number of instrumentation points. To give a concrete example of what I'd like to achieve, consider Clang's -fsanitize flag. These sanitizers add thousands of little independent bits of code to the program, e.g., memory access checks. Code that is very useful but also slows the program down. I'd like to transform this code into zero-overhead instrumentation that I can enable selectively.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>AFAIK, the cost of a well-predicted, not-taken branch is the same as a nop on every x86 made in the last many years.</div></div></div></div></blockquote><div><br></div><div>I'm still not 100% sure whether the `nop <-> br` conversion is the best approach. I've considered some alternatives:</div><div>- Branches where the condition is a flag in memory. My early experiments were too slow :(</div><div>- Conditional branches along with some other way to control the flags register. I'm afraid of the side effects this might have.</div><div><br></div><div>For now, transforming an `llvm.experimental.patchpoint` into an unconditional branch looks most promising. I just need to figure out how to trick LLVM into laying out basic blocks the right way (and not eliminating those that are unreachable due to not-yet-transformed branches).</div><div><br></div><div>Cheers,</div><div>Jonas</div></div></div>