This is an archive of the discontinued LLVM Phabricator instance.

[WebAssembly] Disable wasm.lsda() optimization in WasmEHPrepare
ClosedPublic

Authored by aheejin on Feb 23 2021, 11:31 AM.

Details

Summary

In every catchpad except catch (...), we add a call to
_Unwind_CallPersonality, which is a wapper to call the personality
function. (In most of other Itanium-based architectures the call is done
from libunwind, but in wasm we don't have the control over the VM.)
Because the personatlity function is called to figure out whether the
current exception is a type we should catch, such as int or
SomeClass&, catch (...) does not need the personality function call.
For the same reason, all cleanuppads don't need it.

When we call _Unwind_CallPersonality, we store some necessary info in
a data structure called __wasm_lpad_context of type
_Unwind_LandingPadContext, which is defined in the wasm's port of
libunwind in Emscripten. Also the personality wrapper function returns
some info (selector and the caught pointer) in that data structure, so
it is used as a medium for communication.

One of the info we need to store is the address for LSDA info for the
current function. wasm.lsda() intrinsic returns that address. (This
intrinsic will be lowered to a symbol that points to the LSDA address.)
The simpliest thing is call wasm.lsda() every time we need to call
_Unwind_CallPersonality and store that info in __wasm_lpad_context
data structure. But we tried to be better than that (D77423 and some
more previous CLs), so if catchpad A dominates catchpad B and catchpad A
is not catch (...), we didn't insert wasm.lsda() call in catchpad B,
thinking that the LSDA address is the same for a single function and we
already visited catchpad A and __wasm_lpad_context.lsda field would
already have that value.

But this can be incorrect if there is a call to another function, which
also can have the personality function and LSDA, between catchpad A and
catchpad B, because __wasm_lpad_context is a globally defined
structure and the callee function will overwrite its lsda field.

So in this CL we don't try to do any optimizaions on adding
wasm.lsda() call; we store the result of wasm.lsda() every time we
call _Unwind_CallPersonality. We can do some complicated analysis,
like checking if there is a function call between the dominating
catchpad and the current catchpad, but at this time it seems overkill.

This deletes three tests because they all tested wasm.ldsa() call
optimization.

Fixes https://github.com/emscripten-core/emscripten/issues/13548.

Diff Detail

Event Timeline

aheejin created this revision.Feb 23 2021, 11:31 AM
aheejin requested review of this revision.Feb 23 2021, 11:31 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 23 2021, 11:31 AM
aheejin edited the summary of this revision. (Show Details)Feb 23 2021, 11:31 AM
aheejin edited the summary of this revision. (Show Details)
aheejin edited the summary of this revision. (Show Details)
tlively accepted this revision.Feb 23 2021, 11:48 AM
This revision is now accepted and ready to land.Feb 23 2021, 11:48 AM
aheejin edited the summary of this revision. (Show Details)Feb 23 2021, 11:51 AM