<html><head></head><body dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_quote"><div class=""><br class=""></div><div class=""> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class=""><div dir="ltr" class=""><div dir="ltr" class=""><div class=""></div><div class="">> <span style="white-space: pre-wrap;" class="">In contrast, the machine function splitter extracts cold code into a </span><span style="white-space: pre-wrap;" class="">separate section. </span></div><div class="">HCS also adds a section prefix to all the cold functions. It is possible that the cold functions are still in the same section as the hot one depending on the linker. Ruijie has a patch to move all the cold functions to a separate section, we are still evaluating the results (<a href="https://github.com/ruijiefang/llvm-hcs/commit/4966997e135050c99b4adc0aa971242af99ba832" target="_blank" class="">https://github.com/ruijiefang/llvm-hcs/commit/4966997e135050c99b4adc0aa971242af99ba832</a>). In case it is not difficult to rerun the experiments, it'll help to see the numbers with the llvm-trunk and this patch from @rjf.</div><div class=""><br class=""></div><div class="">> <span style="white-space: pre-wrap;" class="">Furthermore, this may not play well with</span><span style="white-space: pre-wrap;" class=""> optimization passes such as MachineOutliner.</span></div><div class=""><span style="white-space: pre-wrap;" class="">Can you share an example where HCS and Machine Outliner don't play well together?</span></div></div></div></div></blockquote><div class=""><br class=""></div><div class="gmail_default" style="font-family: monospace; font-size: small;">One thing I can think of is that Machine Outliner is based on code pattern, while HCS also looks at hotness. The inconsistency can lead to missing opportunities in machine outliner ?</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class=""><div dir="ltr" class=""><div dir="ltr" class=""><div class=""><span style="white-space: pre-wrap;" class=""><br class=""></span></div></div></div></div></blockquote></div></div></div></blockquote></div><div class=""><br class=""></div><div class="">Just chiming in about the outliner stuff. (In general, I think it's desirable to have multiple options for how early/late a pass runs.)</div><div class=""><br class=""></div><div class="">From what I understand, HCS actually tries to leverage the MachineOutliner (and other size optimizations) by marking cold regions as minsize. (Commit: 03aaa3e2aa37b311999c6af567871325c2fa049f) This is the case at least in AArch64, where the MachineOutliner is a default minsize optimization.</div><div class=""><br class=""></div><div class="">The only missed opportunity I can think of here is something like the following pseudocode:</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">hot_func_1:</div><div class="">  ..</div><div class="">  I1</div><div class="">  I2</div><div class="">  ...</div><div class="">  IN</div><div class="">  ret</div><div class=""><br class=""></div><div class=""><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">hot_func_2:</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">  ..</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">  I1</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">  I2</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">  ...</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">  IN</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">  ret</div></div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><br class=""></div><div class=""><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">cold_func:</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">  ..</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">  I1</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">  I2</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">  ...</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">  IN</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">  ret</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">Let's say that on this target, we can outline tail calls, and that tail calls don't incur any execution time cost. In this case, we probably <i class="">do </i>want the following pseudo-assembly after hot-cold splitting:</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">hot_func_1:</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">  ...</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">  tail_call OUTLINED_FUNCTION_N</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><div class="">hot_func_2:</div><div class="">  ...</div><div class="">  tail_call OUTLINED_FUNCTION_N</div></div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><div class="">cold_func:</div><div class="">  ...</div><div class="">  tail_call OUTLINED_FUNCTION_N</div></div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">Since HCS will only give cold_func the minsize attribute, this can't happen. However, this isn't really a matter of where you run HCS. This is more that the MachineOutliner doesn't have a way to recognize that certain outlining styles are cheaper than others.</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">Also +Vedant who's thought about how HCS + the MachineOutliner interact.</div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">- Jessica</div></div></div></body></html>