This is an archive of the discontinued LLVM Phabricator instance.

[WebAssembly] Share rethrowing BBs in LowerEmscriptenEHSjLj
ClosedPublic

Authored by aheejin on Aug 30 2021, 1:33 PM.

Details

Summary

There are three kinds of "rethrowing" BBs in this pass:

  1. In Emscripten SjLj, after a possibly longjmping function call, we check if the thrown longjmp corresponds to one of setjmps within the current function. If not, we rethrow the longjmp by calling emscripten_longjmp.
  2. In Emscripten EH, after a possibly throwing function call, we check if the thrown exception corresponds to the current catch clauses. If not, we rethrow the exception by calling __resumeException.
  3. When both Emscripten EH and SjLj are used, when we check for an exception after a possibly throwing function call, it is possible that we get not an exception but a longjmp. In this case, we shouldn't swallow it; we should rethrow the longjmp by calling emscripten_longjmp.
  4. When both Emscripten EH and SjLj are used, when we check for a longjmp after a possibly longjmping function call, it is possible that we get not a longjmp but an exception. In this case, we shouldn't swallot it; we should rethrow the exception by calling __resumeException.

Case 1 is in Emscripten SjLj, 2 is in Emscripten EH, and 3 and 4 are
relevant when both Emscripten EH and SjLj are used. 3 and 4 were first
implemented in D106525.

We create BBs for 1, 3, and 4 in this pass. We create those BBs for
every throwing/longjmping function call, along with other BBs that
contain condition checks. What this CL does is to create a single BB
within a function for each of 1, 3, and 4 cases. These BBs are exiting
BBs in the function and thus don't have successors, so easy to be shared
between calls.

The names of BBs created are:
Case 1: call.em.longjmp
Case 3: rethrow.exn
Case 4: rethrow.longjmp

For the case 2 we don't currently create BBs; we only replace the
existing resume instruction with call @__resumeException. And Clang
already creates only a single resume BB per function and reuses it,
so we don't need to optimize this case.

Not sure what are good benchmarks for EH/SjLj, but this decreases the
size of the object file for grfmt_jpeg.bc (presumably from opencv) we
got from one of our users by 8.9%. Even after running wasm-opt -O4 on
them, there is still 4.8% improvement.

Diff Detail

Event Timeline

aheejin created this revision.Aug 30 2021, 1:33 PM
aheejin requested review of this revision.Aug 30 2021, 1:33 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 30 2021, 1:33 PM

Haven't looked at the code yet, but I'm a bit confused about cases 3/4.
If we expect a possible exception, but get a longjmp instead, why do we want to resume an exception rather than resuming the longjmp that we just caught? Likewise the other way around.

Sorry, you are right. I got the two descriptions swapped.. Will fix. The code is not affected.

aheejin edited the summary of this revision. (Show Details)Aug 30 2021, 4:20 PM
dschuff accepted this revision.Aug 30 2021, 4:49 PM

code LGTM

This revision is now accepted and ready to land.Aug 30 2021, 4:49 PM
This revision was landed with ongoing or failed builds.Aug 30 2021, 9:44 PM
This revision was automatically updated to reflect the committed changes.