Skip to content
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

wasm-opt --spill-pointers fails with internal error in wasm::ABI::getStackSpace() #2229

Open
wmaddox opened this issue Jul 17, 2019 · 4 comments

Comments

@wmaddox
Copy link
Contributor

wmaddox commented Jul 17, 2019

% wasm-opt --enable-threads --spill-pointers -o myproject.wasm myproject.nogc.wasm
Fatal: getStackSpace: failed to find the stack pointer

Function wasm::ABI::getStackSpace() attempts to obtain the global stack pointer STACKTOP with the following call: GlobalUtils::getGlobalInitializedToImport(wasm, ENV, "STACKTOP"). This attempts to locate a global variable that is initialized to the value of the imported variable env.STACKTOP. It appears that the expected code idiom is no longer used as of #1870. Instead, the initial value of STACKTOP is hardcoded.

@kripken
Copy link
Member

kripken commented Jul 17, 2019

Yeah, there isn't a good ABI for this sort of thing I'm afraid. Another issue is that the wasm backend's stack goes downward instead of up. So there isn't a good way atm to access the C stack in binaryen. We'd probably need to add specific flags for specific ABI assumptions.

Btw, I'm curious what's your use case for this pass? I've never been sure if this pass is useful for people or not.

@wmaddox
Copy link
Contributor Author

wmaddox commented Jul 17, 2019

We use --spill-pointers to support GC. Our GC is mostly exact, but relies on conservative stack scanning.

It seems to me that wasm-opt might not be the best place to implement this functionality, because lowering to WASM has already eliminated any explicit notion of the linear stack. Before --spill-pointers was implemented, I implemented a similar mechanism as a modification to fastcomp. As I recall, --spill-pointers turned out to be at least as performant, and therefore was preferred going forward, as it was also the upstream solution. The big downside, as I see it, is that spilling really ought to be done after any optimizations that might eliminate or introduce calls (e.g., -Oz) or which would have eliminated the spilled variables, otherwise, unnecessary stores may be retained or optimizations unnecessarily inhibited. This shouldn't be a problem in a fully-native C/C++ to WASM pipeline, but poses a problem for translation via asm.js, since the C++ stack has been lowered already in the translation to asm.js before asm2wasm is run. Nonetheless, asm2wasm seems to be in a better position to handle pointer spilling, as it has access to the symbolic variable names (e.g., "STACKTOP") needed to make the current scheme work.

@kripken
Copy link
Member

kripken commented Jul 18, 2019

Yeah, there are multiple considerations here.

Another issue is the number of locals. Doing spilling after locals have been minimized as much as possible may be more efficient, so doing it after binaryen optimizations would be best. Asyncify works that way as it also spills and restores locals.

But yes, we'd need to make the C stack accessible to Binaryen. Currently it just looks for STACKTOP, but we could connect it to the wasm backend's stack with a little more work. That might work by

  • In emscripten at least one of stackSave/stackRestore/stackAlloc must be exported, so it is kept alive. That function's body will use the stack pointer, so we can identify it from there.
  • In binaryen we can't tell if we are using the wasm backend or not, so we'd need a flag for that (maybe --stack-abi, or maybe just --spill-pointers-wasm-backend). Then it would find that export and identify the stack pointer.

@wmaddox
Copy link
Contributor Author

wmaddox commented Jul 19, 2019

Based on Kripken's comment above, I was able to implement a simple fix that restores wasm-opt --spill-pointers functionality sufficient to get my project "back in business". I make no claims for its generality, and don't attempt to address any of the larger ABI issues.

wmaddox pushed a commit to wmaddox/binaryen that referenced this issue Jul 20, 2019
Recent stack pointer simplification in Emscripten broke the --spill-pointers
pass.  This fix for WebAssembly#2229 restores this functionality by recognizing an
alternative coding idiom in Emscripten-generated WASM code.
kripken pushed a commit that referenced this issue Jul 28, 2019
* Fix stack pointer identification for wasm::ABI::getStackSpace().

Recent stack pointer simplification in Emscripten broke the --spill-pointers
pass.  This fix for #2229 restores this functionality by recognizing an
alternative coding idiom in Emscripten-generated WASM code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants