On Thu, Sep 17, 2009 at 3:40 AM, Duncan Sands <duncan.sands at math.u-psud.fr> wrote:> Hi Bill, > >> Yeah. The logic will need tweaking for sure. I'm also concerned about the >> _Unwind_resume() call. GCC emits a call site region for it in the exception >> table. We...kind of do that. It looks like it's being included in one of the >> "this is a region which isn't in a try-catch block, but it has a call in it, >> so lets add it to the exception table" areas. > > isn't that exactly how it should be? This is a call that will unwind > out of the function, so C++ requires it to have a call site region just > like any other call that we want to let unwind out of the function. I > don't see why it needs any special logic. If I understood right the > change you want to make is that if a call is known not to unwind then > you want to omit adding a call-site entry if that saves some space in > the call site table, which seems irrelevant to this, or am I missing > something? By the way, LLVM "nounwind" calls are different to GCC no > throw regions IIRC. If an exception is thrown in a GCC no throw region > then it must (C++) result in a call to "terminate". These are not > mapped to "nounwind", instead we create explicit "catch-all" filter > expressions for this (IIRC). In LLVM it is undefined what happens if > a call is marked "nounwind" but nonetheless an exception unwinds out > of it. Thus you can add call-site entries for nounwind calls, > or not add them, as you like - whatever is most convenient (eg: saves > the most space). An interesting optimization which we don't do is to > identify which calls correspond to a "catch-all" filter and not generate > an entry for them in the call-site table (no need to add the filter > either) - this saves space and the C++ runtime knows to handle this > just like if we added the filter explicitly. >There's a miscommunication here. :-) The _Unwind_resume call isn't marked with "nounwind", however it's not called through an "invoke" instruction, only a regular "call" instruction. From what I can see, the only reason it falls within a call site in the exception table is because we're generating call sites for areas of code without "invokes". If I implement my optimization to eliminate these call site entries which don't have "invoke" calls in them, then the _Unwind_resume call won't have an entry into the exception table, and that would be bad. That was all I'm saying here. -bw
Hi Bill,>>> Yeah. The logic will need tweaking for sure. I'm also concerned about the >>> _Unwind_resume() call. GCC emits a call site region for it in the exception >>> table. We...kind of do that. It looks like it's being included in one of the >>> "this is a region which isn't in a try-catch block, but it has a call in it, >>> so lets add it to the exception table" areas. >> isn't that exactly how it should be? This is a call that will unwind >> out of the function, so C++ requires it to have a call site region just >> like any other call that we want to let unwind out of the function. I >> don't see why it needs any special logic. If I understood right the >> change you want to make is that if a call is known not to unwind then >> you want to omit adding a call-site entry if that saves some space in >> the call site table, which seems irrelevant to this, or am I missing >> something? By the way, LLVM "nounwind" calls are different to GCC no >> throw regions IIRC. If an exception is thrown in a GCC no throw region >> then it must (C++) result in a call to "terminate". These are not >> mapped to "nounwind", instead we create explicit "catch-all" filter >> expressions for this (IIRC). In LLVM it is undefined what happens if >> a call is marked "nounwind" but nonetheless an exception unwinds out >> of it. Thus you can add call-site entries for nounwind calls, >> or not add them, as you like - whatever is most convenient (eg: saves >> the most space). An interesting optimization which we don't do is to >> identify which calls correspond to a "catch-all" filter and not generate >> an entry for them in the call-site table (no need to add the filter >> either) - this saves space and the C++ runtime knows to handle this >> just like if we added the filter explicitly. >> > There's a miscommunication here. :-) The _Unwind_resume call isn't > marked with "nounwind", however it's not called through an "invoke" > instruction, only a regular "call" instruction. From what I can see, > the only reason it falls within a call site in the exception table is > because we're generating call sites for areas of code without > "invokes".yes, and that's absolutely the right thing to do! Due to a strange design choice, if a call does *not* have an entry in the call-site table, and the call unwinds, then the runtime calls std::terminate. All calls that may throw (like _Unwind_Resume!) must have an entry in the call-site table. If I implement my optimization to eliminate these call site> entries which don't have "invoke" calls in them, then the > _Unwind_resume call won't have an entry into the exception table, and > that would be bad.As explained above, you can only eliminate call-site entries for nounwind calls. Having a call-site entry has nothing to do with whether a call is an invoke or not, it is to do with whether the call can throw an exception or not. Ciao, Duncan.
On Sep 17, 2009, at 6:03 PM, Duncan Sands wrote:> Hi Bill, > >>>> Yeah. The logic will need tweaking for sure. I'm also concerned >>>> about the >>>> _Unwind_resume() call. GCC emits a call site region for it in the >>>> exception >>>> table. We...kind of do that. It looks like it's being included in >>>> one of the >>>> "this is a region which isn't in a try-catch block, but it has a >>>> call in it, >>>> so lets add it to the exception table" areas. >>> isn't that exactly how it should be? This is a call that will >>> unwind >>> out of the function, so C++ requires it to have a call site region >>> just >>> like any other call that we want to let unwind out of the >>> function. I >>> don't see why it needs any special logic. If I understood right the >>> change you want to make is that if a call is known not to unwind >>> then >>> you want to omit adding a call-site entry if that saves some space >>> in >>> the call site table, which seems irrelevant to this, or am I missing >>> something? By the way, LLVM "nounwind" calls are different to GCC >>> no >>> throw regions IIRC. If an exception is thrown in a GCC no throw >>> region >>> then it must (C++) result in a call to "terminate". These are not >>> mapped to "nounwind", instead we create explicit "catch-all" filter >>> expressions for this (IIRC). In LLVM it is undefined what happens >>> if >>> a call is marked "nounwind" but nonetheless an exception unwinds out >>> of it. Thus you can add call-site entries for nounwind calls, >>> or not add them, as you like - whatever is most convenient (eg: >>> saves >>> the most space). An interesting optimization which we don't do is >>> to >>> identify which calls correspond to a "catch-all" filter and not >>> generate >>> an entry for them in the call-site table (no need to add the filter >>> either) - this saves space and the C++ runtime knows to handle this >>> just like if we added the filter explicitly. >>> >> There's a miscommunication here. :-) The _Unwind_resume call isn't >> marked with "nounwind", however it's not called through an "invoke" >> instruction, only a regular "call" instruction. From what I can see, >> the only reason it falls within a call site in the exception table is >> because we're generating call sites for areas of code without >> "invokes". > > yes, and that's absolutely the right thing to do! Due to a strange > design choice, if a call does *not* have an entry in the call-site > table, and the call unwinds, then the runtime calls std::terminate. > All calls that may throw (like _Unwind_Resume!) must have an entry > in the call-site table.But _Unwind_Resume() is special. It never returns. It does not throw. The purpose of _Unwind_Resume() is for when you have a function with a destructor that implicitly needs running during exception processing as the exception unwinds through the stack. The unwinder jumps into that function's landing pad where the compiler has laid down a call to the destructor followed by a call to _Unwind_Resume() which then continues where the unwinding left off in processing the exception. Therefore, I don't see the point of having a call-site entry for the _Unwind_Resume() "call". -Nick
On Sep 17, 2009, at 6:03 PM, Duncan Sands wrote:>> There's a miscommunication here. :-) The _Unwind_resume call isn't >> marked with "nounwind", however it's not called through an "invoke" >> instruction, only a regular "call" instruction. From what I can see, >> the only reason it falls within a call site in the exception table is >> because we're generating call sites for areas of code without >> "invokes". > > yes, and that's absolutely the right thing to do! Due to a strange > design choice, if a call does *not* have an entry in the call-site > table, and the call unwinds, then the runtime calls std::terminate. > All calls that may throw (like _Unwind_Resume!) must have an entry > in the call-site table. > > If I implement my optimization to eliminate these call site >> entries which don't have "invoke" calls in them, then the >> _Unwind_resume call won't have an entry into the exception table, and >> that would be bad. > > As explained above, you can only eliminate call-site entries for > nounwind calls. Having a call-site entry has nothing to do with > whether a call is an invoke or not, it is to do with whether the > call can throw an exception or not. >I was imprecise, but yes, I meant to say that we shouldn't have one for "nounwind" calls. :-) -bw