[PATCH] Work-in-progress omnibus patch for native Windows C++ EH outlining

Andy Kaylor andrew.kaylor at intel.com
Wed Feb 25 16:02:44 PST 2015


REPOSITORY
  rL LLVM

================
Comment at: lib/CodeGen/WinEHPrepare.cpp:1003-1009
@@ +1002,9 @@
+
+// This function parses a landing pad to see if all it does is resume.
+// If so, it would be called from within another landing pad for
+// exception handling, but since it does nothing any invoke that leads
+// to this landing pad can be replaced with a call and an unconditional
+// branch to the normal destination.  Any exceptions that occur within the
+// called function will be handled by the normal runtime exception handling
+// process.
+static bool isLandingPadEmptyResume(const BasicBlock *LPadBB) {
----------------
rnk wrote:
> andrew.w.kaylor wrote:
> > rnk wrote:
> > > Based on the comment, I think SimplifyCFG knows how to do this already. If you run SimplifyCFG() on each landing pad BB, you'll get the same behavior with none of this code.
> > > 
> > > You may need to run some other cleanup utility on the block first, though.
> > I saw the SimplifyResume function in SimplifyCFG.  It wouldn't work as is here because it only handles resumes in the same block as the landing pad instruction.  I considered moving some form of the logic here into SimplifyResume, but I'm not sure it really belongs there.
> > 
> > The case this is meant to handle looks like this:
> > 
> > ```
> > catch14:                                          ; preds = %catch.dispatch11
> >   %exn15 = load i8** %exn.slot
> >   %18 = call i8* @llvm.eh.begincatch(i8* %exn15) #4
> >   %19 = bitcast i8* %18 to float*
> >   %20 = load float* %19, align 4
> >   store float %20, float* %f, align 4
> >   %21 = load float* %f, align 4
> >   invoke void @_Z12handle_floatf(float %21)
> >           to label %invoke.cont17 unwind label %lpad16
> > 
> > lpad16:                                           ; preds = %catch14
> >   %22 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
> >           cleanup
> >   %23 = extractvalue { i8*, i32 } %22, 0
> >   store i8* %23, i8** %exn.slot
> >   %24 = extractvalue { i8*, i32 } %22, 1
> >   store i32 %24, i32* %ehselector.slot
> >   call void @llvm.eh.endcatch() #4
> >   br label %eh.resume
> > 
> > eh.resume:                                        ; preds = %lpad16, %catch.dispatch11
> >   %exn20 = load i8** %exn.slot
> >   %sel21 = load i32* %ehselector.slot
> >   %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn20, 0
> >   %lpad.val22 = insertvalue { i8*, i32 } %lpad.val, i32 %sel21, 1
> >   resume { i8*, i32 } %lpad.val22
> > ```
> > This is the landing pad for an exception inside a catch handler, but in this case the landing pad doesn't do anything except continue the search.  Since that happens automatically, we can just change the invoke in the catch handler to a call.  But there are all kinds of things here that SimplifyResume doesn't know anything about.
> > 
> > There are two things here that make this not a candidate for simplification in SimplifyCFG.  First, the fact that the endcatch call can be eliminated is very Windows specific.  Second, the actual resume block is shared between two landing pads.
> > 
> > Arguably, we could teach SimplifyResume to identify the situations in which llvm.eh.endcatch can be dropped (currently always, but in the future maybe not).  We'd also need to teach it how to consider multiple predecessors and decide which ones it can simplify.
> OK, this is specifically getting rid of unneeded llvm.eh.endcatch EH cleanups. Can we suppress this call to llvm.eh.endcatch in clang when using CxxFrameHandler3, or do we need it to stop outlining? If it doesn't help EH preparation, then it doesn't have much use.
Yeah, I guess you could say this is getting ride of the call to llvm.eh.endcatch since that's the only thing here that isn't scaffolding, but it also gets rid of the landing pad and turns an invoke into a call.  The EH preparation doesn't need any of that.

I'd definitely like to have clang not omit code like this, but I think it still can turn out this way as a result of later optimizations.  For instance, if there's a destructor to be called, clang would need to emit the invoke and cleanup, but if the object being destructed or even just the call to the destructor later gets eliminated then we're back in this situation, so I think WinEHPrepare needs to know how to do this.

http://reviews.llvm.org/D7886

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/






More information about the llvm-commits mailing list