<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
{mso-style-priority:34;
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman",serif;}
p.msonormal0, li.msonormal0, div.msonormal0
{mso-style-name:msonormal;
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
font-size:12.0pt;
font-family:"Times New Roman",serif;}
span.EmailStyle18
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:#1F497D;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri",sans-serif;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">[speaking to your 2<sup>nd</sup> idea, because the “change dominance” plan doesn’t accommodate “</span>you want to use this exceptional token with more than one
invoke<span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">” without token PHIs]<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">It’s an interesting idea, and some of the ideas we discussed and abandoned were similar to pieces of it. I think my objections to doing this as stated would
be:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">1. The lifetime of the token is no longer the lifetime where you’d want to enregister the pointer that gets relocated, so it moves us away from the goal of explicit
relocate instructions in the first place – putting an alloca up where you’d put the gc.exceptional.token call and putting stores and loads around the EH edge uses IR artifacts in roughly the same places but without introducing new IR constructs.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">2. The “</span>A given exceptional token can be used with exactly one or zero GC statepoint calls<span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">”
part places an awkward constraint on static code duplication (by which I mean something like jump threading, loop unswitching, etc). I suppose we already have a notion of “not duplicatable” that applies to thusly-attributed calls and token defs, so code-wise
it wouldn’t be invasive to represent that constraint, but it feels like an unnatural constraint.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">3. You’re right about “</span>you want to use this exceptional token with more than one invoke<span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">”.
We pushed on some similar ideas a bit and realized we were basically working on introducing a back-door way to have token PHIs (that’s arguably exactly what you’ve done, as the uses are correlated with and occur in the predecessor blocks by virtue of appearing
on the terminators, and are wedded to the join point by virtue of the exception edge constraints requiring the landingpad to be the immediate successor of the invoke), which seemed to be an indication that it might not be the best-suited abstraction for the
job.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">4. With unsplittable catchswitches in the mix, the invoke : splittable pad relation is many : many. I’d rather have one gc.relocate per relocated value after
each catchpad, and I think this is going in the direction of requiring (token PHIs or) one gc.relocate per relocated value per predecessor invoke (including transitive predecessors through catchswitches) after each catchpad. Or I guess gc.relocate could be
variadic and just take all the predecessor invokes’ tokens as arguments, but that still seems like more IR than should be needed.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">Thanks<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">-Joseph<o:p></o:p></span></p>
<p class="MsoNormal"><a name="_MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></a></p>
<p class="MsoNormal"><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"> Reid Kleckner [mailto:rnk@google.com]
<br>
<b>Sent:</b> Friday, January 22, 2016 4:39 PM<br>
<b>To:</b> Philip Reames <listmail@philipreames.com><br>
<b>Cc:</b> llvm-dev <llvm-dev@lists.llvm.org>; Joseph Tremoulet <jotrem@microsoft.com>; Manuel Jacob <me@manueljacob.de>; chenli@azulsystems.com; Sanjoy Das <sanjoy@playingwithpointers.com><br>
<b>Subject:</b> Re: [llvm-dev] FYI: gc relocations on exception path w/RS4GC currently broken<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">So, here's a crazy idea. What if we change the definition of dominance for invokes that produce tokens so that the token return value is live out the exceptional edge?<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">If that's too crazy, what if we used operand bundles to make a new token that "forward declares" the statepoint token:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> %exceptional_token = call token @llvm.gc.exceptional.token()<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> %normal_token = invoke @llvm.gc.experimental.statepoint(....) [ "eh_token" token %exceptional_token ]<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> to label %normal_dest unwind label %lpad_dest<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">...<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">lpad_dest:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> %ehvals = { i8*, i32 } landingpad ... like usual<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> %p1 = @llvm.gc.relocate(token %exceptional_token)<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">A given exceptional token can be used with exactly one or zero GC statepoint calls, so a late pass can map from one to the other and insert reloads in the usual way.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">That said, I imagine you want to use this exceptional token with more than one invoke, so that you don't end up needing a landingpad per potentially throwing call site. I think this design can be extended to handle that, though.<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">On Fri, Jan 22, 2016 at 12:35 PM, Philip Reames via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<o:p></o:p></p>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">For anyone following along on ToT using the gc.statepoint mechanism, you should know that ToT is currently not able to express arbitrary exceptional control flow and relocations along exceptional edges. This is a direct result of moving
the gc.statepoint representation to using a token type landingpad. Essentially, we have a design inconsistency where we expect to be able to "resume" a phi of arbitrary landing pads, but we expect relocations to be tied specifically to a particular invoke.<br>
<br>
Chen, Joseph, and I have spent some time talking about how to resolve this. All of the schemes we've come up with representing relocations using gc.relocates on the exceptional path require either a change to how we define an invoke instruction (something
we'd really like to avoid) or a new intrinsic with special treatment in the optimizer so that it basically "becomes part of" the landing pad without actually being the landing pad. None of us were particular thrilled by the changes involved.<br>
<br>
Given exceptional paths are nearly by definition cold, we're currently exploring another option. We're considering having RS4GC insert explicit spill slots at the IR level (via allocas) for values live along exceptional paths, and leaving all of the normal
path values represented as gc.relocates. This avoids the need for another IR extension, makes it slightly easier to meet an ABI requirement Joseph has, and provides a better platform for lowering experimentation. Joseph is working on implementing this and
will probably have something up for review next week or the week after. Once that's in, we're going to run some performance experiments to see if it's a viable lowering strategy even without Joseph's particular ABI requirement, and if so, make that the standard
way of representing relocations on exceptional edges.<br>
<br>
Assuming this approach works, we're going to defer solving the problem of how to cleanly represent explicit relocations along the exceptional path until a later point in time. In particular, the value of the explicit relocations comes mainly from being able
to lower them efficiently to register uses. Since the work to integrate relocations with the register allocator hasn't happened and doesn't look like it's going to happen in the near term (*), this seems like a reasonable compromise.<br>
<br>
Philip<br>
<br>
(*) To give some context on this, it turns out one of our initial starting assumptions was wrong in practice. We expected the quality of lowering for the gc arguments at statepoint/safepoint to be very important for overall code quality. While this may some
day become true, we've found that whenever we encounter a hot safepoint, the problem is usually that we didn't inline appropriately. As a result, we've ended up fixing (out of tree) inlining or devirtualization bugs rather than working on the lowering itself.
For us, a truly hot megamorphic call site has turned out to be a very rare beast. Worth noting is that this is only true because we're a high tier JIT with good profiling information. It's likely that other users who don't have the same design point may
find the lowering far more problematic; in fact, we have some evidence this may already be true.<br>
<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2flists.llvm.org%2fcgi-bin%2fmailman%2flistinfo%2fllvm-dev&data=01%7c01%7cjotrem%40microsoft.com%7cad0c71085d7448cbe9fb08d32374656b%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=uhqlKuPQz2JzEdsp%2by%2fggD8x9i5AembWF4xQ8aUzr38%3d" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><o:p></o:p></p>
</blockquote>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</body>
</html>