[LLVMdev] Exception filter IR model

Joseph Tremoulet jotrem at microsoft.com
Thu Apr 16 12:27:27 PDT 2015


Got it, thanks.

FWIW, I expect filters to be rare for us, too, and totally agree that outlining them is a sensible way forward.

Thanks,
Joseph

From: Reid Kleckner [mailto:rnk at google.com]
Sent: Thursday, April 16, 2015 1:35 PM
To: Joseph Tremoulet
Cc: LLVM Developers Mailing List
Subject: Re: [LLVMdev] Exception filter IR model

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.

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.

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.

On Thu, Apr 16, 2015 at 10:05 AM, Joseph Tremoulet <jotrem at microsoft.com<mailto:jotrem at microsoft.com>> wrote:
Hi,

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:


void foo() {
  int x;
  __try {
    x = 0;
    __try {
      x = 2;
      may_throw();
    }
    __finally {
      if (x == 1) {
        printf("correct\n");
      }
      else {
        printf("incorrect\n");
      }
    }
  }
  __except (x = 1) {
  }
}



The IR for the path from "x = 2" to the load of x in the __finally (via the exception edge) looks like so:


  store i32 2, i32* %x, align 4
  invoke void bitcast (void (...)* @may_throw to void ()*)() #4
          to label %invoke.cont unwind label %lpad

lpad:                                             ; preds = %entry
  %1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
          cleanup
          catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0 at 0@foo@@" to i8*)
  %2 = extractvalue { i8*, i32 } %1, 0
  store i8* %2, i8** %exn.slot
  %3 = extractvalue { i8*, i32 } %1, 1
  store i32 %3, i32* %ehselector.slot
  store i8 1, i8* %abnormal.termination.slot
  br label %__finally

__finally:                                        ; preds = %lpad, %invoke.cont
  %0 = load i32, i32* %x, align 4



What I'm wondering is where exactly this models the call to @"\01?filt$0 at 0@foo@@" and its store to x.  Is it implicitly part of the execution of the landingpad instruction itself?  Or of the invoke?

Thanks
-Joseph


_______________________________________________
LLVM Developers mailing list
LLVMdev at cs.uiuc.edu<mailto:LLVMdev at cs.uiuc.edu>         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150416/b14a31cf/attachment.html>


More information about the llvm-dev mailing list