<div dir="ltr">The current model is that any variable used by an SEH filter is escaped in the entry block, and any external function that can throw should also be able to write to escaped memory. You can see the call to @llvm.frameescape in the entry block and to @llvm.framerecover in the filter function that implement this.<div><br></div><div>This isn't a very accurate model, and it doesn't lend itself to optimization or program analysis, but it was motivated by the idea that SEH filters are rare and changing LLVM's EH model is expensive. Our assessment of rarity comes from experience in Chromium, however, which may not be representative of other programs. :) SEH is also already an enormous barrier to optimization, so we figured it would be OK if we just don't do a good job optimizing functions with SEH filters.<div><br></div><div>We've been discussing other designs that might avoid the early outlining that prevents precise analysis and optimization, but it's not clear if we've found a winner yet. Part of the problem is that, as you've indicated, filters run in EH phase 1, *before* running cleanups and finally blocks. The current stack-driven EH emission strategy in Clang doesn't really handle that, and even if it could, the CFG would be a complete mess.</div><div><br><div><div><div><div><div class="gmail_extra"><div class="gmail_quote">On Thu, Apr 16, 2015 at 10:05 AM, Joseph Tremoulet <span dir="ltr"><<a href="mailto:jotrem@microsoft.com" target="_blank">jotrem@microsoft.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="#0563C1" vlink="#954F72">
<div>
<p class="MsoNormal">Hi,<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">I have a question about the IR model for SEH filters (as I want to use the same model for CLR filters).  In particular, when an outer filter is invoked before entering an inner finally, which piece of IR reflects the filter's side-effects? 
 To take a concrete example, consider this C code:<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">void foo() {<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  int x;<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  __try {<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">    x = 0;<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">    __try {<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      x = 2;<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      may_throw();<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">    }<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">    __finally {<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      if (x == 1) {<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">        printf("correct\n");<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      }<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      else {<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">        printf("incorrect\n");<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">      }<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">    }<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  }<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  __except (x = 1) {<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  }<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">}<u></u><u></u></span></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">The IR for the path from "x = 2" to the load of x in the __finally (via the exception edge) looks like so:<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  store i32 2, i32* %x, align 4<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  invoke void bitcast (void (...)* @may_throw to void ()*)() #4<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">          to label %invoke.cont unwind label %lpad<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">lpad:                                             ; preds = %entry<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  %1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">          cleanup<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">          catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@foo@@" to i8*)<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  %2 = extractvalue { i8*, i32 } %1, 0<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  store i8* %2, i8** %exn.slot<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  %3 = extractvalue { i8*, i32 } %1, 1<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  store i32 %3, i32* %ehselector.slot<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  store i8 1, i8* %abnormal.termination.slot<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  br label %__finally<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">__finally:                                        ; preds = %lpad, %invoke.cont<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  %0 = load i32, i32* %x, align 4<u></u><u></u></span></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">What I'm wondering is where exactly this models the call to @"\01?filt$0@0@foo@@" and its store to x.  Is it implicitly part of the execution of the landingpad instruction itself?  Or of the invoke?<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Thanks<span><font color="#888888"><u></u><u></u></font></span></p><span><font color="#888888">
<p class="MsoNormal">-Joseph<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
</font></span></div>
</div>

<br>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br></blockquote></div><br></div></div></div></div></div></div></div></div>