-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[WebAssembly] Problems of forcing mem2reg in reference-types #81575
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@llvm/issue-subscribers-backend-webassembly Author: Heejin Ahn (aheejin)
I recently noticed that we force mem2reg optimization to run unconditionally, even in `-O0`, when reference-types feature is enabled:
https://github.com/llvm/llvm-project/blob/2dd52046816ac706a25d588efac77705793d8778/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp#L479-L482
This was added in https://github.com/llvm/llvm-project/commit/890146b19206827bc48ee1ae1dc1534ff2ff18d7.
I think this can have some problems:
Any thoughts or ideas? |
@aheejin As it's in the comment we need to promote allocas for reftypes to registers and at the time mem2reg did that for us and it worked fine. It seems that this causes issues with EH as you say. I think we might need a pass here dedicated to just promoting reftypes to allocas that's slightly more constrained - sort of a specialized mem2reg for reftypes. |
@pmatos Do we need to promote allocas to registers? I think promoting them to locals should be enough, which can be done by moving them from |
It has been over a year since I looked into this but if memory serves me right, I don't think we have a way to do that in IR atm. |
@xortoast Thanks for the info! Currently it looks Wasm reference types are represented by |
@aheejin I think you misunderstood a bit. Reference types are represented as For example, a local variable of type After running mem2local, the same |
This adds `WebAssemblyRefTypeMem2Local` pass, which changes the address spaces of reference type `alloca`s to `addrspace(1)`. This in turn changes the address spaces of all `load` and `store` instructions that use the `alloca`s. `addrspace(1)` is `WASM_ADDRESS_SPACE_VAR`, and loads and stores to this address space become `local.get`s and `local.set`s, thanks to the Wasm local IR support added in llvm@82f92e3. In a follow-up PR, I am planning to replace the usage of mem2reg pass with this to solve the reference type `alloca` problems described in llvm#81575.
This adds `WebAssemblyRefTypeMem2Local` pass, which changes the address spaces of reference type `alloca`s to `addrspace(1)`. This in turn changes the address spaces of all `load` and `store` instructions that use the `alloca`s. `addrspace(1)` is `WASM_ADDRESS_SPACE_VAR`, and loads and stores to this address space become `local.get`s and `local.set`s, thanks to the Wasm local IR support added in 82f92e3. In a follow-up PR, I am planning to replace the usage of mem2reg pass with this to solve the reference type `alloca` problems described in #81575.
When reference-types feature is enabled, forcing mem2reg unconditionally even in `-O0` has some problems described in llvm#81575. This uses RefTypeMem2Local pass added in llvm#81965 instead. This also removes `IsForced` parameter added in llvm@890146b given that we don't need it anymore. This may still hurt debug info related to reference type variables a little during the backend transformation given that they are not stored in memory anymore, but reference type variables are presumably rare and it would be still a lot less damage than forcing mem2reg on the whole program. Also this fixes the EH problem described in llvm#81575. Fixes llvm#81575.
When reference-types feature is enabled, forcing mem2reg unconditionally even in `-O0` has some problems described in #81575. This uses RefTypeMem2Local pass added in #81965 instead. This also removes `IsForced` parameter added in 890146b given that we don't need it anymore. This may still hurt debug info related to reference type variables a little during the backend transformation given that they are not stored in memory anymore, but reference type variables are presumably rare and it would be still a lot less damage than forcing mem2reg on the whole program. Also this fixes the EH problem described in #81575. Fixes #81575.
I recently noticed that we force mem2reg optimization to run unconditionally, even in
-O0
, when reference-types feature is enabled:llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
Lines 479 to 482 in 2dd5204
This was added in 890146b.
I think this can have some problems:
This means we run some optimizations even when we are not supposed to. We will handle debug value differently and debug info can be lost even in
-O0
, if reference-types is enabled. And the newest EH spec requires reference-types to be enabled, so this means enabling EH means running some optimizations even in-O0
. Also, as it happens, we've been even discussing enabling reference-types by default. ([WebAssembly] Enable multivalue and reference-types in generic CPU config #80923) It'd be good if there's a way to promote only reference type values to registers.When Wasm EH is used, we demote certain PHIs from registers to memory in
WinEHPrepare
. (Wasm EH uses WinEHPrepare pass, because it uses WinEH IR) Specifically, we cannot have a PHI before acatchswitch
. PHIs incatchswitch
BBs have to be removed (= demoted) becausecatchswitch
s are removed in ISel andcatchswitch
BBs are removed as well, so they can't have other instructions. But when reference-types is enabled, we force to run mem2reg inaddISelPrepare
, which runs afterWinEHPrepare
, re-promoting the demoted PHIs inWinEHPrepare
, which crashes the compiler. This is a problem even if we have a way to promote only reference types because they can be before acatchswitch
too.Any thoughts or ideas?
cc @pmatos
The text was updated successfully, but these errors were encountered: