<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, May 15, 2015 at 5:27 PM, Kaylor, Andrew <span dir="ltr"><<a href="mailto:andrew.kaylor@intel.com" target="_blank">andrew.kaylor@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div lang="EN-US" link="blue" vlink="purple">
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">I like the way this sorts out with regard to funclet code generation. It feels very natural for Windows EH, though obviously not as natural for non-Windows
targets and I think it is likely to block some optimizations that are currently possible with those targets.</span></p></div></div></blockquote><div><br></div><div>Right, it will block some of today's optimizations by default. I'm OK with this because we can add those optimizations back by checking if the personality is Itanium-family (sjlj, arm, or dwarf), and optimizing EH codepaths is not usually performance critical.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">> If the unwind label is missing, then control leaves the function after the EH action is completed. If a function is inlined, EH blocks with missing unwind
labels are wired up to the unwind label used by the inlined call site.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Is this saying that a “missing” unwind label corresponds to telling the runtime to continue the search at the next frame?</span></p></div></blockquote><div><br></div><div>Yep. For the C++ data structure it would simply be a missing or null operand.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Your example looks wrong in this regard, unless I’m misunderstanding it. It looks like any exceptions that aren’t caught in that function will lead to a terminate
call.</span></p></div></blockquote><div><br></div><div>Well, those are the intended semantics of noexcept, unless I'm mistaken. And the inliner *should* wire up the unwind edge of the terminateblock to the unwind edge of the inlined invoke instruction, because it's natural to lower terminateblock to a catch-all plus termination call block. I wanted to express that as data, though, so that in the common case that the noexcept function is not inlined, we can simply flip the "noexcept" bit in the EH info. There's a similar optimization we can do for Itanium that we miss today.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple"><div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">> Invokes that are reached after a catchblock without following any unwind edges must transitively unwind to the first catchend block that the catchblock unwinds
to.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">I’m not sure I understand this correctly. In particular, I’m confused about the roles of resume and catchend.</span></p></div></div></blockquote><div><br></div><div>catchendblock is really there to support figuring out which calls were inside the catch scope. resume has two roles: moving to the next EH action after a cleanup, and transitioning from the catch block back to normal control flow. Some of my coworkers said it should be split into two instructions for each purpose, and I could go either way.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">> %val = cleanupblock <valty> unwind label %nextaction<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Why isn’t this a terminator? It seems like it performs the same sort of role as catchblock, except presumably it is always entered. I suppose that’s probably
the answer to my question, but it strikes me as an ambiguity in the scheme. The catchblock instruction is more or less a conditional branch whereas the cleanupblock is more like a label with a hint as to an unconditional branch that will happen later. And
I guess that’s another thing that bothers me -- a resume instruction at the end of a catch implementation means something subtly different than a resume instruction at the end of a cleanup implementation.</span></p></div></blockquote><div><br></div><div>Yeah, reusing the resume instruction for both these things might not be good. I liked not having to add more terminator instructions, though. I think most optimizations will not care about the differences between the two kinds of resume. For CFG formation purposes, it either has one successor or none, and that's enough for most users. </div><div><br></div><div>I felt that cleanupblock should not be a terminator because it keeps the IR more concise. The smaller an IR construct is, the more people seem to understand it, so I tried to go with that.</div></div></div></div>